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