Commit 4528416291e26456e68f7217576e40e589d276bf
1 parent
02faec09b2
Exists in
master
and in
4 other branches
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 | +} |