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