Commit 8894f491 authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau: register a drm_dp_aux channel for each dp connector

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent ebd6acbb
...@@ -105,6 +105,8 @@ nouveau_connector_destroy(struct drm_connector *connector) ...@@ -105,6 +105,8 @@ nouveau_connector_destroy(struct drm_connector *connector)
kfree(nv_connector->edid); kfree(nv_connector->edid);
drm_sysfs_connector_remove(connector); drm_sysfs_connector_remove(connector);
drm_connector_cleanup(connector); drm_connector_cleanup(connector);
if (nv_connector->aux.transfer)
drm_dp_aux_unregister(&nv_connector->aux);
kfree(connector); kfree(connector);
} }
...@@ -946,6 +948,38 @@ nouveau_connector_hotplug(void *data, u32 type, int index) ...@@ -946,6 +948,38 @@ nouveau_connector_hotplug(void *data, u32 type, int index)
return NVKM_EVENT_DROP; return NVKM_EVENT_DROP;
} }
static ssize_t
nouveau_connector_aux_xfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
{
struct nouveau_connector *nv_connector =
container_of(aux, typeof(*nv_connector), aux);
struct nouveau_encoder *nv_encoder;
struct nouveau_i2c_port *port;
int ret;
nv_encoder = find_encoder(&nv_connector->base, DCB_OUTPUT_DP);
if (!nv_encoder || !(port = nv_encoder->i2c))
return -ENODEV;
if (WARN_ON(msg->size > 16))
return -E2BIG;
if (msg->size == 0)
return msg->size;
ret = nouveau_i2c(port)->acquire(port, 0);
if (ret)
return ret;
ret = port->func->aux(port, false, msg->request, msg->address,
msg->buffer, msg->size);
nouveau_i2c(port)->release(port);
if (ret >= 0) {
msg->reply = ret;
return msg->size;
}
return ret;
}
static int static int
drm_conntype_from_dcb(enum dcb_connector_type dcb) drm_conntype_from_dcb(enum dcb_connector_type dcb)
{ {
...@@ -1066,8 +1100,8 @@ nouveau_connector_create(struct drm_device *dev, int index) ...@@ -1066,8 +1100,8 @@ nouveau_connector_create(struct drm_device *dev, int index)
} }
} }
type = drm_conntype_from_dcb(nv_connector->type); switch ((type = drm_conntype_from_dcb(nv_connector->type))) {
if (type == DRM_MODE_CONNECTOR_LVDS) { case DRM_MODE_CONNECTOR_LVDS:
ret = nouveau_bios_parse_lvds_table(dev, 0, &dummy, &dummy); ret = nouveau_bios_parse_lvds_table(dev, 0, &dummy, &dummy);
if (ret) { if (ret) {
NV_ERROR(drm, "Error parsing LVDS table, disabling\n"); NV_ERROR(drm, "Error parsing LVDS table, disabling\n");
...@@ -1076,8 +1110,23 @@ nouveau_connector_create(struct drm_device *dev, int index) ...@@ -1076,8 +1110,23 @@ nouveau_connector_create(struct drm_device *dev, int index)
} }
funcs = &nouveau_connector_funcs_lvds; funcs = &nouveau_connector_funcs_lvds;
} else { break;
case DRM_MODE_CONNECTOR_DisplayPort:
case DRM_MODE_CONNECTOR_eDP:
nv_connector->aux.dev = dev->dev;
nv_connector->aux.transfer = nouveau_connector_aux_xfer;
ret = drm_dp_aux_register(&nv_connector->aux);
if (ret) {
NV_ERROR(drm, "failed to register aux channel\n");
kfree(nv_connector);
return ERR_PTR(ret);
}
funcs = &nouveau_connector_funcs; funcs = &nouveau_connector_funcs;
break;
default:
funcs = &nouveau_connector_funcs;
break;
} }
/* defaults, will get overridden in detect() */ /* defaults, will get overridden in detect() */
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#define __NOUVEAU_CONNECTOR_H__ #define __NOUVEAU_CONNECTOR_H__
#include <drm/drm_edid.h> #include <drm/drm_edid.h>
#include <drm/drm_dp_helper.h>
#include "nouveau_crtc.h" #include "nouveau_crtc.h"
#include <core/event.h> #include <core/event.h>
...@@ -70,6 +71,8 @@ struct nouveau_connector { ...@@ -70,6 +71,8 @@ struct nouveau_connector {
u32 status; u32 status;
struct work_struct work; struct work_struct work;
struct drm_dp_aux aux;
int dithering_mode; int dithering_mode;
int dithering_depth; int dithering_depth;
int scaling_mode; int scaling_mode;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment