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