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