summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/base.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/nouveau/nvkm/subdev/devinit/base.c')
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/devinit/base.c112
1 files changed, 73 insertions, 39 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/base.c
index e5ef999adbb9..47823f5a2cdf 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/base.c
@@ -26,70 +26,104 @@
#include <core/option.h>
#include <subdev/vga.h>
+u32
+nvkm_devinit_mmio(struct nvkm_devinit *init, u32 addr)
+{
+ if (init->func->mmio)
+ addr = init->func->mmio(init, addr);
+ return addr;
+}
+
int
-_nvkm_devinit_fini(struct nvkm_object *object, bool suspend)
+nvkm_devinit_pll_set(struct nvkm_devinit *init, u32 type, u32 khz)
+{
+ return init->func->pll_set(init, type, khz);
+}
+
+void
+nvkm_devinit_meminit(struct nvkm_devinit *init)
+{
+ if (init->func->meminit)
+ init->func->meminit(init);
+}
+
+u64
+nvkm_devinit_disable(struct nvkm_devinit *init)
{
- struct nvkm_devinit *init = (void *)object;
+ if (init->func->disable)
+ return init->func->disable(init);
+ return 0;
+}
+static int
+nvkm_devinit_fini(struct nvkm_subdev *subdev, bool suspend)
+{
+ struct nvkm_devinit *init = nvkm_devinit(subdev);
/* force full reinit on resume */
if (suspend)
init->post = true;
+ return 0;
+}
- /* unlock the extended vga crtc regs */
- nvkm_lockvgac(init->subdev.device, false);
+static int
+nvkm_devinit_preinit(struct nvkm_subdev *subdev)
+{
+ struct nvkm_devinit *init = nvkm_devinit(subdev);
+
+ if (init->func->preinit)
+ init->func->preinit(init);
- return nvkm_subdev_fini_old(&init->subdev, suspend);
+ /* unlock the extended vga crtc regs */
+ nvkm_lockvgac(subdev->device, false);
+ return 0;
}
-int
-_nvkm_devinit_init(struct nvkm_object *object)
+static int
+nvkm_devinit_init(struct nvkm_subdev *subdev)
{
- struct nvkm_devinit_impl *impl = (void *)object->oclass;
- struct nvkm_devinit *init = (void *)object;
+ struct nvkm_devinit *init = nvkm_devinit(subdev);
int ret;
- ret = nvkm_subdev_init_old(&init->subdev);
+ ret = init->func->post(init, init->post);
if (ret)
return ret;
- ret = impl->post(&init->subdev, init->post);
- if (ret)
- return ret;
+ if (init->func->init)
+ init->func->init(init);
- if (impl->disable)
- nv_device(init)->disable_mask |= impl->disable(init);
+ if (init->func->disable)
+ subdev->device->disable_mask |= init->func->disable(init);
return 0;
}
-void
-_nvkm_devinit_dtor(struct nvkm_object *object)
+static void *
+nvkm_devinit_dtor(struct nvkm_subdev *subdev)
{
- struct nvkm_devinit *init = (void *)object;
+ struct nvkm_devinit *init = nvkm_devinit(subdev);
+ void *data = init;
- /* lock crtc regs */
- nvkm_lockvgac(init->subdev.device, true);
+ if (init->func->dtor)
+ data = init->func->dtor(init);
- nvkm_subdev_destroy(&init->subdev);
+ /* lock crtc regs */
+ nvkm_lockvgac(subdev->device, true);
+ return data;
}
-int
-nvkm_devinit_create_(struct nvkm_object *parent, struct nvkm_object *engine,
- struct nvkm_oclass *oclass, int size, void **pobject)
-{
- struct nvkm_devinit_impl *impl = (void *)oclass;
- struct nvkm_device *device = nv_device(parent);
- struct nvkm_devinit *init;
- int ret;
-
- ret = nvkm_subdev_create_(parent, engine, oclass, 0, "DEVINIT",
- "init", size, pobject);
- init = *pobject;
- if (ret)
- return ret;
+static const struct nvkm_subdev_func
+nvkm_devinit = {
+ .dtor = nvkm_devinit_dtor,
+ .preinit = nvkm_devinit_preinit,
+ .init = nvkm_devinit_init,
+ .fini = nvkm_devinit_fini,
+};
+void
+nvkm_devinit_ctor(const struct nvkm_devinit_func *func,
+ struct nvkm_device *device, int index,
+ struct nvkm_devinit *init)
+{
+ nvkm_subdev_ctor(&nvkm_devinit, device, index, 0, &init->subdev);
+ init->func = func;
init->post = nvkm_boolopt(device->cfgopt, "NvForcePost", false);
- init->meminit = impl->meminit;
- init->pll_set = impl->pll_set;
- init->mmio = impl->mmio;
- return 0;
}
OpenPOWER on IntegriCloud