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