diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2011-11-21 16:41:48 +1000 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2011-12-21 19:01:45 +1000 |
commit | a0b25635515ef5049f93b032a1e37f18b16e0f6f (patch) | |
tree | 34c25948a2fd7b8eadf46418d767d43c9a64c06b /drivers/gpu/drm/nouveau/nouveau_pm.c | |
parent | 675aac033e089833e763ea4fbabae66883d10574 (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.c | 43 |
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) |