Loading drivers/gpu/drm/nouveau/nouveau_connector.c +52 −3 Original line number Diff line number Diff line Loading @@ -105,6 +105,8 @@ nouveau_connector_destroy(struct drm_connector *connector) kfree(nv_connector->edid); drm_sysfs_connector_remove(connector); drm_connector_cleanup(connector); if (nv_connector->aux.transfer) drm_dp_aux_unregister(&nv_connector->aux); kfree(connector); } Loading Loading @@ -946,6 +948,38 @@ nouveau_connector_hotplug(void *data, u32 type, int index) 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 drm_conntype_from_dcb(enum dcb_connector_type dcb) { Loading Loading @@ -1066,8 +1100,8 @@ nouveau_connector_create(struct drm_device *dev, int index) } } type = drm_conntype_from_dcb(nv_connector->type); if (type == DRM_MODE_CONNECTOR_LVDS) { switch ((type = drm_conntype_from_dcb(nv_connector->type))) { case DRM_MODE_CONNECTOR_LVDS: ret = nouveau_bios_parse_lvds_table(dev, 0, &dummy, &dummy); if (ret) { NV_ERROR(drm, "Error parsing LVDS table, disabling\n"); Loading @@ -1076,8 +1110,23 @@ nouveau_connector_create(struct drm_device *dev, int index) } 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; break; default: funcs = &nouveau_connector_funcs; break; } /* defaults, will get overridden in detect() */ Loading drivers/gpu/drm/nouveau/nouveau_connector.h +3 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ #define __NOUVEAU_CONNECTOR_H__ #include <drm/drm_edid.h> #include <drm/drm_dp_helper.h> #include "nouveau_crtc.h" #include <core/event.h> Loading Loading @@ -70,6 +71,8 @@ struct nouveau_connector { u32 status; struct work_struct work; struct drm_dp_aux aux; int dithering_mode; int dithering_depth; int scaling_mode; Loading Loading
drivers/gpu/drm/nouveau/nouveau_connector.c +52 −3 Original line number Diff line number Diff line Loading @@ -105,6 +105,8 @@ nouveau_connector_destroy(struct drm_connector *connector) kfree(nv_connector->edid); drm_sysfs_connector_remove(connector); drm_connector_cleanup(connector); if (nv_connector->aux.transfer) drm_dp_aux_unregister(&nv_connector->aux); kfree(connector); } Loading Loading @@ -946,6 +948,38 @@ nouveau_connector_hotplug(void *data, u32 type, int index) 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 drm_conntype_from_dcb(enum dcb_connector_type dcb) { Loading Loading @@ -1066,8 +1100,8 @@ nouveau_connector_create(struct drm_device *dev, int index) } } type = drm_conntype_from_dcb(nv_connector->type); if (type == DRM_MODE_CONNECTOR_LVDS) { switch ((type = drm_conntype_from_dcb(nv_connector->type))) { case DRM_MODE_CONNECTOR_LVDS: ret = nouveau_bios_parse_lvds_table(dev, 0, &dummy, &dummy); if (ret) { NV_ERROR(drm, "Error parsing LVDS table, disabling\n"); Loading @@ -1076,8 +1110,23 @@ nouveau_connector_create(struct drm_device *dev, int index) } 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; break; default: funcs = &nouveau_connector_funcs; break; } /* defaults, will get overridden in detect() */ Loading
drivers/gpu/drm/nouveau/nouveau_connector.h +3 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ #define __NOUVEAU_CONNECTOR_H__ #include <drm/drm_edid.h> #include <drm/drm_dp_helper.h> #include "nouveau_crtc.h" #include <core/event.h> Loading Loading @@ -70,6 +71,8 @@ struct nouveau_connector { u32 status; struct work_struct work; struct drm_dp_aux aux; int dithering_mode; int dithering_depth; int scaling_mode; Loading