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