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