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