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