aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nouveau_volt.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2012-10-02 23:26:15 -0400
committerDave Airlie <airlied@redhat.com>2012-10-02 23:26:15 -0400
commit268d28371cd326be4dfcd7eba5917bf4b9d30c8f (patch)
treefec4f9e98bde15301b5d5338038a9a31f7555456 /drivers/gpu/drm/nouveau/nouveau_volt.c
parentdf86b5765a48d5f557489577652bd6df145b0e1b (diff)
parentb9f10852fcb1f09369d931dcbfbaad89ad1da4ad (diff)
Merge branch 'drm-nouveau-next' of git://anongit.freedesktop.org/git/nouveau/linux-2.6 into drm-next
This is a major rework of the nouveau driver core, to reflect more closely how the hw is used and to make it easier to implement newer features now that the GPUs are more clearly understood than when nouveau started. It also contains a few other bits: thermal patches nv41/44 pcie gart fixes i2c unregistering fixes. * 'drm-nouveau-next' of git://anongit.freedesktop.org/git/nouveau/linux-2.6: (191 commits) drm/nv98/crypt: fix fuc build with latest envyas drm/nouveau/devinit: fixup various issues with subdev ctor/init ordering drm/nv41/vm: fix and enable use of "real" pciegart drm/nv44/vm: fix and enable use of "real" pciegart drm/nv04/dmaobj: fixup vm target handling in preparation for nv4x pcie drm/nouveau: store supported dma mask in vmmgr drm/nvc0/ibus: initial implementation of subdev drm/nouveau/therm: add support for fan-control modes drm/nouveau/hwmon: rename pwm0* to pmw1* to follow hwmon's rules drm/nouveau/therm: calculate the pwm divisor on nv50+ drm/nouveau/fan: rewrite the fan tachometer driver to get more precision, faster drm/nouveau/therm: move thermal-related functions to the therm subdev drm/nouveau/bios: parse the pwm divisor from the perf table drm/nouveau/therm: use the EXTDEV table to detect i2c monitoring devices drm/nouveau/therm: rework thermal table parsing drm/nouveau/gpio: expose the PWM/TOGGLE parameter found in the gpio vbios table drm/nouveau: fix pm initialization order drm/nouveau/bios: check that fixed tvdac gpio data is valid before using it drm/nouveau: log channel debug/error messages from client object rather than drm client drm/nouveau: have drm debugging macros build on top of core macros ... Conflicts: drivers/gpu/drm/nouveau/nouveau_dp.c
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_volt.c')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_volt.c53
1 files changed, 28 insertions, 25 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_volt.c b/drivers/gpu/drm/nouveau/nouveau_volt.c
index b010cb997b34..c2cc8e2d6539 100644
--- a/drivers/gpu/drm/nouveau/nouveau_volt.c
+++ b/drivers/gpu/drm/nouveau/nouveau_volt.c
@@ -24,18 +24,21 @@
24 24
25#include "drmP.h" 25#include "drmP.h"
26 26
27#include "nouveau_drv.h" 27#include "nouveau_drm.h"
28#include "nouveau_pm.h" 28#include "nouveau_pm.h"
29#include "nouveau_gpio.h"
30 29
31static const enum dcb_gpio_tag vidtag[] = { 0x04, 0x05, 0x06, 0x1a, 0x73 }; 30#include <subdev/bios/gpio.h>
31#include <subdev/gpio.h>
32
33static const enum dcb_gpio_func_name vidtag[] = { 0x04, 0x05, 0x06, 0x1a, 0x73 };
32static int nr_vidtag = sizeof(vidtag) / sizeof(vidtag[0]); 34static int nr_vidtag = sizeof(vidtag) / sizeof(vidtag[0]);
33 35
34int 36int
35nouveau_voltage_gpio_get(struct drm_device *dev) 37nouveau_voltage_gpio_get(struct drm_device *dev)
36{ 38{
37 struct drm_nouveau_private *dev_priv = dev->dev_private; 39 struct nouveau_pm_voltage *volt = &nouveau_pm(dev)->voltage;
38 struct nouveau_pm_voltage *volt = &dev_priv->engine.pm.voltage; 40 struct nouveau_device *device = nouveau_dev(dev);
41 struct nouveau_gpio *gpio = nouveau_gpio(device);
39 u8 vid = 0; 42 u8 vid = 0;
40 int i; 43 int i;
41 44
@@ -43,7 +46,7 @@ nouveau_voltage_gpio_get(struct drm_device *dev)
43 if (!(volt->vid_mask & (1 << i))) 46 if (!(volt->vid_mask & (1 << i)))
44 continue; 47 continue;
45 48
46 vid |= nouveau_gpio_func_get(dev, vidtag[i]) << i; 49 vid |= gpio->get(gpio, 0, vidtag[i], 0xff) << i;
47 } 50 }
48 51
49 return nouveau_volt_lvl_lookup(dev, vid); 52 return nouveau_volt_lvl_lookup(dev, vid);
@@ -52,8 +55,9 @@ nouveau_voltage_gpio_get(struct drm_device *dev)
52int 55int
53nouveau_voltage_gpio_set(struct drm_device *dev, int voltage) 56nouveau_voltage_gpio_set(struct drm_device *dev, int voltage)
54{ 57{
55 struct drm_nouveau_private *dev_priv = dev->dev_private; 58 struct nouveau_device *device = nouveau_dev(dev);
56 struct nouveau_pm_voltage *volt = &dev_priv->engine.pm.voltage; 59 struct nouveau_gpio *gpio = nouveau_gpio(device);
60 struct nouveau_pm_voltage *volt = &nouveau_pm(dev)->voltage;
57 int vid, i; 61 int vid, i;
58 62
59 vid = nouveau_volt_vid_lookup(dev, voltage); 63 vid = nouveau_volt_vid_lookup(dev, voltage);
@@ -64,7 +68,7 @@ nouveau_voltage_gpio_set(struct drm_device *dev, int voltage)
64 if (!(volt->vid_mask & (1 << i))) 68 if (!(volt->vid_mask & (1 << i)))
65 continue; 69 continue;
66 70
67 nouveau_gpio_func_set(dev, vidtag[i], !!(vid & (1 << i))); 71 gpio->set(gpio, 0, vidtag[i], 0xff, !!(vid & (1 << i)));
68 } 72 }
69 73
70 return 0; 74 return 0;
@@ -73,8 +77,7 @@ nouveau_voltage_gpio_set(struct drm_device *dev, int voltage)
73int 77int
74nouveau_volt_vid_lookup(struct drm_device *dev, int voltage) 78nouveau_volt_vid_lookup(struct drm_device *dev, int voltage)
75{ 79{
76 struct drm_nouveau_private *dev_priv = dev->dev_private; 80 struct nouveau_pm_voltage *volt = &nouveau_pm(dev)->voltage;
77 struct nouveau_pm_voltage *volt = &dev_priv->engine.pm.voltage;
78 int i; 81 int i;
79 82
80 for (i = 0; i < volt->nr_level; i++) { 83 for (i = 0; i < volt->nr_level; i++) {
@@ -88,8 +91,7 @@ nouveau_volt_vid_lookup(struct drm_device *dev, int voltage)
88int 91int
89nouveau_volt_lvl_lookup(struct drm_device *dev, int vid) 92nouveau_volt_lvl_lookup(struct drm_device *dev, int vid)
90{ 93{
91 struct drm_nouveau_private *dev_priv = dev->dev_private; 94 struct nouveau_pm_voltage *volt = &nouveau_pm(dev)->voltage;
92 struct nouveau_pm_voltage *volt = &dev_priv->engine.pm.voltage;
93 int i; 95 int i;
94 96
95 for (i = 0; i < volt->nr_level; i++) { 97 for (i = 0; i < volt->nr_level; i++) {
@@ -103,10 +105,12 @@ nouveau_volt_lvl_lookup(struct drm_device *dev, int vid)
103void 105void
104nouveau_volt_init(struct drm_device *dev) 106nouveau_volt_init(struct drm_device *dev)
105{ 107{
106 struct drm_nouveau_private *dev_priv = dev->dev_private; 108 struct nouveau_drm *drm = nouveau_drm(dev);
107 struct nouveau_pm_engine *pm = &dev_priv->engine.pm; 109 struct nouveau_gpio *gpio = nouveau_gpio(drm->device);
110 struct nouveau_pm *pm = nouveau_pm(dev);
108 struct nouveau_pm_voltage *voltage = &pm->voltage; 111 struct nouveau_pm_voltage *voltage = &pm->voltage;
109 struct nvbios *bios = &dev_priv->vbios; 112 struct nvbios *bios = &drm->vbios;
113 struct dcb_gpio_func func;
110 struct bit_entry P; 114 struct bit_entry P;
111 u8 *volt = NULL, *entry; 115 u8 *volt = NULL, *entry;
112 int i, headerlen, recordlen, entries, vidmask, vidshift; 116 int i, headerlen, recordlen, entries, vidmask, vidshift;
@@ -121,11 +125,11 @@ nouveau_volt_init(struct drm_device *dev)
121 if (P.version == 2) 125 if (P.version == 2)
122 volt = ROMPTR(dev, P.data[12]); 126 volt = ROMPTR(dev, P.data[12]);
123 else { 127 else {
124 NV_WARN(dev, "unknown volt for BIT P %d\n", P.version); 128 NV_WARN(drm, "unknown volt for BIT P %d\n", P.version);
125 } 129 }
126 } else { 130 } else {
127 if (bios->data[bios->offset + 6] < 0x27) { 131 if (bios->data[bios->offset + 6] < 0x27) {
128 NV_DEBUG(dev, "BMP version too old for voltage\n"); 132 NV_DEBUG(drm, "BMP version too old for voltage\n");
129 return; 133 return;
130 } 134 }
131 135
@@ -133,7 +137,7 @@ nouveau_volt_init(struct drm_device *dev)
133 } 137 }
134 138
135 if (!volt) { 139 if (!volt) {
136 NV_DEBUG(dev, "voltage table pointer invalid\n"); 140 NV_DEBUG(drm, "voltage table pointer invalid\n");
137 return; 141 return;
138 } 142 }
139 143
@@ -177,7 +181,7 @@ nouveau_volt_init(struct drm_device *dev)
177 vidshift = 0; 181 vidshift = 0;
178 break; 182 break;
179 default: 183 default:
180 NV_WARN(dev, "voltage table 0x%02x unknown\n", volt[0]); 184 NV_WARN(drm, "voltage table 0x%02x unknown\n", volt[0]);
181 return; 185 return;
182 } 186 }
183 187
@@ -189,12 +193,12 @@ nouveau_volt_init(struct drm_device *dev)
189 i = 0; 193 i = 0;
190 while (vidmask) { 194 while (vidmask) {
191 if (i > nr_vidtag) { 195 if (i > nr_vidtag) {
192 NV_DEBUG(dev, "vid bit %d unknown\n", i); 196 NV_DEBUG(drm, "vid bit %d unknown\n", i);
193 return; 197 return;
194 } 198 }
195 199
196 if (!nouveau_gpio_func_valid(dev, vidtag[i])) { 200 if (gpio && gpio->find(gpio, 0, vidtag[i], 0xff, &func)) {
197 NV_DEBUG(dev, "vid bit %d has no gpio tag\n", i); 201 NV_DEBUG(drm, "vid bit %d has no gpio tag\n", i);
198 return; 202 return;
199 } 203 }
200 204
@@ -240,8 +244,7 @@ nouveau_volt_init(struct drm_device *dev)
240void 244void
241nouveau_volt_fini(struct drm_device *dev) 245nouveau_volt_fini(struct drm_device *dev)
242{ 246{
243 struct drm_nouveau_private *dev_priv = dev->dev_private; 247 struct nouveau_pm_voltage *volt = &nouveau_pm(dev)->voltage;
244 struct nouveau_pm_voltage *volt = &dev_priv->engine.pm.voltage;
245 248
246 kfree(volt->level); 249 kfree(volt->level);
247} 250}