aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_sdvo.c
diff options
context:
space:
mode:
authorJesse Barnes <jbarnes@virtuousgeek.org>2008-11-07 17:24:08 -0500
committerDave Airlie <airlied@linux.ie>2008-12-29 02:47:23 -0500
commit79e539453b34e35f39299a899d263b0a1f1670bd (patch)
tree6d1285f2b78fab399aab75a3557b7d6bc0dbd112 /drivers/gpu/drm/i915/intel_sdvo.c
parentf453ba0460742ad027ae0c4c7d61e62817b3e7ef (diff)
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs. Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are supported. HDMI, DisplayPort and additional SDVO output support will follow. Support for the mode setting code is controlled by the new 'modeset' module option. A new config option, CONFIG_DRM_I915_KMS controls the default behavior, and whether a PCI ID list is built into the module for use by user level module utilities. Note that if mode setting is enabled, user level drivers that access display registers directly or that don't use the kernel graphics memory manager will likely corrupt kernel graphics memory, disrupt output configuration (possibly leading to hangs and/or blank displays), and prevent panic/oops messages from appearing. So use caution when enabling this code; be sure your user level code supports the new interfaces. A new SysRq key, 'g', provides emergency support for switching back to the kernel's framebuffer console; which is useful for testing. Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Eric Anholt <eric@anholt.net> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_sdvo.c')
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo.c1127
1 files changed, 1127 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
new file mode 100644
index 000000000000..626258d72c90
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -0,0 +1,1127 @@
1/*
2 * Copyright 2006 Dave Airlie <airlied@linux.ie>
3 * Copyright © 2006-2007 Intel Corporation
4 * Jesse Barnes <jesse.barnes@intel.com>
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
15 * Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
24 *
25 * Authors:
26 * Eric Anholt <eric@anholt.net>
27 */
28#include <linux/i2c.h>
29#include <linux/delay.h>
30#include "drmP.h"
31#include "drm.h"
32#include "drm_crtc.h"
33#include "intel_drv.h"
34#include "i915_drm.h"
35#include "i915_drv.h"
36#include "intel_sdvo_regs.h"
37
38#undef SDVO_DEBUG
39
40struct intel_sdvo_priv {
41 struct intel_i2c_chan *i2c_bus;
42 int slaveaddr;
43 int output_device;
44
45 u16 active_outputs;
46
47 struct intel_sdvo_caps caps;
48 int pixel_clock_min, pixel_clock_max;
49
50 int save_sdvo_mult;
51 u16 save_active_outputs;
52 struct intel_sdvo_dtd save_input_dtd_1, save_input_dtd_2;
53 struct intel_sdvo_dtd save_output_dtd[16];
54 u32 save_SDVOX;
55};
56
57/**
58 * Writes the SDVOB or SDVOC with the given value, but always writes both
59 * SDVOB and SDVOC to work around apparent hardware issues (according to
60 * comments in the BIOS).
61 */
62void intel_sdvo_write_sdvox(struct intel_output *intel_output, u32 val)
63{
64 struct drm_device *dev = intel_output->base.dev;
65 struct drm_i915_private *dev_priv = dev->dev_private;
66 struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
67 u32 bval = val, cval = val;
68 int i;
69
70 if (sdvo_priv->output_device == SDVOB) {
71 cval = I915_READ(SDVOC);
72 } else {
73 bval = I915_READ(SDVOB);
74 }
75 /*
76 * Write the registers twice for luck. Sometimes,
77 * writing them only once doesn't appear to 'stick'.
78 * The BIOS does this too. Yay, magic
79 */
80 for (i = 0; i < 2; i++)
81 {
82 I915_WRITE(SDVOB, bval);
83 I915_READ(SDVOB);
84 I915_WRITE(SDVOC, cval);
85 I915_READ(SDVOC);
86 }
87}
88
89static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr,
90 u8 *ch)
91{
92 struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
93 u8 out_buf[2];
94 u8 buf[2];
95 int ret;
96
97 struct i2c_msg msgs[] = {
98 {
99 .addr = sdvo_priv->i2c_bus->slave_addr,
100 .flags = 0,
101 .len = 1,
102 .buf = out_buf,
103 },
104 {
105 .addr = sdvo_priv->i2c_bus->slave_addr,
106 .flags = I2C_M_RD,
107 .len = 1,
108 .buf = buf,
109 }
110 };
111
112 out_buf[0] = addr;
113 out_buf[1] = 0;
114
115 if ((ret = i2c_transfer(&sdvo_priv->i2c_bus->adapter, msgs, 2)) == 2)
116 {
117 *ch = buf[0];
118 return true;
119 }
120
121 DRM_DEBUG("i2c transfer returned %d\n", ret);
122 return false;
123}
124
125static bool intel_sdvo_write_byte(struct intel_output *intel_output, int addr,
126 u8 ch)
127{
128 u8 out_buf[2];
129 struct i2c_msg msgs[] = {
130 {
131 .addr = intel_output->i2c_bus->slave_addr,
132 .flags = 0,
133 .len = 2,
134 .buf = out_buf,
135 }
136 };
137
138 out_buf[0] = addr;
139 out_buf[1] = ch;
140
141 if (i2c_transfer(&intel_output->i2c_bus->adapter, msgs, 1) == 1)
142 {
143 return true;
144 }
145 return false;
146}
147
148#define SDVO_CMD_NAME_ENTRY(cmd) {cmd, #cmd}
149/** Mapping of command numbers to names, for debug output */
150const static struct _sdvo_cmd_name {
151 u8 cmd;
152 char *name;
153} sdvo_cmd_names[] = {
154 SDVO_CMD_NAME_ENTRY(SDVO_CMD_RESET),
155 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_DEVICE_CAPS),
156 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FIRMWARE_REV),
157 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TRAINED_INPUTS),
158 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ACTIVE_OUTPUTS),
159 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ACTIVE_OUTPUTS),
160 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_IN_OUT_MAP),
161 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_IN_OUT_MAP),
162 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ATTACHED_DISPLAYS),
163 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HOT_PLUG_SUPPORT),
164 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ACTIVE_HOT_PLUG),
165 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ACTIVE_HOT_PLUG),
166 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INTERRUPT_EVENT_SOURCE),
167 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TARGET_INPUT),
168 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TARGET_OUTPUT),
169 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_TIMINGS_PART1),
170 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_TIMINGS_PART2),
171 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART1),
172 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART2),
173 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART1),
174 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OUTPUT_TIMINGS_PART1),
175 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OUTPUT_TIMINGS_PART2),
176 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OUTPUT_TIMINGS_PART1),
177 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OUTPUT_TIMINGS_PART2),
178 SDVO_CMD_NAME_ENTRY(SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING),
179 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1),
180 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2),
181 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE),
182 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OUTPUT_PIXEL_CLOCK_RANGE),
183 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_CLOCK_RATE_MULTS),
184 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_CLOCK_RATE_MULT),
185 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CLOCK_RATE_MULT),
186 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_TV_FORMATS),
187 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TV_FORMAT),
188 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_FORMAT),
189 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_RESOLUTION_SUPPORT),
190 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CONTROL_BUS_SWITCH),
191};
192
193#define SDVO_NAME(dev_priv) ((dev_priv)->output_device == SDVOB ? "SDVOB" : "SDVOC")
194#define SDVO_PRIV(output) ((struct intel_sdvo_priv *) (output)->dev_priv)
195
196#ifdef SDVO_DEBUG
197static void intel_sdvo_debug_write(struct intel_output *intel_output, u8 cmd,
198 void *args, int args_len)
199{
200 struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
201 int i;
202
203 DRM_DEBUG("%s: W: %02X ", SDVO_NAME(sdvo_priv), cmd);
204 for (i = 0; i < args_len; i++)
205 printk("%02X ", ((u8 *)args)[i]);
206 for (; i < 8; i++)
207 printk(" ");
208 for (i = 0; i < sizeof(sdvo_cmd_names) / sizeof(sdvo_cmd_names[0]); i++) {
209 if (cmd == sdvo_cmd_names[i].cmd) {
210 printk("(%s)", sdvo_cmd_names[i].name);
211 break;
212 }
213 }
214 if (i == sizeof(sdvo_cmd_names)/ sizeof(sdvo_cmd_names[0]))
215 printk("(%02X)",cmd);
216 printk("\n");
217}
218#else
219#define intel_sdvo_debug_write(o, c, a, l)
220#endif
221
222static void intel_sdvo_write_cmd(struct intel_output *intel_output, u8 cmd,
223 void *args, int args_len)
224{
225 int i;
226
227 intel_sdvo_debug_write(intel_output, cmd, args, args_len);
228
229 for (i = 0; i < args_len; i++) {
230 intel_sdvo_write_byte(intel_output, SDVO_I2C_ARG_0 - i,
231 ((u8*)args)[i]);
232 }
233
234 intel_sdvo_write_byte(intel_output, SDVO_I2C_OPCODE, cmd);
235}
236
237#ifdef SDVO_DEBUG
238static const char *cmd_status_names[] = {
239 "Power on",
240 "Success",
241 "Not supported",
242 "Invalid arg",
243 "Pending",
244 "Target not specified",
245 "Scaling not supported"
246};
247
248static void intel_sdvo_debug_response(struct intel_output *intel_output,
249 void *response, int response_len,
250 u8 status)
251{
252 struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
253
254 DRM_DEBUG("%s: R: ", SDVO_NAME(sdvo_priv));
255 for (i = 0; i < response_len; i++)
256 printk("%02X ", ((u8 *)response)[i]);
257 for (; i < 8; i++)
258 printk(" ");
259 if (status <= SDVO_CMD_STATUS_SCALING_NOT_SUPP)
260 printk("(%s)", cmd_status_names[status]);
261 else
262 printk("(??? %d)", status);
263 printk("\n");
264}
265#else
266#define intel_sdvo_debug_response(o, r, l, s)
267#endif
268
269static u8 intel_sdvo_read_response(struct intel_output *intel_output,
270 void *response, int response_len)
271{
272 int i;
273 u8 status;
274 u8 retry = 50;
275
276 while (retry--) {
277 /* Read the command response */
278 for (i = 0; i < response_len; i++) {
279 intel_sdvo_read_byte(intel_output,
280 SDVO_I2C_RETURN_0 + i,
281 &((u8 *)response)[i]);
282 }
283
284 /* read the return status */
285 intel_sdvo_read_byte(intel_output, SDVO_I2C_CMD_STATUS,
286 &status);
287
288 intel_sdvo_debug_response(intel_output, response, response_len,
289 status);
290 if (status != SDVO_CMD_STATUS_PENDING)
291 return status;
292
293 mdelay(50);
294 }
295
296 return status;
297}
298
299int intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode)
300{
301 if (mode->clock >= 100000)
302 return 1;
303 else if (mode->clock >= 50000)
304 return 2;
305 else
306 return 4;
307}
308
309/**
310 * Don't check status code from this as it switches the bus back to the
311 * SDVO chips which defeats the purpose of doing a bus switch in the first
312 * place.
313 */
314void intel_sdvo_set_control_bus_switch(struct intel_output *intel_output, u8 target)
315{
316 intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_CONTROL_BUS_SWITCH, &target, 1);
317}
318
319static bool intel_sdvo_set_target_input(struct intel_output *intel_output, bool target_0, bool target_1)
320{
321 struct intel_sdvo_set_target_input_args targets = {0};
322 u8 status;
323
324 if (target_0 && target_1)
325 return SDVO_CMD_STATUS_NOTSUPP;
326
327 if (target_1)
328 targets.target_1 = 1;
329
330 intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_TARGET_INPUT, &targets,
331 sizeof(targets));
332
333 status = intel_sdvo_read_response(intel_output, NULL, 0);
334
335 return (status == SDVO_CMD_STATUS_SUCCESS);
336}
337
338/**
339 * Return whether each input is trained.
340 *
341 * This function is making an assumption about the layout of the response,
342 * which should be checked against the docs.
343 */
344static bool intel_sdvo_get_trained_inputs(struct intel_output *intel_output, bool *input_1, bool *input_2)
345{
346 struct intel_sdvo_get_trained_inputs_response response;
347 u8 status;
348
349 intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_TRAINED_INPUTS, NULL, 0);
350 status = intel_sdvo_read_response(intel_output, &response, sizeof(response));
351 if (status != SDVO_CMD_STATUS_SUCCESS)
352 return false;
353
354 *input_1 = response.input0_trained;
355 *input_2 = response.input1_trained;
356 return true;
357}
358
359static bool intel_sdvo_get_active_outputs(struct intel_output *intel_output,
360 u16 *outputs)
361{
362 u8 status;
363
364 intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ACTIVE_OUTPUTS, NULL, 0);
365 status = intel_sdvo_read_response(intel_output, outputs, sizeof(*outputs));
366
367 return (status == SDVO_CMD_STATUS_SUCCESS);
368}
369
370static bool intel_sdvo_set_active_outputs(struct intel_output *intel_output,
371 u16 outputs)
372{
373 u8 status;
374
375 intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ACTIVE_OUTPUTS, &outputs,
376 sizeof(outputs));
377 status = intel_sdvo_read_response(intel_output, NULL, 0);
378 return (status == SDVO_CMD_STATUS_SUCCESS);
379}
380
381static bool intel_sdvo_set_encoder_power_state(struct intel_output *intel_output,
382 int mode)
383{
384 u8 status, state = SDVO_ENCODER_STATE_ON;
385
386 switch (mode) {
387 case DRM_MODE_DPMS_ON:
388 state = SDVO_ENCODER_STATE_ON;
389 break;
390 case DRM_MODE_DPMS_STANDBY:
391 state = SDVO_ENCODER_STATE_STANDBY;
392 break;
393 case DRM_MODE_DPMS_SUSPEND:
394 state = SDVO_ENCODER_STATE_SUSPEND;
395 break;
396 case DRM_MODE_DPMS_OFF:
397 state = SDVO_ENCODER_STATE_OFF;
398 break;
399 }
400
401 intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ENCODER_POWER_STATE, &state,
402 sizeof(state));
403 status = intel_sdvo_read_response(intel_output, NULL, 0);
404
405 return (status == SDVO_CMD_STATUS_SUCCESS);
406}
407
408static bool intel_sdvo_get_input_pixel_clock_range(struct intel_output *intel_output,
409 int *clock_min,
410 int *clock_max)
411{
412 struct intel_sdvo_pixel_clock_range clocks;
413 u8 status;
414
415 intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE,
416 NULL, 0);
417
418 status = intel_sdvo_read_response(intel_output, &clocks, sizeof(clocks));
419
420 if (status != SDVO_CMD_STATUS_SUCCESS)
421 return false;
422
423 /* Convert the values from units of 10 kHz to kHz. */
424 *clock_min = clocks.min * 10;
425 *clock_max = clocks.max * 10;
426
427 return true;
428}
429
430static bool intel_sdvo_set_target_output(struct intel_output *intel_output,
431 u16 outputs)
432{
433 u8 status;
434
435 intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_TARGET_OUTPUT, &outputs,
436 sizeof(outputs));
437
438 status = intel_sdvo_read_response(intel_output, NULL, 0);
439 return (status == SDVO_CMD_STATUS_SUCCESS);
440}
441
442static bool intel_sdvo_get_timing(struct intel_output *intel_output, u8 cmd,
443 struct intel_sdvo_dtd *dtd)
444{
445 u8 status;
446
447 intel_sdvo_write_cmd(intel_output, cmd, NULL, 0);
448 status = intel_sdvo_read_response(intel_output, &dtd->part1,
449 sizeof(dtd->part1));
450 if (status != SDVO_CMD_STATUS_SUCCESS)
451 return false;
452
453 intel_sdvo_write_cmd(intel_output, cmd + 1, NULL, 0);
454 status = intel_sdvo_read_response(intel_output, &dtd->part2,
455 sizeof(dtd->part2));
456 if (status != SDVO_CMD_STATUS_SUCCESS)
457 return false;
458
459 return true;
460}
461
462static bool intel_sdvo_get_input_timing(struct intel_output *intel_output,
463 struct intel_sdvo_dtd *dtd)
464{
465 return intel_sdvo_get_timing(intel_output,
466 SDVO_CMD_GET_INPUT_TIMINGS_PART1, dtd);
467}
468
469static bool intel_sdvo_get_output_timing(struct intel_output *intel_output,
470 struct intel_sdvo_dtd *dtd)
471{
472 return intel_sdvo_get_timing(intel_output,
473 SDVO_CMD_GET_OUTPUT_TIMINGS_PART1, dtd);
474}
475
476static bool intel_sdvo_set_timing(struct intel_output *intel_output, u8 cmd,
477 struct intel_sdvo_dtd *dtd)
478{
479 u8 status;
480
481 intel_sdvo_write_cmd(intel_output, cmd, &dtd->part1, sizeof(dtd->part1));
482 status = intel_sdvo_read_response(intel_output, NULL, 0);
483 if (status != SDVO_CMD_STATUS_SUCCESS)
484 return false;
485
486 intel_sdvo_write_cmd(intel_output, cmd + 1, &dtd->part2, sizeof(dtd->part2));
487 status = intel_sdvo_read_response(intel_output, NULL, 0);
488 if (status != SDVO_CMD_STATUS_SUCCESS)
489 return false;
490
491 return true;
492}
493
494static bool intel_sdvo_set_input_timing(struct intel_output *intel_output,
495 struct intel_sdvo_dtd *dtd)
496{
497 return intel_sdvo_set_timing(intel_output,
498 SDVO_CMD_SET_INPUT_TIMINGS_PART1, dtd);
499}
500
501static bool intel_sdvo_set_output_timing(struct intel_output *intel_output,
502 struct intel_sdvo_dtd *dtd)
503{
504 return intel_sdvo_set_timing(intel_output,
505 SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd);
506}
507
508
509static int intel_sdvo_get_clock_rate_mult(struct intel_output *intel_output)
510{
511 u8 response, status;
512
513 intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_CLOCK_RATE_MULT, NULL, 0);
514 status = intel_sdvo_read_response(intel_output, &response, 1);
515
516 if (status != SDVO_CMD_STATUS_SUCCESS) {
517 DRM_DEBUG("Couldn't get SDVO clock rate multiplier\n");
518 return SDVO_CLOCK_RATE_MULT_1X;
519 } else {
520 DRM_DEBUG("Current clock rate multiplier: %d\n", response);
521 }
522
523 return response;
524}
525
526static bool intel_sdvo_set_clock_rate_mult(struct intel_output *intel_output, u8 val)
527{
528 u8 status;
529
530 intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_CLOCK_RATE_MULT, &val, 1);
531 status = intel_sdvo_read_response(intel_output, NULL, 0);
532 if (status != SDVO_CMD_STATUS_SUCCESS)
533 return false;
534
535 return true;
536}
537
538static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
539 struct drm_display_mode *mode,
540 struct drm_display_mode *adjusted_mode)
541{
542 /* Make the CRTC code factor in the SDVO pixel multiplier. The SDVO
543 * device will be told of the multiplier during mode_set.
544 */
545 adjusted_mode->clock *= intel_sdvo_get_pixel_multiplier(mode);
546 return true;
547}
548
549static void intel_sdvo_mode_set(struct drm_encoder *encoder,
550 struct drm_display_mode *mode,
551 struct drm_display_mode *adjusted_mode)
552{
553 struct drm_device *dev = encoder->dev;
554 struct drm_i915_private *dev_priv = dev->dev_private;
555 struct drm_crtc *crtc = encoder->crtc;
556 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
557 struct intel_output *intel_output = enc_to_intel_output(encoder);
558 struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
559 u16 width, height;
560 u16 h_blank_len, h_sync_len, v_blank_len, v_sync_len;
561 u16 h_sync_offset, v_sync_offset;
562 u32 sdvox;
563 struct intel_sdvo_dtd output_dtd;
564 int sdvo_pixel_multiply;
565
566 if (!mode)
567 return;
568
569 width = mode->crtc_hdisplay;
570 height = mode->crtc_vdisplay;
571
572 /* do some mode translations */
573 h_blank_len = mode->crtc_hblank_end - mode->crtc_hblank_start;
574 h_sync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
575
576 v_blank_len = mode->crtc_vblank_end - mode->crtc_vblank_start;
577 v_sync_len = mode->crtc_vsync_end - mode->crtc_vsync_start;
578
579 h_sync_offset = mode->crtc_hsync_start - mode->crtc_hblank_start;
580 v_sync_offset = mode->crtc_vsync_start - mode->crtc_vblank_start;
581
582 output_dtd.part1.clock = mode->clock / 10;
583 output_dtd.part1.h_active = width & 0xff;
584 output_dtd.part1.h_blank = h_blank_len & 0xff;
585 output_dtd.part1.h_high = (((width >> 8) & 0xf) << 4) |
586 ((h_blank_len >> 8) & 0xf);
587 output_dtd.part1.v_active = height & 0xff;
588 output_dtd.part1.v_blank = v_blank_len & 0xff;
589 output_dtd.part1.v_high = (((height >> 8) & 0xf) << 4) |
590 ((v_blank_len >> 8) & 0xf);
591
592 output_dtd.part2.h_sync_off = h_sync_offset;
593 output_dtd.part2.h_sync_width = h_sync_len & 0xff;
594 output_dtd.part2.v_sync_off_width = (v_sync_offset & 0xf) << 4 |
595 (v_sync_len & 0xf);
596 output_dtd.part2.sync_off_width_high = ((h_sync_offset & 0x300) >> 2) |
597 ((h_sync_len & 0x300) >> 4) | ((v_sync_offset & 0x30) >> 2) |
598 ((v_sync_len & 0x30) >> 4);
599
600 output_dtd.part2.dtd_flags = 0x18;
601 if (mode->flags & DRM_MODE_FLAG_PHSYNC)
602 output_dtd.part2.dtd_flags |= 0x2;
603 if (mode->flags & DRM_MODE_FLAG_PVSYNC)
604 output_dtd.part2.dtd_flags |= 0x4;
605
606 output_dtd.part2.sdvo_flags = 0;
607 output_dtd.part2.v_sync_off_high = v_sync_offset & 0xc0;
608 output_dtd.part2.reserved = 0;
609
610 /* Set the output timing to the screen */
611 intel_sdvo_set_target_output(intel_output, sdvo_priv->active_outputs);
612 intel_sdvo_set_output_timing(intel_output, &output_dtd);
613
614 /* Set the input timing to the screen. Assume always input 0. */
615 intel_sdvo_set_target_input(intel_output, true, false);
616
617 /* We would like to use i830_sdvo_create_preferred_input_timing() to
618 * provide the device with a timing it can support, if it supports that
619 * feature. However, presumably we would need to adjust the CRTC to
620 * output the preferred timing, and we don't support that currently.
621 */
622 intel_sdvo_set_input_timing(intel_output, &output_dtd);
623
624 switch (intel_sdvo_get_pixel_multiplier(mode)) {
625 case 1:
626 intel_sdvo_set_clock_rate_mult(intel_output,
627 SDVO_CLOCK_RATE_MULT_1X);
628 break;
629 case 2:
630 intel_sdvo_set_clock_rate_mult(intel_output,
631 SDVO_CLOCK_RATE_MULT_2X);
632 break;
633 case 4:
634 intel_sdvo_set_clock_rate_mult(intel_output,
635 SDVO_CLOCK_RATE_MULT_4X);
636 break;
637 }
638
639 /* Set the SDVO control regs. */
640 if (0/*IS_I965GM(dev)*/) {
641 sdvox = SDVO_BORDER_ENABLE;
642 } else {
643 sdvox = I915_READ(sdvo_priv->output_device);
644 switch (sdvo_priv->output_device) {
645 case SDVOB:
646 sdvox &= SDVOB_PRESERVE_MASK;
647 break;
648 case SDVOC:
649 sdvox &= SDVOC_PRESERVE_MASK;
650 break;
651 }
652 sdvox |= (9 << 19) | SDVO_BORDER_ENABLE;
653 }
654 if (intel_crtc->pipe == 1)
655 sdvox |= SDVO_PIPE_B_SELECT;
656
657 sdvo_pixel_multiply = intel_sdvo_get_pixel_multiplier(mode);
658 if (IS_I965G(dev)) {
659 /* done in crtc_mode_set as the dpll_md reg must be written
660 early */
661 } else if (IS_I945G(dev) || IS_I945GM(dev)) {
662 /* done in crtc_mode_set as it lives inside the
663 dpll register */
664 } else {
665 sdvox |= (sdvo_pixel_multiply - 1) << SDVO_PORT_MULTIPLY_SHIFT;
666 }
667
668 intel_sdvo_write_sdvox(intel_output, sdvox);
669}
670
671static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
672{
673 struct drm_device *dev = encoder->dev;
674 struct drm_i915_private *dev_priv = dev->dev_private;
675 struct intel_output *intel_output = enc_to_intel_output(encoder);
676 struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
677 u32 temp;
678
679 if (mode != DRM_MODE_DPMS_ON) {
680 intel_sdvo_set_active_outputs(intel_output, 0);
681 if (0)
682 intel_sdvo_set_encoder_power_state(intel_output, mode);
683
684 if (mode == DRM_MODE_DPMS_OFF) {
685 temp = I915_READ(sdvo_priv->output_device);
686 if ((temp & SDVO_ENABLE) != 0) {
687 intel_sdvo_write_sdvox(intel_output, temp & ~SDVO_ENABLE);
688 }
689 }
690 } else {
691 bool input1, input2;
692 int i;
693 u8 status;
694
695 temp = I915_READ(sdvo_priv->output_device);
696 if ((temp & SDVO_ENABLE) == 0)
697 intel_sdvo_write_sdvox(intel_output, temp | SDVO_ENABLE);
698 for (i = 0; i < 2; i++)
699 intel_wait_for_vblank(dev);
700
701 status = intel_sdvo_get_trained_inputs(intel_output, &input1,
702 &input2);
703
704
705 /* Warn if the device reported failure to sync.
706 * A lot of SDVO devices fail to notify of sync, but it's
707 * a given it the status is a success, we succeeded.
708 */
709 if (status == SDVO_CMD_STATUS_SUCCESS && !input1) {
710 DRM_DEBUG("First %s output reported failure to sync\n",
711 SDVO_NAME(sdvo_priv));
712 }
713
714 if (0)
715 intel_sdvo_set_encoder_power_state(intel_output, mode);
716 intel_sdvo_set_active_outputs(intel_output, sdvo_priv->active_outputs);
717 }
718 return;
719}
720
721static void intel_sdvo_save(struct drm_connector *connector)
722{
723 struct drm_device *dev = connector->dev;
724 struct drm_i915_private *dev_priv = dev->dev_private;
725 struct intel_output *intel_output = to_intel_output(connector);
726 struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
727 int o;
728
729 sdvo_priv->save_sdvo_mult = intel_sdvo_get_clock_rate_mult(intel_output);
730 intel_sdvo_get_active_outputs(intel_output, &sdvo_priv->save_active_outputs);
731
732 if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) {
733 intel_sdvo_set_target_input(intel_output, true, false);
734 intel_sdvo_get_input_timing(intel_output,
735 &sdvo_priv->save_input_dtd_1);
736 }
737
738 if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) {
739 intel_sdvo_set_target_input(intel_output, false, true);
740 intel_sdvo_get_input_timing(intel_output,
741 &sdvo_priv->save_input_dtd_2);
742 }
743
744 for (o = SDVO_OUTPUT_FIRST; o <= SDVO_OUTPUT_LAST; o++)
745 {
746 u16 this_output = (1 << o);
747 if (sdvo_priv->caps.output_flags & this_output)
748 {
749 intel_sdvo_set_target_output(intel_output, this_output);
750 intel_sdvo_get_output_timing(intel_output,
751 &sdvo_priv->save_output_dtd[o]);
752 }
753 }
754
755 sdvo_priv->save_SDVOX = I915_READ(sdvo_priv->output_device);
756}
757
758static void intel_sdvo_restore(struct drm_connector *connector)
759{
760 struct drm_device *dev = connector->dev;
761 struct drm_i915_private *dev_priv = dev->dev_private;
762 struct intel_output *intel_output = to_intel_output(connector);
763 struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
764 int o;
765 int i;
766 bool input1, input2;
767 u8 status;
768
769 intel_sdvo_set_active_outputs(intel_output, 0);
770
771 for (o = SDVO_OUTPUT_FIRST; o <= SDVO_OUTPUT_LAST; o++)
772 {
773 u16 this_output = (1 << o);
774 if (sdvo_priv->caps.output_flags & this_output) {
775 intel_sdvo_set_target_output(intel_output, this_output);
776 intel_sdvo_set_output_timing(intel_output, &sdvo_priv->save_output_dtd[o]);
777 }
778 }
779
780 if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) {
781 intel_sdvo_set_target_input(intel_output, true, false);
782 intel_sdvo_set_input_timing(intel_output, &sdvo_priv->save_input_dtd_1);
783 }
784
785 if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) {
786 intel_sdvo_set_target_input(intel_output, false, true);
787 intel_sdvo_set_input_timing(intel_output, &sdvo_priv->save_input_dtd_2);
788 }
789
790 intel_sdvo_set_clock_rate_mult(intel_output, sdvo_priv->save_sdvo_mult);
791
792 I915_WRITE(sdvo_priv->output_device, sdvo_priv->save_SDVOX);
793
794 if (sdvo_priv->save_SDVOX & SDVO_ENABLE)
795 {
796 for (i = 0; i < 2; i++)
797 intel_wait_for_vblank(dev);
798 status = intel_sdvo_get_trained_inputs(intel_output, &input1, &input2);
799 if (status == SDVO_CMD_STATUS_SUCCESS && !input1)
800 DRM_DEBUG("First %s output reported failure to sync\n",
801 SDVO_NAME(sdvo_priv));
802 }
803
804 intel_sdvo_set_active_outputs(intel_output, sdvo_priv->save_active_outputs);
805}
806
807static int intel_sdvo_mode_valid(struct drm_connector *connector,
808 struct drm_display_mode *mode)
809{
810 struct intel_output *intel_output = to_intel_output(connector);
811 struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
812
813 if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
814 return MODE_NO_DBLESCAN;
815
816 if (sdvo_priv->pixel_clock_min > mode->clock)
817 return MODE_CLOCK_LOW;
818
819 if (sdvo_priv->pixel_clock_max < mode->clock)
820 return MODE_CLOCK_HIGH;
821
822 return MODE_OK;
823}
824
825static bool intel_sdvo_get_capabilities(struct intel_output *intel_output, struct intel_sdvo_caps *caps)
826{
827 u8 status;
828
829 intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_DEVICE_CAPS, NULL, 0);
830 status = intel_sdvo_read_response(intel_output, caps, sizeof(*caps));
831 if (status != SDVO_CMD_STATUS_SUCCESS)
832 return false;
833
834 return true;
835}
836
837struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB)
838{
839 struct drm_connector *connector = NULL;
840 struct intel_output *iout = NULL;
841 struct intel_sdvo_priv *sdvo;
842
843 /* find the sdvo connector */
844 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
845 iout = to_intel_output(connector);
846
847 if (iout->type != INTEL_OUTPUT_SDVO)
848 continue;
849
850 sdvo = iout->dev_priv;
851
852 if (sdvo->output_device == SDVOB && sdvoB)
853 return connector;
854
855 if (sdvo->output_device == SDVOC && !sdvoB)
856 return connector;
857
858 }
859
860 return NULL;
861}
862
863int intel_sdvo_supports_hotplug(struct drm_connector *connector)
864{
865 u8 response[2];
866 u8 status;
867 struct intel_output *intel_output;
868 DRM_DEBUG("\n");
869
870 if (!connector)
871 return 0;
872
873 intel_output = to_intel_output(connector);
874
875 intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0);
876 status = intel_sdvo_read_response(intel_output, &response, 2);
877
878 if (response[0] !=0)
879 return 1;
880
881 return 0;
882}
883
884void intel_sdvo_set_hotplug(struct drm_connector *connector, int on)
885{
886 u8 response[2];
887 u8 status;
888 struct intel_output *intel_output = to_intel_output(connector);
889
890 intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0);
891 intel_sdvo_read_response(intel_output, &response, 2);
892
893 if (on) {
894 intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0);
895 status = intel_sdvo_read_response(intel_output, &response, 2);
896
897 intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2);
898 } else {
899 response[0] = 0;
900 response[1] = 0;
901 intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2);
902 }
903
904 intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0);
905 intel_sdvo_read_response(intel_output, &response, 2);
906}
907
908static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connector)
909{
910 u8 response[2];
911 u8 status;
912 struct intel_output *intel_output = to_intel_output(connector);
913
914 intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0);
915 status = intel_sdvo_read_response(intel_output, &response, 2);
916
917 DRM_DEBUG("SDVO response %d %d\n", response[0], response[1]);
918 if ((response[0] != 0) || (response[1] != 0))
919 return connector_status_connected;
920 else
921 return connector_status_disconnected;
922}
923
924static int intel_sdvo_get_modes(struct drm_connector *connector)
925{
926 struct intel_output *intel_output = to_intel_output(connector);
927
928 /* set the bus switch and get the modes */
929 intel_sdvo_set_control_bus_switch(intel_output, SDVO_CONTROL_BUS_DDC2);
930 intel_ddc_get_modes(intel_output);
931
932 if (list_empty(&connector->probed_modes))
933 return 0;
934 return 1;
935}
936
937static void intel_sdvo_destroy(struct drm_connector *connector)
938{
939 struct intel_output *intel_output = to_intel_output(connector);
940
941 if (intel_output->i2c_bus)
942 intel_i2c_destroy(intel_output->i2c_bus);
943 drm_sysfs_connector_remove(connector);
944 drm_connector_cleanup(connector);
945 kfree(intel_output);
946}
947
948static const struct drm_encoder_helper_funcs intel_sdvo_helper_funcs = {
949 .dpms = intel_sdvo_dpms,
950 .mode_fixup = intel_sdvo_mode_fixup,
951 .prepare = intel_encoder_prepare,
952 .mode_set = intel_sdvo_mode_set,
953 .commit = intel_encoder_commit,
954};
955
956static const struct drm_connector_funcs intel_sdvo_connector_funcs = {
957 .save = intel_sdvo_save,
958 .restore = intel_sdvo_restore,
959 .detect = intel_sdvo_detect,
960 .fill_modes = drm_helper_probe_single_connector_modes,
961 .destroy = intel_sdvo_destroy,
962};
963
964static const struct drm_connector_helper_funcs intel_sdvo_connector_helper_funcs = {
965 .get_modes = intel_sdvo_get_modes,
966 .mode_valid = intel_sdvo_mode_valid,
967 .best_encoder = intel_best_encoder,
968};
969
970void intel_sdvo_enc_destroy(struct drm_encoder *encoder)
971{
972 drm_encoder_cleanup(encoder);
973}
974
975static const struct drm_encoder_funcs intel_sdvo_enc_funcs = {
976 .destroy = intel_sdvo_enc_destroy,
977};
978
979
980void intel_sdvo_init(struct drm_device *dev, int output_device)
981{
982 struct drm_connector *connector;
983 struct intel_output *intel_output;
984 struct intel_sdvo_priv *sdvo_priv;
985 struct intel_i2c_chan *i2cbus = NULL;
986 int connector_type;
987 u8 ch[0x40];
988 int i;
989 int encoder_type, output_id;
990
991 intel_output = kcalloc(sizeof(struct intel_output)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL);
992 if (!intel_output) {
993 return;
994 }
995
996 connector = &intel_output->base;
997
998 drm_connector_init(dev, connector, &intel_sdvo_connector_funcs,
999 DRM_MODE_CONNECTOR_Unknown);
1000 drm_connector_helper_add(connector, &intel_sdvo_connector_helper_funcs);
1001 sdvo_priv = (struct intel_sdvo_priv *)(intel_output + 1);
1002 intel_output->type = INTEL_OUTPUT_SDVO;
1003
1004 connector->interlace_allowed = 0;
1005 connector->doublescan_allowed = 0;
1006
1007 /* setup the DDC bus. */
1008 if (output_device == SDVOB)
1009 i2cbus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB");
1010 else
1011 i2cbus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC");
1012
1013 if (!i2cbus)
1014 goto err_connector;
1015
1016 sdvo_priv->i2c_bus = i2cbus;
1017
1018 if (output_device == SDVOB) {
1019 output_id = 1;
1020 sdvo_priv->i2c_bus->slave_addr = 0x38;
1021 } else {
1022 output_id = 2;
1023 sdvo_priv->i2c_bus->slave_addr = 0x39;
1024 }
1025
1026 sdvo_priv->output_device = output_device;
1027 intel_output->i2c_bus = i2cbus;
1028 intel_output->dev_priv = sdvo_priv;
1029
1030
1031 /* Read the regs to test if we can talk to the device */
1032 for (i = 0; i < 0x40; i++) {
1033 if (!intel_sdvo_read_byte(intel_output, i, &ch[i])) {
1034 DRM_DEBUG("No SDVO device found on SDVO%c\n",
1035 output_device == SDVOB ? 'B' : 'C');
1036 goto err_i2c;
1037 }
1038 }
1039
1040 intel_sdvo_get_capabilities(intel_output, &sdvo_priv->caps);
1041
1042 memset(&sdvo_priv->active_outputs, 0, sizeof(sdvo_priv->active_outputs));
1043
1044 /* TODO, CVBS, SVID, YPRPB & SCART outputs. */
1045 if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB0)
1046 {
1047 sdvo_priv->active_outputs = SDVO_OUTPUT_RGB0;
1048 connector->display_info.subpixel_order = SubPixelHorizontalRGB;
1049 encoder_type = DRM_MODE_ENCODER_DAC;
1050 connector_type = DRM_MODE_CONNECTOR_VGA;
1051 }
1052 else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB1)
1053 {
1054 sdvo_priv->active_outputs = SDVO_OUTPUT_RGB1;
1055 connector->display_info.subpixel_order = SubPixelHorizontalRGB;
1056 encoder_type = DRM_MODE_ENCODER_DAC;
1057 connector_type = DRM_MODE_CONNECTOR_VGA;
1058 }
1059 else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS0)
1060 {
1061 sdvo_priv->active_outputs = SDVO_OUTPUT_TMDS0;
1062 connector->display_info.subpixel_order = SubPixelHorizontalRGB;
1063 encoder_type = DRM_MODE_ENCODER_TMDS;
1064 connector_type = DRM_MODE_CONNECTOR_DVID;
1065 }
1066 else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS1)
1067 {
1068 sdvo_priv->active_outputs = SDVO_OUTPUT_TMDS1;
1069 connector->display_info.subpixel_order = SubPixelHorizontalRGB;
1070 encoder_type = DRM_MODE_ENCODER_TMDS;
1071 connector_type = DRM_MODE_CONNECTOR_DVID;
1072 }
1073 else
1074 {
1075 unsigned char bytes[2];
1076
1077 memcpy (bytes, &sdvo_priv->caps.output_flags, 2);
1078 DRM_DEBUG("%s: No active RGB or TMDS outputs (0x%02x%02x)\n",
1079 SDVO_NAME(sdvo_priv),
1080 bytes[0], bytes[1]);
1081 goto err_i2c;
1082 }
1083
1084 drm_encoder_init(dev, &intel_output->enc, &intel_sdvo_enc_funcs, encoder_type);
1085 drm_encoder_helper_add(&intel_output->enc, &intel_sdvo_helper_funcs);
1086 connector->connector_type = connector_type;
1087
1088 drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc);
1089 drm_sysfs_connector_add(connector);
1090
1091 /* Set the input timing to the screen. Assume always input 0. */
1092 intel_sdvo_set_target_input(intel_output, true, false);
1093
1094 intel_sdvo_get_input_pixel_clock_range(intel_output,
1095 &sdvo_priv->pixel_clock_min,
1096 &sdvo_priv->pixel_clock_max);
1097
1098
1099 DRM_DEBUG("%s device VID/DID: %02X:%02X.%02X, "
1100 "clock range %dMHz - %dMHz, "
1101 "input 1: %c, input 2: %c, "
1102 "output 1: %c, output 2: %c\n",
1103 SDVO_NAME(sdvo_priv),
1104 sdvo_priv->caps.vendor_id, sdvo_priv->caps.device_id,
1105 sdvo_priv->caps.device_rev_id,
1106 sdvo_priv->pixel_clock_min / 1000,
1107 sdvo_priv->pixel_clock_max / 1000,
1108 (sdvo_priv->caps.sdvo_inputs_mask & 0x1) ? 'Y' : 'N',
1109 (sdvo_priv->caps.sdvo_inputs_mask & 0x2) ? 'Y' : 'N',
1110 /* check currently supported outputs */
1111 sdvo_priv->caps.output_flags &
1112 (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_RGB0) ? 'Y' : 'N',
1113 sdvo_priv->caps.output_flags &
1114 (SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N');
1115
1116 intel_output->ddc_bus = i2cbus;
1117
1118 return;
1119
1120err_i2c:
1121 intel_i2c_destroy(intel_output->i2c_bus);
1122err_connector:
1123 drm_connector_cleanup(connector);
1124 kfree(intel_output);
1125
1126 return;
1127}