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