Commit 4528416291e26456e68f7217576e40e589d276bf

Authored by Ben Skeggs
1 parent 02faec09b2

drm/nv50: implement gpio set/get routines

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>

Showing 4 changed files with 86 additions and 7 deletions Side-by-side Diff

drivers/gpu/drm/nouveau/Makefile
... ... @@ -22,7 +22,7 @@
22 22 nv50_cursor.o nv50_display.o nv50_fbcon.o \
23 23 nv04_dac.o nv04_dfp.o nv04_tv.o nv17_tv.o nv17_tv_modes.o \
24 24 nv04_crtc.o nv04_display.o nv04_cursor.o nv04_fbcon.o \
25   - nv17_gpio.o
  25 + nv17_gpio.o nv50_gpio.o
26 26  
27 27 nouveau-$(CONFIG_DRM_NOUVEAU_DEBUG) += nouveau_debugfs.o
28 28 nouveau-$(CONFIG_COMPAT) += nouveau_ioc32.o
drivers/gpu/drm/nouveau/nouveau_bios.c
... ... @@ -2574,7 +2574,6 @@
2574 2574 */
2575 2575  
2576 2576 struct drm_nouveau_private *dev_priv = bios->dev->dev_private;
2577   - const uint32_t nv50_gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 };
2578 2577 const uint32_t nv50_gpio_ctl[2] = { 0xe100, 0xe28c };
2579 2578 int i;
2580 2579  
2581 2580  
... ... @@ -2592,12 +2591,12 @@
2592 2591  
2593 2592 BIOSLOG(bios, "0x%04X: Entry: 0x%08X\n", offset, gpio->entry);
2594 2593  
2595   - r = nv50_gpio_reg[gpio->line >> 3];
2596   - s = (gpio->line & 0x07) << 2;
2597   - v = bios_rd32(bios, r) & ~(0x00000003 << s);
2598   - v |= (gpio->state[gpio->state_default] ^ 2) << s;
2599   - bios_wr32(bios, r, v);
  2594 + nv50_gpio_set(bios->dev, gpio->tag, gpio->state_default);
2600 2595  
  2596 + /* The NVIDIA binary driver doesn't appear to actually do
  2597 + * any of this, my VBIOS does however.
  2598 + */
  2599 + /* Not a clue, needs de-magicing */
2601 2600 r = nv50_gpio_ctl[gpio->line >> 4];
2602 2601 s = (gpio->line & 0x0f);
2603 2602 v = bios_rd32(bios, r) & ~(0x00010001 << s);
drivers/gpu/drm/nouveau/nouveau_drv.h
... ... @@ -1162,6 +1162,10 @@
1162 1162 int nv17_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag);
1163 1163 int nv17_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state);
1164 1164  
  1165 +/* nv50_gpio.c */
  1166 +int nv50_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag);
  1167 +int nv50_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state);
  1168 +
1165 1169 #ifndef ioread32_native
1166 1170 #ifdef __BIG_ENDIAN
1167 1171 #define ioread16_native ioread16be
drivers/gpu/drm/nouveau/nv50_gpio.c
  1 +/*
  2 + * Copyright 2010 Red Hat Inc.
  3 + *
  4 + * Permission is hereby granted, free of charge, to any person obtaining a
  5 + * copy of this software and associated documentation files (the "Software"),
  6 + * to deal in the Software without restriction, including without limitation
  7 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8 + * and/or sell copies of the Software, and to permit persons to whom the
  9 + * Software is furnished to do so, subject to the following conditions:
  10 + *
  11 + * The above copyright notice and this permission notice shall be included in
  12 + * all copies or substantial portions of the Software.
  13 + *
  14 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  17 + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18 + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19 + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20 + * OTHER DEALINGS IN THE SOFTWARE.
  21 + *
  22 + * Authors: Ben Skeggs
  23 + */
  24 +
  25 +#include "drmP.h"
  26 +#include "nouveau_drv.h"
  27 +#include "nouveau_hw.h"
  28 +
  29 +static int
  30 +nv50_gpio_location(struct dcb_gpio_entry *gpio, uint32_t *reg, uint32_t *shift)
  31 +{
  32 + const uint32_t nv50_gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 };
  33 +
  34 + if (gpio->line > 32)
  35 + return -EINVAL;
  36 +
  37 + *reg = nv50_gpio_reg[gpio->line >> 3];
  38 + *shift = (gpio->line & 7) << 2;
  39 + return 0;
  40 +}
  41 +
  42 +int
  43 +nv50_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag)
  44 +{
  45 + struct dcb_gpio_entry *gpio;
  46 + uint32_t r, s, v;
  47 +
  48 + gpio = nouveau_bios_gpio_entry(dev, tag);
  49 + if (!gpio)
  50 + return -ENOENT;
  51 +
  52 + if (nv50_gpio_location(gpio, &r, &s))
  53 + return -EINVAL;
  54 +
  55 + v = nv_rd32(dev, r) >> (s + 2);
  56 + return ((v & 1) == (gpio->state[1] & 1));
  57 +}
  58 +
  59 +int
  60 +nv50_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state)
  61 +{
  62 + struct dcb_gpio_entry *gpio;
  63 + uint32_t r, s, v;
  64 +
  65 + gpio = nouveau_bios_gpio_entry(dev, tag);
  66 + if (!gpio)
  67 + return -ENOENT;
  68 +
  69 + if (nv50_gpio_location(gpio, &r, &s))
  70 + return -EINVAL;
  71 +
  72 + v = nv_rd32(dev, r) & ~(0x3 << s);
  73 + v |= (gpio->state[state] ^ 2) << s;
  74 + nv_wr32(dev, r, v);
  75 + return 0;
  76 +}