|
@@ -28,8 +28,6 @@
|
|
|
#include "ior.h"
|
|
|
|
|
|
#include <core/client.h>
|
|
|
-#include <core/ramht.h>
|
|
|
-#include <subdev/timer.h>
|
|
|
|
|
|
#include <nvif/class.h>
|
|
|
#include <nvif/cl5070.h>
|
|
@@ -315,49 +313,16 @@ nv50_disp_root_child_get_(struct nvkm_object *object, int index,
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
|
|
|
-static int
|
|
|
-nv50_disp_root_fini_(struct nvkm_object *object, bool suspend)
|
|
|
-{
|
|
|
- struct nv50_disp_root *root = nv50_disp_root(object);
|
|
|
- root->func->fini(root);
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-static int
|
|
|
-nv50_disp_root_init_(struct nvkm_object *object)
|
|
|
-{
|
|
|
- struct nv50_disp_root *root = nv50_disp_root(object);
|
|
|
- struct nvkm_ior *ior;
|
|
|
- int ret;
|
|
|
-
|
|
|
- ret = root->func->init(root);
|
|
|
- if (ret)
|
|
|
- return ret;
|
|
|
-
|
|
|
- /* Set 'normal' (ie. when it's attached to a head) state for
|
|
|
- * each output resource to 'fully enabled'.
|
|
|
- */
|
|
|
- list_for_each_entry(ior, &root->disp->base.ior, head) {
|
|
|
- ior->func->power(ior, true, true, true, true, true);
|
|
|
- }
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
static void *
|
|
|
nv50_disp_root_dtor_(struct nvkm_object *object)
|
|
|
{
|
|
|
struct nv50_disp_root *root = nv50_disp_root(object);
|
|
|
- nvkm_ramht_del(&root->ramht);
|
|
|
- nvkm_gpuobj_del(&root->instmem);
|
|
|
return root;
|
|
|
}
|
|
|
|
|
|
static const struct nvkm_object_func
|
|
|
nv50_disp_root_ = {
|
|
|
.dtor = nv50_disp_root_dtor_,
|
|
|
- .init = nv50_disp_root_init_,
|
|
|
- .fini = nv50_disp_root_fini_,
|
|
|
.mthd = nv50_disp_root_mthd_,
|
|
|
.ntfy = nvkm_disp_ntfy,
|
|
|
.sclass = nv50_disp_root_child_get_,
|
|
@@ -370,8 +335,6 @@ nv50_disp_root_new_(const struct nv50_disp_root_func *func,
|
|
|
{
|
|
|
struct nv50_disp *disp = nv50_disp(base);
|
|
|
struct nv50_disp_root *root;
|
|
|
- struct nvkm_device *device = disp->base.engine.subdev.device;
|
|
|
- int ret;
|
|
|
|
|
|
if (!(root = kzalloc(sizeof(*root), GFP_KERNEL)))
|
|
|
return -ENOMEM;
|
|
@@ -380,94 +343,11 @@ nv50_disp_root_new_(const struct nv50_disp_root_func *func,
|
|
|
nvkm_object_ctor(&nv50_disp_root_, oclass, &root->object);
|
|
|
root->func = func;
|
|
|
root->disp = disp;
|
|
|
-
|
|
|
- ret = nvkm_gpuobj_new(disp->base.engine.subdev.device, 0x10000, 0x10000,
|
|
|
- false, NULL, &root->instmem);
|
|
|
- if (ret)
|
|
|
- return ret;
|
|
|
-
|
|
|
- return nvkm_ramht_new(device, 0x1000, 0, root->instmem, &root->ramht);
|
|
|
-}
|
|
|
-
|
|
|
-void
|
|
|
-nv50_disp_root_fini(struct nv50_disp_root *root)
|
|
|
-{
|
|
|
- struct nvkm_device *device = root->disp->base.engine.subdev.device;
|
|
|
- /* disable all interrupts */
|
|
|
- nvkm_wr32(device, 0x610024, 0x00000000);
|
|
|
- nvkm_wr32(device, 0x610020, 0x00000000);
|
|
|
-}
|
|
|
-
|
|
|
-int
|
|
|
-nv50_disp_root_init(struct nv50_disp_root *root)
|
|
|
-{
|
|
|
- struct nv50_disp *disp = root->disp;
|
|
|
- struct nvkm_head *head;
|
|
|
- struct nvkm_device *device = disp->base.engine.subdev.device;
|
|
|
- u32 tmp;
|
|
|
- int i;
|
|
|
-
|
|
|
- /* The below segments of code copying values from one register to
|
|
|
- * another appear to inform EVO of the display capabilities or
|
|
|
- * something similar. NFI what the 0x614004 caps are for..
|
|
|
- */
|
|
|
- tmp = nvkm_rd32(device, 0x614004);
|
|
|
- nvkm_wr32(device, 0x610184, tmp);
|
|
|
-
|
|
|
- /* ... CRTC caps */
|
|
|
- list_for_each_entry(head, &disp->base.head, head) {
|
|
|
- tmp = nvkm_rd32(device, 0x616100 + (head->id * 0x800));
|
|
|
- nvkm_wr32(device, 0x610190 + (head->id * 0x10), tmp);
|
|
|
- tmp = nvkm_rd32(device, 0x616104 + (head->id * 0x800));
|
|
|
- nvkm_wr32(device, 0x610194 + (head->id * 0x10), tmp);
|
|
|
- tmp = nvkm_rd32(device, 0x616108 + (head->id * 0x800));
|
|
|
- nvkm_wr32(device, 0x610198 + (head->id * 0x10), tmp);
|
|
|
- tmp = nvkm_rd32(device, 0x61610c + (head->id * 0x800));
|
|
|
- nvkm_wr32(device, 0x61019c + (head->id * 0x10), tmp);
|
|
|
- }
|
|
|
-
|
|
|
- /* ... DAC caps */
|
|
|
- for (i = 0; i < disp->dac.nr; i++) {
|
|
|
- tmp = nvkm_rd32(device, 0x61a000 + (i * 0x800));
|
|
|
- nvkm_wr32(device, 0x6101d0 + (i * 0x04), tmp);
|
|
|
- }
|
|
|
-
|
|
|
- /* ... SOR caps */
|
|
|
- for (i = 0; i < disp->sor.nr; i++) {
|
|
|
- tmp = nvkm_rd32(device, 0x61c000 + (i * 0x800));
|
|
|
- nvkm_wr32(device, 0x6101e0 + (i * 0x04), tmp);
|
|
|
- }
|
|
|
-
|
|
|
- /* ... PIOR caps */
|
|
|
- for (i = 0; i < disp->pior.nr; i++) {
|
|
|
- tmp = nvkm_rd32(device, 0x61e000 + (i * 0x800));
|
|
|
- nvkm_wr32(device, 0x6101f0 + (i * 0x04), tmp);
|
|
|
- }
|
|
|
-
|
|
|
- /* steal display away from vbios, or something like that */
|
|
|
- if (nvkm_rd32(device, 0x610024) & 0x00000100) {
|
|
|
- nvkm_wr32(device, 0x610024, 0x00000100);
|
|
|
- nvkm_mask(device, 0x6194e8, 0x00000001, 0x00000000);
|
|
|
- if (nvkm_msec(device, 2000,
|
|
|
- if (!(nvkm_rd32(device, 0x6194e8) & 0x00000002))
|
|
|
- break;
|
|
|
- ) < 0)
|
|
|
- return -EBUSY;
|
|
|
- }
|
|
|
-
|
|
|
- /* point at display engine memory area (hash table, objects) */
|
|
|
- nvkm_wr32(device, 0x610010, (root->instmem->addr >> 8) | 9);
|
|
|
-
|
|
|
- /* enable supervisor interrupts, disable everything else */
|
|
|
- nvkm_wr32(device, 0x61002c, 0x00000370);
|
|
|
- nvkm_wr32(device, 0x610028, 0x00000000);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
static const struct nv50_disp_root_func
|
|
|
nv50_disp_root = {
|
|
|
- .init = nv50_disp_root_init,
|
|
|
- .fini = nv50_disp_root_fini,
|
|
|
.dmac = {
|
|
|
&nv50_disp_core_oclass,
|
|
|
&nv50_disp_base_oclass,
|