[PATCH 049/156] drm/nouveau/nvkm: detach user handling from nvkm_outp
Ben Skeggs
bskeggs at nvidia.com
Tue Apr 16 23:38:15 UTC 2024
- preparation for upcoming patches
- open-code current nvkm_uoutp() macro
Signed-off-by: Ben Skeggs <bskeggs at nvidia.com>
---
.../gpu/drm/nouveau/nvkm/engine/disp/outp.h | 3 +-
.../gpu/drm/nouveau/nvkm/engine/disp/uoutp.c | 131 ++++++++++--------
.../gpu/drm/nouveau/nvkm/engine/disp/uoutp.h | 6 +
3 files changed, 78 insertions(+), 62 deletions(-)
create mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.h
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.h
index ebd2f499b4b1..1beba54f80eb 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.h
@@ -63,10 +63,11 @@ struct nvkm_outp {
} dp;
};
- struct nvkm_object object;
struct {
struct nvkm_head *head;
} asy;
+
+ bool user; /* protected by disp->user.lock */
};
int nvkm_outp_new_(const struct nvkm_outp_func *, struct nvkm_disp *, int index,
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c
index 75669d5f8a42..8d39dad73a40 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c
@@ -19,8 +19,7 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
-#define nvkm_uoutp(p) container_of((p), struct nvkm_outp, object)
-#include "outp.h"
+#include "uoutp.h"
#include "dp.h"
#include "head.h"
#include "ior.h"
@@ -29,6 +28,11 @@
#include <nvif/if0012.h>
+struct nvif_outp_priv {
+ struct nvkm_object object;
+ struct nvkm_outp *outp;
+};
+
static int
nvkm_uoutp_mthd_dp_mst_vcpi(struct nvkm_outp *outp, void *argv, u32 argc)
{
@@ -543,7 +547,7 @@ nvkm_uoutp_mthd_noacquire(struct nvkm_outp *outp, u32 mthd, void *argv, u32 argc
static int
nvkm_uoutp_mthd(struct nvkm_object *object, u32 mthd, void *argv, u32 argc)
{
- struct nvkm_outp *outp = nvkm_uoutp(object);
+ struct nvkm_outp *outp = container_of(object, struct nvif_outp_priv, object)->outp;
struct nvkm_disp *disp = outp->disp;
bool invalid = false;
int ret;
@@ -567,13 +571,13 @@ nvkm_uoutp_mthd(struct nvkm_object *object, u32 mthd, void *argv, u32 argc)
static void *
nvkm_uoutp_dtor(struct nvkm_object *object)
{
- struct nvkm_outp *outp = nvkm_uoutp(object);
- struct nvkm_disp *disp = outp->disp;
+ struct nvif_outp_priv *uoutp = container_of(object, typeof(*uoutp), object);
+ struct nvkm_disp *disp = uoutp->outp->disp;
spin_lock(&disp->user.lock);
- outp->object.func = NULL;
+ uoutp->outp->user = false;
spin_unlock(&disp->user.lock);
- return NULL;
+ return uoutp;
}
static const struct nvkm_object_func
@@ -589,7 +593,7 @@ nvkm_uoutp_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, struct nv
struct nvkm_disp *disp = container_of(oclass->parent, struct nvif_disp_priv, object)->disp;
struct nvkm_outp *outt, *outp = NULL;
union nvif_outp_args *args = argv;
- int ret;
+ struct nvif_outp_priv *uoutp;
if (argc != sizeof(args->v0) || args->v0.version != 0)
return -ENOSYS;
@@ -604,63 +608,68 @@ nvkm_uoutp_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, struct nv
if (!outp)
return -EINVAL;
- ret = -EBUSY;
- spin_lock(&disp->user.lock);
- if (!outp->object.func) {
- switch (outp->info.type) {
- case DCB_OUTPUT_ANALOG:
- args->v0.type = NVIF_OUTP_V0_TYPE_DAC;
- args->v0.proto = NVIF_OUTP_V0_PROTO_RGB_CRT;
- args->v0.rgb_crt.freq_max = outp->info.crtconf.maxfreq;
- break;
- case DCB_OUTPUT_TMDS:
- if (!outp->info.location) {
- args->v0.type = NVIF_OUTP_V0_TYPE_SOR;
- args->v0.tmds.dual = (outp->info.tmdsconf.sor.link == 3);
- } else {
- args->v0.type = NVIF_OUTP_V0_TYPE_PIOR;
- args->v0.tmds.dual = 0;
- }
- args->v0.proto = NVIF_OUTP_V0_PROTO_TMDS;
- break;
- case DCB_OUTPUT_LVDS:
+ switch (outp->info.type) {
+ case DCB_OUTPUT_ANALOG:
+ args->v0.type = NVIF_OUTP_V0_TYPE_DAC;
+ args->v0.proto = NVIF_OUTP_V0_PROTO_RGB_CRT;
+ args->v0.rgb_crt.freq_max = outp->info.crtconf.maxfreq;
+ break;
+ case DCB_OUTPUT_TMDS:
+ if (!outp->info.location) {
args->v0.type = NVIF_OUTP_V0_TYPE_SOR;
- args->v0.proto = NVIF_OUTP_V0_PROTO_LVDS;
- args->v0.lvds.acpi_edid = outp->info.lvdsconf.use_acpi_for_edid;
- break;
- case DCB_OUTPUT_DP:
- if (!outp->info.location) {
- args->v0.type = NVIF_OUTP_V0_TYPE_SOR;
- args->v0.dp.aux = outp->info.i2c_index;
- } else {
- args->v0.type = NVIF_OUTP_V0_TYPE_PIOR;
- args->v0.dp.aux = NVKM_I2C_AUX_EXT(outp->info.extdev);
- }
- args->v0.proto = NVIF_OUTP_V0_PROTO_DP;
- args->v0.dp.mst = outp->dp.mst;
- args->v0.dp.increased_wm = outp->dp.increased_wm;
- args->v0.dp.link_nr = outp->info.dpconf.link_nr;
- args->v0.dp.link_bw = outp->info.dpconf.link_bw * 27000;
- break;
- default:
- WARN_ON(1);
- ret = -EINVAL;
- goto done;
+ args->v0.tmds.dual = (outp->info.tmdsconf.sor.link == 3);
+ } else {
+ args->v0.type = NVIF_OUTP_V0_TYPE_PIOR;
+ args->v0.tmds.dual = 0;
}
+ args->v0.proto = NVIF_OUTP_V0_PROTO_TMDS;
+ break;
+ case DCB_OUTPUT_LVDS:
+ args->v0.type = NVIF_OUTP_V0_TYPE_SOR;
+ args->v0.proto = NVIF_OUTP_V0_PROTO_LVDS;
+ args->v0.lvds.acpi_edid = outp->info.lvdsconf.use_acpi_for_edid;
+ break;
+ case DCB_OUTPUT_DP:
+ if (!outp->info.location) {
+ args->v0.type = NVIF_OUTP_V0_TYPE_SOR;
+ args->v0.dp.aux = outp->info.i2c_index;
+ } else {
+ args->v0.type = NVIF_OUTP_V0_TYPE_PIOR;
+ args->v0.dp.aux = NVKM_I2C_AUX_EXT(outp->info.extdev);
+ }
+ args->v0.proto = NVIF_OUTP_V0_PROTO_DP;
+ args->v0.dp.mst = outp->dp.mst;
+ args->v0.dp.increased_wm = outp->dp.increased_wm;
+ args->v0.dp.link_nr = outp->info.dpconf.link_nr;
+ args->v0.dp.link_bw = outp->info.dpconf.link_bw * 27000;
+ break;
+ default:
+ WARN_ON(1);
+ return -EINVAL;
+ }
- if (outp->info.location)
- args->v0.ddc = NVKM_I2C_BUS_EXT(outp->info.extdev);
- else
- args->v0.ddc = outp->info.i2c_index;
- args->v0.heads = outp->info.heads;
- args->v0.conn = outp->info.connector;
+ if (outp->info.location)
+ args->v0.ddc = NVKM_I2C_BUS_EXT(outp->info.extdev);
+ else
+ args->v0.ddc = outp->info.i2c_index;
+ args->v0.heads = outp->info.heads;
+ args->v0.conn = outp->info.connector;
- nvkm_object_ctor(&nvkm_uoutp, oclass, &outp->object);
- *pobject = &outp->object;
- ret = 0;
- }
+ uoutp = kzalloc(sizeof(*uoutp), GFP_KERNEL);
+ if (!uoutp)
+ return -ENOMEM;
-done:
+ spin_lock(&disp->user.lock);
+ if (outp->user) {
+ spin_unlock(&disp->user.lock);
+ kfree(uoutp);
+ return -EBUSY;
+ }
+ outp->user = true;
spin_unlock(&disp->user.lock);
- return ret;
+
+ nvkm_object_ctor(&nvkm_uoutp, oclass, &uoutp->object);
+ uoutp->outp = outp;
+ *pobject = &uoutp->object;
+ return 0;
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.h
new file mode 100644
index 000000000000..37ecd2891a1a
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.h
@@ -0,0 +1,6 @@
+/* SPDX-License-Identifier: MIT */
+#ifndef __NVKM_UOUTP_H__
+#define __NVKM_UOUTP_H__
+#include "outp.h"
+
+#endif
--
2.41.0
More information about the Nouveau
mailing list