Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
exynos_dp_core.c
Go to the documentation of this file.
1 /*
2  * Samsung SoC DP (Display Port) interface driver.
3  *
4  * Copyright (C) 2012 Samsung Electronics Co., Ltd.
5  * Author: Jingoo Han <[email protected]>
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by the
9  * Free Software Foundation; either version 2 of the License, or (at your
10  * option) any later version.
11  */
12 
13 #include <linux/module.h>
14 #include <linux/platform_device.h>
15 #include <linux/slab.h>
16 #include <linux/err.h>
17 #include <linux/clk.h>
18 #include <linux/io.h>
19 #include <linux/interrupt.h>
20 #include <linux/delay.h>
21 
22 #include <video/exynos_dp.h>
23 
24 #include "exynos_dp_core.h"
25 
26 static int exynos_dp_init_dp(struct exynos_dp_device *dp)
27 {
28  exynos_dp_reset(dp);
29 
31 
34 
35  /* SW defined function Normal operation */
37 
40 
43 
44  return 0;
45 }
46 
47 static int exynos_dp_detect_hpd(struct exynos_dp_device *dp)
48 {
49  int timeout_loop = 0;
50 
52 
53  usleep_range(200, 210);
54 
55  while (exynos_dp_get_plug_in_status(dp) != 0) {
56  timeout_loop++;
57  if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
58  dev_err(dp->dev, "failed to get hpd plug status\n");
59  return -ETIMEDOUT;
60  }
61  usleep_range(10, 11);
62  }
63 
64  return 0;
65 }
66 
67 static unsigned char exynos_dp_calc_edid_check_sum(unsigned char *edid_data)
68 {
69  int i;
70  unsigned char sum = 0;
71 
72  for (i = 0; i < EDID_BLOCK_LENGTH; i++)
73  sum = sum + edid_data[i];
74 
75  return sum;
76 }
77 
78 static int exynos_dp_read_edid(struct exynos_dp_device *dp)
79 {
80  unsigned char edid[EDID_BLOCK_LENGTH * 2];
81  unsigned int extend_block = 0;
82  unsigned char sum;
83  unsigned char test_vector;
84  int retval;
85 
86  /*
87  * EDID device address is 0x50.
88  * However, if necessary, you must have set upper address
89  * into E-EDID in I2C device, 0x30.
90  */
91 
92  /* Read Extension Flag, Number of 128-byte EDID extension blocks */
95  &extend_block);
96 
97  if (extend_block > 0) {
98  dev_dbg(dp->dev, "EDID data includes a single extension!\n");
99 
100  /* Read EDID data */
104  &edid[EDID_HEADER_PATTERN]);
105  if (retval != 0) {
106  dev_err(dp->dev, "EDID Read failed!\n");
107  return -EIO;
108  }
109  sum = exynos_dp_calc_edid_check_sum(edid);
110  if (sum != 0) {
111  dev_err(dp->dev, "EDID bad checksum!\n");
112  return -EIO;
113  }
114 
115  /* Read additional EDID data */
116  retval = exynos_dp_read_bytes_from_i2c(dp,
120  &edid[EDID_BLOCK_LENGTH]);
121  if (retval != 0) {
122  dev_err(dp->dev, "EDID Read failed!\n");
123  return -EIO;
124  }
125  sum = exynos_dp_calc_edid_check_sum(&edid[EDID_BLOCK_LENGTH]);
126  if (sum != 0) {
127  dev_err(dp->dev, "EDID bad checksum!\n");
128  return -EIO;
129  }
130 
132  &test_vector);
133  if (test_vector & DPCD_TEST_EDID_READ) {
140  }
141  } else {
142  dev_info(dp->dev, "EDID data does not include any extensions.\n");
143 
144  /* Read EDID data */
145  retval = exynos_dp_read_bytes_from_i2c(dp,
149  &edid[EDID_HEADER_PATTERN]);
150  if (retval != 0) {
151  dev_err(dp->dev, "EDID Read failed!\n");
152  return -EIO;
153  }
154  sum = exynos_dp_calc_edid_check_sum(edid);
155  if (sum != 0) {
156  dev_err(dp->dev, "EDID bad checksum!\n");
157  return -EIO;
158  }
159 
162  &test_vector);
163  if (test_vector & DPCD_TEST_EDID_READ) {
166  edid[EDID_CHECKSUM]);
170  }
171  }
172 
173  dev_err(dp->dev, "EDID Read success!\n");
174  return 0;
175 }
176 
177 static int exynos_dp_handle_edid(struct exynos_dp_device *dp)
178 {
179  u8 buf[12];
180  int i;
181  int retval;
182 
183  /* Read DPCD DPCD_ADDR_DPCD_REV~RECEIVE_PORT1_CAP_1 */
186  12, buf);
187 
188  /* Read EDID */
189  for (i = 0; i < 3; i++) {
190  retval = exynos_dp_read_edid(dp);
191  if (retval == 0)
192  break;
193  }
194 
195  return retval;
196 }
197 
198 static void exynos_dp_enable_rx_to_enhanced_mode(struct exynos_dp_device *dp,
199  bool enable)
200 {
201  u8 data;
202 
204 
205  if (enable)
208  DPCD_LANE_COUNT_SET(data));
209  else
211  DPCD_LANE_COUNT_SET(data));
212 }
213 
214 static int exynos_dp_is_enhanced_mode_available(struct exynos_dp_device *dp)
215 {
216  u8 data;
217  int retval;
218 
220  retval = DPCD_ENHANCED_FRAME_CAP(data);
221 
222  return retval;
223 }
224 
225 static void exynos_dp_set_enhanced_mode(struct exynos_dp_device *dp)
226 {
227  u8 data;
228 
229  data = exynos_dp_is_enhanced_mode_available(dp);
230  exynos_dp_enable_rx_to_enhanced_mode(dp, data);
232 }
233 
234 static void exynos_dp_training_pattern_dis(struct exynos_dp_device *dp)
235 {
237 
241 }
242 
243 static void exynos_dp_set_lane_lane_pre_emphasis(struct exynos_dp_device *dp,
244  int pre_emphasis, int lane)
245 {
246  switch (lane) {
247  case 0:
248  exynos_dp_set_lane0_pre_emphasis(dp, pre_emphasis);
249  break;
250  case 1:
251  exynos_dp_set_lane1_pre_emphasis(dp, pre_emphasis);
252  break;
253 
254  case 2:
255  exynos_dp_set_lane2_pre_emphasis(dp, pre_emphasis);
256  break;
257 
258  case 3:
259  exynos_dp_set_lane3_pre_emphasis(dp, pre_emphasis);
260  break;
261  }
262 }
263 
264 static void exynos_dp_link_start(struct exynos_dp_device *dp)
265 {
266  u8 buf[4];
267  int lane;
268  int lane_count;
269 
270  lane_count = dp->link_train.lane_count;
271 
272  dp->link_train.lt_state = CLOCK_RECOVERY;
273  dp->link_train.eq_loop = 0;
274 
275  for (lane = 0; lane < lane_count; lane++)
276  dp->link_train.cr_loop[lane] = 0;
277 
278  /* Set sink to D0 (Sink Not Ready) mode. */
281 
282  /* Set link rate and count as you want to establish*/
283  exynos_dp_set_link_bandwidth(dp, dp->link_train.link_rate);
284  exynos_dp_set_lane_count(dp, dp->link_train.lane_count);
285 
286  /* Setup RX configuration */
287  buf[0] = dp->link_train.link_rate;
288  buf[1] = dp->link_train.lane_count;
290  2, buf);
291 
292  /* Set TX pre-emphasis to minimum */
293  for (lane = 0; lane < lane_count; lane++)
294  exynos_dp_set_lane_lane_pre_emphasis(dp,
295  PRE_EMPHASIS_LEVEL_0, lane);
296 
297  /* Set training pattern 1 */
299 
300  /* Set RX training pattern */
305 
306  for (lane = 0; lane < lane_count; lane++)
311  lane_count, buf);
312 }
313 
314 static unsigned char exynos_dp_get_lane_status(u8 link_status[2], int lane)
315 {
316  int shift = (lane & 1) * 4;
317  u8 link_value = link_status[lane>>1];
318 
319  return (link_value >> shift) & 0xf;
320 }
321 
322 static int exynos_dp_clock_recovery_ok(u8 link_status[2], int lane_count)
323 {
324  int lane;
325  u8 lane_status;
326 
327  for (lane = 0; lane < lane_count; lane++) {
328  lane_status = exynos_dp_get_lane_status(link_status, lane);
329  if ((lane_status & DPCD_LANE_CR_DONE) == 0)
330  return -EINVAL;
331  }
332  return 0;
333 }
334 
335 static int exynos_dp_channel_eq_ok(u8 link_align[3], int lane_count)
336 {
337  int lane;
338  u8 lane_align;
339  u8 lane_status;
340 
341  lane_align = link_align[2];
342  if ((lane_align & DPCD_INTERLANE_ALIGN_DONE) == 0)
343  return -EINVAL;
344 
345  for (lane = 0; lane < lane_count; lane++) {
346  lane_status = exynos_dp_get_lane_status(link_align, lane);
347  lane_status &= DPCD_CHANNEL_EQ_BITS;
348  if (lane_status != DPCD_CHANNEL_EQ_BITS)
349  return -EINVAL;
350  }
351 
352  return 0;
353 }
354 
355 static unsigned char exynos_dp_get_adjust_request_voltage(u8 adjust_request[2],
356  int lane)
357 {
358  int shift = (lane & 1) * 4;
359  u8 link_value = adjust_request[lane>>1];
360 
361  return (link_value >> shift) & 0x3;
362 }
363 
364 static unsigned char exynos_dp_get_adjust_request_pre_emphasis(
365  u8 adjust_request[2],
366  int lane)
367 {
368  int shift = (lane & 1) * 4;
369  u8 link_value = adjust_request[lane>>1];
370 
371  return ((link_value >> shift) & 0xc) >> 2;
372 }
373 
374 static void exynos_dp_set_lane_link_training(struct exynos_dp_device *dp,
375  u8 training_lane_set, int lane)
376 {
377  switch (lane) {
378  case 0:
379  exynos_dp_set_lane0_link_training(dp, training_lane_set);
380  break;
381  case 1:
382  exynos_dp_set_lane1_link_training(dp, training_lane_set);
383  break;
384 
385  case 2:
386  exynos_dp_set_lane2_link_training(dp, training_lane_set);
387  break;
388 
389  case 3:
390  exynos_dp_set_lane3_link_training(dp, training_lane_set);
391  break;
392  }
393 }
394 
395 static unsigned int exynos_dp_get_lane_link_training(
396  struct exynos_dp_device *dp,
397  int lane)
398 {
399  u32 reg;
400 
401  switch (lane) {
402  case 0:
404  break;
405  case 1:
407  break;
408  case 2:
410  break;
411  case 3:
413  break;
414  default:
415  WARN_ON(1);
416  return 0;
417  }
418 
419  return reg;
420 }
421 
422 static void exynos_dp_reduce_link_rate(struct exynos_dp_device *dp)
423 {
424  exynos_dp_training_pattern_dis(dp);
425  exynos_dp_set_enhanced_mode(dp);
426 
427  dp->link_train.lt_state = FAILED;
428 }
429 
430 static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
431 {
432  u8 link_status[2];
433  int lane;
434  int lane_count;
435 
436  u8 adjust_request[2];
437  u8 voltage_swing;
438  u8 pre_emphasis;
439  u8 training_lane;
440 
441  usleep_range(100, 101);
442 
443  lane_count = dp->link_train.lane_count;
444 
446  2, link_status);
447 
448  if (exynos_dp_clock_recovery_ok(link_status, lane_count) == 0) {
449  /* set training pattern 2 for EQ */
451 
452  for (lane = 0; lane < lane_count; lane++) {
455  2, adjust_request);
456  voltage_swing = exynos_dp_get_adjust_request_voltage(
457  adjust_request, lane);
458  pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
459  adjust_request, lane);
460  training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) |
461  DPCD_PRE_EMPHASIS_SET(pre_emphasis);
462 
463  if (voltage_swing == VOLTAGE_LEVEL_3)
464  training_lane |= DPCD_MAX_SWING_REACHED;
465  if (pre_emphasis == PRE_EMPHASIS_LEVEL_3)
466  training_lane |= DPCD_MAX_PRE_EMPHASIS_REACHED;
467 
468  dp->link_train.training_lane[lane] = training_lane;
469 
470  exynos_dp_set_lane_link_training(dp,
471  dp->link_train.training_lane[lane],
472  lane);
473  }
474 
479 
482  lane_count,
483  dp->link_train.training_lane);
484 
485  dev_info(dp->dev, "Link Training Clock Recovery success\n");
486  dp->link_train.lt_state = EQUALIZER_TRAINING;
487  } else {
488  for (lane = 0; lane < lane_count; lane++) {
489  training_lane = exynos_dp_get_lane_link_training(
490  dp, lane);
493  2, adjust_request);
494  voltage_swing = exynos_dp_get_adjust_request_voltage(
495  adjust_request, lane);
496  pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
497  adjust_request, lane);
498 
499  if (voltage_swing == VOLTAGE_LEVEL_3 ||
500  pre_emphasis == PRE_EMPHASIS_LEVEL_3) {
501  dev_err(dp->dev, "voltage or pre emphasis reached max level\n");
502  goto reduce_link_rate;
503  }
504 
505  if ((DPCD_VOLTAGE_SWING_GET(training_lane) ==
506  voltage_swing) &&
507  (DPCD_PRE_EMPHASIS_GET(training_lane) ==
508  pre_emphasis)) {
509  dp->link_train.cr_loop[lane]++;
510  if (dp->link_train.cr_loop[lane] == MAX_CR_LOOP) {
511  dev_err(dp->dev, "CR Max loop\n");
512  goto reduce_link_rate;
513  }
514  }
515 
516  training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) |
517  DPCD_PRE_EMPHASIS_SET(pre_emphasis);
518 
519  if (voltage_swing == VOLTAGE_LEVEL_3)
520  training_lane |= DPCD_MAX_SWING_REACHED;
521  if (pre_emphasis == PRE_EMPHASIS_LEVEL_3)
522  training_lane |= DPCD_MAX_PRE_EMPHASIS_REACHED;
523 
524  dp->link_train.training_lane[lane] = training_lane;
525 
526  exynos_dp_set_lane_link_training(dp,
527  dp->link_train.training_lane[lane], lane);
528  }
529 
532  lane_count,
533  dp->link_train.training_lane);
534  }
535 
536  return 0;
537 
538 reduce_link_rate:
539  exynos_dp_reduce_link_rate(dp);
540  return -EIO;
541 }
542 
543 static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)
544 {
545  u8 link_status[2];
546  u8 link_align[3];
547  int lane;
548  int lane_count;
549  u32 reg;
550 
551  u8 adjust_request[2];
552  u8 voltage_swing;
553  u8 pre_emphasis;
554  u8 training_lane;
555 
556  usleep_range(400, 401);
557 
558  lane_count = dp->link_train.lane_count;
559 
561  2, link_status);
562 
563  if (exynos_dp_clock_recovery_ok(link_status, lane_count) == 0) {
564  link_align[0] = link_status[0];
565  link_align[1] = link_status[1];
566 
569  &link_align[2]);
570 
571  for (lane = 0; lane < lane_count; lane++) {
574  2, adjust_request);
575  voltage_swing = exynos_dp_get_adjust_request_voltage(
576  adjust_request, lane);
577  pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
578  adjust_request, lane);
579  training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) |
580  DPCD_PRE_EMPHASIS_SET(pre_emphasis);
581 
582  if (voltage_swing == VOLTAGE_LEVEL_3)
583  training_lane |= DPCD_MAX_SWING_REACHED;
584  if (pre_emphasis == PRE_EMPHASIS_LEVEL_3)
585  training_lane |= DPCD_MAX_PRE_EMPHASIS_REACHED;
586 
587  dp->link_train.training_lane[lane] = training_lane;
588  }
589 
590  if (exynos_dp_channel_eq_ok(link_align, lane_count) == 0) {
591  /* traing pattern Set to Normal */
592  exynos_dp_training_pattern_dis(dp);
593 
594  dev_info(dp->dev, "Link Training success!\n");
595 
597  dp->link_train.link_rate = reg;
598  dev_dbg(dp->dev, "final bandwidth = %.2x\n",
599  dp->link_train.link_rate);
600 
601  exynos_dp_get_lane_count(dp, &reg);
602  dp->link_train.lane_count = reg;
603  dev_dbg(dp->dev, "final lane count = %.2x\n",
604  dp->link_train.lane_count);
605 
606  /* set enhanced mode if available */
607  exynos_dp_set_enhanced_mode(dp);
608  dp->link_train.lt_state = FINISHED;
609  } else {
610  /* not all locked */
611  dp->link_train.eq_loop++;
612 
613  if (dp->link_train.eq_loop > MAX_EQ_LOOP) {
614  dev_err(dp->dev, "EQ Max loop\n");
615  goto reduce_link_rate;
616  }
617 
618  for (lane = 0; lane < lane_count; lane++)
619  exynos_dp_set_lane_link_training(dp,
620  dp->link_train.training_lane[lane],
621  lane);
622 
625  lane_count,
626  dp->link_train.training_lane);
627  }
628  } else {
629  goto reduce_link_rate;
630  }
631 
632  return 0;
633 
634 reduce_link_rate:
635  exynos_dp_reduce_link_rate(dp);
636  return -EIO;
637 }
638 
639 static void exynos_dp_get_max_rx_bandwidth(struct exynos_dp_device *dp,
640  u8 *bandwidth)
641 {
642  u8 data;
643 
644  /*
645  * For DP rev.1.1, Maximum link rate of Main Link lanes
646  * 0x06 = 1.62 Gbps, 0x0a = 2.7 Gbps
647  */
649  *bandwidth = data;
650 }
651 
652 static void exynos_dp_get_max_rx_lane_count(struct exynos_dp_device *dp,
653  u8 *lane_count)
654 {
655  u8 data;
656 
657  /*
658  * For DP rev.1.1, Maximum number of Main Link lanes
659  * 0x01 = 1 lane, 0x02 = 2 lanes, 0x04 = 4 lanes
660  */
662  *lane_count = DPCD_MAX_LANE_COUNT(data);
663 }
664 
665 static void exynos_dp_init_training(struct exynos_dp_device *dp,
666  enum link_lane_count_type max_lane,
667  enum link_rate_type max_rate)
668 {
669  /*
670  * MACRO_RST must be applied after the PLL_LOCK to avoid
671  * the DP inter pair skew issue for at least 10 us
672  */
674 
675  /* Initialize by reading RX's DPCD */
676  exynos_dp_get_max_rx_bandwidth(dp, &dp->link_train.link_rate);
677  exynos_dp_get_max_rx_lane_count(dp, &dp->link_train.lane_count);
678 
679  if ((dp->link_train.link_rate != LINK_RATE_1_62GBPS) &&
680  (dp->link_train.link_rate != LINK_RATE_2_70GBPS)) {
681  dev_err(dp->dev, "Rx Max Link Rate is abnormal :%x !\n",
682  dp->link_train.link_rate);
683  dp->link_train.link_rate = LINK_RATE_1_62GBPS;
684  }
685 
686  if (dp->link_train.lane_count == 0) {
687  dev_err(dp->dev, "Rx Max Lane count is abnormal :%x !\n",
688  dp->link_train.lane_count);
689  dp->link_train.lane_count = (u8)LANE_COUNT1;
690  }
691 
692  /* Setup TX lane count & rate */
693  if (dp->link_train.lane_count > max_lane)
694  dp->link_train.lane_count = max_lane;
695  if (dp->link_train.link_rate > max_rate)
696  dp->link_train.link_rate = max_rate;
697 
698  /* All DP analog module power up */
700 }
701 
702 static int exynos_dp_sw_link_training(struct exynos_dp_device *dp)
703 {
704  int retval = 0;
705  int training_finished = 0;
706 
707  dp->link_train.lt_state = START;
708 
709  /* Process here */
710  while (!training_finished) {
711  switch (dp->link_train.lt_state) {
712  case START:
713  exynos_dp_link_start(dp);
714  break;
715  case CLOCK_RECOVERY:
716  retval = exynos_dp_process_clock_recovery(dp);
717  if (retval)
718  dev_err(dp->dev, "LT CR failed!\n");
719  break;
720  case EQUALIZER_TRAINING:
721  retval = exynos_dp_process_equalizer_training(dp);
722  if (retval)
723  dev_err(dp->dev, "LT EQ failed!\n");
724  break;
725  case FINISHED:
726  training_finished = 1;
727  break;
728  case FAILED:
729  return -EREMOTEIO;
730  }
731  }
732 
733  return retval;
734 }
735 
736 static int exynos_dp_set_link_train(struct exynos_dp_device *dp,
737  u32 count,
738  u32 bwtype)
739 {
740  int i;
741  int retval;
742 
743  for (i = 0; i < DP_TIMEOUT_LOOP_COUNT; i++) {
744  exynos_dp_init_training(dp, count, bwtype);
745  retval = exynos_dp_sw_link_training(dp);
746  if (retval == 0)
747  break;
748 
749  usleep_range(100, 110);
750  }
751 
752  return retval;
753 }
754 
755 static int exynos_dp_config_video(struct exynos_dp_device *dp,
756  struct video_info *video_info)
757 {
758  int retval = 0;
759  int timeout_loop = 0;
760  int done_count = 0;
761 
762  exynos_dp_config_video_slave_mode(dp, video_info);
763 
765  video_info->color_space,
766  video_info->dynamic_range,
767  video_info->ycbcr_coeff);
768 
770  dev_err(dp->dev, "PLL is not locked yet.\n");
771  return -EINVAL;
772  }
773 
774  for (;;) {
775  timeout_loop++;
777  break;
778  if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
779  dev_err(dp->dev, "Timeout of video streamclk ok\n");
780  return -ETIMEDOUT;
781  }
782 
783  usleep_range(1, 2);
784  }
785 
786  /* Set to use the register calculated M/N video */
788 
789  /* For video bist, Video timing must be generated by register */
791 
792  /* Disable video mute */
794 
795  /* Configure video slave mode */
797 
798  /* Enable video */
800 
801  timeout_loop = 0;
802 
803  for (;;) {
804  timeout_loop++;
805  if (exynos_dp_is_video_stream_on(dp) == 0) {
806  done_count++;
807  if (done_count > 10)
808  break;
809  } else if (done_count) {
810  done_count = 0;
811  }
812  if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
813  dev_err(dp->dev, "Timeout of video streamclk ok\n");
814  return -ETIMEDOUT;
815  }
816 
817  usleep_range(1000, 1001);
818  }
819 
820  if (retval != 0)
821  dev_err(dp->dev, "Video stream is not detected!\n");
822 
823  return retval;
824 }
825 
826 static void exynos_dp_enable_scramble(struct exynos_dp_device *dp, bool enable)
827 {
828  u8 data;
829 
830  if (enable) {
832 
835  &data);
838  (u8)(data & ~DPCD_SCRAMBLING_DISABLED));
839  } else {
841 
844  &data);
847  (u8)(data | DPCD_SCRAMBLING_DISABLED));
848  }
849 }
850 
851 static irqreturn_t exynos_dp_irq_handler(int irq, void *arg)
852 {
853  struct exynos_dp_device *dp = arg;
854 
855  dev_err(dp->dev, "exynos_dp_irq_handler\n");
856  return IRQ_HANDLED;
857 }
858 
859 static int __devinit exynos_dp_probe(struct platform_device *pdev)
860 {
861  struct resource *res;
862  struct exynos_dp_device *dp;
863  struct exynos_dp_platdata *pdata;
864 
865  int ret = 0;
866 
867  pdata = pdev->dev.platform_data;
868  if (!pdata) {
869  dev_err(&pdev->dev, "no platform data\n");
870  return -EINVAL;
871  }
872 
873  dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device),
874  GFP_KERNEL);
875  if (!dp) {
876  dev_err(&pdev->dev, "no memory for device data\n");
877  return -ENOMEM;
878  }
879 
880  dp->dev = &pdev->dev;
881 
882  dp->clock = devm_clk_get(&pdev->dev, "dp");
883  if (IS_ERR(dp->clock)) {
884  dev_err(&pdev->dev, "failed to get clock\n");
885  return PTR_ERR(dp->clock);
886  }
887 
888  clk_prepare_enable(dp->clock);
889 
890  res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
891 
892  dp->reg_base = devm_request_and_ioremap(&pdev->dev, res);
893  if (!dp->reg_base) {
894  dev_err(&pdev->dev, "failed to ioremap\n");
895  return -ENOMEM;
896  }
897 
898  dp->irq = platform_get_irq(pdev, 0);
899  if (!dp->irq) {
900  dev_err(&pdev->dev, "failed to get irq\n");
901  return -ENODEV;
902  }
903 
904  ret = devm_request_irq(&pdev->dev, dp->irq, exynos_dp_irq_handler, 0,
905  "exynos-dp", dp);
906  if (ret) {
907  dev_err(&pdev->dev, "failed to request irq\n");
908  return ret;
909  }
910 
911  dp->video_info = pdata->video_info;
912  if (pdata->phy_init)
913  pdata->phy_init();
914 
915  exynos_dp_init_dp(dp);
916 
917  ret = exynos_dp_detect_hpd(dp);
918  if (ret) {
919  dev_err(&pdev->dev, "unable to detect hpd\n");
920  return ret;
921  }
922 
923  exynos_dp_handle_edid(dp);
924 
925  ret = exynos_dp_set_link_train(dp, dp->video_info->lane_count,
926  dp->video_info->link_rate);
927  if (ret) {
928  dev_err(&pdev->dev, "unable to do link train\n");
929  return ret;
930  }
931 
932  exynos_dp_enable_scramble(dp, 1);
933  exynos_dp_enable_rx_to_enhanced_mode(dp, 1);
935 
936  exynos_dp_set_lane_count(dp, dp->video_info->lane_count);
937  exynos_dp_set_link_bandwidth(dp, dp->video_info->link_rate);
938 
940  ret = exynos_dp_config_video(dp, dp->video_info);
941  if (ret) {
942  dev_err(&pdev->dev, "unable to config video\n");
943  return ret;
944  }
945 
946  platform_set_drvdata(pdev, dp);
947 
948  return 0;
949 }
950 
951 static int __devexit exynos_dp_remove(struct platform_device *pdev)
952 {
953  struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
954  struct exynos_dp_device *dp = platform_get_drvdata(pdev);
955 
956  if (pdata && pdata->phy_exit)
957  pdata->phy_exit();
958 
959  clk_disable_unprepare(dp->clock);
960 
961  return 0;
962 }
963 
964 #ifdef CONFIG_PM_SLEEP
965 static int exynos_dp_suspend(struct device *dev)
966 {
967  struct platform_device *pdev = to_platform_device(dev);
968  struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
969  struct exynos_dp_device *dp = platform_get_drvdata(pdev);
970 
971  if (pdata && pdata->phy_exit)
972  pdata->phy_exit();
973 
974  clk_disable_unprepare(dp->clock);
975 
976  return 0;
977 }
978 
979 static int exynos_dp_resume(struct device *dev)
980 {
981  struct platform_device *pdev = to_platform_device(dev);
982  struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
983  struct exynos_dp_device *dp = platform_get_drvdata(pdev);
984 
985  if (pdata && pdata->phy_init)
986  pdata->phy_init();
987 
988  clk_prepare_enable(dp->clock);
989 
990  exynos_dp_init_dp(dp);
991 
992  exynos_dp_detect_hpd(dp);
993  exynos_dp_handle_edid(dp);
994 
995  exynos_dp_set_link_train(dp, dp->video_info->lane_count,
996  dp->video_info->link_rate);
997 
998  exynos_dp_enable_scramble(dp, 1);
999  exynos_dp_enable_rx_to_enhanced_mode(dp, 1);
1001 
1002  exynos_dp_set_lane_count(dp, dp->video_info->lane_count);
1003  exynos_dp_set_link_bandwidth(dp, dp->video_info->link_rate);
1004 
1006  exynos_dp_config_video(dp, dp->video_info);
1007 
1008  return 0;
1009 }
1010 #endif
1011 
1012 static const struct dev_pm_ops exynos_dp_pm_ops = {
1013  SET_SYSTEM_SLEEP_PM_OPS(exynos_dp_suspend, exynos_dp_resume)
1014 };
1015 
1016 static struct platform_driver exynos_dp_driver = {
1017  .probe = exynos_dp_probe,
1018  .remove = __devexit_p(exynos_dp_remove),
1019  .driver = {
1020  .name = "exynos-dp",
1021  .owner = THIS_MODULE,
1022  .pm = &exynos_dp_pm_ops,
1023  },
1024 };
1025 
1026 module_platform_driver(exynos_dp_driver);
1027 
1028 MODULE_AUTHOR("Jingoo Han <[email protected]>");
1029 MODULE_DESCRIPTION("Samsung SoC DP Driver");
1030 MODULE_LICENSE("GPL");