diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2014-05-30 02:20:58 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2014-06-11 02:11:04 -0400 |
commit | 8894f4919bc43f821775db2cfff4b917871b2102 (patch) | |
tree | de56e4e07318893cbc58d1b89cc7ca0664ebd5f9 | |
parent | ebd6acbb068b6558735eb80aabce1e7af9e78e1e (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.c | 55 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_connector.h | 3 |
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 | ||
951 | static ssize_t | ||
952 | nouveau_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 | |||
949 | static int | 983 | static int |
950 | drm_conntype_from_dcb(enum dcb_connector_type dcb) | 984 | drm_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; |