mirror of
https://github.com/torvalds/linux.git
synced 2026-10-13 05:41:02 +02:00
drm/nouveau/disp: add output method to fetch edid
- needed to support TMDS EDID on RM Signed-off-by: Ben Skeggs <bskeggs@redhat.com> Reviewed-by: Lyude Paul <lyude@redhat.com> Acked-by: Danilo Krummrich <me@dakr.org> Signed-off-by: Lyude Paul <lyude@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20230919220442.202488-9-lyude@redhat.com
This commit is contained in:
parent
a69eeb37f9
commit
0cd7e07181
|
|
@ -13,6 +13,7 @@ union nvif_outp_args {
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NVIF_OUTP_V0_DETECT 0x00
|
#define NVIF_OUTP_V0_DETECT 0x00
|
||||||
|
#define NVIF_OUTP_V0_EDID_GET 0x01
|
||||||
|
|
||||||
#define NVIF_OUTP_V0_ACQUIRE 0x11
|
#define NVIF_OUTP_V0_ACQUIRE 0x11
|
||||||
#define NVIF_OUTP_V0_RELEASE 0x12
|
#define NVIF_OUTP_V0_RELEASE 0x12
|
||||||
|
|
@ -36,6 +37,15 @@ union nvif_outp_detect_args {
|
||||||
} v0;
|
} v0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
union nvif_outp_edid_get_args {
|
||||||
|
struct nvif_outp_edid_get_v0 {
|
||||||
|
__u8 version;
|
||||||
|
__u8 pad01;
|
||||||
|
__u16 size;
|
||||||
|
__u8 data[2048];
|
||||||
|
} v0;
|
||||||
|
};
|
||||||
|
|
||||||
union nvif_outp_load_detect_args {
|
union nvif_outp_load_detect_args {
|
||||||
struct nvif_outp_load_detect_v0 {
|
struct nvif_outp_load_detect_v0 {
|
||||||
__u8 version;
|
__u8 version;
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ enum nvif_outp_detect_status {
|
||||||
};
|
};
|
||||||
|
|
||||||
enum nvif_outp_detect_status nvif_outp_detect(struct nvif_outp *);
|
enum nvif_outp_detect_status nvif_outp_detect(struct nvif_outp *);
|
||||||
|
int nvif_outp_edid_get(struct nvif_outp *, u8 **pedid);
|
||||||
|
|
||||||
int nvif_outp_load_detect(struct nvif_outp *, u32 loadval);
|
int nvif_outp_load_detect(struct nvif_outp *, u32 loadval);
|
||||||
int nvif_outp_acquire_rgb_crt(struct nvif_outp *);
|
int nvif_outp_acquire_rgb_crt(struct nvif_outp *);
|
||||||
|
|
|
||||||
|
|
@ -570,7 +570,6 @@ nouveau_connector_detect(struct drm_connector *connector, bool force)
|
||||||
struct nouveau_connector *nv_connector = nouveau_connector(connector);
|
struct nouveau_connector *nv_connector = nouveau_connector(connector);
|
||||||
struct nouveau_encoder *nv_encoder = NULL;
|
struct nouveau_encoder *nv_encoder = NULL;
|
||||||
struct nouveau_encoder *nv_partner;
|
struct nouveau_encoder *nv_partner;
|
||||||
struct i2c_adapter *i2c;
|
|
||||||
int type;
|
int type;
|
||||||
int ret;
|
int ret;
|
||||||
enum drm_connector_status conn_status = connector_status_disconnected;
|
enum drm_connector_status conn_status = connector_status_disconnected;
|
||||||
|
|
@ -593,15 +592,20 @@ nouveau_connector_detect(struct drm_connector *connector, bool force)
|
||||||
}
|
}
|
||||||
|
|
||||||
nv_encoder = nouveau_connector_ddc_detect(connector);
|
nv_encoder = nouveau_connector_ddc_detect(connector);
|
||||||
if (nv_encoder && (i2c = nv_encoder->i2c) != NULL) {
|
if (nv_encoder) {
|
||||||
struct edid *new_edid;
|
struct edid *new_edid = NULL;
|
||||||
|
|
||||||
if ((vga_switcheroo_handler_flags() &
|
if (nv_encoder->i2c) {
|
||||||
VGA_SWITCHEROO_CAN_SWITCH_DDC) &&
|
if ((vga_switcheroo_handler_flags() & VGA_SWITCHEROO_CAN_SWITCH_DDC) &&
|
||||||
nv_connector->type == DCB_CONNECTOR_LVDS)
|
nv_connector->type == DCB_CONNECTOR_LVDS)
|
||||||
new_edid = drm_get_edid_switcheroo(connector, i2c);
|
new_edid = drm_get_edid_switcheroo(connector, nv_encoder->i2c);
|
||||||
else
|
else
|
||||||
new_edid = drm_get_edid(connector, i2c);
|
new_edid = drm_get_edid(connector, nv_encoder->i2c);
|
||||||
|
} else {
|
||||||
|
ret = nvif_outp_edid_get(&nv_encoder->outp, (u8 **)&new_edid);
|
||||||
|
if (ret < 0)
|
||||||
|
return connector_status_disconnected;
|
||||||
|
}
|
||||||
|
|
||||||
nouveau_connector_set_edid(nv_connector, new_edid);
|
nouveau_connector_set_edid(nv_connector, new_edid);
|
||||||
if (!nv_connector->edid) {
|
if (!nv_connector->edid) {
|
||||||
|
|
|
||||||
|
|
@ -210,6 +210,36 @@ nvif_outp_load_detect(struct nvif_outp *outp, u32 loadval)
|
||||||
return ret < 0 ? ret : args.load;
|
return ret < 0 ? ret : args.load;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
nvif_outp_edid_get(struct nvif_outp *outp, u8 **pedid)
|
||||||
|
{
|
||||||
|
struct nvif_outp_edid_get_v0 *args;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
args = kmalloc(sizeof(*args), GFP_KERNEL);
|
||||||
|
if (!args)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
args->version = 0;
|
||||||
|
|
||||||
|
ret = nvif_mthd(&outp->object, NVIF_OUTP_V0_EDID_GET, args, sizeof(*args));
|
||||||
|
NVIF_ERRON(ret, &outp->object, "[EDID_GET] size:%d", args->size);
|
||||||
|
if (ret)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
*pedid = kmalloc(args->size, GFP_KERNEL);
|
||||||
|
if (!*pedid) {
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(*pedid, args->data, args->size);
|
||||||
|
ret = args->size;
|
||||||
|
done:
|
||||||
|
kfree(args);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
enum nvif_outp_detect_status
|
enum nvif_outp_detect_status
|
||||||
nvif_outp_detect(struct nvif_outp *outp)
|
nvif_outp_detect(struct nvif_outp *outp)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -87,6 +87,7 @@ struct nvkm_outp_func {
|
||||||
void (*fini)(struct nvkm_outp *);
|
void (*fini)(struct nvkm_outp *);
|
||||||
|
|
||||||
int (*detect)(struct nvkm_outp *);
|
int (*detect)(struct nvkm_outp *);
|
||||||
|
int (*edid_get)(struct nvkm_outp *, u8 *data, u16 *size);
|
||||||
|
|
||||||
int (*acquire)(struct nvkm_outp *);
|
int (*acquire)(struct nvkm_outp *);
|
||||||
void (*release)(struct nvkm_outp *);
|
void (*release)(struct nvkm_outp *);
|
||||||
|
|
|
||||||
|
|
@ -275,6 +275,20 @@ nvkm_uoutp_mthd_load_detect(struct nvkm_outp *outp, void *argv, u32 argc)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
nvkm_uoutp_mthd_edid_get(struct nvkm_outp *outp, void *argv, u32 argc)
|
||||||
|
{
|
||||||
|
union nvif_outp_edid_get_args *args = argv;
|
||||||
|
|
||||||
|
if (argc != sizeof(args->v0) || args->v0.version != 0)
|
||||||
|
return -ENOSYS;
|
||||||
|
if (!outp->func->edid_get)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
args->v0.size = ARRAY_SIZE(args->v0.data);
|
||||||
|
return outp->func->edid_get(outp, args->v0.data, &args->v0.size);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
nvkm_uoutp_mthd_detect(struct nvkm_outp *outp, void *argv, u32 argc)
|
nvkm_uoutp_mthd_detect(struct nvkm_outp *outp, void *argv, u32 argc)
|
||||||
{
|
{
|
||||||
|
|
@ -319,6 +333,7 @@ nvkm_uoutp_mthd_noacquire(struct nvkm_outp *outp, u32 mthd, void *argv, u32 argc
|
||||||
{
|
{
|
||||||
switch (mthd) {
|
switch (mthd) {
|
||||||
case NVIF_OUTP_V0_DETECT : return nvkm_uoutp_mthd_detect (outp, argv, argc);
|
case NVIF_OUTP_V0_DETECT : return nvkm_uoutp_mthd_detect (outp, argv, argc);
|
||||||
|
case NVIF_OUTP_V0_EDID_GET : return nvkm_uoutp_mthd_edid_get (outp, argv, argc);
|
||||||
case NVIF_OUTP_V0_ACQUIRE : return nvkm_uoutp_mthd_acquire (outp, argv, argc);
|
case NVIF_OUTP_V0_ACQUIRE : return nvkm_uoutp_mthd_acquire (outp, argv, argc);
|
||||||
case NVIF_OUTP_V0_LOAD_DETECT: return nvkm_uoutp_mthd_load_detect(outp, argv, argc);
|
case NVIF_OUTP_V0_LOAD_DETECT: return nvkm_uoutp_mthd_load_detect(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_PWR : return nvkm_uoutp_mthd_dp_aux_pwr (outp, argv, argc);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user