aboutsummaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/nouveau/nvkm/subdev/gpio
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/nouveau/nvkm/subdev/gpio')
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/gpio/Kbuild2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/gpio/base.c147
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/gpio/g94.c41
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/gpio/gf119.c (renamed from drivers/gpu/drm/nouveau/nvkm/subdev/gpio/gf110.c)50
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/gpio/gk104.c47
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/gpio/nv10.c41
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/gpio/nv50.c46
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/gpio/priv.h37
8 files changed, 187 insertions, 224 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/Kbuild
index ea42a9ed1821..e52c5e87f242 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/Kbuild
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/Kbuild
@@ -2,5 +2,5 @@ nvkm-y += nvkm/subdev/gpio/base.o
nvkm-y += nvkm/subdev/gpio/nv10.o
nvkm-y += nvkm/subdev/gpio/nv50.o
nvkm-y += nvkm/subdev/gpio/g94.o
-nvkm-y += nvkm/subdev/gpio/gf110.o
+nvkm-y += nvkm/subdev/gpio/gf119.o
nvkm-y += nvkm/subdev/gpio/gk104.o
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/base.c
index dea58161ba46..d45ec99f0e38 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/base.c
@@ -23,28 +23,33 @@
*/
#include "priv.h"
-#include <core/device.h>
#include <core/notify.h>
static int
nvkm_gpio_drive(struct nvkm_gpio *gpio, int idx, int line, int dir, int out)
{
- const struct nvkm_gpio_impl *impl = (void *)nv_object(gpio)->oclass;
- return impl->drive ? impl->drive(gpio, line, dir, out) : -ENODEV;
+ return gpio->func->drive(gpio, line, dir, out);
}
static int
nvkm_gpio_sense(struct nvkm_gpio *gpio, int idx, int line)
{
- const struct nvkm_gpio_impl *impl = (void *)nv_object(gpio)->oclass;
- return impl->sense ? impl->sense(gpio, line) : -ENODEV;
+ return gpio->func->sense(gpio, line);
}
-static int
+void
+nvkm_gpio_reset(struct nvkm_gpio *gpio, u8 func)
+{
+ if (gpio->func->reset)
+ gpio->func->reset(gpio, func);
+}
+
+int
nvkm_gpio_find(struct nvkm_gpio *gpio, int idx, u8 tag, u8 line,
struct dcb_gpio_func *func)
{
- struct nvkm_bios *bios = nvkm_bios(gpio);
+ struct nvkm_device *device = gpio->subdev.device;
+ struct nvkm_bios *bios = device->bios;
u8 ver, len;
u16 data;
@@ -56,11 +61,11 @@ nvkm_gpio_find(struct nvkm_gpio *gpio, int idx, u8 tag, u8 line,
return 0;
/* Apple iMac G4 NV18 */
- if (nv_device_match(nv_object(gpio), 0x0189, 0x10de, 0x0010)) {
+ if (device->quirk && device->quirk->tv_gpio) {
if (tag == DCB_GPIO_TVDAC0) {
*func = (struct dcb_gpio_func) {
.func = DCB_GPIO_TVDAC0,
- .line = 4,
+ .line = device->quirk->tv_gpio,
.log[0] = 0,
.log[1] = 1,
};
@@ -71,7 +76,7 @@ nvkm_gpio_find(struct nvkm_gpio *gpio, int idx, u8 tag, u8 line,
return -ENOENT;
}
-static int
+int
nvkm_gpio_set(struct nvkm_gpio *gpio, int idx, u8 tag, u8 line, int state)
{
struct dcb_gpio_func func;
@@ -87,7 +92,7 @@ nvkm_gpio_set(struct nvkm_gpio *gpio, int idx, u8 tag, u8 line, int state)
return ret;
}
-static int
+int
nvkm_gpio_get(struct nvkm_gpio *gpio, int idx, u8 tag, u8 line)
{
struct dcb_gpio_func func;
@@ -107,16 +112,14 @@ static void
nvkm_gpio_intr_fini(struct nvkm_event *event, int type, int index)
{
struct nvkm_gpio *gpio = container_of(event, typeof(*gpio), event);
- const struct nvkm_gpio_impl *impl = (void *)nv_object(gpio)->oclass;
- impl->intr_mask(gpio, type, 1 << index, 0);
+ gpio->func->intr_mask(gpio, type, 1 << index, 0);
}
static void
nvkm_gpio_intr_init(struct nvkm_event *event, int type, int index)
{
struct nvkm_gpio *gpio = container_of(event, typeof(*gpio), event);
- const struct nvkm_gpio_impl *impl = (void *)nv_object(gpio)->oclass;
- impl->intr_mask(gpio, type, 1 << index, 1 << index);
+ gpio->func->intr_mask(gpio, type, 1 << index, 1 << index);
}
static int
@@ -133,16 +136,22 @@ nvkm_gpio_intr_ctor(struct nvkm_object *object, void *data, u32 size,
return -EINVAL;
}
+static const struct nvkm_event_func
+nvkm_gpio_intr_func = {
+ .ctor = nvkm_gpio_intr_ctor,
+ .init = nvkm_gpio_intr_init,
+ .fini = nvkm_gpio_intr_fini,
+};
+
static void
nvkm_gpio_intr(struct nvkm_subdev *subdev)
{
struct nvkm_gpio *gpio = nvkm_gpio(subdev);
- const struct nvkm_gpio_impl *impl = (void *)nv_object(gpio)->oclass;
u32 hi, lo, i;
- impl->intr_stat(gpio, &hi, &lo);
+ gpio->func->intr_stat(gpio, &hi, &lo);
- for (i = 0; (hi | lo) && i < impl->lines; i++) {
+ for (i = 0; (hi | lo) && i < gpio->func->lines; i++) {
struct nvkm_gpio_ntfy_rep rep = {
.mask = (NVKM_GPIO_HI * !!(hi & (1 << i))) |
(NVKM_GPIO_LO * !!(lo & (1 << i))),
@@ -151,24 +160,15 @@ nvkm_gpio_intr(struct nvkm_subdev *subdev)
}
}
-static const struct nvkm_event_func
-nvkm_gpio_intr_func = {
- .ctor = nvkm_gpio_intr_ctor,
- .init = nvkm_gpio_intr_init,
- .fini = nvkm_gpio_intr_fini,
-};
-
-int
-_nvkm_gpio_fini(struct nvkm_object *object, bool suspend)
+static int
+nvkm_gpio_fini(struct nvkm_subdev *subdev, bool suspend)
{
- const struct nvkm_gpio_impl *impl = (void *)object->oclass;
- struct nvkm_gpio *gpio = nvkm_gpio(object);
- u32 mask = (1 << impl->lines) - 1;
-
- impl->intr_mask(gpio, NVKM_GPIO_TOGGLED, mask, 0);
- impl->intr_stat(gpio, &mask, &mask);
+ struct nvkm_gpio *gpio = nvkm_gpio(subdev);
+ u32 mask = (1 << gpio->func->lines) - 1;
- return nvkm_subdev_fini(&gpio->base, suspend);
+ gpio->func->intr_mask(gpio, NVKM_GPIO_TOGGLED, mask, 0);
+ gpio->func->intr_stat(gpio, &mask, &mask);
+ return 0;
}
static struct dmi_system_id gpio_reset_ids[] = {
@@ -182,70 +182,43 @@ static struct dmi_system_id gpio_reset_ids[] = {
{ }
};
-int
-_nvkm_gpio_init(struct nvkm_object *object)
+static int
+nvkm_gpio_init(struct nvkm_subdev *subdev)
{
- struct nvkm_gpio *gpio = nvkm_gpio(object);
- int ret;
-
- ret = nvkm_subdev_init(&gpio->base);
- if (ret)
- return ret;
-
- if (gpio->reset && dmi_check_system(gpio_reset_ids))
- gpio->reset(gpio, DCB_GPIO_UNUSED);
-
- return ret;
+ struct nvkm_gpio *gpio = nvkm_gpio(subdev);
+ if (dmi_check_system(gpio_reset_ids))
+ nvkm_gpio_reset(gpio, DCB_GPIO_UNUSED);
+ return 0;
}
-void
-_nvkm_gpio_dtor(struct nvkm_object *object)
+static void *
+nvkm_gpio_dtor(struct nvkm_subdev *subdev)
{
- struct nvkm_gpio *gpio = (void *)object;
+ struct nvkm_gpio *gpio = nvkm_gpio(subdev);
nvkm_event_fini(&gpio->event);
- nvkm_subdev_destroy(&gpio->base);
+ return gpio;
}
-int
-nvkm_gpio_create_(struct nvkm_object *parent, struct nvkm_object *engine,
- struct nvkm_oclass *oclass, int length, void **pobject)
-{
- const struct nvkm_gpio_impl *impl = (void *)oclass;
- struct nvkm_gpio *gpio;
- int ret;
-
- ret = nvkm_subdev_create_(parent, engine, oclass, 0, "GPIO",
- "gpio", length, pobject);
- gpio = *pobject;
- if (ret)
- return ret;
-
- gpio->find = nvkm_gpio_find;
- gpio->set = nvkm_gpio_set;
- gpio->get = nvkm_gpio_get;
- gpio->reset = impl->reset;
-
- ret = nvkm_event_init(&nvkm_gpio_intr_func, 2, impl->lines,
- &gpio->event);
- if (ret)
- return ret;
-
- nv_subdev(gpio)->intr = nvkm_gpio_intr;
- return 0;
-}
+static const struct nvkm_subdev_func
+nvkm_gpio = {
+ .dtor = nvkm_gpio_dtor,
+ .init = nvkm_gpio_init,
+ .fini = nvkm_gpio_fini,
+ .intr = nvkm_gpio_intr,
+};
int
-_nvkm_gpio_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
- struct nvkm_oclass *oclass, void *data, u32 size,
- struct nvkm_object **pobject)
+nvkm_gpio_new_(const struct nvkm_gpio_func *func, struct nvkm_device *device,
+ int index, struct nvkm_gpio **pgpio)
{
struct nvkm_gpio *gpio;
- int ret;
- ret = nvkm_gpio_create(parent, engine, oclass, &gpio);
- *pobject = nv_object(gpio);
- if (ret)
- return ret;
+ if (!(gpio = *pgpio = kzalloc(sizeof(*gpio), GFP_KERNEL)))
+ return -ENOMEM;
- return 0;
+ nvkm_subdev_ctor(&nvkm_gpio, device, index, 0, &gpio->subdev);
+ gpio->func = func;
+
+ return nvkm_event_init(&nvkm_gpio_intr_func, 2, func->lines,
+ &gpio->event);
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/g94.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/g94.c
index 12b3e01fca8e..6dcda55fb865 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/g94.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/g94.c
@@ -26,21 +26,23 @@
void
g94_gpio_intr_stat(struct nvkm_gpio *gpio, u32 *hi, u32 *lo)
{
- u32 intr0 = nv_rd32(gpio, 0x00e054);
- u32 intr1 = nv_rd32(gpio, 0x00e074);
- u32 stat0 = nv_rd32(gpio, 0x00e050) & intr0;
- u32 stat1 = nv_rd32(gpio, 0x00e070) & intr1;
+ struct nvkm_device *device = gpio->subdev.device;
+ u32 intr0 = nvkm_rd32(device, 0x00e054);
+ u32 intr1 = nvkm_rd32(device, 0x00e074);
+ u32 stat0 = nvkm_rd32(device, 0x00e050) & intr0;
+ u32 stat1 = nvkm_rd32(device, 0x00e070) & intr1;
*lo = (stat1 & 0xffff0000) | (stat0 >> 16);
*hi = (stat1 << 16) | (stat0 & 0x0000ffff);
- nv_wr32(gpio, 0x00e054, intr0);
- nv_wr32(gpio, 0x00e074, intr1);
+ nvkm_wr32(device, 0x00e054, intr0);
+ nvkm_wr32(device, 0x00e074, intr1);
}
void
g94_gpio_intr_mask(struct nvkm_gpio *gpio, u32 type, u32 mask, u32 data)
{
- u32 inte0 = nv_rd32(gpio, 0x00e050);
- u32 inte1 = nv_rd32(gpio, 0x00e070);
+ struct nvkm_device *device = gpio->subdev.device;
+ u32 inte0 = nvkm_rd32(device, 0x00e050);
+ u32 inte1 = nvkm_rd32(device, 0x00e070);
if (type & NVKM_GPIO_LO)
inte0 = (inte0 & ~(mask << 16)) | (data << 16);
if (type & NVKM_GPIO_HI)
@@ -51,23 +53,22 @@ g94_gpio_intr_mask(struct nvkm_gpio *gpio, u32 type, u32 mask, u32 data)
inte1 = (inte1 & ~(mask << 16)) | (data << 16);
if (type & NVKM_GPIO_HI)
inte1 = (inte1 & ~mask) | data;
- nv_wr32(gpio, 0x00e050, inte0);
- nv_wr32(gpio, 0x00e070, inte1);
+ nvkm_wr32(device, 0x00e050, inte0);
+ nvkm_wr32(device, 0x00e070, inte1);
}
-struct nvkm_oclass *
-g94_gpio_oclass = &(struct nvkm_gpio_impl) {
- .base.handle = NV_SUBDEV(GPIO, 0x94),
- .base.ofuncs = &(struct nvkm_ofuncs) {
- .ctor = _nvkm_gpio_ctor,
- .dtor = _nvkm_gpio_dtor,
- .init = _nvkm_gpio_init,
- .fini = _nvkm_gpio_fini,
- },
+static const struct nvkm_gpio_func
+g94_gpio = {
.lines = 32,
.intr_stat = g94_gpio_intr_stat,
.intr_mask = g94_gpio_intr_mask,
.drive = nv50_gpio_drive,
.sense = nv50_gpio_sense,
.reset = nv50_gpio_reset,
-}.base;
+};
+
+int
+g94_gpio_new(struct nvkm_device *device, int index, struct nvkm_gpio **pgpio)
+{
+ return nvkm_gpio_new_(&g94_gpio, device, index, pgpio);
+}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/gf110.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/gf119.c
index 2c3bb255d1f8..bb7400dfaef8 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/gf110.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/gf119.c
@@ -24,15 +24,16 @@
#include "priv.h"
void
-gf110_gpio_reset(struct nvkm_gpio *gpio, u8 match)
+gf119_gpio_reset(struct nvkm_gpio *gpio, u8 match)
{
- struct nvkm_bios *bios = nvkm_bios(gpio);
+ struct nvkm_device *device = gpio->subdev.device;
+ struct nvkm_bios *bios = device->bios;
u8 ver, len;
u16 entry;
int ent = -1;
while ((entry = dcb_gpio_entry(bios, 0, ++ent, &ver, &len))) {
- u32 data = nv_ro32(bios, entry);
+ u32 data = nvbios_rd32(bios, entry);
u8 line = (data & 0x0000003f);
u8 defs = !!(data & 0x00000080);
u8 func = (data & 0x0000ff00) >> 8;
@@ -43,42 +44,43 @@ gf110_gpio_reset(struct nvkm_gpio *gpio, u8 match)
(match != DCB_GPIO_UNUSED && match != func))
continue;
- gpio->set(gpio, 0, func, line, defs);
+ nvkm_gpio_set(gpio, 0, func, line, defs);
- nv_mask(gpio, 0x00d610 + (line * 4), 0xff, unk0);
+ nvkm_mask(device, 0x00d610 + (line * 4), 0xff, unk0);
if (unk1--)
- nv_mask(gpio, 0x00d740 + (unk1 * 4), 0xff, line);
+ nvkm_mask(device, 0x00d740 + (unk1 * 4), 0xff, line);
}
}
int
-gf110_gpio_drive(struct nvkm_gpio *gpio, int line, int dir, int out)
+gf119_gpio_drive(struct nvkm_gpio *gpio, int line, int dir, int out)
{
+ struct nvkm_device *device = gpio->subdev.device;
u32 data = ((dir ^ 1) << 13) | (out << 12);
- nv_mask(gpio, 0x00d610 + (line * 4), 0x00003000, data);
- nv_mask(gpio, 0x00d604, 0x00000001, 0x00000001); /* update? */
+ nvkm_mask(device, 0x00d610 + (line * 4), 0x00003000, data);
+ nvkm_mask(device, 0x00d604, 0x00000001, 0x00000001); /* update? */
return 0;
}
int
-gf110_gpio_sense(struct nvkm_gpio *gpio, int line)
+gf119_gpio_sense(struct nvkm_gpio *gpio, int line)
{
- return !!(nv_rd32(gpio, 0x00d610 + (line * 4)) & 0x00004000);
+ struct nvkm_device *device = gpio->subdev.device;
+ return !!(nvkm_rd32(device, 0x00d610 + (line * 4)) & 0x00004000);
}
-struct nvkm_oclass *
-gf110_gpio_oclass = &(struct nvkm_gpio_impl) {
- .base.handle = NV_SUBDEV(GPIO, 0xd0),
- .base.ofuncs = &(struct nvkm_ofuncs) {
- .ctor = _nvkm_gpio_ctor,
- .dtor = _nvkm_gpio_dtor,
- .init = _nvkm_gpio_init,
- .fini = _nvkm_gpio_fini,
- },
+static const struct nvkm_gpio_func
+gf119_gpio = {
.lines = 32,
.intr_stat = g94_gpio_intr_stat,
.intr_mask = g94_gpio_intr_mask,
- .drive = gf110_gpio_drive,
- .sense = gf110_gpio_sense,
- .reset = gf110_gpio_reset,
-}.base;
+ .drive = gf119_gpio_drive,
+ .sense = gf119_gpio_sense,
+ .reset = gf119_gpio_reset,
+};
+
+int
+gf119_gpio_new(struct nvkm_device *device, int index, struct nvkm_gpio **pgpio)
+{
+ return nvkm_gpio_new_(&gf119_gpio, device, index, pgpio);
+}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/gk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/gk104.c
index 42fd2faaaa4f..3f45afd17d5a 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/gk104.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/gk104.c
@@ -26,21 +26,23 @@
static void
gk104_gpio_intr_stat(struct nvkm_gpio *gpio, u32 *hi, u32 *lo)
{
- u32 intr0 = nv_rd32(gpio, 0x00dc00);
- u32 intr1 = nv_rd32(gpio, 0x00dc80);
- u32 stat0 = nv_rd32(gpio, 0x00dc08) & intr0;
- u32 stat1 = nv_rd32(gpio, 0x00dc88) & intr1;
+ struct nvkm_device *device = gpio->subdev.device;
+ u32 intr0 = nvkm_rd32(device, 0x00dc00);
+ u32 intr1 = nvkm_rd32(device, 0x00dc80);
+ u32 stat0 = nvkm_rd32(device, 0x00dc08) & intr0;
+ u32 stat1 = nvkm_rd32(device, 0x00dc88) & intr1;
*lo = (stat1 & 0xffff0000) | (stat0 >> 16);
*hi = (stat1 << 16) | (stat0 & 0x0000ffff);
- nv_wr32(gpio, 0x00dc00, intr0);
- nv_wr32(gpio, 0x00dc80, intr1);
+ nvkm_wr32(device, 0x00dc00, intr0);
+ nvkm_wr32(device, 0x00dc80, intr1);
}
void
gk104_gpio_intr_mask(struct nvkm_gpio *gpio, u32 type, u32 mask, u32 data)
{
- u32 inte0 = nv_rd32(gpio, 0x00dc08);
- u32 inte1 = nv_rd32(gpio, 0x00dc88);
+ struct nvkm_device *device = gpio->subdev.device;
+ u32 inte0 = nvkm_rd32(device, 0x00dc08);
+ u32 inte1 = nvkm_rd32(device, 0x00dc88);
if (type & NVKM_GPIO_LO)
inte0 = (inte0 & ~(mask << 16)) | (data << 16);
if (type & NVKM_GPIO_HI)
@@ -51,23 +53,22 @@ gk104_gpio_intr_mask(struct nvkm_gpio *gpio, u32 type, u32 mask, u32 data)
inte1 = (inte1 & ~(mask << 16)) | (data << 16);
if (type & NVKM_GPIO_HI)
inte1 = (inte1 & ~mask) | data;
- nv_wr32(gpio, 0x00dc08, inte0);
- nv_wr32(gpio, 0x00dc88, inte1);
+ nvkm_wr32(device, 0x00dc08, inte0);
+ nvkm_wr32(device, 0x00dc88, inte1);
}
-struct nvkm_oclass *
-gk104_gpio_oclass = &(struct nvkm_gpio_impl) {
- .base.handle = NV_SUBDEV(GPIO, 0xe0),
- .base.ofuncs = &(struct nvkm_ofuncs) {
- .ctor = _nvkm_gpio_ctor,
- .dtor = _nvkm_gpio_dtor,
- .init = _nvkm_gpio_init,
- .fini = _nvkm_gpio_fini,
- },
+static const struct nvkm_gpio_func
+gk104_gpio = {
.lines = 32,
.intr_stat = gk104_gpio_intr_stat,
.intr_mask = gk104_gpio_intr_mask,
- .drive = gf110_gpio_drive,
- .sense = gf110_gpio_sense,
- .reset = gf110_gpio_reset,
-}.base;
+ .drive = gf119_gpio_drive,
+ .sense = gf119_gpio_sense,
+ .reset = gf119_gpio_reset,
+};
+
+int
+gk104_gpio_new(struct nvkm_device *device, int index, struct nvkm_gpio **pgpio)
+{
+ return nvkm_gpio_new_(&gk104_gpio, device, index, pgpio);
+}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/nv10.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/nv10.c
index 2b295154247e..ae3499b48330 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/nv10.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/nv10.c
@@ -28,19 +28,20 @@
static int
nv10_gpio_sense(struct nvkm_gpio *gpio, int line)
{
+ struct nvkm_device *device = gpio->subdev.device;
if (line < 2) {
line = line * 16;
- line = nv_rd32(gpio, 0x600818) >> line;
+ line = nvkm_rd32(device, 0x600818) >> line;
return !!(line & 0x0100);
} else
if (line < 10) {
line = (line - 2) * 4;
- line = nv_rd32(gpio, 0x60081c) >> line;
+ line = nvkm_rd32(device, 0x60081c) >> line;
return !!(line & 0x04);
} else
if (line < 14) {
line = (line - 10) * 4;
- line = nv_rd32(gpio, 0x600850) >> line;
+ line = nvkm_rd32(device, 0x600850) >> line;
return !!(line & 0x04);
}
@@ -50,6 +51,7 @@ nv10_gpio_sense(struct nvkm_gpio *gpio, int line)
static int
nv10_gpio_drive(struct nvkm_gpio *gpio, int line, int dir, int out)
{
+ struct nvkm_device *device = gpio->subdev.device;
u32 reg, mask, data;
if (line < 2) {
@@ -73,43 +75,44 @@ nv10_gpio_drive(struct nvkm_gpio *gpio, int line, int dir, int out)
return -EINVAL;
}
- nv_mask(gpio, reg, mask << line, data << line);
+ nvkm_mask(device, reg, mask << line, data << line);
return 0;
}
static void
nv10_gpio_intr_stat(struct nvkm_gpio *gpio, u32 *hi, u32 *lo)
{
- u32 intr = nv_rd32(gpio, 0x001104);
- u32 stat = nv_rd32(gpio, 0x001144) & intr;
+ struct nvkm_device *device = gpio->subdev.device;
+ u32 intr = nvkm_rd32(device, 0x001104);
+ u32 stat = nvkm_rd32(device, 0x001144) & intr;
*lo = (stat & 0xffff0000) >> 16;
*hi = (stat & 0x0000ffff);
- nv_wr32(gpio, 0x001104, intr);
+ nvkm_wr32(device, 0x001104, intr);
}
static void
nv10_gpio_intr_mask(struct nvkm_gpio *gpio, u32 type, u32 mask, u32 data)
{
- u32 inte = nv_rd32(gpio, 0x001144);
+ struct nvkm_device *device = gpio->subdev.device;
+ u32 inte = nvkm_rd32(device, 0x001144);
if (type & NVKM_GPIO_LO)
inte = (inte & ~(mask << 16)) | (data << 16);
if (type & NVKM_GPIO_HI)
inte = (inte & ~mask) | data;
- nv_wr32(gpio, 0x001144, inte);
+ nvkm_wr32(device, 0x001144, inte);
}
-struct nvkm_oclass *
-nv10_gpio_oclass = &(struct nvkm_gpio_impl) {
- .base.handle = NV_SUBDEV(GPIO, 0x10),
- .base.ofuncs = &(struct nvkm_ofuncs) {
- .ctor = _nvkm_gpio_ctor,
- .dtor = _nvkm_gpio_dtor,
- .init = _nvkm_gpio_init,
- .fini = _nvkm_gpio_fini,
- },
+static const struct nvkm_gpio_func
+nv10_gpio = {
.lines = 16,
.intr_stat = nv10_gpio_intr_stat,
.intr_mask = nv10_gpio_intr_mask,
.drive = nv10_gpio_drive,
.sense = nv10_gpio_sense,
-}.base;
+};
+
+int
+nv10_gpio_new(struct nvkm_device *device, int index, struct nvkm_gpio **pgpio)
+{
+ return nvkm_gpio_new_(&nv10_gpio, device, index, pgpio);
+}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/nv50.c
index 6a031035bd27..8996649209ab 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/nv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/nv50.c
@@ -26,14 +26,15 @@
void
nv50_gpio_reset(struct nvkm_gpio *gpio, u8 match)
{
- struct nvkm_bios *bios = nvkm_bios(gpio);
+ struct nvkm_device *device = gpio->subdev.device;
+ struct nvkm_bios *bios = device->bios;
u8 ver, len;
u16 entry;
int ent = -1;
while ((entry = dcb_gpio_entry(bios, 0, ++ent, &ver, &len))) {
static const u32 regs[] = { 0xe100, 0xe28c };
- u32 data = nv_ro32(bios, entry);
+ u32 data = nvbios_rd32(bios, entry);
u8 line = (data & 0x0000001f);
u8 func = (data & 0x0000ff00) >> 8;
u8 defs = !!(data & 0x01000000);
@@ -47,9 +48,9 @@ nv50_gpio_reset(struct nvkm_gpio *gpio, u8 match)
(match != DCB_GPIO_UNUSED && match != func))
continue;
- gpio->set(gpio, 0, func, line, defs);
+ nvkm_gpio_set(gpio, 0, func, line, defs);
- nv_mask(gpio, reg, 0x00010001 << lsh, val << lsh);
+ nvkm_mask(device, reg, 0x00010001 << lsh, val << lsh);
}
}
@@ -69,60 +70,63 @@ nv50_gpio_location(int line, u32 *reg, u32 *shift)
int
nv50_gpio_drive(struct nvkm_gpio *gpio, int line, int dir, int out)
{
+ struct nvkm_device *device = gpio->subdev.device;
u32 reg, shift;
if (nv50_gpio_location(line, &reg, &shift))
return -EINVAL;
- nv_mask(gpio, reg, 3 << shift, (((dir ^ 1) << 1) | out) << shift);
+ nvkm_mask(device, reg, 3 << shift, (((dir ^ 1) << 1) | out) << shift);
return 0;
}
int
nv50_gpio_sense(struct nvkm_gpio *gpio, int line)
{
+ struct nvkm_device *device = gpio->subdev.device;
u32 reg, shift;
if (nv50_gpio_location(line, &reg, &shift))
return -EINVAL;
- return !!(nv_rd32(gpio, reg) & (4 << shift));
+ return !!(nvkm_rd32(device, reg) & (4 << shift));
}
static void
nv50_gpio_intr_stat(struct nvkm_gpio *gpio, u32 *hi, u32 *lo)
{
- u32 intr = nv_rd32(gpio, 0x00e054);
- u32 stat = nv_rd32(gpio, 0x00e050) & intr;
+ struct nvkm_device *device = gpio->subdev.device;
+ u32 intr = nvkm_rd32(device, 0x00e054);
+ u32 stat = nvkm_rd32(device, 0x00e050) & intr;
*lo = (stat & 0xffff0000) >> 16;
*hi = (stat & 0x0000ffff);
- nv_wr32(gpio, 0x00e054, intr);
+ nvkm_wr32(device, 0x00e054, intr);
}
static void
nv50_gpio_intr_mask(struct nvkm_gpio *gpio, u32 type, u32 mask, u32 data)
{
- u32 inte = nv_rd32(gpio, 0x00e050);
+ struct nvkm_device *device = gpio->subdev.device;
+ u32 inte = nvkm_rd32(device, 0x00e050);
if (type & NVKM_GPIO_LO)
inte = (inte & ~(mask << 16)) | (data << 16);
if (type & NVKM_GPIO_HI)
inte = (inte & ~mask) | data;
- nv_wr32(gpio, 0x00e050, inte);
+ nvkm_wr32(device, 0x00e050, inte);
}
-struct nvkm_oclass *
-nv50_gpio_oclass = &(struct nvkm_gpio_impl) {
- .base.handle = NV_SUBDEV(GPIO, 0x50),
- .base.ofuncs = &(struct nvkm_ofuncs) {
- .ctor = _nvkm_gpio_ctor,
- .dtor = _nvkm_gpio_dtor,
- .init = _nvkm_gpio_init,
- .fini = _nvkm_gpio_fini,
- },
+static const struct nvkm_gpio_func
+nv50_gpio = {
.lines = 16,
.intr_stat = nv50_gpio_intr_stat,
.intr_mask = nv50_gpio_intr_mask,
.drive = nv50_gpio_drive,
.sense = nv50_gpio_sense,
.reset = nv50_gpio_reset,
-}.base;
+};
+
+int
+nv50_gpio_new(struct nvkm_device *device, int index, struct nvkm_gpio **pgpio)
+{
+ return nvkm_gpio_new_(&nv50_gpio, device, index, pgpio);
+}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/priv.h
index 382f8d44e140..371bcdbbe0d6 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/priv.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/priv.h
@@ -1,33 +1,9 @@
#ifndef __NVKM_GPIO_PRIV_H__
#define __NVKM_GPIO_PRIV_H__
+#define nvkm_gpio(p) container_of((p), struct nvkm_gpio, subdev)
#include <subdev/gpio.h>
-#define nvkm_gpio_create(p,e,o,d) \
- nvkm_gpio_create_((p), (e), (o), sizeof(**d), (void **)d)
-#define nvkm_gpio_destroy(p) ({ \
- struct nvkm_gpio *gpio = (p); \
- _nvkm_gpio_dtor(nv_object(gpio)); \
-})
-#define nvkm_gpio_init(p) ({ \
- struct nvkm_gpio *gpio = (p); \
- _nvkm_gpio_init(nv_object(gpio)); \
-})
-#define nvkm_gpio_fini(p,s) ({ \
- struct nvkm_gpio *gpio = (p); \
- _nvkm_gpio_fini(nv_object(gpio), (s)); \
-})
-
-int nvkm_gpio_create_(struct nvkm_object *, struct nvkm_object *,
- struct nvkm_oclass *, int, void **);
-int _nvkm_gpio_ctor(struct nvkm_object *, struct nvkm_object *,
- struct nvkm_oclass *, void *, u32,
- struct nvkm_object **);
-void _nvkm_gpio_dtor(struct nvkm_object *);
-int _nvkm_gpio_init(struct nvkm_object *);
-int _nvkm_gpio_fini(struct nvkm_object *, bool);
-
-struct nvkm_gpio_impl {
- struct nvkm_oclass base;
+struct nvkm_gpio_func {
int lines;
/* read and ack pending interrupts, returning only data
@@ -51,6 +27,9 @@ struct nvkm_gpio_impl {
void (*reset)(struct nvkm_gpio *, u8);
};
+int nvkm_gpio_new_(const struct nvkm_gpio_func *, struct nvkm_device *,
+ int index, struct nvkm_gpio **);
+
void nv50_gpio_reset(struct nvkm_gpio *, u8);
int nv50_gpio_drive(struct nvkm_gpio *, int, int, int);
int nv50_gpio_sense(struct nvkm_gpio *, int);
@@ -58,7 +37,7 @@ int nv50_gpio_sense(struct nvkm_gpio *, int);
void g94_gpio_intr_stat(struct nvkm_gpio *, u32 *, u32 *);
void g94_gpio_intr_mask(struct nvkm_gpio *, u32, u32, u32);
-void gf110_gpio_reset(struct nvkm_gpio *, u8);
-int gf110_gpio_drive(struct nvkm_gpio *, int, int, int);
-int gf110_gpio_sense(struct nvkm_gpio *, int);
+void gf119_gpio_reset(struct nvkm_gpio *, u8);
+int gf119_gpio_drive(struct nvkm_gpio *, int, int, int);
+int gf119_gpio_sense(struct nvkm_gpio *, int);
#endif