diff options
| author | Ben Skeggs <bskeggs@redhat.com> | 2010-04-06 22:57:35 -0400 |
|---|---|---|
| committer | Ben Skeggs <bskeggs@redhat.com> | 2010-04-08 20:15:46 -0400 |
| commit | 4528416291e26456e68f7217576e40e589d276bf (patch) | |
| tree | b1de183465e90d58b30f0879de9300bdd4f3f1ca | |
| parent | 02faec09b2814b6ad3fd202e2f28b3c4b712a3f1 (diff) | |
drm/nv50: implement gpio set/get routines
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
| -rw-r--r-- | drivers/gpu/drm/nouveau/Makefile | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_bios.c | 11 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_drv.h | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nv50_gpio.c | 76 |
4 files changed, 86 insertions, 7 deletions
diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile index 7f0d807a0d0d..453df3f6053f 100644 --- a/drivers/gpu/drm/nouveau/Makefile +++ b/drivers/gpu/drm/nouveau/Makefile | |||
| @@ -22,7 +22,7 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \ | |||
| 22 | nv50_cursor.o nv50_display.o nv50_fbcon.o \ | 22 | nv50_cursor.o nv50_display.o nv50_fbcon.o \ |
| 23 | nv04_dac.o nv04_dfp.o nv04_tv.o nv17_tv.o nv17_tv_modes.o \ | 23 | nv04_dac.o nv04_dfp.o nv04_tv.o nv17_tv.o nv17_tv_modes.o \ |
| 24 | nv04_crtc.o nv04_display.o nv04_cursor.o nv04_fbcon.o \ | 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 | nouveau-$(CONFIG_DRM_NOUVEAU_DEBUG) += nouveau_debugfs.o | 27 | nouveau-$(CONFIG_DRM_NOUVEAU_DEBUG) += nouveau_debugfs.o |
| 28 | nouveau-$(CONFIG_COMPAT) += nouveau_ioc32.o | 28 | nouveau-$(CONFIG_COMPAT) += nouveau_ioc32.o |
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 70a51fc2323e..abc382a9918b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c | |||
| @@ -2574,7 +2574,6 @@ init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
| 2574 | */ | 2574 | */ |
| 2575 | 2575 | ||
| 2576 | struct drm_nouveau_private *dev_priv = bios->dev->dev_private; | 2576 | struct drm_nouveau_private *dev_priv = bios->dev->dev_private; |
| 2577 | const uint32_t nv50_gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 }; | ||
| 2578 | const uint32_t nv50_gpio_ctl[2] = { 0xe100, 0xe28c }; | 2577 | const uint32_t nv50_gpio_ctl[2] = { 0xe100, 0xe28c }; |
| 2579 | int i; | 2578 | int i; |
| 2580 | 2579 | ||
| @@ -2592,12 +2591,12 @@ init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
| 2592 | 2591 | ||
| 2593 | BIOSLOG(bios, "0x%04X: Entry: 0x%08X\n", offset, gpio->entry); | 2592 | BIOSLOG(bios, "0x%04X: Entry: 0x%08X\n", offset, gpio->entry); |
| 2594 | 2593 | ||
| 2595 | r = nv50_gpio_reg[gpio->line >> 3]; | 2594 | nv50_gpio_set(bios->dev, gpio->tag, gpio->state_default); |
| 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); | ||
| 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 | r = nv50_gpio_ctl[gpio->line >> 4]; | 2600 | r = nv50_gpio_ctl[gpio->line >> 4]; |
| 2602 | s = (gpio->line & 0x0f); | 2601 | s = (gpio->line & 0x0f); |
| 2603 | v = bios_rd32(bios, r) & ~(0x00010001 << s); | 2602 | v = bios_rd32(bios, r) & ~(0x00010001 << s); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index c4f5658b9e49..ace630aa89e1 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h | |||
| @@ -1162,6 +1162,10 @@ extern int nouveau_gem_ioctl_info(struct drm_device *, void *, | |||
| 1162 | int nv17_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag); | 1162 | int nv17_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag); |
| 1163 | int nv17_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state); | 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 | #ifndef ioread32_native | 1169 | #ifndef ioread32_native |
| 1166 | #ifdef __BIG_ENDIAN | 1170 | #ifdef __BIG_ENDIAN |
| 1167 | #define ioread16_native ioread16be | 1171 | #define ioread16_native ioread16be |
diff --git a/drivers/gpu/drm/nouveau/nv50_gpio.c b/drivers/gpu/drm/nouveau/nv50_gpio.c new file mode 100644 index 000000000000..c61782b314e7 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nv50_gpio.c | |||
| @@ -0,0 +1,76 @@ | |||
| 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 | } | ||
