diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nvkm/engine')
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c | 14 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c | 27 |
3 files changed, 38 insertions, 4 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c index 99fe7ef07a44..49fbb32f5022 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c @@ -42,6 +42,19 @@ #define AMPERE_IED_HACK(disp) ((disp)->engine.subdev.device->card_type >= GA100) static int +nvkm_dp_aux_xfer(struct nvkm_outp *outp, u8 type, u32 addr, u8 *data, u8 *size) +{ + int ret = nvkm_i2c_aux_acquire(outp->dp.aux); + + if (ret) + return ret; + + ret = nvkm_i2c_aux_xfer(outp->dp.aux, false, type, addr, data, size); + nvkm_i2c_aux_release(outp->dp.aux); + return ret; +} + +static int nvkm_dp_aux_pwr(struct nvkm_outp *outp, bool pu) { outp->dp.enabled = pu; @@ -823,6 +836,7 @@ nvkm_dp_func = { .bl.get = nvkm_outp_bl_get, .bl.set = nvkm_outp_bl_set, .dp.aux_pwr = nvkm_dp_aux_pwr, + .dp.aux_xfer = nvkm_dp_aux_xfer, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.h index 513794a278a9..a2391b224ea4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.h @@ -107,6 +107,7 @@ struct nvkm_outp_func { struct { int (*aux_pwr)(struct nvkm_outp *, bool pu); + int (*aux_xfer)(struct nvkm_outp *, u8 type, u32 addr, u8 *data, u8 *size); } dp; }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c index 6ca364e953bd..cd92db9028a3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c @@ -25,6 +25,8 @@ #include "head.h" #include "ior.h" +#include <subdev/i2c.h> + #include <nvif/if0012.h> static int @@ -69,6 +71,20 @@ nvkm_uoutp_mthd_acquire_dp(struct nvkm_outp *outp, u8 dpcd[DP_RECEIVER_CAP_SIZE] } static int +nvkm_uoutp_mthd_dp_aux_xfer(struct nvkm_outp *outp, void *argv, u32 argc) +{ + union nvif_outp_dp_aux_xfer_args *args = argv; + + if (argc != sizeof(args->v0) || args->v0.version != 0) + return -ENOSYS; + if (!outp->func->dp.aux_xfer) + return -EINVAL; + + return outp->func->dp.aux_xfer(outp, args->v0.type, args->v0.addr, + args->v0.data, &args->v0.size); +} + +static int nvkm_uoutp_mthd_dp_aux_pwr(struct nvkm_outp *outp, void *argv, u32 argc) { union nvif_outp_dp_aux_pwr_args *args = argv; @@ -429,7 +445,7 @@ nvkm_uoutp_mthd_acquired(struct nvkm_outp *outp, u32 mthd, void *argv, u32 argc) } static int -nvkm_uoutp_mthd_noacquire(struct nvkm_outp *outp, u32 mthd, void *argv, u32 argc) +nvkm_uoutp_mthd_noacquire(struct nvkm_outp *outp, u32 mthd, void *argv, u32 argc, bool *invalid) { switch (mthd) { case NVIF_OUTP_V0_DETECT : return nvkm_uoutp_mthd_detect (outp, argv, argc); @@ -440,11 +456,13 @@ nvkm_uoutp_mthd_noacquire(struct nvkm_outp *outp, u32 mthd, void *argv, u32 argc case NVIF_OUTP_V0_BL_GET : return nvkm_uoutp_mthd_bl_get (outp, argv, argc); case NVIF_OUTP_V0_BL_SET : return nvkm_uoutp_mthd_bl_set (outp, argv, argc); case NVIF_OUTP_V0_DP_AUX_PWR : return nvkm_uoutp_mthd_dp_aux_pwr (outp, argv, argc); + case NVIF_OUTP_V0_DP_AUX_XFER: return nvkm_uoutp_mthd_dp_aux_xfer(outp, argv, argc); default: break; } - return 1; + *invalid = true; + return 0; } static int @@ -452,12 +470,13 @@ nvkm_uoutp_mthd(struct nvkm_object *object, u32 mthd, void *argv, u32 argc) { struct nvkm_outp *outp = nvkm_uoutp(object); struct nvkm_disp *disp = outp->disp; + bool invalid = false; int ret; mutex_lock(&disp->super.mutex); - ret = nvkm_uoutp_mthd_noacquire(outp, mthd, argv, argc); - if (ret <= 0) + ret = nvkm_uoutp_mthd_noacquire(outp, mthd, argv, argc, &invalid); + if (!invalid) goto done; if (outp->ior) |