summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2017-05-19 16:59:34 +0300
committerBen Skeggs <bskeggs@redhat.com>2017-06-16 07:04:48 +0300
commita1c930789aa51b928f804c9186f9821efd070ce1 (patch)
tree383e8145267b88db8feed522b492a7fa476b35b5 /drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c
parent4b2b42f8e910c65aceb8b2d12fe392a7b7955449 (diff)
downloadlinux-a1c930789aa51b928f804c9186f9821efd070ce1.tar.xz
drm/nouveau/disp: introduce object to track per-head functions/state
Primarily intended as a way to pass per-head state around during supervisor handling, and share logic between NV50/GF119. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c')
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c69
1 files changed, 36 insertions, 33 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c
index 8d1e535af208..59bf3f950eea 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c
@@ -22,6 +22,7 @@
* Authors: Ben Skeggs
*/
#include "nv50.h"
+#include "head.h"
#include "rootnv50.h"
#include <subdev/bios.h>
@@ -364,55 +365,55 @@ gf119_disp_super(struct work_struct *work)
container_of(work, struct nv50_disp, supervisor);
struct nvkm_subdev *subdev = &disp->base.engine.subdev;
struct nvkm_device *device = subdev->device;
+ struct nvkm_head *head;
u32 mask[4];
- int head;
nvkm_debug(subdev, "supervisor %d\n", ffs(disp->super));
- for (head = 0; head < disp->base.head.nr; head++) {
- mask[head] = nvkm_rd32(device, 0x6101d4 + (head * 0x800));
- nvkm_debug(subdev, "head %d: %08x\n", head, mask[head]);
+ list_for_each_entry(head, &disp->base.head, head) {
+ mask[head->id] = nvkm_rd32(device, 0x6101d4 + (head->id * 0x800));
+ HEAD_DBG(head, "%08x", mask[head->id]);
}
if (disp->super & 0x00000001) {
nv50_disp_chan_mthd(disp->chan[0], NV_DBG_DEBUG);
- for (head = 0; head < disp->base.head.nr; head++) {
- if (!(mask[head] & 0x00001000))
+ list_for_each_entry(head, &disp->base.head, head) {
+ if (!(mask[head->id] & 0x00001000))
continue;
- nvkm_debug(subdev, "supervisor 1.0 - head %d\n", head);
- gf119_disp_intr_unk1_0(disp, head);
+ nvkm_debug(subdev, "supervisor 1.0 - head %d\n", head->id);
+ gf119_disp_intr_unk1_0(disp, head->id);
}
} else
if (disp->super & 0x00000002) {
- for (head = 0; head < disp->base.head.nr; head++) {
- if (!(mask[head] & 0x00001000))
+ list_for_each_entry(head, &disp->base.head, head) {
+ if (!(mask[head->id] & 0x00001000))
continue;
- nvkm_debug(subdev, "supervisor 2.0 - head %d\n", head);
- gf119_disp_intr_unk2_0(disp, head);
+ nvkm_debug(subdev, "supervisor 2.0 - head %d\n", head->id);
+ gf119_disp_intr_unk2_0(disp, head->id);
}
- for (head = 0; head < disp->base.head.nr; head++) {
- if (!(mask[head] & 0x00010000))
+ list_for_each_entry(head, &disp->base.head, head) {
+ if (!(mask[head->id] & 0x00010000))
continue;
- nvkm_debug(subdev, "supervisor 2.1 - head %d\n", head);
- gf119_disp_intr_unk2_1(disp, head);
+ nvkm_debug(subdev, "supervisor 2.1 - head %d\n", head->id);
+ gf119_disp_intr_unk2_1(disp, head->id);
}
- for (head = 0; head < disp->base.head.nr; head++) {
- if (!(mask[head] & 0x00001000))
+ list_for_each_entry(head, &disp->base.head, head) {
+ if (!(mask[head->id] & 0x00001000))
continue;
- nvkm_debug(subdev, "supervisor 2.2 - head %d\n", head);
- gf119_disp_intr_unk2_2(disp, head);
+ nvkm_debug(subdev, "supervisor 2.2 - head %d\n", head->id);
+ gf119_disp_intr_unk2_2(disp, head->id);
}
} else
if (disp->super & 0x00000004) {
- for (head = 0; head < disp->base.head.nr; head++) {
- if (!(mask[head] & 0x00001000))
+ list_for_each_entry(head, &disp->base.head, head) {
+ if (!(mask[head->id] & 0x00001000))
continue;
- nvkm_debug(subdev, "supervisor 3.0 - head %d\n", head);
- gf119_disp_intr_unk4_0(disp, head);
+ nvkm_debug(subdev, "supervisor 3.0 - head %d\n", head->id);
+ gf119_disp_intr_unk4_0(disp, head->id);
}
}
- for (head = 0; head < disp->base.head.nr; head++)
- nvkm_wr32(device, 0x6101d4 + (head * 0x800), 0x00000000);
+ list_for_each_entry(head, &disp->base.head, head)
+ nvkm_wr32(device, 0x6101d4 + (head->id * 0x800), 0x00000000);
nvkm_wr32(device, 0x6101d0, 0x80000000);
}
@@ -447,8 +448,8 @@ gf119_disp_intr(struct nv50_disp *disp)
{
struct nvkm_subdev *subdev = &disp->base.engine.subdev;
struct nvkm_device *device = subdev->device;
+ struct nvkm_head *head;
u32 intr = nvkm_rd32(device, 0x610088);
- int i;
if (intr & 0x00000001) {
u32 stat = nvkm_rd32(device, 0x61008c);
@@ -485,14 +486,15 @@ gf119_disp_intr(struct nv50_disp *disp)
intr &= ~0x00100000;
}
- for (i = 0; i < disp->base.head.nr; i++) {
- u32 mask = 0x01000000 << i;
+ list_for_each_entry(head, &disp->base.head, head) {
+ const u32 hoff = head->id * 0x800;
+ u32 mask = 0x01000000 << head->id;
if (mask & intr) {
- u32 stat = nvkm_rd32(device, 0x6100bc + (i * 0x800));
+ u32 stat = nvkm_rd32(device, 0x6100bc + hoff);
if (stat & 0x00000001)
- nvkm_disp_vblank(&disp->base, i);
- nvkm_mask(device, 0x6100bc + (i * 0x800), 0, 0);
- nvkm_rd32(device, 0x6100c0 + (i * 0x800));
+ nvkm_disp_vblank(&disp->base, head->id);
+ nvkm_mask(device, 0x6100bc + hoff, 0, 0);
+ nvkm_rd32(device, 0x6100c0 + hoff);
}
}
}
@@ -512,6 +514,7 @@ gf119_disp = {
.uevent = &gf119_disp_chan_uevent,
.super = gf119_disp_super,
.root = &gf119_disp_root_oclass,
+ .head.new = gf119_head_new,
.head.vblank_init = gf119_disp_vblank_init,
.head.vblank_fini = gf119_disp_vblank_fini,
.head.scanoutpos = gf119_disp_root_scanoutpos,