diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2022-06-01 13:46:36 +0300 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2022-11-09 03:43:10 +0300 |
commit | a2b7eadfef5963138a5aeaba90c4f513414823c2 (patch) | |
tree | b11d8ba92e7da8de21317266e9dcb53b6b11c74c /drivers/gpu | |
parent | 8c7d980da9ba3eb67a1b40fd4b33bcf49397084b (diff) | |
download | linux-a2b7eadfef5963138a5aeaba90c4f513414823c2.tar.xz |
drm/nouveau/disp: add head class
v2: remove extra whitespace
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/nouveau/dispnv04/crtc.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/dispnv50/head.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/include/nvif/class.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/include/nvif/disp.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/include/nvif/head.h | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/include/nvif/if0010.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/include/nvif/if0013.h | 12 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_crtc.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvif/Kbuild | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvif/disp.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvif/head.c | 48 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/disp/head.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/disp/priv.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/disp/udisp.c | 12 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/disp/uhead.c | 66 |
16 files changed, 175 insertions, 3 deletions
diff --git a/drivers/gpu/drm/nouveau/dispnv04/crtc.c b/drivers/gpu/drm/nouveau/dispnv04/crtc.c index ee92d576d277..f35c25607508 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/crtc.c +++ b/drivers/gpu/drm/nouveau/dispnv04/crtc.c @@ -762,6 +762,7 @@ static void nv_crtc_destroy(struct drm_crtc *crtc) nouveau_bo_unpin(nv_crtc->cursor.nvbo); nouveau_bo_ref(NULL, &nv_crtc->cursor.nvbo); nvif_notify_dtor(&nv_crtc->vblank); + nvif_head_dtor(&nv_crtc->head); kfree(nv_crtc); } @@ -1341,6 +1342,10 @@ nv04_crtc_create(struct drm_device *dev, int crtc_num) nv04_cursor_init(nv_crtc); + ret = nvif_head_ctor(&disp->disp, nv_crtc->base.name, nv_crtc->index, &nv_crtc->head); + if (ret) + return ret; + ret = nvif_notify_ctor(&disp->disp.object, "kmsVbl", nv04_crtc_vblank_handler, false, NV04_DISP_NTFY_VBLANK, &(struct nvif_notify_head_req_v0) { diff --git a/drivers/gpu/drm/nouveau/dispnv50/head.c b/drivers/gpu/drm/nouveau/dispnv50/head.c index c3c57be54e1c..8ac3474111c5 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/head.c +++ b/drivers/gpu/drm/nouveau/dispnv50/head.c @@ -518,6 +518,7 @@ nv50_head_destroy(struct drm_crtc *crtc) struct nv50_head *head = nv50_head(crtc); nvif_notify_dtor(&head->base.vblank); + nvif_head_dtor(&head->base.head); nv50_lut_fini(&head->olut); drm_crtc_cleanup(crtc); kfree(head); @@ -624,6 +625,10 @@ nv50_head_create(struct drm_device *dev, int index) } } + ret = nvif_head_ctor(disp->disp, head->base.base.name, head->base.index, &head->base.head); + if (ret) + return ERR_PTR(ret); + ret = nvif_notify_ctor(&disp->disp->object, "kmsVbl", nv50_head_vblank_handler, false, NV04_DISP_NTFY_VBLANK, &(struct nvif_notify_head_req_v0) { diff --git a/drivers/gpu/drm/nouveau/include/nvif/class.h b/drivers/gpu/drm/nouveau/include/nvif/class.h index 8641db649f48..03f0f7c299f2 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/class.h +++ b/drivers/gpu/drm/nouveau/include/nvif/class.h @@ -35,6 +35,7 @@ #define NVIF_CLASS_DISP /* if0010.h */ 0x80000010 #define NVIF_CLASS_CONN /* if0011.h */ 0x80000011 #define NVIF_CLASS_OUTP /* if0012.h */ 0x80000012 +#define NVIF_CLASS_HEAD /* if0013.h */ 0x80000013 #define NVIF_CLASS_DISP_CHAN /* if0014.h */ 0x80000014 /* the below match nvidia-assigned (either in hw, or sw) class numbers */ diff --git a/drivers/gpu/drm/nouveau/include/nvif/disp.h b/drivers/gpu/drm/nouveau/include/nvif/disp.h index 742632ad3bea..56eb7293e01c 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/disp.h +++ b/drivers/gpu/drm/nouveau/include/nvif/disp.h @@ -7,6 +7,7 @@ struct nvif_disp { struct nvif_object object; unsigned long conn_mask; unsigned long outp_mask; + unsigned long head_mask; }; int nvif_disp_ctor(struct nvif_device *, const char *name, s32 oclass, diff --git a/drivers/gpu/drm/nouveau/include/nvif/head.h b/drivers/gpu/drm/nouveau/include/nvif/head.h new file mode 100644 index 000000000000..09170c7bc0af --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvif/head.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: MIT */ +#ifndef __NVIF_HEAD_H__ +#define __NVIF_HEAD_H__ +#include <nvif/object.h> +struct nvif_disp; + +struct nvif_head { + struct nvif_object object; +}; + +int nvif_head_ctor(struct nvif_disp *, const char *name, int id, struct nvif_head *); +void nvif_head_dtor(struct nvif_head *); +#endif diff --git a/drivers/gpu/drm/nouveau/include/nvif/if0010.h b/drivers/gpu/drm/nouveau/include/nvif/if0010.h index fc236ef28965..4c835bbe6fe3 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/if0010.h +++ b/drivers/gpu/drm/nouveau/include/nvif/if0010.h @@ -8,6 +8,7 @@ union nvif_disp_args { __u8 pad01[3]; __u32 conn_mask; __u32 outp_mask; + __u32 head_mask; } v0; }; #endif diff --git a/drivers/gpu/drm/nouveau/include/nvif/if0013.h b/drivers/gpu/drm/nouveau/include/nvif/if0013.h new file mode 100644 index 000000000000..218ba6eeba7b --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvif/if0013.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: MIT */ +#ifndef __NVIF_IF0013_H__ +#define __NVIF_IF0013_H__ + +union nvif_head_args { + struct nvif_head_v0 { + __u8 version; + __u8 id; + __u8 pad02[6]; + } v0; +}; +#endif diff --git a/drivers/gpu/drm/nouveau/nouveau_crtc.h b/drivers/gpu/drm/nouveau/nouveau_crtc.h index 7f63be2ec35d..e85e74f9a28d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_crtc.h +++ b/drivers/gpu/drm/nouveau/nouveau_crtc.h @@ -26,14 +26,15 @@ #ifndef __NOUVEAU_CRTC_H__ #define __NOUVEAU_CRTC_H__ - #include <drm/drm_crtc.h> +#include <nvif/head.h> #include <nvif/notify.h> struct nouveau_crtc { struct drm_crtc base; + struct nvif_head head; int index; struct nvif_notify vblank; diff --git a/drivers/gpu/drm/nouveau/nvif/Kbuild b/drivers/gpu/drm/nouveau/nvif/Kbuild index 6abc4bc42e35..6281291c70dc 100644 --- a/drivers/gpu/drm/nouveau/nvif/Kbuild +++ b/drivers/gpu/drm/nouveau/nvif/Kbuild @@ -6,6 +6,7 @@ nvif-y += nvif/device.o nvif-y += nvif/disp.o nvif-y += nvif/driver.o nvif-y += nvif/fifo.o +nvif-y += nvif/head.o nvif-y += nvif/mem.o nvif-y += nvif/mmu.o nvif-y += nvif/notify.o diff --git a/drivers/gpu/drm/nouveau/nvif/disp.c b/drivers/gpu/drm/nouveau/nvif/disp.c index 926b0c04b1e8..09915f2715af 100644 --- a/drivers/gpu/drm/nouveau/nvif/disp.c +++ b/drivers/gpu/drm/nouveau/nvif/disp.c @@ -72,9 +72,10 @@ nvif_disp_ctor(struct nvif_device *device, const char *name, s32 oclass, struct if (ret) return ret; - NVIF_DEBUG(&disp->object, "[NEW] conn_mask:%08x outp_mask:%08x", - args.conn_mask, args.outp_mask); + NVIF_DEBUG(&disp->object, "[NEW] conn_mask:%08x outp_mask:%08x head_mask:%08x", + args.conn_mask, args.outp_mask, args.head_mask); disp->conn_mask = args.conn_mask; disp->outp_mask = args.outp_mask; + disp->head_mask = args.head_mask; return 0; } diff --git a/drivers/gpu/drm/nouveau/nvif/head.c b/drivers/gpu/drm/nouveau/nvif/head.c new file mode 100644 index 000000000000..01deba462600 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvif/head.c @@ -0,0 +1,48 @@ +/* + * Copyright 2021 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include <nvif/head.h> +#include <nvif/disp.h> +#include <nvif/printf.h> + +#include <nvif/class.h> +#include <nvif/if0013.h> + +void +nvif_head_dtor(struct nvif_head *head) +{ + nvif_object_dtor(&head->object); +} + +int +nvif_head_ctor(struct nvif_disp *disp, const char *name, int id, struct nvif_head *head) +{ + struct nvif_head_v0 args; + int ret; + + args.version = 0; + args.id = id; + + ret = nvif_object_ctor(&disp->object, name ? name : "nvifHead", id, NVIF_CLASS_HEAD, + &args, sizeof(args), &head->object); + NVIF_ERRON(ret, &disp->object, "[NEW head id:%d]", args.id); + return ret; +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild index 600072a904be..e403040658b6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild @@ -34,3 +34,4 @@ nvkm-y += nvkm/engine/disp/rootnv50.o nvkm-y += nvkm/engine/disp/udisp.o nvkm-y += nvkm/engine/disp/uconn.o nvkm-y += nvkm/engine/disp/uoutp.o +nvkm-y += nvkm/engine/disp/uhead.o diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/head.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/head.h index 84a2989193cf..d95d4b591b2e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/head.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/head.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: MIT */ #ifndef __NVKM_DISP_HEAD_H__ #define __NVKM_DISP_HEAD_H__ +#include <nvif/object.h> #include "priv.h" struct nvkm_head { @@ -26,6 +27,8 @@ struct nvkm_head { u8 depth; } or; } arm, asy; + + struct nvkm_object object; }; int nvkm_head_new_(const struct nvkm_head_func *, struct nvkm_disp *, int id); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/priv.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/priv.h index cb25dfe849f0..9e89615c4f67 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/priv.h @@ -86,4 +86,5 @@ extern const struct nvkm_event_func gv100_disp_chan_uevent; int nvkm_udisp_new(const struct nvkm_oclass *, void *, u32, struct nvkm_object **); int nvkm_uconn_new(const struct nvkm_oclass *, void *, u32, struct nvkm_object **); int nvkm_uoutp_new(const struct nvkm_oclass *, void *, u32, struct nvkm_object **); +int nvkm_uhead_new(const struct nvkm_oclass *, void *, u32, struct nvkm_object **); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/udisp.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/udisp.c index 0841e7ce0343..93a0b816b33b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/udisp.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/udisp.c @@ -21,6 +21,7 @@ */ #include "priv.h" #include "conn.h" +#include "head.h" #include "outp.h" #include <nvif/class.h> @@ -43,6 +44,12 @@ nvkm_udisp_sclass(struct nvkm_object *object, int index, struct nvkm_oclass *scl return 0; } + if (index-- == 0) { + sclass->base = (struct nvkm_sclass) { 0, 0, NVIF_CLASS_HEAD }; + sclass->ctor = nvkm_uhead_new; + return 0; + } + if (disp->func->user[index].ctor) { sclass->base = disp->func->user[index].base; sclass->ctor = disp->func->user[index].ctor; @@ -89,6 +96,7 @@ nvkm_udisp_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, struct nv struct nvkm_disp *disp = nvkm_disp(oclass->engine); struct nvkm_conn *conn; struct nvkm_outp *outp; + struct nvkm_head *head; union nvif_disp_args *args = argv; if (argc != sizeof(args->v0) || args->v0.version != 0) @@ -111,5 +119,9 @@ nvkm_udisp_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, struct nv list_for_each_entry(outp, &disp->outps, head) args->v0.outp_mask |= BIT(outp->index); + args->v0.head_mask = 0; + list_for_each_entry(head, &disp->heads, head) + args->v0.head_mask |= BIT(head->id); + return 0; } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uhead.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uhead.c new file mode 100644 index 000000000000..a58f4b5fcd01 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uhead.c @@ -0,0 +1,66 @@ +/* + * Copyright 2021 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#define nvkm_uhead(p) container_of((p), struct nvkm_head, object) +#include "head.h" + +#include <nvif/if0013.h> + +static void * +nvkm_uhead_dtor(struct nvkm_object *object) +{ + struct nvkm_head *head = nvkm_uhead(object); + struct nvkm_disp *disp = head->disp; + + spin_lock(&disp->client.lock); + head->object.func = NULL; + spin_unlock(&disp->client.lock); + return NULL; +} + +static const struct nvkm_object_func +nvkm_uhead = { + .dtor = nvkm_uhead_dtor, +}; + +int +nvkm_uhead_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, struct nvkm_object **pobject) +{ + struct nvkm_disp *disp = nvkm_udisp(oclass->parent); + struct nvkm_head *head; + union nvif_head_args *args = argv; + int ret; + + if (argc != sizeof(args->v0) || args->v0.version != 0) + return -ENOSYS; + if (!(head = nvkm_head_find(disp, args->v0.id))) + return -EINVAL; + + ret = -EBUSY; + spin_lock(&disp->client.lock); + if (!head->object.func) { + nvkm_object_ctor(&nvkm_uhead, oclass, &head->object); + *pobject = &head->object; + ret = 0; + } + spin_unlock(&disp->client.lock); + return ret; +} |