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