drm/exynos: cleanup exynos_hdmi.h
[platform/adaptation/renesas_rcar/renesas_kernel.git] / drivers / gpu / drm / exynos / exynos_hdmi.c
1 /*
2  * Copyright (C) 2011 Samsung Electronics Co.Ltd
3  * Authors:
4  * Seung-Woo Kim <sw0312.kim@samsung.com>
5  *      Inki Dae <inki.dae@samsung.com>
6  *      Joonyoung Shim <jy0922.shim@samsung.com>
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 "drmP.h"
18 #include "drm_edid.h"
19 #include "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>
34 #include <linux/regulator/consumer.h>
35
36 #include <drm/exynos_drm.h>
37
38 #include "exynos_drm_drv.h"
39 #include "exynos_drm_hdmi.h"
40
41 #include "exynos_hdmi.h"
42
43 #define HDMI_OVERLAY_NUMBER     3
44 #define MAX_WIDTH               1920
45 #define MAX_HEIGHT              1080
46 #define get_hdmi_context(dev)   platform_get_drvdata(to_platform_device(dev))
47
48 struct hdmi_resources {
49         struct clk                      *hdmi;
50         struct clk                      *sclk_hdmi;
51         struct clk                      *sclk_pixel;
52         struct clk                      *sclk_hdmiphy;
53         struct clk                      *hdmiphy;
54         struct regulator_bulk_data      *regul_bulk;
55         int                             regul_count;
56 };
57
58 struct hdmi_context {
59         struct device                   *dev;
60         struct drm_device               *drm_dev;
61         struct fb_videomode             *default_timing;
62         unsigned int                    is_v13:1;
63         unsigned int                    default_win;
64         unsigned int                    default_bpp;
65         bool                            hpd_handle;
66         bool                            enabled;
67
68         struct resource                 *regs_res;
69         void __iomem                    *regs;
70         unsigned int                    irq;
71         struct workqueue_struct         *wq;
72         struct work_struct              hotplug_work;
73
74         struct i2c_client               *ddc_port;
75         struct i2c_client               *hdmiphy_port;
76
77         /* current hdmiphy conf index */
78         int cur_conf;
79
80         struct hdmi_resources           res;
81         void                            *parent_ctx;
82 };
83
84 /* HDMI Version 1.3 */
85 static const u8 hdmiphy_v13_conf27[32] = {
86         0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40,
87         0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
88         0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
89         0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
90 };
91
92 static const u8 hdmiphy_v13_conf27_027[32] = {
93         0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09, 0x64,
94         0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
95         0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
96         0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
97 };
98
99 static const u8 hdmiphy_v13_conf74_175[32] = {
100         0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef, 0x5B,
101         0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3, 0x54, 0xb9,
102         0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
103         0x22, 0x40, 0xa5, 0x26, 0x01, 0x00, 0x00, 0x00,
104 };
105
106 static const u8 hdmiphy_v13_conf74_25[32] = {
107         0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c, 0xf8, 0x40,
108         0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1, 0x54, 0xba,
109         0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xe0,
110         0x22, 0x40, 0xa4, 0x26, 0x01, 0x00, 0x00, 0x00,
111 };
112
113 static const u8 hdmiphy_v13_conf148_5[32] = {
114         0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf8, 0x40,
115         0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1, 0x54, 0xba,
116         0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0,
117         0x22, 0x40, 0xa4, 0x26, 0x02, 0x00, 0x00, 0x00,
118 };
119
120 struct hdmi_v13_tg_regs {
121         u8 cmd;
122         u8 h_fsz_l;
123         u8 h_fsz_h;
124         u8 hact_st_l;
125         u8 hact_st_h;
126         u8 hact_sz_l;
127         u8 hact_sz_h;
128         u8 v_fsz_l;
129         u8 v_fsz_h;
130         u8 vsync_l;
131         u8 vsync_h;
132         u8 vsync2_l;
133         u8 vsync2_h;
134         u8 vact_st_l;
135         u8 vact_st_h;
136         u8 vact_sz_l;
137         u8 vact_sz_h;
138         u8 field_chg_l;
139         u8 field_chg_h;
140         u8 vact_st2_l;
141         u8 vact_st2_h;
142         u8 vsync_top_hdmi_l;
143         u8 vsync_top_hdmi_h;
144         u8 vsync_bot_hdmi_l;
145         u8 vsync_bot_hdmi_h;
146         u8 field_top_hdmi_l;
147         u8 field_top_hdmi_h;
148         u8 field_bot_hdmi_l;
149         u8 field_bot_hdmi_h;
150 };
151
152 struct hdmi_v13_core_regs {
153         u8 h_blank[2];
154         u8 v_blank[3];
155         u8 h_v_line[3];
156         u8 vsync_pol[1];
157         u8 int_pro_mode[1];
158         u8 v_blank_f[3];
159         u8 h_sync_gen[3];
160         u8 v_sync_gen1[3];
161         u8 v_sync_gen2[3];
162         u8 v_sync_gen3[3];
163 };
164
165 struct hdmi_v13_preset_conf {
166         struct hdmi_v13_core_regs core;
167         struct hdmi_v13_tg_regs tg;
168 };
169
170 struct hdmi_v13_conf {
171         int width;
172         int height;
173         int vrefresh;
174         bool interlace;
175         const u8 *hdmiphy_data;
176         const struct hdmi_v13_preset_conf *conf;
177 };
178
179 static const struct hdmi_v13_preset_conf hdmi_v13_conf_480p = {
180         .core = {
181                 .h_blank = {0x8a, 0x00},
182                 .v_blank = {0x0d, 0x6a, 0x01},
183                 .h_v_line = {0x0d, 0xa2, 0x35},
184                 .vsync_pol = {0x01},
185                 .int_pro_mode = {0x00},
186                 .v_blank_f = {0x00, 0x00, 0x00},
187                 .h_sync_gen = {0x0e, 0x30, 0x11},
188                 .v_sync_gen1 = {0x0f, 0x90, 0x00},
189                 /* other don't care */
190         },
191         .tg = {
192                 0x00, /* cmd */
193                 0x5a, 0x03, /* h_fsz */
194                 0x8a, 0x00, 0xd0, 0x02, /* hact */
195                 0x0d, 0x02, /* v_fsz */
196                 0x01, 0x00, 0x33, 0x02, /* vsync */
197                 0x2d, 0x00, 0xe0, 0x01, /* vact */
198                 0x33, 0x02, /* field_chg */
199                 0x49, 0x02, /* vact_st2 */
200                 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
201                 0x01, 0x00, 0x33, 0x02, /* field top/bot */
202         },
203 };
204
205 static const struct hdmi_v13_preset_conf hdmi_v13_conf_720p60 = {
206         .core = {
207                 .h_blank = {0x72, 0x01},
208                 .v_blank = {0xee, 0xf2, 0x00},
209                 .h_v_line = {0xee, 0x22, 0x67},
210                 .vsync_pol = {0x00},
211                 .int_pro_mode = {0x00},
212                 .v_blank_f = {0x00, 0x00, 0x00}, /* don't care */
213                 .h_sync_gen = {0x6c, 0x50, 0x02},
214                 .v_sync_gen1 = {0x0a, 0x50, 0x00},
215                 .v_sync_gen2 = {0x01, 0x10, 0x00},
216                 .v_sync_gen3 = {0x01, 0x10, 0x00},
217                 /* other don't care */
218         },
219         .tg = {
220                 0x00, /* cmd */
221                 0x72, 0x06, /* h_fsz */
222                 0x71, 0x01, 0x01, 0x05, /* hact */
223                 0xee, 0x02, /* v_fsz */
224                 0x01, 0x00, 0x33, 0x02, /* vsync */
225                 0x1e, 0x00, 0xd0, 0x02, /* vact */
226                 0x33, 0x02, /* field_chg */
227                 0x49, 0x02, /* vact_st2 */
228                 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
229                 0x01, 0x00, 0x33, 0x02, /* field top/bot */
230         },
231 };
232
233 static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080i50 = {
234         .core = {
235                 .h_blank = {0xd0, 0x02},
236                 .v_blank = {0x32, 0xB2, 0x00},
237                 .h_v_line = {0x65, 0x04, 0xa5},
238                 .vsync_pol = {0x00},
239                 .int_pro_mode = {0x01},
240                 .v_blank_f = {0x49, 0x2A, 0x23},
241                 .h_sync_gen = {0x0E, 0xEA, 0x08},
242                 .v_sync_gen1 = {0x07, 0x20, 0x00},
243                 .v_sync_gen2 = {0x39, 0x42, 0x23},
244                 .v_sync_gen3 = {0x38, 0x87, 0x73},
245                 /* other don't care */
246         },
247         .tg = {
248                 0x00, /* cmd */
249                 0x50, 0x0A, /* h_fsz */
250                 0xCF, 0x02, 0x81, 0x07, /* hact */
251                 0x65, 0x04, /* v_fsz */
252                 0x01, 0x00, 0x33, 0x02, /* vsync */
253                 0x16, 0x00, 0x1c, 0x02, /* vact */
254                 0x33, 0x02, /* field_chg */
255                 0x49, 0x02, /* vact_st2 */
256                 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
257                 0x01, 0x00, 0x33, 0x02, /* field top/bot */
258         },
259 };
260
261 static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080p50 = {
262         .core = {
263                 .h_blank = {0xd0, 0x02},
264                 .v_blank = {0x65, 0x6c, 0x01},
265                 .h_v_line = {0x65, 0x04, 0xa5},
266                 .vsync_pol = {0x00},
267                 .int_pro_mode = {0x00},
268                 .v_blank_f = {0x00, 0x00, 0x00}, /* don't care */
269                 .h_sync_gen = {0x0e, 0xea, 0x08},
270                 .v_sync_gen1 = {0x09, 0x40, 0x00},
271                 .v_sync_gen2 = {0x01, 0x10, 0x00},
272                 .v_sync_gen3 = {0x01, 0x10, 0x00},
273                 /* other don't care */
274         },
275         .tg = {
276                 0x00, /* cmd */
277                 0x50, 0x0A, /* h_fsz */
278                 0xCF, 0x02, 0x81, 0x07, /* hact */
279                 0x65, 0x04, /* v_fsz */
280                 0x01, 0x00, 0x33, 0x02, /* vsync */
281                 0x2d, 0x00, 0x38, 0x04, /* vact */
282                 0x33, 0x02, /* field_chg */
283                 0x48, 0x02, /* vact_st2 */
284                 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
285                 0x01, 0x00, 0x33, 0x02, /* field top/bot */
286         },
287 };
288
289 static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080i60 = {
290         .core = {
291                 .h_blank = {0x18, 0x01},
292                 .v_blank = {0x32, 0xB2, 0x00},
293                 .h_v_line = {0x65, 0x84, 0x89},
294                 .vsync_pol = {0x00},
295                 .int_pro_mode = {0x01},
296                 .v_blank_f = {0x49, 0x2A, 0x23},
297                 .h_sync_gen = {0x56, 0x08, 0x02},
298                 .v_sync_gen1 = {0x07, 0x20, 0x00},
299                 .v_sync_gen2 = {0x39, 0x42, 0x23},
300                 .v_sync_gen3 = {0xa4, 0x44, 0x4a},
301                 /* other don't care */
302         },
303         .tg = {
304                 0x00, /* cmd */
305                 0x98, 0x08, /* h_fsz */
306                 0x17, 0x01, 0x81, 0x07, /* hact */
307                 0x65, 0x04, /* v_fsz */
308                 0x01, 0x00, 0x33, 0x02, /* vsync */
309                 0x16, 0x00, 0x1c, 0x02, /* vact */
310                 0x33, 0x02, /* field_chg */
311                 0x49, 0x02, /* vact_st2 */
312                 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
313                 0x01, 0x00, 0x33, 0x02, /* field top/bot */
314         },
315 };
316
317 static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080p60 = {
318         .core = {
319                 .h_blank = {0x18, 0x01},
320                 .v_blank = {0x65, 0x6c, 0x01},
321                 .h_v_line = {0x65, 0x84, 0x89},
322                 .vsync_pol = {0x00},
323                 .int_pro_mode = {0x00},
324                 .v_blank_f = {0x00, 0x00, 0x00}, /* don't care */
325                 .h_sync_gen = {0x56, 0x08, 0x02},
326                 .v_sync_gen1 = {0x09, 0x40, 0x00},
327                 .v_sync_gen2 = {0x01, 0x10, 0x00},
328                 .v_sync_gen3 = {0x01, 0x10, 0x00},
329                 /* other don't care */
330         },
331         .tg = {
332                 0x00, /* cmd */
333                 0x98, 0x08, /* h_fsz */
334                 0x17, 0x01, 0x81, 0x07, /* hact */
335                 0x65, 0x04, /* v_fsz */
336                 0x01, 0x00, 0x33, 0x02, /* vsync */
337                 0x2d, 0x00, 0x38, 0x04, /* vact */
338                 0x33, 0x02, /* field_chg */
339                 0x48, 0x02, /* vact_st2 */
340                 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
341                 0x01, 0x00, 0x33, 0x02, /* field top/bot */
342         },
343 };
344
345 static const struct hdmi_v13_conf hdmi_v13_confs[] = {
346         { 1280, 720, 60, false, hdmiphy_v13_conf74_25, &hdmi_v13_conf_720p60 },
347         { 1280, 720, 50, false, hdmiphy_v13_conf74_25, &hdmi_v13_conf_720p60 },
348         { 720, 480, 60, false, hdmiphy_v13_conf27_027, &hdmi_v13_conf_480p },
349         { 1920, 1080, 50, true, hdmiphy_v13_conf74_25, &hdmi_v13_conf_1080i50 },
350         { 1920, 1080, 50, false, hdmiphy_v13_conf148_5,
351                                  &hdmi_v13_conf_1080p50 },
352         { 1920, 1080, 60, true, hdmiphy_v13_conf74_25, &hdmi_v13_conf_1080i60 },
353         { 1920, 1080, 60, false, hdmiphy_v13_conf148_5,
354                                  &hdmi_v13_conf_1080p60 },
355 };
356
357 /* HDMI Version 1.4 */
358 static const u8 hdmiphy_conf27_027[32] = {
359         0x01, 0xd1, 0x2d, 0x72, 0x40, 0x64, 0x12, 0x08,
360         0x43, 0xa0, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
361         0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
362         0x54, 0xe3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00,
363 };
364
365 static const u8 hdmiphy_conf74_25[32] = {
366         0x01, 0xd1, 0x1f, 0x10, 0x40, 0x40, 0xf8, 0x08,
367         0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
368         0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
369         0x54, 0xa5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00,
370 };
371
372 static const u8 hdmiphy_conf148_5[32] = {
373         0x01, 0xd1, 0x1f, 0x00, 0x40, 0x40, 0xf8, 0x08,
374         0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
375         0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
376         0x54, 0x4b, 0x25, 0x03, 0x00, 0x00, 0x01, 0x00,
377 };
378
379 struct hdmi_tg_regs {
380         u8 cmd;
381         u8 h_fsz_l;
382         u8 h_fsz_h;
383         u8 hact_st_l;
384         u8 hact_st_h;
385         u8 hact_sz_l;
386         u8 hact_sz_h;
387         u8 v_fsz_l;
388         u8 v_fsz_h;
389         u8 vsync_l;
390         u8 vsync_h;
391         u8 vsync2_l;
392         u8 vsync2_h;
393         u8 vact_st_l;
394         u8 vact_st_h;
395         u8 vact_sz_l;
396         u8 vact_sz_h;
397         u8 field_chg_l;
398         u8 field_chg_h;
399         u8 vact_st2_l;
400         u8 vact_st2_h;
401         u8 vact_st3_l;
402         u8 vact_st3_h;
403         u8 vact_st4_l;
404         u8 vact_st4_h;
405         u8 vsync_top_hdmi_l;
406         u8 vsync_top_hdmi_h;
407         u8 vsync_bot_hdmi_l;
408         u8 vsync_bot_hdmi_h;
409         u8 field_top_hdmi_l;
410         u8 field_top_hdmi_h;
411         u8 field_bot_hdmi_l;
412         u8 field_bot_hdmi_h;
413         u8 tg_3d;
414 };
415
416 struct hdmi_core_regs {
417         u8 h_blank[2];
418         u8 v2_blank[2];
419         u8 v1_blank[2];
420         u8 v_line[2];
421         u8 h_line[2];
422         u8 hsync_pol[1];
423         u8 vsync_pol[1];
424         u8 int_pro_mode[1];
425         u8 v_blank_f0[2];
426         u8 v_blank_f1[2];
427         u8 h_sync_start[2];
428         u8 h_sync_end[2];
429         u8 v_sync_line_bef_2[2];
430         u8 v_sync_line_bef_1[2];
431         u8 v_sync_line_aft_2[2];
432         u8 v_sync_line_aft_1[2];
433         u8 v_sync_line_aft_pxl_2[2];
434         u8 v_sync_line_aft_pxl_1[2];
435         u8 v_blank_f2[2]; /* for 3D mode */
436         u8 v_blank_f3[2]; /* for 3D mode */
437         u8 v_blank_f4[2]; /* for 3D mode */
438         u8 v_blank_f5[2]; /* for 3D mode */
439         u8 v_sync_line_aft_3[2];
440         u8 v_sync_line_aft_4[2];
441         u8 v_sync_line_aft_5[2];
442         u8 v_sync_line_aft_6[2];
443         u8 v_sync_line_aft_pxl_3[2];
444         u8 v_sync_line_aft_pxl_4[2];
445         u8 v_sync_line_aft_pxl_5[2];
446         u8 v_sync_line_aft_pxl_6[2];
447         u8 vact_space_1[2];
448         u8 vact_space_2[2];
449         u8 vact_space_3[2];
450         u8 vact_space_4[2];
451         u8 vact_space_5[2];
452         u8 vact_space_6[2];
453 };
454
455 struct hdmi_preset_conf {
456         struct hdmi_core_regs core;
457         struct hdmi_tg_regs tg;
458 };
459
460 struct hdmi_conf {
461         int width;
462         int height;
463         int vrefresh;
464         bool interlace;
465         const u8 *hdmiphy_data;
466         const struct hdmi_preset_conf *conf;
467 };
468
469 static const struct hdmi_preset_conf hdmi_conf_480p60 = {
470         .core = {
471                 .h_blank = {0x8a, 0x00},
472                 .v2_blank = {0x0d, 0x02},
473                 .v1_blank = {0x2d, 0x00},
474                 .v_line = {0x0d, 0x02},
475                 .h_line = {0x5a, 0x03},
476                 .hsync_pol = {0x01},
477                 .vsync_pol = {0x01},
478                 .int_pro_mode = {0x00},
479                 .v_blank_f0 = {0xff, 0xff},
480                 .v_blank_f1 = {0xff, 0xff},
481                 .h_sync_start = {0x0e, 0x00},
482                 .h_sync_end = {0x4c, 0x00},
483                 .v_sync_line_bef_2 = {0x0f, 0x00},
484                 .v_sync_line_bef_1 = {0x09, 0x00},
485                 .v_sync_line_aft_2 = {0xff, 0xff},
486                 .v_sync_line_aft_1 = {0xff, 0xff},
487                 .v_sync_line_aft_pxl_2 = {0xff, 0xff},
488                 .v_sync_line_aft_pxl_1 = {0xff, 0xff},
489                 .v_blank_f2 = {0xff, 0xff},
490                 .v_blank_f3 = {0xff, 0xff},
491                 .v_blank_f4 = {0xff, 0xff},
492                 .v_blank_f5 = {0xff, 0xff},
493                 .v_sync_line_aft_3 = {0xff, 0xff},
494                 .v_sync_line_aft_4 = {0xff, 0xff},
495                 .v_sync_line_aft_5 = {0xff, 0xff},
496                 .v_sync_line_aft_6 = {0xff, 0xff},
497                 .v_sync_line_aft_pxl_3 = {0xff, 0xff},
498                 .v_sync_line_aft_pxl_4 = {0xff, 0xff},
499                 .v_sync_line_aft_pxl_5 = {0xff, 0xff},
500                 .v_sync_line_aft_pxl_6 = {0xff, 0xff},
501                 .vact_space_1 = {0xff, 0xff},
502                 .vact_space_2 = {0xff, 0xff},
503                 .vact_space_3 = {0xff, 0xff},
504                 .vact_space_4 = {0xff, 0xff},
505                 .vact_space_5 = {0xff, 0xff},
506                 .vact_space_6 = {0xff, 0xff},
507                 /* other don't care */
508         },
509         .tg = {
510                 0x00, /* cmd */
511                 0x5a, 0x03, /* h_fsz */
512                 0x8a, 0x00, 0xd0, 0x02, /* hact */
513                 0x0d, 0x02, /* v_fsz */
514                 0x01, 0x00, 0x33, 0x02, /* vsync */
515                 0x2d, 0x00, 0xe0, 0x01, /* vact */
516                 0x33, 0x02, /* field_chg */
517                 0x48, 0x02, /* vact_st2 */
518                 0x00, 0x00, /* vact_st3 */
519                 0x00, 0x00, /* vact_st4 */
520                 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
521                 0x01, 0x00, 0x33, 0x02, /* field top/bot */
522                 0x00, /* 3d FP */
523         },
524 };
525
526 static const struct hdmi_preset_conf hdmi_conf_720p50 = {
527         .core = {
528                 .h_blank = {0xbc, 0x02},
529                 .v2_blank = {0xee, 0x02},
530                 .v1_blank = {0x1e, 0x00},
531                 .v_line = {0xee, 0x02},
532                 .h_line = {0xbc, 0x07},
533                 .hsync_pol = {0x00},
534                 .vsync_pol = {0x00},
535                 .int_pro_mode = {0x00},
536                 .v_blank_f0 = {0xff, 0xff},
537                 .v_blank_f1 = {0xff, 0xff},
538                 .h_sync_start = {0xb6, 0x01},
539                 .h_sync_end = {0xde, 0x01},
540                 .v_sync_line_bef_2 = {0x0a, 0x00},
541                 .v_sync_line_bef_1 = {0x05, 0x00},
542                 .v_sync_line_aft_2 = {0xff, 0xff},
543                 .v_sync_line_aft_1 = {0xff, 0xff},
544                 .v_sync_line_aft_pxl_2 = {0xff, 0xff},
545                 .v_sync_line_aft_pxl_1 = {0xff, 0xff},
546                 .v_blank_f2 = {0xff, 0xff},
547                 .v_blank_f3 = {0xff, 0xff},
548                 .v_blank_f4 = {0xff, 0xff},
549                 .v_blank_f5 = {0xff, 0xff},
550                 .v_sync_line_aft_3 = {0xff, 0xff},
551                 .v_sync_line_aft_4 = {0xff, 0xff},
552                 .v_sync_line_aft_5 = {0xff, 0xff},
553                 .v_sync_line_aft_6 = {0xff, 0xff},
554                 .v_sync_line_aft_pxl_3 = {0xff, 0xff},
555                 .v_sync_line_aft_pxl_4 = {0xff, 0xff},
556                 .v_sync_line_aft_pxl_5 = {0xff, 0xff},
557                 .v_sync_line_aft_pxl_6 = {0xff, 0xff},
558                 .vact_space_1 = {0xff, 0xff},
559                 .vact_space_2 = {0xff, 0xff},
560                 .vact_space_3 = {0xff, 0xff},
561                 .vact_space_4 = {0xff, 0xff},
562                 .vact_space_5 = {0xff, 0xff},
563                 .vact_space_6 = {0xff, 0xff},
564                 /* other don't care */
565         },
566         .tg = {
567                 0x00, /* cmd */
568                 0xbc, 0x07, /* h_fsz */
569                 0xbc, 0x02, 0x00, 0x05, /* hact */
570                 0xee, 0x02, /* v_fsz */
571                 0x01, 0x00, 0x33, 0x02, /* vsync */
572                 0x1e, 0x00, 0xd0, 0x02, /* vact */
573                 0x33, 0x02, /* field_chg */
574                 0x48, 0x02, /* vact_st2 */
575                 0x00, 0x00, /* vact_st3 */
576                 0x00, 0x00, /* vact_st4 */
577                 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
578                 0x01, 0x00, 0x33, 0x02, /* field top/bot */
579                 0x00, /* 3d FP */
580         },
581 };
582
583 static const struct hdmi_preset_conf hdmi_conf_720p60 = {
584         .core = {
585                 .h_blank = {0x72, 0x01},
586                 .v2_blank = {0xee, 0x02},
587                 .v1_blank = {0x1e, 0x00},
588                 .v_line = {0xee, 0x02},
589                 .h_line = {0x72, 0x06},
590                 .hsync_pol = {0x00},
591                 .vsync_pol = {0x00},
592                 .int_pro_mode = {0x00},
593                 .v_blank_f0 = {0xff, 0xff},
594                 .v_blank_f1 = {0xff, 0xff},
595                 .h_sync_start = {0x6c, 0x00},
596                 .h_sync_end = {0x94, 0x00},
597                 .v_sync_line_bef_2 = {0x0a, 0x00},
598                 .v_sync_line_bef_1 = {0x05, 0x00},
599                 .v_sync_line_aft_2 = {0xff, 0xff},
600                 .v_sync_line_aft_1 = {0xff, 0xff},
601                 .v_sync_line_aft_pxl_2 = {0xff, 0xff},
602                 .v_sync_line_aft_pxl_1 = {0xff, 0xff},
603                 .v_blank_f2 = {0xff, 0xff},
604                 .v_blank_f3 = {0xff, 0xff},
605                 .v_blank_f4 = {0xff, 0xff},
606                 .v_blank_f5 = {0xff, 0xff},
607                 .v_sync_line_aft_3 = {0xff, 0xff},
608                 .v_sync_line_aft_4 = {0xff, 0xff},
609                 .v_sync_line_aft_5 = {0xff, 0xff},
610                 .v_sync_line_aft_6 = {0xff, 0xff},
611                 .v_sync_line_aft_pxl_3 = {0xff, 0xff},
612                 .v_sync_line_aft_pxl_4 = {0xff, 0xff},
613                 .v_sync_line_aft_pxl_5 = {0xff, 0xff},
614                 .v_sync_line_aft_pxl_6 = {0xff, 0xff},
615                 .vact_space_1 = {0xff, 0xff},
616                 .vact_space_2 = {0xff, 0xff},
617                 .vact_space_3 = {0xff, 0xff},
618                 .vact_space_4 = {0xff, 0xff},
619                 .vact_space_5 = {0xff, 0xff},
620                 .vact_space_6 = {0xff, 0xff},
621                 /* other don't care */
622         },
623         .tg = {
624                 0x00, /* cmd */
625                 0x72, 0x06, /* h_fsz */
626                 0x72, 0x01, 0x00, 0x05, /* hact */
627                 0xee, 0x02, /* v_fsz */
628                 0x01, 0x00, 0x33, 0x02, /* vsync */
629                 0x1e, 0x00, 0xd0, 0x02, /* vact */
630                 0x33, 0x02, /* field_chg */
631                 0x48, 0x02, /* vact_st2 */
632                 0x00, 0x00, /* vact_st3 */
633                 0x00, 0x00, /* vact_st4 */
634                 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
635                 0x01, 0x00, 0x33, 0x02, /* field top/bot */
636                 0x00, /* 3d FP */
637         },
638 };
639
640 static const struct hdmi_preset_conf hdmi_conf_1080i50 = {
641         .core = {
642                 .h_blank = {0xd0, 0x02},
643                 .v2_blank = {0x32, 0x02},
644                 .v1_blank = {0x16, 0x00},
645                 .v_line = {0x65, 0x04},
646                 .h_line = {0x50, 0x0a},
647                 .hsync_pol = {0x00},
648                 .vsync_pol = {0x00},
649                 .int_pro_mode = {0x01},
650                 .v_blank_f0 = {0x49, 0x02},
651                 .v_blank_f1 = {0x65, 0x04},
652                 .h_sync_start = {0x0e, 0x02},
653                 .h_sync_end = {0x3a, 0x02},
654                 .v_sync_line_bef_2 = {0x07, 0x00},
655                 .v_sync_line_bef_1 = {0x02, 0x00},
656                 .v_sync_line_aft_2 = {0x39, 0x02},
657                 .v_sync_line_aft_1 = {0x34, 0x02},
658                 .v_sync_line_aft_pxl_2 = {0x38, 0x07},
659                 .v_sync_line_aft_pxl_1 = {0x38, 0x07},
660                 .v_blank_f2 = {0xff, 0xff},
661                 .v_blank_f3 = {0xff, 0xff},
662                 .v_blank_f4 = {0xff, 0xff},
663                 .v_blank_f5 = {0xff, 0xff},
664                 .v_sync_line_aft_3 = {0xff, 0xff},
665                 .v_sync_line_aft_4 = {0xff, 0xff},
666                 .v_sync_line_aft_5 = {0xff, 0xff},
667                 .v_sync_line_aft_6 = {0xff, 0xff},
668                 .v_sync_line_aft_pxl_3 = {0xff, 0xff},
669                 .v_sync_line_aft_pxl_4 = {0xff, 0xff},
670                 .v_sync_line_aft_pxl_5 = {0xff, 0xff},
671                 .v_sync_line_aft_pxl_6 = {0xff, 0xff},
672                 .vact_space_1 = {0xff, 0xff},
673                 .vact_space_2 = {0xff, 0xff},
674                 .vact_space_3 = {0xff, 0xff},
675                 .vact_space_4 = {0xff, 0xff},
676                 .vact_space_5 = {0xff, 0xff},
677                 .vact_space_6 = {0xff, 0xff},
678                 /* other don't care */
679         },
680         .tg = {
681                 0x00, /* cmd */
682                 0x50, 0x0a, /* h_fsz */
683                 0xd0, 0x02, 0x80, 0x07, /* hact */
684                 0x65, 0x04, /* v_fsz */
685                 0x01, 0x00, 0x33, 0x02, /* vsync */
686                 0x16, 0x00, 0x1c, 0x02, /* vact */
687                 0x33, 0x02, /* field_chg */
688                 0x49, 0x02, /* vact_st2 */
689                 0x00, 0x00, /* vact_st3 */
690                 0x00, 0x00, /* vact_st4 */
691                 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
692                 0x01, 0x00, 0x33, 0x02, /* field top/bot */
693                 0x00, /* 3d FP */
694         },
695 };
696
697 static const struct hdmi_preset_conf hdmi_conf_1080i60 = {
698         .core = {
699                 .h_blank = {0x18, 0x01},
700                 .v2_blank = {0x32, 0x02},
701                 .v1_blank = {0x16, 0x00},
702                 .v_line = {0x65, 0x04},
703                 .h_line = {0x98, 0x08},
704                 .hsync_pol = {0x00},
705                 .vsync_pol = {0x00},
706                 .int_pro_mode = {0x01},
707                 .v_blank_f0 = {0x49, 0x02},
708                 .v_blank_f1 = {0x65, 0x04},
709                 .h_sync_start = {0x56, 0x00},
710                 .h_sync_end = {0x82, 0x00},
711                 .v_sync_line_bef_2 = {0x07, 0x00},
712                 .v_sync_line_bef_1 = {0x02, 0x00},
713                 .v_sync_line_aft_2 = {0x39, 0x02},
714                 .v_sync_line_aft_1 = {0x34, 0x02},
715                 .v_sync_line_aft_pxl_2 = {0xa4, 0x04},
716                 .v_sync_line_aft_pxl_1 = {0xa4, 0x04},
717                 .v_blank_f2 = {0xff, 0xff},
718                 .v_blank_f3 = {0xff, 0xff},
719                 .v_blank_f4 = {0xff, 0xff},
720                 .v_blank_f5 = {0xff, 0xff},
721                 .v_sync_line_aft_3 = {0xff, 0xff},
722                 .v_sync_line_aft_4 = {0xff, 0xff},
723                 .v_sync_line_aft_5 = {0xff, 0xff},
724                 .v_sync_line_aft_6 = {0xff, 0xff},
725                 .v_sync_line_aft_pxl_3 = {0xff, 0xff},
726                 .v_sync_line_aft_pxl_4 = {0xff, 0xff},
727                 .v_sync_line_aft_pxl_5 = {0xff, 0xff},
728                 .v_sync_line_aft_pxl_6 = {0xff, 0xff},
729                 .vact_space_1 = {0xff, 0xff},
730                 .vact_space_2 = {0xff, 0xff},
731                 .vact_space_3 = {0xff, 0xff},
732                 .vact_space_4 = {0xff, 0xff},
733                 .vact_space_5 = {0xff, 0xff},
734                 .vact_space_6 = {0xff, 0xff},
735                 /* other don't care */
736         },
737         .tg = {
738                 0x00, /* cmd */
739                 0x98, 0x08, /* h_fsz */
740                 0x18, 0x01, 0x80, 0x07, /* hact */
741                 0x65, 0x04, /* v_fsz */
742                 0x01, 0x00, 0x33, 0x02, /* vsync */
743                 0x16, 0x00, 0x1c, 0x02, /* vact */
744                 0x33, 0x02, /* field_chg */
745                 0x49, 0x02, /* vact_st2 */
746                 0x00, 0x00, /* vact_st3 */
747                 0x00, 0x00, /* vact_st4 */
748                 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
749                 0x01, 0x00, 0x33, 0x02, /* field top/bot */
750                 0x00, /* 3d FP */
751         },
752 };
753
754 static const struct hdmi_preset_conf hdmi_conf_1080p50 = {
755         .core = {
756                 .h_blank = {0xd0, 0x02},
757                 .v2_blank = {0x65, 0x04},
758                 .v1_blank = {0x2d, 0x00},
759                 .v_line = {0x65, 0x04},
760                 .h_line = {0x50, 0x0a},
761                 .hsync_pol = {0x00},
762                 .vsync_pol = {0x00},
763                 .int_pro_mode = {0x00},
764                 .v_blank_f0 = {0xff, 0xff},
765                 .v_blank_f1 = {0xff, 0xff},
766                 .h_sync_start = {0x0e, 0x02},
767                 .h_sync_end = {0x3a, 0x02},
768                 .v_sync_line_bef_2 = {0x09, 0x00},
769                 .v_sync_line_bef_1 = {0x04, 0x00},
770                 .v_sync_line_aft_2 = {0xff, 0xff},
771                 .v_sync_line_aft_1 = {0xff, 0xff},
772                 .v_sync_line_aft_pxl_2 = {0xff, 0xff},
773                 .v_sync_line_aft_pxl_1 = {0xff, 0xff},
774                 .v_blank_f2 = {0xff, 0xff},
775                 .v_blank_f3 = {0xff, 0xff},
776                 .v_blank_f4 = {0xff, 0xff},
777                 .v_blank_f5 = {0xff, 0xff},
778                 .v_sync_line_aft_3 = {0xff, 0xff},
779                 .v_sync_line_aft_4 = {0xff, 0xff},
780                 .v_sync_line_aft_5 = {0xff, 0xff},
781                 .v_sync_line_aft_6 = {0xff, 0xff},
782                 .v_sync_line_aft_pxl_3 = {0xff, 0xff},
783                 .v_sync_line_aft_pxl_4 = {0xff, 0xff},
784                 .v_sync_line_aft_pxl_5 = {0xff, 0xff},
785                 .v_sync_line_aft_pxl_6 = {0xff, 0xff},
786                 .vact_space_1 = {0xff, 0xff},
787                 .vact_space_2 = {0xff, 0xff},
788                 .vact_space_3 = {0xff, 0xff},
789                 .vact_space_4 = {0xff, 0xff},
790                 .vact_space_5 = {0xff, 0xff},
791                 .vact_space_6 = {0xff, 0xff},
792                 /* other don't care */
793         },
794         .tg = {
795                 0x00, /* cmd */
796                 0x50, 0x0a, /* h_fsz */
797                 0xd0, 0x02, 0x80, 0x07, /* hact */
798                 0x65, 0x04, /* v_fsz */
799                 0x01, 0x00, 0x33, 0x02, /* vsync */
800                 0x2d, 0x00, 0x38, 0x04, /* vact */
801                 0x33, 0x02, /* field_chg */
802                 0x48, 0x02, /* vact_st2 */
803                 0x00, 0x00, /* vact_st3 */
804                 0x00, 0x00, /* vact_st4 */
805                 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
806                 0x01, 0x00, 0x33, 0x02, /* field top/bot */
807                 0x00, /* 3d FP */
808         },
809 };
810
811 static const struct hdmi_preset_conf hdmi_conf_1080p60 = {
812         .core = {
813                 .h_blank = {0x18, 0x01},
814                 .v2_blank = {0x65, 0x04},
815                 .v1_blank = {0x2d, 0x00},
816                 .v_line = {0x65, 0x04},
817                 .h_line = {0x98, 0x08},
818                 .hsync_pol = {0x00},
819                 .vsync_pol = {0x00},
820                 .int_pro_mode = {0x00},
821                 .v_blank_f0 = {0xff, 0xff},
822                 .v_blank_f1 = {0xff, 0xff},
823                 .h_sync_start = {0x56, 0x00},
824                 .h_sync_end = {0x82, 0x00},
825                 .v_sync_line_bef_2 = {0x09, 0x00},
826                 .v_sync_line_bef_1 = {0x04, 0x00},
827                 .v_sync_line_aft_2 = {0xff, 0xff},
828                 .v_sync_line_aft_1 = {0xff, 0xff},
829                 .v_sync_line_aft_pxl_2 = {0xff, 0xff},
830                 .v_sync_line_aft_pxl_1 = {0xff, 0xff},
831                 .v_blank_f2 = {0xff, 0xff},
832                 .v_blank_f3 = {0xff, 0xff},
833                 .v_blank_f4 = {0xff, 0xff},
834                 .v_blank_f5 = {0xff, 0xff},
835                 .v_sync_line_aft_3 = {0xff, 0xff},
836                 .v_sync_line_aft_4 = {0xff, 0xff},
837                 .v_sync_line_aft_5 = {0xff, 0xff},
838                 .v_sync_line_aft_6 = {0xff, 0xff},
839                 .v_sync_line_aft_pxl_3 = {0xff, 0xff},
840                 .v_sync_line_aft_pxl_4 = {0xff, 0xff},
841                 .v_sync_line_aft_pxl_5 = {0xff, 0xff},
842                 .v_sync_line_aft_pxl_6 = {0xff, 0xff},
843                 /* other don't care */
844         },
845         .tg = {
846                 0x00, /* cmd */
847                 0x98, 0x08, /* h_fsz */
848                 0x18, 0x01, 0x80, 0x07, /* hact */
849                 0x65, 0x04, /* v_fsz */
850                 0x01, 0x00, 0x33, 0x02, /* vsync */
851                 0x2d, 0x00, 0x38, 0x04, /* vact */
852                 0x33, 0x02, /* field_chg */
853                 0x48, 0x02, /* vact_st2 */
854                 0x00, 0x00, /* vact_st3 */
855                 0x00, 0x00, /* vact_st4 */
856                 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
857                 0x01, 0x00, 0x33, 0x02, /* field top/bot */
858                 0x00, /* 3d FP */
859         },
860 };
861
862 static const struct hdmi_conf hdmi_confs[] = {
863         { 720, 480, 60, false, hdmiphy_conf27_027, &hdmi_conf_480p60 },
864         { 1280, 720, 50, false, hdmiphy_conf74_25, &hdmi_conf_720p50 },
865         { 1280, 720, 60, false, hdmiphy_conf74_25, &hdmi_conf_720p60 },
866         { 1920, 1080, 50, true, hdmiphy_conf74_25, &hdmi_conf_1080i50 },
867         { 1920, 1080, 60, true, hdmiphy_conf74_25, &hdmi_conf_1080i60 },
868         { 1920, 1080, 50, false, hdmiphy_conf148_5, &hdmi_conf_1080p50 },
869         { 1920, 1080, 60, false, hdmiphy_conf148_5, &hdmi_conf_1080p60 },
870 };
871
872
873 static inline u32 hdmi_reg_read(struct hdmi_context *hdata, u32 reg_id)
874 {
875         return readl(hdata->regs + reg_id);
876 }
877
878 static inline void hdmi_reg_writeb(struct hdmi_context *hdata,
879                                  u32 reg_id, u8 value)
880 {
881         writeb(value, hdata->regs + reg_id);
882 }
883
884 static inline void hdmi_reg_writemask(struct hdmi_context *hdata,
885                                  u32 reg_id, u32 value, u32 mask)
886 {
887         u32 old = readl(hdata->regs + reg_id);
888         value = (value & mask) | (old & ~mask);
889         writel(value, hdata->regs + reg_id);
890 }
891
892 static void hdmi_v13_regs_dump(struct hdmi_context *hdata, char *prefix)
893 {
894 #define DUMPREG(reg_id) \
895         DRM_DEBUG_KMS("%s:" #reg_id " = %08x\n", prefix, \
896         readl(hdata->regs + reg_id))
897         DRM_DEBUG_KMS("%s: ---- CONTROL REGISTERS ----\n", prefix);
898         DUMPREG(HDMI_INTC_FLAG);
899         DUMPREG(HDMI_INTC_CON);
900         DUMPREG(HDMI_HPD_STATUS);
901         DUMPREG(HDMI_V13_PHY_RSTOUT);
902         DUMPREG(HDMI_V13_PHY_VPLL);
903         DUMPREG(HDMI_V13_PHY_CMU);
904         DUMPREG(HDMI_V13_CORE_RSTOUT);
905
906         DRM_DEBUG_KMS("%s: ---- CORE REGISTERS ----\n", prefix);
907         DUMPREG(HDMI_CON_0);
908         DUMPREG(HDMI_CON_1);
909         DUMPREG(HDMI_CON_2);
910         DUMPREG(HDMI_SYS_STATUS);
911         DUMPREG(HDMI_V13_PHY_STATUS);
912         DUMPREG(HDMI_STATUS_EN);
913         DUMPREG(HDMI_HPD);
914         DUMPREG(HDMI_MODE_SEL);
915         DUMPREG(HDMI_V13_HPD_GEN);
916         DUMPREG(HDMI_V13_DC_CONTROL);
917         DUMPREG(HDMI_V13_VIDEO_PATTERN_GEN);
918
919         DRM_DEBUG_KMS("%s: ---- CORE SYNC REGISTERS ----\n", prefix);
920         DUMPREG(HDMI_H_BLANK_0);
921         DUMPREG(HDMI_H_BLANK_1);
922         DUMPREG(HDMI_V13_V_BLANK_0);
923         DUMPREG(HDMI_V13_V_BLANK_1);
924         DUMPREG(HDMI_V13_V_BLANK_2);
925         DUMPREG(HDMI_V13_H_V_LINE_0);
926         DUMPREG(HDMI_V13_H_V_LINE_1);
927         DUMPREG(HDMI_V13_H_V_LINE_2);
928         DUMPREG(HDMI_VSYNC_POL);
929         DUMPREG(HDMI_INT_PRO_MODE);
930         DUMPREG(HDMI_V13_V_BLANK_F_0);
931         DUMPREG(HDMI_V13_V_BLANK_F_1);
932         DUMPREG(HDMI_V13_V_BLANK_F_2);
933         DUMPREG(HDMI_V13_H_SYNC_GEN_0);
934         DUMPREG(HDMI_V13_H_SYNC_GEN_1);
935         DUMPREG(HDMI_V13_H_SYNC_GEN_2);
936         DUMPREG(HDMI_V13_V_SYNC_GEN_1_0);
937         DUMPREG(HDMI_V13_V_SYNC_GEN_1_1);
938         DUMPREG(HDMI_V13_V_SYNC_GEN_1_2);
939         DUMPREG(HDMI_V13_V_SYNC_GEN_2_0);
940         DUMPREG(HDMI_V13_V_SYNC_GEN_2_1);
941         DUMPREG(HDMI_V13_V_SYNC_GEN_2_2);
942         DUMPREG(HDMI_V13_V_SYNC_GEN_3_0);
943         DUMPREG(HDMI_V13_V_SYNC_GEN_3_1);
944         DUMPREG(HDMI_V13_V_SYNC_GEN_3_2);
945
946         DRM_DEBUG_KMS("%s: ---- TG REGISTERS ----\n", prefix);
947         DUMPREG(HDMI_TG_CMD);
948         DUMPREG(HDMI_TG_H_FSZ_L);
949         DUMPREG(HDMI_TG_H_FSZ_H);
950         DUMPREG(HDMI_TG_HACT_ST_L);
951         DUMPREG(HDMI_TG_HACT_ST_H);
952         DUMPREG(HDMI_TG_HACT_SZ_L);
953         DUMPREG(HDMI_TG_HACT_SZ_H);
954         DUMPREG(HDMI_TG_V_FSZ_L);
955         DUMPREG(HDMI_TG_V_FSZ_H);
956         DUMPREG(HDMI_TG_VSYNC_L);
957         DUMPREG(HDMI_TG_VSYNC_H);
958         DUMPREG(HDMI_TG_VSYNC2_L);
959         DUMPREG(HDMI_TG_VSYNC2_H);
960         DUMPREG(HDMI_TG_VACT_ST_L);
961         DUMPREG(HDMI_TG_VACT_ST_H);
962         DUMPREG(HDMI_TG_VACT_SZ_L);
963         DUMPREG(HDMI_TG_VACT_SZ_H);
964         DUMPREG(HDMI_TG_FIELD_CHG_L);
965         DUMPREG(HDMI_TG_FIELD_CHG_H);
966         DUMPREG(HDMI_TG_VACT_ST2_L);
967         DUMPREG(HDMI_TG_VACT_ST2_H);
968         DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_L);
969         DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_H);
970         DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_L);
971         DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_H);
972         DUMPREG(HDMI_TG_FIELD_TOP_HDMI_L);
973         DUMPREG(HDMI_TG_FIELD_TOP_HDMI_H);
974         DUMPREG(HDMI_TG_FIELD_BOT_HDMI_L);
975         DUMPREG(HDMI_TG_FIELD_BOT_HDMI_H);
976 #undef DUMPREG
977 }
978
979 static void hdmi_v14_regs_dump(struct hdmi_context *hdata, char *prefix)
980 {
981         int i;
982
983 #define DUMPREG(reg_id) \
984         DRM_DEBUG_KMS("%s:" #reg_id " = %08x\n", prefix, \
985         readl(hdata->regs + reg_id))
986
987         DRM_DEBUG_KMS("%s: ---- CONTROL REGISTERS ----\n", prefix);
988         DUMPREG(HDMI_INTC_CON);
989         DUMPREG(HDMI_INTC_FLAG);
990         DUMPREG(HDMI_HPD_STATUS);
991         DUMPREG(HDMI_INTC_CON_1);
992         DUMPREG(HDMI_INTC_FLAG_1);
993         DUMPREG(HDMI_PHY_STATUS_0);
994         DUMPREG(HDMI_PHY_STATUS_PLL);
995         DUMPREG(HDMI_PHY_CON_0);
996         DUMPREG(HDMI_PHY_RSTOUT);
997         DUMPREG(HDMI_PHY_VPLL);
998         DUMPREG(HDMI_PHY_CMU);
999         DUMPREG(HDMI_CORE_RSTOUT);
1000
1001         DRM_DEBUG_KMS("%s: ---- CORE REGISTERS ----\n", prefix);
1002         DUMPREG(HDMI_CON_0);
1003         DUMPREG(HDMI_CON_1);
1004         DUMPREG(HDMI_CON_2);
1005         DUMPREG(HDMI_SYS_STATUS);
1006         DUMPREG(HDMI_PHY_STATUS_0);
1007         DUMPREG(HDMI_STATUS_EN);
1008         DUMPREG(HDMI_HPD);
1009         DUMPREG(HDMI_MODE_SEL);
1010         DUMPREG(HDMI_ENC_EN);
1011         DUMPREG(HDMI_DC_CONTROL);
1012         DUMPREG(HDMI_VIDEO_PATTERN_GEN);
1013
1014         DRM_DEBUG_KMS("%s: ---- CORE SYNC REGISTERS ----\n", prefix);
1015         DUMPREG(HDMI_H_BLANK_0);
1016         DUMPREG(HDMI_H_BLANK_1);
1017         DUMPREG(HDMI_V2_BLANK_0);
1018         DUMPREG(HDMI_V2_BLANK_1);
1019         DUMPREG(HDMI_V1_BLANK_0);
1020         DUMPREG(HDMI_V1_BLANK_1);
1021         DUMPREG(HDMI_V_LINE_0);
1022         DUMPREG(HDMI_V_LINE_1);
1023         DUMPREG(HDMI_H_LINE_0);
1024         DUMPREG(HDMI_H_LINE_1);
1025         DUMPREG(HDMI_HSYNC_POL);
1026
1027         DUMPREG(HDMI_VSYNC_POL);
1028         DUMPREG(HDMI_INT_PRO_MODE);
1029         DUMPREG(HDMI_V_BLANK_F0_0);
1030         DUMPREG(HDMI_V_BLANK_F0_1);
1031         DUMPREG(HDMI_V_BLANK_F1_0);
1032         DUMPREG(HDMI_V_BLANK_F1_1);
1033
1034         DUMPREG(HDMI_H_SYNC_START_0);
1035         DUMPREG(HDMI_H_SYNC_START_1);
1036         DUMPREG(HDMI_H_SYNC_END_0);
1037         DUMPREG(HDMI_H_SYNC_END_1);
1038
1039         DUMPREG(HDMI_V_SYNC_LINE_BEF_2_0);
1040         DUMPREG(HDMI_V_SYNC_LINE_BEF_2_1);
1041         DUMPREG(HDMI_V_SYNC_LINE_BEF_1_0);
1042         DUMPREG(HDMI_V_SYNC_LINE_BEF_1_1);
1043
1044         DUMPREG(HDMI_V_SYNC_LINE_AFT_2_0);
1045         DUMPREG(HDMI_V_SYNC_LINE_AFT_2_1);
1046         DUMPREG(HDMI_V_SYNC_LINE_AFT_1_0);
1047         DUMPREG(HDMI_V_SYNC_LINE_AFT_1_1);
1048
1049         DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_2_0);
1050         DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_2_1);
1051         DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_1_0);
1052         DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_1_1);
1053
1054         DUMPREG(HDMI_V_BLANK_F2_0);
1055         DUMPREG(HDMI_V_BLANK_F2_1);
1056         DUMPREG(HDMI_V_BLANK_F3_0);
1057         DUMPREG(HDMI_V_BLANK_F3_1);
1058         DUMPREG(HDMI_V_BLANK_F4_0);
1059         DUMPREG(HDMI_V_BLANK_F4_1);
1060         DUMPREG(HDMI_V_BLANK_F5_0);
1061         DUMPREG(HDMI_V_BLANK_F5_1);
1062
1063         DUMPREG(HDMI_V_SYNC_LINE_AFT_3_0);
1064         DUMPREG(HDMI_V_SYNC_LINE_AFT_3_1);
1065         DUMPREG(HDMI_V_SYNC_LINE_AFT_4_0);
1066         DUMPREG(HDMI_V_SYNC_LINE_AFT_4_1);
1067         DUMPREG(HDMI_V_SYNC_LINE_AFT_5_0);
1068         DUMPREG(HDMI_V_SYNC_LINE_AFT_5_1);
1069         DUMPREG(HDMI_V_SYNC_LINE_AFT_6_0);
1070         DUMPREG(HDMI_V_SYNC_LINE_AFT_6_1);
1071
1072         DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_3_0);
1073         DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_3_1);
1074         DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_4_0);
1075         DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_4_1);
1076         DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_5_0);
1077         DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_5_1);
1078         DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_6_0);
1079         DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_6_1);
1080
1081         DUMPREG(HDMI_VACT_SPACE_1_0);
1082         DUMPREG(HDMI_VACT_SPACE_1_1);
1083         DUMPREG(HDMI_VACT_SPACE_2_0);
1084         DUMPREG(HDMI_VACT_SPACE_2_1);
1085         DUMPREG(HDMI_VACT_SPACE_3_0);
1086         DUMPREG(HDMI_VACT_SPACE_3_1);
1087         DUMPREG(HDMI_VACT_SPACE_4_0);
1088         DUMPREG(HDMI_VACT_SPACE_4_1);
1089         DUMPREG(HDMI_VACT_SPACE_5_0);
1090         DUMPREG(HDMI_VACT_SPACE_5_1);
1091         DUMPREG(HDMI_VACT_SPACE_6_0);
1092         DUMPREG(HDMI_VACT_SPACE_6_1);
1093
1094         DRM_DEBUG_KMS("%s: ---- TG REGISTERS ----\n", prefix);
1095         DUMPREG(HDMI_TG_CMD);
1096         DUMPREG(HDMI_TG_H_FSZ_L);
1097         DUMPREG(HDMI_TG_H_FSZ_H);
1098         DUMPREG(HDMI_TG_HACT_ST_L);
1099         DUMPREG(HDMI_TG_HACT_ST_H);
1100         DUMPREG(HDMI_TG_HACT_SZ_L);
1101         DUMPREG(HDMI_TG_HACT_SZ_H);
1102         DUMPREG(HDMI_TG_V_FSZ_L);
1103         DUMPREG(HDMI_TG_V_FSZ_H);
1104         DUMPREG(HDMI_TG_VSYNC_L);
1105         DUMPREG(HDMI_TG_VSYNC_H);
1106         DUMPREG(HDMI_TG_VSYNC2_L);
1107         DUMPREG(HDMI_TG_VSYNC2_H);
1108         DUMPREG(HDMI_TG_VACT_ST_L);
1109         DUMPREG(HDMI_TG_VACT_ST_H);
1110         DUMPREG(HDMI_TG_VACT_SZ_L);
1111         DUMPREG(HDMI_TG_VACT_SZ_H);
1112         DUMPREG(HDMI_TG_FIELD_CHG_L);
1113         DUMPREG(HDMI_TG_FIELD_CHG_H);
1114         DUMPREG(HDMI_TG_VACT_ST2_L);
1115         DUMPREG(HDMI_TG_VACT_ST2_H);
1116         DUMPREG(HDMI_TG_VACT_ST3_L);
1117         DUMPREG(HDMI_TG_VACT_ST3_H);
1118         DUMPREG(HDMI_TG_VACT_ST4_L);
1119         DUMPREG(HDMI_TG_VACT_ST4_H);
1120         DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_L);
1121         DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_H);
1122         DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_L);
1123         DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_H);
1124         DUMPREG(HDMI_TG_FIELD_TOP_HDMI_L);
1125         DUMPREG(HDMI_TG_FIELD_TOP_HDMI_H);
1126         DUMPREG(HDMI_TG_FIELD_BOT_HDMI_L);
1127         DUMPREG(HDMI_TG_FIELD_BOT_HDMI_H);
1128         DUMPREG(HDMI_TG_3D);
1129
1130         DRM_DEBUG_KMS("%s: ---- PACKET REGISTERS ----\n", prefix);
1131         DUMPREG(HDMI_AVI_CON);
1132         DUMPREG(HDMI_AVI_HEADER0);
1133         DUMPREG(HDMI_AVI_HEADER1);
1134         DUMPREG(HDMI_AVI_HEADER2);
1135         DUMPREG(HDMI_AVI_CHECK_SUM);
1136         DUMPREG(HDMI_VSI_CON);
1137         DUMPREG(HDMI_VSI_HEADER0);
1138         DUMPREG(HDMI_VSI_HEADER1);
1139         DUMPREG(HDMI_VSI_HEADER2);
1140         for (i = 0; i < 7; ++i)
1141                 DUMPREG(HDMI_VSI_DATA(i));
1142
1143 #undef DUMPREG
1144 }
1145
1146 static void hdmi_regs_dump(struct hdmi_context *hdata, char *prefix)
1147 {
1148         if (hdata->is_v13)
1149                 hdmi_v13_regs_dump(hdata, prefix);
1150         else
1151                 hdmi_v14_regs_dump(hdata, prefix);
1152 }
1153
1154 static int hdmi_v13_conf_index(struct drm_display_mode *mode)
1155 {
1156         int i;
1157
1158         for (i = 0; i < ARRAY_SIZE(hdmi_v13_confs); ++i)
1159                 if (hdmi_v13_confs[i].width == mode->hdisplay &&
1160                                 hdmi_v13_confs[i].height == mode->vdisplay &&
1161                                 hdmi_v13_confs[i].vrefresh == mode->vrefresh &&
1162                                 hdmi_v13_confs[i].interlace ==
1163                                 ((mode->flags & DRM_MODE_FLAG_INTERLACE) ?
1164                                  true : false))
1165                         return i;
1166
1167         return -EINVAL;
1168 }
1169
1170 static int hdmi_v14_conf_index(struct drm_display_mode *mode)
1171 {
1172         int i;
1173
1174         for (i = 0; i < ARRAY_SIZE(hdmi_confs); ++i)
1175                 if (hdmi_confs[i].width == mode->hdisplay &&
1176                                 hdmi_confs[i].height == mode->vdisplay &&
1177                                 hdmi_confs[i].vrefresh == mode->vrefresh &&
1178                                 hdmi_confs[i].interlace ==
1179                                 ((mode->flags & DRM_MODE_FLAG_INTERLACE) ?
1180                                  true : false))
1181                         return i;
1182
1183         return -EINVAL;
1184 }
1185
1186 static int hdmi_conf_index(struct hdmi_context *hdata,
1187                            struct drm_display_mode *mode)
1188 {
1189         if (hdata->is_v13)
1190                 return hdmi_v13_conf_index(mode);
1191
1192         return hdmi_v14_conf_index(mode);
1193 }
1194
1195 static bool hdmi_is_connected(void *ctx)
1196 {
1197         struct hdmi_context *hdata = (struct hdmi_context *)ctx;
1198         u32 val = hdmi_reg_read(hdata, HDMI_HPD_STATUS);
1199
1200         if (val)
1201                 return true;
1202
1203         return false;
1204 }
1205
1206 static int hdmi_get_edid(void *ctx, struct drm_connector *connector,
1207                                 u8 *edid, int len)
1208 {
1209         struct edid *raw_edid;
1210         struct hdmi_context *hdata = (struct hdmi_context *)ctx;
1211
1212         DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1213
1214         if (!hdata->ddc_port)
1215                 return -ENODEV;
1216
1217         raw_edid = drm_get_edid(connector, hdata->ddc_port->adapter);
1218         if (raw_edid) {
1219                 memcpy(edid, raw_edid, min((1 + raw_edid->extensions)
1220                                         * EDID_LENGTH, len));
1221                 DRM_DEBUG_KMS("width[%d] x height[%d]\n",
1222                                 raw_edid->width_cm, raw_edid->height_cm);
1223         } else {
1224                 return -ENODEV;
1225         }
1226
1227         return 0;
1228 }
1229
1230 static int hdmi_v13_check_timing(struct fb_videomode *check_timing)
1231 {
1232         int i;
1233
1234         DRM_DEBUG_KMS("valid mode : xres=%d, yres=%d, refresh=%d, intl=%d\n",
1235                         check_timing->xres, check_timing->yres,
1236                         check_timing->refresh, (check_timing->vmode &
1237                         FB_VMODE_INTERLACED) ? true : false);
1238
1239         for (i = 0; i < ARRAY_SIZE(hdmi_v13_confs); ++i)
1240                 if (hdmi_v13_confs[i].width == check_timing->xres &&
1241                         hdmi_v13_confs[i].height == check_timing->yres &&
1242                         hdmi_v13_confs[i].vrefresh == check_timing->refresh &&
1243                         hdmi_v13_confs[i].interlace ==
1244                         ((check_timing->vmode & FB_VMODE_INTERLACED) ?
1245                          true : false))
1246                                 return 0;
1247
1248         /* TODO */
1249
1250         return -EINVAL;
1251 }
1252
1253 static int hdmi_v14_check_timing(struct fb_videomode *check_timing)
1254 {
1255         int i;
1256
1257         DRM_DEBUG_KMS("valid mode : xres=%d, yres=%d, refresh=%d, intl=%d\n",
1258                         check_timing->xres, check_timing->yres,
1259                         check_timing->refresh, (check_timing->vmode &
1260                         FB_VMODE_INTERLACED) ? true : false);
1261
1262         for (i = 0; i < ARRAY_SIZE(hdmi_confs); i++)
1263                 if (hdmi_confs[i].width == check_timing->xres &&
1264                         hdmi_confs[i].height == check_timing->yres &&
1265                         hdmi_confs[i].vrefresh == check_timing->refresh &&
1266                         hdmi_confs[i].interlace ==
1267                         ((check_timing->vmode & FB_VMODE_INTERLACED) ?
1268                          true : false))
1269                                 return 0;
1270
1271         /* TODO */
1272
1273         return -EINVAL;
1274 }
1275
1276 static int hdmi_check_timing(void *ctx, void *timing)
1277 {
1278         struct hdmi_context *hdata = (struct hdmi_context *)ctx;
1279         struct fb_videomode *check_timing = timing;
1280
1281         DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1282
1283         DRM_DEBUG_KMS("[%d]x[%d] [%d]Hz [%x]\n", check_timing->xres,
1284                         check_timing->yres, check_timing->refresh,
1285                         check_timing->vmode);
1286
1287         if (hdata->is_v13)
1288                 return hdmi_v13_check_timing(check_timing);
1289         else
1290                 return hdmi_v14_check_timing(check_timing);
1291 }
1292
1293 static int hdmi_display_power_on(void *ctx, int mode)
1294 {
1295         DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1296
1297         switch (mode) {
1298         case DRM_MODE_DPMS_ON:
1299                 DRM_DEBUG_KMS("hdmi [on]\n");
1300                 break;
1301         case DRM_MODE_DPMS_STANDBY:
1302                 break;
1303         case DRM_MODE_DPMS_SUSPEND:
1304                 break;
1305         case DRM_MODE_DPMS_OFF:
1306                 DRM_DEBUG_KMS("hdmi [off]\n");
1307                 break;
1308         default:
1309                 break;
1310         }
1311
1312         return 0;
1313 }
1314
1315 static struct exynos_hdmi_display_ops display_ops = {
1316         .is_connected   = hdmi_is_connected,
1317         .get_edid       = hdmi_get_edid,
1318         .check_timing   = hdmi_check_timing,
1319         .power_on       = hdmi_display_power_on,
1320 };
1321
1322 static void hdmi_conf_reset(struct hdmi_context *hdata)
1323 {
1324         u32 reg;
1325
1326         /* disable hpd handle for drm */
1327         hdata->hpd_handle = false;
1328
1329         if (hdata->is_v13)
1330                 reg = HDMI_V13_CORE_RSTOUT;
1331         else
1332                 reg = HDMI_CORE_RSTOUT;
1333
1334         /* resetting HDMI core */
1335         hdmi_reg_writemask(hdata, reg,  0, HDMI_CORE_SW_RSTOUT);
1336         mdelay(10);
1337         hdmi_reg_writemask(hdata, reg, ~0, HDMI_CORE_SW_RSTOUT);
1338         mdelay(10);
1339
1340         /* enable hpd handle for drm */
1341         hdata->hpd_handle = true;
1342 }
1343
1344 static void hdmi_conf_init(struct hdmi_context *hdata)
1345 {
1346         /* disable hpd handle for drm */
1347         hdata->hpd_handle = false;
1348
1349         /* enable HPD interrupts */
1350         hdmi_reg_writemask(hdata, HDMI_INTC_CON, 0, HDMI_INTC_EN_GLOBAL |
1351                 HDMI_INTC_EN_HPD_PLUG | HDMI_INTC_EN_HPD_UNPLUG);
1352         mdelay(10);
1353         hdmi_reg_writemask(hdata, HDMI_INTC_CON, ~0, HDMI_INTC_EN_GLOBAL |
1354                 HDMI_INTC_EN_HPD_PLUG | HDMI_INTC_EN_HPD_UNPLUG);
1355
1356         /* choose HDMI mode */
1357         hdmi_reg_writemask(hdata, HDMI_MODE_SEL,
1358                 HDMI_MODE_HDMI_EN, HDMI_MODE_MASK);
1359         /* disable bluescreen */
1360         hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_BLUE_SCR_EN);
1361
1362         if (hdata->is_v13) {
1363                 /* choose bluescreen (fecal) color */
1364                 hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_0, 0x12);
1365                 hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_1, 0x34);
1366                 hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_2, 0x56);
1367
1368                 /* enable AVI packet every vsync, fixes purple line problem */
1369                 hdmi_reg_writeb(hdata, HDMI_V13_AVI_CON, 0x02);
1370                 /* force RGB, look to CEA-861-D, table 7 for more detail */
1371                 hdmi_reg_writeb(hdata, HDMI_V13_AVI_BYTE(0), 0 << 5);
1372                 hdmi_reg_writemask(hdata, HDMI_CON_1, 0x10 << 5, 0x11 << 5);
1373
1374                 hdmi_reg_writeb(hdata, HDMI_V13_SPD_CON, 0x02);
1375                 hdmi_reg_writeb(hdata, HDMI_V13_AUI_CON, 0x02);
1376                 hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 0x04);
1377         } else {
1378                 /* enable AVI packet every vsync, fixes purple line problem */
1379                 hdmi_reg_writeb(hdata, HDMI_AVI_CON, 0x02);
1380                 hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(1), 2 << 5);
1381                 hdmi_reg_writemask(hdata, HDMI_CON_1, 2, 3 << 5);
1382         }
1383
1384         /* enable hpd handle for drm */
1385         hdata->hpd_handle = true;
1386 }
1387
1388 static void hdmi_v13_timing_apply(struct hdmi_context *hdata)
1389 {
1390         const struct hdmi_v13_preset_conf *conf =
1391                 hdmi_v13_confs[hdata->cur_conf].conf;
1392         const struct hdmi_v13_core_regs *core = &conf->core;
1393         const struct hdmi_v13_tg_regs *tg = &conf->tg;
1394         int tries;
1395
1396         /* setting core registers */
1397         hdmi_reg_writeb(hdata, HDMI_H_BLANK_0, core->h_blank[0]);
1398         hdmi_reg_writeb(hdata, HDMI_H_BLANK_1, core->h_blank[1]);
1399         hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_0, core->v_blank[0]);
1400         hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_1, core->v_blank[1]);
1401         hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_2, core->v_blank[2]);
1402         hdmi_reg_writeb(hdata, HDMI_V13_H_V_LINE_0, core->h_v_line[0]);
1403         hdmi_reg_writeb(hdata, HDMI_V13_H_V_LINE_1, core->h_v_line[1]);
1404         hdmi_reg_writeb(hdata, HDMI_V13_H_V_LINE_2, core->h_v_line[2]);
1405         hdmi_reg_writeb(hdata, HDMI_VSYNC_POL, core->vsync_pol[0]);
1406         hdmi_reg_writeb(hdata, HDMI_INT_PRO_MODE, core->int_pro_mode[0]);
1407         hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_F_0, core->v_blank_f[0]);
1408         hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_F_1, core->v_blank_f[1]);
1409         hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_F_2, core->v_blank_f[2]);
1410         hdmi_reg_writeb(hdata, HDMI_V13_H_SYNC_GEN_0, core->h_sync_gen[0]);
1411         hdmi_reg_writeb(hdata, HDMI_V13_H_SYNC_GEN_1, core->h_sync_gen[1]);
1412         hdmi_reg_writeb(hdata, HDMI_V13_H_SYNC_GEN_2, core->h_sync_gen[2]);
1413         hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_1_0, core->v_sync_gen1[0]);
1414         hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_1_1, core->v_sync_gen1[1]);
1415         hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_1_2, core->v_sync_gen1[2]);
1416         hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_2_0, core->v_sync_gen2[0]);
1417         hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_2_1, core->v_sync_gen2[1]);
1418         hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_2_2, core->v_sync_gen2[2]);
1419         hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_0, core->v_sync_gen3[0]);
1420         hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_1, core->v_sync_gen3[1]);
1421         hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_2, core->v_sync_gen3[2]);
1422         /* Timing generator registers */
1423         hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_L, tg->h_fsz_l);
1424         hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_H, tg->h_fsz_h);
1425         hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_L, tg->hact_st_l);
1426         hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_H, tg->hact_st_h);
1427         hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_L, tg->hact_sz_l);
1428         hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_H, tg->hact_sz_h);
1429         hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_L, tg->v_fsz_l);
1430         hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_H, tg->v_fsz_h);
1431         hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_L, tg->vsync_l);
1432         hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_H, tg->vsync_h);
1433         hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_L, tg->vsync2_l);
1434         hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_H, tg->vsync2_h);
1435         hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_L, tg->vact_st_l);
1436         hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_H, tg->vact_st_h);
1437         hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_L, tg->vact_sz_l);
1438         hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_H, tg->vact_sz_h);
1439         hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_L, tg->field_chg_l);
1440         hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_H, tg->field_chg_h);
1441         hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_L, tg->vact_st2_l);
1442         hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_H, tg->vact_st2_h);
1443         hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_L, tg->vsync_top_hdmi_l);
1444         hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_H, tg->vsync_top_hdmi_h);
1445         hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, tg->vsync_bot_hdmi_l);
1446         hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_H, tg->vsync_bot_hdmi_h);
1447         hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_L, tg->field_top_hdmi_l);
1448         hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_H, tg->field_top_hdmi_h);
1449         hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_L, tg->field_bot_hdmi_l);
1450         hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_H, tg->field_bot_hdmi_h);
1451
1452         /* waiting for HDMIPHY's PLL to get to steady state */
1453         for (tries = 100; tries; --tries) {
1454                 u32 val = hdmi_reg_read(hdata, HDMI_V13_PHY_STATUS);
1455                 if (val & HDMI_PHY_STATUS_READY)
1456                         break;
1457                 mdelay(1);
1458         }
1459         /* steady state not achieved */
1460         if (tries == 0) {
1461                 DRM_ERROR("hdmiphy's pll could not reach steady state.\n");
1462                 hdmi_regs_dump(hdata, "timing apply");
1463         }
1464
1465         clk_disable(hdata->res.sclk_hdmi);
1466         clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_hdmiphy);
1467         clk_enable(hdata->res.sclk_hdmi);
1468
1469         /* enable HDMI and timing generator */
1470         hdmi_reg_writemask(hdata, HDMI_CON_0, ~0, HDMI_EN);
1471         if (core->int_pro_mode[0])
1472                 hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN |
1473                                 HDMI_FIELD_EN);
1474         else
1475                 hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN);
1476 }
1477
1478 static void hdmi_v14_timing_apply(struct hdmi_context *hdata)
1479 {
1480         const struct hdmi_preset_conf *conf = hdmi_confs[hdata->cur_conf].conf;
1481         const struct hdmi_core_regs *core = &conf->core;
1482         const struct hdmi_tg_regs *tg = &conf->tg;
1483         int tries;
1484
1485         /* setting core registers */
1486         hdmi_reg_writeb(hdata, HDMI_H_BLANK_0, core->h_blank[0]);
1487         hdmi_reg_writeb(hdata, HDMI_H_BLANK_1, core->h_blank[1]);
1488         hdmi_reg_writeb(hdata, HDMI_V2_BLANK_0, core->v2_blank[0]);
1489         hdmi_reg_writeb(hdata, HDMI_V2_BLANK_1, core->v2_blank[1]);
1490         hdmi_reg_writeb(hdata, HDMI_V1_BLANK_0, core->v1_blank[0]);
1491         hdmi_reg_writeb(hdata, HDMI_V1_BLANK_1, core->v1_blank[1]);
1492         hdmi_reg_writeb(hdata, HDMI_V_LINE_0, core->v_line[0]);
1493         hdmi_reg_writeb(hdata, HDMI_V_LINE_1, core->v_line[1]);
1494         hdmi_reg_writeb(hdata, HDMI_H_LINE_0, core->h_line[0]);
1495         hdmi_reg_writeb(hdata, HDMI_H_LINE_1, core->h_line[1]);
1496         hdmi_reg_writeb(hdata, HDMI_HSYNC_POL, core->hsync_pol[0]);
1497         hdmi_reg_writeb(hdata, HDMI_VSYNC_POL, core->vsync_pol[0]);
1498         hdmi_reg_writeb(hdata, HDMI_INT_PRO_MODE, core->int_pro_mode[0]);
1499         hdmi_reg_writeb(hdata, HDMI_V_BLANK_F0_0, core->v_blank_f0[0]);
1500         hdmi_reg_writeb(hdata, HDMI_V_BLANK_F0_1, core->v_blank_f0[1]);
1501         hdmi_reg_writeb(hdata, HDMI_V_BLANK_F1_0, core->v_blank_f1[0]);
1502         hdmi_reg_writeb(hdata, HDMI_V_BLANK_F1_1, core->v_blank_f1[1]);
1503         hdmi_reg_writeb(hdata, HDMI_H_SYNC_START_0, core->h_sync_start[0]);
1504         hdmi_reg_writeb(hdata, HDMI_H_SYNC_START_1, core->h_sync_start[1]);
1505         hdmi_reg_writeb(hdata, HDMI_H_SYNC_END_0, core->h_sync_end[0]);
1506         hdmi_reg_writeb(hdata, HDMI_H_SYNC_END_1, core->h_sync_end[1]);
1507         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_2_0,
1508                         core->v_sync_line_bef_2[0]);
1509         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_2_1,
1510                         core->v_sync_line_bef_2[1]);
1511         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_1_0,
1512                         core->v_sync_line_bef_1[0]);
1513         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_1_1,
1514                         core->v_sync_line_bef_1[1]);
1515         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_2_0,
1516                         core->v_sync_line_aft_2[0]);
1517         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_2_1,
1518                         core->v_sync_line_aft_2[1]);
1519         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_1_0,
1520                         core->v_sync_line_aft_1[0]);
1521         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_1_1,
1522                         core->v_sync_line_aft_1[1]);
1523         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_0,
1524                         core->v_sync_line_aft_pxl_2[0]);
1525         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_1,
1526                         core->v_sync_line_aft_pxl_2[1]);
1527         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_0,
1528                         core->v_sync_line_aft_pxl_1[0]);
1529         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_1,
1530                         core->v_sync_line_aft_pxl_1[1]);
1531         hdmi_reg_writeb(hdata, HDMI_V_BLANK_F2_0, core->v_blank_f2[0]);
1532         hdmi_reg_writeb(hdata, HDMI_V_BLANK_F2_1, core->v_blank_f2[1]);
1533         hdmi_reg_writeb(hdata, HDMI_V_BLANK_F3_0, core->v_blank_f3[0]);
1534         hdmi_reg_writeb(hdata, HDMI_V_BLANK_F3_1, core->v_blank_f3[1]);
1535         hdmi_reg_writeb(hdata, HDMI_V_BLANK_F4_0, core->v_blank_f4[0]);
1536         hdmi_reg_writeb(hdata, HDMI_V_BLANK_F4_1, core->v_blank_f4[1]);
1537         hdmi_reg_writeb(hdata, HDMI_V_BLANK_F5_0, core->v_blank_f5[0]);
1538         hdmi_reg_writeb(hdata, HDMI_V_BLANK_F5_1, core->v_blank_f5[1]);
1539         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_3_0,
1540                         core->v_sync_line_aft_3[0]);
1541         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_3_1,
1542                         core->v_sync_line_aft_3[1]);
1543         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_4_0,
1544                         core->v_sync_line_aft_4[0]);
1545         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_4_1,
1546                         core->v_sync_line_aft_4[1]);
1547         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_5_0,
1548                         core->v_sync_line_aft_5[0]);
1549         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_5_1,
1550                         core->v_sync_line_aft_5[1]);
1551         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_6_0,
1552                         core->v_sync_line_aft_6[0]);
1553         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_6_1,
1554                         core->v_sync_line_aft_6[1]);
1555         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_3_0,
1556                         core->v_sync_line_aft_pxl_3[0]);
1557         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_3_1,
1558                         core->v_sync_line_aft_pxl_3[1]);
1559         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_4_0,
1560                         core->v_sync_line_aft_pxl_4[0]);
1561         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_4_1,
1562                         core->v_sync_line_aft_pxl_4[1]);
1563         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_5_0,
1564                         core->v_sync_line_aft_pxl_5[0]);
1565         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_5_1,
1566                         core->v_sync_line_aft_pxl_5[1]);
1567         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_0,
1568                         core->v_sync_line_aft_pxl_6[0]);
1569         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_1,
1570                         core->v_sync_line_aft_pxl_6[1]);
1571         hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_1_0, core->vact_space_1[0]);
1572         hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_1_1, core->vact_space_1[1]);
1573         hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_2_0, core->vact_space_2[0]);
1574         hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_2_1, core->vact_space_2[1]);
1575         hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_3_0, core->vact_space_3[0]);
1576         hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_3_1, core->vact_space_3[1]);
1577         hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_4_0, core->vact_space_4[0]);
1578         hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_4_1, core->vact_space_4[1]);
1579         hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_5_0, core->vact_space_5[0]);
1580         hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_5_1, core->vact_space_5[1]);
1581         hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_6_0, core->vact_space_6[0]);
1582         hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_6_1, core->vact_space_6[1]);
1583
1584         /* Timing generator registers */
1585         hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_L, tg->h_fsz_l);
1586         hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_H, tg->h_fsz_h);
1587         hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_L, tg->hact_st_l);
1588         hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_H, tg->hact_st_h);
1589         hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_L, tg->hact_sz_l);
1590         hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_H, tg->hact_sz_h);
1591         hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_L, tg->v_fsz_l);
1592         hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_H, tg->v_fsz_h);
1593         hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_L, tg->vsync_l);
1594         hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_H, tg->vsync_h);
1595         hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_L, tg->vsync2_l);
1596         hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_H, tg->vsync2_h);
1597         hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_L, tg->vact_st_l);
1598         hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_H, tg->vact_st_h);
1599         hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_L, tg->vact_sz_l);
1600         hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_H, tg->vact_sz_h);
1601         hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_L, tg->field_chg_l);
1602         hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_H, tg->field_chg_h);
1603         hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_L, tg->vact_st2_l);
1604         hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_H, tg->vact_st2_h);
1605         hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST3_L, tg->vact_st3_l);
1606         hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST3_H, tg->vact_st3_h);
1607         hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST4_L, tg->vact_st4_l);
1608         hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST4_H, tg->vact_st4_h);
1609         hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_L, tg->vsync_top_hdmi_l);
1610         hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_H, tg->vsync_top_hdmi_h);
1611         hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, tg->vsync_bot_hdmi_l);
1612         hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_H, tg->vsync_bot_hdmi_h);
1613         hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_L, tg->field_top_hdmi_l);
1614         hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_H, tg->field_top_hdmi_h);
1615         hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_L, tg->field_bot_hdmi_l);
1616         hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_H, tg->field_bot_hdmi_h);
1617         hdmi_reg_writeb(hdata, HDMI_TG_3D, tg->tg_3d);
1618
1619         /* waiting for HDMIPHY's PLL to get to steady state */
1620         for (tries = 100; tries; --tries) {
1621                 u32 val = hdmi_reg_read(hdata, HDMI_PHY_STATUS_0);
1622                 if (val & HDMI_PHY_STATUS_READY)
1623                         break;
1624                 mdelay(1);
1625         }
1626         /* steady state not achieved */
1627         if (tries == 0) {
1628                 DRM_ERROR("hdmiphy's pll could not reach steady state.\n");
1629                 hdmi_regs_dump(hdata, "timing apply");
1630         }
1631
1632         clk_disable(hdata->res.sclk_hdmi);
1633         clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_hdmiphy);
1634         clk_enable(hdata->res.sclk_hdmi);
1635
1636         /* enable HDMI and timing generator */
1637         hdmi_reg_writemask(hdata, HDMI_CON_0, ~0, HDMI_EN);
1638         if (core->int_pro_mode[0])
1639                 hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN |
1640                                 HDMI_FIELD_EN);
1641         else
1642                 hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN);
1643 }
1644
1645 static void hdmi_timing_apply(struct hdmi_context *hdata)
1646 {
1647         if (hdata->is_v13)
1648                 hdmi_v13_timing_apply(hdata);
1649         else
1650                 hdmi_v14_timing_apply(hdata);
1651 }
1652
1653 static void hdmiphy_conf_reset(struct hdmi_context *hdata)
1654 {
1655         u8 buffer[2];
1656         u32 reg;
1657
1658         clk_disable(hdata->res.sclk_hdmi);
1659         clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_pixel);
1660         clk_enable(hdata->res.sclk_hdmi);
1661
1662         /* operation mode */
1663         buffer[0] = 0x1f;
1664         buffer[1] = 0x00;
1665
1666         if (hdata->hdmiphy_port)
1667                 i2c_master_send(hdata->hdmiphy_port, buffer, 2);
1668
1669         if (hdata->is_v13)
1670                 reg = HDMI_V13_PHY_RSTOUT;
1671         else
1672                 reg = HDMI_PHY_RSTOUT;
1673
1674         /* reset hdmiphy */
1675         hdmi_reg_writemask(hdata, reg, ~0, HDMI_PHY_SW_RSTOUT);
1676         mdelay(10);
1677         hdmi_reg_writemask(hdata, reg,  0, HDMI_PHY_SW_RSTOUT);
1678         mdelay(10);
1679 }
1680
1681 static void hdmiphy_conf_apply(struct hdmi_context *hdata)
1682 {
1683         const u8 *hdmiphy_data;
1684         u8 buffer[32];
1685         u8 operation[2];
1686         u8 read_buffer[32] = {0, };
1687         int ret;
1688         int i;
1689
1690         if (!hdata->hdmiphy_port) {
1691                 DRM_ERROR("hdmiphy is not attached\n");
1692                 return;
1693         }
1694
1695         /* pixel clock */
1696         if (hdata->is_v13)
1697                 hdmiphy_data = hdmi_v13_confs[hdata->cur_conf].hdmiphy_data;
1698         else
1699                 hdmiphy_data = hdmi_confs[hdata->cur_conf].hdmiphy_data;
1700
1701         memcpy(buffer, hdmiphy_data, 32);
1702         ret = i2c_master_send(hdata->hdmiphy_port, buffer, 32);
1703         if (ret != 32) {
1704                 DRM_ERROR("failed to configure HDMIPHY via I2C\n");
1705                 return;
1706         }
1707
1708         mdelay(10);
1709
1710         /* operation mode */
1711         operation[0] = 0x1f;
1712         operation[1] = 0x80;
1713
1714         ret = i2c_master_send(hdata->hdmiphy_port, operation, 2);
1715         if (ret != 2) {
1716                 DRM_ERROR("failed to enable hdmiphy\n");
1717                 return;
1718         }
1719
1720         ret = i2c_master_recv(hdata->hdmiphy_port, read_buffer, 32);
1721         if (ret < 0) {
1722                 DRM_ERROR("failed to read hdmiphy config\n");
1723                 return;
1724         }
1725
1726         for (i = 0; i < ret; i++)
1727                 DRM_DEBUG_KMS("hdmiphy[0x%02x] write[0x%02x] - "
1728                         "recv [0x%02x]\n", i, buffer[i], read_buffer[i]);
1729 }
1730
1731 static void hdmi_conf_apply(struct hdmi_context *hdata)
1732 {
1733         DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1734
1735         hdmiphy_conf_reset(hdata);
1736         hdmiphy_conf_apply(hdata);
1737
1738         hdmi_conf_reset(hdata);
1739         hdmi_conf_init(hdata);
1740
1741         /* setting core registers */
1742         hdmi_timing_apply(hdata);
1743
1744         hdmi_regs_dump(hdata, "start");
1745 }
1746
1747 static void hdmi_mode_fixup(void *ctx, struct drm_connector *connector,
1748                                 struct drm_display_mode *mode,
1749                                 struct drm_display_mode *adjusted_mode)
1750 {
1751         struct drm_display_mode *m;
1752         struct hdmi_context *hdata = (struct hdmi_context *)ctx;
1753         int index;
1754
1755         DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1756
1757         drm_mode_set_crtcinfo(adjusted_mode, 0);
1758
1759         if (hdata->is_v13)
1760                 index = hdmi_v13_conf_index(adjusted_mode);
1761         else
1762                 index = hdmi_v14_conf_index(adjusted_mode);
1763
1764         /* just return if user desired mode exists. */
1765         if (index >= 0)
1766                 return;
1767
1768         /*
1769          * otherwise, find the most suitable mode among modes and change it
1770          * to adjusted_mode.
1771          */
1772         list_for_each_entry(m, &connector->modes, head) {
1773                 if (hdata->is_v13)
1774                         index = hdmi_v13_conf_index(m);
1775                 else
1776                         index = hdmi_v14_conf_index(m);
1777
1778                 if (index >= 0) {
1779                         DRM_INFO("desired mode doesn't exist so\n");
1780                         DRM_INFO("use the most suitable mode among modes.\n");
1781                         memcpy(adjusted_mode, m, sizeof(*m));
1782                         break;
1783                 }
1784         }
1785 }
1786
1787 static void hdmi_mode_set(void *ctx, void *mode)
1788 {
1789         struct hdmi_context *hdata = (struct hdmi_context *)ctx;
1790         int conf_idx;
1791
1792         DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1793
1794         conf_idx = hdmi_conf_index(hdata, mode);
1795         if (conf_idx >= 0)
1796                 hdata->cur_conf = conf_idx;
1797         else
1798                 DRM_DEBUG_KMS("not supported mode\n");
1799 }
1800
1801 static void hdmi_get_max_resol(void *ctx, unsigned int *width,
1802                                         unsigned int *height)
1803 {
1804         DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1805
1806         *width = MAX_WIDTH;
1807         *height = MAX_HEIGHT;
1808 }
1809
1810 static void hdmi_commit(void *ctx)
1811 {
1812         struct hdmi_context *hdata = (struct hdmi_context *)ctx;
1813
1814         DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1815
1816         hdmi_conf_apply(hdata);
1817
1818         hdata->enabled = true;
1819 }
1820
1821 static void hdmi_disable(void *ctx)
1822 {
1823         struct hdmi_context *hdata = (struct hdmi_context *)ctx;
1824
1825         DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1826
1827         if (hdata->enabled) {
1828                 hdmiphy_conf_reset(hdata);
1829                 hdmi_conf_reset(hdata);
1830         }
1831 }
1832
1833 static struct exynos_hdmi_manager_ops manager_ops = {
1834         .mode_fixup     = hdmi_mode_fixup,
1835         .mode_set       = hdmi_mode_set,
1836         .get_max_resol  = hdmi_get_max_resol,
1837         .commit         = hdmi_commit,
1838         .disable        = hdmi_disable,
1839 };
1840
1841 /*
1842  * Handle hotplug events outside the interrupt handler proper.
1843  */
1844 static void hdmi_hotplug_func(struct work_struct *work)
1845 {
1846         struct hdmi_context *hdata =
1847                 container_of(work, struct hdmi_context, hotplug_work);
1848         struct exynos_drm_hdmi_context *ctx =
1849                 (struct exynos_drm_hdmi_context *)hdata->parent_ctx;
1850
1851         drm_helper_hpd_irq_event(ctx->drm_dev);
1852 }
1853
1854 static irqreturn_t hdmi_irq_handler(int irq, void *arg)
1855 {
1856         struct exynos_drm_hdmi_context *ctx = arg;
1857         struct hdmi_context *hdata = (struct hdmi_context *)ctx->ctx;
1858         u32 intc_flag;
1859
1860         intc_flag = hdmi_reg_read(hdata, HDMI_INTC_FLAG);
1861         /* clearing flags for HPD plug/unplug */
1862         if (intc_flag & HDMI_INTC_FLAG_HPD_UNPLUG) {
1863                 DRM_DEBUG_KMS("unplugged, handling:%d\n", hdata->hpd_handle);
1864                 hdmi_reg_writemask(hdata, HDMI_INTC_FLAG, ~0,
1865                         HDMI_INTC_FLAG_HPD_UNPLUG);
1866         }
1867         if (intc_flag & HDMI_INTC_FLAG_HPD_PLUG) {
1868                 DRM_DEBUG_KMS("plugged, handling:%d\n", hdata->hpd_handle);
1869                 hdmi_reg_writemask(hdata, HDMI_INTC_FLAG, ~0,
1870                         HDMI_INTC_FLAG_HPD_PLUG);
1871         }
1872
1873         if (ctx->drm_dev && hdata->hpd_handle)
1874                 queue_work(hdata->wq, &hdata->hotplug_work);
1875
1876         return IRQ_HANDLED;
1877 }
1878
1879 static int __devinit hdmi_resources_init(struct hdmi_context *hdata)
1880 {
1881         struct device *dev = hdata->dev;
1882         struct hdmi_resources *res = &hdata->res;
1883         static char *supply[] = {
1884                 "hdmi-en",
1885                 "vdd",
1886                 "vdd_osc",
1887                 "vdd_pll",
1888         };
1889         int i, ret;
1890
1891         DRM_DEBUG_KMS("HDMI resource init\n");
1892
1893         memset(res, 0, sizeof *res);
1894
1895         /* get clocks, power */
1896         res->hdmi = clk_get(dev, "hdmi");
1897         if (IS_ERR_OR_NULL(res->hdmi)) {
1898                 DRM_ERROR("failed to get clock 'hdmi'\n");
1899                 goto fail;
1900         }
1901         res->sclk_hdmi = clk_get(dev, "sclk_hdmi");
1902         if (IS_ERR_OR_NULL(res->sclk_hdmi)) {
1903                 DRM_ERROR("failed to get clock 'sclk_hdmi'\n");
1904                 goto fail;
1905         }
1906         res->sclk_pixel = clk_get(dev, "sclk_pixel");
1907         if (IS_ERR_OR_NULL(res->sclk_pixel)) {
1908                 DRM_ERROR("failed to get clock 'sclk_pixel'\n");
1909                 goto fail;
1910         }
1911         res->sclk_hdmiphy = clk_get(dev, "sclk_hdmiphy");
1912         if (IS_ERR_OR_NULL(res->sclk_hdmiphy)) {
1913                 DRM_ERROR("failed to get clock 'sclk_hdmiphy'\n");
1914                 goto fail;
1915         }
1916         res->hdmiphy = clk_get(dev, "hdmiphy");
1917         if (IS_ERR_OR_NULL(res->hdmiphy)) {
1918                 DRM_ERROR("failed to get clock 'hdmiphy'\n");
1919                 goto fail;
1920         }
1921
1922         clk_set_parent(res->sclk_hdmi, res->sclk_pixel);
1923
1924         res->regul_bulk = kzalloc(ARRAY_SIZE(supply) *
1925                 sizeof res->regul_bulk[0], GFP_KERNEL);
1926         if (!res->regul_bulk) {
1927                 DRM_ERROR("failed to get memory for regulators\n");
1928                 goto fail;
1929         }
1930         for (i = 0; i < ARRAY_SIZE(supply); ++i) {
1931                 res->regul_bulk[i].supply = supply[i];
1932                 res->regul_bulk[i].consumer = NULL;
1933         }
1934         ret = regulator_bulk_get(dev, ARRAY_SIZE(supply), res->regul_bulk);
1935         if (ret) {
1936                 DRM_ERROR("failed to get regulators\n");
1937                 goto fail;
1938         }
1939         res->regul_count = ARRAY_SIZE(supply);
1940
1941         return 0;
1942 fail:
1943         DRM_ERROR("HDMI resource init - failed\n");
1944         return -ENODEV;
1945 }
1946
1947 static int hdmi_resources_cleanup(struct hdmi_context *hdata)
1948 {
1949         struct hdmi_resources *res = &hdata->res;
1950
1951         regulator_bulk_free(res->regul_count, res->regul_bulk);
1952         /* kfree is NULL-safe */
1953         kfree(res->regul_bulk);
1954         if (!IS_ERR_OR_NULL(res->hdmiphy))
1955                 clk_put(res->hdmiphy);
1956         if (!IS_ERR_OR_NULL(res->sclk_hdmiphy))
1957                 clk_put(res->sclk_hdmiphy);
1958         if (!IS_ERR_OR_NULL(res->sclk_pixel))
1959                 clk_put(res->sclk_pixel);
1960         if (!IS_ERR_OR_NULL(res->sclk_hdmi))
1961                 clk_put(res->sclk_hdmi);
1962         if (!IS_ERR_OR_NULL(res->hdmi))
1963                 clk_put(res->hdmi);
1964         memset(res, 0, sizeof *res);
1965
1966         return 0;
1967 }
1968
1969 static void hdmi_resource_poweron(struct hdmi_context *hdata)
1970 {
1971         struct hdmi_resources *res = &hdata->res;
1972
1973         DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1974
1975         /* turn HDMI power on */
1976         regulator_bulk_enable(res->regul_count, res->regul_bulk);
1977         /* power-on hdmi physical interface */
1978         clk_enable(res->hdmiphy);
1979         /* turn clocks on */
1980         clk_enable(res->hdmi);
1981         clk_enable(res->sclk_hdmi);
1982
1983         hdmiphy_conf_reset(hdata);
1984         hdmi_conf_reset(hdata);
1985         hdmi_conf_init(hdata);
1986 }
1987
1988 static void hdmi_resource_poweroff(struct hdmi_context *hdata)
1989 {
1990         struct hdmi_resources *res = &hdata->res;
1991
1992         DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1993
1994         /* turn clocks off */
1995         clk_disable(res->sclk_hdmi);
1996         clk_disable(res->hdmi);
1997         /* power-off hdmiphy */
1998         clk_disable(res->hdmiphy);
1999         /* turn HDMI power off */
2000         regulator_bulk_disable(res->regul_count, res->regul_bulk);
2001 }
2002
2003 static int hdmi_runtime_suspend(struct device *dev)
2004 {
2005         struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev);
2006
2007         DRM_DEBUG_KMS("%s\n", __func__);
2008
2009         hdmi_resource_poweroff((struct hdmi_context *)ctx->ctx);
2010
2011         return 0;
2012 }
2013
2014 static int hdmi_runtime_resume(struct device *dev)
2015 {
2016         struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev);
2017
2018         DRM_DEBUG_KMS("%s\n", __func__);
2019
2020         hdmi_resource_poweron((struct hdmi_context *)ctx->ctx);
2021
2022         return 0;
2023 }
2024
2025 static const struct dev_pm_ops hdmi_pm_ops = {
2026         .runtime_suspend = hdmi_runtime_suspend,
2027         .runtime_resume  = hdmi_runtime_resume,
2028 };
2029
2030 static struct i2c_client *hdmi_ddc, *hdmi_hdmiphy;
2031
2032 void hdmi_attach_ddc_client(struct i2c_client *ddc)
2033 {
2034         if (ddc)
2035                 hdmi_ddc = ddc;
2036 }
2037
2038 void hdmi_attach_hdmiphy_client(struct i2c_client *hdmiphy)
2039 {
2040         if (hdmiphy)
2041                 hdmi_hdmiphy = hdmiphy;
2042 }
2043
2044 static int __devinit hdmi_probe(struct platform_device *pdev)
2045 {
2046         struct device *dev = &pdev->dev;
2047         struct exynos_drm_hdmi_context *drm_hdmi_ctx;
2048         struct hdmi_context *hdata;
2049         struct exynos_drm_hdmi_pdata *pdata;
2050         struct resource *res;
2051         int ret;
2052
2053         DRM_DEBUG_KMS("[%d]\n", __LINE__);
2054
2055         pdata = pdev->dev.platform_data;
2056         if (!pdata) {
2057                 DRM_ERROR("no platform data specified\n");
2058                 return -EINVAL;
2059         }
2060
2061         drm_hdmi_ctx = kzalloc(sizeof(*drm_hdmi_ctx), GFP_KERNEL);
2062         if (!drm_hdmi_ctx) {
2063                 DRM_ERROR("failed to allocate common hdmi context.\n");
2064                 return -ENOMEM;
2065         }
2066
2067         hdata = kzalloc(sizeof(struct hdmi_context), GFP_KERNEL);
2068         if (!hdata) {
2069                 DRM_ERROR("out of memory\n");
2070                 kfree(drm_hdmi_ctx);
2071                 return -ENOMEM;
2072         }
2073
2074         drm_hdmi_ctx->ctx = (void *)hdata;
2075         hdata->parent_ctx = (void *)drm_hdmi_ctx;
2076
2077         platform_set_drvdata(pdev, drm_hdmi_ctx);
2078
2079         hdata->is_v13 = pdata->is_v13;
2080         hdata->default_win = pdata->default_win;
2081         hdata->default_timing = &pdata->timing;
2082         hdata->default_bpp = pdata->bpp;
2083         hdata->dev = dev;
2084
2085         ret = hdmi_resources_init(hdata);
2086         if (ret) {
2087                 ret = -EINVAL;
2088                 goto err_data;
2089         }
2090
2091         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2092         if (!res) {
2093                 DRM_ERROR("failed to find registers\n");
2094                 ret = -ENOENT;
2095                 goto err_resource;
2096         }
2097
2098         hdata->regs_res = request_mem_region(res->start, resource_size(res),
2099                                            dev_name(dev));
2100         if (!hdata->regs_res) {
2101                 DRM_ERROR("failed to claim register region\n");
2102                 ret = -ENOENT;
2103                 goto err_resource;
2104         }
2105
2106         hdata->regs = ioremap(res->start, resource_size(res));
2107         if (!hdata->regs) {
2108                 DRM_ERROR("failed to map registers\n");
2109                 ret = -ENXIO;
2110                 goto err_req_region;
2111         }
2112
2113         /* DDC i2c driver */
2114         if (i2c_add_driver(&ddc_driver)) {
2115                 DRM_ERROR("failed to register ddc i2c driver\n");
2116                 ret = -ENOENT;
2117                 goto err_iomap;
2118         }
2119
2120         hdata->ddc_port = hdmi_ddc;
2121
2122         /* hdmiphy i2c driver */
2123         if (i2c_add_driver(&hdmiphy_driver)) {
2124                 DRM_ERROR("failed to register hdmiphy i2c driver\n");
2125                 ret = -ENOENT;
2126                 goto err_ddc;
2127         }
2128
2129         hdata->hdmiphy_port = hdmi_hdmiphy;
2130
2131         res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
2132         if (res == NULL) {
2133                 DRM_ERROR("get interrupt resource failed.\n");
2134                 ret = -ENXIO;
2135                 goto err_hdmiphy;
2136         }
2137
2138         /* create workqueue and hotplug work */
2139         hdata->wq = alloc_workqueue("exynos-drm-hdmi",
2140                         WQ_UNBOUND | WQ_NON_REENTRANT, 1);
2141         if (hdata->wq == NULL) {
2142                 DRM_ERROR("Failed to create workqueue.\n");
2143                 ret = -ENOMEM;
2144                 goto err_hdmiphy;
2145         }
2146         INIT_WORK(&hdata->hotplug_work, hdmi_hotplug_func);
2147
2148         /* register hpd interrupt */
2149         ret = request_irq(res->start, hdmi_irq_handler, 0, "drm_hdmi",
2150                                 drm_hdmi_ctx);
2151         if (ret) {
2152                 DRM_ERROR("request interrupt failed.\n");
2153                 goto err_workqueue;
2154         }
2155         hdata->irq = res->start;
2156
2157         /* register specific callbacks to common hdmi. */
2158         exynos_drm_display_ops_register(&display_ops);
2159         exynos_drm_manager_ops_register(&manager_ops);
2160
2161         hdmi_resource_poweron(hdata);
2162
2163         return 0;
2164
2165 err_workqueue:
2166         destroy_workqueue(hdata->wq);
2167 err_hdmiphy:
2168         i2c_del_driver(&hdmiphy_driver);
2169 err_ddc:
2170         i2c_del_driver(&ddc_driver);
2171 err_iomap:
2172         iounmap(hdata->regs);
2173 err_req_region:
2174         release_mem_region(hdata->regs_res->start,
2175                         resource_size(hdata->regs_res));
2176 err_resource:
2177         hdmi_resources_cleanup(hdata);
2178 err_data:
2179         kfree(hdata);
2180         kfree(drm_hdmi_ctx);
2181         return ret;
2182 }
2183
2184 static int __devexit hdmi_remove(struct platform_device *pdev)
2185 {
2186         struct exynos_drm_hdmi_context *ctx = platform_get_drvdata(pdev);
2187         struct hdmi_context *hdata = (struct hdmi_context *)ctx->ctx;
2188
2189         DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2190
2191         hdmi_resource_poweroff(hdata);
2192
2193         disable_irq(hdata->irq);
2194         free_irq(hdata->irq, hdata);
2195
2196         cancel_work_sync(&hdata->hotplug_work);
2197         destroy_workqueue(hdata->wq);
2198
2199         hdmi_resources_cleanup(hdata);
2200
2201         iounmap(hdata->regs);
2202
2203         release_mem_region(hdata->regs_res->start,
2204                         resource_size(hdata->regs_res));
2205
2206         /* hdmiphy i2c driver */
2207         i2c_del_driver(&hdmiphy_driver);
2208         /* DDC i2c driver */
2209         i2c_del_driver(&ddc_driver);
2210
2211         kfree(hdata);
2212
2213         return 0;
2214 }
2215
2216 struct platform_driver hdmi_driver = {
2217         .probe          = hdmi_probe,
2218         .remove         = __devexit_p(hdmi_remove),
2219         .driver         = {
2220                 .name   = "exynos4-hdmi",
2221                 .owner  = THIS_MODULE,
2222                 .pm = &hdmi_pm_ops,
2223         },
2224 };