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