Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
exynos_hdmi.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2011 Samsung Electronics Co.Ltd
3  * Authors:
4  * Seung-Woo Kim <[email protected]>
5  * Inki Dae <[email protected]>
6  * Joonyoung Shim <[email protected]>
7  *
8  * Based on drivers/media/video/s5p-tv/hdmi_drv.c
9  *
10  * This program is free software; you can redistribute it and/or modify it
11  * under the terms of the GNU General Public License as published by the
12  * Free Software Foundation; either version 2 of the License, or (at your
13  * option) any later version.
14  *
15  */
16 
17 #include <drm/drmP.h>
18 #include <drm/drm_edid.h>
19 #include <drm/drm_crtc_helper.h>
20 
21 #include "regs-hdmi.h"
22 
23 #include <linux/kernel.h>
24 #include <linux/spinlock.h>
25 #include <linux/wait.h>
26 #include <linux/i2c.h>
27 #include <linux/module.h>
28 #include <linux/platform_device.h>
29 #include <linux/interrupt.h>
30 #include <linux/irq.h>
31 #include <linux/delay.h>
32 #include <linux/pm_runtime.h>
33 #include <linux/clk.h>
35 #include <linux/io.h>
36 #include <linux/of_gpio.h>
37 #include <plat/gpio-cfg.h>
38 
39 #include <drm/exynos_drm.h>
40 
41 #include "exynos_drm_drv.h"
42 #include "exynos_drm_hdmi.h"
43 
44 #include "exynos_hdmi.h"
45 
46 #include <linux/gpio.h>
47 #include <media/s5p_hdmi.h>
48 
49 #define MAX_WIDTH 1920
50 #define MAX_HEIGHT 1080
51 #define get_hdmi_context(dev) platform_get_drvdata(to_platform_device(dev))
52 
53 enum hdmi_type {
56 };
57 
59  struct clk *hdmi;
60  struct clk *sclk_hdmi;
61  struct clk *sclk_pixel;
62  struct clk *sclk_hdmiphy;
63  struct clk *hdmiphy;
66 };
67 
68 struct hdmi_context {
69  struct device *dev;
71  bool hpd;
72  bool powered;
73  bool dvi_mode;
74  struct mutex hdmi_mutex;
75 
76  void __iomem *regs;
79 
82 
83  /* current hdmiphy conf index */
84  int cur_conf;
85 
87  void *parent_ctx;
88 
89  int hpd_gpio;
90 
92 };
93 
94 /* HDMI Version 1.3 */
95 static const u8 hdmiphy_v13_conf27[32] = {
96  0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40,
97  0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
98  0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
99  0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
100 };
101 
102 static const u8 hdmiphy_v13_conf27_027[32] = {
103  0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09, 0x64,
104  0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
105  0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
106  0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
107 };
108 
109 static const u8 hdmiphy_v13_conf74_175[32] = {
110  0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef, 0x5B,
111  0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3, 0x54, 0xb9,
112  0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
113  0x22, 0x40, 0xa5, 0x26, 0x01, 0x00, 0x00, 0x00,
114 };
115 
116 static const u8 hdmiphy_v13_conf74_25[32] = {
117  0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c, 0xf8, 0x40,
118  0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1, 0x54, 0xba,
119  0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xe0,
120  0x22, 0x40, 0xa4, 0x26, 0x01, 0x00, 0x00, 0x00,
121 };
122 
123 static const u8 hdmiphy_v13_conf148_5[32] = {
124  0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf8, 0x40,
125  0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1, 0x54, 0xba,
126  0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0,
127  0x22, 0x40, 0xa4, 0x26, 0x02, 0x00, 0x00, 0x00,
128 };
129 
160 };
161 
173 };
174 
178 };
179 
181  int width;
182  int height;
183  int vrefresh;
184  bool interlace;
185  const u8 *hdmiphy_data;
186  const struct hdmi_v13_preset_conf *conf;
187 };
188 
189 static const struct hdmi_v13_preset_conf hdmi_v13_conf_480p = {
190  .core = {
191  .h_blank = {0x8a, 0x00},
192  .v_blank = {0x0d, 0x6a, 0x01},
193  .h_v_line = {0x0d, 0xa2, 0x35},
194  .vsync_pol = {0x01},
195  .int_pro_mode = {0x00},
196  .v_blank_f = {0x00, 0x00, 0x00},
197  .h_sync_gen = {0x0e, 0x30, 0x11},
198  .v_sync_gen1 = {0x0f, 0x90, 0x00},
199  /* other don't care */
200  },
201  .tg = {
202  0x00, /* cmd */
203  0x5a, 0x03, /* h_fsz */
204  0x8a, 0x00, 0xd0, 0x02, /* hact */
205  0x0d, 0x02, /* v_fsz */
206  0x01, 0x00, 0x33, 0x02, /* vsync */
207  0x2d, 0x00, 0xe0, 0x01, /* vact */
208  0x33, 0x02, /* field_chg */
209  0x49, 0x02, /* vact_st2 */
210  0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
211  0x01, 0x00, 0x33, 0x02, /* field top/bot */
212  },
213 };
214 
215 static const struct hdmi_v13_preset_conf hdmi_v13_conf_720p60 = {
216  .core = {
217  .h_blank = {0x72, 0x01},
218  .v_blank = {0xee, 0xf2, 0x00},
219  .h_v_line = {0xee, 0x22, 0x67},
220  .vsync_pol = {0x00},
221  .int_pro_mode = {0x00},
222  .v_blank_f = {0x00, 0x00, 0x00}, /* don't care */
223  .h_sync_gen = {0x6c, 0x50, 0x02},
224  .v_sync_gen1 = {0x0a, 0x50, 0x00},
225  .v_sync_gen2 = {0x01, 0x10, 0x00},
226  .v_sync_gen3 = {0x01, 0x10, 0x00},
227  /* other don't care */
228  },
229  .tg = {
230  0x00, /* cmd */
231  0x72, 0x06, /* h_fsz */
232  0x71, 0x01, 0x01, 0x05, /* hact */
233  0xee, 0x02, /* v_fsz */
234  0x01, 0x00, 0x33, 0x02, /* vsync */
235  0x1e, 0x00, 0xd0, 0x02, /* vact */
236  0x33, 0x02, /* field_chg */
237  0x49, 0x02, /* vact_st2 */
238  0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
239  0x01, 0x00, 0x33, 0x02, /* field top/bot */
240  },
241 };
242 
243 static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080i50 = {
244  .core = {
245  .h_blank = {0xd0, 0x02},
246  .v_blank = {0x32, 0xB2, 0x00},
247  .h_v_line = {0x65, 0x04, 0xa5},
248  .vsync_pol = {0x00},
249  .int_pro_mode = {0x01},
250  .v_blank_f = {0x49, 0x2A, 0x23},
251  .h_sync_gen = {0x0E, 0xEA, 0x08},
252  .v_sync_gen1 = {0x07, 0x20, 0x00},
253  .v_sync_gen2 = {0x39, 0x42, 0x23},
254  .v_sync_gen3 = {0x38, 0x87, 0x73},
255  /* other don't care */
256  },
257  .tg = {
258  0x00, /* cmd */
259  0x50, 0x0A, /* h_fsz */
260  0xCF, 0x02, 0x81, 0x07, /* hact */
261  0x65, 0x04, /* v_fsz */
262  0x01, 0x00, 0x33, 0x02, /* vsync */
263  0x16, 0x00, 0x1c, 0x02, /* vact */
264  0x33, 0x02, /* field_chg */
265  0x49, 0x02, /* vact_st2 */
266  0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
267  0x01, 0x00, 0x33, 0x02, /* field top/bot */
268  },
269 };
270 
271 static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080p50 = {
272  .core = {
273  .h_blank = {0xd0, 0x02},
274  .v_blank = {0x65, 0x6c, 0x01},
275  .h_v_line = {0x65, 0x04, 0xa5},
276  .vsync_pol = {0x00},
277  .int_pro_mode = {0x00},
278  .v_blank_f = {0x00, 0x00, 0x00}, /* don't care */
279  .h_sync_gen = {0x0e, 0xea, 0x08},
280  .v_sync_gen1 = {0x09, 0x40, 0x00},
281  .v_sync_gen2 = {0x01, 0x10, 0x00},
282  .v_sync_gen3 = {0x01, 0x10, 0x00},
283  /* other don't care */
284  },
285  .tg = {
286  0x00, /* cmd */
287  0x50, 0x0A, /* h_fsz */
288  0xCF, 0x02, 0x81, 0x07, /* hact */
289  0x65, 0x04, /* v_fsz */
290  0x01, 0x00, 0x33, 0x02, /* vsync */
291  0x2d, 0x00, 0x38, 0x04, /* vact */
292  0x33, 0x02, /* field_chg */
293  0x48, 0x02, /* vact_st2 */
294  0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
295  0x01, 0x00, 0x33, 0x02, /* field top/bot */
296  },
297 };
298 
299 static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080i60 = {
300  .core = {
301  .h_blank = {0x18, 0x01},
302  .v_blank = {0x32, 0xB2, 0x00},
303  .h_v_line = {0x65, 0x84, 0x89},
304  .vsync_pol = {0x00},
305  .int_pro_mode = {0x01},
306  .v_blank_f = {0x49, 0x2A, 0x23},
307  .h_sync_gen = {0x56, 0x08, 0x02},
308  .v_sync_gen1 = {0x07, 0x20, 0x00},
309  .v_sync_gen2 = {0x39, 0x42, 0x23},
310  .v_sync_gen3 = {0xa4, 0x44, 0x4a},
311  /* other don't care */
312  },
313  .tg = {
314  0x00, /* cmd */
315  0x98, 0x08, /* h_fsz */
316  0x17, 0x01, 0x81, 0x07, /* hact */
317  0x65, 0x04, /* v_fsz */
318  0x01, 0x00, 0x33, 0x02, /* vsync */
319  0x16, 0x00, 0x1c, 0x02, /* vact */
320  0x33, 0x02, /* field_chg */
321  0x49, 0x02, /* vact_st2 */
322  0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
323  0x01, 0x00, 0x33, 0x02, /* field top/bot */
324  },
325 };
326 
327 static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080p60 = {
328  .core = {
329  .h_blank = {0x18, 0x01},
330  .v_blank = {0x65, 0x6c, 0x01},
331  .h_v_line = {0x65, 0x84, 0x89},
332  .vsync_pol = {0x00},
333  .int_pro_mode = {0x00},
334  .v_blank_f = {0x00, 0x00, 0x00}, /* don't care */
335  .h_sync_gen = {0x56, 0x08, 0x02},
336  .v_sync_gen1 = {0x09, 0x40, 0x00},
337  .v_sync_gen2 = {0x01, 0x10, 0x00},
338  .v_sync_gen3 = {0x01, 0x10, 0x00},
339  /* other don't care */
340  },
341  .tg = {
342  0x00, /* cmd */
343  0x98, 0x08, /* h_fsz */
344  0x17, 0x01, 0x81, 0x07, /* hact */
345  0x65, 0x04, /* v_fsz */
346  0x01, 0x00, 0x33, 0x02, /* vsync */
347  0x2d, 0x00, 0x38, 0x04, /* vact */
348  0x33, 0x02, /* field_chg */
349  0x48, 0x02, /* vact_st2 */
350  0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
351  0x01, 0x00, 0x33, 0x02, /* field top/bot */
352  },
353 };
354 
355 static const struct hdmi_v13_conf hdmi_v13_confs[] = {
356  { 1280, 720, 60, false, hdmiphy_v13_conf74_25, &hdmi_v13_conf_720p60 },
357  { 1280, 720, 50, false, hdmiphy_v13_conf74_25, &hdmi_v13_conf_720p60 },
358  { 720, 480, 60, false, hdmiphy_v13_conf27_027, &hdmi_v13_conf_480p },
359  { 1920, 1080, 50, true, hdmiphy_v13_conf74_25, &hdmi_v13_conf_1080i50 },
360  { 1920, 1080, 50, false, hdmiphy_v13_conf148_5,
361  &hdmi_v13_conf_1080p50 },
362  { 1920, 1080, 60, true, hdmiphy_v13_conf74_25, &hdmi_v13_conf_1080i60 },
363  { 1920, 1080, 60, false, hdmiphy_v13_conf148_5,
364  &hdmi_v13_conf_1080p60 },
365 };
366 
367 /* HDMI Version 1.4 */
368 static const u8 hdmiphy_conf27_027[32] = {
369  0x01, 0xd1, 0x2d, 0x72, 0x40, 0x64, 0x12, 0x08,
370  0x43, 0xa0, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
371  0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
372  0x54, 0xe3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00,
373 };
374 
375 static const u8 hdmiphy_conf74_176[32] = {
376  0x01, 0xd1, 0x1f, 0x10, 0x40, 0x5b, 0xef, 0x08,
377  0x81, 0xa0, 0xb9, 0xd8, 0x45, 0xa0, 0xac, 0x80,
378  0x5a, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
379  0x54, 0xa6, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00,
380 };
381 
382 static const u8 hdmiphy_conf74_25[32] = {
383  0x01, 0xd1, 0x1f, 0x10, 0x40, 0x40, 0xf8, 0x08,
384  0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
385  0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
386  0x54, 0xa5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00,
387 };
388 
389 static const u8 hdmiphy_conf148_5[32] = {
390  0x01, 0xd1, 0x1f, 0x00, 0x40, 0x40, 0xf8, 0x08,
391  0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
392  0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
393  0x54, 0x4b, 0x25, 0x03, 0x00, 0x00, 0x01, 0x00,
394 };
395 
396 struct hdmi_tg_regs {
431 };
432 
437  u8 v_line[2];
438  u8 h_line[2];
452  u8 v_blank_f2[2]; /* for 3D mode */
453  u8 v_blank_f3[2]; /* for 3D mode */
454  u8 v_blank_f4[2]; /* for 3D mode */
455  u8 v_blank_f5[2]; /* for 3D mode */
470 };
471 
474  struct hdmi_tg_regs tg;
475 };
476 
477 struct hdmi_conf {
478  int width;
479  int height;
480  int vrefresh;
481  bool interlace;
482  const u8 *hdmiphy_data;
483  const struct hdmi_preset_conf *conf;
484 };
485 
486 static const struct hdmi_preset_conf hdmi_conf_480p60 = {
487  .core = {
488  .h_blank = {0x8a, 0x00},
489  .v2_blank = {0x0d, 0x02},
490  .v1_blank = {0x2d, 0x00},
491  .v_line = {0x0d, 0x02},
492  .h_line = {0x5a, 0x03},
493  .hsync_pol = {0x01},
494  .vsync_pol = {0x01},
495  .int_pro_mode = {0x00},
496  .v_blank_f0 = {0xff, 0xff},
497  .v_blank_f1 = {0xff, 0xff},
498  .h_sync_start = {0x0e, 0x00},
499  .h_sync_end = {0x4c, 0x00},
500  .v_sync_line_bef_2 = {0x0f, 0x00},
501  .v_sync_line_bef_1 = {0x09, 0x00},
502  .v_sync_line_aft_2 = {0xff, 0xff},
503  .v_sync_line_aft_1 = {0xff, 0xff},
504  .v_sync_line_aft_pxl_2 = {0xff, 0xff},
505  .v_sync_line_aft_pxl_1 = {0xff, 0xff},
506  .v_blank_f2 = {0xff, 0xff},
507  .v_blank_f3 = {0xff, 0xff},
508  .v_blank_f4 = {0xff, 0xff},
509  .v_blank_f5 = {0xff, 0xff},
510  .v_sync_line_aft_3 = {0xff, 0xff},
511  .v_sync_line_aft_4 = {0xff, 0xff},
512  .v_sync_line_aft_5 = {0xff, 0xff},
513  .v_sync_line_aft_6 = {0xff, 0xff},
514  .v_sync_line_aft_pxl_3 = {0xff, 0xff},
515  .v_sync_line_aft_pxl_4 = {0xff, 0xff},
516  .v_sync_line_aft_pxl_5 = {0xff, 0xff},
517  .v_sync_line_aft_pxl_6 = {0xff, 0xff},
518  .vact_space_1 = {0xff, 0xff},
519  .vact_space_2 = {0xff, 0xff},
520  .vact_space_3 = {0xff, 0xff},
521  .vact_space_4 = {0xff, 0xff},
522  .vact_space_5 = {0xff, 0xff},
523  .vact_space_6 = {0xff, 0xff},
524  /* other don't care */
525  },
526  .tg = {
527  0x00, /* cmd */
528  0x5a, 0x03, /* h_fsz */
529  0x8a, 0x00, 0xd0, 0x02, /* hact */
530  0x0d, 0x02, /* v_fsz */
531  0x01, 0x00, 0x33, 0x02, /* vsync */
532  0x2d, 0x00, 0xe0, 0x01, /* vact */
533  0x33, 0x02, /* field_chg */
534  0x48, 0x02, /* vact_st2 */
535  0x00, 0x00, /* vact_st3 */
536  0x00, 0x00, /* vact_st4 */
537  0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
538  0x01, 0x00, 0x33, 0x02, /* field top/bot */
539  0x00, /* 3d FP */
540  },
541 };
542 
543 static const struct hdmi_preset_conf hdmi_conf_720p50 = {
544  .core = {
545  .h_blank = {0xbc, 0x02},
546  .v2_blank = {0xee, 0x02},
547  .v1_blank = {0x1e, 0x00},
548  .v_line = {0xee, 0x02},
549  .h_line = {0xbc, 0x07},
550  .hsync_pol = {0x00},
551  .vsync_pol = {0x00},
552  .int_pro_mode = {0x00},
553  .v_blank_f0 = {0xff, 0xff},
554  .v_blank_f1 = {0xff, 0xff},
555  .h_sync_start = {0xb6, 0x01},
556  .h_sync_end = {0xde, 0x01},
557  .v_sync_line_bef_2 = {0x0a, 0x00},
558  .v_sync_line_bef_1 = {0x05, 0x00},
559  .v_sync_line_aft_2 = {0xff, 0xff},
560  .v_sync_line_aft_1 = {0xff, 0xff},
561  .v_sync_line_aft_pxl_2 = {0xff, 0xff},
562  .v_sync_line_aft_pxl_1 = {0xff, 0xff},
563  .v_blank_f2 = {0xff, 0xff},
564  .v_blank_f3 = {0xff, 0xff},
565  .v_blank_f4 = {0xff, 0xff},
566  .v_blank_f5 = {0xff, 0xff},
567  .v_sync_line_aft_3 = {0xff, 0xff},
568  .v_sync_line_aft_4 = {0xff, 0xff},
569  .v_sync_line_aft_5 = {0xff, 0xff},
570  .v_sync_line_aft_6 = {0xff, 0xff},
571  .v_sync_line_aft_pxl_3 = {0xff, 0xff},
572  .v_sync_line_aft_pxl_4 = {0xff, 0xff},
573  .v_sync_line_aft_pxl_5 = {0xff, 0xff},
574  .v_sync_line_aft_pxl_6 = {0xff, 0xff},
575  .vact_space_1 = {0xff, 0xff},
576  .vact_space_2 = {0xff, 0xff},
577  .vact_space_3 = {0xff, 0xff},
578  .vact_space_4 = {0xff, 0xff},
579  .vact_space_5 = {0xff, 0xff},
580  .vact_space_6 = {0xff, 0xff},
581  /* other don't care */
582  },
583  .tg = {
584  0x00, /* cmd */
585  0xbc, 0x07, /* h_fsz */
586  0xbc, 0x02, 0x00, 0x05, /* hact */
587  0xee, 0x02, /* v_fsz */
588  0x01, 0x00, 0x33, 0x02, /* vsync */
589  0x1e, 0x00, 0xd0, 0x02, /* vact */
590  0x33, 0x02, /* field_chg */
591  0x48, 0x02, /* vact_st2 */
592  0x00, 0x00, /* vact_st3 */
593  0x00, 0x00, /* vact_st4 */
594  0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
595  0x01, 0x00, 0x33, 0x02, /* field top/bot */
596  0x00, /* 3d FP */
597  },
598 };
599 
600 static const struct hdmi_preset_conf hdmi_conf_720p60 = {
601  .core = {
602  .h_blank = {0x72, 0x01},
603  .v2_blank = {0xee, 0x02},
604  .v1_blank = {0x1e, 0x00},
605  .v_line = {0xee, 0x02},
606  .h_line = {0x72, 0x06},
607  .hsync_pol = {0x00},
608  .vsync_pol = {0x00},
609  .int_pro_mode = {0x00},
610  .v_blank_f0 = {0xff, 0xff},
611  .v_blank_f1 = {0xff, 0xff},
612  .h_sync_start = {0x6c, 0x00},
613  .h_sync_end = {0x94, 0x00},
614  .v_sync_line_bef_2 = {0x0a, 0x00},
615  .v_sync_line_bef_1 = {0x05, 0x00},
616  .v_sync_line_aft_2 = {0xff, 0xff},
617  .v_sync_line_aft_1 = {0xff, 0xff},
618  .v_sync_line_aft_pxl_2 = {0xff, 0xff},
619  .v_sync_line_aft_pxl_1 = {0xff, 0xff},
620  .v_blank_f2 = {0xff, 0xff},
621  .v_blank_f3 = {0xff, 0xff},
622  .v_blank_f4 = {0xff, 0xff},
623  .v_blank_f5 = {0xff, 0xff},
624  .v_sync_line_aft_3 = {0xff, 0xff},
625  .v_sync_line_aft_4 = {0xff, 0xff},
626  .v_sync_line_aft_5 = {0xff, 0xff},
627  .v_sync_line_aft_6 = {0xff, 0xff},
628  .v_sync_line_aft_pxl_3 = {0xff, 0xff},
629  .v_sync_line_aft_pxl_4 = {0xff, 0xff},
630  .v_sync_line_aft_pxl_5 = {0xff, 0xff},
631  .v_sync_line_aft_pxl_6 = {0xff, 0xff},
632  .vact_space_1 = {0xff, 0xff},
633  .vact_space_2 = {0xff, 0xff},
634  .vact_space_3 = {0xff, 0xff},
635  .vact_space_4 = {0xff, 0xff},
636  .vact_space_5 = {0xff, 0xff},
637  .vact_space_6 = {0xff, 0xff},
638  /* other don't care */
639  },
640  .tg = {
641  0x00, /* cmd */
642  0x72, 0x06, /* h_fsz */
643  0x72, 0x01, 0x00, 0x05, /* hact */
644  0xee, 0x02, /* v_fsz */
645  0x01, 0x00, 0x33, 0x02, /* vsync */
646  0x1e, 0x00, 0xd0, 0x02, /* vact */
647  0x33, 0x02, /* field_chg */
648  0x48, 0x02, /* vact_st2 */
649  0x00, 0x00, /* vact_st3 */
650  0x00, 0x00, /* vact_st4 */
651  0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
652  0x01, 0x00, 0x33, 0x02, /* field top/bot */
653  0x00, /* 3d FP */
654  },
655 };
656 
657 static const struct hdmi_preset_conf hdmi_conf_1080i50 = {
658  .core = {
659  .h_blank = {0xd0, 0x02},
660  .v2_blank = {0x32, 0x02},
661  .v1_blank = {0x16, 0x00},
662  .v_line = {0x65, 0x04},
663  .h_line = {0x50, 0x0a},
664  .hsync_pol = {0x00},
665  .vsync_pol = {0x00},
666  .int_pro_mode = {0x01},
667  .v_blank_f0 = {0x49, 0x02},
668  .v_blank_f1 = {0x65, 0x04},
669  .h_sync_start = {0x0e, 0x02},
670  .h_sync_end = {0x3a, 0x02},
671  .v_sync_line_bef_2 = {0x07, 0x00},
672  .v_sync_line_bef_1 = {0x02, 0x00},
673  .v_sync_line_aft_2 = {0x39, 0x02},
674  .v_sync_line_aft_1 = {0x34, 0x02},
675  .v_sync_line_aft_pxl_2 = {0x38, 0x07},
676  .v_sync_line_aft_pxl_1 = {0x38, 0x07},
677  .v_blank_f2 = {0xff, 0xff},
678  .v_blank_f3 = {0xff, 0xff},
679  .v_blank_f4 = {0xff, 0xff},
680  .v_blank_f5 = {0xff, 0xff},
681  .v_sync_line_aft_3 = {0xff, 0xff},
682  .v_sync_line_aft_4 = {0xff, 0xff},
683  .v_sync_line_aft_5 = {0xff, 0xff},
684  .v_sync_line_aft_6 = {0xff, 0xff},
685  .v_sync_line_aft_pxl_3 = {0xff, 0xff},
686  .v_sync_line_aft_pxl_4 = {0xff, 0xff},
687  .v_sync_line_aft_pxl_5 = {0xff, 0xff},
688  .v_sync_line_aft_pxl_6 = {0xff, 0xff},
689  .vact_space_1 = {0xff, 0xff},
690  .vact_space_2 = {0xff, 0xff},
691  .vact_space_3 = {0xff, 0xff},
692  .vact_space_4 = {0xff, 0xff},
693  .vact_space_5 = {0xff, 0xff},
694  .vact_space_6 = {0xff, 0xff},
695  /* other don't care */
696  },
697  .tg = {
698  0x00, /* cmd */
699  0x50, 0x0a, /* h_fsz */
700  0xd0, 0x02, 0x80, 0x07, /* hact */
701  0x65, 0x04, /* v_fsz */
702  0x01, 0x00, 0x33, 0x02, /* vsync */
703  0x16, 0x00, 0x1c, 0x02, /* vact */
704  0x33, 0x02, /* field_chg */
705  0x49, 0x02, /* vact_st2 */
706  0x00, 0x00, /* vact_st3 */
707  0x00, 0x00, /* vact_st4 */
708  0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
709  0x01, 0x00, 0x33, 0x02, /* field top/bot */
710  0x00, /* 3d FP */
711  },
712 };
713 
714 static const struct hdmi_preset_conf hdmi_conf_1080i60 = {
715  .core = {
716  .h_blank = {0x18, 0x01},
717  .v2_blank = {0x32, 0x02},
718  .v1_blank = {0x16, 0x00},
719  .v_line = {0x65, 0x04},
720  .h_line = {0x98, 0x08},
721  .hsync_pol = {0x00},
722  .vsync_pol = {0x00},
723  .int_pro_mode = {0x01},
724  .v_blank_f0 = {0x49, 0x02},
725  .v_blank_f1 = {0x65, 0x04},
726  .h_sync_start = {0x56, 0x00},
727  .h_sync_end = {0x82, 0x00},
728  .v_sync_line_bef_2 = {0x07, 0x00},
729  .v_sync_line_bef_1 = {0x02, 0x00},
730  .v_sync_line_aft_2 = {0x39, 0x02},
731  .v_sync_line_aft_1 = {0x34, 0x02},
732  .v_sync_line_aft_pxl_2 = {0xa4, 0x04},
733  .v_sync_line_aft_pxl_1 = {0xa4, 0x04},
734  .v_blank_f2 = {0xff, 0xff},
735  .v_blank_f3 = {0xff, 0xff},
736  .v_blank_f4 = {0xff, 0xff},
737  .v_blank_f5 = {0xff, 0xff},
738  .v_sync_line_aft_3 = {0xff, 0xff},
739  .v_sync_line_aft_4 = {0xff, 0xff},
740  .v_sync_line_aft_5 = {0xff, 0xff},
741  .v_sync_line_aft_6 = {0xff, 0xff},
742  .v_sync_line_aft_pxl_3 = {0xff, 0xff},
743  .v_sync_line_aft_pxl_4 = {0xff, 0xff},
744  .v_sync_line_aft_pxl_5 = {0xff, 0xff},
745  .v_sync_line_aft_pxl_6 = {0xff, 0xff},
746  .vact_space_1 = {0xff, 0xff},
747  .vact_space_2 = {0xff, 0xff},
748  .vact_space_3 = {0xff, 0xff},
749  .vact_space_4 = {0xff, 0xff},
750  .vact_space_5 = {0xff, 0xff},
751  .vact_space_6 = {0xff, 0xff},
752  /* other don't care */
753  },
754  .tg = {
755  0x00, /* cmd */
756  0x98, 0x08, /* h_fsz */
757  0x18, 0x01, 0x80, 0x07, /* hact */
758  0x65, 0x04, /* v_fsz */
759  0x01, 0x00, 0x33, 0x02, /* vsync */
760  0x16, 0x00, 0x1c, 0x02, /* vact */
761  0x33, 0x02, /* field_chg */
762  0x49, 0x02, /* vact_st2 */
763  0x00, 0x00, /* vact_st3 */
764  0x00, 0x00, /* vact_st4 */
765  0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
766  0x01, 0x00, 0x33, 0x02, /* field top/bot */
767  0x00, /* 3d FP */
768  },
769 };
770 
771 static const struct hdmi_preset_conf hdmi_conf_1080p30 = {
772  .core = {
773  .h_blank = {0x18, 0x01},
774  .v2_blank = {0x65, 0x04},
775  .v1_blank = {0x2d, 0x00},
776  .v_line = {0x65, 0x04},
777  .h_line = {0x98, 0x08},
778  .hsync_pol = {0x00},
779  .vsync_pol = {0x00},
780  .int_pro_mode = {0x00},
781  .v_blank_f0 = {0xff, 0xff},
782  .v_blank_f1 = {0xff, 0xff},
783  .h_sync_start = {0x56, 0x00},
784  .h_sync_end = {0x82, 0x00},
785  .v_sync_line_bef_2 = {0x09, 0x00},
786  .v_sync_line_bef_1 = {0x04, 0x00},
787  .v_sync_line_aft_2 = {0xff, 0xff},
788  .v_sync_line_aft_1 = {0xff, 0xff},
789  .v_sync_line_aft_pxl_2 = {0xff, 0xff},
790  .v_sync_line_aft_pxl_1 = {0xff, 0xff},
791  .v_blank_f2 = {0xff, 0xff},
792  .v_blank_f3 = {0xff, 0xff},
793  .v_blank_f4 = {0xff, 0xff},
794  .v_blank_f5 = {0xff, 0xff},
795  .v_sync_line_aft_3 = {0xff, 0xff},
796  .v_sync_line_aft_4 = {0xff, 0xff},
797  .v_sync_line_aft_5 = {0xff, 0xff},
798  .v_sync_line_aft_6 = {0xff, 0xff},
799  .v_sync_line_aft_pxl_3 = {0xff, 0xff},
800  .v_sync_line_aft_pxl_4 = {0xff, 0xff},
801  .v_sync_line_aft_pxl_5 = {0xff, 0xff},
802  .v_sync_line_aft_pxl_6 = {0xff, 0xff},
803  .vact_space_1 = {0xff, 0xff},
804  .vact_space_2 = {0xff, 0xff},
805  .vact_space_3 = {0xff, 0xff},
806  .vact_space_4 = {0xff, 0xff},
807  .vact_space_5 = {0xff, 0xff},
808  .vact_space_6 = {0xff, 0xff},
809  /* other don't care */
810  },
811  .tg = {
812  0x00, /* cmd */
813  0x98, 0x08, /* h_fsz */
814  0x18, 0x01, 0x80, 0x07, /* hact */
815  0x65, 0x04, /* v_fsz */
816  0x01, 0x00, 0x33, 0x02, /* vsync */
817  0x2d, 0x00, 0x38, 0x04, /* vact */
818  0x33, 0x02, /* field_chg */
819  0x48, 0x02, /* vact_st2 */
820  0x00, 0x00, /* vact_st3 */
821  0x00, 0x00, /* vact_st4 */
822  0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
823  0x01, 0x00, 0x33, 0x02, /* field top/bot */
824  0x00, /* 3d FP */
825  },
826 };
827 
828 static const struct hdmi_preset_conf hdmi_conf_1080p50 = {
829  .core = {
830  .h_blank = {0xd0, 0x02},
831  .v2_blank = {0x65, 0x04},
832  .v1_blank = {0x2d, 0x00},
833  .v_line = {0x65, 0x04},
834  .h_line = {0x50, 0x0a},
835  .hsync_pol = {0x00},
836  .vsync_pol = {0x00},
837  .int_pro_mode = {0x00},
838  .v_blank_f0 = {0xff, 0xff},
839  .v_blank_f1 = {0xff, 0xff},
840  .h_sync_start = {0x0e, 0x02},
841  .h_sync_end = {0x3a, 0x02},
842  .v_sync_line_bef_2 = {0x09, 0x00},
843  .v_sync_line_bef_1 = {0x04, 0x00},
844  .v_sync_line_aft_2 = {0xff, 0xff},
845  .v_sync_line_aft_1 = {0xff, 0xff},
846  .v_sync_line_aft_pxl_2 = {0xff, 0xff},
847  .v_sync_line_aft_pxl_1 = {0xff, 0xff},
848  .v_blank_f2 = {0xff, 0xff},
849  .v_blank_f3 = {0xff, 0xff},
850  .v_blank_f4 = {0xff, 0xff},
851  .v_blank_f5 = {0xff, 0xff},
852  .v_sync_line_aft_3 = {0xff, 0xff},
853  .v_sync_line_aft_4 = {0xff, 0xff},
854  .v_sync_line_aft_5 = {0xff, 0xff},
855  .v_sync_line_aft_6 = {0xff, 0xff},
856  .v_sync_line_aft_pxl_3 = {0xff, 0xff},
857  .v_sync_line_aft_pxl_4 = {0xff, 0xff},
858  .v_sync_line_aft_pxl_5 = {0xff, 0xff},
859  .v_sync_line_aft_pxl_6 = {0xff, 0xff},
860  .vact_space_1 = {0xff, 0xff},
861  .vact_space_2 = {0xff, 0xff},
862  .vact_space_3 = {0xff, 0xff},
863  .vact_space_4 = {0xff, 0xff},
864  .vact_space_5 = {0xff, 0xff},
865  .vact_space_6 = {0xff, 0xff},
866  /* other don't care */
867  },
868  .tg = {
869  0x00, /* cmd */
870  0x50, 0x0a, /* h_fsz */
871  0xd0, 0x02, 0x80, 0x07, /* hact */
872  0x65, 0x04, /* v_fsz */
873  0x01, 0x00, 0x33, 0x02, /* vsync */
874  0x2d, 0x00, 0x38, 0x04, /* vact */
875  0x33, 0x02, /* field_chg */
876  0x48, 0x02, /* vact_st2 */
877  0x00, 0x00, /* vact_st3 */
878  0x00, 0x00, /* vact_st4 */
879  0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
880  0x01, 0x00, 0x33, 0x02, /* field top/bot */
881  0x00, /* 3d FP */
882  },
883 };
884 
885 static const struct hdmi_preset_conf hdmi_conf_1080p60 = {
886  .core = {
887  .h_blank = {0x18, 0x01},
888  .v2_blank = {0x65, 0x04},
889  .v1_blank = {0x2d, 0x00},
890  .v_line = {0x65, 0x04},
891  .h_line = {0x98, 0x08},
892  .hsync_pol = {0x00},
893  .vsync_pol = {0x00},
894  .int_pro_mode = {0x00},
895  .v_blank_f0 = {0xff, 0xff},
896  .v_blank_f1 = {0xff, 0xff},
897  .h_sync_start = {0x56, 0x00},
898  .h_sync_end = {0x82, 0x00},
899  .v_sync_line_bef_2 = {0x09, 0x00},
900  .v_sync_line_bef_1 = {0x04, 0x00},
901  .v_sync_line_aft_2 = {0xff, 0xff},
902  .v_sync_line_aft_1 = {0xff, 0xff},
903  .v_sync_line_aft_pxl_2 = {0xff, 0xff},
904  .v_sync_line_aft_pxl_1 = {0xff, 0xff},
905  .v_blank_f2 = {0xff, 0xff},
906  .v_blank_f3 = {0xff, 0xff},
907  .v_blank_f4 = {0xff, 0xff},
908  .v_blank_f5 = {0xff, 0xff},
909  .v_sync_line_aft_3 = {0xff, 0xff},
910  .v_sync_line_aft_4 = {0xff, 0xff},
911  .v_sync_line_aft_5 = {0xff, 0xff},
912  .v_sync_line_aft_6 = {0xff, 0xff},
913  .v_sync_line_aft_pxl_3 = {0xff, 0xff},
914  .v_sync_line_aft_pxl_4 = {0xff, 0xff},
915  .v_sync_line_aft_pxl_5 = {0xff, 0xff},
916  .v_sync_line_aft_pxl_6 = {0xff, 0xff},
917  /* other don't care */
918  },
919  .tg = {
920  0x00, /* cmd */
921  0x98, 0x08, /* h_fsz */
922  0x18, 0x01, 0x80, 0x07, /* hact */
923  0x65, 0x04, /* v_fsz */
924  0x01, 0x00, 0x33, 0x02, /* vsync */
925  0x2d, 0x00, 0x38, 0x04, /* vact */
926  0x33, 0x02, /* field_chg */
927  0x48, 0x02, /* vact_st2 */
928  0x00, 0x00, /* vact_st3 */
929  0x00, 0x00, /* vact_st4 */
930  0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
931  0x01, 0x00, 0x33, 0x02, /* field top/bot */
932  0x00, /* 3d FP */
933  },
934 };
935 
936 static const struct hdmi_conf hdmi_confs[] = {
937  { 720, 480, 60, false, hdmiphy_conf27_027, &hdmi_conf_480p60 },
938  { 1280, 720, 50, false, hdmiphy_conf74_25, &hdmi_conf_720p50 },
939  { 1280, 720, 60, false, hdmiphy_conf74_25, &hdmi_conf_720p60 },
940  { 1920, 1080, 50, true, hdmiphy_conf74_25, &hdmi_conf_1080i50 },
941  { 1920, 1080, 60, true, hdmiphy_conf74_25, &hdmi_conf_1080i60 },
942  { 1920, 1080, 30, false, hdmiphy_conf74_176, &hdmi_conf_1080p30 },
943  { 1920, 1080, 50, false, hdmiphy_conf148_5, &hdmi_conf_1080p50 },
944  { 1920, 1080, 60, false, hdmiphy_conf148_5, &hdmi_conf_1080p60 },
945 };
946 
947 
948 static inline u32 hdmi_reg_read(struct hdmi_context *hdata, u32 reg_id)
949 {
950  return readl(hdata->regs + reg_id);
951 }
952 
953 static inline void hdmi_reg_writeb(struct hdmi_context *hdata,
954  u32 reg_id, u8 value)
955 {
956  writeb(value, hdata->regs + reg_id);
957 }
958 
959 static inline void hdmi_reg_writemask(struct hdmi_context *hdata,
960  u32 reg_id, u32 value, u32 mask)
961 {
962  u32 old = readl(hdata->regs + reg_id);
963  value = (value & mask) | (old & ~mask);
964  writel(value, hdata->regs + reg_id);
965 }
966 
967 static void hdmi_v13_regs_dump(struct hdmi_context *hdata, char *prefix)
968 {
969 #define DUMPREG(reg_id) \
970  DRM_DEBUG_KMS("%s:" #reg_id " = %08x\n", prefix, \
971  readl(hdata->regs + reg_id))
972  DRM_DEBUG_KMS("%s: ---- CONTROL REGISTERS ----\n", prefix);
980 
981  DRM_DEBUG_KMS("%s: ---- CORE REGISTERS ----\n", prefix);
988  DUMPREG(HDMI_HPD);
993 
994  DRM_DEBUG_KMS("%s: ---- CORE SYNC REGISTERS ----\n", prefix);
1020 
1021  DRM_DEBUG_KMS("%s: ---- TG REGISTERS ----\n", prefix);
1051 #undef DUMPREG
1052 }
1053 
1054 static void hdmi_v14_regs_dump(struct hdmi_context *hdata, char *prefix)
1055 {
1056  int i;
1057 
1058 #define DUMPREG(reg_id) \
1059  DRM_DEBUG_KMS("%s:" #reg_id " = %08x\n", prefix, \
1060  readl(hdata->regs + reg_id))
1061 
1062  DRM_DEBUG_KMS("%s: ---- CONTROL REGISTERS ----\n", prefix);
1075 
1076  DRM_DEBUG_KMS("%s: ---- CORE REGISTERS ----\n", prefix);
1083  DUMPREG(HDMI_HPD);
1088 
1089  DRM_DEBUG_KMS("%s: ---- CORE SYNC REGISTERS ----\n", prefix);
1101 
1108 
1113 
1118 
1123 
1128 
1137 
1146 
1155 
1168 
1169  DRM_DEBUG_KMS("%s: ---- TG REGISTERS ----\n", prefix);
1204 
1205  DRM_DEBUG_KMS("%s: ---- PACKET REGISTERS ----\n", prefix);
1215  for (i = 0; i < 7; ++i)
1216  DUMPREG(HDMI_VSI_DATA(i));
1217 
1218 #undef DUMPREG
1219 }
1220 
1221 static void hdmi_regs_dump(struct hdmi_context *hdata, char *prefix)
1222 {
1223  if (hdata->type == HDMI_TYPE13)
1224  hdmi_v13_regs_dump(hdata, prefix);
1225  else
1226  hdmi_v14_regs_dump(hdata, prefix);
1227 }
1228 
1229 static int hdmi_v13_conf_index(struct drm_display_mode *mode)
1230 {
1231  int i;
1232 
1233  for (i = 0; i < ARRAY_SIZE(hdmi_v13_confs); ++i)
1234  if (hdmi_v13_confs[i].width == mode->hdisplay &&
1235  hdmi_v13_confs[i].height == mode->vdisplay &&
1236  hdmi_v13_confs[i].vrefresh == mode->vrefresh &&
1237  hdmi_v13_confs[i].interlace ==
1238  ((mode->flags & DRM_MODE_FLAG_INTERLACE) ?
1239  true : false))
1240  return i;
1241 
1242  return -EINVAL;
1243 }
1244 
1245 static int hdmi_v14_conf_index(struct drm_display_mode *mode)
1246 {
1247  int i;
1248 
1249  for (i = 0; i < ARRAY_SIZE(hdmi_confs); ++i)
1250  if (hdmi_confs[i].width == mode->hdisplay &&
1251  hdmi_confs[i].height == mode->vdisplay &&
1252  hdmi_confs[i].vrefresh == mode->vrefresh &&
1253  hdmi_confs[i].interlace ==
1254  ((mode->flags & DRM_MODE_FLAG_INTERLACE) ?
1255  true : false))
1256  return i;
1257 
1258  return -EINVAL;
1259 }
1260 
1261 static int hdmi_conf_index(struct hdmi_context *hdata,
1262  struct drm_display_mode *mode)
1263 {
1264  if (hdata->type == HDMI_TYPE13)
1265  return hdmi_v13_conf_index(mode);
1266 
1267  return hdmi_v14_conf_index(mode);
1268 }
1269 
1270 static bool hdmi_is_connected(void *ctx)
1271 {
1272  struct hdmi_context *hdata = ctx;
1273 
1274  return hdata->hpd;
1275 }
1276 
1277 static int hdmi_get_edid(void *ctx, struct drm_connector *connector,
1278  u8 *edid, int len)
1279 {
1280  struct edid *raw_edid;
1281  struct hdmi_context *hdata = ctx;
1282 
1283  DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1284 
1285  if (!hdata->ddc_port)
1286  return -ENODEV;
1287 
1288  raw_edid = drm_get_edid(connector, hdata->ddc_port->adapter);
1289  if (raw_edid) {
1290  hdata->dvi_mode = !drm_detect_hdmi_monitor(raw_edid);
1291  memcpy(edid, raw_edid, min((1 + raw_edid->extensions)
1292  * EDID_LENGTH, len));
1293  DRM_DEBUG_KMS("%s : width[%d] x height[%d]\n",
1294  (hdata->dvi_mode ? "dvi monitor" : "hdmi monitor"),
1295  raw_edid->width_cm, raw_edid->height_cm);
1296  } else {
1297  return -ENODEV;
1298  }
1299 
1300  return 0;
1301 }
1302 
1303 static int hdmi_v13_check_timing(struct fb_videomode *check_timing)
1304 {
1305  int i;
1306 
1307  DRM_DEBUG_KMS("valid mode : xres=%d, yres=%d, refresh=%d, intl=%d\n",
1308  check_timing->xres, check_timing->yres,
1309  check_timing->refresh, (check_timing->vmode &
1310  FB_VMODE_INTERLACED) ? true : false);
1311 
1312  for (i = 0; i < ARRAY_SIZE(hdmi_v13_confs); ++i)
1313  if (hdmi_v13_confs[i].width == check_timing->xres &&
1314  hdmi_v13_confs[i].height == check_timing->yres &&
1315  hdmi_v13_confs[i].vrefresh == check_timing->refresh &&
1316  hdmi_v13_confs[i].interlace ==
1317  ((check_timing->vmode & FB_VMODE_INTERLACED) ?
1318  true : false))
1319  return 0;
1320 
1321  /* TODO */
1322 
1323  return -EINVAL;
1324 }
1325 
1326 static int hdmi_v14_check_timing(struct fb_videomode *check_timing)
1327 {
1328  int i;
1329 
1330  DRM_DEBUG_KMS("valid mode : xres=%d, yres=%d, refresh=%d, intl=%d\n",
1331  check_timing->xres, check_timing->yres,
1332  check_timing->refresh, (check_timing->vmode &
1333  FB_VMODE_INTERLACED) ? true : false);
1334 
1335  for (i = 0; i < ARRAY_SIZE(hdmi_confs); i++)
1336  if (hdmi_confs[i].width == check_timing->xres &&
1337  hdmi_confs[i].height == check_timing->yres &&
1338  hdmi_confs[i].vrefresh == check_timing->refresh &&
1339  hdmi_confs[i].interlace ==
1340  ((check_timing->vmode & FB_VMODE_INTERLACED) ?
1341  true : false))
1342  return 0;
1343 
1344  /* TODO */
1345 
1346  return -EINVAL;
1347 }
1348 
1349 static int hdmi_check_timing(void *ctx, void *timing)
1350 {
1351  struct hdmi_context *hdata = ctx;
1352  struct fb_videomode *check_timing = timing;
1353 
1354  DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1355 
1356  DRM_DEBUG_KMS("[%d]x[%d] [%d]Hz [%x]\n", check_timing->xres,
1357  check_timing->yres, check_timing->refresh,
1358  check_timing->vmode);
1359 
1360  if (hdata->type == HDMI_TYPE13)
1361  return hdmi_v13_check_timing(check_timing);
1362  else
1363  return hdmi_v14_check_timing(check_timing);
1364 }
1365 
1366 static void hdmi_set_acr(u32 freq, u8 *acr)
1367 {
1368  u32 n, cts;
1369 
1370  switch (freq) {
1371  case 32000:
1372  n = 4096;
1373  cts = 27000;
1374  break;
1375  case 44100:
1376  n = 6272;
1377  cts = 30000;
1378  break;
1379  case 88200:
1380  n = 12544;
1381  cts = 30000;
1382  break;
1383  case 176400:
1384  n = 25088;
1385  cts = 30000;
1386  break;
1387  case 48000:
1388  n = 6144;
1389  cts = 27000;
1390  break;
1391  case 96000:
1392  n = 12288;
1393  cts = 27000;
1394  break;
1395  case 192000:
1396  n = 24576;
1397  cts = 27000;
1398  break;
1399  default:
1400  n = 0;
1401  cts = 0;
1402  break;
1403  }
1404 
1405  acr[1] = cts >> 16;
1406  acr[2] = cts >> 8 & 0xff;
1407  acr[3] = cts & 0xff;
1408 
1409  acr[4] = n >> 16;
1410  acr[5] = n >> 8 & 0xff;
1411  acr[6] = n & 0xff;
1412 }
1413 
1414 static void hdmi_reg_acr(struct hdmi_context *hdata, u8 *acr)
1415 {
1416  hdmi_reg_writeb(hdata, HDMI_ACR_N0, acr[6]);
1417  hdmi_reg_writeb(hdata, HDMI_ACR_N1, acr[5]);
1418  hdmi_reg_writeb(hdata, HDMI_ACR_N2, acr[4]);
1419  hdmi_reg_writeb(hdata, HDMI_ACR_MCTS0, acr[3]);
1420  hdmi_reg_writeb(hdata, HDMI_ACR_MCTS1, acr[2]);
1421  hdmi_reg_writeb(hdata, HDMI_ACR_MCTS2, acr[1]);
1422  hdmi_reg_writeb(hdata, HDMI_ACR_CTS0, acr[3]);
1423  hdmi_reg_writeb(hdata, HDMI_ACR_CTS1, acr[2]);
1424  hdmi_reg_writeb(hdata, HDMI_ACR_CTS2, acr[1]);
1425 
1426  if (hdata->type == HDMI_TYPE13)
1427  hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 4);
1428  else
1429  hdmi_reg_writeb(hdata, HDMI_ACR_CON, 4);
1430 }
1431 
1432 static void hdmi_audio_init(struct hdmi_context *hdata)
1433 {
1434  u32 sample_rate, bits_per_sample, frame_size_code;
1435  u32 data_num, bit_ch, sample_frq;
1436  u32 val;
1437  u8 acr[7];
1438 
1439  sample_rate = 44100;
1440  bits_per_sample = 16;
1441  frame_size_code = 0;
1442 
1443  switch (bits_per_sample) {
1444  case 20:
1445  data_num = 2;
1446  bit_ch = 1;
1447  break;
1448  case 24:
1449  data_num = 3;
1450  bit_ch = 1;
1451  break;
1452  default:
1453  data_num = 1;
1454  bit_ch = 0;
1455  break;
1456  }
1457 
1458  hdmi_set_acr(sample_rate, acr);
1459  hdmi_reg_acr(hdata, acr);
1460 
1461  hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CON, HDMI_I2S_IN_DISABLE
1464 
1465  hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CH, HDMI_I2S_CH0_EN
1467 
1468  hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CUV, HDMI_I2S_CUV_RL_EN);
1469 
1470  sample_frq = (sample_rate == 44100) ? 0 :
1471  (sample_rate == 48000) ? 2 :
1472  (sample_rate == 32000) ? 3 :
1473  (sample_rate == 96000) ? 0xa : 0x0;
1474 
1475  hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_DIS);
1476  hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_EN);
1477 
1478  val = hdmi_reg_read(hdata, HDMI_I2S_DSD_CON) | 0x01;
1479  hdmi_reg_writeb(hdata, HDMI_I2S_DSD_CON, val);
1480 
1481  /* Configuration I2S input ports. Configure I2S_PIN_SEL_0~4 */
1482  hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_0, HDMI_I2S_SEL_SCLK(5)
1483  | HDMI_I2S_SEL_LRCK(6));
1484  hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_1, HDMI_I2S_SEL_SDATA1(1)
1485  | HDMI_I2S_SEL_SDATA2(4));
1486  hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_2, HDMI_I2S_SEL_SDATA3(1)
1487  | HDMI_I2S_SEL_SDATA2(2));
1488  hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_3, HDMI_I2S_SEL_DSD(0));
1489 
1490  /* I2S_CON_1 & 2 */
1491  hdmi_reg_writeb(hdata, HDMI_I2S_CON_1, HDMI_I2S_SCLK_FALLING_EDGE
1493  hdmi_reg_writeb(hdata, HDMI_I2S_CON_2, HDMI_I2S_MSB_FIRST_MODE
1494  | HDMI_I2S_SET_BIT_CH(bit_ch)
1495  | HDMI_I2S_SET_SDATA_BIT(data_num)
1497 
1498  /* Configure register related to CUV information */
1499  hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_0, HDMI_I2S_CH_STATUS_MODE_0
1504  hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_1, HDMI_I2S_CD_PLAYER);
1505  hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_2, HDMI_I2S_SET_SOURCE_NUM(0));
1506  hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_3, HDMI_I2S_CLK_ACCUR_LEVEL_2
1507  | HDMI_I2S_SET_SMP_FREQ(sample_frq));
1508  hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_4,
1512 
1513  hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_CON, HDMI_I2S_CH_STATUS_RELOAD);
1514 }
1515 
1516 static void hdmi_audio_control(struct hdmi_context *hdata, bool onoff)
1517 {
1518  if (hdata->dvi_mode)
1519  return;
1520 
1521  hdmi_reg_writeb(hdata, HDMI_AUI_CON, onoff ? 2 : 0);
1522  hdmi_reg_writemask(hdata, HDMI_CON_0, onoff ?
1524 }
1525 
1526 static void hdmi_conf_reset(struct hdmi_context *hdata)
1527 {
1528  u32 reg;
1529 
1530  if (hdata->type == HDMI_TYPE13)
1531  reg = HDMI_V13_CORE_RSTOUT;
1532  else
1533  reg = HDMI_CORE_RSTOUT;
1534 
1535  /* resetting HDMI core */
1536  hdmi_reg_writemask(hdata, reg, 0, HDMI_CORE_SW_RSTOUT);
1537  mdelay(10);
1538  hdmi_reg_writemask(hdata, reg, ~0, HDMI_CORE_SW_RSTOUT);
1539  mdelay(10);
1540 }
1541 
1542 static void hdmi_conf_init(struct hdmi_context *hdata)
1543 {
1544  /* disable HPD interrupts */
1545  hdmi_reg_writemask(hdata, HDMI_INTC_CON, 0, HDMI_INTC_EN_GLOBAL |
1547 
1548  /* choose HDMI mode */
1549  hdmi_reg_writemask(hdata, HDMI_MODE_SEL,
1551  /* disable bluescreen */
1552  hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_BLUE_SCR_EN);
1553 
1554  if (hdata->dvi_mode) {
1555  /* choose DVI mode */
1556  hdmi_reg_writemask(hdata, HDMI_MODE_SEL,
1558  hdmi_reg_writeb(hdata, HDMI_CON_2,
1560  }
1561 
1562  if (hdata->type == HDMI_TYPE13) {
1563  /* choose bluescreen (fecal) color */
1564  hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_0, 0x12);
1565  hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_1, 0x34);
1566  hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_2, 0x56);
1567 
1568  /* enable AVI packet every vsync, fixes purple line problem */
1569  hdmi_reg_writeb(hdata, HDMI_V13_AVI_CON, 0x02);
1570  /* force RGB, look to CEA-861-D, table 7 for more detail */
1571  hdmi_reg_writeb(hdata, HDMI_V13_AVI_BYTE(0), 0 << 5);
1572  hdmi_reg_writemask(hdata, HDMI_CON_1, 0x10 << 5, 0x11 << 5);
1573 
1574  hdmi_reg_writeb(hdata, HDMI_V13_SPD_CON, 0x02);
1575  hdmi_reg_writeb(hdata, HDMI_V13_AUI_CON, 0x02);
1576  hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 0x04);
1577  } else {
1578  /* enable AVI packet every vsync, fixes purple line problem */
1579  hdmi_reg_writeb(hdata, HDMI_AVI_CON, 0x02);
1580  hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(1), 2 << 5);
1581  hdmi_reg_writemask(hdata, HDMI_CON_1, 2, 3 << 5);
1582  }
1583 }
1584 
1585 static void hdmi_v13_timing_apply(struct hdmi_context *hdata)
1586 {
1587  const struct hdmi_v13_preset_conf *conf =
1588  hdmi_v13_confs[hdata->cur_conf].conf;
1589  const struct hdmi_v13_core_regs *core = &conf->core;
1590  const struct hdmi_v13_tg_regs *tg = &conf->tg;
1591  int tries;
1592 
1593  /* setting core registers */
1594  hdmi_reg_writeb(hdata, HDMI_H_BLANK_0, core->h_blank[0]);
1595  hdmi_reg_writeb(hdata, HDMI_H_BLANK_1, core->h_blank[1]);
1596  hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_0, core->v_blank[0]);
1597  hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_1, core->v_blank[1]);
1598  hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_2, core->v_blank[2]);
1599  hdmi_reg_writeb(hdata, HDMI_V13_H_V_LINE_0, core->h_v_line[0]);
1600  hdmi_reg_writeb(hdata, HDMI_V13_H_V_LINE_1, core->h_v_line[1]);
1601  hdmi_reg_writeb(hdata, HDMI_V13_H_V_LINE_2, core->h_v_line[2]);
1602  hdmi_reg_writeb(hdata, HDMI_VSYNC_POL, core->vsync_pol[0]);
1603  hdmi_reg_writeb(hdata, HDMI_INT_PRO_MODE, core->int_pro_mode[0]);
1604  hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_F_0, core->v_blank_f[0]);
1605  hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_F_1, core->v_blank_f[1]);
1606  hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_F_2, core->v_blank_f[2]);
1607  hdmi_reg_writeb(hdata, HDMI_V13_H_SYNC_GEN_0, core->h_sync_gen[0]);
1608  hdmi_reg_writeb(hdata, HDMI_V13_H_SYNC_GEN_1, core->h_sync_gen[1]);
1609  hdmi_reg_writeb(hdata, HDMI_V13_H_SYNC_GEN_2, core->h_sync_gen[2]);
1610  hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_1_0, core->v_sync_gen1[0]);
1611  hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_1_1, core->v_sync_gen1[1]);
1612  hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_1_2, core->v_sync_gen1[2]);
1613  hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_2_0, core->v_sync_gen2[0]);
1614  hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_2_1, core->v_sync_gen2[1]);
1615  hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_2_2, core->v_sync_gen2[2]);
1616  hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_0, core->v_sync_gen3[0]);
1617  hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_1, core->v_sync_gen3[1]);
1618  hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_2, core->v_sync_gen3[2]);
1619  /* Timing generator registers */
1620  hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_L, tg->h_fsz_l);
1621  hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_H, tg->h_fsz_h);
1622  hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_L, tg->hact_st_l);
1623  hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_H, tg->hact_st_h);
1624  hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_L, tg->hact_sz_l);
1625  hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_H, tg->hact_sz_h);
1626  hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_L, tg->v_fsz_l);
1627  hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_H, tg->v_fsz_h);
1628  hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_L, tg->vsync_l);
1629  hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_H, tg->vsync_h);
1630  hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_L, tg->vsync2_l);
1631  hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_H, tg->vsync2_h);
1632  hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_L, tg->vact_st_l);
1633  hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_H, tg->vact_st_h);
1634  hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_L, tg->vact_sz_l);
1635  hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_H, tg->vact_sz_h);
1636  hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_L, tg->field_chg_l);
1637  hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_H, tg->field_chg_h);
1638  hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_L, tg->vact_st2_l);
1639  hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_H, tg->vact_st2_h);
1640  hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_L, tg->vsync_top_hdmi_l);
1641  hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_H, tg->vsync_top_hdmi_h);
1642  hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, tg->vsync_bot_hdmi_l);
1643  hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_H, tg->vsync_bot_hdmi_h);
1644  hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_L, tg->field_top_hdmi_l);
1645  hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_H, tg->field_top_hdmi_h);
1646  hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_L, tg->field_bot_hdmi_l);
1647  hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_H, tg->field_bot_hdmi_h);
1648 
1649  /* waiting for HDMIPHY's PLL to get to steady state */
1650  for (tries = 100; tries; --tries) {
1651  u32 val = hdmi_reg_read(hdata, HDMI_V13_PHY_STATUS);
1652  if (val & HDMI_PHY_STATUS_READY)
1653  break;
1654  mdelay(1);
1655  }
1656  /* steady state not achieved */
1657  if (tries == 0) {
1658  DRM_ERROR("hdmiphy's pll could not reach steady state.\n");
1659  hdmi_regs_dump(hdata, "timing apply");
1660  }
1661 
1662  clk_disable(hdata->res.sclk_hdmi);
1663  clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_hdmiphy);
1664  clk_enable(hdata->res.sclk_hdmi);
1665 
1666  /* enable HDMI and timing generator */
1667  hdmi_reg_writemask(hdata, HDMI_CON_0, ~0, HDMI_EN);
1668  if (core->int_pro_mode[0])
1669  hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN |
1670  HDMI_FIELD_EN);
1671  else
1672  hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN);
1673 }
1674 
1675 static void hdmi_v14_timing_apply(struct hdmi_context *hdata)
1676 {
1677  const struct hdmi_preset_conf *conf = hdmi_confs[hdata->cur_conf].conf;
1678  const struct hdmi_core_regs *core = &conf->core;
1679  const struct hdmi_tg_regs *tg = &conf->tg;
1680  int tries;
1681 
1682  /* setting core registers */
1683  hdmi_reg_writeb(hdata, HDMI_H_BLANK_0, core->h_blank[0]);
1684  hdmi_reg_writeb(hdata, HDMI_H_BLANK_1, core->h_blank[1]);
1685  hdmi_reg_writeb(hdata, HDMI_V2_BLANK_0, core->v2_blank[0]);
1686  hdmi_reg_writeb(hdata, HDMI_V2_BLANK_1, core->v2_blank[1]);
1687  hdmi_reg_writeb(hdata, HDMI_V1_BLANK_0, core->v1_blank[0]);
1688  hdmi_reg_writeb(hdata, HDMI_V1_BLANK_1, core->v1_blank[1]);
1689  hdmi_reg_writeb(hdata, HDMI_V_LINE_0, core->v_line[0]);
1690  hdmi_reg_writeb(hdata, HDMI_V_LINE_1, core->v_line[1]);
1691  hdmi_reg_writeb(hdata, HDMI_H_LINE_0, core->h_line[0]);
1692  hdmi_reg_writeb(hdata, HDMI_H_LINE_1, core->h_line[1]);
1693  hdmi_reg_writeb(hdata, HDMI_HSYNC_POL, core->hsync_pol[0]);
1694  hdmi_reg_writeb(hdata, HDMI_VSYNC_POL, core->vsync_pol[0]);
1695  hdmi_reg_writeb(hdata, HDMI_INT_PRO_MODE, core->int_pro_mode[0]);
1696  hdmi_reg_writeb(hdata, HDMI_V_BLANK_F0_0, core->v_blank_f0[0]);
1697  hdmi_reg_writeb(hdata, HDMI_V_BLANK_F0_1, core->v_blank_f0[1]);
1698  hdmi_reg_writeb(hdata, HDMI_V_BLANK_F1_0, core->v_blank_f1[0]);
1699  hdmi_reg_writeb(hdata, HDMI_V_BLANK_F1_1, core->v_blank_f1[1]);
1700  hdmi_reg_writeb(hdata, HDMI_H_SYNC_START_0, core->h_sync_start[0]);
1701  hdmi_reg_writeb(hdata, HDMI_H_SYNC_START_1, core->h_sync_start[1]);
1702  hdmi_reg_writeb(hdata, HDMI_H_SYNC_END_0, core->h_sync_end[0]);
1703  hdmi_reg_writeb(hdata, HDMI_H_SYNC_END_1, core->h_sync_end[1]);
1704  hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_2_0,
1705  core->v_sync_line_bef_2[0]);
1706  hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_2_1,
1707  core->v_sync_line_bef_2[1]);
1708  hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_1_0,
1709  core->v_sync_line_bef_1[0]);
1710  hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_1_1,
1711  core->v_sync_line_bef_1[1]);
1712  hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_2_0,
1713  core->v_sync_line_aft_2[0]);
1714  hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_2_1,
1715  core->v_sync_line_aft_2[1]);
1716  hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_1_0,
1717  core->v_sync_line_aft_1[0]);
1718  hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_1_1,
1719  core->v_sync_line_aft_1[1]);
1720  hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_0,
1721  core->v_sync_line_aft_pxl_2[0]);
1722  hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_1,
1723  core->v_sync_line_aft_pxl_2[1]);
1724  hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_0,
1725  core->v_sync_line_aft_pxl_1[0]);
1726  hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_1,
1727  core->v_sync_line_aft_pxl_1[1]);
1728  hdmi_reg_writeb(hdata, HDMI_V_BLANK_F2_0, core->v_blank_f2[0]);
1729  hdmi_reg_writeb(hdata, HDMI_V_BLANK_F2_1, core->v_blank_f2[1]);
1730  hdmi_reg_writeb(hdata, HDMI_V_BLANK_F3_0, core->v_blank_f3[0]);
1731  hdmi_reg_writeb(hdata, HDMI_V_BLANK_F3_1, core->v_blank_f3[1]);
1732  hdmi_reg_writeb(hdata, HDMI_V_BLANK_F4_0, core->v_blank_f4[0]);
1733  hdmi_reg_writeb(hdata, HDMI_V_BLANK_F4_1, core->v_blank_f4[1]);
1734  hdmi_reg_writeb(hdata, HDMI_V_BLANK_F5_0, core->v_blank_f5[0]);
1735  hdmi_reg_writeb(hdata, HDMI_V_BLANK_F5_1, core->v_blank_f5[1]);
1736  hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_3_0,
1737  core->v_sync_line_aft_3[0]);
1738  hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_3_1,
1739  core->v_sync_line_aft_3[1]);
1740  hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_4_0,
1741  core->v_sync_line_aft_4[0]);
1742  hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_4_1,
1743  core->v_sync_line_aft_4[1]);
1744  hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_5_0,
1745  core->v_sync_line_aft_5[0]);
1746  hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_5_1,
1747  core->v_sync_line_aft_5[1]);
1748  hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_6_0,
1749  core->v_sync_line_aft_6[0]);
1750  hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_6_1,
1751  core->v_sync_line_aft_6[1]);
1752  hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_3_0,
1753  core->v_sync_line_aft_pxl_3[0]);
1754  hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_3_1,
1755  core->v_sync_line_aft_pxl_3[1]);
1756  hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_4_0,
1757  core->v_sync_line_aft_pxl_4[0]);
1758  hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_4_1,
1759  core->v_sync_line_aft_pxl_4[1]);
1760  hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_5_0,
1761  core->v_sync_line_aft_pxl_5[0]);
1762  hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_5_1,
1763  core->v_sync_line_aft_pxl_5[1]);
1764  hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_0,
1765  core->v_sync_line_aft_pxl_6[0]);
1766  hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_1,
1767  core->v_sync_line_aft_pxl_6[1]);
1768  hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_1_0, core->vact_space_1[0]);
1769  hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_1_1, core->vact_space_1[1]);
1770  hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_2_0, core->vact_space_2[0]);
1771  hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_2_1, core->vact_space_2[1]);
1772  hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_3_0, core->vact_space_3[0]);
1773  hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_3_1, core->vact_space_3[1]);
1774  hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_4_0, core->vact_space_4[0]);
1775  hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_4_1, core->vact_space_4[1]);
1776  hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_5_0, core->vact_space_5[0]);
1777  hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_5_1, core->vact_space_5[1]);
1778  hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_6_0, core->vact_space_6[0]);
1779  hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_6_1, core->vact_space_6[1]);
1780 
1781  /* Timing generator registers */
1782  hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_L, tg->h_fsz_l);
1783  hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_H, tg->h_fsz_h);
1784  hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_L, tg->hact_st_l);
1785  hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_H, tg->hact_st_h);
1786  hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_L, tg->hact_sz_l);
1787  hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_H, tg->hact_sz_h);
1788  hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_L, tg->v_fsz_l);
1789  hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_H, tg->v_fsz_h);
1790  hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_L, tg->vsync_l);
1791  hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_H, tg->vsync_h);
1792  hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_L, tg->vsync2_l);
1793  hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_H, tg->vsync2_h);
1794  hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_L, tg->vact_st_l);
1795  hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_H, tg->vact_st_h);
1796  hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_L, tg->vact_sz_l);
1797  hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_H, tg->vact_sz_h);
1798  hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_L, tg->field_chg_l);
1799  hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_H, tg->field_chg_h);
1800  hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_L, tg->vact_st2_l);
1801  hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_H, tg->vact_st2_h);
1802  hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST3_L, tg->vact_st3_l);
1803  hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST3_H, tg->vact_st3_h);
1804  hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST4_L, tg->vact_st4_l);
1805  hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST4_H, tg->vact_st4_h);
1806  hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_L, tg->vsync_top_hdmi_l);
1807  hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_H, tg->vsync_top_hdmi_h);
1808  hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, tg->vsync_bot_hdmi_l);
1809  hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_H, tg->vsync_bot_hdmi_h);
1810  hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_L, tg->field_top_hdmi_l);
1811  hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_H, tg->field_top_hdmi_h);
1812  hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_L, tg->field_bot_hdmi_l);
1813  hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_H, tg->field_bot_hdmi_h);
1814  hdmi_reg_writeb(hdata, HDMI_TG_3D, tg->tg_3d);
1815 
1816  /* waiting for HDMIPHY's PLL to get to steady state */
1817  for (tries = 100; tries; --tries) {
1818  u32 val = hdmi_reg_read(hdata, HDMI_PHY_STATUS_0);
1819  if (val & HDMI_PHY_STATUS_READY)
1820  break;
1821  mdelay(1);
1822  }
1823  /* steady state not achieved */
1824  if (tries == 0) {
1825  DRM_ERROR("hdmiphy's pll could not reach steady state.\n");
1826  hdmi_regs_dump(hdata, "timing apply");
1827  }
1828 
1829  clk_disable(hdata->res.sclk_hdmi);
1830  clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_hdmiphy);
1831  clk_enable(hdata->res.sclk_hdmi);
1832 
1833  /* enable HDMI and timing generator */
1834  hdmi_reg_writemask(hdata, HDMI_CON_0, ~0, HDMI_EN);
1835  if (core->int_pro_mode[0])
1836  hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN |
1837  HDMI_FIELD_EN);
1838  else
1839  hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN);
1840 }
1841 
1842 static void hdmi_timing_apply(struct hdmi_context *hdata)
1843 {
1844  if (hdata->type == HDMI_TYPE13)
1845  hdmi_v13_timing_apply(hdata);
1846  else
1847  hdmi_v14_timing_apply(hdata);
1848 }
1849 
1850 static void hdmiphy_conf_reset(struct hdmi_context *hdata)
1851 {
1852  u8 buffer[2];
1853  u32 reg;
1854 
1855  clk_disable(hdata->res.sclk_hdmi);
1856  clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_pixel);
1857  clk_enable(hdata->res.sclk_hdmi);
1858 
1859  /* operation mode */
1860  buffer[0] = 0x1f;
1861  buffer[1] = 0x00;
1862 
1863  if (hdata->hdmiphy_port)
1864  i2c_master_send(hdata->hdmiphy_port, buffer, 2);
1865 
1866  if (hdata->type == HDMI_TYPE13)
1867  reg = HDMI_V13_PHY_RSTOUT;
1868  else
1869  reg = HDMI_PHY_RSTOUT;
1870 
1871  /* reset hdmiphy */
1872  hdmi_reg_writemask(hdata, reg, ~0, HDMI_PHY_SW_RSTOUT);
1873  mdelay(10);
1874  hdmi_reg_writemask(hdata, reg, 0, HDMI_PHY_SW_RSTOUT);
1875  mdelay(10);
1876 }
1877 
1878 static void hdmiphy_conf_apply(struct hdmi_context *hdata)
1879 {
1880  const u8 *hdmiphy_data;
1881  u8 buffer[32];
1882  u8 operation[2];
1883  u8 read_buffer[32] = {0, };
1884  int ret;
1885  int i;
1886 
1887  if (!hdata->hdmiphy_port) {
1888  DRM_ERROR("hdmiphy is not attached\n");
1889  return;
1890  }
1891 
1892  /* pixel clock */
1893  if (hdata->type == HDMI_TYPE13)
1894  hdmiphy_data = hdmi_v13_confs[hdata->cur_conf].hdmiphy_data;
1895  else
1896  hdmiphy_data = hdmi_confs[hdata->cur_conf].hdmiphy_data;
1897 
1898  memcpy(buffer, hdmiphy_data, 32);
1899  ret = i2c_master_send(hdata->hdmiphy_port, buffer, 32);
1900  if (ret != 32) {
1901  DRM_ERROR("failed to configure HDMIPHY via I2C\n");
1902  return;
1903  }
1904 
1905  mdelay(10);
1906 
1907  /* operation mode */
1908  operation[0] = 0x1f;
1909  operation[1] = 0x80;
1910 
1911  ret = i2c_master_send(hdata->hdmiphy_port, operation, 2);
1912  if (ret != 2) {
1913  DRM_ERROR("failed to enable hdmiphy\n");
1914  return;
1915  }
1916 
1917  ret = i2c_master_recv(hdata->hdmiphy_port, read_buffer, 32);
1918  if (ret < 0) {
1919  DRM_ERROR("failed to read hdmiphy config\n");
1920  return;
1921  }
1922 
1923  for (i = 0; i < ret; i++)
1924  DRM_DEBUG_KMS("hdmiphy[0x%02x] write[0x%02x] - "
1925  "recv [0x%02x]\n", i, buffer[i], read_buffer[i]);
1926 }
1927 
1928 static void hdmi_conf_apply(struct hdmi_context *hdata)
1929 {
1930  DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1931 
1932  hdmiphy_conf_reset(hdata);
1933  hdmiphy_conf_apply(hdata);
1934 
1935  mutex_lock(&hdata->hdmi_mutex);
1936  hdmi_conf_reset(hdata);
1937  hdmi_conf_init(hdata);
1938  mutex_unlock(&hdata->hdmi_mutex);
1939 
1940  hdmi_audio_init(hdata);
1941 
1942  /* setting core registers */
1943  hdmi_timing_apply(hdata);
1944  hdmi_audio_control(hdata, true);
1945 
1946  hdmi_regs_dump(hdata, "start");
1947 }
1948 
1949 static void hdmi_mode_fixup(void *ctx, struct drm_connector *connector,
1950  const struct drm_display_mode *mode,
1951  struct drm_display_mode *adjusted_mode)
1952 {
1953  struct drm_display_mode *m;
1954  struct hdmi_context *hdata = ctx;
1955  int index;
1956 
1957  DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1958 
1959  drm_mode_set_crtcinfo(adjusted_mode, 0);
1960 
1961  if (hdata->type == HDMI_TYPE13)
1962  index = hdmi_v13_conf_index(adjusted_mode);
1963  else
1964  index = hdmi_v14_conf_index(adjusted_mode);
1965 
1966  /* just return if user desired mode exists. */
1967  if (index >= 0)
1968  return;
1969 
1970  /*
1971  * otherwise, find the most suitable mode among modes and change it
1972  * to adjusted_mode.
1973  */
1974  list_for_each_entry(m, &connector->modes, head) {
1975  if (hdata->type == HDMI_TYPE13)
1976  index = hdmi_v13_conf_index(m);
1977  else
1978  index = hdmi_v14_conf_index(m);
1979 
1980  if (index >= 0) {
1981  DRM_INFO("desired mode doesn't exist so\n");
1982  DRM_INFO("use the most suitable mode among modes.\n");
1983  memcpy(adjusted_mode, m, sizeof(*m));
1984  break;
1985  }
1986  }
1987 }
1988 
1989 static void hdmi_mode_set(void *ctx, void *mode)
1990 {
1991  struct hdmi_context *hdata = ctx;
1992  int conf_idx;
1993 
1994  DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1995 
1996  conf_idx = hdmi_conf_index(hdata, mode);
1997  if (conf_idx >= 0)
1998  hdata->cur_conf = conf_idx;
1999  else
2000  DRM_DEBUG_KMS("not supported mode\n");
2001 }
2002 
2003 static void hdmi_get_max_resol(void *ctx, unsigned int *width,
2004  unsigned int *height)
2005 {
2006  DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2007 
2008  *width = MAX_WIDTH;
2009  *height = MAX_HEIGHT;
2010 }
2011 
2012 static void hdmi_commit(void *ctx)
2013 {
2014  struct hdmi_context *hdata = ctx;
2015 
2016  DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2017 
2018  hdmi_conf_apply(hdata);
2019 }
2020 
2021 static void hdmi_poweron(struct hdmi_context *hdata)
2022 {
2023  struct hdmi_resources *res = &hdata->res;
2024 
2025  DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2026 
2027  mutex_lock(&hdata->hdmi_mutex);
2028  if (hdata->powered) {
2029  mutex_unlock(&hdata->hdmi_mutex);
2030  return;
2031  }
2032 
2033  hdata->powered = true;
2034 
2035  mutex_unlock(&hdata->hdmi_mutex);
2036 
2037  pm_runtime_get_sync(hdata->dev);
2038 
2040  clk_enable(res->hdmiphy);
2041  clk_enable(res->hdmi);
2042  clk_enable(res->sclk_hdmi);
2043 }
2044 
2045 static void hdmi_poweroff(struct hdmi_context *hdata)
2046 {
2047  struct hdmi_resources *res = &hdata->res;
2048 
2049  DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2050 
2051  mutex_lock(&hdata->hdmi_mutex);
2052  if (!hdata->powered)
2053  goto out;
2054  mutex_unlock(&hdata->hdmi_mutex);
2055 
2056  /*
2057  * The TV power domain needs any condition of hdmiphy to turn off and
2058  * its reset state seems to meet the condition.
2059  */
2060  hdmiphy_conf_reset(hdata);
2061 
2062  clk_disable(res->sclk_hdmi);
2063  clk_disable(res->hdmi);
2064  clk_disable(res->hdmiphy);
2066 
2067  pm_runtime_put_sync(hdata->dev);
2068 
2069  mutex_lock(&hdata->hdmi_mutex);
2070 
2071  hdata->powered = false;
2072 
2073 out:
2074  mutex_unlock(&hdata->hdmi_mutex);
2075 }
2076 
2077 static void hdmi_dpms(void *ctx, int mode)
2078 {
2079  struct hdmi_context *hdata = ctx;
2080 
2081  DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2082 
2083  switch (mode) {
2084  case DRM_MODE_DPMS_ON:
2085  hdmi_poweron(hdata);
2086  break;
2087  case DRM_MODE_DPMS_STANDBY:
2088  case DRM_MODE_DPMS_SUSPEND:
2089  case DRM_MODE_DPMS_OFF:
2090  hdmi_poweroff(hdata);
2091  break;
2092  default:
2093  DRM_DEBUG_KMS("unknown dpms mode: %d\n", mode);
2094  break;
2095  }
2096 }
2097 
2098 static struct exynos_hdmi_ops hdmi_ops = {
2099  /* display */
2100  .is_connected = hdmi_is_connected,
2101  .get_edid = hdmi_get_edid,
2102  .check_timing = hdmi_check_timing,
2103 
2104  /* manager */
2105  .mode_fixup = hdmi_mode_fixup,
2106  .mode_set = hdmi_mode_set,
2107  .get_max_resol = hdmi_get_max_resol,
2108  .commit = hdmi_commit,
2109  .dpms = hdmi_dpms,
2110 };
2111 
2112 static irqreturn_t hdmi_external_irq_thread(int irq, void *arg)
2113 {
2114  struct exynos_drm_hdmi_context *ctx = arg;
2115  struct hdmi_context *hdata = ctx->ctx;
2116 
2117  mutex_lock(&hdata->hdmi_mutex);
2118  hdata->hpd = gpio_get_value(hdata->hpd_gpio);
2119  mutex_unlock(&hdata->hdmi_mutex);
2120 
2121  if (ctx->drm_dev)
2123 
2124  return IRQ_HANDLED;
2125 }
2126 
2127 static irqreturn_t hdmi_internal_irq_thread(int irq, void *arg)
2128 {
2129  struct exynos_drm_hdmi_context *ctx = arg;
2130  struct hdmi_context *hdata = ctx->ctx;
2131  u32 intc_flag;
2132 
2133  intc_flag = hdmi_reg_read(hdata, HDMI_INTC_FLAG);
2134  /* clearing flags for HPD plug/unplug */
2135  if (intc_flag & HDMI_INTC_FLAG_HPD_UNPLUG) {
2136  DRM_DEBUG_KMS("unplugged\n");
2137  hdmi_reg_writemask(hdata, HDMI_INTC_FLAG, ~0,
2138  HDMI_INTC_FLAG_HPD_UNPLUG);
2139  }
2140  if (intc_flag & HDMI_INTC_FLAG_HPD_PLUG) {
2141  DRM_DEBUG_KMS("plugged\n");
2142  hdmi_reg_writemask(hdata, HDMI_INTC_FLAG, ~0,
2143  HDMI_INTC_FLAG_HPD_PLUG);
2144  }
2145 
2146  if (ctx->drm_dev)
2148 
2149  return IRQ_HANDLED;
2150 }
2151 
2152 static int __devinit hdmi_resources_init(struct hdmi_context *hdata)
2153 {
2154  struct device *dev = hdata->dev;
2155  struct hdmi_resources *res = &hdata->res;
2156  static char *supply[] = {
2157  "hdmi-en",
2158  "vdd",
2159  "vdd_osc",
2160  "vdd_pll",
2161  };
2162  int i, ret;
2163 
2164  DRM_DEBUG_KMS("HDMI resource init\n");
2165 
2166  memset(res, 0, sizeof(*res));
2167 
2168  /* get clocks, power */
2169  res->hdmi = clk_get(dev, "hdmi");
2170  if (IS_ERR_OR_NULL(res->hdmi)) {
2171  DRM_ERROR("failed to get clock 'hdmi'\n");
2172  goto fail;
2173  }
2174  res->sclk_hdmi = clk_get(dev, "sclk_hdmi");
2175  if (IS_ERR_OR_NULL(res->sclk_hdmi)) {
2176  DRM_ERROR("failed to get clock 'sclk_hdmi'\n");
2177  goto fail;
2178  }
2179  res->sclk_pixel = clk_get(dev, "sclk_pixel");
2180  if (IS_ERR_OR_NULL(res->sclk_pixel)) {
2181  DRM_ERROR("failed to get clock 'sclk_pixel'\n");
2182  goto fail;
2183  }
2184  res->sclk_hdmiphy = clk_get(dev, "sclk_hdmiphy");
2185  if (IS_ERR_OR_NULL(res->sclk_hdmiphy)) {
2186  DRM_ERROR("failed to get clock 'sclk_hdmiphy'\n");
2187  goto fail;
2188  }
2189  res->hdmiphy = clk_get(dev, "hdmiphy");
2190  if (IS_ERR_OR_NULL(res->hdmiphy)) {
2191  DRM_ERROR("failed to get clock 'hdmiphy'\n");
2192  goto fail;
2193  }
2194 
2195  clk_set_parent(res->sclk_hdmi, res->sclk_pixel);
2196 
2197  res->regul_bulk = kzalloc(ARRAY_SIZE(supply) *
2198  sizeof(res->regul_bulk[0]), GFP_KERNEL);
2199  if (!res->regul_bulk) {
2200  DRM_ERROR("failed to get memory for regulators\n");
2201  goto fail;
2202  }
2203  for (i = 0; i < ARRAY_SIZE(supply); ++i) {
2204  res->regul_bulk[i].supply = supply[i];
2205  res->regul_bulk[i].consumer = NULL;
2206  }
2207  ret = regulator_bulk_get(dev, ARRAY_SIZE(supply), res->regul_bulk);
2208  if (ret) {
2209  DRM_ERROR("failed to get regulators\n");
2210  goto fail;
2211  }
2212  res->regul_count = ARRAY_SIZE(supply);
2213 
2214  return 0;
2215 fail:
2216  DRM_ERROR("HDMI resource init - failed\n");
2217  return -ENODEV;
2218 }
2219 
2220 static int hdmi_resources_cleanup(struct hdmi_context *hdata)
2221 {
2222  struct hdmi_resources *res = &hdata->res;
2223 
2225  /* kfree is NULL-safe */
2226  kfree(res->regul_bulk);
2227  if (!IS_ERR_OR_NULL(res->hdmiphy))
2228  clk_put(res->hdmiphy);
2229  if (!IS_ERR_OR_NULL(res->sclk_hdmiphy))
2230  clk_put(res->sclk_hdmiphy);
2231  if (!IS_ERR_OR_NULL(res->sclk_pixel))
2232  clk_put(res->sclk_pixel);
2233  if (!IS_ERR_OR_NULL(res->sclk_hdmi))
2234  clk_put(res->sclk_hdmi);
2235  if (!IS_ERR_OR_NULL(res->hdmi))
2236  clk_put(res->hdmi);
2237  memset(res, 0, sizeof(*res));
2238 
2239  return 0;
2240 }
2241 
2242 static struct i2c_client *hdmi_ddc, *hdmi_hdmiphy;
2243 
2245 {
2246  if (ddc)
2247  hdmi_ddc = ddc;
2248 }
2249 
2251 {
2252  if (hdmiphy)
2253  hdmi_hdmiphy = hdmiphy;
2254 }
2255 
2256 #ifdef CONFIG_OF
2257 static struct s5p_hdmi_platform_data *drm_hdmi_dt_parse_pdata
2258  (struct device *dev)
2259 {
2260  struct device_node *np = dev->of_node;
2261  struct s5p_hdmi_platform_data *pd;
2262  enum of_gpio_flags flags;
2263  u32 value;
2264 
2265  pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
2266  if (!pd) {
2267  DRM_ERROR("memory allocation for pdata failed\n");
2268  goto err_data;
2269  }
2270 
2271  if (!of_find_property(np, "hpd-gpio", &value)) {
2272  DRM_ERROR("no hpd gpio property found\n");
2273  goto err_data;
2274  }
2275 
2276  pd->hpd_gpio = of_get_named_gpio_flags(np, "hpd-gpio", 0, &flags);
2277 
2278  return pd;
2279 
2280 err_data:
2281  return NULL;
2282 }
2283 #else
2284 static struct s5p_hdmi_platform_data *drm_hdmi_dt_parse_pdata
2285  (struct device *dev)
2286 {
2287  return NULL;
2288 }
2289 #endif
2290 
2291 static struct platform_device_id hdmi_driver_types[] = {
2292  {
2293  .name = "s5pv210-hdmi",
2294  .driver_data = HDMI_TYPE13,
2295  }, {
2296  .name = "exynos4-hdmi",
2297  .driver_data = HDMI_TYPE13,
2298  }, {
2299  .name = "exynos4-hdmi14",
2300  .driver_data = HDMI_TYPE14,
2301  }, {
2302  .name = "exynos5-hdmi",
2303  .driver_data = HDMI_TYPE14,
2304  }, {
2305  /* end node */
2306  }
2307 };
2308 
2309 static struct of_device_id hdmi_match_types[] = {
2310  {
2311  .compatible = "samsung,exynos5-hdmi",
2312  .data = (void *)HDMI_TYPE14,
2313  }, {
2314  /* end node */
2315  }
2316 };
2317 
2318 static int __devinit hdmi_probe(struct platform_device *pdev)
2319 {
2320  struct device *dev = &pdev->dev;
2321  struct exynos_drm_hdmi_context *drm_hdmi_ctx;
2322  struct hdmi_context *hdata;
2323  struct s5p_hdmi_platform_data *pdata;
2324  struct resource *res;
2325  int ret;
2326 
2327  DRM_DEBUG_KMS("[%d]\n", __LINE__);
2328 
2329  if (pdev->dev.of_node) {
2330  pdata = drm_hdmi_dt_parse_pdata(dev);
2331  if (IS_ERR(pdata)) {
2332  DRM_ERROR("failed to parse dt\n");
2333  return PTR_ERR(pdata);
2334  }
2335  } else {
2336  pdata = pdev->dev.platform_data;
2337  }
2338 
2339  if (!pdata) {
2340  DRM_ERROR("no platform data specified\n");
2341  return -EINVAL;
2342  }
2343 
2344  drm_hdmi_ctx = devm_kzalloc(&pdev->dev, sizeof(*drm_hdmi_ctx),
2345  GFP_KERNEL);
2346  if (!drm_hdmi_ctx) {
2347  DRM_ERROR("failed to allocate common hdmi context.\n");
2348  return -ENOMEM;
2349  }
2350 
2351  hdata = devm_kzalloc(&pdev->dev, sizeof(struct hdmi_context),
2352  GFP_KERNEL);
2353  if (!hdata) {
2354  DRM_ERROR("out of memory\n");
2355  return -ENOMEM;
2356  }
2357 
2358  mutex_init(&hdata->hdmi_mutex);
2359 
2360  drm_hdmi_ctx->ctx = (void *)hdata;
2361  hdata->parent_ctx = (void *)drm_hdmi_ctx;
2362 
2363  platform_set_drvdata(pdev, drm_hdmi_ctx);
2364 
2365  if (dev->of_node) {
2366  const struct of_device_id *match;
2367  match = of_match_node(of_match_ptr(hdmi_match_types),
2368  pdev->dev.of_node);
2369  hdata->type = (enum hdmi_type)match->data;
2370  } else {
2371  hdata->type = (enum hdmi_type)platform_get_device_id
2372  (pdev)->driver_data;
2373  }
2374 
2375  hdata->hpd_gpio = pdata->hpd_gpio;
2376  hdata->dev = dev;
2377 
2378  ret = hdmi_resources_init(hdata);
2379 
2380  if (ret) {
2381  ret = -EINVAL;
2382  DRM_ERROR("hdmi_resources_init failed\n");
2383  goto err_data;
2384  }
2385 
2386  res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2387  if (!res) {
2388  DRM_ERROR("failed to find registers\n");
2389  ret = -ENOENT;
2390  goto err_resource;
2391  }
2392 
2393  hdata->regs = devm_request_and_ioremap(&pdev->dev, res);
2394  if (!hdata->regs) {
2395  DRM_ERROR("failed to map registers\n");
2396  ret = -ENXIO;
2397  goto err_resource;
2398  }
2399 
2400  ret = gpio_request(hdata->hpd_gpio, "HPD");
2401  if (ret) {
2402  DRM_ERROR("failed to request HPD gpio\n");
2403  goto err_resource;
2404  }
2405 
2406  /* DDC i2c driver */
2407  if (i2c_add_driver(&ddc_driver)) {
2408  DRM_ERROR("failed to register ddc i2c driver\n");
2409  ret = -ENOENT;
2410  goto err_gpio;
2411  }
2412 
2413  hdata->ddc_port = hdmi_ddc;
2414 
2415  /* hdmiphy i2c driver */
2416  if (i2c_add_driver(&hdmiphy_driver)) {
2417  DRM_ERROR("failed to register hdmiphy i2c driver\n");
2418  ret = -ENOENT;
2419  goto err_ddc;
2420  }
2421 
2422  hdata->hdmiphy_port = hdmi_hdmiphy;
2423 
2424  hdata->external_irq = gpio_to_irq(hdata->hpd_gpio);
2425  if (hdata->external_irq < 0) {
2426  DRM_ERROR("failed to get GPIO external irq\n");
2427  ret = hdata->external_irq;
2428  goto err_hdmiphy;
2429  }
2430 
2431  hdata->internal_irq = platform_get_irq(pdev, 0);
2432  if (hdata->internal_irq < 0) {
2433  DRM_ERROR("failed to get platform internal irq\n");
2434  ret = hdata->internal_irq;
2435  goto err_hdmiphy;
2436  }
2437 
2438  hdata->hpd = gpio_get_value(hdata->hpd_gpio);
2439 
2440  ret = request_threaded_irq(hdata->external_irq, NULL,
2441  hdmi_external_irq_thread, IRQF_TRIGGER_RISING |
2443  "hdmi_external", drm_hdmi_ctx);
2444  if (ret) {
2445  DRM_ERROR("failed to register hdmi external interrupt\n");
2446  goto err_hdmiphy;
2447  }
2448 
2449  ret = request_threaded_irq(hdata->internal_irq, NULL,
2450  hdmi_internal_irq_thread, IRQF_ONESHOT,
2451  "hdmi_internal", drm_hdmi_ctx);
2452  if (ret) {
2453  DRM_ERROR("failed to register hdmi internal interrupt\n");
2454  goto err_free_irq;
2455  }
2456 
2457  /* Attach HDMI Driver to common hdmi. */
2458  exynos_hdmi_drv_attach(drm_hdmi_ctx);
2459 
2460  /* register specific callbacks to common hdmi. */
2461  exynos_hdmi_ops_register(&hdmi_ops);
2462 
2463  pm_runtime_enable(dev);
2464 
2465  return 0;
2466 
2467 err_free_irq:
2468  free_irq(hdata->external_irq, drm_hdmi_ctx);
2469 err_hdmiphy:
2471 err_ddc:
2473 err_gpio:
2474  gpio_free(hdata->hpd_gpio);
2475 err_resource:
2476  hdmi_resources_cleanup(hdata);
2477 err_data:
2478  return ret;
2479 }
2480 
2481 static int __devexit hdmi_remove(struct platform_device *pdev)
2482 {
2483  struct device *dev = &pdev->dev;
2484  struct exynos_drm_hdmi_context *ctx = platform_get_drvdata(pdev);
2485  struct hdmi_context *hdata = ctx->ctx;
2486 
2487  DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2488 
2489  pm_runtime_disable(dev);
2490 
2491  free_irq(hdata->internal_irq, hdata);
2492  free_irq(hdata->external_irq, hdata);
2493 
2494  gpio_free(hdata->hpd_gpio);
2495 
2496  hdmi_resources_cleanup(hdata);
2497 
2498  /* hdmiphy i2c driver */
2500  /* DDC i2c driver */
2502 
2503  return 0;
2504 }
2505 
2506 #ifdef CONFIG_PM_SLEEP
2507 static int hdmi_suspend(struct device *dev)
2508 {
2509  struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev);
2510  struct hdmi_context *hdata = ctx->ctx;
2511 
2512  disable_irq(hdata->internal_irq);
2513  disable_irq(hdata->external_irq);
2514 
2515  hdata->hpd = false;
2516  if (ctx->drm_dev)
2518 
2519  hdmi_poweroff(hdata);
2520 
2521  return 0;
2522 }
2523 
2524 static int hdmi_resume(struct device *dev)
2525 {
2526  struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev);
2527  struct hdmi_context *hdata = ctx->ctx;
2528 
2529  enable_irq(hdata->external_irq);
2530  enable_irq(hdata->internal_irq);
2531  return 0;
2532 }
2533 #endif
2534 
2535 static SIMPLE_DEV_PM_OPS(hdmi_pm_ops, hdmi_suspend, hdmi_resume);
2536 
2538  .probe = hdmi_probe,
2539  .remove = __devexit_p(hdmi_remove),
2540  .id_table = hdmi_driver_types,
2541  .driver = {
2542  .name = "exynos-hdmi",
2543  .owner = THIS_MODULE,
2544  .pm = &hdmi_pm_ops,
2545  .of_match_table = hdmi_match_types,
2546  },
2547 };