diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_connector.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_connector.c | 60 |
1 files changed, 26 insertions, 34 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index dbdc9ad59546..1ec44c83e919 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c | |||
@@ -42,9 +42,7 @@ | |||
42 | #include "nouveau_encoder.h" | 42 | #include "nouveau_encoder.h" |
43 | #include "nouveau_crtc.h" | 43 | #include "nouveau_crtc.h" |
44 | 44 | ||
45 | #include <subdev/i2c.h> | 45 | #include <nvif/event.h> |
46 | #include <subdev/gpio.h> | ||
47 | #include <engine/disp.h> | ||
48 | 46 | ||
49 | MODULE_PARM_DESC(tv_disable, "Disable TV-out detection"); | 47 | MODULE_PARM_DESC(tv_disable, "Disable TV-out detection"); |
50 | static int nouveau_tv_disable = 0; | 48 | static int nouveau_tv_disable = 0; |
@@ -102,7 +100,7 @@ static void | |||
102 | nouveau_connector_destroy(struct drm_connector *connector) | 100 | nouveau_connector_destroy(struct drm_connector *connector) |
103 | { | 101 | { |
104 | struct nouveau_connector *nv_connector = nouveau_connector(connector); | 102 | struct nouveau_connector *nv_connector = nouveau_connector(connector); |
105 | nouveau_event_ref(NULL, &nv_connector->hpd); | 103 | nvif_notify_fini(&nv_connector->hpd); |
106 | kfree(nv_connector->edid); | 104 | kfree(nv_connector->edid); |
107 | drm_connector_unregister(connector); | 105 | drm_connector_unregister(connector); |
108 | drm_connector_cleanup(connector); | 106 | drm_connector_cleanup(connector); |
@@ -117,7 +115,7 @@ nouveau_connector_ddc_detect(struct drm_connector *connector) | |||
117 | struct drm_device *dev = connector->dev; | 115 | struct drm_device *dev = connector->dev; |
118 | struct nouveau_connector *nv_connector = nouveau_connector(connector); | 116 | struct nouveau_connector *nv_connector = nouveau_connector(connector); |
119 | struct nouveau_drm *drm = nouveau_drm(dev); | 117 | struct nouveau_drm *drm = nouveau_drm(dev); |
120 | struct nouveau_gpio *gpio = nouveau_gpio(drm->device); | 118 | struct nouveau_gpio *gpio = nvkm_gpio(&drm->device); |
121 | struct nouveau_encoder *nv_encoder; | 119 | struct nouveau_encoder *nv_encoder; |
122 | struct drm_encoder *encoder; | 120 | struct drm_encoder *encoder; |
123 | int i, panel = -ENODEV; | 121 | int i, panel = -ENODEV; |
@@ -206,7 +204,7 @@ nouveau_connector_set_encoder(struct drm_connector *connector, | |||
206 | return; | 204 | return; |
207 | nv_connector->detected_encoder = nv_encoder; | 205 | nv_connector->detected_encoder = nv_encoder; |
208 | 206 | ||
209 | if (nv_device(drm->device)->card_type >= NV_50) { | 207 | if (drm->device.info.family >= NV_DEVICE_INFO_V0_TESLA) { |
210 | connector->interlace_allowed = true; | 208 | connector->interlace_allowed = true; |
211 | connector->doublescan_allowed = true; | 209 | connector->doublescan_allowed = true; |
212 | } else | 210 | } else |
@@ -216,9 +214,8 @@ nouveau_connector_set_encoder(struct drm_connector *connector, | |||
216 | connector->interlace_allowed = false; | 214 | connector->interlace_allowed = false; |
217 | } else { | 215 | } else { |
218 | connector->doublescan_allowed = true; | 216 | connector->doublescan_allowed = true; |
219 | if (nv_device(drm->device)->card_type == NV_20 || | 217 | if (drm->device.info.family == NV_DEVICE_INFO_V0_KELVIN || |
220 | ((nv_device(drm->device)->card_type == NV_10 || | 218 | (drm->device.info.family == NV_DEVICE_INFO_V0_CELSIUS && |
221 | nv_device(drm->device)->card_type == NV_11) && | ||
222 | (dev->pdev->device & 0x0ff0) != 0x0100 && | 219 | (dev->pdev->device & 0x0ff0) != 0x0100 && |
223 | (dev->pdev->device & 0x0ff0) != 0x0150)) | 220 | (dev->pdev->device & 0x0ff0) != 0x0150)) |
224 | /* HW is broken */ | 221 | /* HW is broken */ |
@@ -802,11 +799,11 @@ get_tmds_link_bandwidth(struct drm_connector *connector) | |||
802 | struct dcb_output *dcb = nv_connector->detected_encoder->dcb; | 799 | struct dcb_output *dcb = nv_connector->detected_encoder->dcb; |
803 | 800 | ||
804 | if (dcb->location != DCB_LOC_ON_CHIP || | 801 | if (dcb->location != DCB_LOC_ON_CHIP || |
805 | nv_device(drm->device)->chipset >= 0x46) | 802 | drm->device.info.chipset >= 0x46) |
806 | return 165000; | 803 | return 165000; |
807 | else if (nv_device(drm->device)->chipset >= 0x40) | 804 | else if (drm->device.info.chipset >= 0x40) |
808 | return 155000; | 805 | return 155000; |
809 | else if (nv_device(drm->device)->chipset >= 0x18) | 806 | else if (drm->device.info.chipset >= 0x18) |
810 | return 135000; | 807 | return 135000; |
811 | else | 808 | else |
812 | return 112000; | 809 | return 112000; |
@@ -939,18 +936,19 @@ nouveau_connector_funcs_dp = { | |||
939 | .force = nouveau_connector_force | 936 | .force = nouveau_connector_force |
940 | }; | 937 | }; |
941 | 938 | ||
942 | static void | 939 | static int |
943 | nouveau_connector_hotplug_work(struct work_struct *work) | 940 | nouveau_connector_hotplug(struct nvif_notify *notify) |
944 | { | 941 | { |
945 | struct nouveau_connector *nv_connector = | 942 | struct nouveau_connector *nv_connector = |
946 | container_of(work, typeof(*nv_connector), work); | 943 | container_of(notify, typeof(*nv_connector), hpd); |
947 | struct drm_connector *connector = &nv_connector->base; | 944 | struct drm_connector *connector = &nv_connector->base; |
948 | struct nouveau_drm *drm = nouveau_drm(connector->dev); | 945 | struct nouveau_drm *drm = nouveau_drm(connector->dev); |
946 | const struct nvif_notify_conn_rep_v0 *rep = notify->data; | ||
949 | const char *name = connector->name; | 947 | const char *name = connector->name; |
950 | 948 | ||
951 | if (nv_connector->status & NVKM_HPD_IRQ) { | 949 | if (rep->mask & NVIF_NOTIFY_CONN_V0_IRQ) { |
952 | } else { | 950 | } else { |
953 | bool plugged = (nv_connector->status != NVKM_HPD_UNPLUG); | 951 | bool plugged = (rep->mask != NVIF_NOTIFY_CONN_V0_UNPLUG); |
954 | 952 | ||
955 | NV_DEBUG(drm, "%splugged %s\n", plugged ? "" : "un", name); | 953 | NV_DEBUG(drm, "%splugged %s\n", plugged ? "" : "un", name); |
956 | 954 | ||
@@ -961,16 +959,7 @@ nouveau_connector_hotplug_work(struct work_struct *work) | |||
961 | drm_helper_hpd_irq_event(connector->dev); | 959 | drm_helper_hpd_irq_event(connector->dev); |
962 | } | 960 | } |
963 | 961 | ||
964 | nouveau_event_get(nv_connector->hpd); | 962 | return NVIF_NOTIFY_KEEP; |
965 | } | ||
966 | |||
967 | static int | ||
968 | nouveau_connector_hotplug(void *data, u32 type, int index) | ||
969 | { | ||
970 | struct nouveau_connector *nv_connector = data; | ||
971 | nv_connector->status = type; | ||
972 | schedule_work(&nv_connector->work); | ||
973 | return NVKM_EVENT_DROP; | ||
974 | } | 963 | } |
975 | 964 | ||
976 | static ssize_t | 965 | static ssize_t |
@@ -1040,7 +1029,6 @@ nouveau_connector_create(struct drm_device *dev, int index) | |||
1040 | struct nouveau_drm *drm = nouveau_drm(dev); | 1029 | struct nouveau_drm *drm = nouveau_drm(dev); |
1041 | struct nouveau_display *disp = nouveau_display(dev); | 1030 | struct nouveau_display *disp = nouveau_display(dev); |
1042 | struct nouveau_connector *nv_connector = NULL; | 1031 | struct nouveau_connector *nv_connector = NULL; |
1043 | struct nouveau_disp *pdisp = nouveau_disp(drm->device); | ||
1044 | struct drm_connector *connector; | 1032 | struct drm_connector *connector; |
1045 | int type, ret = 0; | 1033 | int type, ret = 0; |
1046 | bool dummy; | 1034 | bool dummy; |
@@ -1194,7 +1182,7 @@ nouveau_connector_create(struct drm_device *dev, int index) | |||
1194 | 1182 | ||
1195 | switch (nv_connector->type) { | 1183 | switch (nv_connector->type) { |
1196 | case DCB_CONNECTOR_VGA: | 1184 | case DCB_CONNECTOR_VGA: |
1197 | if (nv_device(drm->device)->card_type >= NV_50) { | 1185 | if (drm->device.info.family >= NV_DEVICE_INFO_V0_TESLA) { |
1198 | drm_object_attach_property(&connector->base, | 1186 | drm_object_attach_property(&connector->base, |
1199 | dev->mode_config.scaling_mode_property, | 1187 | dev->mode_config.scaling_mode_property, |
1200 | nv_connector->scaling_mode); | 1188 | nv_connector->scaling_mode); |
@@ -1226,16 +1214,20 @@ nouveau_connector_create(struct drm_device *dev, int index) | |||
1226 | break; | 1214 | break; |
1227 | } | 1215 | } |
1228 | 1216 | ||
1229 | ret = nouveau_event_new(pdisp->hpd, NVKM_HPD, index, | 1217 | ret = nvif_notify_init(&disp->disp, NULL, nouveau_connector_hotplug, |
1230 | nouveau_connector_hotplug, | 1218 | true, NV04_DISP_NTFY_CONN, |
1231 | nv_connector, &nv_connector->hpd); | 1219 | &(struct nvif_notify_conn_req_v0) { |
1220 | .mask = NVIF_NOTIFY_CONN_V0_ANY, | ||
1221 | .conn = index, | ||
1222 | }, | ||
1223 | sizeof(struct nvif_notify_conn_req_v0), | ||
1224 | sizeof(struct nvif_notify_conn_rep_v0), | ||
1225 | &nv_connector->hpd); | ||
1232 | if (ret) | 1226 | if (ret) |
1233 | connector->polled = DRM_CONNECTOR_POLL_CONNECT; | 1227 | connector->polled = DRM_CONNECTOR_POLL_CONNECT; |
1234 | else | 1228 | else |
1235 | connector->polled = DRM_CONNECTOR_POLL_HPD; | 1229 | connector->polled = DRM_CONNECTOR_POLL_HPD; |
1236 | 1230 | ||
1237 | INIT_WORK(&nv_connector->work, nouveau_connector_hotplug_work); | ||
1238 | |||
1239 | drm_connector_register(connector); | 1231 | drm_connector_register(connector); |
1240 | return connector; | 1232 | return connector; |
1241 | } | 1233 | } |