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