aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'linux-core/nv50_connector.c')
-rw-r--r--linux-core/nv50_connector.c245
1 files changed, 0 insertions, 245 deletions
diff --git a/linux-core/nv50_connector.c b/linux-core/nv50_connector.c
deleted file mode 100644
index 34706bae..00000000
--- a/linux-core/nv50_connector.c
+++ /dev/null
@@ -1,245 +0,0 @@
1/*
2 * Copyright (C) 2008 Maarten Maathuis.
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial
15 * portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 *
25 */
26
27#include "nv50_connector.h"
28
29static struct nv50_output *nv50_connector_to_output(struct nv50_connector *connector, bool digital)
30{
31 struct nv50_display *display = nv50_get_display(connector->dev);
32 struct nv50_output *output = NULL;
33 bool digital_possible = false;
34 bool analog_possible = false;
35
36 switch (connector->type) {
37 case CONNECTOR_VGA:
38 case CONNECTOR_TV:
39 analog_possible = true;
40 break;
41 case CONNECTOR_DVI_I:
42 analog_possible = true;
43 digital_possible = true;
44 break;
45 case CONNECTOR_DVI_D:
46 case CONNECTOR_LVDS:
47 digital_possible = true;
48 break;
49 default:
50 break;
51 }
52
53 /* Return early on bad situations. */
54 if (!analog_possible && !digital_possible)
55 return NULL;
56
57 if (!analog_possible && !digital)
58 return NULL;
59
60 if (!digital_possible && digital)
61 return NULL;
62
63 list_for_each_entry(output, &display->outputs, item) {
64 if (connector->bus != output->bus)
65 continue;
66 if (digital && output->type == OUTPUT_TMDS)
67 return output;
68 if (digital && output->type == OUTPUT_LVDS)
69 return output;
70 if (!digital && output->type == OUTPUT_DAC)
71 return output;
72 if (!digital && output->type == OUTPUT_TV)
73 return output;
74 }
75
76 return NULL;
77}
78
79static int nv50_connector_hpd_detect(struct nv50_connector *connector)
80{
81 struct drm_nouveau_private *dev_priv = connector->dev->dev_private;
82 bool present = 0;
83 uint32_t reg = 0;
84
85 /* Assume connected for the moment. */
86 if (connector->type == CONNECTOR_LVDS) {
87 NV50_DEBUG("LVDS is defaulting to connected for the moment.\n");
88 return 1;
89 }
90
91 /* No i2c port, no idea what to do for hotplug. */
92 if (connector->i2c_chan->index == 15) {
93 DRM_ERROR("You have a non-LVDS SOR with no i2c port, please report\n");
94 return -EINVAL;
95 }
96
97 if (connector->i2c_chan->index > 3) {
98 DRM_ERROR("You have an unusual configuration, index is %d\n", connector->i2c_chan->index);
99 DRM_ERROR("Please report.\n");
100 return -EINVAL;
101 }
102
103 /* Check hotplug pins. */
104 reg = NV_READ(NV50_PCONNECTOR_HOTPLUG_STATE);
105 if (reg & (NV50_PCONNECTOR_HOTPLUG_STATE_PIN_CONNECTED_I2C0 << (4 * connector->i2c_chan->index)))
106 present = 1;
107
108 if (present)
109 NV50_DEBUG("Hotplug detect returned positive for bus %d\n", connector->bus);
110 else
111 NV50_DEBUG("Hotplug detect returned negative for bus %d\n", connector->bus);
112
113 return present;
114}
115
116static int nv50_connector_i2c_detect(struct nv50_connector *connector)
117{
118 /* kindly borrrowed from the intel driver, hope it works. */
119 uint8_t out_buf[] = { 0x0, 0x0};
120 uint8_t buf[2];
121 int ret;
122 struct i2c_msg msgs[] = {
123 {
124 .addr = 0x50,
125 .flags = 0,
126 .len = 1,
127 .buf = out_buf,
128 },
129 {
130 .addr = 0x50,
131 .flags = I2C_M_RD,
132 .len = 1,
133 .buf = buf,
134 }
135 };
136
137 if (!connector->i2c_chan)
138 return -EINVAL;
139
140 ret = i2c_transfer(&connector->i2c_chan->adapter, msgs, 2);
141 NV50_DEBUG("I2C detect returned %d\n", ret);
142
143 if (ret == 2)
144 return true;
145
146 return false;
147}
148
149static int nv50_connector_destroy(struct nv50_connector *connector)
150{
151 struct drm_device *dev = connector->dev;
152 struct drm_nouveau_private *dev_priv = dev->dev_private;
153 struct nv50_display *display = nv50_get_display(dev);
154
155 NV50_DEBUG("\n");
156
157 if (!display || !connector)
158 return -EINVAL;
159
160 list_del(&connector->item);
161
162 if (connector->i2c_chan)
163 nv50_i2c_channel_destroy(connector->i2c_chan);
164
165 if (dev_priv->free_connector)
166 dev_priv->free_connector(connector);
167
168 return 0;
169}
170
171int nv50_connector_create(struct drm_device *dev, int bus, int i2c_index, int type)
172{
173 struct nv50_connector *connector = NULL;
174 struct drm_nouveau_private *dev_priv = dev->dev_private;
175 struct nv50_display *display = NULL;
176
177 NV50_DEBUG("\n");
178
179 /* This allows the public layer to do it's thing. */
180 if (dev_priv->alloc_connector)
181 connector = dev_priv->alloc_connector(dev);
182
183 if (!connector)
184 return -ENOMEM;
185
186 connector->dev = dev;
187
188 display = nv50_get_display(dev);
189 if (!display)
190 goto out;
191
192 if (type == CONNECTOR_UNKNOWN)
193 goto out;
194
195 list_add_tail(&connector->item, &display->connectors);
196
197 connector->bus = bus;
198 connector->type = type;
199
200 switch (type) {
201 case CONNECTOR_VGA:
202 DRM_INFO("Detected a VGA connector\n");
203 break;
204 case CONNECTOR_DVI_D:
205 DRM_INFO("Detected a DVI-D connector\n");
206 break;
207 case CONNECTOR_DVI_I:
208 DRM_INFO("Detected a DVI-I connector\n");
209 break;
210 case CONNECTOR_LVDS:
211 DRM_INFO("Detected a LVDS connector\n");
212 break;
213 case CONNECTOR_TV:
214 DRM_INFO("Detected a TV connector\n");
215 break;
216 default:
217 DRM_ERROR("Unknown connector, this is not good.\n");
218 break;
219 }
220
221 /* some reasonable defaults */
222 if (type == CONNECTOR_DVI_D || type == CONNECTOR_DVI_I || type == CONNECTOR_LVDS)
223 connector->requested_scaling_mode = SCALE_FULLSCREEN;
224 else
225 connector->requested_scaling_mode = SCALE_NON_GPU;
226
227 connector->use_dithering = false;
228
229 if (i2c_index < 0xf)
230 connector->i2c_chan = nv50_i2c_channel_create(dev, i2c_index);
231
232 /* set function pointers */
233 connector->hpd_detect = nv50_connector_hpd_detect;
234 connector->i2c_detect = nv50_connector_i2c_detect;
235 connector->destroy = nv50_connector_destroy;
236 connector->to_output = nv50_connector_to_output;
237
238 return 0;
239
240out:
241 if (dev_priv->free_connector)
242 dev_priv->free_connector(connector);
243
244 return -EINVAL;
245}