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