]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/gpu/drm/exynos/exynos_hdmi.c
2c115f8a62a31dd47793b8306f348a870e8eef8a
[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         int                             external_irq;
78         int                             internal_irq;
79
80         struct i2c_client               *ddc_port;
81         struct i2c_client               *hdmiphy_port;
82
83         /* current hdmiphy conf index */
84         int cur_conf;
85
86         struct hdmi_resources           res;
87         void                            *parent_ctx;
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         } else {
1297                 return -ENODEV;
1298         }
1299
1300         return 0;
1301 }
1302
1303 static int hdmi_v13_check_timing(struct fb_videomode *check_timing)
1304 {
1305         int i;
1306
1307         DRM_DEBUG_KMS("valid mode : xres=%d, yres=%d, refresh=%d, intl=%d\n",
1308                         check_timing->xres, check_timing->yres,
1309                         check_timing->refresh, (check_timing->vmode &
1310                         FB_VMODE_INTERLACED) ? true : false);
1311
1312         for (i = 0; i < ARRAY_SIZE(hdmi_v13_confs); ++i)
1313                 if (hdmi_v13_confs[i].width == check_timing->xres &&
1314                         hdmi_v13_confs[i].height == check_timing->yres &&
1315                         hdmi_v13_confs[i].vrefresh == check_timing->refresh &&
1316                         hdmi_v13_confs[i].interlace ==
1317                         ((check_timing->vmode & FB_VMODE_INTERLACED) ?
1318                          true : false))
1319                                 return 0;
1320
1321         /* TODO */
1322
1323         return -EINVAL;
1324 }
1325
1326 static int hdmi_v14_check_timing(struct fb_videomode *check_timing)
1327 {
1328         int i;
1329
1330         DRM_DEBUG_KMS("valid mode : xres=%d, yres=%d, refresh=%d, intl=%d\n",
1331                         check_timing->xres, check_timing->yres,
1332                         check_timing->refresh, (check_timing->vmode &
1333                         FB_VMODE_INTERLACED) ? true : false);
1334
1335         for (i = 0; i < ARRAY_SIZE(hdmi_confs); i++)
1336                 if (hdmi_confs[i].width == check_timing->xres &&
1337                         hdmi_confs[i].height == check_timing->yres &&
1338                         hdmi_confs[i].vrefresh == check_timing->refresh &&
1339                         hdmi_confs[i].interlace ==
1340                         ((check_timing->vmode & FB_VMODE_INTERLACED) ?
1341                          true : false))
1342                                 return 0;
1343
1344         /* TODO */
1345
1346         return -EINVAL;
1347 }
1348
1349 static int hdmi_check_timing(void *ctx, void *timing)
1350 {
1351         struct hdmi_context *hdata = ctx;
1352         struct fb_videomode *check_timing = timing;
1353
1354         DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1355
1356         DRM_DEBUG_KMS("[%d]x[%d] [%d]Hz [%x]\n", check_timing->xres,
1357                         check_timing->yres, check_timing->refresh,
1358                         check_timing->vmode);
1359
1360         if (hdata->type == HDMI_TYPE13)
1361                 return hdmi_v13_check_timing(check_timing);
1362         else
1363                 return hdmi_v14_check_timing(check_timing);
1364 }
1365
1366 static void hdmi_set_acr(u32 freq, u8 *acr)
1367 {
1368         u32 n, cts;
1369
1370         switch (freq) {
1371         case 32000:
1372                 n = 4096;
1373                 cts = 27000;
1374                 break;
1375         case 44100:
1376                 n = 6272;
1377                 cts = 30000;
1378                 break;
1379         case 88200:
1380                 n = 12544;
1381                 cts = 30000;
1382                 break;
1383         case 176400:
1384                 n = 25088;
1385                 cts = 30000;
1386                 break;
1387         case 48000:
1388                 n = 6144;
1389                 cts = 27000;
1390                 break;
1391         case 96000:
1392                 n = 12288;
1393                 cts = 27000;
1394                 break;
1395         case 192000:
1396                 n = 24576;
1397                 cts = 27000;
1398                 break;
1399         default:
1400                 n = 0;
1401                 cts = 0;
1402                 break;
1403         }
1404
1405         acr[1] = cts >> 16;
1406         acr[2] = cts >> 8 & 0xff;
1407         acr[3] = cts & 0xff;
1408
1409         acr[4] = n >> 16;
1410         acr[5] = n >> 8 & 0xff;
1411         acr[6] = n & 0xff;
1412 }
1413
1414 static void hdmi_reg_acr(struct hdmi_context *hdata, u8 *acr)
1415 {
1416         hdmi_reg_writeb(hdata, HDMI_ACR_N0, acr[6]);
1417         hdmi_reg_writeb(hdata, HDMI_ACR_N1, acr[5]);
1418         hdmi_reg_writeb(hdata, HDMI_ACR_N2, acr[4]);
1419         hdmi_reg_writeb(hdata, HDMI_ACR_MCTS0, acr[3]);
1420         hdmi_reg_writeb(hdata, HDMI_ACR_MCTS1, acr[2]);
1421         hdmi_reg_writeb(hdata, HDMI_ACR_MCTS2, acr[1]);
1422         hdmi_reg_writeb(hdata, HDMI_ACR_CTS0, acr[3]);
1423         hdmi_reg_writeb(hdata, HDMI_ACR_CTS1, acr[2]);
1424         hdmi_reg_writeb(hdata, HDMI_ACR_CTS2, acr[1]);
1425
1426         if (hdata->type == HDMI_TYPE13)
1427                 hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 4);
1428         else
1429                 hdmi_reg_writeb(hdata, HDMI_ACR_CON, 4);
1430 }
1431
1432 static void hdmi_audio_init(struct hdmi_context *hdata)
1433 {
1434         u32 sample_rate, bits_per_sample, frame_size_code;
1435         u32 data_num, bit_ch, sample_frq;
1436         u32 val;
1437         u8 acr[7];
1438
1439         sample_rate = 44100;
1440         bits_per_sample = 16;
1441         frame_size_code = 0;
1442
1443         switch (bits_per_sample) {
1444         case 20:
1445                 data_num = 2;
1446                 bit_ch  = 1;
1447                 break;
1448         case 24:
1449                 data_num = 3;
1450                 bit_ch  = 1;
1451                 break;
1452         default:
1453                 data_num = 1;
1454                 bit_ch  = 0;
1455                 break;
1456         }
1457
1458         hdmi_set_acr(sample_rate, acr);
1459         hdmi_reg_acr(hdata, acr);
1460
1461         hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CON, HDMI_I2S_IN_DISABLE
1462                                 | HDMI_I2S_AUD_I2S | HDMI_I2S_CUV_I2S_ENABLE
1463                                 | HDMI_I2S_MUX_ENABLE);
1464
1465         hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CH, HDMI_I2S_CH0_EN
1466                         | HDMI_I2S_CH1_EN | HDMI_I2S_CH2_EN);
1467
1468         hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CUV, HDMI_I2S_CUV_RL_EN);
1469
1470         sample_frq = (sample_rate == 44100) ? 0 :
1471                         (sample_rate == 48000) ? 2 :
1472                         (sample_rate == 32000) ? 3 :
1473                         (sample_rate == 96000) ? 0xa : 0x0;
1474
1475         hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_DIS);
1476         hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_EN);
1477
1478         val = hdmi_reg_read(hdata, HDMI_I2S_DSD_CON) | 0x01;
1479         hdmi_reg_writeb(hdata, HDMI_I2S_DSD_CON, val);
1480
1481         /* Configuration I2S input ports. Configure I2S_PIN_SEL_0~4 */
1482         hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_0, HDMI_I2S_SEL_SCLK(5)
1483                         | HDMI_I2S_SEL_LRCK(6));
1484         hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_1, HDMI_I2S_SEL_SDATA1(1)
1485                         | HDMI_I2S_SEL_SDATA2(4));
1486         hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_2, HDMI_I2S_SEL_SDATA3(1)
1487                         | HDMI_I2S_SEL_SDATA2(2));
1488         hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_3, HDMI_I2S_SEL_DSD(0));
1489
1490         /* I2S_CON_1 & 2 */
1491         hdmi_reg_writeb(hdata, HDMI_I2S_CON_1, HDMI_I2S_SCLK_FALLING_EDGE
1492                         | HDMI_I2S_L_CH_LOW_POL);
1493         hdmi_reg_writeb(hdata, HDMI_I2S_CON_2, HDMI_I2S_MSB_FIRST_MODE
1494                         | HDMI_I2S_SET_BIT_CH(bit_ch)
1495                         | HDMI_I2S_SET_SDATA_BIT(data_num)
1496                         | HDMI_I2S_BASIC_FORMAT);
1497
1498         /* Configure register related to CUV information */
1499         hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_0, HDMI_I2S_CH_STATUS_MODE_0
1500                         | HDMI_I2S_2AUD_CH_WITHOUT_PREEMPH
1501                         | HDMI_I2S_COPYRIGHT
1502                         | HDMI_I2S_LINEAR_PCM
1503                         | HDMI_I2S_CONSUMER_FORMAT);
1504         hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_1, HDMI_I2S_CD_PLAYER);
1505         hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_2, HDMI_I2S_SET_SOURCE_NUM(0));
1506         hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_3, HDMI_I2S_CLK_ACCUR_LEVEL_2
1507                         | HDMI_I2S_SET_SMP_FREQ(sample_frq));
1508         hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_4,
1509                         HDMI_I2S_ORG_SMP_FREQ_44_1
1510                         | HDMI_I2S_WORD_LEN_MAX24_24BITS
1511                         | HDMI_I2S_WORD_LEN_MAX_24BITS);
1512
1513         hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_CON, HDMI_I2S_CH_STATUS_RELOAD);
1514 }
1515
1516 static void hdmi_audio_control(struct hdmi_context *hdata, bool onoff)
1517 {
1518         if (hdata->dvi_mode)
1519                 return;
1520
1521         hdmi_reg_writeb(hdata, HDMI_AUI_CON, onoff ? 2 : 0);
1522         hdmi_reg_writemask(hdata, HDMI_CON_0, onoff ?
1523                         HDMI_ASP_EN : HDMI_ASP_DIS, HDMI_ASP_MASK);
1524 }
1525
1526 static void hdmi_conf_reset(struct hdmi_context *hdata)
1527 {
1528         u32 reg;
1529
1530         if (hdata->type == HDMI_TYPE13)
1531                 reg = HDMI_V13_CORE_RSTOUT;
1532         else
1533                 reg = HDMI_CORE_RSTOUT;
1534
1535         /* resetting HDMI core */
1536         hdmi_reg_writemask(hdata, reg,  0, HDMI_CORE_SW_RSTOUT);
1537         mdelay(10);
1538         hdmi_reg_writemask(hdata, reg, ~0, HDMI_CORE_SW_RSTOUT);
1539         mdelay(10);
1540 }
1541
1542 static void hdmi_conf_init(struct hdmi_context *hdata)
1543 {
1544         /* disable HPD interrupts */
1545         hdmi_reg_writemask(hdata, HDMI_INTC_CON, 0, HDMI_INTC_EN_GLOBAL |
1546                 HDMI_INTC_EN_HPD_PLUG | HDMI_INTC_EN_HPD_UNPLUG);
1547
1548         /* choose HDMI mode */
1549         hdmi_reg_writemask(hdata, HDMI_MODE_SEL,
1550                 HDMI_MODE_HDMI_EN, HDMI_MODE_MASK);
1551         /* disable bluescreen */
1552         hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_BLUE_SCR_EN);
1553
1554         if (hdata->dvi_mode) {
1555                 /* choose DVI mode */
1556                 hdmi_reg_writemask(hdata, HDMI_MODE_SEL,
1557                                 HDMI_MODE_DVI_EN, HDMI_MODE_MASK);
1558                 hdmi_reg_writeb(hdata, HDMI_CON_2,
1559                                 HDMI_VID_PREAMBLE_DIS | HDMI_GUARD_BAND_DIS);
1560         }
1561
1562         if (hdata->type == HDMI_TYPE13) {
1563                 /* choose bluescreen (fecal) color */
1564                 hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_0, 0x12);
1565                 hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_1, 0x34);
1566                 hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_2, 0x56);
1567
1568                 /* enable AVI packet every vsync, fixes purple line problem */
1569                 hdmi_reg_writeb(hdata, HDMI_V13_AVI_CON, 0x02);
1570                 /* force RGB, look to CEA-861-D, table 7 for more detail */
1571                 hdmi_reg_writeb(hdata, HDMI_V13_AVI_BYTE(0), 0 << 5);
1572                 hdmi_reg_writemask(hdata, HDMI_CON_1, 0x10 << 5, 0x11 << 5);
1573
1574                 hdmi_reg_writeb(hdata, HDMI_V13_SPD_CON, 0x02);
1575                 hdmi_reg_writeb(hdata, HDMI_V13_AUI_CON, 0x02);
1576                 hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 0x04);
1577         } else {
1578                 /* enable AVI packet every vsync, fixes purple line problem */
1579                 hdmi_reg_writeb(hdata, HDMI_AVI_CON, 0x02);
1580                 hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(1), 2 << 5);
1581                 hdmi_reg_writemask(hdata, HDMI_CON_1, 2, 3 << 5);
1582         }
1583 }
1584
1585 static void hdmi_v13_timing_apply(struct hdmi_context *hdata)
1586 {
1587         const struct hdmi_v13_preset_conf *conf =
1588                 hdmi_v13_confs[hdata->cur_conf].conf;
1589         const struct hdmi_v13_core_regs *core = &conf->core;
1590         const struct hdmi_v13_tg_regs *tg = &conf->tg;
1591         int tries;
1592
1593         /* setting core registers */
1594         hdmi_reg_writeb(hdata, HDMI_H_BLANK_0, core->h_blank[0]);
1595         hdmi_reg_writeb(hdata, HDMI_H_BLANK_1, core->h_blank[1]);
1596         hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_0, core->v_blank[0]);
1597         hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_1, core->v_blank[1]);
1598         hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_2, core->v_blank[2]);
1599         hdmi_reg_writeb(hdata, HDMI_V13_H_V_LINE_0, core->h_v_line[0]);
1600         hdmi_reg_writeb(hdata, HDMI_V13_H_V_LINE_1, core->h_v_line[1]);
1601         hdmi_reg_writeb(hdata, HDMI_V13_H_V_LINE_2, core->h_v_line[2]);
1602         hdmi_reg_writeb(hdata, HDMI_VSYNC_POL, core->vsync_pol[0]);
1603         hdmi_reg_writeb(hdata, HDMI_INT_PRO_MODE, core->int_pro_mode[0]);
1604         hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_F_0, core->v_blank_f[0]);
1605         hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_F_1, core->v_blank_f[1]);
1606         hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_F_2, core->v_blank_f[2]);
1607         hdmi_reg_writeb(hdata, HDMI_V13_H_SYNC_GEN_0, core->h_sync_gen[0]);
1608         hdmi_reg_writeb(hdata, HDMI_V13_H_SYNC_GEN_1, core->h_sync_gen[1]);
1609         hdmi_reg_writeb(hdata, HDMI_V13_H_SYNC_GEN_2, core->h_sync_gen[2]);
1610         hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_1_0, core->v_sync_gen1[0]);
1611         hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_1_1, core->v_sync_gen1[1]);
1612         hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_1_2, core->v_sync_gen1[2]);
1613         hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_2_0, core->v_sync_gen2[0]);
1614         hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_2_1, core->v_sync_gen2[1]);
1615         hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_2_2, core->v_sync_gen2[2]);
1616         hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_0, core->v_sync_gen3[0]);
1617         hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_1, core->v_sync_gen3[1]);
1618         hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_2, core->v_sync_gen3[2]);
1619         /* Timing generator registers */
1620         hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_L, tg->h_fsz_l);
1621         hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_H, tg->h_fsz_h);
1622         hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_L, tg->hact_st_l);
1623         hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_H, tg->hact_st_h);
1624         hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_L, tg->hact_sz_l);
1625         hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_H, tg->hact_sz_h);
1626         hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_L, tg->v_fsz_l);
1627         hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_H, tg->v_fsz_h);
1628         hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_L, tg->vsync_l);
1629         hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_H, tg->vsync_h);
1630         hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_L, tg->vsync2_l);
1631         hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_H, tg->vsync2_h);
1632         hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_L, tg->vact_st_l);
1633         hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_H, tg->vact_st_h);
1634         hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_L, tg->vact_sz_l);
1635         hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_H, tg->vact_sz_h);
1636         hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_L, tg->field_chg_l);
1637         hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_H, tg->field_chg_h);
1638         hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_L, tg->vact_st2_l);
1639         hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_H, tg->vact_st2_h);
1640         hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_L, tg->vsync_top_hdmi_l);
1641         hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_H, tg->vsync_top_hdmi_h);
1642         hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, tg->vsync_bot_hdmi_l);
1643         hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_H, tg->vsync_bot_hdmi_h);
1644         hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_L, tg->field_top_hdmi_l);
1645         hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_H, tg->field_top_hdmi_h);
1646         hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_L, tg->field_bot_hdmi_l);
1647         hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_H, tg->field_bot_hdmi_h);
1648
1649         /* waiting for HDMIPHY's PLL to get to steady state */
1650         for (tries = 100; tries; --tries) {
1651                 u32 val = hdmi_reg_read(hdata, HDMI_V13_PHY_STATUS);
1652                 if (val & HDMI_PHY_STATUS_READY)
1653                         break;
1654                 mdelay(1);
1655         }
1656         /* steady state not achieved */
1657         if (tries == 0) {
1658                 DRM_ERROR("hdmiphy's pll could not reach steady state.\n");
1659                 hdmi_regs_dump(hdata, "timing apply");
1660         }
1661
1662         clk_disable(hdata->res.sclk_hdmi);
1663         clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_hdmiphy);
1664         clk_enable(hdata->res.sclk_hdmi);
1665
1666         /* enable HDMI and timing generator */
1667         hdmi_reg_writemask(hdata, HDMI_CON_0, ~0, HDMI_EN);
1668         if (core->int_pro_mode[0])
1669                 hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN |
1670                                 HDMI_FIELD_EN);
1671         else
1672                 hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN);
1673 }
1674
1675 static void hdmi_v14_timing_apply(struct hdmi_context *hdata)
1676 {
1677         const struct hdmi_preset_conf *conf = hdmi_confs[hdata->cur_conf].conf;
1678         const struct hdmi_core_regs *core = &conf->core;
1679         const struct hdmi_tg_regs *tg = &conf->tg;
1680         int tries;
1681
1682         /* setting core registers */
1683         hdmi_reg_writeb(hdata, HDMI_H_BLANK_0, core->h_blank[0]);
1684         hdmi_reg_writeb(hdata, HDMI_H_BLANK_1, core->h_blank[1]);
1685         hdmi_reg_writeb(hdata, HDMI_V2_BLANK_0, core->v2_blank[0]);
1686         hdmi_reg_writeb(hdata, HDMI_V2_BLANK_1, core->v2_blank[1]);
1687         hdmi_reg_writeb(hdata, HDMI_V1_BLANK_0, core->v1_blank[0]);
1688         hdmi_reg_writeb(hdata, HDMI_V1_BLANK_1, core->v1_blank[1]);
1689         hdmi_reg_writeb(hdata, HDMI_V_LINE_0, core->v_line[0]);
1690         hdmi_reg_writeb(hdata, HDMI_V_LINE_1, core->v_line[1]);
1691         hdmi_reg_writeb(hdata, HDMI_H_LINE_0, core->h_line[0]);
1692         hdmi_reg_writeb(hdata, HDMI_H_LINE_1, core->h_line[1]);
1693         hdmi_reg_writeb(hdata, HDMI_HSYNC_POL, core->hsync_pol[0]);
1694         hdmi_reg_writeb(hdata, HDMI_VSYNC_POL, core->vsync_pol[0]);
1695         hdmi_reg_writeb(hdata, HDMI_INT_PRO_MODE, core->int_pro_mode[0]);
1696         hdmi_reg_writeb(hdata, HDMI_V_BLANK_F0_0, core->v_blank_f0[0]);
1697         hdmi_reg_writeb(hdata, HDMI_V_BLANK_F0_1, core->v_blank_f0[1]);
1698         hdmi_reg_writeb(hdata, HDMI_V_BLANK_F1_0, core->v_blank_f1[0]);
1699         hdmi_reg_writeb(hdata, HDMI_V_BLANK_F1_1, core->v_blank_f1[1]);
1700         hdmi_reg_writeb(hdata, HDMI_H_SYNC_START_0, core->h_sync_start[0]);
1701         hdmi_reg_writeb(hdata, HDMI_H_SYNC_START_1, core->h_sync_start[1]);
1702         hdmi_reg_writeb(hdata, HDMI_H_SYNC_END_0, core->h_sync_end[0]);
1703         hdmi_reg_writeb(hdata, HDMI_H_SYNC_END_1, core->h_sync_end[1]);
1704         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_2_0,
1705                         core->v_sync_line_bef_2[0]);
1706         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_2_1,
1707                         core->v_sync_line_bef_2[1]);
1708         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_1_0,
1709                         core->v_sync_line_bef_1[0]);
1710         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_1_1,
1711                         core->v_sync_line_bef_1[1]);
1712         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_2_0,
1713                         core->v_sync_line_aft_2[0]);
1714         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_2_1,
1715                         core->v_sync_line_aft_2[1]);
1716         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_1_0,
1717                         core->v_sync_line_aft_1[0]);
1718         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_1_1,
1719                         core->v_sync_line_aft_1[1]);
1720         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_0,
1721                         core->v_sync_line_aft_pxl_2[0]);
1722         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_1,
1723                         core->v_sync_line_aft_pxl_2[1]);
1724         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_0,
1725                         core->v_sync_line_aft_pxl_1[0]);
1726         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_1,
1727                         core->v_sync_line_aft_pxl_1[1]);
1728         hdmi_reg_writeb(hdata, HDMI_V_BLANK_F2_0, core->v_blank_f2[0]);
1729         hdmi_reg_writeb(hdata, HDMI_V_BLANK_F2_1, core->v_blank_f2[1]);
1730         hdmi_reg_writeb(hdata, HDMI_V_BLANK_F3_0, core->v_blank_f3[0]);
1731         hdmi_reg_writeb(hdata, HDMI_V_BLANK_F3_1, core->v_blank_f3[1]);
1732         hdmi_reg_writeb(hdata, HDMI_V_BLANK_F4_0, core->v_blank_f4[0]);
1733         hdmi_reg_writeb(hdata, HDMI_V_BLANK_F4_1, core->v_blank_f4[1]);
1734         hdmi_reg_writeb(hdata, HDMI_V_BLANK_F5_0, core->v_blank_f5[0]);
1735         hdmi_reg_writeb(hdata, HDMI_V_BLANK_F5_1, core->v_blank_f5[1]);
1736         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_3_0,
1737                         core->v_sync_line_aft_3[0]);
1738         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_3_1,
1739                         core->v_sync_line_aft_3[1]);
1740         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_4_0,
1741                         core->v_sync_line_aft_4[0]);
1742         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_4_1,
1743                         core->v_sync_line_aft_4[1]);
1744         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_5_0,
1745                         core->v_sync_line_aft_5[0]);
1746         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_5_1,
1747                         core->v_sync_line_aft_5[1]);
1748         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_6_0,
1749                         core->v_sync_line_aft_6[0]);
1750         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_6_1,
1751                         core->v_sync_line_aft_6[1]);
1752         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_3_0,
1753                         core->v_sync_line_aft_pxl_3[0]);
1754         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_3_1,
1755                         core->v_sync_line_aft_pxl_3[1]);
1756         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_4_0,
1757                         core->v_sync_line_aft_pxl_4[0]);
1758         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_4_1,
1759                         core->v_sync_line_aft_pxl_4[1]);
1760         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_5_0,
1761                         core->v_sync_line_aft_pxl_5[0]);
1762         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_5_1,
1763                         core->v_sync_line_aft_pxl_5[1]);
1764         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_0,
1765                         core->v_sync_line_aft_pxl_6[0]);
1766         hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_1,
1767                         core->v_sync_line_aft_pxl_6[1]);
1768         hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_1_0, core->vact_space_1[0]);
1769         hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_1_1, core->vact_space_1[1]);
1770         hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_2_0, core->vact_space_2[0]);
1771         hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_2_1, core->vact_space_2[1]);
1772         hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_3_0, core->vact_space_3[0]);
1773         hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_3_1, core->vact_space_3[1]);
1774         hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_4_0, core->vact_space_4[0]);
1775         hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_4_1, core->vact_space_4[1]);
1776         hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_5_0, core->vact_space_5[0]);
1777         hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_5_1, core->vact_space_5[1]);
1778         hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_6_0, core->vact_space_6[0]);
1779         hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_6_1, core->vact_space_6[1]);
1780
1781         /* Timing generator registers */
1782         hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_L, tg->h_fsz_l);
1783         hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_H, tg->h_fsz_h);
1784         hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_L, tg->hact_st_l);
1785         hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_H, tg->hact_st_h);
1786         hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_L, tg->hact_sz_l);
1787         hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_H, tg->hact_sz_h);
1788         hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_L, tg->v_fsz_l);
1789         hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_H, tg->v_fsz_h);
1790         hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_L, tg->vsync_l);
1791         hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_H, tg->vsync_h);
1792         hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_L, tg->vsync2_l);
1793         hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_H, tg->vsync2_h);
1794         hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_L, tg->vact_st_l);
1795         hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_H, tg->vact_st_h);
1796         hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_L, tg->vact_sz_l);
1797         hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_H, tg->vact_sz_h);
1798         hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_L, tg->field_chg_l);
1799         hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_H, tg->field_chg_h);
1800         hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_L, tg->vact_st2_l);
1801         hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_H, tg->vact_st2_h);
1802         hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST3_L, tg->vact_st3_l);
1803         hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST3_H, tg->vact_st3_h);
1804         hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST4_L, tg->vact_st4_l);
1805         hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST4_H, tg->vact_st4_h);
1806         hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_L, tg->vsync_top_hdmi_l);
1807         hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_H, tg->vsync_top_hdmi_h);
1808         hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, tg->vsync_bot_hdmi_l);
1809         hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_H, tg->vsync_bot_hdmi_h);
1810         hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_L, tg->field_top_hdmi_l);
1811         hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_H, tg->field_top_hdmi_h);
1812         hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_L, tg->field_bot_hdmi_l);
1813         hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_H, tg->field_bot_hdmi_h);
1814         hdmi_reg_writeb(hdata, HDMI_TG_3D, tg->tg_3d);
1815
1816         /* waiting for HDMIPHY's PLL to get to steady state */
1817         for (tries = 100; tries; --tries) {
1818                 u32 val = hdmi_reg_read(hdata, HDMI_PHY_STATUS_0);
1819                 if (val & HDMI_PHY_STATUS_READY)
1820                         break;
1821                 mdelay(1);
1822         }
1823         /* steady state not achieved */
1824         if (tries == 0) {
1825                 DRM_ERROR("hdmiphy's pll could not reach steady state.\n");
1826                 hdmi_regs_dump(hdata, "timing apply");
1827         }
1828
1829         clk_disable(hdata->res.sclk_hdmi);
1830         clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_hdmiphy);
1831         clk_enable(hdata->res.sclk_hdmi);
1832
1833         /* enable HDMI and timing generator */
1834         hdmi_reg_writemask(hdata, HDMI_CON_0, ~0, HDMI_EN);
1835         if (core->int_pro_mode[0])
1836                 hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN |
1837                                 HDMI_FIELD_EN);
1838         else
1839                 hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN);
1840 }
1841
1842 static void hdmi_timing_apply(struct hdmi_context *hdata)
1843 {
1844         if (hdata->type == HDMI_TYPE13)
1845                 hdmi_v13_timing_apply(hdata);
1846         else
1847                 hdmi_v14_timing_apply(hdata);
1848 }
1849
1850 static void hdmiphy_conf_reset(struct hdmi_context *hdata)
1851 {
1852         u8 buffer[2];
1853         u32 reg;
1854
1855         clk_disable(hdata->res.sclk_hdmi);
1856         clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_pixel);
1857         clk_enable(hdata->res.sclk_hdmi);
1858
1859         /* operation mode */
1860         buffer[0] = 0x1f;
1861         buffer[1] = 0x00;
1862
1863         if (hdata->hdmiphy_port)
1864                 i2c_master_send(hdata->hdmiphy_port, buffer, 2);
1865
1866         if (hdata->type == HDMI_TYPE13)
1867                 reg = HDMI_V13_PHY_RSTOUT;
1868         else
1869                 reg = HDMI_PHY_RSTOUT;
1870
1871         /* reset hdmiphy */
1872         hdmi_reg_writemask(hdata, reg, ~0, HDMI_PHY_SW_RSTOUT);
1873         mdelay(10);
1874         hdmi_reg_writemask(hdata, reg,  0, HDMI_PHY_SW_RSTOUT);
1875         mdelay(10);
1876 }
1877
1878 static void hdmiphy_conf_apply(struct hdmi_context *hdata)
1879 {
1880         const u8 *hdmiphy_data;
1881         u8 buffer[32];
1882         u8 operation[2];
1883         u8 read_buffer[32] = {0, };
1884         int ret;
1885         int i;
1886
1887         if (!hdata->hdmiphy_port) {
1888                 DRM_ERROR("hdmiphy is not attached\n");
1889                 return;
1890         }
1891
1892         /* pixel clock */
1893         if (hdata->type == HDMI_TYPE13)
1894                 hdmiphy_data = hdmi_v13_confs[hdata->cur_conf].hdmiphy_data;
1895         else
1896                 hdmiphy_data = hdmi_confs[hdata->cur_conf].hdmiphy_data;
1897
1898         memcpy(buffer, hdmiphy_data, 32);
1899         ret = i2c_master_send(hdata->hdmiphy_port, buffer, 32);
1900         if (ret != 32) {
1901                 DRM_ERROR("failed to configure HDMIPHY via I2C\n");
1902                 return;
1903         }
1904
1905         mdelay(10);
1906
1907         /* operation mode */
1908         operation[0] = 0x1f;
1909         operation[1] = 0x80;
1910
1911         ret = i2c_master_send(hdata->hdmiphy_port, operation, 2);
1912         if (ret != 2) {
1913                 DRM_ERROR("failed to enable hdmiphy\n");
1914                 return;
1915         }
1916
1917         ret = i2c_master_recv(hdata->hdmiphy_port, read_buffer, 32);
1918         if (ret < 0) {
1919                 DRM_ERROR("failed to read hdmiphy config\n");
1920                 return;
1921         }
1922
1923         for (i = 0; i < ret; i++)
1924                 DRM_DEBUG_KMS("hdmiphy[0x%02x] write[0x%02x] - "
1925                         "recv [0x%02x]\n", i, buffer[i], read_buffer[i]);
1926 }
1927
1928 static void hdmi_conf_apply(struct hdmi_context *hdata)
1929 {
1930         DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1931
1932         hdmiphy_conf_reset(hdata);
1933         hdmiphy_conf_apply(hdata);
1934
1935         mutex_lock(&hdata->hdmi_mutex);
1936         hdmi_conf_reset(hdata);
1937         hdmi_conf_init(hdata);
1938         mutex_unlock(&hdata->hdmi_mutex);
1939
1940         hdmi_audio_init(hdata);
1941
1942         /* setting core registers */
1943         hdmi_timing_apply(hdata);
1944         hdmi_audio_control(hdata, true);
1945
1946         hdmi_regs_dump(hdata, "start");
1947 }
1948
1949 static void hdmi_mode_fixup(void *ctx, struct drm_connector *connector,
1950                                 const struct drm_display_mode *mode,
1951                                 struct drm_display_mode *adjusted_mode)
1952 {
1953         struct drm_display_mode *m;
1954         struct hdmi_context *hdata = ctx;
1955         int index;
1956
1957         DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1958
1959         drm_mode_set_crtcinfo(adjusted_mode, 0);
1960
1961         if (hdata->type == HDMI_TYPE13)
1962                 index = hdmi_v13_conf_index(adjusted_mode);
1963         else
1964                 index = hdmi_v14_conf_index(adjusted_mode);
1965
1966         /* just return if user desired mode exists. */
1967         if (index >= 0)
1968                 return;
1969
1970         /*
1971          * otherwise, find the most suitable mode among modes and change it
1972          * to adjusted_mode.
1973          */
1974         list_for_each_entry(m, &connector->modes, head) {
1975                 if (hdata->type == HDMI_TYPE13)
1976                         index = hdmi_v13_conf_index(m);
1977                 else
1978                         index = hdmi_v14_conf_index(m);
1979
1980                 if (index >= 0) {
1981                         DRM_INFO("desired mode doesn't exist so\n");
1982                         DRM_INFO("use the most suitable mode among modes.\n");
1983                         memcpy(adjusted_mode, m, sizeof(*m));
1984                         break;
1985                 }
1986         }
1987 }
1988
1989 static void hdmi_mode_set(void *ctx, void *mode)
1990 {
1991         struct hdmi_context *hdata = ctx;
1992         int conf_idx;
1993
1994         DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1995
1996         conf_idx = hdmi_conf_index(hdata, mode);
1997         if (conf_idx >= 0)
1998                 hdata->cur_conf = conf_idx;
1999         else
2000                 DRM_DEBUG_KMS("not supported mode\n");
2001 }
2002
2003 static void hdmi_get_max_resol(void *ctx, unsigned int *width,
2004                                         unsigned int *height)
2005 {
2006         DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2007
2008         *width = MAX_WIDTH;
2009         *height = MAX_HEIGHT;
2010 }
2011
2012 static void hdmi_commit(void *ctx)
2013 {
2014         struct hdmi_context *hdata = ctx;
2015
2016         DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2017
2018         hdmi_conf_apply(hdata);
2019 }
2020
2021 static void hdmi_poweron(struct hdmi_context *hdata)
2022 {
2023         struct hdmi_resources *res = &hdata->res;
2024
2025         DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2026
2027         mutex_lock(&hdata->hdmi_mutex);
2028         if (hdata->powered) {
2029                 mutex_unlock(&hdata->hdmi_mutex);
2030                 return;
2031         }
2032
2033         hdata->powered = true;
2034
2035         mutex_unlock(&hdata->hdmi_mutex);
2036
2037         pm_runtime_get_sync(hdata->dev);
2038
2039         regulator_bulk_enable(res->regul_count, res->regul_bulk);
2040         clk_enable(res->hdmiphy);
2041         clk_enable(res->hdmi);
2042         clk_enable(res->sclk_hdmi);
2043 }
2044
2045 static void hdmi_poweroff(struct hdmi_context *hdata)
2046 {
2047         struct hdmi_resources *res = &hdata->res;
2048
2049         DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2050
2051         mutex_lock(&hdata->hdmi_mutex);
2052         if (!hdata->powered)
2053                 goto out;
2054         mutex_unlock(&hdata->hdmi_mutex);
2055
2056         /*
2057          * The TV power domain needs any condition of hdmiphy to turn off and
2058          * its reset state seems to meet the condition.
2059          */
2060         hdmiphy_conf_reset(hdata);
2061
2062         clk_disable(res->sclk_hdmi);
2063         clk_disable(res->hdmi);
2064         clk_disable(res->hdmiphy);
2065         regulator_bulk_disable(res->regul_count, res->regul_bulk);
2066
2067         pm_runtime_put_sync(hdata->dev);
2068
2069         mutex_lock(&hdata->hdmi_mutex);
2070
2071         hdata->powered = false;
2072
2073 out:
2074         mutex_unlock(&hdata->hdmi_mutex);
2075 }
2076
2077 static void hdmi_dpms(void *ctx, int mode)
2078 {
2079         struct hdmi_context *hdata = ctx;
2080
2081         DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2082
2083         switch (mode) {
2084         case DRM_MODE_DPMS_ON:
2085                 hdmi_poweron(hdata);
2086                 break;
2087         case DRM_MODE_DPMS_STANDBY:
2088         case DRM_MODE_DPMS_SUSPEND:
2089         case DRM_MODE_DPMS_OFF:
2090                 hdmi_poweroff(hdata);
2091                 break;
2092         default:
2093                 DRM_DEBUG_KMS("unknown dpms mode: %d\n", mode);
2094                 break;
2095         }
2096 }
2097
2098 static struct exynos_hdmi_ops hdmi_ops = {
2099         /* display */
2100         .is_connected   = hdmi_is_connected,
2101         .get_edid       = hdmi_get_edid,
2102         .check_timing   = hdmi_check_timing,
2103
2104         /* manager */
2105         .mode_fixup     = hdmi_mode_fixup,
2106         .mode_set       = hdmi_mode_set,
2107         .get_max_resol  = hdmi_get_max_resol,
2108         .commit         = hdmi_commit,
2109         .dpms           = hdmi_dpms,
2110 };
2111
2112 static irqreturn_t hdmi_external_irq_thread(int irq, void *arg)
2113 {
2114         struct exynos_drm_hdmi_context *ctx = arg;
2115         struct hdmi_context *hdata = ctx->ctx;
2116
2117         mutex_lock(&hdata->hdmi_mutex);
2118         hdata->hpd = gpio_get_value(hdata->hpd_gpio);
2119         mutex_unlock(&hdata->hdmi_mutex);
2120
2121         if (ctx->drm_dev)
2122                 drm_helper_hpd_irq_event(ctx->drm_dev);
2123
2124         return IRQ_HANDLED;
2125 }
2126
2127 static irqreturn_t hdmi_internal_irq_thread(int irq, void *arg)
2128 {
2129         struct exynos_drm_hdmi_context *ctx = arg;
2130         struct hdmi_context *hdata = ctx->ctx;
2131         u32 intc_flag;
2132
2133         intc_flag = hdmi_reg_read(hdata, HDMI_INTC_FLAG);
2134         /* clearing flags for HPD plug/unplug */
2135         if (intc_flag & HDMI_INTC_FLAG_HPD_UNPLUG) {
2136                 DRM_DEBUG_KMS("unplugged\n");
2137                 hdmi_reg_writemask(hdata, HDMI_INTC_FLAG, ~0,
2138                         HDMI_INTC_FLAG_HPD_UNPLUG);
2139         }
2140         if (intc_flag & HDMI_INTC_FLAG_HPD_PLUG) {
2141                 DRM_DEBUG_KMS("plugged\n");
2142                 hdmi_reg_writemask(hdata, HDMI_INTC_FLAG, ~0,
2143                         HDMI_INTC_FLAG_HPD_PLUG);
2144         }
2145
2146         if (ctx->drm_dev)
2147                 drm_helper_hpd_irq_event(ctx->drm_dev);
2148
2149         return IRQ_HANDLED;
2150 }
2151
2152 static int __devinit hdmi_resources_init(struct hdmi_context *hdata)
2153 {
2154         struct device *dev = hdata->dev;
2155         struct hdmi_resources *res = &hdata->res;
2156         static char *supply[] = {
2157                 "hdmi-en",
2158                 "vdd",
2159                 "vdd_osc",
2160                 "vdd_pll",
2161         };
2162         int i, ret;
2163
2164         DRM_DEBUG_KMS("HDMI resource init\n");
2165
2166         memset(res, 0, sizeof(*res));
2167
2168         /* get clocks, power */
2169         res->hdmi = clk_get(dev, "hdmi");
2170         if (IS_ERR_OR_NULL(res->hdmi)) {
2171                 DRM_ERROR("failed to get clock 'hdmi'\n");
2172                 goto fail;
2173         }
2174         res->sclk_hdmi = clk_get(dev, "sclk_hdmi");
2175         if (IS_ERR_OR_NULL(res->sclk_hdmi)) {
2176                 DRM_ERROR("failed to get clock 'sclk_hdmi'\n");
2177                 goto fail;
2178         }
2179         res->sclk_pixel = clk_get(dev, "sclk_pixel");
2180         if (IS_ERR_OR_NULL(res->sclk_pixel)) {
2181                 DRM_ERROR("failed to get clock 'sclk_pixel'\n");
2182                 goto fail;
2183         }
2184         res->sclk_hdmiphy = clk_get(dev, "sclk_hdmiphy");
2185         if (IS_ERR_OR_NULL(res->sclk_hdmiphy)) {
2186                 DRM_ERROR("failed to get clock 'sclk_hdmiphy'\n");
2187                 goto fail;
2188         }
2189         res->hdmiphy = clk_get(dev, "hdmiphy");
2190         if (IS_ERR_OR_NULL(res->hdmiphy)) {
2191                 DRM_ERROR("failed to get clock 'hdmiphy'\n");
2192                 goto fail;
2193         }
2194
2195         clk_set_parent(res->sclk_hdmi, res->sclk_pixel);
2196
2197         res->regul_bulk = kzalloc(ARRAY_SIZE(supply) *
2198                 sizeof(res->regul_bulk[0]), GFP_KERNEL);
2199         if (!res->regul_bulk) {
2200                 DRM_ERROR("failed to get memory for regulators\n");
2201                 goto fail;
2202         }
2203         for (i = 0; i < ARRAY_SIZE(supply); ++i) {
2204                 res->regul_bulk[i].supply = supply[i];
2205                 res->regul_bulk[i].consumer = NULL;
2206         }
2207         ret = regulator_bulk_get(dev, ARRAY_SIZE(supply), res->regul_bulk);
2208         if (ret) {
2209                 DRM_ERROR("failed to get regulators\n");
2210                 goto fail;
2211         }
2212         res->regul_count = ARRAY_SIZE(supply);
2213
2214         return 0;
2215 fail:
2216         DRM_ERROR("HDMI resource init - failed\n");
2217         return -ENODEV;
2218 }
2219
2220 static int hdmi_resources_cleanup(struct hdmi_context *hdata)
2221 {
2222         struct hdmi_resources *res = &hdata->res;
2223
2224         regulator_bulk_free(res->regul_count, res->regul_bulk);
2225         /* kfree is NULL-safe */
2226         kfree(res->regul_bulk);
2227         if (!IS_ERR_OR_NULL(res->hdmiphy))
2228                 clk_put(res->hdmiphy);
2229         if (!IS_ERR_OR_NULL(res->sclk_hdmiphy))
2230                 clk_put(res->sclk_hdmiphy);
2231         if (!IS_ERR_OR_NULL(res->sclk_pixel))
2232                 clk_put(res->sclk_pixel);
2233         if (!IS_ERR_OR_NULL(res->sclk_hdmi))
2234                 clk_put(res->sclk_hdmi);
2235         if (!IS_ERR_OR_NULL(res->hdmi))
2236                 clk_put(res->hdmi);
2237         memset(res, 0, sizeof(*res));
2238
2239         return 0;
2240 }
2241
2242 static struct i2c_client *hdmi_ddc, *hdmi_hdmiphy;
2243
2244 void hdmi_attach_ddc_client(struct i2c_client *ddc)
2245 {
2246         if (ddc)
2247                 hdmi_ddc = ddc;
2248 }
2249
2250 void hdmi_attach_hdmiphy_client(struct i2c_client *hdmiphy)
2251 {
2252         if (hdmiphy)
2253                 hdmi_hdmiphy = hdmiphy;
2254 }
2255
2256 #ifdef CONFIG_OF
2257 static struct s5p_hdmi_platform_data *drm_hdmi_dt_parse_pdata
2258                                         (struct device *dev)
2259 {
2260         struct device_node *np = dev->of_node;
2261         struct s5p_hdmi_platform_data *pd;
2262         enum of_gpio_flags flags;
2263         u32 value;
2264
2265         pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
2266         if (!pd) {
2267                 DRM_ERROR("memory allocation for pdata failed\n");
2268                 goto err_data;
2269         }
2270
2271         if (!of_find_property(np, "hpd-gpio", &value)) {
2272                 DRM_ERROR("no hpd gpio property found\n");
2273                 goto err_data;
2274         }
2275
2276         pd->hpd_gpio = of_get_named_gpio_flags(np, "hpd-gpio", 0, &flags);
2277
2278         return pd;
2279
2280 err_data:
2281         return NULL;
2282 }
2283 #else
2284 static struct s5p_hdmi_platform_data *drm_hdmi_dt_parse_pdata
2285                                         (struct device *dev)
2286 {
2287         return NULL;
2288 }
2289 #endif
2290
2291 static struct platform_device_id hdmi_driver_types[] = {
2292         {
2293                 .name           = "s5pv210-hdmi",
2294                 .driver_data    = HDMI_TYPE13,
2295         }, {
2296                 .name           = "exynos4-hdmi",
2297                 .driver_data    = HDMI_TYPE13,
2298         }, {
2299                 .name           = "exynos4-hdmi14",
2300                 .driver_data    = HDMI_TYPE14,
2301         }, {
2302                 .name           = "exynos5-hdmi",
2303                 .driver_data    = HDMI_TYPE14,
2304         }, {
2305                 /* end node */
2306         }
2307 };
2308
2309 static struct of_device_id hdmi_match_types[] = {
2310         {
2311                 .compatible = "samsung,exynos5-hdmi",
2312                 .data   = (void *)HDMI_TYPE14,
2313         }, {
2314                 /* end node */
2315         }
2316 };
2317
2318 static int __devinit hdmi_probe(struct platform_device *pdev)
2319 {
2320         struct device *dev = &pdev->dev;
2321         struct exynos_drm_hdmi_context *drm_hdmi_ctx;
2322         struct hdmi_context *hdata;
2323         struct s5p_hdmi_platform_data *pdata;
2324         struct resource *res;
2325         int ret;
2326
2327         DRM_DEBUG_KMS("[%d]\n", __LINE__);
2328
2329         if (pdev->dev.of_node) {
2330                 pdata = drm_hdmi_dt_parse_pdata(dev);
2331                 if (IS_ERR(pdata)) {
2332                         DRM_ERROR("failed to parse dt\n");
2333                         return PTR_ERR(pdata);
2334                 }
2335         } else {
2336                 pdata = pdev->dev.platform_data;
2337         }
2338
2339         if (!pdata) {
2340                 DRM_ERROR("no platform data specified\n");
2341                 return -EINVAL;
2342         }
2343
2344         drm_hdmi_ctx = devm_kzalloc(&pdev->dev, sizeof(*drm_hdmi_ctx),
2345                                                                 GFP_KERNEL);
2346         if (!drm_hdmi_ctx) {
2347                 DRM_ERROR("failed to allocate common hdmi context.\n");
2348                 return -ENOMEM;
2349         }
2350
2351         hdata = devm_kzalloc(&pdev->dev, sizeof(struct hdmi_context),
2352                                                                 GFP_KERNEL);
2353         if (!hdata) {
2354                 DRM_ERROR("out of memory\n");
2355                 return -ENOMEM;
2356         }
2357
2358         mutex_init(&hdata->hdmi_mutex);
2359
2360         drm_hdmi_ctx->ctx = (void *)hdata;
2361         hdata->parent_ctx = (void *)drm_hdmi_ctx;
2362
2363         platform_set_drvdata(pdev, drm_hdmi_ctx);
2364
2365         if (dev->of_node) {
2366                 const struct of_device_id *match;
2367                 match = of_match_node(of_match_ptr(hdmi_match_types),
2368                                         pdev->dev.of_node);
2369                 hdata->type = (enum hdmi_type)match->data;
2370         } else {
2371                 hdata->type = (enum hdmi_type)platform_get_device_id
2372                                         (pdev)->driver_data;
2373         }
2374
2375         hdata->hpd_gpio = pdata->hpd_gpio;
2376         hdata->dev = dev;
2377
2378         ret = hdmi_resources_init(hdata);
2379
2380         if (ret) {
2381                 ret = -EINVAL;
2382                 DRM_ERROR("hdmi_resources_init failed\n");
2383                 goto err_data;
2384         }
2385
2386         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2387         if (!res) {
2388                 DRM_ERROR("failed to find registers\n");
2389                 ret = -ENOENT;
2390                 goto err_resource;
2391         }
2392
2393         hdata->regs = devm_request_and_ioremap(&pdev->dev, res);
2394         if (!hdata->regs) {
2395                 DRM_ERROR("failed to map registers\n");
2396                 ret = -ENXIO;
2397                 goto err_resource;
2398         }
2399
2400         ret = gpio_request(hdata->hpd_gpio, "HPD");
2401         if (ret) {
2402                 DRM_ERROR("failed to request HPD gpio\n");
2403                 goto err_resource;
2404         }
2405
2406         /* DDC i2c driver */
2407         if (i2c_add_driver(&ddc_driver)) {
2408                 DRM_ERROR("failed to register ddc i2c driver\n");
2409                 ret = -ENOENT;
2410                 goto err_gpio;
2411         }
2412
2413         hdata->ddc_port = hdmi_ddc;
2414
2415         /* hdmiphy i2c driver */
2416         if (i2c_add_driver(&hdmiphy_driver)) {
2417                 DRM_ERROR("failed to register hdmiphy i2c driver\n");
2418                 ret = -ENOENT;
2419                 goto err_ddc;
2420         }
2421
2422         hdata->hdmiphy_port = hdmi_hdmiphy;
2423
2424         hdata->external_irq = gpio_to_irq(hdata->hpd_gpio);
2425         if (hdata->external_irq < 0) {
2426                 DRM_ERROR("failed to get GPIO external irq\n");
2427                 ret = hdata->external_irq;
2428                 goto err_hdmiphy;
2429         }
2430
2431         hdata->internal_irq = platform_get_irq(pdev, 0);
2432         if (hdata->internal_irq < 0) {
2433                 DRM_ERROR("failed to get platform internal irq\n");
2434                 ret = hdata->internal_irq;
2435                 goto err_hdmiphy;
2436         }
2437
2438         hdata->hpd = gpio_get_value(hdata->hpd_gpio);
2439
2440         ret = request_threaded_irq(hdata->external_irq, NULL,
2441                         hdmi_external_irq_thread, IRQF_TRIGGER_RISING |
2442                         IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
2443                         "hdmi_external", drm_hdmi_ctx);
2444         if (ret) {
2445                 DRM_ERROR("failed to register hdmi external interrupt\n");
2446                 goto err_hdmiphy;
2447         }
2448
2449         ret = request_threaded_irq(hdata->internal_irq, NULL,
2450                         hdmi_internal_irq_thread, IRQF_ONESHOT,
2451                         "hdmi_internal", drm_hdmi_ctx);
2452         if (ret) {
2453                 DRM_ERROR("failed to register hdmi internal interrupt\n");
2454                 goto err_free_irq;
2455         }
2456
2457         /* Attach HDMI Driver to common hdmi. */
2458         exynos_hdmi_drv_attach(drm_hdmi_ctx);
2459
2460         /* register specific callbacks to common hdmi. */
2461         exynos_hdmi_ops_register(&hdmi_ops);
2462
2463         pm_runtime_enable(dev);
2464
2465         return 0;
2466
2467 err_free_irq:
2468         free_irq(hdata->external_irq, drm_hdmi_ctx);
2469 err_hdmiphy:
2470         i2c_del_driver(&hdmiphy_driver);
2471 err_ddc:
2472         i2c_del_driver(&ddc_driver);
2473 err_gpio:
2474         gpio_free(hdata->hpd_gpio);
2475 err_resource:
2476         hdmi_resources_cleanup(hdata);
2477 err_data:
2478         return ret;
2479 }
2480
2481 static int __devexit hdmi_remove(struct platform_device *pdev)
2482 {
2483         struct device *dev = &pdev->dev;
2484         struct exynos_drm_hdmi_context *ctx = platform_get_drvdata(pdev);
2485         struct hdmi_context *hdata = ctx->ctx;
2486
2487         DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2488
2489         pm_runtime_disable(dev);
2490
2491         free_irq(hdata->internal_irq, hdata);
2492         free_irq(hdata->external_irq, hdata);
2493
2494         gpio_free(hdata->hpd_gpio);
2495
2496         hdmi_resources_cleanup(hdata);
2497
2498         /* hdmiphy i2c driver */
2499         i2c_del_driver(&hdmiphy_driver);
2500         /* DDC i2c driver */
2501         i2c_del_driver(&ddc_driver);
2502
2503         return 0;
2504 }
2505
2506 #ifdef CONFIG_PM_SLEEP
2507 static int hdmi_suspend(struct device *dev)
2508 {
2509         struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev);
2510         struct hdmi_context *hdata = ctx->ctx;
2511
2512         disable_irq(hdata->internal_irq);
2513         disable_irq(hdata->external_irq);
2514
2515         hdata->hpd = false;
2516         if (ctx->drm_dev)
2517                 drm_helper_hpd_irq_event(ctx->drm_dev);
2518
2519         hdmi_poweroff(hdata);
2520
2521         return 0;
2522 }
2523
2524 static int hdmi_resume(struct device *dev)
2525 {
2526         struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev);
2527         struct hdmi_context *hdata = ctx->ctx;
2528
2529         enable_irq(hdata->external_irq);
2530         enable_irq(hdata->internal_irq);
2531         return 0;
2532 }
2533 #endif
2534
2535 static SIMPLE_DEV_PM_OPS(hdmi_pm_ops, hdmi_suspend, hdmi_resume);
2536
2537 struct platform_driver hdmi_driver = {
2538         .probe          = hdmi_probe,
2539         .remove         = __devexit_p(hdmi_remove),
2540         .id_table = hdmi_driver_types,
2541         .driver         = {
2542                 .name   = "exynos-hdmi",
2543                 .owner  = THIS_MODULE,
2544                 .pm     = &hdmi_pm_ops,
2545                 .of_match_table = hdmi_match_types,
2546         },
2547 };