aboutsummaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/nouveau/nouveau_pm.c
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2011-11-21 16:41:48 +1000
committerBen Skeggs <bskeggs@redhat.com>2011-12-21 19:01:45 +1000
commita0b25635515ef5049f93b032a1e37f18b16e0f6f (patch)
tree34c25948a2fd7b8eadf46418d767d43c9a64c06b /drivers/gpu/drm/nouveau/nouveau_pm.c
parent675aac033e089833e763ea4fbabae66883d10574 (diff)
drm/nouveau/gpio: reimplement as nouveau_gpio.c, fixing a number of issues
- moves out of nouveau_bios.c and demagics the logical state definitions - simplifies chipset-specific driver interface - makes most of gpio irq handling common, will use for nv4x hpd later - api extended to allow both direct gpio access, and access using the logical function states - api extended to allow for future use of gpio extender chips - pre-nv50 was handled very badly, the main issue being that all GPIOs were being treated as output-only. - fixes nvd0 so gpio changes actually stick, magic reg needs bashing Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_pm.c')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_pm.c43
1 files changed, 21 insertions, 22 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.c b/drivers/gpu/drm/nouveau/nouveau_pm.c
index 788ba33da77..aba3362d421 100644
--- a/drivers/gpu/drm/nouveau/nouveau_pm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_pm.c
@@ -26,6 +26,7 @@
#include "nouveau_drv.h"
#include "nouveau_pm.h"
+#include "nouveau_gpio.h"
#ifdef CONFIG_ACPI
#include <linux/acpi.h>
@@ -38,27 +39,25 @@ static int
nouveau_pwmfan_get(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio;
struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
- struct dcb_gpio_entry *gpio = NULL;
+ struct gpio_func gpio;
u32 divs, duty;
int ret;
if (!pm->pwm_get)
return -ENODEV;
- gpio = nouveau_bios_gpio_entry(dev, DCB_GPIO_PWM_FAN);
- if (gpio) {
- ret = pm->pwm_get(dev, gpio->line, &divs, &duty);
+ ret = nouveau_gpio_find(dev, 0, DCB_GPIO_PWM_FAN, 0xff, &gpio);
+ if (ret == 0) {
+ ret = pm->pwm_get(dev, gpio.line, &divs, &duty);
if (ret == 0) {
divs = max(divs, duty);
- if (dev_priv->card_type <= NV_40 ||
- (gpio->state[0] & 1))
+ if (dev_priv->card_type <= NV_40 || (gpio.log[0] & 1))
duty = divs - duty;
return (duty * 100) / divs;
}
- return pgpio->get(dev, gpio->tag) * 100;
+ return nouveau_gpio_func_get(dev, gpio.func) * 100;
}
return -ENODEV;
@@ -69,14 +68,15 @@ nouveau_pwmfan_set(struct drm_device *dev, int percent)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
- struct dcb_gpio_entry *gpio;
+ struct gpio_func gpio;
u32 divs, duty;
+ int ret;
if (!pm->pwm_set)
return -ENODEV;
- gpio = nouveau_bios_gpio_entry(dev, DCB_GPIO_PWM_FAN);
- if (gpio) {
+ ret = nouveau_gpio_find(dev, 0, DCB_GPIO_PWM_FAN, 0xff, &gpio);
+ if (ret == 0) {
divs = pm->pwm_divisor;
if (pm->fan.pwm_freq) {
/*XXX: PNVIO clock more than likely... */
@@ -86,11 +86,10 @@ nouveau_pwmfan_set(struct drm_device *dev, int percent)
}
duty = ((divs * percent) + 99) / 100;
- if (dev_priv->card_type <= NV_40 ||
- (gpio->state[0] & 1))
+ if (dev_priv->card_type <= NV_40 || (gpio.log[0] & 1))
duty = divs - duty;
- return pm->pwm_set(dev, gpio->line, divs, duty);
+ return pm->pwm_set(dev, gpio.line, divs, duty);
}
return -ENODEV;
@@ -472,24 +471,24 @@ nouveau_hwmon_show_fan0_input(struct device *d, struct device_attribute *attr,
struct drm_device *dev = dev_get_drvdata(d);
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer;
- struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio;
- struct dcb_gpio_entry *gpio;
+ struct gpio_func gpio;
u32 cycles, cur, prev;
u64 start;
+ int ret;
- gpio = nouveau_bios_gpio_entry(dev, DCB_GPIO_FAN_SENSE);
- if (!gpio)
- return -ENODEV;
+ ret = nouveau_gpio_find(dev, 0, DCB_GPIO_FAN_SENSE, 0xff, &gpio);
+ if (ret)
+ return ret;
/* Monitor the GPIO input 0x3b for 250ms.
* When the fan spins, it changes the value of GPIO FAN_SENSE.
* We get 4 changes (0 -> 1 -> 0 -> 1 -> [...]) per complete rotation.
*/
start = ptimer->read(dev);
- prev = pgpio->get(dev, DCB_GPIO_FAN_SENSE);
+ prev = nouveau_gpio_sense(dev, 0, gpio.line);
cycles = 0;
do {
- cur = pgpio->get(dev, DCB_GPIO_FAN_SENSE);
+ cur = nouveau_gpio_sense(dev, 0, gpio.line);
if (prev != cur) {
cycles++;
prev = cur;
@@ -701,7 +700,7 @@ nouveau_hwmon_init(struct drm_device *dev)
}
/* if the card can read the fan rpm */
- if (nouveau_bios_gpio_entry(dev, DCB_GPIO_FAN_SENSE)) {
+ if (nouveau_gpio_func_valid(dev, DCB_GPIO_FAN_SENSE)) {
ret = sysfs_create_group(&dev->pdev->dev.kobj,
&hwmon_fan_rpm_attrgroup);
if (ret)