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