Rev 1123 | Rev 1129 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1123 | Rev 1126 | ||
---|---|---|---|
1 | /* |
1 | /* |
2 | * Copyright 2007-8 Advanced Micro Devices, Inc. |
2 | * Copyright 2007-8 Advanced Micro Devices, Inc. |
3 | * Copyright 2008 Red Hat Inc. |
3 | * Copyright 2008 Red Hat Inc. |
4 | * |
4 | * |
5 | * Permission is hereby granted, free of charge, to any person obtaining a |
5 | * Permission is hereby granted, free of charge, to any person obtaining a |
6 | * copy of this software and associated documentation files (the "Software"), |
6 | * copy of this software and associated documentation files (the "Software"), |
7 | * to deal in the Software without restriction, including without limitation |
7 | * to deal in the Software without restriction, including without limitation |
8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
9 | * and/or sell copies of the Software, and to permit persons to whom the |
9 | * and/or sell copies of the Software, and to permit persons to whom the |
10 | * Software is furnished to do so, subject to the following conditions: |
10 | * Software is furnished to do so, subject to the following conditions: |
11 | * |
11 | * |
12 | * The above copyright notice and this permission notice shall be included in |
12 | * The above copyright notice and this permission notice shall be included in |
13 | * all copies or substantial portions of the Software. |
13 | * all copies or substantial portions of the Software. |
14 | * |
14 | * |
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
18 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR |
18 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR |
19 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
19 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
20 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
20 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
21 | * OTHER DEALINGS IN THE SOFTWARE. |
21 | * OTHER DEALINGS IN THE SOFTWARE. |
22 | * |
22 | * |
23 | * Authors: Dave Airlie |
23 | * Authors: Dave Airlie |
24 | * Alex Deucher |
24 | * Alex Deucher |
25 | */ |
25 | */ |
26 | #include "drmP.h" |
26 | #include "drmP.h" |
27 | //#include "drm_edid.h" |
27 | #include "drm_edid.h" |
28 | #include "drm_crtc.h" |
- | |
29 | #include "drm_crtc_helper.h" |
28 | #include "drm_crtc_helper.h" |
30 | #include "radeon_drm.h" |
29 | #include "radeon_drm.h" |
31 | #include "radeon.h" |
30 | #include "radeon.h" |
32 | 31 | ||
33 | extern void |
32 | extern void |
34 | radeon_combios_connected_scratch_regs(struct drm_connector *connector, |
33 | radeon_combios_connected_scratch_regs(struct drm_connector *connector, |
35 | struct drm_encoder *encoder, |
34 | struct drm_encoder *encoder, |
36 | bool connected); |
35 | bool connected); |
37 | extern void |
36 | extern void |
38 | radeon_atombios_connected_scratch_regs(struct drm_connector *connector, |
37 | radeon_atombios_connected_scratch_regs(struct drm_connector *connector, |
39 | struct drm_encoder *encoder, |
38 | struct drm_encoder *encoder, |
40 | bool connected); |
39 | bool connected); |
41 | 40 | ||
42 | static void |
41 | static void |
43 | radeon_connector_update_scratch_regs(struct drm_connector *connector, enum drm_connector_status status) |
42 | radeon_connector_update_scratch_regs(struct drm_connector *connector, enum drm_connector_status status) |
44 | { |
43 | { |
45 | struct drm_device *dev = connector->dev; |
44 | struct drm_device *dev = connector->dev; |
46 | struct radeon_device *rdev = dev->dev_private; |
45 | struct radeon_device *rdev = dev->dev_private; |
47 | struct drm_encoder *best_encoder = NULL; |
46 | struct drm_encoder *best_encoder = NULL; |
48 | struct drm_encoder *encoder = NULL; |
47 | struct drm_encoder *encoder = NULL; |
49 | struct drm_connector_helper_funcs *connector_funcs = connector->helper_private; |
48 | struct drm_connector_helper_funcs *connector_funcs = connector->helper_private; |
50 | struct drm_mode_object *obj; |
49 | struct drm_mode_object *obj; |
51 | bool connected; |
50 | bool connected; |
52 | int i; |
51 | int i; |
53 | 52 | ||
54 | best_encoder = connector_funcs->best_encoder(connector); |
53 | best_encoder = connector_funcs->best_encoder(connector); |
55 | 54 | ||
56 | for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { |
55 | for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { |
57 | if (connector->encoder_ids[i] == 0) |
56 | if (connector->encoder_ids[i] == 0) |
58 | break; |
57 | break; |
59 | 58 | ||
60 | obj = drm_mode_object_find(connector->dev, |
59 | obj = drm_mode_object_find(connector->dev, |
61 | connector->encoder_ids[i], |
60 | connector->encoder_ids[i], |
62 | DRM_MODE_OBJECT_ENCODER); |
61 | DRM_MODE_OBJECT_ENCODER); |
63 | if (!obj) |
62 | if (!obj) |
64 | continue; |
63 | continue; |
65 | 64 | ||
66 | encoder = obj_to_encoder(obj); |
65 | encoder = obj_to_encoder(obj); |
67 | 66 | ||
68 | if ((encoder == best_encoder) && (status == connector_status_connected)) |
67 | if ((encoder == best_encoder) && (status == connector_status_connected)) |
69 | connected = true; |
68 | connected = true; |
70 | else |
69 | else |
71 | connected = false; |
70 | connected = false; |
72 | 71 | ||
73 | if (rdev->is_atom_bios) |
72 | if (rdev->is_atom_bios) |
74 | radeon_atombios_connected_scratch_regs(connector, encoder, connected); |
73 | radeon_atombios_connected_scratch_regs(connector, encoder, connected); |
75 | else |
74 | else |
76 | radeon_combios_connected_scratch_regs(connector, encoder, connected); |
75 | radeon_combios_connected_scratch_regs(connector, encoder, connected); |
77 | 76 | ||
78 | } |
77 | } |
79 | } |
78 | } |
80 | 79 | ||
81 | struct drm_encoder *radeon_best_single_encoder(struct drm_connector *connector) |
80 | struct drm_encoder *radeon_best_single_encoder(struct drm_connector *connector) |
82 | { |
81 | { |
83 | int enc_id = connector->encoder_ids[0]; |
82 | int enc_id = connector->encoder_ids[0]; |
84 | struct drm_mode_object *obj; |
83 | struct drm_mode_object *obj; |
85 | struct drm_encoder *encoder; |
84 | struct drm_encoder *encoder; |
- | 85 | ||
- | 86 | ENTRY(); |
|
86 | 87 | ||
87 | /* pick the encoder ids */ |
88 | /* pick the encoder ids */ |
88 | if (enc_id) { |
89 | if (enc_id) { |
89 | obj = drm_mode_object_find(connector->dev, enc_id, DRM_MODE_OBJECT_ENCODER); |
90 | obj = drm_mode_object_find(connector->dev, enc_id, DRM_MODE_OBJECT_ENCODER); |
90 | if (!obj) |
91 | if (!obj) |
91 | return NULL; |
92 | return NULL; |
92 | encoder = obj_to_encoder(obj); |
93 | encoder = obj_to_encoder(obj); |
93 | return encoder; |
94 | return encoder; |
94 | } |
95 | } |
95 | return NULL; |
96 | return NULL; |
96 | } |
97 | } |
97 | 98 | ||
98 | static struct drm_display_mode *radeon_fp_native_mode(struct drm_encoder *encoder) |
99 | static struct drm_display_mode *radeon_fp_native_mode(struct drm_encoder *encoder) |
99 | { |
100 | { |
100 | struct drm_device *dev = encoder->dev; |
101 | struct drm_device *dev = encoder->dev; |
101 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
102 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
102 | struct drm_display_mode *mode = NULL; |
103 | struct drm_display_mode *mode = NULL; |
103 | struct radeon_native_mode *native_mode = &radeon_encoder->native_mode; |
104 | struct radeon_native_mode *native_mode = &radeon_encoder->native_mode; |
104 | 105 | ||
105 | if (native_mode->panel_xres != 0 && |
106 | if (native_mode->panel_xres != 0 && |
106 | native_mode->panel_yres != 0 && |
107 | native_mode->panel_yres != 0 && |
107 | native_mode->dotclock != 0) { |
108 | native_mode->dotclock != 0) { |
108 | mode = drm_mode_create(dev); |
109 | mode = drm_mode_create(dev); |
109 | 110 | ||
110 | mode->hdisplay = native_mode->panel_xres; |
111 | mode->hdisplay = native_mode->panel_xres; |
111 | mode->vdisplay = native_mode->panel_yres; |
112 | mode->vdisplay = native_mode->panel_yres; |
112 | 113 | ||
113 | mode->htotal = mode->hdisplay + native_mode->hblank; |
114 | mode->htotal = mode->hdisplay + native_mode->hblank; |
114 | mode->hsync_start = mode->hdisplay + native_mode->hoverplus; |
115 | mode->hsync_start = mode->hdisplay + native_mode->hoverplus; |
115 | mode->hsync_end = mode->hsync_start + native_mode->hsync_width; |
116 | mode->hsync_end = mode->hsync_start + native_mode->hsync_width; |
116 | mode->vtotal = mode->vdisplay + native_mode->vblank; |
117 | mode->vtotal = mode->vdisplay + native_mode->vblank; |
117 | mode->vsync_start = mode->vdisplay + native_mode->voverplus; |
118 | mode->vsync_start = mode->vdisplay + native_mode->voverplus; |
118 | mode->vsync_end = mode->vsync_start + native_mode->vsync_width; |
119 | mode->vsync_end = mode->vsync_start + native_mode->vsync_width; |
119 | mode->clock = native_mode->dotclock; |
120 | mode->clock = native_mode->dotclock; |
120 | mode->flags = 0; |
121 | mode->flags = 0; |
121 | 122 | ||
122 | mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER; |
123 | mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER; |
123 | drm_mode_set_name(mode); |
124 | drm_mode_set_name(mode); |
124 | 125 | ||
125 | DRM_DEBUG("Adding native panel mode %s\n", mode->name); |
126 | DRM_DEBUG("Adding native panel mode %s\n", mode->name); |
126 | } |
127 | } |
127 | return mode; |
128 | return mode; |
128 | } |
129 | } |
129 | 130 | ||
130 | int radeon_connector_set_property(struct drm_connector *connector, struct drm_property *property, |
131 | int radeon_connector_set_property(struct drm_connector *connector, struct drm_property *property, |
131 | uint64_t val) |
132 | uint64_t val) |
132 | { |
133 | { |
133 | return 0; |
134 | return 0; |
134 | } |
135 | } |
135 | 136 | ||
136 | 137 | ||
137 | static int radeon_lvds_get_modes(struct drm_connector *connector) |
138 | static int radeon_lvds_get_modes(struct drm_connector *connector) |
138 | { |
139 | { |
139 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
140 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
140 | struct drm_encoder *encoder; |
141 | struct drm_encoder *encoder; |
141 | int ret = 0; |
142 | int ret = 0; |
142 | struct drm_display_mode *mode; |
143 | struct drm_display_mode *mode; |
143 | 144 | ||
144 | if (radeon_connector->ddc_bus) { |
145 | if (radeon_connector->ddc_bus) { |
145 | ret = radeon_ddc_get_modes(radeon_connector); |
146 | ret = radeon_ddc_get_modes(radeon_connector); |
146 | if (ret > 0) { |
147 | if (ret > 0) { |
147 | return ret; |
148 | return ret; |
148 | } |
149 | } |
149 | } |
150 | } |
150 | 151 | ||
151 | encoder = radeon_best_single_encoder(connector); |
152 | encoder = radeon_best_single_encoder(connector); |
152 | if (!encoder) |
153 | if (!encoder) |
153 | return 0; |
154 | return 0; |
154 | 155 | ||
155 | /* we have no EDID modes */ |
156 | /* we have no EDID modes */ |
156 | mode = radeon_fp_native_mode(encoder); |
157 | mode = radeon_fp_native_mode(encoder); |
157 | if (mode) { |
158 | if (mode) { |
158 | ret = 1; |
159 | ret = 1; |
159 | drm_mode_probed_add(connector, mode); |
160 | drm_mode_probed_add(connector, mode); |
160 | } |
161 | } |
161 | return ret; |
162 | return ret; |
162 | } |
163 | } |
163 | 164 | ||
164 | static int radeon_lvds_mode_valid(struct drm_connector *connector, |
165 | static int radeon_lvds_mode_valid(struct drm_connector *connector, |
165 | struct drm_display_mode *mode) |
166 | struct drm_display_mode *mode) |
166 | { |
167 | { |
167 | return MODE_OK; |
168 | return MODE_OK; |
168 | } |
169 | } |
169 | 170 | ||
170 | static enum drm_connector_status radeon_lvds_detect(struct drm_connector *connector) |
171 | static enum drm_connector_status radeon_lvds_detect(struct drm_connector *connector) |
171 | { |
172 | { |
172 | enum drm_connector_status ret = connector_status_connected; |
173 | enum drm_connector_status ret = connector_status_connected; |
173 | /* check acpi lid status ??? */ |
174 | /* check acpi lid status ??? */ |
174 | radeon_connector_update_scratch_regs(connector, ret); |
175 | radeon_connector_update_scratch_regs(connector, ret); |
175 | return ret; |
176 | return ret; |
176 | } |
177 | } |
177 | 178 | ||
178 | static void radeon_connector_destroy(struct drm_connector *connector) |
179 | static void radeon_connector_destroy(struct drm_connector *connector) |
179 | { |
180 | { |
180 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
181 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
181 | 182 | ||
182 | if (radeon_connector->ddc_bus) |
183 | if (radeon_connector->ddc_bus) |
183 | radeon_i2c_destroy(radeon_connector->ddc_bus); |
184 | radeon_i2c_destroy(radeon_connector->ddc_bus); |
184 | kfree(radeon_connector->con_priv); |
185 | kfree(radeon_connector->con_priv); |
185 | // drm_sysfs_connector_remove(connector); |
186 | // drm_sysfs_connector_remove(connector); |
186 | drm_connector_cleanup(connector); |
187 | drm_connector_cleanup(connector); |
187 | kfree(connector); |
188 | kfree(connector); |
188 | } |
189 | } |
189 | 190 | ||
190 | struct drm_connector_helper_funcs radeon_lvds_connector_helper_funcs = { |
191 | struct drm_connector_helper_funcs radeon_lvds_connector_helper_funcs = { |
191 | .get_modes = radeon_lvds_get_modes, |
192 | .get_modes = radeon_lvds_get_modes, |
192 | .mode_valid = radeon_lvds_mode_valid, |
193 | .mode_valid = radeon_lvds_mode_valid, |
193 | .best_encoder = radeon_best_single_encoder, |
194 | .best_encoder = radeon_best_single_encoder, |
194 | }; |
195 | }; |
195 | 196 | ||
196 | struct drm_connector_funcs radeon_lvds_connector_funcs = { |
197 | struct drm_connector_funcs radeon_lvds_connector_funcs = { |
197 | .dpms = drm_helper_connector_dpms, |
198 | .dpms = drm_helper_connector_dpms, |
198 | .detect = radeon_lvds_detect, |
199 | .detect = radeon_lvds_detect, |
199 | .fill_modes = drm_helper_probe_single_connector_modes, |
200 | .fill_modes = drm_helper_probe_single_connector_modes, |
200 | .destroy = radeon_connector_destroy, |
201 | .destroy = radeon_connector_destroy, |
201 | .set_property = radeon_connector_set_property, |
202 | .set_property = radeon_connector_set_property, |
202 | }; |
203 | }; |
203 | 204 | ||
204 | static int radeon_vga_get_modes(struct drm_connector *connector) |
205 | static int radeon_vga_get_modes(struct drm_connector *connector) |
205 | { |
206 | { |
206 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
207 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
207 | int ret; |
208 | int ret; |
208 | 209 | ||
209 | ret = radeon_ddc_get_modes(radeon_connector); |
210 | ret = radeon_ddc_get_modes(radeon_connector); |
210 | 211 | ||
211 | return ret; |
212 | return ret; |
212 | } |
213 | } |
213 | 214 | ||
214 | static int radeon_vga_mode_valid(struct drm_connector *connector, |
215 | static int radeon_vga_mode_valid(struct drm_connector *connector, |
215 | struct drm_display_mode *mode) |
216 | struct drm_display_mode *mode) |
216 | { |
217 | { |
217 | 218 | ||
218 | return MODE_OK; |
219 | return MODE_OK; |
219 | } |
220 | } |
220 | 221 | ||
221 | static enum drm_connector_status radeon_vga_detect(struct drm_connector *connector) |
222 | static enum drm_connector_status radeon_vga_detect(struct drm_connector *connector) |
222 | { |
223 | { |
223 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
224 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
224 | struct drm_encoder *encoder; |
225 | struct drm_encoder *encoder; |
225 | struct drm_encoder_helper_funcs *encoder_funcs; |
226 | struct drm_encoder_helper_funcs *encoder_funcs; |
226 | bool dret; |
227 | bool dret; |
227 | enum drm_connector_status ret = connector_status_disconnected; |
228 | enum drm_connector_status ret = connector_status_disconnected; |
228 | 229 | ||
229 | radeon_i2c_do_lock(radeon_connector, 1); |
230 | radeon_i2c_do_lock(radeon_connector, 1); |
230 | dret = radeon_ddc_probe(radeon_connector); |
231 | dret = radeon_ddc_probe(radeon_connector); |
231 | radeon_i2c_do_lock(radeon_connector, 0); |
232 | radeon_i2c_do_lock(radeon_connector, 0); |
232 | if (dret) |
233 | if (dret) |
233 | ret = connector_status_connected; |
234 | ret = connector_status_connected; |
234 | else { |
235 | else { |
235 | /* if EDID fails to a load detect */ |
236 | /* if EDID fails to a load detect */ |
236 | encoder = radeon_best_single_encoder(connector); |
237 | encoder = radeon_best_single_encoder(connector); |
237 | if (!encoder) |
238 | if (!encoder) |
238 | ret = connector_status_disconnected; |
239 | ret = connector_status_disconnected; |
239 | else { |
240 | else { |
240 | encoder_funcs = encoder->helper_private; |
241 | encoder_funcs = encoder->helper_private; |
241 | ret = encoder_funcs->detect(encoder, connector); |
242 | ret = encoder_funcs->detect(encoder, connector); |
242 | } |
243 | } |
243 | } |
244 | } |
244 | 245 | ||
245 | radeon_connector_update_scratch_regs(connector, ret); |
246 | radeon_connector_update_scratch_regs(connector, ret); |
246 | return ret; |
247 | return ret; |
247 | } |
248 | } |
248 | 249 | ||
249 | struct drm_connector_helper_funcs radeon_vga_connector_helper_funcs = { |
250 | struct drm_connector_helper_funcs radeon_vga_connector_helper_funcs = { |
250 | .get_modes = radeon_vga_get_modes, |
251 | .get_modes = radeon_vga_get_modes, |
251 | .mode_valid = radeon_vga_mode_valid, |
252 | .mode_valid = radeon_vga_mode_valid, |
252 | .best_encoder = radeon_best_single_encoder, |
253 | .best_encoder = radeon_best_single_encoder, |
253 | }; |
254 | }; |
254 | 255 | ||
255 | struct drm_connector_funcs radeon_vga_connector_funcs = { |
256 | struct drm_connector_funcs radeon_vga_connector_funcs = { |
256 | .dpms = drm_helper_connector_dpms, |
257 | .dpms = drm_helper_connector_dpms, |
257 | .detect = radeon_vga_detect, |
258 | .detect = radeon_vga_detect, |
258 | .fill_modes = drm_helper_probe_single_connector_modes, |
259 | .fill_modes = drm_helper_probe_single_connector_modes, |
259 | .destroy = radeon_connector_destroy, |
260 | .destroy = radeon_connector_destroy, |
260 | .set_property = radeon_connector_set_property, |
261 | .set_property = radeon_connector_set_property, |
261 | }; |
262 | }; |
262 | 263 | ||
263 | static int radeon_dvi_get_modes(struct drm_connector *connector) |
264 | static int radeon_dvi_get_modes(struct drm_connector *connector) |
264 | { |
265 | { |
265 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
266 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
266 | int ret; |
267 | int ret; |
267 | 268 | ||
268 | ret = radeon_ddc_get_modes(radeon_connector); |
269 | ret = radeon_ddc_get_modes(radeon_connector); |
269 | /* reset scratch regs here since radeon_dvi_detect doesn't check digital bit */ |
270 | /* reset scratch regs here since radeon_dvi_detect doesn't check digital bit */ |
270 | radeon_connector_update_scratch_regs(connector, connector_status_connected); |
271 | radeon_connector_update_scratch_regs(connector, connector_status_connected); |
271 | return ret; |
272 | return ret; |
272 | } |
273 | } |
273 | 274 | ||
274 | static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connector) |
275 | static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connector) |
275 | { |
276 | { |
276 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
277 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
277 | struct drm_encoder *encoder; |
278 | struct drm_encoder *encoder; |
278 | struct drm_encoder_helper_funcs *encoder_funcs; |
279 | struct drm_encoder_helper_funcs *encoder_funcs; |
279 | struct drm_mode_object *obj; |
280 | struct drm_mode_object *obj; |
280 | int i; |
281 | int i; |
281 | enum drm_connector_status ret = connector_status_disconnected; |
282 | enum drm_connector_status ret = connector_status_disconnected; |
282 | bool dret; |
283 | bool dret; |
283 | 284 | ||
284 | radeon_i2c_do_lock(radeon_connector, 1); |
285 | radeon_i2c_do_lock(radeon_connector, 1); |
285 | dret = radeon_ddc_probe(radeon_connector); |
286 | dret = radeon_ddc_probe(radeon_connector); |
286 | radeon_i2c_do_lock(radeon_connector, 0); |
287 | radeon_i2c_do_lock(radeon_connector, 0); |
287 | if (dret) |
288 | if (dret) |
288 | ret = connector_status_connected; |
289 | ret = connector_status_connected; |
289 | else { |
290 | else { |
290 | for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { |
291 | for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { |
291 | if (connector->encoder_ids[i] == 0) |
292 | if (connector->encoder_ids[i] == 0) |
292 | break; |
293 | break; |
293 | 294 | ||
294 | obj = drm_mode_object_find(connector->dev, |
295 | obj = drm_mode_object_find(connector->dev, |
295 | connector->encoder_ids[i], |
296 | connector->encoder_ids[i], |
296 | DRM_MODE_OBJECT_ENCODER); |
297 | DRM_MODE_OBJECT_ENCODER); |
297 | if (!obj) |
298 | if (!obj) |
298 | continue; |
299 | continue; |
299 | 300 | ||
300 | encoder = obj_to_encoder(obj); |
301 | encoder = obj_to_encoder(obj); |
301 | 302 | ||
302 | encoder_funcs = encoder->helper_private; |
303 | encoder_funcs = encoder->helper_private; |
303 | if (encoder_funcs->detect) { |
304 | if (encoder_funcs->detect) { |
304 | ret = encoder_funcs->detect(encoder, connector); |
305 | ret = encoder_funcs->detect(encoder, connector); |
305 | if (ret == connector_status_connected) { |
306 | if (ret == connector_status_connected) { |
306 | radeon_connector->use_digital = 0; |
307 | radeon_connector->use_digital = 0; |
307 | break; |
308 | break; |
308 | } |
309 | } |
309 | } |
310 | } |
310 | } |
311 | } |
311 | } |
312 | } |
312 | 313 | ||
313 | /* updated in get modes as well since we need to know if it's analog or digital */ |
314 | /* updated in get modes as well since we need to know if it's analog or digital */ |
314 | radeon_connector_update_scratch_regs(connector, ret); |
315 | radeon_connector_update_scratch_regs(connector, ret); |
315 | return ret; |
316 | return ret; |
316 | } |
317 | } |
317 | 318 | ||
318 | /* okay need to be smart in here about which encoder to pick */ |
319 | /* okay need to be smart in here about which encoder to pick */ |
319 | struct drm_encoder *radeon_dvi_encoder(struct drm_connector *connector) |
320 | struct drm_encoder *radeon_dvi_encoder(struct drm_connector *connector) |
320 | { |
321 | { |
321 | int enc_id = connector->encoder_ids[0]; |
322 | int enc_id = connector->encoder_ids[0]; |
322 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
323 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
323 | struct drm_mode_object *obj; |
324 | struct drm_mode_object *obj; |
324 | struct drm_encoder *encoder; |
325 | struct drm_encoder *encoder; |
325 | int i; |
326 | int i; |
- | 327 | ||
- | 328 | ENTRY(); |
|
- | 329 | ||
326 | for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { |
330 | for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { |
327 | if (connector->encoder_ids[i] == 0) |
331 | if (connector->encoder_ids[i] == 0) |
328 | break; |
332 | break; |
329 | 333 | ||
330 | obj = drm_mode_object_find(connector->dev, connector->encoder_ids[i], DRM_MODE_OBJECT_ENCODER); |
334 | obj = drm_mode_object_find(connector->dev, connector->encoder_ids[i], DRM_MODE_OBJECT_ENCODER); |
331 | if (!obj) |
335 | if (!obj) |
332 | continue; |
336 | continue; |
333 | 337 | ||
334 | encoder = obj_to_encoder(obj); |
338 | encoder = obj_to_encoder(obj); |
335 | 339 | ||
336 | if (radeon_connector->use_digital) { |
340 | if (radeon_connector->use_digital) { |
337 | if (encoder->encoder_type == DRM_MODE_ENCODER_TMDS) |
341 | if (encoder->encoder_type == DRM_MODE_ENCODER_TMDS) |
338 | return encoder; |
342 | return encoder; |
339 | } else { |
343 | } else { |
340 | if (encoder->encoder_type == DRM_MODE_ENCODER_DAC || |
344 | if (encoder->encoder_type == DRM_MODE_ENCODER_DAC || |
341 | encoder->encoder_type == DRM_MODE_ENCODER_TVDAC) |
345 | encoder->encoder_type == DRM_MODE_ENCODER_TVDAC) |
342 | return encoder; |
346 | return encoder; |
343 | } |
347 | } |
344 | } |
348 | } |
345 | 349 | ||
346 | /* see if we have a default encoder TODO */ |
350 | /* see if we have a default encoder TODO */ |
347 | 351 | ||
348 | /* then check use digitial */ |
352 | /* then check use digitial */ |
349 | /* pick the first one */ |
353 | /* pick the first one */ |
- | 354 | ||
- | 355 | dbgprintf("enc_id = %x\n", enc_id); |
|
- | 356 | ||
350 | if (enc_id) { |
357 | if (enc_id) { |
351 | obj = drm_mode_object_find(connector->dev, enc_id, DRM_MODE_OBJECT_ENCODER); |
358 | obj = drm_mode_object_find(connector->dev, enc_id, DRM_MODE_OBJECT_ENCODER); |
352 | if (!obj) |
359 | if (!obj) |
353 | return NULL; |
360 | return NULL; |
354 | encoder = obj_to_encoder(obj); |
361 | encoder = obj_to_encoder(obj); |
355 | return encoder; |
362 | return encoder; |
356 | } |
363 | } |
357 | return NULL; |
364 | return NULL; |
358 | } |
365 | } |
359 | 366 | ||
360 | struct drm_connector_helper_funcs radeon_dvi_connector_helper_funcs = { |
367 | struct drm_connector_helper_funcs radeon_dvi_connector_helper_funcs = { |
361 | .get_modes = radeon_dvi_get_modes, |
368 | .get_modes = radeon_dvi_get_modes, |
362 | .mode_valid = radeon_vga_mode_valid, |
369 | .mode_valid = radeon_vga_mode_valid, |
363 | .best_encoder = radeon_dvi_encoder, |
370 | .best_encoder = radeon_dvi_encoder, |
364 | }; |
371 | }; |
365 | 372 | ||
366 | struct drm_connector_funcs radeon_dvi_connector_funcs = { |
373 | struct drm_connector_funcs radeon_dvi_connector_funcs = { |
367 | .dpms = drm_helper_connector_dpms, |
374 | .dpms = drm_helper_connector_dpms, |
368 | .detect = radeon_dvi_detect, |
375 | .detect = radeon_dvi_detect, |
369 | .fill_modes = drm_helper_probe_single_connector_modes, |
376 | .fill_modes = drm_helper_probe_single_connector_modes, |
370 | .set_property = radeon_connector_set_property, |
377 | .set_property = radeon_connector_set_property, |
371 | .destroy = radeon_connector_destroy, |
378 | .destroy = radeon_connector_destroy, |
372 | }; |
379 | }; |
373 | 380 | ||
374 | void |
381 | void |
375 | radeon_add_atom_connector(struct drm_device *dev, |
382 | radeon_add_atom_connector(struct drm_device *dev, |
376 | uint32_t connector_id, |
383 | uint32_t connector_id, |
377 | uint32_t supported_device, |
384 | uint32_t supported_device, |
378 | int connector_type, |
385 | int connector_type, |
379 | struct radeon_i2c_bus_rec *i2c_bus, |
386 | struct radeon_i2c_bus_rec *i2c_bus, |
380 | bool linkb, |
387 | bool linkb, |
381 | uint32_t igp_lane_info) |
388 | uint32_t igp_lane_info) |
382 | { |
389 | { |
383 | struct drm_connector *connector; |
390 | struct drm_connector *connector; |
384 | struct radeon_connector *radeon_connector; |
391 | struct radeon_connector *radeon_connector; |
385 | struct radeon_connector_atom_dig *radeon_dig_connector; |
392 | struct radeon_connector_atom_dig *radeon_dig_connector; |
386 | uint32_t subpixel_order = SubPixelNone; |
393 | uint32_t subpixel_order = SubPixelNone; |
387 | 394 | ||
388 | /* fixme - tv/cv/din */ |
395 | /* fixme - tv/cv/din */ |
389 | if ((connector_type == DRM_MODE_CONNECTOR_Unknown) || |
396 | if ((connector_type == DRM_MODE_CONNECTOR_Unknown) || |
390 | (connector_type == DRM_MODE_CONNECTOR_SVIDEO) || |
397 | (connector_type == DRM_MODE_CONNECTOR_SVIDEO) || |
391 | (connector_type == DRM_MODE_CONNECTOR_Composite) || |
398 | (connector_type == DRM_MODE_CONNECTOR_Composite) || |
392 | (connector_type == DRM_MODE_CONNECTOR_9PinDIN)) |
399 | (connector_type == DRM_MODE_CONNECTOR_9PinDIN)) |
393 | return; |
400 | return; |
394 | 401 | ||
395 | /* see if we already added it */ |
402 | /* see if we already added it */ |
396 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
403 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
397 | radeon_connector = to_radeon_connector(connector); |
404 | radeon_connector = to_radeon_connector(connector); |
398 | if (radeon_connector->connector_id == connector_id) { |
405 | if (radeon_connector->connector_id == connector_id) { |
399 | radeon_connector->devices |= supported_device; |
406 | radeon_connector->devices |= supported_device; |
400 | return; |
407 | return; |
401 | } |
408 | } |
402 | } |
409 | } |
403 | 410 | ||
404 | radeon_connector = kzalloc(sizeof(struct radeon_connector), GFP_KERNEL); |
411 | radeon_connector = kzalloc(sizeof(struct radeon_connector), GFP_KERNEL); |
405 | if (!radeon_connector) |
412 | if (!radeon_connector) |
406 | return; |
413 | return; |
407 | 414 | ||
408 | connector = &radeon_connector->base; |
415 | connector = &radeon_connector->base; |
409 | 416 | ||
410 | radeon_connector->connector_id = connector_id; |
417 | radeon_connector->connector_id = connector_id; |
411 | radeon_connector->devices = supported_device; |
418 | radeon_connector->devices = supported_device; |
412 | switch (connector_type) { |
419 | switch (connector_type) { |
413 | case DRM_MODE_CONNECTOR_VGA: |
420 | case DRM_MODE_CONNECTOR_VGA: |
414 | drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); |
421 | drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); |
415 | drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs); |
422 | drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs); |
416 | if (i2c_bus->valid) { |
423 | if (i2c_bus->valid) { |
417 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "VGA"); |
424 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "VGA"); |
418 | if (!radeon_connector->ddc_bus) |
425 | if (!radeon_connector->ddc_bus) |
419 | goto failed; |
426 | goto failed; |
420 | } |
427 | } |
421 | break; |
428 | break; |
422 | case DRM_MODE_CONNECTOR_DVIA: |
429 | case DRM_MODE_CONNECTOR_DVIA: |
423 | drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); |
430 | drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); |
424 | drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs); |
431 | drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs); |
425 | if (i2c_bus->valid) { |
432 | if (i2c_bus->valid) { |
426 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI"); |
433 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI"); |
427 | if (!radeon_connector->ddc_bus) |
434 | if (!radeon_connector->ddc_bus) |
428 | goto failed; |
435 | goto failed; |
429 | } |
436 | } |
430 | break; |
437 | break; |
431 | case DRM_MODE_CONNECTOR_DVII: |
438 | case DRM_MODE_CONNECTOR_DVII: |
432 | case DRM_MODE_CONNECTOR_DVID: |
439 | case DRM_MODE_CONNECTOR_DVID: |
433 | radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); |
440 | radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); |
434 | if (!radeon_dig_connector) |
441 | if (!radeon_dig_connector) |
435 | goto failed; |
442 | goto failed; |
436 | radeon_dig_connector->linkb = linkb; |
443 | radeon_dig_connector->linkb = linkb; |
437 | radeon_dig_connector->igp_lane_info = igp_lane_info; |
444 | radeon_dig_connector->igp_lane_info = igp_lane_info; |
438 | radeon_connector->con_priv = radeon_dig_connector; |
445 | radeon_connector->con_priv = radeon_dig_connector; |
439 | drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); |
446 | drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); |
440 | drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs); |
447 | drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs); |
441 | if (i2c_bus->valid) { |
448 | if (i2c_bus->valid) { |
442 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI"); |
449 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI"); |
443 | if (!radeon_connector->ddc_bus) |
450 | if (!radeon_connector->ddc_bus) |
444 | goto failed; |
451 | goto failed; |
445 | } |
452 | } |
446 | subpixel_order = SubPixelHorizontalRGB; |
453 | subpixel_order = SubPixelHorizontalRGB; |
447 | break; |
454 | break; |
448 | case DRM_MODE_CONNECTOR_HDMIA: |
455 | case DRM_MODE_CONNECTOR_HDMIA: |
449 | case DRM_MODE_CONNECTOR_HDMIB: |
456 | case DRM_MODE_CONNECTOR_HDMIB: |
450 | radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); |
457 | radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); |
451 | if (!radeon_dig_connector) |
458 | if (!radeon_dig_connector) |
452 | goto failed; |
459 | goto failed; |
453 | radeon_dig_connector->linkb = linkb; |
460 | radeon_dig_connector->linkb = linkb; |
454 | radeon_dig_connector->igp_lane_info = igp_lane_info; |
461 | radeon_dig_connector->igp_lane_info = igp_lane_info; |
455 | radeon_connector->con_priv = radeon_dig_connector; |
462 | radeon_connector->con_priv = radeon_dig_connector; |
456 | drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); |
463 | drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); |
457 | drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs); |
464 | drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs); |
458 | if (i2c_bus->valid) { |
465 | if (i2c_bus->valid) { |
459 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "HDMI"); |
466 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "HDMI"); |
460 | if (!radeon_connector->ddc_bus) |
467 | if (!radeon_connector->ddc_bus) |
461 | goto failed; |
468 | goto failed; |
462 | } |
469 | } |
463 | subpixel_order = SubPixelHorizontalRGB; |
470 | subpixel_order = SubPixelHorizontalRGB; |
464 | break; |
471 | break; |
465 | case DRM_MODE_CONNECTOR_DisplayPort: |
472 | case DRM_MODE_CONNECTOR_DisplayPort: |
466 | radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); |
473 | radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); |
467 | if (!radeon_dig_connector) |
474 | if (!radeon_dig_connector) |
468 | goto failed; |
475 | goto failed; |
469 | radeon_dig_connector->linkb = linkb; |
476 | radeon_dig_connector->linkb = linkb; |
470 | radeon_dig_connector->igp_lane_info = igp_lane_info; |
477 | radeon_dig_connector->igp_lane_info = igp_lane_info; |
471 | radeon_connector->con_priv = radeon_dig_connector; |
478 | radeon_connector->con_priv = radeon_dig_connector; |
472 | drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); |
479 | drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); |
473 | drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs); |
480 | drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs); |
474 | if (i2c_bus->valid) { |
481 | if (i2c_bus->valid) { |
475 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DP"); |
482 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DP"); |
476 | if (!radeon_connector->ddc_bus) |
483 | if (!radeon_connector->ddc_bus) |
477 | goto failed; |
484 | goto failed; |
478 | } |
485 | } |
479 | subpixel_order = SubPixelHorizontalRGB; |
486 | subpixel_order = SubPixelHorizontalRGB; |
480 | break; |
487 | break; |
481 | case DRM_MODE_CONNECTOR_SVIDEO: |
488 | case DRM_MODE_CONNECTOR_SVIDEO: |
482 | case DRM_MODE_CONNECTOR_Composite: |
489 | case DRM_MODE_CONNECTOR_Composite: |
483 | case DRM_MODE_CONNECTOR_9PinDIN: |
490 | case DRM_MODE_CONNECTOR_9PinDIN: |
484 | break; |
491 | break; |
485 | case DRM_MODE_CONNECTOR_LVDS: |
492 | case DRM_MODE_CONNECTOR_LVDS: |
486 | radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); |
493 | radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); |
487 | if (!radeon_dig_connector) |
494 | if (!radeon_dig_connector) |
488 | goto failed; |
495 | goto failed; |
489 | radeon_dig_connector->linkb = linkb; |
496 | radeon_dig_connector->linkb = linkb; |
490 | radeon_dig_connector->igp_lane_info = igp_lane_info; |
497 | radeon_dig_connector->igp_lane_info = igp_lane_info; |
491 | radeon_connector->con_priv = radeon_dig_connector; |
498 | radeon_connector->con_priv = radeon_dig_connector; |
492 | drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type); |
499 | drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type); |
493 | drm_connector_helper_add(&radeon_connector->base, &radeon_lvds_connector_helper_funcs); |
500 | drm_connector_helper_add(&radeon_connector->base, &radeon_lvds_connector_helper_funcs); |
494 | if (i2c_bus->valid) { |
501 | if (i2c_bus->valid) { |
495 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "LVDS"); |
502 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "LVDS"); |
496 | if (!radeon_connector->ddc_bus) |
503 | if (!radeon_connector->ddc_bus) |
497 | goto failed; |
504 | goto failed; |
498 | } |
505 | } |
499 | subpixel_order = SubPixelHorizontalRGB; |
506 | subpixel_order = SubPixelHorizontalRGB; |
500 | break; |
507 | break; |
501 | } |
508 | } |
502 | 509 | ||
503 | connector->display_info.subpixel_order = subpixel_order; |
510 | connector->display_info.subpixel_order = subpixel_order; |
504 | // drm_sysfs_connector_add(connector); |
511 | // drm_sysfs_connector_add(connector); |
505 | return; |
512 | return; |
506 | 513 | ||
507 | failed: |
514 | failed: |
508 | if (radeon_connector->ddc_bus) |
515 | if (radeon_connector->ddc_bus) |
509 | radeon_i2c_destroy(radeon_connector->ddc_bus); |
516 | radeon_i2c_destroy(radeon_connector->ddc_bus); |
510 | drm_connector_cleanup(connector); |
517 | drm_connector_cleanup(connector); |
511 | kfree(connector); |
518 | kfree(connector); |
512 | } |
519 | } |
513 | 520 | ||
514 | void |
521 | void |
515 | radeon_add_legacy_connector(struct drm_device *dev, |
522 | radeon_add_legacy_connector(struct drm_device *dev, |
516 | uint32_t connector_id, |
523 | uint32_t connector_id, |
517 | uint32_t supported_device, |
524 | uint32_t supported_device, |
518 | int connector_type, |
525 | int connector_type, |
519 | struct radeon_i2c_bus_rec *i2c_bus) |
526 | struct radeon_i2c_bus_rec *i2c_bus) |
520 | { |
527 | { |
521 | struct drm_connector *connector; |
528 | struct drm_connector *connector; |
522 | struct radeon_connector *radeon_connector; |
529 | struct radeon_connector *radeon_connector; |
523 | uint32_t subpixel_order = SubPixelNone; |
530 | uint32_t subpixel_order = SubPixelNone; |
524 | 531 | ||
525 | /* fixme - tv/cv/din */ |
532 | /* fixme - tv/cv/din */ |
526 | if ((connector_type == DRM_MODE_CONNECTOR_Unknown) || |
533 | if ((connector_type == DRM_MODE_CONNECTOR_Unknown) || |
527 | (connector_type == DRM_MODE_CONNECTOR_SVIDEO) || |
534 | (connector_type == DRM_MODE_CONNECTOR_SVIDEO) || |
528 | (connector_type == DRM_MODE_CONNECTOR_Composite) || |
535 | (connector_type == DRM_MODE_CONNECTOR_Composite) || |
529 | (connector_type == DRM_MODE_CONNECTOR_9PinDIN)) |
536 | (connector_type == DRM_MODE_CONNECTOR_9PinDIN)) |
530 | return; |
537 | return; |
531 | 538 | ||
532 | /* see if we already added it */ |
539 | /* see if we already added it */ |
533 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
540 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
534 | radeon_connector = to_radeon_connector(connector); |
541 | radeon_connector = to_radeon_connector(connector); |
535 | if (radeon_connector->connector_id == connector_id) { |
542 | if (radeon_connector->connector_id == connector_id) { |
536 | radeon_connector->devices |= supported_device; |
543 | radeon_connector->devices |= supported_device; |
537 | return; |
544 | return; |
538 | } |
545 | } |
539 | } |
546 | } |
540 | 547 | ||
541 | radeon_connector = kzalloc(sizeof(struct radeon_connector), GFP_KERNEL); |
548 | radeon_connector = kzalloc(sizeof(struct radeon_connector), GFP_KERNEL); |
542 | if (!radeon_connector) |
549 | if (!radeon_connector) |
543 | return; |
550 | return; |
544 | 551 | ||
545 | connector = &radeon_connector->base; |
552 | connector = &radeon_connector->base; |
546 | 553 | ||
547 | radeon_connector->connector_id = connector_id; |
554 | radeon_connector->connector_id = connector_id; |
548 | radeon_connector->devices = supported_device; |
555 | radeon_connector->devices = supported_device; |
549 | switch (connector_type) { |
556 | switch (connector_type) { |
550 | case DRM_MODE_CONNECTOR_VGA: |
557 | case DRM_MODE_CONNECTOR_VGA: |
551 | drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); |
558 | drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); |
552 | drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs); |
559 | drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs); |
553 | if (i2c_bus->valid) { |
560 | if (i2c_bus->valid) { |
554 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "VGA"); |
561 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "VGA"); |
555 | if (!radeon_connector->ddc_bus) |
562 | if (!radeon_connector->ddc_bus) |
556 | goto failed; |
563 | goto failed; |
557 | } |
564 | } |
558 | break; |
565 | break; |
559 | case DRM_MODE_CONNECTOR_DVIA: |
566 | case DRM_MODE_CONNECTOR_DVIA: |
560 | drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); |
567 | drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); |
561 | drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs); |
568 | drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs); |
562 | if (i2c_bus->valid) { |
569 | if (i2c_bus->valid) { |
563 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI"); |
570 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI"); |
564 | if (!radeon_connector->ddc_bus) |
571 | if (!radeon_connector->ddc_bus) |
565 | goto failed; |
572 | goto failed; |
566 | } |
573 | } |
567 | break; |
574 | break; |
568 | case DRM_MODE_CONNECTOR_DVII: |
575 | case DRM_MODE_CONNECTOR_DVII: |
569 | case DRM_MODE_CONNECTOR_DVID: |
576 | case DRM_MODE_CONNECTOR_DVID: |
570 | drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); |
577 | drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); |
571 | drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs); |
578 | drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs); |
572 | if (i2c_bus->valid) { |
579 | if (i2c_bus->valid) { |
573 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI"); |
580 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI"); |
574 | if (!radeon_connector->ddc_bus) |
581 | if (!radeon_connector->ddc_bus) |
575 | goto failed; |
582 | goto failed; |
576 | } |
583 | } |
577 | subpixel_order = SubPixelHorizontalRGB; |
584 | subpixel_order = SubPixelHorizontalRGB; |
578 | break; |
585 | break; |
579 | case DRM_MODE_CONNECTOR_SVIDEO: |
586 | case DRM_MODE_CONNECTOR_SVIDEO: |
580 | case DRM_MODE_CONNECTOR_Composite: |
587 | case DRM_MODE_CONNECTOR_Composite: |
581 | case DRM_MODE_CONNECTOR_9PinDIN: |
588 | case DRM_MODE_CONNECTOR_9PinDIN: |
582 | break; |
589 | break; |
583 | case DRM_MODE_CONNECTOR_LVDS: |
590 | case DRM_MODE_CONNECTOR_LVDS: |
584 | drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type); |
591 | drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type); |
585 | drm_connector_helper_add(&radeon_connector->base, &radeon_lvds_connector_helper_funcs); |
592 | drm_connector_helper_add(&radeon_connector->base, &radeon_lvds_connector_helper_funcs); |
586 | if (i2c_bus->valid) { |
593 | if (i2c_bus->valid) { |
587 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "LVDS"); |
594 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "LVDS"); |
588 | if (!radeon_connector->ddc_bus) |
595 | if (!radeon_connector->ddc_bus) |
589 | goto failed; |
596 | goto failed; |
590 | } |
597 | } |
591 | subpixel_order = SubPixelHorizontalRGB; |
598 | subpixel_order = SubPixelHorizontalRGB; |
592 | break; |
599 | break; |
593 | } |
600 | } |
594 | 601 | ||
595 | connector->display_info.subpixel_order = subpixel_order; |
602 | connector->display_info.subpixel_order = subpixel_order; |
596 | // drm_sysfs_connector_add(connector); |
603 | // drm_sysfs_connector_add(connector); |
597 | return; |
604 | return; |
598 | 605 | ||
599 | failed: |
606 | failed: |
600 | if (radeon_connector->ddc_bus) |
607 | if (radeon_connector->ddc_bus) |
601 | radeon_i2c_destroy(radeon_connector->ddc_bus); |
608 | radeon_i2c_destroy(radeon_connector->ddc_bus); |
602 | drm_connector_cleanup(connector); |
609 | drm_connector_cleanup(connector); |
603 | kfree(connector); |
610 | kfree(connector); |
604 | }>>> |
611 | }>>> |