diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nvkm/subdev/gpio')
| -rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/gpio/Kbuild | 6 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/gpio/base.c | 255 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/gpio/nv10.c | 116 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/gpio/nv50.c | 129 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/gpio/nv94.c | 74 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/gpio/nvd0.c | 85 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/gpio/nve0.c | 74 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/gpio/priv.h | 67 |
8 files changed, 806 insertions, 0 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/Kbuild new file mode 100644 index 000000000000..77bc88672af6 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/Kbuild | |||
| @@ -0,0 +1,6 @@ | |||
| 1 | nvkm-y += nvkm/subdev/gpio/base.o | ||
| 2 | nvkm-y += nvkm/subdev/gpio/nv10.o | ||
| 3 | nvkm-y += nvkm/subdev/gpio/nv50.o | ||
| 4 | nvkm-y += nvkm/subdev/gpio/nv94.o | ||
| 5 | nvkm-y += nvkm/subdev/gpio/nvd0.o | ||
| 6 | nvkm-y += nvkm/subdev/gpio/nve0.o | ||
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/base.c new file mode 100644 index 000000000000..7ad99b763f4c --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/base.c | |||
| @@ -0,0 +1,255 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2011 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 <subdev/bios.h> | ||
| 26 | #include <subdev/bios/gpio.h> | ||
| 27 | |||
| 28 | #include "priv.h" | ||
| 29 | |||
| 30 | static int | ||
| 31 | nouveau_gpio_drive(struct nouveau_gpio *gpio, | ||
| 32 | int idx, int line, int dir, int out) | ||
| 33 | { | ||
| 34 | const struct nouveau_gpio_impl *impl = (void *)nv_object(gpio)->oclass; | ||
| 35 | return impl->drive ? impl->drive(gpio, line, dir, out) : -ENODEV; | ||
| 36 | } | ||
| 37 | |||
| 38 | static int | ||
| 39 | nouveau_gpio_sense(struct nouveau_gpio *gpio, int idx, int line) | ||
| 40 | { | ||
| 41 | const struct nouveau_gpio_impl *impl = (void *)nv_object(gpio)->oclass; | ||
| 42 | return impl->sense ? impl->sense(gpio, line) : -ENODEV; | ||
| 43 | } | ||
| 44 | |||
| 45 | static int | ||
| 46 | nouveau_gpio_find(struct nouveau_gpio *gpio, int idx, u8 tag, u8 line, | ||
| 47 | struct dcb_gpio_func *func) | ||
| 48 | { | ||
| 49 | struct nouveau_bios *bios = nouveau_bios(gpio); | ||
| 50 | u8 ver, len; | ||
| 51 | u16 data; | ||
| 52 | |||
| 53 | if (line == 0xff && tag == 0xff) | ||
| 54 | return -EINVAL; | ||
| 55 | |||
| 56 | data = dcb_gpio_match(bios, idx, tag, line, &ver, &len, func); | ||
| 57 | if (data) | ||
| 58 | return 0; | ||
| 59 | |||
| 60 | /* Apple iMac G4 NV18 */ | ||
| 61 | if (nv_device_match(nv_object(gpio), 0x0189, 0x10de, 0x0010)) { | ||
| 62 | if (tag == DCB_GPIO_TVDAC0) { | ||
| 63 | *func = (struct dcb_gpio_func) { | ||
| 64 | .func = DCB_GPIO_TVDAC0, | ||
| 65 | .line = 4, | ||
| 66 | .log[0] = 0, | ||
| 67 | .log[1] = 1, | ||
| 68 | }; | ||
| 69 | return 0; | ||
| 70 | } | ||
| 71 | } | ||
| 72 | |||
| 73 | return -ENOENT; | ||
| 74 | } | ||
| 75 | |||
| 76 | static int | ||
| 77 | nouveau_gpio_set(struct nouveau_gpio *gpio, int idx, u8 tag, u8 line, int state) | ||
| 78 | { | ||
| 79 | struct dcb_gpio_func func; | ||
| 80 | int ret; | ||
| 81 | |||
| 82 | ret = nouveau_gpio_find(gpio, idx, tag, line, &func); | ||
| 83 | if (ret == 0) { | ||
| 84 | int dir = !!(func.log[state] & 0x02); | ||
| 85 | int out = !!(func.log[state] & 0x01); | ||
| 86 | ret = nouveau_gpio_drive(gpio, idx, func.line, dir, out); | ||
| 87 | } | ||
| 88 | |||
| 89 | return ret; | ||
| 90 | } | ||
| 91 | |||
| 92 | static int | ||
| 93 | nouveau_gpio_get(struct nouveau_gpio *gpio, int idx, u8 tag, u8 line) | ||
| 94 | { | ||
| 95 | struct dcb_gpio_func func; | ||
| 96 | int ret; | ||
| 97 | |||
| 98 | ret = nouveau_gpio_find(gpio, idx, tag, line, &func); | ||
| 99 | if (ret == 0) { | ||
| 100 | ret = nouveau_gpio_sense(gpio, idx, func.line); | ||
| 101 | if (ret >= 0) | ||
| 102 | ret = (ret == (func.log[1] & 1)); | ||
| 103 | } | ||
| 104 | |||
| 105 | return ret; | ||
| 106 | } | ||
| 107 | |||
| 108 | static void | ||
| 109 | nouveau_gpio_intr_fini(struct nvkm_event *event, int type, int index) | ||
| 110 | { | ||
| 111 | struct nouveau_gpio *gpio = container_of(event, typeof(*gpio), event); | ||
| 112 | const struct nouveau_gpio_impl *impl = (void *)nv_object(gpio)->oclass; | ||
| 113 | impl->intr_mask(gpio, type, 1 << index, 0); | ||
| 114 | } | ||
| 115 | |||
| 116 | static void | ||
| 117 | nouveau_gpio_intr_init(struct nvkm_event *event, int type, int index) | ||
| 118 | { | ||
| 119 | struct nouveau_gpio *gpio = container_of(event, typeof(*gpio), event); | ||
| 120 | const struct nouveau_gpio_impl *impl = (void *)nv_object(gpio)->oclass; | ||
| 121 | impl->intr_mask(gpio, type, 1 << index, 1 << index); | ||
| 122 | } | ||
| 123 | |||
| 124 | static int | ||
| 125 | nouveau_gpio_intr_ctor(struct nouveau_object *object, void *data, u32 size, | ||
| 126 | struct nvkm_notify *notify) | ||
| 127 | { | ||
| 128 | struct nvkm_gpio_ntfy_req *req = data; | ||
| 129 | if (!WARN_ON(size != sizeof(*req))) { | ||
| 130 | notify->size = sizeof(struct nvkm_gpio_ntfy_rep); | ||
| 131 | notify->types = req->mask; | ||
| 132 | notify->index = req->line; | ||
| 133 | return 0; | ||
| 134 | } | ||
| 135 | return -EINVAL; | ||
| 136 | } | ||
| 137 | |||
| 138 | static void | ||
| 139 | nouveau_gpio_intr(struct nouveau_subdev *subdev) | ||
| 140 | { | ||
| 141 | struct nouveau_gpio *gpio = nouveau_gpio(subdev); | ||
| 142 | const struct nouveau_gpio_impl *impl = (void *)nv_object(gpio)->oclass; | ||
| 143 | u32 hi, lo, i; | ||
| 144 | |||
| 145 | impl->intr_stat(gpio, &hi, &lo); | ||
| 146 | |||
| 147 | for (i = 0; (hi | lo) && i < impl->lines; i++) { | ||
| 148 | struct nvkm_gpio_ntfy_rep rep = { | ||
| 149 | .mask = (NVKM_GPIO_HI * !!(hi & (1 << i))) | | ||
| 150 | (NVKM_GPIO_LO * !!(lo & (1 << i))), | ||
| 151 | }; | ||
| 152 | nvkm_event_send(&gpio->event, rep.mask, i, &rep, sizeof(rep)); | ||
| 153 | } | ||
| 154 | } | ||
| 155 | |||
| 156 | static const struct nvkm_event_func | ||
| 157 | nouveau_gpio_intr_func = { | ||
| 158 | .ctor = nouveau_gpio_intr_ctor, | ||
| 159 | .init = nouveau_gpio_intr_init, | ||
| 160 | .fini = nouveau_gpio_intr_fini, | ||
| 161 | }; | ||
| 162 | |||
| 163 | int | ||
| 164 | _nouveau_gpio_fini(struct nouveau_object *object, bool suspend) | ||
| 165 | { | ||
| 166 | const struct nouveau_gpio_impl *impl = (void *)object->oclass; | ||
| 167 | struct nouveau_gpio *gpio = nouveau_gpio(object); | ||
| 168 | u32 mask = (1 << impl->lines) - 1; | ||
| 169 | |||
| 170 | impl->intr_mask(gpio, NVKM_GPIO_TOGGLED, mask, 0); | ||
| 171 | impl->intr_stat(gpio, &mask, &mask); | ||
| 172 | |||
| 173 | return nouveau_subdev_fini(&gpio->base, suspend); | ||
| 174 | } | ||
| 175 | |||
| 176 | static struct dmi_system_id gpio_reset_ids[] = { | ||
| 177 | { | ||
| 178 | .ident = "Apple Macbook 10,1", | ||
| 179 | .matches = { | ||
| 180 | DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), | ||
| 181 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro10,1"), | ||
| 182 | } | ||
| 183 | }, | ||
| 184 | { } | ||
| 185 | }; | ||
| 186 | |||
| 187 | int | ||
| 188 | _nouveau_gpio_init(struct nouveau_object *object) | ||
| 189 | { | ||
| 190 | struct nouveau_gpio *gpio = nouveau_gpio(object); | ||
| 191 | int ret; | ||
| 192 | |||
| 193 | ret = nouveau_subdev_init(&gpio->base); | ||
| 194 | if (ret) | ||
| 195 | return ret; | ||
| 196 | |||
| 197 | if (gpio->reset && dmi_check_system(gpio_reset_ids)) | ||
| 198 | gpio->reset(gpio, DCB_GPIO_UNUSED); | ||
| 199 | |||
| 200 | return ret; | ||
| 201 | } | ||
| 202 | |||
| 203 | void | ||
| 204 | _nouveau_gpio_dtor(struct nouveau_object *object) | ||
| 205 | { | ||
| 206 | struct nouveau_gpio *gpio = (void *)object; | ||
| 207 | nvkm_event_fini(&gpio->event); | ||
| 208 | nouveau_subdev_destroy(&gpio->base); | ||
| 209 | } | ||
| 210 | |||
| 211 | int | ||
| 212 | nouveau_gpio_create_(struct nouveau_object *parent, | ||
| 213 | struct nouveau_object *engine, | ||
| 214 | struct nouveau_oclass *oclass, | ||
| 215 | int length, void **pobject) | ||
| 216 | { | ||
| 217 | const struct nouveau_gpio_impl *impl = (void *)oclass; | ||
| 218 | struct nouveau_gpio *gpio; | ||
| 219 | int ret; | ||
| 220 | |||
| 221 | ret = nouveau_subdev_create_(parent, engine, oclass, 0, "GPIO", "gpio", | ||
| 222 | length, pobject); | ||
| 223 | gpio = *pobject; | ||
| 224 | if (ret) | ||
| 225 | return ret; | ||
| 226 | |||
| 227 | gpio->find = nouveau_gpio_find; | ||
| 228 | gpio->set = nouveau_gpio_set; | ||
| 229 | gpio->get = nouveau_gpio_get; | ||
| 230 | gpio->reset = impl->reset; | ||
| 231 | |||
| 232 | ret = nvkm_event_init(&nouveau_gpio_intr_func, 2, impl->lines, | ||
| 233 | &gpio->event); | ||
| 234 | if (ret) | ||
| 235 | return ret; | ||
| 236 | |||
| 237 | nv_subdev(gpio)->intr = nouveau_gpio_intr; | ||
| 238 | return 0; | ||
| 239 | } | ||
| 240 | |||
| 241 | int | ||
| 242 | _nouveau_gpio_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | ||
| 243 | struct nouveau_oclass *oclass, void *data, u32 size, | ||
| 244 | struct nouveau_object **pobject) | ||
| 245 | { | ||
| 246 | struct nouveau_gpio *gpio; | ||
| 247 | int ret; | ||
| 248 | |||
| 249 | ret = nouveau_gpio_create(parent, engine, oclass, &gpio); | ||
| 250 | *pobject = nv_object(gpio); | ||
| 251 | if (ret) | ||
| 252 | return ret; | ||
| 253 | |||
| 254 | return 0; | ||
| 255 | } | ||
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/nv10.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/nv10.c new file mode 100644 index 000000000000..27ad23eaf185 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/nv10.c | |||
| @@ -0,0 +1,116 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2009 Francisco Jerez. | ||
| 3 | * All Rights Reserved. | ||
| 4 | * | ||
| 5 | * Permission is hereby granted, free of charge, to any person obtaining | ||
| 6 | * a copy of this software and associated documentation files (the | ||
| 7 | * "Software"), to deal in the Software without restriction, including | ||
| 8 | * without limitation the rights to use, copy, modify, merge, publish, | ||
| 9 | * distribute, sublicense, and/or sell copies of the Software, and to | ||
| 10 | * permit persons to whom the Software is furnished to do so, subject to | ||
| 11 | * the following conditions: | ||
| 12 | * | ||
| 13 | * The above copyright notice and this permission notice (including the | ||
| 14 | * next paragraph) shall be included in all copies or substantial | ||
| 15 | * portions of the Software. | ||
| 16 | * | ||
| 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| 18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||
| 20 | * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE | ||
| 21 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||
| 22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||
| 23 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 24 | * | ||
| 25 | */ | ||
| 26 | |||
| 27 | #include "priv.h" | ||
| 28 | |||
| 29 | static int | ||
| 30 | nv10_gpio_sense(struct nouveau_gpio *gpio, int line) | ||
| 31 | { | ||
| 32 | if (line < 2) { | ||
| 33 | line = line * 16; | ||
| 34 | line = nv_rd32(gpio, 0x600818) >> line; | ||
| 35 | return !!(line & 0x0100); | ||
| 36 | } else | ||
| 37 | if (line < 10) { | ||
| 38 | line = (line - 2) * 4; | ||
| 39 | line = nv_rd32(gpio, 0x60081c) >> line; | ||
| 40 | return !!(line & 0x04); | ||
| 41 | } else | ||
| 42 | if (line < 14) { | ||
| 43 | line = (line - 10) * 4; | ||
| 44 | line = nv_rd32(gpio, 0x600850) >> line; | ||
| 45 | return !!(line & 0x04); | ||
| 46 | } | ||
| 47 | |||
| 48 | return -EINVAL; | ||
| 49 | } | ||
| 50 | |||
| 51 | static int | ||
| 52 | nv10_gpio_drive(struct nouveau_gpio *gpio, int line, int dir, int out) | ||
| 53 | { | ||
| 54 | u32 reg, mask, data; | ||
| 55 | |||
| 56 | if (line < 2) { | ||
| 57 | line = line * 16; | ||
| 58 | reg = 0x600818; | ||
| 59 | mask = 0x00000011; | ||
| 60 | data = (dir << 4) | out; | ||
| 61 | } else | ||
| 62 | if (line < 10) { | ||
| 63 | line = (line - 2) * 4; | ||
| 64 | reg = 0x60081c; | ||
| 65 | mask = 0x00000003; | ||
| 66 | data = (dir << 1) | out; | ||
| 67 | } else | ||
| 68 | if (line < 14) { | ||
| 69 | line = (line - 10) * 4; | ||
| 70 | reg = 0x600850; | ||
| 71 | mask = 0x00000003; | ||
| 72 | data = (dir << 1) | out; | ||
| 73 | } else { | ||
| 74 | return -EINVAL; | ||
| 75 | } | ||
| 76 | |||
| 77 | nv_mask(gpio, reg, mask << line, data << line); | ||
| 78 | return 0; | ||
| 79 | } | ||
| 80 | |||
| 81 | static void | ||
| 82 | nv10_gpio_intr_stat(struct nouveau_gpio *gpio, u32 *hi, u32 *lo) | ||
| 83 | { | ||
| 84 | u32 intr = nv_rd32(gpio, 0x001104); | ||
| 85 | u32 stat = nv_rd32(gpio, 0x001144) & intr; | ||
| 86 | *lo = (stat & 0xffff0000) >> 16; | ||
| 87 | *hi = (stat & 0x0000ffff); | ||
| 88 | nv_wr32(gpio, 0x001104, intr); | ||
| 89 | } | ||
| 90 | |||
| 91 | static void | ||
| 92 | nv10_gpio_intr_mask(struct nouveau_gpio *gpio, u32 type, u32 mask, u32 data) | ||
| 93 | { | ||
| 94 | u32 inte = nv_rd32(gpio, 0x001144); | ||
| 95 | if (type & NVKM_GPIO_LO) | ||
| 96 | inte = (inte & ~(mask << 16)) | (data << 16); | ||
| 97 | if (type & NVKM_GPIO_HI) | ||
| 98 | inte = (inte & ~mask) | data; | ||
| 99 | nv_wr32(gpio, 0x001144, inte); | ||
| 100 | } | ||
| 101 | |||
| 102 | struct nouveau_oclass * | ||
| 103 | nv10_gpio_oclass = &(struct nouveau_gpio_impl) { | ||
| 104 | .base.handle = NV_SUBDEV(GPIO, 0x10), | ||
| 105 | .base.ofuncs = &(struct nouveau_ofuncs) { | ||
| 106 | .ctor = _nouveau_gpio_ctor, | ||
| 107 | .dtor = _nouveau_gpio_dtor, | ||
| 108 | .init = _nouveau_gpio_init, | ||
| 109 | .fini = _nouveau_gpio_fini, | ||
| 110 | }, | ||
| 111 | .lines = 16, | ||
| 112 | .intr_stat = nv10_gpio_intr_stat, | ||
| 113 | .intr_mask = nv10_gpio_intr_mask, | ||
| 114 | .drive = nv10_gpio_drive, | ||
| 115 | .sense = nv10_gpio_sense, | ||
| 116 | }.base; | ||
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/nv50.c new file mode 100644 index 000000000000..2e30d5a62d6e --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/nv50.c | |||
| @@ -0,0 +1,129 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2012 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 "priv.h" | ||
| 26 | |||
| 27 | void | ||
| 28 | nv50_gpio_reset(struct nouveau_gpio *gpio, u8 match) | ||
| 29 | { | ||
| 30 | struct nouveau_bios *bios = nouveau_bios(gpio); | ||
| 31 | u8 ver, len; | ||
| 32 | u16 entry; | ||
| 33 | int ent = -1; | ||
| 34 | |||
| 35 | while ((entry = dcb_gpio_entry(bios, 0, ++ent, &ver, &len))) { | ||
| 36 | static const u32 regs[] = { 0xe100, 0xe28c }; | ||
| 37 | u32 data = nv_ro32(bios, entry); | ||
| 38 | u8 line = (data & 0x0000001f); | ||
| 39 | u8 func = (data & 0x0000ff00) >> 8; | ||
| 40 | u8 defs = !!(data & 0x01000000); | ||
| 41 | u8 unk0 = !!(data & 0x02000000); | ||
| 42 | u8 unk1 = !!(data & 0x04000000); | ||
| 43 | u32 val = (unk1 << 16) | unk0; | ||
| 44 | u32 reg = regs[line >> 4]; | ||
| 45 | u32 lsh = line & 0x0f; | ||
| 46 | |||
| 47 | if ( func == DCB_GPIO_UNUSED || | ||
| 48 | (match != DCB_GPIO_UNUSED && match != func)) | ||
| 49 | continue; | ||
| 50 | |||
| 51 | gpio->set(gpio, 0, func, line, defs); | ||
| 52 | |||
| 53 | nv_mask(gpio, reg, 0x00010001 << lsh, val << lsh); | ||
| 54 | } | ||
| 55 | } | ||
| 56 | |||
| 57 | int | ||
| 58 | nv50_gpio_location(int line, u32 *reg, u32 *shift) | ||
| 59 | { | ||
| 60 | const u32 nv50_gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 }; | ||
| 61 | |||
| 62 | if (line >= 32) | ||
| 63 | return -EINVAL; | ||
| 64 | |||
| 65 | *reg = nv50_gpio_reg[line >> 3]; | ||
| 66 | *shift = (line & 7) << 2; | ||
| 67 | return 0; | ||
| 68 | } | ||
| 69 | |||
| 70 | int | ||
| 71 | nv50_gpio_drive(struct nouveau_gpio *gpio, int line, int dir, int out) | ||
| 72 | { | ||
| 73 | u32 reg, shift; | ||
| 74 | |||
| 75 | if (nv50_gpio_location(line, ®, &shift)) | ||
| 76 | return -EINVAL; | ||
| 77 | |||
| 78 | nv_mask(gpio, reg, 3 << shift, (((dir ^ 1) << 1) | out) << shift); | ||
| 79 | return 0; | ||
| 80 | } | ||
| 81 | |||
| 82 | int | ||
| 83 | nv50_gpio_sense(struct nouveau_gpio *gpio, int line) | ||
| 84 | { | ||
| 85 | u32 reg, shift; | ||
| 86 | |||
| 87 | if (nv50_gpio_location(line, ®, &shift)) | ||
| 88 | return -EINVAL; | ||
| 89 | |||
| 90 | return !!(nv_rd32(gpio, reg) & (4 << shift)); | ||
| 91 | } | ||
| 92 | |||
| 93 | static void | ||
| 94 | nv50_gpio_intr_stat(struct nouveau_gpio *gpio, u32 *hi, u32 *lo) | ||
| 95 | { | ||
| 96 | u32 intr = nv_rd32(gpio, 0x00e054); | ||
| 97 | u32 stat = nv_rd32(gpio, 0x00e050) & intr; | ||
| 98 | *lo = (stat & 0xffff0000) >> 16; | ||
| 99 | *hi = (stat & 0x0000ffff); | ||
| 100 | nv_wr32(gpio, 0x00e054, intr); | ||
| 101 | } | ||
| 102 | |||
| 103 | static void | ||
| 104 | nv50_gpio_intr_mask(struct nouveau_gpio *gpio, u32 type, u32 mask, u32 data) | ||
| 105 | { | ||
| 106 | u32 inte = nv_rd32(gpio, 0x00e050); | ||
| 107 | if (type & NVKM_GPIO_LO) | ||
| 108 | inte = (inte & ~(mask << 16)) | (data << 16); | ||
| 109 | if (type & NVKM_GPIO_HI) | ||
| 110 | inte = (inte & ~mask) | data; | ||
| 111 | nv_wr32(gpio, 0x00e050, inte); | ||
| 112 | } | ||
| 113 | |||
| 114 | struct nouveau_oclass * | ||
| 115 | nv50_gpio_oclass = &(struct nouveau_gpio_impl) { | ||
| 116 | .base.handle = NV_SUBDEV(GPIO, 0x50), | ||
| 117 | .base.ofuncs = &(struct nouveau_ofuncs) { | ||
| 118 | .ctor = _nouveau_gpio_ctor, | ||
| 119 | .dtor = _nouveau_gpio_dtor, | ||
| 120 | .init = _nouveau_gpio_init, | ||
| 121 | .fini = _nouveau_gpio_fini, | ||
| 122 | }, | ||
| 123 | .lines = 16, | ||
| 124 | .intr_stat = nv50_gpio_intr_stat, | ||
| 125 | .intr_mask = nv50_gpio_intr_mask, | ||
| 126 | .drive = nv50_gpio_drive, | ||
| 127 | .sense = nv50_gpio_sense, | ||
| 128 | .reset = nv50_gpio_reset, | ||
| 129 | }.base; | ||
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/nv94.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/nv94.c new file mode 100644 index 000000000000..cae404ccadac --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/nv94.c | |||
| @@ -0,0 +1,74 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2012 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 "priv.h" | ||
| 26 | |||
| 27 | void | ||
| 28 | nv94_gpio_intr_stat(struct nouveau_gpio *gpio, u32 *hi, u32 *lo) | ||
| 29 | { | ||
| 30 | u32 intr0 = nv_rd32(gpio, 0x00e054); | ||
| 31 | u32 intr1 = nv_rd32(gpio, 0x00e074); | ||
| 32 | u32 stat0 = nv_rd32(gpio, 0x00e050) & intr0; | ||
| 33 | u32 stat1 = nv_rd32(gpio, 0x00e070) & intr1; | ||
| 34 | *lo = (stat1 & 0xffff0000) | (stat0 >> 16); | ||
| 35 | *hi = (stat1 << 16) | (stat0 & 0x0000ffff); | ||
| 36 | nv_wr32(gpio, 0x00e054, intr0); | ||
| 37 | nv_wr32(gpio, 0x00e074, intr1); | ||
| 38 | } | ||
| 39 | |||
| 40 | void | ||
| 41 | nv94_gpio_intr_mask(struct nouveau_gpio *gpio, u32 type, u32 mask, u32 data) | ||
| 42 | { | ||
| 43 | u32 inte0 = nv_rd32(gpio, 0x00e050); | ||
| 44 | u32 inte1 = nv_rd32(gpio, 0x00e070); | ||
| 45 | if (type & NVKM_GPIO_LO) | ||
| 46 | inte0 = (inte0 & ~(mask << 16)) | (data << 16); | ||
| 47 | if (type & NVKM_GPIO_HI) | ||
| 48 | inte0 = (inte0 & ~(mask & 0xffff)) | (data & 0xffff); | ||
| 49 | mask >>= 16; | ||
| 50 | data >>= 16; | ||
| 51 | if (type & NVKM_GPIO_LO) | ||
| 52 | inte1 = (inte1 & ~(mask << 16)) | (data << 16); | ||
| 53 | if (type & NVKM_GPIO_HI) | ||
| 54 | inte1 = (inte1 & ~mask) | data; | ||
| 55 | nv_wr32(gpio, 0x00e050, inte0); | ||
| 56 | nv_wr32(gpio, 0x00e070, inte1); | ||
| 57 | } | ||
| 58 | |||
| 59 | struct nouveau_oclass * | ||
| 60 | nv94_gpio_oclass = &(struct nouveau_gpio_impl) { | ||
| 61 | .base.handle = NV_SUBDEV(GPIO, 0x94), | ||
| 62 | .base.ofuncs = &(struct nouveau_ofuncs) { | ||
| 63 | .ctor = _nouveau_gpio_ctor, | ||
| 64 | .dtor = _nouveau_gpio_dtor, | ||
| 65 | .init = _nouveau_gpio_init, | ||
| 66 | .fini = _nouveau_gpio_fini, | ||
| 67 | }, | ||
| 68 | .lines = 32, | ||
| 69 | .intr_stat = nv94_gpio_intr_stat, | ||
| 70 | .intr_mask = nv94_gpio_intr_mask, | ||
| 71 | .drive = nv50_gpio_drive, | ||
| 72 | .sense = nv50_gpio_sense, | ||
| 73 | .reset = nv50_gpio_reset, | ||
| 74 | }.base; | ||
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/nvd0.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/nvd0.c new file mode 100644 index 000000000000..480d6d2af770 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/nvd0.c | |||
| @@ -0,0 +1,85 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2012 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 "priv.h" | ||
| 26 | |||
| 27 | void | ||
| 28 | nvd0_gpio_reset(struct nouveau_gpio *gpio, u8 match) | ||
| 29 | { | ||
| 30 | struct nouveau_bios *bios = nouveau_bios(gpio); | ||
| 31 | u8 ver, len; | ||
| 32 | u16 entry; | ||
| 33 | int ent = -1; | ||
| 34 | |||
| 35 | while ((entry = dcb_gpio_entry(bios, 0, ++ent, &ver, &len))) { | ||
| 36 | u32 data = nv_ro32(bios, entry); | ||
| 37 | u8 line = (data & 0x0000003f); | ||
| 38 | u8 defs = !!(data & 0x00000080); | ||
| 39 | u8 func = (data & 0x0000ff00) >> 8; | ||
| 40 | u8 unk0 = (data & 0x00ff0000) >> 16; | ||
| 41 | u8 unk1 = (data & 0x1f000000) >> 24; | ||
| 42 | |||
| 43 | if ( func == DCB_GPIO_UNUSED || | ||
| 44 | (match != DCB_GPIO_UNUSED && match != func)) | ||
| 45 | continue; | ||
| 46 | |||
| 47 | gpio->set(gpio, 0, func, line, defs); | ||
| 48 | |||
| 49 | nv_mask(gpio, 0x00d610 + (line * 4), 0xff, unk0); | ||
| 50 | if (unk1--) | ||
| 51 | nv_mask(gpio, 0x00d740 + (unk1 * 4), 0xff, line); | ||
| 52 | } | ||
| 53 | } | ||
| 54 | |||
| 55 | int | ||
| 56 | nvd0_gpio_drive(struct nouveau_gpio *gpio, int line, int dir, int out) | ||
| 57 | { | ||
| 58 | u32 data = ((dir ^ 1) << 13) | (out << 12); | ||
| 59 | nv_mask(gpio, 0x00d610 + (line * 4), 0x00003000, data); | ||
| 60 | nv_mask(gpio, 0x00d604, 0x00000001, 0x00000001); /* update? */ | ||
| 61 | return 0; | ||
| 62 | } | ||
| 63 | |||
| 64 | int | ||
| 65 | nvd0_gpio_sense(struct nouveau_gpio *gpio, int line) | ||
| 66 | { | ||
| 67 | return !!(nv_rd32(gpio, 0x00d610 + (line * 4)) & 0x00004000); | ||
| 68 | } | ||
| 69 | |||
| 70 | struct nouveau_oclass * | ||
| 71 | nvd0_gpio_oclass = &(struct nouveau_gpio_impl) { | ||
| 72 | .base.handle = NV_SUBDEV(GPIO, 0xd0), | ||
| 73 | .base.ofuncs = &(struct nouveau_ofuncs) { | ||
| 74 | .ctor = _nouveau_gpio_ctor, | ||
| 75 | .dtor = _nouveau_gpio_dtor, | ||
| 76 | .init = _nouveau_gpio_init, | ||
| 77 | .fini = _nouveau_gpio_fini, | ||
| 78 | }, | ||
| 79 | .lines = 32, | ||
| 80 | .intr_stat = nv94_gpio_intr_stat, | ||
| 81 | .intr_mask = nv94_gpio_intr_mask, | ||
| 82 | .drive = nvd0_gpio_drive, | ||
| 83 | .sense = nvd0_gpio_sense, | ||
| 84 | .reset = nvd0_gpio_reset, | ||
| 85 | }.base; | ||
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/nve0.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/nve0.c new file mode 100644 index 000000000000..e1145b48c76c --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/nve0.c | |||
| @@ -0,0 +1,74 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2012 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 "priv.h" | ||
| 26 | |||
| 27 | static void | ||
| 28 | nve0_gpio_intr_stat(struct nouveau_gpio *gpio, u32 *hi, u32 *lo) | ||
| 29 | { | ||
| 30 | u32 intr0 = nv_rd32(gpio, 0x00dc00); | ||
| 31 | u32 intr1 = nv_rd32(gpio, 0x00dc80); | ||
| 32 | u32 stat0 = nv_rd32(gpio, 0x00dc08) & intr0; | ||
| 33 | u32 stat1 = nv_rd32(gpio, 0x00dc88) & intr1; | ||
| 34 | *lo = (stat1 & 0xffff0000) | (stat0 >> 16); | ||
| 35 | *hi = (stat1 << 16) | (stat0 & 0x0000ffff); | ||
| 36 | nv_wr32(gpio, 0x00dc00, intr0); | ||
| 37 | nv_wr32(gpio, 0x00dc80, intr1); | ||
| 38 | } | ||
| 39 | |||
| 40 | void | ||
| 41 | nve0_gpio_intr_mask(struct nouveau_gpio *gpio, u32 type, u32 mask, u32 data) | ||
| 42 | { | ||
| 43 | u32 inte0 = nv_rd32(gpio, 0x00dc08); | ||
| 44 | u32 inte1 = nv_rd32(gpio, 0x00dc88); | ||
| 45 | if (type & NVKM_GPIO_LO) | ||
| 46 | inte0 = (inte0 & ~(mask << 16)) | (data << 16); | ||
| 47 | if (type & NVKM_GPIO_HI) | ||
| 48 | inte0 = (inte0 & ~(mask & 0xffff)) | (data & 0xffff); | ||
| 49 | mask >>= 16; | ||
| 50 | data >>= 16; | ||
| 51 | if (type & NVKM_GPIO_LO) | ||
| 52 | inte1 = (inte1 & ~(mask << 16)) | (data << 16); | ||
| 53 | if (type & NVKM_GPIO_HI) | ||
| 54 | inte1 = (inte1 & ~mask) | data; | ||
| 55 | nv_wr32(gpio, 0x00dc08, inte0); | ||
| 56 | nv_wr32(gpio, 0x00dc88, inte1); | ||
| 57 | } | ||
| 58 | |||
| 59 | struct nouveau_oclass * | ||
| 60 | nve0_gpio_oclass = &(struct nouveau_gpio_impl) { | ||
| 61 | .base.handle = NV_SUBDEV(GPIO, 0xe0), | ||
| 62 | .base.ofuncs = &(struct nouveau_ofuncs) { | ||
| 63 | .ctor = _nouveau_gpio_ctor, | ||
| 64 | .dtor = _nouveau_gpio_dtor, | ||
| 65 | .init = _nouveau_gpio_init, | ||
| 66 | .fini = _nouveau_gpio_fini, | ||
| 67 | }, | ||
| 68 | .lines = 32, | ||
| 69 | .intr_stat = nve0_gpio_intr_stat, | ||
| 70 | .intr_mask = nve0_gpio_intr_mask, | ||
| 71 | .drive = nvd0_gpio_drive, | ||
| 72 | .sense = nvd0_gpio_sense, | ||
| 73 | .reset = nvd0_gpio_reset, | ||
| 74 | }.base; | ||
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/priv.h new file mode 100644 index 000000000000..bff98b86e2b5 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/priv.h | |||
| @@ -0,0 +1,67 @@ | |||
| 1 | #ifndef __NVKM_GPIO_H__ | ||
| 2 | #define __NVKM_GPIO_H__ | ||
| 3 | |||
| 4 | #include <subdev/gpio.h> | ||
| 5 | |||
| 6 | #define nouveau_gpio_create(p,e,o,d) \ | ||
| 7 | nouveau_gpio_create_((p), (e), (o), sizeof(**d), (void **)d) | ||
| 8 | #define nouveau_gpio_destroy(p) ({ \ | ||
| 9 | struct nouveau_gpio *gpio = (p); \ | ||
| 10 | _nouveau_gpio_dtor(nv_object(gpio)); \ | ||
| 11 | }) | ||
| 12 | #define nouveau_gpio_init(p) ({ \ | ||
| 13 | struct nouveau_gpio *gpio = (p); \ | ||
| 14 | _nouveau_gpio_init(nv_object(gpio)); \ | ||
| 15 | }) | ||
| 16 | #define nouveau_gpio_fini(p,s) ({ \ | ||
| 17 | struct nouveau_gpio *gpio = (p); \ | ||
| 18 | _nouveau_gpio_fini(nv_object(gpio), (s)); \ | ||
| 19 | }) | ||
| 20 | |||
| 21 | int nouveau_gpio_create_(struct nouveau_object *, struct nouveau_object *, | ||
| 22 | struct nouveau_oclass *, int, void **); | ||
| 23 | int _nouveau_gpio_ctor(struct nouveau_object *, struct nouveau_object *, | ||
| 24 | struct nouveau_oclass *, void *, u32, | ||
| 25 | struct nouveau_object **); | ||
| 26 | void _nouveau_gpio_dtor(struct nouveau_object *); | ||
| 27 | int _nouveau_gpio_init(struct nouveau_object *); | ||
| 28 | int _nouveau_gpio_fini(struct nouveau_object *, bool); | ||
| 29 | |||
| 30 | struct nouveau_gpio_impl { | ||
| 31 | struct nouveau_oclass base; | ||
| 32 | int lines; | ||
| 33 | |||
| 34 | /* read and ack pending interrupts, returning only data | ||
| 35 | * for lines that have not been masked off, while still | ||
| 36 | * performing the ack for anything that was pending. | ||
| 37 | */ | ||
| 38 | void (*intr_stat)(struct nouveau_gpio *, u32 *, u32 *); | ||
| 39 | |||
| 40 | /* mask on/off interrupts for hi/lo transitions on a | ||
| 41 | * given set of gpio lines | ||
| 42 | */ | ||
| 43 | void (*intr_mask)(struct nouveau_gpio *, u32, u32, u32); | ||
| 44 | |||
| 45 | /* configure gpio direction and output value */ | ||
| 46 | int (*drive)(struct nouveau_gpio *, int line, int dir, int out); | ||
| 47 | |||
| 48 | /* sense current state of given gpio line */ | ||
| 49 | int (*sense)(struct nouveau_gpio *, int line); | ||
| 50 | |||
| 51 | /*XXX*/ | ||
| 52 | void (*reset)(struct nouveau_gpio *, u8); | ||
| 53 | }; | ||
| 54 | |||
| 55 | void nv50_gpio_reset(struct nouveau_gpio *, u8); | ||
| 56 | int nv50_gpio_drive(struct nouveau_gpio *, int, int, int); | ||
| 57 | int nv50_gpio_sense(struct nouveau_gpio *, int); | ||
| 58 | |||
| 59 | void nv94_gpio_intr_stat(struct nouveau_gpio *, u32 *, u32 *); | ||
| 60 | void nv94_gpio_intr_mask(struct nouveau_gpio *, u32, u32, u32); | ||
| 61 | |||
| 62 | void nvd0_gpio_reset(struct nouveau_gpio *, u8); | ||
| 63 | int nvd0_gpio_drive(struct nouveau_gpio *, int, int, int); | ||
| 64 | int nvd0_gpio_sense(struct nouveau_gpio *, int); | ||
| 65 | |||
| 66 | |||
| 67 | #endif | ||
