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