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