]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/blame - drivers/gpu/drm/exynos/exynos_hdmi.c
treewide: devm_kzalloc() -> devm_kcalloc()
[mirror_ubuntu-focal-kernel.git] / drivers / gpu / drm / exynos / exynos_hdmi.c
CommitLineData
d8408326
SWK
1/*
2 * Copyright (C) 2011 Samsung Electronics Co.Ltd
3 * Authors:
4 * Seung-Woo Kim <sw0312.kim@samsung.com>
5 * Inki Dae <inki.dae@samsung.com>
6 * Joonyoung Shim <jy0922.shim@samsung.com>
7 *
8 * Based on drivers/media/video/s5p-tv/hdmi_drv.c
9 *
5eefadb5
AH
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
d8408326
SWK
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>
4ea9526b 20#include <drm/drm_atomic_helper.h>
d8408326
SWK
21
22#include "regs-hdmi.h"
23
24#include <linux/kernel.h>
d8408326
SWK
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>
2228b7cd 33#include <linux/gpio/consumer.h>
d8408326 34#include <linux/regulator/consumer.h>
22c4f428 35#include <linux/io.h>
d5e9ca4c 36#include <linux/of_address.h>
cd240cde 37#include <linux/of_device.h>
aa181570 38#include <linux/of_graph.h>
d34d59bd 39#include <linux/hdmi.h>
f37cd5e8 40#include <linux/component.h>
049d34e9
RS
41#include <linux/mfd/syscon.h>
42#include <linux/regmap.h>
691da76f 43#include <sound/hdmi-codec.h>
d8408326
SWK
44#include <drm/exynos_drm.h>
45
278c811c
HV
46#include <media/cec-notifier.h>
47
f37cd5e8 48#include "exynos_drm_crtc.h"
d8408326 49
724fd140
SP
50#define HOTPLUG_DEBOUNCE_MS 1100
51
5a325071
RS
52enum hdmi_type {
53 HDMI_TYPE13,
54 HDMI_TYPE14,
633d00b3
AH
55 HDMI_TYPE_COUNT
56};
57
58#define HDMI_MAPPED_BASE 0xffff0000
59
60enum hdmi_mapped_regs {
61 HDMI_PHY_STATUS = HDMI_MAPPED_BASE,
62 HDMI_PHY_RSTOUT,
63 HDMI_ACR_CON,
d24bb3e5
AH
64 HDMI_ACR_MCTS0,
65 HDMI_ACR_CTS0,
66 HDMI_ACR_N0
633d00b3
AH
67};
68
69static const u32 hdmi_reg_map[][HDMI_TYPE_COUNT] = {
70 { HDMI_V13_PHY_STATUS, HDMI_PHY_STATUS_0 },
71 { HDMI_V13_PHY_RSTOUT, HDMI_V14_PHY_RSTOUT },
72 { HDMI_V13_ACR_CON, HDMI_V14_ACR_CON },
d24bb3e5
AH
73 { HDMI_V13_ACR_MCTS0, HDMI_V14_ACR_MCTS0 },
74 { HDMI_V13_ACR_CTS0, HDMI_V14_ACR_CTS0 },
75 { HDMI_V13_ACR_N0, HDMI_V14_ACR_N0 },
5a325071
RS
76};
77
1ab739db
AH
78static const char * const supply[] = {
79 "vdd",
80 "vdd_osc",
81 "vdd_pll",
82};
83
65e98030
AH
84struct hdmiphy_config {
85 int pixel_clock;
86 u8 conf[32];
87};
88
89struct hdmiphy_configs {
90 int count;
91 const struct hdmiphy_config *data;
92};
93
9be7e989
AH
94struct string_array_spec {
95 int count;
96 const char * const *data;
97};
98
99#define INIT_ARRAY_SPEC(a) { .count = ARRAY_SIZE(a), .data = a }
100
bfe4e84c
ID
101struct hdmi_driver_data {
102 unsigned int type;
103 unsigned int is_apb_phy:1;
68cd004e 104 unsigned int has_sysreg:1;
65e98030 105 struct hdmiphy_configs phy_confs;
9be7e989
AH
106 struct string_array_spec clk_gates;
107 /*
108 * Array of triplets (p_off, p_on, clock), where p_off and p_on are
109 * required parents of clock when HDMI-PHY is respectively off or on.
110 */
111 struct string_array_spec clk_muxes;
bfe4e84c
ID
112};
113
691da76f
SN
114struct hdmi_audio {
115 struct platform_device *pdev;
116 struct hdmi_audio_infoframe infoframe;
117 struct hdmi_codec_params params;
118 bool mute;
119};
120
590f418a 121struct hdmi_context {
2b8376c8 122 struct drm_encoder encoder;
590f418a
JS
123 struct device *dev;
124 struct drm_device *drm_dev;
d9716ee3 125 struct drm_connector connector;
872d20d6 126 bool dvi_mode;
724fd140 127 struct delayed_work hotplug_work;
278c811c 128 struct cec_notifier *notifier;
cd240cde 129 const struct hdmi_driver_data *drv_data;
7ecd34e8 130
af1f7c24 131 void __iomem *regs;
d5e9ca4c 132 void __iomem *regs_hdmiphy;
af1f7c24
AH
133 struct i2c_client *hdmiphy_port;
134 struct i2c_adapter *ddc_adpt;
f28464c3 135 struct gpio_desc *hpd_gpio;
af1f7c24 136 int irq;
049d34e9 137 struct regmap *pmureg;
68cd004e 138 struct regmap *sysreg;
9be7e989
AH
139 struct clk **clk_gates;
140 struct clk **clk_muxes;
af1f7c24
AH
141 struct regulator_bulk_data regul_bulk[ARRAY_SIZE(supply)];
142 struct regulator *reg_hdmi_en;
59b62d3c 143 struct exynos_drm_clk phy_clk;
aa181570 144 struct drm_bridge *bridge;
691da76f
SN
145
146 /* mutex protecting subsequent fields below */
147 struct mutex mutex;
148 struct hdmi_audio audio;
149 bool powered;
590f418a
JS
150};
151
2b8376c8 152static inline struct hdmi_context *encoder_to_hdmi(struct drm_encoder *e)
0d8424f8 153{
cf67cc9a 154 return container_of(e, struct hdmi_context, encoder);
0d8424f8
AH
155}
156
185f22d2
AH
157static inline struct hdmi_context *connector_to_hdmi(struct drm_connector *c)
158{
159 return container_of(c, struct hdmi_context, connector);
160}
161
6b986edf
RS
162static const struct hdmiphy_config hdmiphy_v13_configs[] = {
163 {
164 .pixel_clock = 27000000,
165 .conf = {
166 0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40,
167 0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
168 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
74a74ff4 169 0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x80,
6b986edf 170 },
d8408326 171 },
6b986edf
RS
172 {
173 .pixel_clock = 27027000,
174 .conf = {
175 0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09, 0x64,
176 0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
177 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
74a74ff4 178 0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x80,
6b986edf 179 },
d8408326 180 },
6b986edf
RS
181 {
182 .pixel_clock = 74176000,
183 .conf = {
184 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef, 0x5B,
185 0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3, 0x54, 0xb9,
186 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
74a74ff4 187 0x22, 0x40, 0xa5, 0x26, 0x01, 0x00, 0x00, 0x80,
6b986edf 188 },
d8408326 189 },
6b986edf
RS
190 {
191 .pixel_clock = 74250000,
192 .conf = {
193 0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c, 0xf8, 0x40,
194 0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1, 0x54, 0xba,
195 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xe0,
74a74ff4 196 0x22, 0x40, 0xa4, 0x26, 0x01, 0x00, 0x00, 0x80,
6b986edf 197 },
d8408326 198 },
6b986edf
RS
199 {
200 .pixel_clock = 148500000,
201 .conf = {
202 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf8, 0x40,
203 0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1, 0x54, 0xba,
204 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0,
74a74ff4 205 0x22, 0x40, 0xa4, 0x26, 0x02, 0x00, 0x00, 0x80,
6b986edf 206 },
d8408326
SWK
207 },
208};
209
2f7e2ed0
SP
210static const struct hdmiphy_config hdmiphy_v14_configs[] = {
211 {
212 .pixel_clock = 25200000,
213 .conf = {
214 0x01, 0x51, 0x2A, 0x75, 0x40, 0x01, 0x00, 0x08,
215 0x82, 0x80, 0xfc, 0xd8, 0x45, 0xa0, 0xac, 0x80,
216 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
217 0x54, 0xf4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
218 },
3ecd70b1 219 },
2f7e2ed0
SP
220 {
221 .pixel_clock = 27000000,
222 .conf = {
223 0x01, 0xd1, 0x22, 0x51, 0x40, 0x08, 0xfc, 0x20,
224 0x98, 0xa0, 0xcb, 0xd8, 0x45, 0xa0, 0xac, 0x80,
225 0x06, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
226 0x54, 0xe4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
227 },
3ecd70b1 228 },
2f7e2ed0
SP
229 {
230 .pixel_clock = 27027000,
231 .conf = {
232 0x01, 0xd1, 0x2d, 0x72, 0x40, 0x64, 0x12, 0x08,
233 0x43, 0xa0, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
234 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
74a74ff4 235 0x54, 0xe3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
2f7e2ed0 236 },
3ecd70b1 237 },
2f7e2ed0
SP
238 {
239 .pixel_clock = 36000000,
240 .conf = {
241 0x01, 0x51, 0x2d, 0x55, 0x40, 0x01, 0x00, 0x08,
242 0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
243 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
244 0x54, 0xab, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
245 },
3ecd70b1 246 },
2f7e2ed0
SP
247 {
248 .pixel_clock = 40000000,
249 .conf = {
250 0x01, 0x51, 0x32, 0x55, 0x40, 0x01, 0x00, 0x08,
251 0x82, 0x80, 0x2c, 0xd9, 0x45, 0xa0, 0xac, 0x80,
252 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
253 0x54, 0x9a, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
254 },
3ecd70b1 255 },
2f7e2ed0
SP
256 {
257 .pixel_clock = 65000000,
258 .conf = {
259 0x01, 0xd1, 0x36, 0x34, 0x40, 0x1e, 0x0a, 0x08,
260 0x82, 0xa0, 0x45, 0xd9, 0x45, 0xa0, 0xac, 0x80,
261 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
262 0x54, 0xbd, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
263 },
3ecd70b1 264 },
e1d883c0
S
265 {
266 .pixel_clock = 71000000,
267 .conf = {
96d2653a
S
268 0x01, 0xd1, 0x3b, 0x35, 0x40, 0x0c, 0x04, 0x08,
269 0x85, 0xa0, 0x63, 0xd9, 0x45, 0xa0, 0xac, 0x80,
270 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
e1d883c0
S
271 0x54, 0xad, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
272 },
273 },
274 {
275 .pixel_clock = 73250000,
276 .conf = {
96d2653a
S
277 0x01, 0xd1, 0x3d, 0x35, 0x40, 0x18, 0x02, 0x08,
278 0x83, 0xa0, 0x6e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
279 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
e1d883c0
S
280 0x54, 0xa8, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
281 },
282 },
2f7e2ed0
SP
283 {
284 .pixel_clock = 74176000,
285 .conf = {
286 0x01, 0xd1, 0x3e, 0x35, 0x40, 0x5b, 0xde, 0x08,
287 0x82, 0xa0, 0x73, 0xd9, 0x45, 0xa0, 0xac, 0x80,
288 0x56, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
289 0x54, 0xa6, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
290 },
3ecd70b1 291 },
2f7e2ed0
SP
292 {
293 .pixel_clock = 74250000,
294 .conf = {
295 0x01, 0xd1, 0x1f, 0x10, 0x40, 0x40, 0xf8, 0x08,
296 0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
297 0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
74a74ff4 298 0x54, 0xa5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
2f7e2ed0 299 },
e540adf3 300 },
2f7e2ed0
SP
301 {
302 .pixel_clock = 83500000,
303 .conf = {
304 0x01, 0xd1, 0x23, 0x11, 0x40, 0x0c, 0xfb, 0x08,
305 0x85, 0xa0, 0xd1, 0xd8, 0x45, 0xa0, 0xac, 0x80,
306 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
307 0x54, 0x93, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
308 },
e540adf3 309 },
ae58c03e
DD
310 {
311 .pixel_clock = 85500000,
312 .conf = {
313 0x01, 0xd1, 0x24, 0x11, 0x40, 0x40, 0xd0, 0x08,
314 0x84, 0xa0, 0xd6, 0xd8, 0x45, 0xa0, 0xac, 0x80,
315 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
316 0x54, 0x90, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
317 },
318 },
2f7e2ed0
SP
319 {
320 .pixel_clock = 106500000,
321 .conf = {
322 0x01, 0xd1, 0x2c, 0x12, 0x40, 0x0c, 0x09, 0x08,
323 0x84, 0xa0, 0x0a, 0xd9, 0x45, 0xa0, 0xac, 0x80,
324 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
325 0x54, 0x73, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
326 },
3ecd70b1 327 },
2f7e2ed0
SP
328 {
329 .pixel_clock = 108000000,
330 .conf = {
331 0x01, 0x51, 0x2d, 0x15, 0x40, 0x01, 0x00, 0x08,
332 0x82, 0x80, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
333 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
334 0x54, 0xc7, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
335 },
3ecd70b1 336 },
e1d883c0
S
337 {
338 .pixel_clock = 115500000,
339 .conf = {
96d2653a
S
340 0x01, 0xd1, 0x30, 0x12, 0x40, 0x40, 0x10, 0x08,
341 0x80, 0x80, 0x21, 0xd9, 0x45, 0xa0, 0xac, 0x80,
342 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
e1d883c0
S
343 0x54, 0xaa, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
344 },
345 },
346 {
347 .pixel_clock = 119000000,
348 .conf = {
96d2653a
S
349 0x01, 0xd1, 0x32, 0x1a, 0x40, 0x30, 0xd8, 0x08,
350 0x04, 0xa0, 0x2a, 0xd9, 0x45, 0xa0, 0xac, 0x80,
351 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
e1d883c0
S
352 0x54, 0x9d, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
353 },
354 },
2f7e2ed0
SP
355 {
356 .pixel_clock = 146250000,
357 .conf = {
358 0x01, 0xd1, 0x3d, 0x15, 0x40, 0x18, 0xfd, 0x08,
359 0x83, 0xa0, 0x6e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
360 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
361 0x54, 0x50, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
362 },
3ecd70b1 363 },
2f7e2ed0
SP
364 {
365 .pixel_clock = 148500000,
366 .conf = {
367 0x01, 0xd1, 0x1f, 0x00, 0x40, 0x40, 0xf8, 0x08,
368 0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
369 0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
74a74ff4 370 0x54, 0x4b, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
2f7e2ed0 371 },
3ecd70b1
JS
372 },
373};
374
a18a2dda
RS
375static const struct hdmiphy_config hdmiphy_5420_configs[] = {
376 {
377 .pixel_clock = 25200000,
378 .conf = {
379 0x01, 0x52, 0x3F, 0x55, 0x40, 0x01, 0x00, 0xC8,
380 0x82, 0xC8, 0xBD, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
381 0x06, 0x80, 0x01, 0x84, 0x05, 0x02, 0x24, 0x66,
382 0x54, 0xF4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
383 },
384 },
385 {
386 .pixel_clock = 27000000,
387 .conf = {
388 0x01, 0xD1, 0x22, 0x51, 0x40, 0x08, 0xFC, 0xE0,
389 0x98, 0xE8, 0xCB, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
390 0x06, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
391 0x54, 0xE4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
392 },
393 },
394 {
395 .pixel_clock = 27027000,
396 .conf = {
397 0x01, 0xD1, 0x2D, 0x72, 0x40, 0x64, 0x12, 0xC8,
398 0x43, 0xE8, 0x0E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
399 0x26, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
400 0x54, 0xE3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
401 },
402 },
403 {
404 .pixel_clock = 36000000,
405 .conf = {
406 0x01, 0x51, 0x2D, 0x55, 0x40, 0x40, 0x00, 0xC8,
407 0x02, 0xC8, 0x0E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
408 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
409 0x54, 0xAB, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
410 },
411 },
412 {
413 .pixel_clock = 40000000,
414 .conf = {
415 0x01, 0xD1, 0x21, 0x31, 0x40, 0x3C, 0x28, 0xC8,
416 0x87, 0xE8, 0xC8, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
417 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
418 0x54, 0x9A, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
419 },
420 },
421 {
422 .pixel_clock = 65000000,
423 .conf = {
424 0x01, 0xD1, 0x36, 0x34, 0x40, 0x0C, 0x04, 0xC8,
425 0x82, 0xE8, 0x45, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
426 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
427 0x54, 0xBD, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
428 },
429 },
430 {
431 .pixel_clock = 71000000,
432 .conf = {
433 0x01, 0xD1, 0x3B, 0x35, 0x40, 0x0C, 0x04, 0xC8,
434 0x85, 0xE8, 0x63, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
435 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
436 0x54, 0x57, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
437 },
438 },
439 {
440 .pixel_clock = 73250000,
441 .conf = {
442 0x01, 0xD1, 0x1F, 0x10, 0x40, 0x78, 0x8D, 0xC8,
443 0x81, 0xE8, 0xB7, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
444 0x56, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
445 0x54, 0xA8, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
446 },
447 },
448 {
449 .pixel_clock = 74176000,
450 .conf = {
451 0x01, 0xD1, 0x1F, 0x10, 0x40, 0x5B, 0xEF, 0xC8,
452 0x81, 0xE8, 0xB9, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
453 0x56, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
454 0x54, 0xA6, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
455 },
456 },
457 {
458 .pixel_clock = 74250000,
459 .conf = {
460 0x01, 0xD1, 0x1F, 0x10, 0x40, 0x40, 0xF8, 0x08,
461 0x81, 0xE8, 0xBA, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
462 0x26, 0x80, 0x09, 0x84, 0x05, 0x22, 0x24, 0x66,
463 0x54, 0xA5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
464 },
465 },
466 {
467 .pixel_clock = 83500000,
468 .conf = {
469 0x01, 0xD1, 0x23, 0x11, 0x40, 0x0C, 0xFB, 0xC8,
470 0x85, 0xE8, 0xD1, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
471 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
472 0x54, 0x4A, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
473 },
474 },
475 {
476 .pixel_clock = 88750000,
477 .conf = {
478 0x01, 0xD1, 0x25, 0x11, 0x40, 0x18, 0xFF, 0xC8,
479 0x83, 0xE8, 0xDE, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
480 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
481 0x54, 0x45, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
482 },
483 },
484 {
485 .pixel_clock = 106500000,
486 .conf = {
487 0x01, 0xD1, 0x2C, 0x12, 0x40, 0x0C, 0x09, 0xC8,
488 0x84, 0xE8, 0x0A, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
489 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
490 0x54, 0x73, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
491 },
492 },
493 {
494 .pixel_clock = 108000000,
495 .conf = {
496 0x01, 0x51, 0x2D, 0x15, 0x40, 0x01, 0x00, 0xC8,
497 0x82, 0xC8, 0x0E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
498 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
499 0x54, 0xC7, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
500 },
501 },
502 {
503 .pixel_clock = 115500000,
504 .conf = {
505 0x01, 0xD1, 0x30, 0x14, 0x40, 0x0C, 0x03, 0xC8,
506 0x88, 0xE8, 0x21, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
507 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
508 0x54, 0x6A, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
509 },
510 },
511 {
512 .pixel_clock = 146250000,
513 .conf = {
514 0x01, 0xD1, 0x3D, 0x15, 0x40, 0x18, 0xFD, 0xC8,
515 0x83, 0xE8, 0x6E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
516 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
517 0x54, 0x54, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
518 },
519 },
520 {
521 .pixel_clock = 148500000,
522 .conf = {
523 0x01, 0xD1, 0x1F, 0x00, 0x40, 0x40, 0xF8, 0x08,
524 0x81, 0xE8, 0xBA, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
525 0x26, 0x80, 0x09, 0x84, 0x05, 0x22, 0x24, 0x66,
526 0x54, 0x4B, 0x25, 0x03, 0x00, 0x80, 0x01, 0x80,
527 },
528 },
529};
530
68cd004e
AH
531static const struct hdmiphy_config hdmiphy_5433_configs[] = {
532 {
533 .pixel_clock = 27000000,
534 .conf = {
849fb0de
AH
535 0x01, 0x51, 0x2d, 0x75, 0x01, 0x00, 0x88, 0x02,
536 0x72, 0x50, 0x44, 0x8c, 0x27, 0x00, 0x7c, 0xac,
537 0xd6, 0x2b, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
68cd004e
AH
538 0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
539 },
540 },
541 {
542 .pixel_clock = 27027000,
543 .conf = {
544 0x01, 0x51, 0x2d, 0x72, 0x64, 0x09, 0x88, 0xc3,
849fb0de
AH
545 0x71, 0x50, 0x44, 0x8c, 0x27, 0x00, 0x7c, 0xac,
546 0xd6, 0x2b, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
547 0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
68cd004e
AH
548 },
549 },
550 {
551 .pixel_clock = 40000000,
552 .conf = {
553 0x01, 0x51, 0x32, 0x55, 0x01, 0x00, 0x88, 0x02,
554 0x4d, 0x50, 0x44, 0x8C, 0x27, 0x00, 0x7C, 0xAC,
555 0xD6, 0x2B, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
556 0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
557 },
558 },
559 {
560 .pixel_clock = 50000000,
561 .conf = {
562 0x01, 0x51, 0x34, 0x40, 0x64, 0x09, 0x88, 0xc3,
563 0x3d, 0x50, 0x44, 0x8C, 0x27, 0x00, 0x7C, 0xAC,
564 0xD6, 0x2B, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
565 0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
566 },
567 },
568 {
569 .pixel_clock = 65000000,
570 .conf = {
571 0x01, 0x51, 0x36, 0x31, 0x40, 0x10, 0x04, 0xc6,
572 0x2e, 0xe8, 0x44, 0x8C, 0x27, 0x00, 0x7C, 0xAC,
573 0xD6, 0x2B, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
574 0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
575 },
576 },
577 {
578 .pixel_clock = 74176000,
579 .conf = {
580 0x01, 0x51, 0x3E, 0x35, 0x5B, 0xDE, 0x88, 0x42,
581 0x53, 0x51, 0x44, 0x8C, 0x27, 0x00, 0x7C, 0xAC,
582 0xD6, 0x2B, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
583 0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
584 },
585 },
586 {
587 .pixel_clock = 74250000,
588 .conf = {
589 0x01, 0x51, 0x3E, 0x35, 0x40, 0xF0, 0x88, 0xC2,
590 0x52, 0x51, 0x44, 0x8C, 0x27, 0x00, 0x7C, 0xAC,
591 0xD6, 0x2B, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
592 0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
593 },
594 },
595 {
596 .pixel_clock = 108000000,
597 .conf = {
598 0x01, 0x51, 0x2d, 0x15, 0x01, 0x00, 0x88, 0x02,
599 0x72, 0x52, 0x44, 0x8C, 0x27, 0x00, 0x7C, 0xAC,
600 0xD6, 0x2B, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
601 0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
602 },
603 },
604 {
605 .pixel_clock = 148500000,
606 .conf = {
607 0x01, 0x51, 0x1f, 0x00, 0x40, 0xf8, 0x88, 0xc1,
608 0x52, 0x52, 0x24, 0x0c, 0x24, 0x0f, 0x7c, 0xa5,
609 0xd4, 0x2b, 0x87, 0x00, 0x00, 0x04, 0x00, 0x30,
610 0x08, 0x10, 0x01, 0x01, 0x48, 0x4a, 0x00, 0x40,
611 },
612 },
64822588
AH
613 {
614 .pixel_clock = 297000000,
615 .conf = {
616 0x01, 0x51, 0x3E, 0x05, 0x40, 0xF0, 0x88, 0xC2,
617 0x52, 0x53, 0x44, 0x8C, 0x27, 0x00, 0x7C, 0xAC,
618 0xD6, 0x2B, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
619 0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
620 },
621 },
68cd004e
AH
622};
623
190a3c61 624static const char * const hdmi_clk_gates4[] = {
9be7e989
AH
625 "hdmi", "sclk_hdmi"
626};
627
190a3c61 628static const char * const hdmi_clk_muxes4[] = {
9be7e989
AH
629 "sclk_pixel", "sclk_hdmiphy", "mout_hdmi"
630};
631
68cd004e
AH
632static const char * const hdmi_clk_gates5433[] = {
633 "hdmi_pclk", "hdmi_i_pclk", "i_tmds_clk", "i_pixel_clk", "i_spdif_clk"
634};
635
636static const char * const hdmi_clk_muxes5433[] = {
637 "oscclk", "tmds_clko", "tmds_clko_user",
638 "oscclk", "pixel_clko", "pixel_clko_user"
639};
640
5eefadb5
AH
641static const struct hdmi_driver_data exynos4210_hdmi_driver_data = {
642 .type = HDMI_TYPE13,
643 .phy_confs = INIT_ARRAY_SPEC(hdmiphy_v13_configs),
9be7e989
AH
644 .clk_gates = INIT_ARRAY_SPEC(hdmi_clk_gates4),
645 .clk_muxes = INIT_ARRAY_SPEC(hdmi_clk_muxes4),
a18a2dda 646};
d5e9ca4c 647
190a3c61 648static const struct hdmi_driver_data exynos4212_hdmi_driver_data = {
d5e9ca4c 649 .type = HDMI_TYPE14,
65e98030 650 .phy_confs = INIT_ARRAY_SPEC(hdmiphy_v14_configs),
9be7e989
AH
651 .clk_gates = INIT_ARRAY_SPEC(hdmi_clk_gates4),
652 .clk_muxes = INIT_ARRAY_SPEC(hdmi_clk_muxes4),
d5e9ca4c
RS
653};
654
5eefadb5
AH
655static const struct hdmi_driver_data exynos5420_hdmi_driver_data = {
656 .type = HDMI_TYPE14,
657 .is_apb_phy = 1,
658 .phy_confs = INIT_ARRAY_SPEC(hdmiphy_5420_configs),
9be7e989
AH
659 .clk_gates = INIT_ARRAY_SPEC(hdmi_clk_gates4),
660 .clk_muxes = INIT_ARRAY_SPEC(hdmi_clk_muxes4),
ff830c96
MS
661};
662
68cd004e
AH
663static const struct hdmi_driver_data exynos5433_hdmi_driver_data = {
664 .type = HDMI_TYPE14,
665 .is_apb_phy = 1,
666 .has_sysreg = 1,
667 .phy_confs = INIT_ARRAY_SPEC(hdmiphy_5433_configs),
668 .clk_gates = INIT_ARRAY_SPEC(hdmi_clk_gates5433),
669 .clk_muxes = INIT_ARRAY_SPEC(hdmi_clk_muxes5433),
670};
671
633d00b3
AH
672static inline u32 hdmi_map_reg(struct hdmi_context *hdata, u32 reg_id)
673{
674 if ((reg_id & 0xffff0000) == HDMI_MAPPED_BASE)
675 return hdmi_reg_map[reg_id & 0xffff][hdata->drv_data->type];
676 return reg_id;
677}
678
d8408326
SWK
679static inline u32 hdmi_reg_read(struct hdmi_context *hdata, u32 reg_id)
680{
633d00b3 681 return readl(hdata->regs + hdmi_map_reg(hdata, reg_id));
d8408326
SWK
682}
683
684static inline void hdmi_reg_writeb(struct hdmi_context *hdata,
685 u32 reg_id, u8 value)
686{
1993c339 687 writel(value, hdata->regs + hdmi_map_reg(hdata, reg_id));
d8408326
SWK
688}
689
edb6e412
AH
690static inline void hdmi_reg_writev(struct hdmi_context *hdata, u32 reg_id,
691 int bytes, u32 val)
692{
633d00b3
AH
693 reg_id = hdmi_map_reg(hdata, reg_id);
694
edb6e412 695 while (--bytes >= 0) {
1993c339 696 writel(val & 0xff, hdata->regs + reg_id);
edb6e412
AH
697 val >>= 8;
698 reg_id += 4;
699 }
700}
701
5f9e228d
AH
702static inline void hdmi_reg_write_buf(struct hdmi_context *hdata, u32 reg_id,
703 u8 *buf, int size)
704{
705 for (reg_id = hdmi_map_reg(hdata, reg_id); size; --size, reg_id += 4)
706 writel(*buf++, hdata->regs + reg_id);
707}
708
d8408326
SWK
709static inline void hdmi_reg_writemask(struct hdmi_context *hdata,
710 u32 reg_id, u32 value, u32 mask)
711{
633d00b3
AH
712 u32 old;
713
714 reg_id = hdmi_map_reg(hdata, reg_id);
715 old = readl(hdata->regs + reg_id);
d8408326
SWK
716 value = (value & mask) | (old & ~mask);
717 writel(value, hdata->regs + reg_id);
718}
719
d5e9ca4c
RS
720static int hdmiphy_reg_write_buf(struct hdmi_context *hdata,
721 u32 reg_offset, const u8 *buf, u32 len)
722{
723 if ((reg_offset + len) > 32)
724 return -EINVAL;
725
726 if (hdata->hdmiphy_port) {
727 int ret;
728
729 ret = i2c_master_send(hdata->hdmiphy_port, buf, len);
730 if (ret == len)
731 return 0;
732 return ret;
733 } else {
734 int i;
735 for (i = 0; i < len; i++)
1993c339 736 writel(buf[i], hdata->regs_hdmiphy +
d5e9ca4c
RS
737 ((reg_offset + i)<<2));
738 return 0;
739 }
740}
741
9be7e989
AH
742static int hdmi_clk_enable_gates(struct hdmi_context *hdata)
743{
744 int i, ret;
745
746 for (i = 0; i < hdata->drv_data->clk_gates.count; ++i) {
747 ret = clk_prepare_enable(hdata->clk_gates[i]);
748 if (!ret)
749 continue;
750
751 dev_err(hdata->dev, "Cannot enable clock '%s', %d\n",
752 hdata->drv_data->clk_gates.data[i], ret);
753 while (i--)
754 clk_disable_unprepare(hdata->clk_gates[i]);
755 return ret;
756 }
757
758 return 0;
759}
760
761static void hdmi_clk_disable_gates(struct hdmi_context *hdata)
762{
763 int i = hdata->drv_data->clk_gates.count;
764
765 while (i--)
766 clk_disable_unprepare(hdata->clk_gates[i]);
767}
768
769static int hdmi_clk_set_parents(struct hdmi_context *hdata, bool to_phy)
770{
771 struct device *dev = hdata->dev;
772 int ret = 0;
773 int i;
774
775 for (i = 0; i < hdata->drv_data->clk_muxes.count; i += 3) {
776 struct clk **c = &hdata->clk_muxes[i];
777
778 ret = clk_set_parent(c[2], c[to_phy]);
779 if (!ret)
780 continue;
781
782 dev_err(dev, "Cannot set clock parent of '%s' to '%s', %d\n",
783 hdata->drv_data->clk_muxes.data[i + 2],
784 hdata->drv_data->clk_muxes.data[i + to_phy], ret);
785 }
786
787 return ret;
788}
789
691da76f
SN
790static int hdmi_audio_infoframe_apply(struct hdmi_context *hdata)
791{
792 struct hdmi_audio_infoframe *infoframe = &hdata->audio.infoframe;
793 u8 buf[HDMI_INFOFRAME_SIZE(AUDIO)];
794 int len;
795
796 len = hdmi_audio_infoframe_pack(infoframe, buf, sizeof(buf));
797 if (len < 0)
798 return len;
799
800 hdmi_reg_writeb(hdata, HDMI_AUI_CON, HDMI_AUI_CON_EVERY_VSYNC);
801 hdmi_reg_write_buf(hdata, HDMI_AUI_HEADER0, buf, len);
802
803 return 0;
804}
805
5f9e228d 806static void hdmi_reg_infoframes(struct hdmi_context *hdata)
a144c2e9 807{
991ea04e 808 struct drm_display_mode *m = &hdata->encoder.crtc->state->mode;
5f9e228d
AH
809 union hdmi_infoframe frm;
810 u8 buf[25];
811 int ret;
a144c2e9 812
a144c2e9 813 if (hdata->dvi_mode) {
a144c2e9
RS
814 hdmi_reg_writeb(hdata, HDMI_AVI_CON,
815 HDMI_AVI_CON_DO_NOT_TRANSMIT);
5f9e228d
AH
816 hdmi_reg_writeb(hdata, HDMI_VSI_CON,
817 HDMI_VSI_CON_DO_NOT_TRANSMIT);
a144c2e9
RS
818 hdmi_reg_writeb(hdata, HDMI_AUI_CON, HDMI_AUI_CON_NO_TRAN);
819 return;
820 }
821
991ea04e 822 ret = drm_hdmi_avi_infoframe_from_display_mode(&frm.avi, m, false);
5f9e228d
AH
823 if (!ret)
824 ret = hdmi_avi_infoframe_pack(&frm.avi, buf, sizeof(buf));
825 if (ret > 0) {
a144c2e9 826 hdmi_reg_writeb(hdata, HDMI_AVI_CON, HDMI_AVI_CON_EVERY_VSYNC);
5f9e228d
AH
827 hdmi_reg_write_buf(hdata, HDMI_AVI_HEADER0, buf, ret);
828 } else {
829 DRM_INFO("%s: invalid AVI infoframe (%d)\n", __func__, ret);
830 }
a144c2e9 831
f1781e9b
VS
832 ret = drm_hdmi_vendor_infoframe_from_display_mode(&frm.vendor.hdmi,
833 &hdata->connector, m);
5f9e228d
AH
834 if (!ret)
835 ret = hdmi_vendor_infoframe_pack(&frm.vendor.hdmi, buf,
836 sizeof(buf));
837 if (ret > 0) {
838 hdmi_reg_writeb(hdata, HDMI_VSI_CON, HDMI_VSI_CON_EVERY_VSYNC);
10abdbc5
AH
839 hdmi_reg_write_buf(hdata, HDMI_VSI_HEADER0, buf, 3);
840 hdmi_reg_write_buf(hdata, HDMI_VSI_DATA(0), buf + 3, ret - 3);
5f9e228d 841 }
a144c2e9 842
691da76f 843 hdmi_audio_infoframe_apply(hdata);
a144c2e9
RS
844}
845
d9716ee3
SP
846static enum drm_connector_status hdmi_detect(struct drm_connector *connector,
847 bool force)
4551789f 848{
185f22d2 849 struct hdmi_context *hdata = connector_to_hdmi(connector);
4551789f 850
2228b7cd 851 if (gpiod_get_value(hdata->hpd_gpio))
ef6ce28b 852 return connector_status_connected;
5137c8ca 853
278c811c 854 cec_notifier_set_phys_addr(hdata->notifier, CEC_PHYS_ADDR_INVALID);
ef6ce28b 855 return connector_status_disconnected;
4551789f
SP
856}
857
d9716ee3 858static void hdmi_connector_destroy(struct drm_connector *connector)
d8408326 859{
ad279310
AH
860 drm_connector_unregister(connector);
861 drm_connector_cleanup(connector);
d8408326
SWK
862}
863
800ba2b5 864static const struct drm_connector_funcs hdmi_connector_funcs = {
d9716ee3
SP
865 .fill_modes = drm_helper_probe_single_connector_modes,
866 .detect = hdmi_detect,
867 .destroy = hdmi_connector_destroy,
4ea9526b
GP
868 .reset = drm_atomic_helper_connector_reset,
869 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
870 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
d9716ee3
SP
871};
872
873static int hdmi_get_modes(struct drm_connector *connector)
d8408326 874{
185f22d2 875 struct hdmi_context *hdata = connector_to_hdmi(connector);
d9716ee3 876 struct edid *edid;
64ebd890 877 int ret;
d8408326 878
8fa04aae 879 if (!hdata->ddc_adpt)
d9716ee3 880 return -ENODEV;
d8408326 881
8fa04aae 882 edid = drm_get_edid(connector, hdata->ddc_adpt);
d9716ee3
SP
883 if (!edid)
884 return -ENODEV;
9c08e4ba 885
d9716ee3 886 hdata->dvi_mode = !drm_detect_hdmi_monitor(edid);
9c08e4ba
RS
887 DRM_DEBUG_KMS("%s : width[%d] x height[%d]\n",
888 (hdata->dvi_mode ? "dvi monitor" : "hdmi monitor"),
d9716ee3 889 edid->width_cm, edid->height_cm);
d8408326 890
d9716ee3 891 drm_mode_connector_update_edid_property(connector, edid);
278c811c 892 cec_notifier_set_phys_addr_from_edid(hdata->notifier, edid);
d9716ee3 893
64ebd890
AH
894 ret = drm_add_edid_modes(connector, edid);
895
896 kfree(edid);
897
898 return ret;
d8408326
SWK
899}
900
6b986edf 901static int hdmi_find_phy_conf(struct hdmi_context *hdata, u32 pixel_clock)
d8408326 902{
65e98030 903 const struct hdmiphy_configs *confs = &hdata->drv_data->phy_confs;
d5e9ca4c 904 int i;
6b986edf 905
65e98030
AH
906 for (i = 0; i < confs->count; i++)
907 if (confs->data[i].pixel_clock == pixel_clock)
2f7e2ed0 908 return i;
2f7e2ed0
SP
909
910 DRM_DEBUG_KMS("Could not find phy config for %d\n", pixel_clock);
911 return -EINVAL;
912}
913
d9716ee3 914static int hdmi_mode_valid(struct drm_connector *connector,
f041b257 915 struct drm_display_mode *mode)
3ecd70b1 916{
185f22d2 917 struct hdmi_context *hdata = connector_to_hdmi(connector);
6b986edf 918 int ret;
3ecd70b1 919
16844fb1
RS
920 DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%d clock=%d\n",
921 mode->hdisplay, mode->vdisplay, mode->vrefresh,
922 (mode->flags & DRM_MODE_FLAG_INTERLACE) ? true :
923 false, mode->clock * 1000);
3ecd70b1 924
16844fb1 925 ret = hdmi_find_phy_conf(hdata, mode->clock * 1000);
6b986edf 926 if (ret < 0)
d9716ee3
SP
927 return MODE_BAD;
928
929 return MODE_OK;
930}
931
800ba2b5 932static const struct drm_connector_helper_funcs hdmi_connector_helper_funcs = {
d9716ee3
SP
933 .get_modes = hdmi_get_modes,
934 .mode_valid = hdmi_mode_valid,
d9716ee3
SP
935};
936
2b8376c8 937static int hdmi_create_connector(struct drm_encoder *encoder)
d9716ee3 938{
2b8376c8 939 struct hdmi_context *hdata = encoder_to_hdmi(encoder);
d9716ee3
SP
940 struct drm_connector *connector = &hdata->connector;
941 int ret;
942
d9716ee3
SP
943 connector->interlace_allowed = true;
944 connector->polled = DRM_CONNECTOR_POLL_HPD;
945
946 ret = drm_connector_init(hdata->drm_dev, connector,
947 &hdmi_connector_funcs, DRM_MODE_CONNECTOR_HDMIA);
948 if (ret) {
949 DRM_ERROR("Failed to initialize connector with drm\n");
6b986edf 950 return ret;
d9716ee3
SP
951 }
952
953 drm_connector_helper_add(connector, &hdmi_connector_helper_funcs);
2b8376c8 954 drm_mode_connector_attach_encoder(connector, encoder);
d9716ee3 955
aa181570 956 if (hdata->bridge) {
aa181570
AH
957 ret = drm_bridge_attach(encoder, hdata->bridge, NULL);
958 if (ret)
959 DRM_ERROR("Failed to attach bridge\n");
960 }
961
962 return ret;
d9716ee3
SP
963}
964
2b8376c8
GP
965static bool hdmi_mode_fixup(struct drm_encoder *encoder,
966 const struct drm_display_mode *mode,
967 struct drm_display_mode *adjusted_mode)
f041b257 968{
2b8376c8
GP
969 struct drm_device *dev = encoder->dev;
970 struct drm_connector *connector;
f041b257 971 struct drm_display_mode *m;
04fc52fb 972 struct drm_connector_list_iter conn_iter;
f041b257
SP
973 int mode_ok;
974
f041b257
SP
975 drm_mode_set_crtcinfo(adjusted_mode, 0);
976
04fc52fb
MP
977 drm_connector_list_iter_begin(dev, &conn_iter);
978 drm_for_each_connector_iter(connector, &conn_iter) {
2b8376c8
GP
979 if (connector->encoder == encoder)
980 break;
981 }
04fc52fb
MP
982 if (connector)
983 drm_connector_get(connector);
984 drm_connector_list_iter_end(&conn_iter);
2b8376c8 985
04fc52fb 986 if (!connector)
2b8376c8
GP
987 return true;
988
d9716ee3 989 mode_ok = hdmi_mode_valid(connector, adjusted_mode);
f041b257 990
d9716ee3 991 if (mode_ok == MODE_OK)
04fc52fb 992 goto cleanup;
f041b257
SP
993
994 /*
5eefadb5 995 * Find the most suitable mode and copy it to adjusted_mode.
f041b257
SP
996 */
997 list_for_each_entry(m, &connector->modes, head) {
d9716ee3 998 mode_ok = hdmi_mode_valid(connector, m);
f041b257 999
d9716ee3 1000 if (mode_ok == MODE_OK) {
f041b257
SP
1001 DRM_INFO("desired mode doesn't exist so\n");
1002 DRM_INFO("use the most suitable mode among modes.\n");
1003
1004 DRM_DEBUG_KMS("Adjusted Mode: [%d]x[%d] [%d]Hz\n",
1005 m->hdisplay, m->vdisplay, m->vrefresh);
1006
75626853 1007 drm_mode_copy(adjusted_mode, m);
f041b257
SP
1008 break;
1009 }
1010 }
2b8376c8 1011
04fc52fb
MP
1012cleanup:
1013 drm_connector_put(connector);
1014
2b8376c8 1015 return true;
f041b257
SP
1016}
1017
d24bb3e5 1018static void hdmi_reg_acr(struct hdmi_context *hdata, u32 freq)
3e148baf
SWK
1019{
1020 u32 n, cts;
1021
d24bb3e5
AH
1022 cts = (freq % 9) ? 27000 : 30000;
1023 n = 128 * freq / (27000000 / cts);
3e148baf 1024
d24bb3e5
AH
1025 hdmi_reg_writev(hdata, HDMI_ACR_N0, 3, n);
1026 hdmi_reg_writev(hdata, HDMI_ACR_MCTS0, 3, cts);
1027 hdmi_reg_writev(hdata, HDMI_ACR_CTS0, 3, cts);
633d00b3 1028 hdmi_reg_writeb(hdata, HDMI_ACR_CON, 4);
3e148baf
SWK
1029}
1030
691da76f 1031static void hdmi_audio_config(struct hdmi_context *hdata)
3e148baf 1032{
691da76f
SN
1033 u32 bit_ch = 1;
1034 u32 data_num, val;
1035 int i;
3e148baf 1036
691da76f 1037 switch (hdata->audio.params.sample_width) {
3e148baf
SWK
1038 case 20:
1039 data_num = 2;
3e148baf
SWK
1040 break;
1041 case 24:
1042 data_num = 3;
3e148baf
SWK
1043 break;
1044 default:
1045 data_num = 1;
5eefadb5 1046 bit_ch = 0;
3e148baf
SWK
1047 break;
1048 }
1049
691da76f 1050 hdmi_reg_acr(hdata, hdata->audio.params.sample_rate);
3e148baf
SWK
1051
1052 hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CON, HDMI_I2S_IN_DISABLE
1053 | HDMI_I2S_AUD_I2S | HDMI_I2S_CUV_I2S_ENABLE
1054 | HDMI_I2S_MUX_ENABLE);
1055
1056 hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CH, HDMI_I2S_CH0_EN
1057 | HDMI_I2S_CH1_EN | HDMI_I2S_CH2_EN);
1058
1059 hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CUV, HDMI_I2S_CUV_RL_EN);
3e148baf
SWK
1060 hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_DIS);
1061 hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_EN);
1062
1063 val = hdmi_reg_read(hdata, HDMI_I2S_DSD_CON) | 0x01;
1064 hdmi_reg_writeb(hdata, HDMI_I2S_DSD_CON, val);
1065
1066 /* Configuration I2S input ports. Configure I2S_PIN_SEL_0~4 */
1067 hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_0, HDMI_I2S_SEL_SCLK(5)
1068 | HDMI_I2S_SEL_LRCK(6));
c84b66f8
SN
1069
1070 hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_1, HDMI_I2S_SEL_SDATA1(3)
1071 | HDMI_I2S_SEL_SDATA0(4));
1072
3e148baf
SWK
1073 hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_2, HDMI_I2S_SEL_SDATA3(1)
1074 | HDMI_I2S_SEL_SDATA2(2));
c84b66f8 1075
3e148baf
SWK
1076 hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_3, HDMI_I2S_SEL_DSD(0));
1077
1078 /* I2S_CON_1 & 2 */
1079 hdmi_reg_writeb(hdata, HDMI_I2S_CON_1, HDMI_I2S_SCLK_FALLING_EDGE
1080 | HDMI_I2S_L_CH_LOW_POL);
1081 hdmi_reg_writeb(hdata, HDMI_I2S_CON_2, HDMI_I2S_MSB_FIRST_MODE
1082 | HDMI_I2S_SET_BIT_CH(bit_ch)
1083 | HDMI_I2S_SET_SDATA_BIT(data_num)
1084 | HDMI_I2S_BASIC_FORMAT);
1085
691da76f
SN
1086 /* Configuration of the audio channel status registers */
1087 for (i = 0; i < HDMI_I2S_CH_ST_MAXNUM; i++)
1088 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST(i),
1089 hdata->audio.params.iec.status[i]);
3e148baf
SWK
1090
1091 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_CON, HDMI_I2S_CH_STATUS_RELOAD);
1092}
1093
691da76f 1094static void hdmi_audio_control(struct hdmi_context *hdata)
3e148baf 1095{
691da76f
SN
1096 bool enable = !hdata->audio.mute;
1097
872d20d6 1098 if (hdata->dvi_mode)
3e148baf
SWK
1099 return;
1100
691da76f
SN
1101 hdmi_reg_writeb(hdata, HDMI_AUI_CON, enable ?
1102 HDMI_AVI_CON_EVERY_VSYNC : HDMI_AUI_CON_NO_TRAN);
1103 hdmi_reg_writemask(hdata, HDMI_CON_0, enable ?
3e148baf
SWK
1104 HDMI_ASP_EN : HDMI_ASP_DIS, HDMI_ASP_MASK);
1105}
1106
bfa48423 1107static void hdmi_start(struct hdmi_context *hdata, bool start)
d8408326 1108{
991ea04e 1109 struct drm_display_mode *m = &hdata->encoder.crtc->state->mode;
bfa48423 1110 u32 val = start ? HDMI_TG_EN : 0;
3ecd70b1 1111
991ea04e 1112 if (m->flags & DRM_MODE_FLAG_INTERLACE)
bfa48423 1113 val |= HDMI_FIELD_EN;
3ecd70b1 1114
bfa48423
RS
1115 hdmi_reg_writemask(hdata, HDMI_CON_0, val, HDMI_EN);
1116 hdmi_reg_writemask(hdata, HDMI_TG_CMD, val, HDMI_TG_EN | HDMI_FIELD_EN);
d8408326
SWK
1117}
1118
1119static void hdmi_conf_init(struct hdmi_context *hdata)
1120{
77006a7a 1121 /* disable HPD interrupts from HDMI IP block, use GPIO instead */
d8408326
SWK
1122 hdmi_reg_writemask(hdata, HDMI_INTC_CON, 0, HDMI_INTC_EN_GLOBAL |
1123 HDMI_INTC_EN_HPD_PLUG | HDMI_INTC_EN_HPD_UNPLUG);
d8408326
SWK
1124
1125 /* choose HDMI mode */
1126 hdmi_reg_writemask(hdata, HDMI_MODE_SEL,
1127 HDMI_MODE_HDMI_EN, HDMI_MODE_MASK);
5eefadb5 1128 /* apply video pre-amble and guard band in HDMI mode only */
9a8e1cb0 1129 hdmi_reg_writeb(hdata, HDMI_CON_2, 0);
d8408326
SWK
1130 /* disable bluescreen */
1131 hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_BLUE_SCR_EN);
3ecd70b1 1132
872d20d6 1133 if (hdata->dvi_mode) {
872d20d6
SWK
1134 hdmi_reg_writemask(hdata, HDMI_MODE_SEL,
1135 HDMI_MODE_DVI_EN, HDMI_MODE_MASK);
1136 hdmi_reg_writeb(hdata, HDMI_CON_2,
1137 HDMI_VID_PREAMBLE_DIS | HDMI_GUARD_BAND_DIS);
1138 }
1139
cd240cde 1140 if (hdata->drv_data->type == HDMI_TYPE13) {
3ecd70b1
JS
1141 /* choose bluescreen (fecal) color */
1142 hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_0, 0x12);
1143 hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_1, 0x34);
1144 hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_2, 0x56);
1145
1146 /* enable AVI packet every vsync, fixes purple line problem */
1147 hdmi_reg_writeb(hdata, HDMI_V13_AVI_CON, 0x02);
1148 /* force RGB, look to CEA-861-D, table 7 for more detail */
1149 hdmi_reg_writeb(hdata, HDMI_V13_AVI_BYTE(0), 0 << 5);
1150 hdmi_reg_writemask(hdata, HDMI_CON_1, 0x10 << 5, 0x11 << 5);
1151
1152 hdmi_reg_writeb(hdata, HDMI_V13_SPD_CON, 0x02);
1153 hdmi_reg_writeb(hdata, HDMI_V13_AUI_CON, 0x02);
1154 hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 0x04);
1155 } else {
5f9e228d 1156 hdmi_reg_infoframes(hdata);
a144c2e9 1157
3ecd70b1 1158 /* enable AVI packet every vsync, fixes purple line problem */
3ecd70b1
JS
1159 hdmi_reg_writemask(hdata, HDMI_CON_1, 2, 3 << 5);
1160 }
d8408326
SWK
1161}
1162
8eb6d4ec
AH
1163static void hdmiphy_wait_for_pll(struct hdmi_context *hdata)
1164{
1165 int tries;
1166
1167 for (tries = 0; tries < 10; ++tries) {
1168 u32 val = hdmi_reg_read(hdata, HDMI_PHY_STATUS);
1169
1170 if (val & HDMI_PHY_STATUS_READY) {
1171 DRM_DEBUG_KMS("PLL stabilized after %d tries\n", tries);
1172 return;
1173 }
1174 usleep_range(10, 20);
1175 }
1176
1177 DRM_ERROR("PLL could not reach steady state\n");
1178}
1179
16844fb1 1180static void hdmi_v13_mode_apply(struct hdmi_context *hdata)
d8408326 1181{
991ea04e 1182 struct drm_display_mode *m = &hdata->encoder.crtc->state->mode;
edb6e412 1183 unsigned int val;
3ecd70b1 1184
edb6e412
AH
1185 hdmi_reg_writev(hdata, HDMI_H_BLANK_0, 2, m->htotal - m->hdisplay);
1186 hdmi_reg_writev(hdata, HDMI_V13_H_V_LINE_0, 3,
1187 (m->htotal << 12) | m->vtotal);
1188
1189 val = (m->flags & DRM_MODE_FLAG_NVSYNC) ? 1 : 0;
1190 hdmi_reg_writev(hdata, HDMI_VSYNC_POL, 1, val);
1191
1192 val = (m->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0;
1193 hdmi_reg_writev(hdata, HDMI_INT_PRO_MODE, 1, val);
1194
1195 val = (m->hsync_start - m->hdisplay - 2);
1196 val |= ((m->hsync_end - m->hdisplay - 2) << 10);
5eefadb5 1197 val |= ((m->flags & DRM_MODE_FLAG_NHSYNC) ? 1 : 0)<<20;
edb6e412
AH
1198 hdmi_reg_writev(hdata, HDMI_V13_H_SYNC_GEN_0, 3, val);
1199
1200 /*
1201 * Quirk requirement for exynos HDMI IP design,
1202 * 2 pixels less than the actual calculation for hsync_start
1203 * and end.
1204 */
1205
1206 /* Following values & calculations differ for different type of modes */
1207 if (m->flags & DRM_MODE_FLAG_INTERLACE) {
edb6e412
AH
1208 val = ((m->vsync_end - m->vdisplay) / 2);
1209 val |= ((m->vsync_start - m->vdisplay) / 2) << 12;
1210 hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_1_0, 3, val);
1211
1212 val = m->vtotal / 2;
1213 val |= ((m->vtotal - m->vdisplay) / 2) << 11;
1214 hdmi_reg_writev(hdata, HDMI_V13_V_BLANK_0, 3, val);
1215
1216 val = (m->vtotal +
1217 ((m->vsync_end - m->vsync_start) * 4) + 5) / 2;
1218 val |= m->vtotal << 11;
1219 hdmi_reg_writev(hdata, HDMI_V13_V_BLANK_F_0, 3, val);
1220
1221 val = ((m->vtotal / 2) + 7);
1222 val |= ((m->vtotal / 2) + 2) << 12;
1223 hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_2_0, 3, val);
1224
1225 val = ((m->htotal / 2) + (m->hsync_start - m->hdisplay));
1226 val |= ((m->htotal / 2) +
1227 (m->hsync_start - m->hdisplay)) << 12;
1228 hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_3_0, 3, val);
1229
1230 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2,
1231 (m->vtotal - m->vdisplay) / 2);
1232 hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay / 2);
1233
1234 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST2_L, 2, 0x249);
1235 } else {
edb6e412
AH
1236 val = m->vtotal;
1237 val |= (m->vtotal - m->vdisplay) << 11;
1238 hdmi_reg_writev(hdata, HDMI_V13_V_BLANK_0, 3, val);
1239
1240 hdmi_reg_writev(hdata, HDMI_V13_V_BLANK_F_0, 3, 0);
1241
1242 val = (m->vsync_end - m->vdisplay);
1243 val |= ((m->vsync_start - m->vdisplay) << 12);
1244 hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_1_0, 3, val);
1245
1246 hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_2_0, 3, 0x1001);
1247 hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_3_0, 3, 0x1001);
1248 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2,
1249 m->vtotal - m->vdisplay);
1250 hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay);
edb6e412
AH
1251 }
1252
edb6e412
AH
1253 hdmi_reg_writev(hdata, HDMI_TG_H_FSZ_L, 2, m->htotal);
1254 hdmi_reg_writev(hdata, HDMI_TG_HACT_ST_L, 2, m->htotal - m->hdisplay);
1255 hdmi_reg_writev(hdata, HDMI_TG_HACT_SZ_L, 2, m->hdisplay);
1256 hdmi_reg_writev(hdata, HDMI_TG_V_FSZ_L, 2, m->vtotal);
3ecd70b1
JS
1257}
1258
16844fb1 1259static void hdmi_v14_mode_apply(struct hdmi_context *hdata)
3ecd70b1 1260{
991ea04e 1261 struct drm_display_mode *m = &hdata->encoder.crtc->state->mode;
36fd887a
AH
1262 struct drm_display_mode *am =
1263 &hdata->encoder.crtc->state->adjusted_mode;
1264 int hquirk = 0;
1265
1266 /*
1267 * In case video mode coming from CRTC differs from requested one HDMI
1268 * sometimes is able to almost properly perform conversion - only
1269 * first line is distorted.
1270 */
1271 if ((m->vdisplay != am->vdisplay) &&
ae58c03e 1272 (m->hdisplay == 1280 || m->hdisplay == 1024 || m->hdisplay == 1366))
36fd887a 1273 hquirk = 258;
d8408326 1274
7b5102da
AH
1275 hdmi_reg_writev(hdata, HDMI_H_BLANK_0, 2, m->htotal - m->hdisplay);
1276 hdmi_reg_writev(hdata, HDMI_V_LINE_0, 2, m->vtotal);
1277 hdmi_reg_writev(hdata, HDMI_H_LINE_0, 2, m->htotal);
1278 hdmi_reg_writev(hdata, HDMI_HSYNC_POL, 1,
5eefadb5 1279 (m->flags & DRM_MODE_FLAG_NHSYNC) ? 1 : 0);
7b5102da
AH
1280 hdmi_reg_writev(hdata, HDMI_VSYNC_POL, 1,
1281 (m->flags & DRM_MODE_FLAG_NVSYNC) ? 1 : 0);
1282 hdmi_reg_writev(hdata, HDMI_INT_PRO_MODE, 1,
1283 (m->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0);
1284
1285 /*
1286 * Quirk requirement for exynos 5 HDMI IP design,
1287 * 2 pixels less than the actual calculation for hsync_start
1288 * and end.
1289 */
1290
1291 /* Following values & calculations differ for different type of modes */
1292 if (m->flags & DRM_MODE_FLAG_INTERLACE) {
7b5102da
AH
1293 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_2_0, 2,
1294 (m->vsync_end - m->vdisplay) / 2);
1295 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_1_0, 2,
1296 (m->vsync_start - m->vdisplay) / 2);
1297 hdmi_reg_writev(hdata, HDMI_V2_BLANK_0, 2, m->vtotal / 2);
1298 hdmi_reg_writev(hdata, HDMI_V1_BLANK_0, 2,
1299 (m->vtotal - m->vdisplay) / 2);
1300 hdmi_reg_writev(hdata, HDMI_V_BLANK_F0_0, 2,
1301 m->vtotal - m->vdisplay / 2);
1302 hdmi_reg_writev(hdata, HDMI_V_BLANK_F1_0, 2, m->vtotal);
1303 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_2_0, 2,
1304 (m->vtotal / 2) + 7);
1305 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_1_0, 2,
1306 (m->vtotal / 2) + 2);
1307 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_0, 2,
1308 (m->htotal / 2) + (m->hsync_start - m->hdisplay));
1309 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_0, 2,
1310 (m->htotal / 2) + (m->hsync_start - m->hdisplay));
1311 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2,
1312 (m->vtotal - m->vdisplay) / 2);
1313 hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay / 2);
1314 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST2_L, 2,
1315 m->vtotal - m->vdisplay / 2);
1316 hdmi_reg_writev(hdata, HDMI_TG_VSYNC2_L, 2,
1317 (m->vtotal / 2) + 1);
1318 hdmi_reg_writev(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, 2,
1319 (m->vtotal / 2) + 1);
1320 hdmi_reg_writev(hdata, HDMI_TG_FIELD_BOT_HDMI_L, 2,
1321 (m->vtotal / 2) + 1);
1322 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST3_L, 2, 0x0);
1323 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST4_L, 2, 0x0);
1324 } else {
7b5102da
AH
1325 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_2_0, 2,
1326 m->vsync_end - m->vdisplay);
1327 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_1_0, 2,
1328 m->vsync_start - m->vdisplay);
1329 hdmi_reg_writev(hdata, HDMI_V2_BLANK_0, 2, m->vtotal);
1330 hdmi_reg_writev(hdata, HDMI_V1_BLANK_0, 2,
1331 m->vtotal - m->vdisplay);
1332 hdmi_reg_writev(hdata, HDMI_V_BLANK_F0_0, 2, 0xffff);
1333 hdmi_reg_writev(hdata, HDMI_V_BLANK_F1_0, 2, 0xffff);
1334 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_2_0, 2, 0xffff);
1335 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_1_0, 2, 0xffff);
1336 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_0, 2, 0xffff);
1337 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_0, 2, 0xffff);
1338 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2,
1339 m->vtotal - m->vdisplay);
1340 hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay);
7b5102da
AH
1341 }
1342
7b5102da
AH
1343 hdmi_reg_writev(hdata, HDMI_H_SYNC_START_0, 2,
1344 m->hsync_start - m->hdisplay - 2);
1345 hdmi_reg_writev(hdata, HDMI_H_SYNC_END_0, 2,
1346 m->hsync_end - m->hdisplay - 2);
1347 hdmi_reg_writev(hdata, HDMI_VACT_SPACE_1_0, 2, 0xffff);
1348 hdmi_reg_writev(hdata, HDMI_VACT_SPACE_2_0, 2, 0xffff);
1349 hdmi_reg_writev(hdata, HDMI_VACT_SPACE_3_0, 2, 0xffff);
1350 hdmi_reg_writev(hdata, HDMI_VACT_SPACE_4_0, 2, 0xffff);
1351 hdmi_reg_writev(hdata, HDMI_VACT_SPACE_5_0, 2, 0xffff);
1352 hdmi_reg_writev(hdata, HDMI_VACT_SPACE_6_0, 2, 0xffff);
1353 hdmi_reg_writev(hdata, HDMI_V_BLANK_F2_0, 2, 0xffff);
1354 hdmi_reg_writev(hdata, HDMI_V_BLANK_F3_0, 2, 0xffff);
1355 hdmi_reg_writev(hdata, HDMI_V_BLANK_F4_0, 2, 0xffff);
1356 hdmi_reg_writev(hdata, HDMI_V_BLANK_F5_0, 2, 0xffff);
1357 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_3_0, 2, 0xffff);
1358 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_4_0, 2, 0xffff);
1359 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_5_0, 2, 0xffff);
1360 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_6_0, 2, 0xffff);
1361 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_3_0, 2, 0xffff);
1362 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_4_0, 2, 0xffff);
1363 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_5_0, 2, 0xffff);
1364 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_0, 2, 0xffff);
3ecd70b1 1365
7b5102da 1366 hdmi_reg_writev(hdata, HDMI_TG_H_FSZ_L, 2, m->htotal);
36fd887a
AH
1367 hdmi_reg_writev(hdata, HDMI_TG_HACT_ST_L, 2,
1368 m->htotal - m->hdisplay - hquirk);
1369 hdmi_reg_writev(hdata, HDMI_TG_HACT_SZ_L, 2, m->hdisplay + hquirk);
7b5102da 1370 hdmi_reg_writev(hdata, HDMI_TG_V_FSZ_L, 2, m->vtotal);
68cd004e
AH
1371 if (hdata->drv_data == &exynos5433_hdmi_driver_data)
1372 hdmi_reg_writeb(hdata, HDMI_TG_DECON_EN, 1);
d8408326
SWK
1373}
1374
16844fb1 1375static void hdmi_mode_apply(struct hdmi_context *hdata)
3ecd70b1 1376{
cd240cde 1377 if (hdata->drv_data->type == HDMI_TYPE13)
16844fb1 1378 hdmi_v13_mode_apply(hdata);
3ecd70b1 1379 else
16844fb1 1380 hdmi_v14_mode_apply(hdata);
8eb6d4ec 1381
8eb6d4ec 1382 hdmi_start(hdata, true);
3ecd70b1
JS
1383}
1384
d8408326
SWK
1385static void hdmiphy_conf_reset(struct hdmi_context *hdata)
1386{
69f88877
AH
1387 hdmi_reg_writemask(hdata, HDMI_CORE_RSTOUT, 0, 1);
1388 usleep_range(10000, 12000);
1389 hdmi_reg_writemask(hdata, HDMI_CORE_RSTOUT, ~0, 1);
1390 usleep_range(10000, 12000);
633d00b3 1391 hdmi_reg_writemask(hdata, HDMI_PHY_RSTOUT, ~0, HDMI_PHY_SW_RSTOUT);
09760ea3 1392 usleep_range(10000, 12000);
5eefadb5 1393 hdmi_reg_writemask(hdata, HDMI_PHY_RSTOUT, 0, HDMI_PHY_SW_RSTOUT);
09760ea3 1394 usleep_range(10000, 12000);
d8408326
SWK
1395}
1396
68cd004e
AH
1397static void hdmiphy_enable_mode_set(struct hdmi_context *hdata, bool enable)
1398{
1399 u8 v = enable ? HDMI_PHY_ENABLE_MODE_SET : HDMI_PHY_DISABLE_MODE_SET;
1400
1401 if (hdata->drv_data == &exynos5433_hdmi_driver_data)
1402 writel(v, hdata->regs_hdmiphy + HDMIPHY5433_MODE_SET_DONE);
1403}
1404
d8408326
SWK
1405static void hdmiphy_conf_apply(struct hdmi_context *hdata)
1406{
991ea04e 1407 struct drm_display_mode *m = &hdata->encoder.crtc->state->mode;
d8408326 1408 int ret;
4677f51a 1409 const u8 *phy_conf;
d8408326 1410
991ea04e 1411 ret = hdmi_find_phy_conf(hdata, m->clock * 1000);
4677f51a 1412 if (ret < 0) {
6b986edf
RS
1413 DRM_ERROR("failed to find hdmiphy conf\n");
1414 return;
1415 }
4677f51a
AH
1416 phy_conf = hdata->drv_data->phy_confs.data[ret].conf;
1417
1418 hdmi_clk_set_parents(hdata, false);
1419
1420 hdmiphy_conf_reset(hdata);
6b986edf 1421
68cd004e 1422 hdmiphy_enable_mode_set(hdata, true);
4677f51a 1423 ret = hdmiphy_reg_write_buf(hdata, 0, phy_conf, 32);
d5e9ca4c
RS
1424 if (ret) {
1425 DRM_ERROR("failed to configure hdmiphy\n");
d8408326
SWK
1426 return;
1427 }
68cd004e 1428 hdmiphy_enable_mode_set(hdata, false);
4677f51a 1429 hdmi_clk_set_parents(hdata, true);
09760ea3 1430 usleep_range(10000, 12000);
4677f51a 1431 hdmiphy_wait_for_pll(hdata);
d8408326
SWK
1432}
1433
691da76f 1434/* Should be called with hdata->mutex mutex held */
d8408326
SWK
1435static void hdmi_conf_apply(struct hdmi_context *hdata)
1436{
bfa48423 1437 hdmi_start(hdata, false);
d8408326 1438 hdmi_conf_init(hdata);
691da76f 1439 hdmi_audio_config(hdata);
16844fb1 1440 hdmi_mode_apply(hdata);
691da76f 1441 hdmi_audio_control(hdata);
d8408326
SWK
1442}
1443
68cd004e
AH
1444static void hdmi_set_refclk(struct hdmi_context *hdata, bool on)
1445{
1446 if (!hdata->sysreg)
1447 return;
1448
1449 regmap_update_bits(hdata->sysreg, EXYNOS5433_SYSREG_DISP_HDMI_PHY,
1450 SYSREG_HDMI_REFCLK_INT_CLK, on ? ~0 : 0);
1451}
1452
691da76f 1453/* Should be called with hdata->mutex mutex held. */
59b62d3c 1454static void hdmiphy_enable(struct hdmi_context *hdata)
cf8fc4f1 1455{
882a0644 1456 if (hdata->powered)
cf8fc4f1 1457 return;
d8408326 1458
af65c804
SP
1459 pm_runtime_get_sync(hdata->dev);
1460
af1f7c24 1461 if (regulator_bulk_enable(ARRAY_SIZE(supply), hdata->regul_bulk))
ad07945a
SWK
1462 DRM_DEBUG_KMS("failed to enable regulator bulk\n");
1463
049d34e9
RS
1464 regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL,
1465 PMU_HDMI_PHY_ENABLE_BIT, 1);
1466
68cd004e
AH
1467 hdmi_set_refclk(hdata, true);
1468
5dd45e2c
AH
1469 hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, 0, HDMI_PHY_POWER_OFF_EN);
1470
59b62d3c 1471 hdmiphy_conf_apply(hdata);
f28464c3
GP
1472
1473 hdata->powered = true;
cf8fc4f1
JS
1474}
1475
691da76f 1476/* Should be called with hdata->mutex mutex held. */
59b62d3c
AH
1477static void hdmiphy_disable(struct hdmi_context *hdata)
1478{
1479 if (!hdata->powered)
1480 return;
1481
1482 hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_EN);
1483
1484 hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, ~0, HDMI_PHY_POWER_OFF_EN);
1485
1486 hdmi_set_refclk(hdata, false);
1487
1488 regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL,
1489 PMU_HDMI_PHY_ENABLE_BIT, 0);
1490
1491 regulator_bulk_disable(ARRAY_SIZE(supply), hdata->regul_bulk);
1492
1493 pm_runtime_put_sync(hdata->dev);
1494
1495 hdata->powered = false;
1496}
1497
1498static void hdmi_enable(struct drm_encoder *encoder)
1499{
1500 struct hdmi_context *hdata = encoder_to_hdmi(encoder);
1501
691da76f
SN
1502 mutex_lock(&hdata->mutex);
1503
59b62d3c
AH
1504 hdmiphy_enable(hdata);
1505 hdmi_conf_apply(hdata);
691da76f
SN
1506
1507 mutex_unlock(&hdata->mutex);
59b62d3c
AH
1508}
1509
2b8376c8 1510static void hdmi_disable(struct drm_encoder *encoder)
cf8fc4f1 1511{
cf67cc9a 1512 struct hdmi_context *hdata = encoder_to_hdmi(encoder);
cf8fc4f1 1513
691da76f
SN
1514 mutex_lock(&hdata->mutex);
1515
1516 if (hdata->powered) {
1517 /*
1518 * The SFRs of VP and Mixer are updated by Vertical Sync of
1519 * Timing generator which is a part of HDMI so the sequence
1520 * to disable TV Subsystem should be as following,
1521 * VP -> Mixer -> HDMI
1522 *
1523 * To achieve such sequence HDMI is disabled together with
1524 * HDMI PHY, via pipe clock callback.
1525 */
1526 mutex_unlock(&hdata->mutex);
1527 cancel_delayed_work(&hdata->hotplug_work);
1528 cec_notifier_set_phys_addr(hdata->notifier,
1529 CEC_PHYS_ADDR_INVALID);
882a0644 1530 return;
691da76f 1531 }
cf8fc4f1 1532
691da76f 1533 mutex_unlock(&hdata->mutex);
d8408326
SWK
1534}
1535
800ba2b5 1536static const struct drm_encoder_helper_funcs exynos_hdmi_encoder_helper_funcs = {
f041b257 1537 .mode_fixup = hdmi_mode_fixup,
b6595dc7
GP
1538 .enable = hdmi_enable,
1539 .disable = hdmi_disable,
d8408326
SWK
1540};
1541
800ba2b5 1542static const struct drm_encoder_funcs exynos_hdmi_encoder_funcs = {
2b8376c8
GP
1543 .destroy = drm_encoder_cleanup,
1544};
1545
691da76f
SN
1546static void hdmi_audio_shutdown(struct device *dev, void *data)
1547{
1548 struct hdmi_context *hdata = dev_get_drvdata(dev);
1549
1550 mutex_lock(&hdata->mutex);
1551
1552 hdata->audio.mute = true;
1553
1554 if (hdata->powered)
1555 hdmi_audio_control(hdata);
1556
1557 mutex_unlock(&hdata->mutex);
1558}
1559
1560static int hdmi_audio_hw_params(struct device *dev, void *data,
1561 struct hdmi_codec_daifmt *daifmt,
1562 struct hdmi_codec_params *params)
1563{
1564 struct hdmi_context *hdata = dev_get_drvdata(dev);
1565
1566 if (daifmt->fmt != HDMI_I2S || daifmt->bit_clk_inv ||
1567 daifmt->frame_clk_inv || daifmt->bit_clk_master ||
1568 daifmt->frame_clk_master) {
1569 dev_err(dev, "%s: Bad flags %d %d %d %d\n", __func__,
1570 daifmt->bit_clk_inv, daifmt->frame_clk_inv,
1571 daifmt->bit_clk_master,
1572 daifmt->frame_clk_master);
1573 return -EINVAL;
1574 }
1575
1576 mutex_lock(&hdata->mutex);
1577
1578 hdata->audio.params = *params;
1579
1580 if (hdata->powered) {
1581 hdmi_audio_config(hdata);
1582 hdmi_audio_infoframe_apply(hdata);
1583 }
1584
1585 mutex_unlock(&hdata->mutex);
1586
1587 return 0;
1588}
1589
1590static int hdmi_audio_digital_mute(struct device *dev, void *data, bool mute)
1591{
1592 struct hdmi_context *hdata = dev_get_drvdata(dev);
1593
1594 mutex_lock(&hdata->mutex);
1595
1596 hdata->audio.mute = mute;
1597
1598 if (hdata->powered)
1599 hdmi_audio_control(hdata);
1600
1601 mutex_unlock(&hdata->mutex);
1602
1603 return 0;
1604}
1605
1606static int hdmi_audio_get_eld(struct device *dev, void *data, uint8_t *buf,
1607 size_t len)
1608{
1609 struct hdmi_context *hdata = dev_get_drvdata(dev);
1610 struct drm_connector *connector = &hdata->connector;
1611
1612 memcpy(buf, connector->eld, min(sizeof(connector->eld), len));
1613
1614 return 0;
1615}
1616
1617static const struct hdmi_codec_ops audio_codec_ops = {
1618 .hw_params = hdmi_audio_hw_params,
1619 .audio_shutdown = hdmi_audio_shutdown,
1620 .digital_mute = hdmi_audio_digital_mute,
1621 .get_eld = hdmi_audio_get_eld,
1622};
1623
1624static int hdmi_register_audio_device(struct hdmi_context *hdata)
1625{
1626 struct hdmi_codec_pdata codec_data = {
1627 .ops = &audio_codec_ops,
1628 .max_i2s_channels = 6,
1629 .i2s = 1,
1630 };
1631
1632 hdata->audio.pdev = platform_device_register_data(
1633 hdata->dev, HDMI_CODEC_DRV_NAME, PLATFORM_DEVID_AUTO,
1634 &codec_data, sizeof(codec_data));
1635
1636 return PTR_ERR_OR_ZERO(hdata->audio.pdev);
1637}
1638
724fd140 1639static void hdmi_hotplug_work_func(struct work_struct *work)
cf8fc4f1 1640{
724fd140
SP
1641 struct hdmi_context *hdata;
1642
1643 hdata = container_of(work, struct hdmi_context, hotplug_work.work);
cf8fc4f1 1644
4551789f
SP
1645 if (hdata->drm_dev)
1646 drm_helper_hpd_irq_event(hdata->drm_dev);
724fd140
SP
1647}
1648
1649static irqreturn_t hdmi_irq_thread(int irq, void *arg)
1650{
1651 struct hdmi_context *hdata = arg;
1652
1653 mod_delayed_work(system_wq, &hdata->hotplug_work,
1654 msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS));
cf8fc4f1 1655
cf8fc4f1
JS
1656 return IRQ_HANDLED;
1657}
1658
9be7e989
AH
1659static int hdmi_clks_get(struct hdmi_context *hdata,
1660 const struct string_array_spec *names,
1661 struct clk **clks)
1662{
1663 struct device *dev = hdata->dev;
1664 int i;
1665
1666 for (i = 0; i < names->count; ++i) {
1667 struct clk *clk = devm_clk_get(dev, names->data[i]);
1668
1669 if (IS_ERR(clk)) {
1670 int ret = PTR_ERR(clk);
1671
1672 dev_err(dev, "Cannot get clock %s, %d\n",
1673 names->data[i], ret);
1674
1675 return ret;
1676 }
1677
1678 clks[i] = clk;
1679 }
1680
1681 return 0;
1682}
1683
1684static int hdmi_clk_init(struct hdmi_context *hdata)
1685{
1686 const struct hdmi_driver_data *drv_data = hdata->drv_data;
1687 int count = drv_data->clk_gates.count + drv_data->clk_muxes.count;
1688 struct device *dev = hdata->dev;
1689 struct clk **clks;
1690 int ret;
1691
1692 if (!count)
1693 return 0;
1694
a86854d0 1695 clks = devm_kcalloc(dev, count, sizeof(*clks), GFP_KERNEL);
9be7e989 1696 if (!clks)
f9628c2a 1697 return -ENOMEM;
9be7e989
AH
1698
1699 hdata->clk_gates = clks;
1700 hdata->clk_muxes = clks + drv_data->clk_gates.count;
1701
1702 ret = hdmi_clks_get(hdata, &drv_data->clk_gates, hdata->clk_gates);
1703 if (ret)
1704 return ret;
1705
1706 return hdmi_clks_get(hdata, &drv_data->clk_muxes, hdata->clk_muxes);
1707}
1708
1709
59b62d3c
AH
1710static void hdmiphy_clk_enable(struct exynos_drm_clk *clk, bool enable)
1711{
1712 struct hdmi_context *hdata = container_of(clk, struct hdmi_context,
1713 phy_clk);
691da76f 1714 mutex_lock(&hdata->mutex);
59b62d3c
AH
1715
1716 if (enable)
1717 hdmiphy_enable(hdata);
1718 else
1719 hdmiphy_disable(hdata);
691da76f
SN
1720
1721 mutex_unlock(&hdata->mutex);
59b62d3c
AH
1722}
1723
aa181570
AH
1724static int hdmi_bridge_init(struct hdmi_context *hdata)
1725{
1726 struct device *dev = hdata->dev;
1727 struct device_node *ep, *np;
1728
1729 ep = of_graph_get_endpoint_by_regs(dev->of_node, 1, -1);
1730 if (!ep)
1731 return 0;
1732
1733 np = of_graph_get_remote_port_parent(ep);
1734 of_node_put(ep);
1735 if (!np) {
1736 DRM_ERROR("failed to get remote port parent");
1737 return -EINVAL;
1738 }
1739
1740 hdata->bridge = of_drm_find_bridge(np);
1741 of_node_put(np);
1742
1743 if (!hdata->bridge)
1744 return -EPROBE_DEFER;
1745
1746 return 0;
1747}
1748
56550d94 1749static int hdmi_resources_init(struct hdmi_context *hdata)
d8408326
SWK
1750{
1751 struct device *dev = hdata->dev;
d8408326
SWK
1752 int i, ret;
1753
1754 DRM_DEBUG_KMS("HDMI resource init\n");
1755
2228b7cd
AH
1756 hdata->hpd_gpio = devm_gpiod_get(dev, "hpd", GPIOD_IN);
1757 if (IS_ERR(hdata->hpd_gpio)) {
1758 DRM_ERROR("cannot get hpd gpio property\n");
1759 return PTR_ERR(hdata->hpd_gpio);
1760 }
1761
1762 hdata->irq = gpiod_to_irq(hdata->hpd_gpio);
1763 if (hdata->irq < 0) {
1764 DRM_ERROR("failed to get GPIO irq\n");
1765 return hdata->irq;
1766 }
d8408326 1767
9be7e989
AH
1768 ret = hdmi_clk_init(hdata);
1769 if (ret)
1770 return ret;
1771
1772 ret = hdmi_clk_set_parents(hdata, false);
1773 if (ret)
1774 return ret;
d8408326 1775
c0d656dd 1776 for (i = 0; i < ARRAY_SIZE(supply); ++i)
af1f7c24 1777 hdata->regul_bulk[i].supply = supply[i];
c0d656dd 1778
af1f7c24 1779 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(supply), hdata->regul_bulk);
d8408326 1780 if (ret) {
b85881dd
JMC
1781 if (ret != -EPROBE_DEFER)
1782 DRM_ERROR("failed to get regulators\n");
df5225bc 1783 return ret;
d8408326 1784 }
d8408326 1785
af1f7c24 1786 hdata->reg_hdmi_en = devm_regulator_get_optional(dev, "hdmi-en");
498d5a37 1787
aa181570
AH
1788 if (PTR_ERR(hdata->reg_hdmi_en) != -ENODEV) {
1789 if (IS_ERR(hdata->reg_hdmi_en))
1790 return PTR_ERR(hdata->reg_hdmi_en);
498d5a37 1791
aa181570
AH
1792 ret = regulator_enable(hdata->reg_hdmi_en);
1793 if (ret) {
1794 DRM_ERROR("failed to enable hdmi-en regulator\n");
1795 return ret;
1796 }
1797 }
05fdf987 1798
aa181570 1799 return hdmi_bridge_init(hdata);
d8408326
SWK
1800}
1801
e3cc51ea 1802static const struct of_device_id hdmi_match_types[] = {
22c4f428 1803 {
ff830c96
MS
1804 .compatible = "samsung,exynos4210-hdmi",
1805 .data = &exynos4210_hdmi_driver_data,
cc57caf0
RS
1806 }, {
1807 .compatible = "samsung,exynos4212-hdmi",
bfe4e84c 1808 .data = &exynos4212_hdmi_driver_data,
a18a2dda
RS
1809 }, {
1810 .compatible = "samsung,exynos5420-hdmi",
1811 .data = &exynos5420_hdmi_driver_data,
68cd004e
AH
1812 }, {
1813 .compatible = "samsung,exynos5433-hdmi",
1814 .data = &exynos5433_hdmi_driver_data,
c119ed05
TS
1815 }, {
1816 /* end node */
1817 }
1818};
39b58a39 1819MODULE_DEVICE_TABLE (of, hdmi_match_types);
c119ed05 1820
f37cd5e8
ID
1821static int hdmi_bind(struct device *dev, struct device *master, void *data)
1822{
1823 struct drm_device *drm_dev = data;
930865fb 1824 struct hdmi_context *hdata = dev_get_drvdata(dev);
2b8376c8 1825 struct drm_encoder *encoder = &hdata->encoder;
1ca582f1
AH
1826 struct exynos_drm_crtc *crtc;
1827 int ret;
f37cd5e8 1828
f37cd5e8
ID
1829 hdata->drm_dev = drm_dev;
1830
59b62d3c
AH
1831 hdata->phy_clk.enable = hdmiphy_clk_enable;
1832
2b8376c8 1833 drm_encoder_init(drm_dev, encoder, &exynos_hdmi_encoder_funcs,
13a3d91f 1834 DRM_MODE_ENCODER_TMDS, NULL);
2b8376c8
GP
1835
1836 drm_encoder_helper_add(encoder, &exynos_hdmi_encoder_helper_funcs);
a2986e80 1837
1ca582f1
AH
1838 ret = exynos_drm_set_possible_crtcs(encoder, EXYNOS_DISPLAY_TYPE_HDMI);
1839 if (ret < 0)
1840 return ret;
1841
1842 crtc = exynos_drm_crtc_get_by_type(drm_dev, EXYNOS_DISPLAY_TYPE_HDMI);
1843 crtc->pipe_clk = &hdata->phy_clk;
1844
2b8376c8 1845 ret = hdmi_create_connector(encoder);
a2986e80
GP
1846 if (ret) {
1847 DRM_ERROR("failed to create connector ret = %d\n", ret);
2b8376c8 1848 drm_encoder_cleanup(encoder);
a2986e80
GP
1849 return ret;
1850 }
1851
1852 return 0;
f37cd5e8
ID
1853}
1854
1855static void hdmi_unbind(struct device *dev, struct device *master, void *data)
1856{
f37cd5e8
ID
1857}
1858
1859static const struct component_ops hdmi_component_ops = {
1860 .bind = hdmi_bind,
1861 .unbind = hdmi_unbind,
1862};
1863
1caa360e 1864static int hdmi_get_ddc_adapter(struct hdmi_context *hdata)
e2a562dc
ID
1865{
1866 const char *compatible_str = "samsung,exynos4210-hdmiddc";
1867 struct device_node *np;
1caa360e 1868 struct i2c_adapter *adpt;
e2a562dc
ID
1869
1870 np = of_find_compatible_node(NULL, NULL, compatible_str);
1871 if (np)
1caa360e
MK
1872 np = of_get_next_parent(np);
1873 else
1874 np = of_parse_phandle(hdata->dev->of_node, "ddc", 0);
1875
1876 if (!np) {
1877 DRM_ERROR("Failed to find ddc node in device tree\n");
1878 return -ENODEV;
1879 }
1880
1881 adpt = of_find_i2c_adapter_by_node(np);
1882 of_node_put(np);
e2a562dc 1883
1caa360e
MK
1884 if (!adpt) {
1885 DRM_INFO("Failed to get ddc i2c adapter by node\n");
1886 return -EPROBE_DEFER;
1887 }
1888
1889 hdata->ddc_adpt = adpt;
1890
1891 return 0;
e2a562dc
ID
1892}
1893
b5413022 1894static int hdmi_get_phy_io(struct hdmi_context *hdata)
e2a562dc
ID
1895{
1896 const char *compatible_str = "samsung,exynos4212-hdmiphy";
b5413022
MK
1897 struct device_node *np;
1898 int ret = 0;
1899
1900 np = of_find_compatible_node(NULL, NULL, compatible_str);
1901 if (!np) {
1902 np = of_parse_phandle(hdata->dev->of_node, "phy", 0);
1903 if (!np) {
1904 DRM_ERROR("Failed to find hdmiphy node in device tree\n");
1905 return -ENODEV;
1906 }
1907 }
1908
1909 if (hdata->drv_data->is_apb_phy) {
1910 hdata->regs_hdmiphy = of_iomap(np, 0);
1911 if (!hdata->regs_hdmiphy) {
1912 DRM_ERROR("failed to ioremap hdmi phy\n");
1913 ret = -ENOMEM;
1914 goto out;
1915 }
1916 } else {
1917 hdata->hdmiphy_port = of_find_i2c_device_by_node(np);
1918 if (!hdata->hdmiphy_port) {
1919 DRM_INFO("Failed to get hdmi phy i2c client\n");
1920 ret = -EPROBE_DEFER;
1921 goto out;
1922 }
1923 }
e2a562dc 1924
b5413022
MK
1925out:
1926 of_node_put(np);
1927 return ret;
e2a562dc
ID
1928}
1929
56550d94 1930static int hdmi_probe(struct platform_device *pdev)
d8408326 1931{
691da76f 1932 struct hdmi_audio_infoframe *audio_infoframe;
d8408326 1933 struct device *dev = &pdev->dev;
d8408326 1934 struct hdmi_context *hdata;
d8408326
SWK
1935 struct resource *res;
1936 int ret;
1937
88c49815 1938 hdata = devm_kzalloc(dev, sizeof(struct hdmi_context), GFP_KERNEL);
930865fb
AH
1939 if (!hdata)
1940 return -ENOMEM;
1941
57a64122 1942 hdata->drv_data = of_device_get_match_data(dev);
930865fb 1943
930865fb 1944 platform_set_drvdata(pdev, hdata);
d8408326 1945
d8408326
SWK
1946 hdata->dev = dev;
1947
691da76f
SN
1948 mutex_init(&hdata->mutex);
1949
d8408326
SWK
1950 ret = hdmi_resources_init(hdata);
1951 if (ret) {
b85881dd
JMC
1952 if (ret != -EPROBE_DEFER)
1953 DRM_ERROR("hdmi_resources_init failed\n");
df5225bc 1954 return ret;
d8408326
SWK
1955 }
1956
1957 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
d873ab99 1958 hdata->regs = devm_ioremap_resource(dev, res);
df5225bc
ID
1959 if (IS_ERR(hdata->regs)) {
1960 ret = PTR_ERR(hdata->regs);
86650408 1961 return ret;
df5225bc 1962 }
d8408326 1963
1caa360e
MK
1964 ret = hdmi_get_ddc_adapter(hdata);
1965 if (ret)
1966 return ret;
d8408326 1967
b5413022
MK
1968 ret = hdmi_get_phy_io(hdata);
1969 if (ret)
2b768132 1970 goto err_ddc;
d8408326 1971
724fd140
SP
1972 INIT_DELAYED_WORK(&hdata->hotplug_work, hdmi_hotplug_work_func);
1973
dcb9a7c7 1974 ret = devm_request_threaded_irq(dev, hdata->irq, NULL,
77006a7a 1975 hdmi_irq_thread, IRQF_TRIGGER_RISING |
cf8fc4f1 1976 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
f041b257 1977 "hdmi", hdata);
d8408326 1978 if (ret) {
77006a7a 1979 DRM_ERROR("failed to register hdmi interrupt\n");
66265a2e 1980 goto err_hdmiphy;
d8408326 1981 }
d8408326 1982
049d34e9
RS
1983 hdata->pmureg = syscon_regmap_lookup_by_phandle(dev->of_node,
1984 "samsung,syscon-phandle");
1985 if (IS_ERR(hdata->pmureg)) {
1986 DRM_ERROR("syscon regmap lookup failed.\n");
df5225bc 1987 ret = -EPROBE_DEFER;
049d34e9
RS
1988 goto err_hdmiphy;
1989 }
1990
68cd004e
AH
1991 if (hdata->drv_data->has_sysreg) {
1992 hdata->sysreg = syscon_regmap_lookup_by_phandle(dev->of_node,
1993 "samsung,sysreg-phandle");
1994 if (IS_ERR(hdata->sysreg)) {
1995 DRM_ERROR("sysreg regmap lookup failed.\n");
1996 ret = -EPROBE_DEFER;
1997 goto err_hdmiphy;
1998 }
1999 }
2000
278c811c
HV
2001 hdata->notifier = cec_notifier_get(&pdev->dev);
2002 if (hdata->notifier == NULL) {
2003 ret = -ENOMEM;
2004 goto err_hdmiphy;
2005 }
2006
af65c804 2007 pm_runtime_enable(dev);
d8408326 2008
691da76f
SN
2009 audio_infoframe = &hdata->audio.infoframe;
2010 hdmi_audio_infoframe_init(audio_infoframe);
2011 audio_infoframe->coding_type = HDMI_AUDIO_CODING_TYPE_STREAM;
2012 audio_infoframe->sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM;
2013 audio_infoframe->sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM;
2014 audio_infoframe->channels = 2;
2015
2016 ret = hdmi_register_audio_device(hdata);
df5225bc 2017 if (ret)
278c811c 2018 goto err_notifier_put;
df5225bc 2019
691da76f
SN
2020 ret = component_add(&pdev->dev, &hdmi_component_ops);
2021 if (ret)
2022 goto err_unregister_audio;
2023
df5225bc
ID
2024 return ret;
2025
691da76f
SN
2026err_unregister_audio:
2027 platform_device_unregister(hdata->audio.pdev);
2028
278c811c
HV
2029err_notifier_put:
2030 cec_notifier_put(hdata->notifier);
df5225bc 2031 pm_runtime_disable(dev);
d8408326 2032
d8408326 2033err_hdmiphy:
b21a3bf4
PT
2034 if (hdata->hdmiphy_port)
2035 put_device(&hdata->hdmiphy_port->dev);
d7420002
AY
2036 if (hdata->regs_hdmiphy)
2037 iounmap(hdata->regs_hdmiphy);
d8408326 2038err_ddc:
8fa04aae 2039 put_device(&hdata->ddc_adpt->dev);
df5225bc 2040
d8408326
SWK
2041 return ret;
2042}
2043
56550d94 2044static int hdmi_remove(struct platform_device *pdev)
d8408326 2045{
930865fb 2046 struct hdmi_context *hdata = platform_get_drvdata(pdev);
d8408326 2047
724fd140 2048 cancel_delayed_work_sync(&hdata->hotplug_work);
278c811c 2049 cec_notifier_set_phys_addr(hdata->notifier, CEC_PHYS_ADDR_INVALID);
724fd140 2050
2445c4a4 2051 component_del(&pdev->dev, &hdmi_component_ops);
691da76f 2052 platform_device_unregister(hdata->audio.pdev);
2445c4a4 2053
278c811c 2054 cec_notifier_put(hdata->notifier);
2445c4a4
AH
2055 pm_runtime_disable(&pdev->dev);
2056
af1f7c24
AH
2057 if (!IS_ERR(hdata->reg_hdmi_en))
2058 regulator_disable(hdata->reg_hdmi_en);
05fdf987 2059
9d1e25c9
SWK
2060 if (hdata->hdmiphy_port)
2061 put_device(&hdata->hdmiphy_port->dev);
f37cd5e8 2062
d7420002
AY
2063 if (hdata->regs_hdmiphy)
2064 iounmap(hdata->regs_hdmiphy);
2065
2445c4a4 2066 put_device(&hdata->ddc_adpt->dev);
d8408326 2067
691da76f
SN
2068 mutex_destroy(&hdata->mutex);
2069
d8408326
SWK
2070 return 0;
2071}
2072
7e175100 2073static int __maybe_unused exynos_hdmi_suspend(struct device *dev)
f28464c3
GP
2074{
2075 struct hdmi_context *hdata = dev_get_drvdata(dev);
2076
9be7e989 2077 hdmi_clk_disable_gates(hdata);
f28464c3
GP
2078
2079 return 0;
2080}
2081
7e175100 2082static int __maybe_unused exynos_hdmi_resume(struct device *dev)
f28464c3
GP
2083{
2084 struct hdmi_context *hdata = dev_get_drvdata(dev);
2085 int ret;
2086
9be7e989
AH
2087 ret = hdmi_clk_enable_gates(hdata);
2088 if (ret < 0)
f28464c3 2089 return ret;
f28464c3
GP
2090
2091 return 0;
2092}
f28464c3
GP
2093
2094static const struct dev_pm_ops exynos_hdmi_pm_ops = {
2095 SET_RUNTIME_PM_OPS(exynos_hdmi_suspend, exynos_hdmi_resume, NULL)
2096};
2097
d8408326
SWK
2098struct platform_driver hdmi_driver = {
2099 .probe = hdmi_probe,
56550d94 2100 .remove = hdmi_remove,
d8408326 2101 .driver = {
22c4f428 2102 .name = "exynos-hdmi",
d8408326 2103 .owner = THIS_MODULE,
f28464c3 2104 .pm = &exynos_hdmi_pm_ops,
88c49815 2105 .of_match_table = hdmi_match_types,
d8408326
SWK
2106 },
2107};