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