diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/g84.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/g84.c index 842e1b72ee421eb9a04e31e3199a9f8ccd6fb8ce..a1741a80bd050352780275b7047499c6d5b5e405 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/g84.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/g84.c @@ -32,7 +32,7 @@ g84_disp = { .uevent = &nv50_disp_chan_uevent, .super = nv50_disp_super, .root = &g84_disp_root_oclass, - .head.new = nv50_head_new, + .head = { .cnt = nv50_head_cnt, .new = nv50_head_new }, .dac = { .nr = 3, .new = nv50_dac_new }, .sor = { .nr = 2, .new = g84_sor_new }, .pior = { .nr = 3, .new = nv50_pior_new }, @@ -41,5 +41,5 @@ g84_disp = { int g84_disp_new(struct nvkm_device *device, int index, struct nvkm_disp **pdisp) { - return nv50_disp_new_(&g84_disp, device, index, 2, pdisp); + return nv50_disp_new_(&g84_disp, device, index, pdisp); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/g94.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/g94.c index d184e6ab8918d55aee47b32dc0e85089addda061..b7febc4b0f85613f009c22cde51c3a42e9cc73e0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/g94.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/g94.c @@ -32,7 +32,7 @@ g94_disp = { .uevent = &nv50_disp_chan_uevent, .super = nv50_disp_super, .root = &g94_disp_root_oclass, - .head.new = nv50_head_new, + .head = { .cnt = nv50_head_cnt, .new = nv50_head_new }, .dac = { .nr = 3, .new = nv50_dac_new }, .sor = { .nr = 4, .new = g94_sor_new }, .pior = { .nr = 3, .new = nv50_pior_new }, @@ -41,5 +41,5 @@ g94_disp = { int g94_disp_new(struct nvkm_device *device, int index, struct nvkm_disp **pdisp) { - return nv50_disp_new_(&g94_disp, device, index, 2, pdisp); + return nv50_disp_new_(&g94_disp, device, index, pdisp); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c index d8765b57180b9530154583bd37c41ef255dc2d0a..b580ca9b4418bce1d696102eadfd20966427f4e3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c @@ -164,14 +164,6 @@ gf119_disp_intr(struct nv50_disp *disp) } } -int -gf119_disp_new_(const struct nv50_disp_func *func, struct nvkm_device *device, - int index, struct nvkm_disp **pdisp) -{ - u32 heads = nvkm_rd32(device, 0x022448); - return nv50_disp_new_(func, device, index, heads, pdisp); -} - static const struct nv50_disp_func gf119_disp = { .intr = gf119_disp_intr, @@ -179,7 +171,7 @@ gf119_disp = { .uevent = &gf119_disp_chan_uevent, .super = gf119_disp_super, .root = &gf119_disp_root_oclass, - .head.new = gf119_head_new, + .head = { .cnt = gf119_head_cnt, .new = gf119_head_new }, .dac = { .nr = 3, .new = gf119_dac_new }, .sor = { .nr = 4, .new = gf119_sor_new }, }; @@ -187,5 +179,5 @@ gf119_disp = { int gf119_disp_new(struct nvkm_device *device, int index, struct nvkm_disp **pdisp) { - return gf119_disp_new_(&gf119_disp, device, index, pdisp); + return nv50_disp_new_(&gf119_disp, device, index, pdisp); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gk104.c index e8fe9f315d641f878e2a157d358c88f1301427a0..b3ee5b1d4a45f9b1089613edd6e9e21e9723f6cf 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gk104.c @@ -33,7 +33,7 @@ gk104_disp = { .uevent = &gf119_disp_chan_uevent, .super = gf119_disp_super, .root = &gk104_disp_root_oclass, - .head.new = gf119_head_new, + .head = { .cnt = gf119_head_cnt, .new = gf119_head_new }, .dac = { .nr = 3, .new = gf119_dac_new }, .sor = { .nr = 4, .new = gk104_sor_new }, }; @@ -41,5 +41,5 @@ gk104_disp = { int gk104_disp_new(struct nvkm_device *device, int index, struct nvkm_disp **pdisp) { - return gf119_disp_new_(&gk104_disp, device, index, pdisp); + return nv50_disp_new_(&gk104_disp, device, index, pdisp); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gk110.c index 769687502e7a831d9d5e7c3687c41201313a6fbe..22533abbfb67c8600f64ec57a630b566bbcb539d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gk110.c @@ -33,7 +33,7 @@ gk110_disp = { .uevent = &gf119_disp_chan_uevent, .super = gf119_disp_super, .root = &gk110_disp_root_oclass, - .head.new = gf119_head_new, + .head = { .cnt = gf119_head_cnt, .new = gf119_head_new }, .dac = { .nr = 3, .new = gf119_dac_new }, .sor = { .nr = 4, .new = gk104_sor_new }, }; @@ -41,5 +41,5 @@ gk110_disp = { int gk110_disp_new(struct nvkm_device *device, int index, struct nvkm_disp **pdisp) { - return gf119_disp_new_(&gk110_disp, device, index, pdisp); + return nv50_disp_new_(&gk110_disp, device, index, pdisp); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c index ede70e5d188e2627e3b87d793d0d9a9cfce8c0c8..85e602120abc3be1cadde4de807576930ea79d84 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c @@ -33,7 +33,7 @@ gm107_disp = { .uevent = &gf119_disp_chan_uevent, .super = gf119_disp_super, .root = &gm107_disp_root_oclass, - .head.new = gf119_head_new, + .head = { .cnt = gf119_head_cnt, .new = gf119_head_new }, .dac = { .nr = 3, .new = gf119_dac_new }, .sor = { .nr = 4, .new = gm107_sor_new }, }; @@ -41,5 +41,5 @@ gm107_disp = { int gm107_disp_new(struct nvkm_device *device, int index, struct nvkm_disp **pdisp) { - return gf119_disp_new_(&gm107_disp, device, index, pdisp); + return nv50_disp_new_(&gm107_disp, device, index, pdisp); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm200.c index 292d3b5f970460cd61aac2a2b438c2a9aa33aba9..48ab65d827178be5d92b8c3ecc4a835c50637b22 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm200.c @@ -33,7 +33,7 @@ gm200_disp = { .uevent = &gf119_disp_chan_uevent, .super = gf119_disp_super, .root = &gm200_disp_root_oclass, - .head.new = gf119_head_new, + .head = { .cnt = gf119_head_cnt, .new = gf119_head_new }, .dac = { .nr = 3, .new = gf119_dac_new }, .sor = { .nr = 4, .new = gm200_sor_new }, }; @@ -41,5 +41,5 @@ gm200_disp = { int gm200_disp_new(struct nvkm_device *device, int index, struct nvkm_disp **pdisp) { - return gf119_disp_new_(&gm200_disp, device, index, pdisp); + return nv50_disp_new_(&gm200_disp, device, index, pdisp); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp100.c index 39eb98b2c3a24ced81c3ad4d144d097545f5f149..190d03025fc1b76166a7decf1ea95744d89ccdba 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp100.c @@ -33,12 +33,12 @@ gp100_disp = { .uevent = &gf119_disp_chan_uevent, .super = gf119_disp_super, .root = &gp100_disp_root_oclass, - .head.new = gf119_head_new, + .head = { .cnt = gf119_head_cnt, .new = gf119_head_new }, .sor = { .nr = 4, .new = gm200_sor_new }, }; int gp100_disp_new(struct nvkm_device *device, int index, struct nvkm_disp **pdisp) { - return gf119_disp_new_(&gp100_disp, device, index, pdisp); + return nv50_disp_new_(&gp100_disp, device, index, pdisp); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp102.c index 91d70fe18275a3460f1a7a8b66047e0f5a13fa2d..a059c65243a939a2b6ea0c7c1c1ef6727e59f01b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp102.c @@ -59,12 +59,12 @@ gp102_disp = { .uevent = &gf119_disp_chan_uevent, .super = gf119_disp_super, .root = &gp102_disp_root_oclass, - .head.new = gf119_head_new, + .head = { .cnt = gf119_head_cnt, .new = gf119_head_new }, .sor = { .nr = 4, .new = gm200_sor_new }, }; int gp102_disp_new(struct nvkm_device *device, int index, struct nvkm_disp **pdisp) { - return gf119_disp_new_(&gp102_disp, device, index, pdisp); + return nv50_disp_new_(&gp102_disp, device, index, pdisp); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt200.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt200.c index bf00c4e3be3acdb8833cb03dc9c3acf90760f67e..7554c732a655a434b0a312e74c37cff50f66795a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt200.c @@ -32,7 +32,7 @@ gt200_disp = { .uevent = &nv50_disp_chan_uevent, .super = nv50_disp_super, .root = >200_disp_root_oclass, - .head.new = nv50_head_new, + .head = { .cnt = nv50_head_cnt, .new = nv50_head_new }, .dac = { .nr = 3, .new = nv50_dac_new }, .sor = { .nr = 2, .new = g84_sor_new }, .pior = { .nr = 3, .new = nv50_pior_new }, @@ -41,5 +41,5 @@ gt200_disp = { int gt200_disp_new(struct nvkm_device *device, int index, struct nvkm_disp **pdisp) { - return nv50_disp_new_(>200_disp, device, index, 2, pdisp); + return nv50_disp_new_(>200_disp, device, index, pdisp); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt215.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt215.c index 2cdd4d7a98d301fe567fe3e5ab614c5cc9b3e6f9..6a878a7e6af35084124bcf61e049ba06d490ca36 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt215.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt215.c @@ -32,7 +32,7 @@ gt215_disp = { .uevent = &nv50_disp_chan_uevent, .super = nv50_disp_super, .root = >215_disp_root_oclass, - .head.new = nv50_head_new, + .head = { .cnt = nv50_head_cnt, .new = nv50_head_new }, .dac = { .nr = 3, .new = nv50_dac_new }, .sor = { .nr = 4, .new = gt215_sor_new }, .pior = { .nr = 3, .new = nv50_pior_new }, @@ -41,5 +41,5 @@ gt215_disp = { int gt215_disp_new(struct nvkm_device *device, int index, struct nvkm_disp **pdisp) { - return nv50_disp_new_(>215_disp, device, index, 2, pdisp); + return nv50_disp_new_(>215_disp, device, index, pdisp); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/head.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/head.h index 57030b3a4a753409ea41c71f6ed014d9c3f5ffa1..4a5d7892ff5492eb3d1d8636d5a42ee595d807f2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/head.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/head.h @@ -52,6 +52,10 @@ void nv50_head_rgpos(struct nvkm_head *, u16 *, u16 *); #define HEAD_DBG(h,f,a...) HEAD_MSG((h), debug, f, ##a) int nv04_head_new(struct nvkm_disp *, int id); + +int nv50_head_cnt(struct nvkm_disp *, unsigned long *); int nv50_head_new(struct nvkm_disp *, int id); + +int gf119_head_cnt(struct nvkm_disp *, unsigned long *); int gf119_head_new(struct nvkm_disp *, int id); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/headgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/headgf119.c index 9fd7ae3313080e4c1a727a43c9bcb553e4390651..bcbdaaf8ba202dbd48c7f392b3f63a56d2dfd91d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/headgf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/headgf119.c @@ -92,8 +92,13 @@ gf119_head = { int gf119_head_new(struct nvkm_disp *disp, int id) { - struct nvkm_device *device = disp->engine.subdev.device; - if (!(nvkm_rd32(device, 0x612004) & (0x00000001 << id))) - return 0; return nvkm_head_new_(&gf119_head, disp, id); } + +int +gf119_head_cnt(struct nvkm_disp *disp, unsigned long *pmask) +{ + struct nvkm_device *device = disp->engine.subdev.device; + *pmask = nvkm_rd32(device, 0x612004) & 0x0000000f; + return nvkm_rd32(device, 0x022448); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/headnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/headnv50.c index c80d06d5168f5b01a528486897036a0d549923ba..e7d5c397cd2983912d7fca49d27a1b0950706515 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/headnv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/headnv50.c @@ -90,3 +90,10 @@ nv50_head_new(struct nvkm_disp *disp, int id) { return nvkm_head_new_(&nv50_head, disp, id); } + +int +nv50_head_cnt(struct nvkm_disp *disp, unsigned long *pmask) +{ + *pmask = 3; + return 2; +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp77.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp77.c index d7e0fbb12bf11231898302f50406b91a16566364..9fc7507774e15efcbbc4ef1ce4e3cff989a59799 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp77.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp77.c @@ -30,7 +30,7 @@ mcp77_disp = { .uevent = &nv50_disp_chan_uevent, .super = nv50_disp_super, .root = &g94_disp_root_oclass, - .head.new = nv50_head_new, + .head = { .cnt = nv50_head_cnt, .new = nv50_head_new }, .dac = { .nr = 3, .new = nv50_dac_new }, .sor = { .nr = 4, .new = mcp77_sor_new }, .pior = { .nr = 3, .new = nv50_pior_new }, @@ -39,5 +39,5 @@ mcp77_disp = { int mcp77_disp_new(struct nvkm_device *device, int index, struct nvkm_disp **pdisp) { - return nv50_disp_new_(&mcp77_disp, device, index, 2, pdisp); + return nv50_disp_new_(&mcp77_disp, device, index, pdisp); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp89.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp89.c index 7b75c57c12edf2243ca11b0932ae2211b1d4abf7..28647d365057dd36bab12cffb39c0594094879f0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp89.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp89.c @@ -30,7 +30,7 @@ mcp89_disp = { .uevent = &nv50_disp_chan_uevent, .super = nv50_disp_super, .root = >215_disp_root_oclass, - .head.new = nv50_head_new, + .head = { .cnt = nv50_head_cnt, .new = nv50_head_new }, .dac = { .nr = 3, .new = nv50_dac_new }, .sor = { .nr = 4, .new = mcp89_sor_new }, .pior = { .nr = 3, .new = nv50_pior_new }, @@ -39,5 +39,5 @@ mcp89_disp = { int mcp89_disp_new(struct nvkm_device *device, int index, struct nvkm_disp **pdisp) { - return nv50_disp_new_(&mcp89_disp, device, index, 2, pdisp); + return nv50_disp_new_(&mcp89_disp, device, index, pdisp); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c index 43373b3662632a715b0029938a81cd80f7254fc0..bf50b7be88267f8be6692caa36f433e3c38791e6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c @@ -64,9 +64,13 @@ nv50_disp_oneinit_(struct nvkm_disp *base) { struct nv50_disp *disp = nv50_disp(base); const struct nv50_disp_func *func = disp->func; + struct nvkm_subdev *subdev = &disp->base.engine.subdev; int ret, i; - for (i = 0; func->head.new && i < disp->head.nr; i++) { + disp->head.nr = func->head.cnt(&disp->base, &disp->head.mask); + nvkm_debug(subdev, " Head(s): %d (%02lx)\n", + disp->head.nr, disp->head.mask); + for_each_set_bit(i, &disp->head.mask, disp->head.nr) { ret = func->head.new(&disp->base, i); if (ret) return ret; @@ -103,7 +107,7 @@ nv50_disp_ = { int nv50_disp_new_(const struct nv50_disp_func *func, struct nvkm_device *device, - int index, int heads, struct nvkm_disp **pdisp) + int index, struct nvkm_disp **pdisp) { struct nv50_disp *disp; int ret; @@ -122,7 +126,6 @@ nv50_disp_new_(const struct nv50_disp_func *func, struct nvkm_device *device, return -ENOMEM; INIT_WORK(&disp->supervisor, func->super); - disp->head.nr = heads; return nvkm_event_init(func->uevent, 1, ARRAY_SIZE(disp->chan), &disp->uevent); @@ -633,7 +636,7 @@ nv50_disp = { .uevent = &nv50_disp_chan_uevent, .super = nv50_disp_super, .root = &nv50_disp_root_oclass, - .head.new = nv50_head_new, + .head = { .cnt = nv50_head_cnt, .new = nv50_head_new }, .dac = { .nr = 3, .new = nv50_dac_new }, .sor = { .nr = 2, .new = nv50_sor_new }, .pior = { .nr = 3, .new = nv50_pior_new }, @@ -642,5 +645,5 @@ nv50_disp = { int nv50_disp_new(struct nvkm_device *device, int index, struct nvkm_disp **pdisp) { - return nv50_disp_new_(&nv50_disp, device, index, 2, pdisp); + return nv50_disp_new_(&nv50_disp, device, index, pdisp); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h index 0ae32cda45e7121337dfc7b787fd1e8f67059ea4..c7fe29cf3e0535c275f047b90d2b89492dbc4261 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h @@ -16,6 +16,7 @@ struct nv50_disp { struct nvkm_event uevent; struct { + unsigned long mask; int nr; } head; @@ -38,9 +39,7 @@ void nv50_disp_super_2_2(struct nv50_disp *, struct nvkm_head *); void nv50_disp_super_3_0(struct nv50_disp *, struct nvkm_head *); int nv50_disp_new_(const struct nv50_disp_func *, struct nvkm_device *, - int index, int heads, struct nvkm_disp **); -int gf119_disp_new_(const struct nv50_disp_func *, struct nvkm_device *, - int index, struct nvkm_disp **); + int index, struct nvkm_disp **); struct nv50_disp_func { void (*intr)(struct nv50_disp *); @@ -52,6 +51,7 @@ struct nv50_disp_func { const struct nvkm_disp_oclass *root; struct { + int (*cnt)(struct nvkm_disp *, unsigned long *mask); int (*new)(struct nvkm_disp *, int id); } head;