aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2014-05-30 02:20:58 -0400
committerBen Skeggs <bskeggs@redhat.com>2014-06-11 02:11:04 -0400
commit8894f4919bc43f821775db2cfff4b917871b2102 (patch)
treede56e4e07318893cbc58d1b89cc7ca0664ebd5f9
parentebd6acbb068b6558735eb80aabce1e7af9e78e1e (diff)
drm/nouveau: register a drm_dp_aux channel for each dp connector
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_connector.c55
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_connector.h3
2 files changed, 55 insertions, 3 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c
index 80ab3a1a44c1..7535a8700fe9 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -105,6 +105,8 @@ nouveau_connector_destroy(struct drm_connector *connector)
105 kfree(nv_connector->edid); 105 kfree(nv_connector->edid);
106 drm_sysfs_connector_remove(connector); 106 drm_sysfs_connector_remove(connector);
107 drm_connector_cleanup(connector); 107 drm_connector_cleanup(connector);
108 if (nv_connector->aux.transfer)
109 drm_dp_aux_unregister(&nv_connector->aux);
108 kfree(connector); 110 kfree(connector);
109} 111}
110 112
@@ -946,6 +948,38 @@ nouveau_connector_hotplug(void *data, u32 type, int index)
946 return NVKM_EVENT_DROP; 948 return NVKM_EVENT_DROP;
947} 949}
948 950
951static ssize_t
952nouveau_connector_aux_xfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
953{
954 struct nouveau_connector *nv_connector =
955 container_of(aux, typeof(*nv_connector), aux);
956 struct nouveau_encoder *nv_encoder;
957 struct nouveau_i2c_port *port;
958 int ret;
959
960 nv_encoder = find_encoder(&nv_connector->base, DCB_OUTPUT_DP);
961 if (!nv_encoder || !(port = nv_encoder->i2c))
962 return -ENODEV;
963 if (WARN_ON(msg->size > 16))
964 return -E2BIG;
965 if (msg->size == 0)
966 return msg->size;
967
968 ret = nouveau_i2c(port)->acquire(port, 0);
969 if (ret)
970 return ret;
971
972 ret = port->func->aux(port, false, msg->request, msg->address,
973 msg->buffer, msg->size);
974 nouveau_i2c(port)->release(port);
975 if (ret >= 0) {
976 msg->reply = ret;
977 return msg->size;
978 }
979
980 return ret;
981}
982
949static int 983static int
950drm_conntype_from_dcb(enum dcb_connector_type dcb) 984drm_conntype_from_dcb(enum dcb_connector_type dcb)
951{ 985{
@@ -1066,8 +1100,8 @@ nouveau_connector_create(struct drm_device *dev, int index)
1066 } 1100 }
1067 } 1101 }
1068 1102
1069 type = drm_conntype_from_dcb(nv_connector->type); 1103 switch ((type = drm_conntype_from_dcb(nv_connector->type))) {
1070 if (type == DRM_MODE_CONNECTOR_LVDS) { 1104 case DRM_MODE_CONNECTOR_LVDS:
1071 ret = nouveau_bios_parse_lvds_table(dev, 0, &dummy, &dummy); 1105 ret = nouveau_bios_parse_lvds_table(dev, 0, &dummy, &dummy);
1072 if (ret) { 1106 if (ret) {
1073 NV_ERROR(drm, "Error parsing LVDS table, disabling\n"); 1107 NV_ERROR(drm, "Error parsing LVDS table, disabling\n");
@@ -1076,8 +1110,23 @@ nouveau_connector_create(struct drm_device *dev, int index)
1076 } 1110 }
1077 1111
1078 funcs = &nouveau_connector_funcs_lvds; 1112 funcs = &nouveau_connector_funcs_lvds;
1079 } else { 1113 break;
1114 case DRM_MODE_CONNECTOR_DisplayPort:
1115 case DRM_MODE_CONNECTOR_eDP:
1116 nv_connector->aux.dev = dev->dev;
1117 nv_connector->aux.transfer = nouveau_connector_aux_xfer;
1118 ret = drm_dp_aux_register(&nv_connector->aux);
1119 if (ret) {
1120 NV_ERROR(drm, "failed to register aux channel\n");
1121 kfree(nv_connector);
1122 return ERR_PTR(ret);
1123 }
1124
1080 funcs = &nouveau_connector_funcs; 1125 funcs = &nouveau_connector_funcs;
1126 break;
1127 default:
1128 funcs = &nouveau_connector_funcs;
1129 break;
1081 } 1130 }
1082 1131
1083 /* defaults, will get overridden in detect() */ 1132 /* defaults, will get overridden in detect() */
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.h b/drivers/gpu/drm/nouveau/nouveau_connector.h
index 7e7682dfa991..8861b6c579ad 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.h
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.h
@@ -28,6 +28,7 @@
28#define __NOUVEAU_CONNECTOR_H__ 28#define __NOUVEAU_CONNECTOR_H__
29 29
30#include <drm/drm_edid.h> 30#include <drm/drm_edid.h>
31#include <drm/drm_dp_helper.h>
31#include "nouveau_crtc.h" 32#include "nouveau_crtc.h"
32 33
33#include <core/event.h> 34#include <core/event.h>
@@ -70,6 +71,8 @@ struct nouveau_connector {
70 u32 status; 71 u32 status;
71 struct work_struct work; 72 struct work_struct work;
72 73
74 struct drm_dp_aux aux;
75
73 int dithering_mode; 76 int dithering_mode;
74 int dithering_depth; 77 int dithering_depth;
75 int scaling_mode; 78 int scaling_mode;