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