blob: 745eec4e8fb88612a5e28215372ba3ddc221329a [file] [log] [blame]
Thierry Redingedec4af2012-11-15 21:28:23 +00001/*
2 * Copyright (C) 2012 Avionic Design GmbH
3 * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 */
9
10#include <linux/clk.h>
Prashant Gaikwad61fd2902013-01-11 13:16:26 +053011#include <linux/clk/tegra.h>
Thierry Reding9eb9b222013-09-24 16:32:47 +020012#include <linux/debugfs.h>
13#include <linux/hdmi.h>
14#include <linux/regulator/consumer.h>
Thierry Redingac24c222012-11-23 15:14:00 +010015
Thierry Redingedec4af2012-11-15 21:28:23 +000016#include "hdmi.h"
17#include "drm.h"
18#include "dc.h"
19
Thierry Reding59af0592013-10-14 09:43:05 +020020struct tmds_config {
21 unsigned int pclk;
22 u32 pll0;
23 u32 pll1;
24 u32 pe_current;
25 u32 drive_current;
26};
27
28struct tegra_hdmi_config {
29 const struct tmds_config *tmds;
30 unsigned int num_tmds;
31
32 unsigned long fuse_override_offset;
33 unsigned long fuse_override_value;
34};
35
Thierry Redingedec4af2012-11-15 21:28:23 +000036struct tegra_hdmi {
Thierry Reding776dc382013-10-14 14:43:22 +020037 struct host1x_client client;
Thierry Redingedec4af2012-11-15 21:28:23 +000038 struct tegra_output output;
39 struct device *dev;
40
41 struct regulator *vdd;
42 struct regulator *pll;
43
44 void __iomem *regs;
45 unsigned int irq;
46
47 struct clk *clk_parent;
48 struct clk *clk;
49
Thierry Reding59af0592013-10-14 09:43:05 +020050 const struct tegra_hdmi_config *config;
51
Thierry Redingedec4af2012-11-15 21:28:23 +000052 unsigned int audio_source;
53 unsigned int audio_freq;
54 bool stereo;
55 bool dvi;
56
57 struct drm_info_list *debugfs_files;
58 struct drm_minor *minor;
59 struct dentry *debugfs;
60};
61
62static inline struct tegra_hdmi *
Thierry Reding776dc382013-10-14 14:43:22 +020063host1x_client_to_hdmi(struct host1x_client *client)
Thierry Redingedec4af2012-11-15 21:28:23 +000064{
65 return container_of(client, struct tegra_hdmi, client);
66}
67
68static inline struct tegra_hdmi *to_hdmi(struct tegra_output *output)
69{
70 return container_of(output, struct tegra_hdmi, output);
71}
72
73#define HDMI_AUDIOCLK_FREQ 216000000
74#define HDMI_REKEY_DEFAULT 56
75
76enum {
77 AUTO = 0,
78 SPDIF,
79 HDA,
80};
81
82static inline unsigned long tegra_hdmi_readl(struct tegra_hdmi *hdmi,
83 unsigned long reg)
84{
85 return readl(hdmi->regs + (reg << 2));
86}
87
88static inline void tegra_hdmi_writel(struct tegra_hdmi *hdmi, unsigned long val,
89 unsigned long reg)
90{
91 writel(val, hdmi->regs + (reg << 2));
92}
93
94struct tegra_hdmi_audio_config {
95 unsigned int pclk;
96 unsigned int n;
97 unsigned int cts;
98 unsigned int aval;
99};
100
101static const struct tegra_hdmi_audio_config tegra_hdmi_audio_32k[] = {
102 { 25200000, 4096, 25200, 24000 },
103 { 27000000, 4096, 27000, 24000 },
104 { 74250000, 4096, 74250, 24000 },
105 { 148500000, 4096, 148500, 24000 },
106 { 0, 0, 0, 0 },
107};
108
109static const struct tegra_hdmi_audio_config tegra_hdmi_audio_44_1k[] = {
110 { 25200000, 5880, 26250, 25000 },
111 { 27000000, 5880, 28125, 25000 },
112 { 74250000, 4704, 61875, 20000 },
113 { 148500000, 4704, 123750, 20000 },
114 { 0, 0, 0, 0 },
115};
116
117static const struct tegra_hdmi_audio_config tegra_hdmi_audio_48k[] = {
118 { 25200000, 6144, 25200, 24000 },
119 { 27000000, 6144, 27000, 24000 },
120 { 74250000, 6144, 74250, 24000 },
121 { 148500000, 6144, 148500, 24000 },
122 { 0, 0, 0, 0 },
123};
124
125static const struct tegra_hdmi_audio_config tegra_hdmi_audio_88_2k[] = {
126 { 25200000, 11760, 26250, 25000 },
127 { 27000000, 11760, 28125, 25000 },
128 { 74250000, 9408, 61875, 20000 },
129 { 148500000, 9408, 123750, 20000 },
130 { 0, 0, 0, 0 },
131};
132
133static const struct tegra_hdmi_audio_config tegra_hdmi_audio_96k[] = {
134 { 25200000, 12288, 25200, 24000 },
135 { 27000000, 12288, 27000, 24000 },
136 { 74250000, 12288, 74250, 24000 },
137 { 148500000, 12288, 148500, 24000 },
138 { 0, 0, 0, 0 },
139};
140
141static const struct tegra_hdmi_audio_config tegra_hdmi_audio_176_4k[] = {
142 { 25200000, 23520, 26250, 25000 },
143 { 27000000, 23520, 28125, 25000 },
144 { 74250000, 18816, 61875, 20000 },
145 { 148500000, 18816, 123750, 20000 },
146 { 0, 0, 0, 0 },
147};
148
149static const struct tegra_hdmi_audio_config tegra_hdmi_audio_192k[] = {
150 { 25200000, 24576, 25200, 24000 },
151 { 27000000, 24576, 27000, 24000 },
152 { 74250000, 24576, 74250, 24000 },
153 { 148500000, 24576, 148500, 24000 },
154 { 0, 0, 0, 0 },
155};
156
Thierry Redingf27db962013-09-30 15:14:41 +0200157static const struct tmds_config tegra20_tmds_config[] = {
Lucas Stachfa416dd2012-12-19 21:38:55 +0000158 { /* slow pixel clock modes */
Thierry Redingedec4af2012-11-15 21:28:23 +0000159 .pclk = 27000000,
160 .pll0 = SOR_PLL_BG_V17_S(3) | SOR_PLL_ICHPMP(1) |
161 SOR_PLL_RESISTORSEL | SOR_PLL_VCOCAP(0) |
162 SOR_PLL_TX_REG_LOAD(3),
163 .pll1 = SOR_PLL_TMDS_TERM_ENABLE,
164 .pe_current = PE_CURRENT0(PE_CURRENT_0_0_mA) |
165 PE_CURRENT1(PE_CURRENT_0_0_mA) |
166 PE_CURRENT2(PE_CURRENT_0_0_mA) |
167 PE_CURRENT3(PE_CURRENT_0_0_mA),
168 .drive_current = DRIVE_CURRENT_LANE0(DRIVE_CURRENT_7_125_mA) |
169 DRIVE_CURRENT_LANE1(DRIVE_CURRENT_7_125_mA) |
170 DRIVE_CURRENT_LANE2(DRIVE_CURRENT_7_125_mA) |
171 DRIVE_CURRENT_LANE3(DRIVE_CURRENT_7_125_mA),
Lucas Stachfa416dd2012-12-19 21:38:55 +0000172 },
173 { /* high pixel clock modes */
Thierry Redingedec4af2012-11-15 21:28:23 +0000174 .pclk = UINT_MAX,
175 .pll0 = SOR_PLL_BG_V17_S(3) | SOR_PLL_ICHPMP(1) |
176 SOR_PLL_RESISTORSEL | SOR_PLL_VCOCAP(1) |
177 SOR_PLL_TX_REG_LOAD(3),
178 .pll1 = SOR_PLL_TMDS_TERM_ENABLE | SOR_PLL_PE_EN,
179 .pe_current = PE_CURRENT0(PE_CURRENT_6_0_mA) |
180 PE_CURRENT1(PE_CURRENT_6_0_mA) |
181 PE_CURRENT2(PE_CURRENT_6_0_mA) |
182 PE_CURRENT3(PE_CURRENT_6_0_mA),
183 .drive_current = DRIVE_CURRENT_LANE0(DRIVE_CURRENT_7_125_mA) |
184 DRIVE_CURRENT_LANE1(DRIVE_CURRENT_7_125_mA) |
185 DRIVE_CURRENT_LANE2(DRIVE_CURRENT_7_125_mA) |
186 DRIVE_CURRENT_LANE3(DRIVE_CURRENT_7_125_mA),
187 },
188};
189
Thierry Redingf27db962013-09-30 15:14:41 +0200190static const struct tmds_config tegra30_tmds_config[] = {
Thierry Redingedec4af2012-11-15 21:28:23 +0000191 { /* 480p modes */
192 .pclk = 27000000,
193 .pll0 = SOR_PLL_BG_V17_S(3) | SOR_PLL_ICHPMP(1) |
194 SOR_PLL_RESISTORSEL | SOR_PLL_VCOCAP(0) |
195 SOR_PLL_TX_REG_LOAD(0),
196 .pll1 = SOR_PLL_TMDS_TERM_ENABLE,
197 .pe_current = PE_CURRENT0(PE_CURRENT_0_0_mA) |
198 PE_CURRENT1(PE_CURRENT_0_0_mA) |
199 PE_CURRENT2(PE_CURRENT_0_0_mA) |
200 PE_CURRENT3(PE_CURRENT_0_0_mA),
201 .drive_current = DRIVE_CURRENT_LANE0(DRIVE_CURRENT_5_250_mA) |
202 DRIVE_CURRENT_LANE1(DRIVE_CURRENT_5_250_mA) |
203 DRIVE_CURRENT_LANE2(DRIVE_CURRENT_5_250_mA) |
204 DRIVE_CURRENT_LANE3(DRIVE_CURRENT_5_250_mA),
205 }, { /* 720p modes */
206 .pclk = 74250000,
207 .pll0 = SOR_PLL_BG_V17_S(3) | SOR_PLL_ICHPMP(1) |
208 SOR_PLL_RESISTORSEL | SOR_PLL_VCOCAP(1) |
209 SOR_PLL_TX_REG_LOAD(0),
210 .pll1 = SOR_PLL_TMDS_TERM_ENABLE | SOR_PLL_PE_EN,
211 .pe_current = PE_CURRENT0(PE_CURRENT_5_0_mA) |
212 PE_CURRENT1(PE_CURRENT_5_0_mA) |
213 PE_CURRENT2(PE_CURRENT_5_0_mA) |
214 PE_CURRENT3(PE_CURRENT_5_0_mA),
215 .drive_current = DRIVE_CURRENT_LANE0(DRIVE_CURRENT_5_250_mA) |
216 DRIVE_CURRENT_LANE1(DRIVE_CURRENT_5_250_mA) |
217 DRIVE_CURRENT_LANE2(DRIVE_CURRENT_5_250_mA) |
218 DRIVE_CURRENT_LANE3(DRIVE_CURRENT_5_250_mA),
219 }, { /* 1080p modes */
220 .pclk = UINT_MAX,
221 .pll0 = SOR_PLL_BG_V17_S(3) | SOR_PLL_ICHPMP(1) |
222 SOR_PLL_RESISTORSEL | SOR_PLL_VCOCAP(3) |
223 SOR_PLL_TX_REG_LOAD(0),
224 .pll1 = SOR_PLL_TMDS_TERM_ENABLE | SOR_PLL_PE_EN,
225 .pe_current = PE_CURRENT0(PE_CURRENT_5_0_mA) |
226 PE_CURRENT1(PE_CURRENT_5_0_mA) |
227 PE_CURRENT2(PE_CURRENT_5_0_mA) |
228 PE_CURRENT3(PE_CURRENT_5_0_mA),
229 .drive_current = DRIVE_CURRENT_LANE0(DRIVE_CURRENT_5_250_mA) |
230 DRIVE_CURRENT_LANE1(DRIVE_CURRENT_5_250_mA) |
231 DRIVE_CURRENT_LANE2(DRIVE_CURRENT_5_250_mA) |
232 DRIVE_CURRENT_LANE3(DRIVE_CURRENT_5_250_mA),
233 },
234};
235
236static const struct tegra_hdmi_audio_config *
237tegra_hdmi_get_audio_config(unsigned int audio_freq, unsigned int pclk)
238{
239 const struct tegra_hdmi_audio_config *table;
240
241 switch (audio_freq) {
242 case 32000:
243 table = tegra_hdmi_audio_32k;
244 break;
245
246 case 44100:
247 table = tegra_hdmi_audio_44_1k;
248 break;
249
250 case 48000:
251 table = tegra_hdmi_audio_48k;
252 break;
253
254 case 88200:
255 table = tegra_hdmi_audio_88_2k;
256 break;
257
258 case 96000:
259 table = tegra_hdmi_audio_96k;
260 break;
261
262 case 176400:
263 table = tegra_hdmi_audio_176_4k;
264 break;
265
266 case 192000:
267 table = tegra_hdmi_audio_192k;
268 break;
269
270 default:
271 return NULL;
272 }
273
274 while (table->pclk) {
275 if (table->pclk == pclk)
276 return table;
277
278 table++;
279 }
280
281 return NULL;
282}
283
284static void tegra_hdmi_setup_audio_fs_tables(struct tegra_hdmi *hdmi)
285{
286 const unsigned int freqs[] = {
287 32000, 44100, 48000, 88200, 96000, 176400, 192000
288 };
289 unsigned int i;
290
291 for (i = 0; i < ARRAY_SIZE(freqs); i++) {
292 unsigned int f = freqs[i];
293 unsigned int eight_half;
294 unsigned long value;
295 unsigned int delta;
296
297 if (f > 96000)
298 delta = 2;
299 else if (f > 480000)
300 delta = 6;
301 else
302 delta = 9;
303
304 eight_half = (8 * HDMI_AUDIOCLK_FREQ) / (f * 128);
305 value = AUDIO_FS_LOW(eight_half - delta) |
306 AUDIO_FS_HIGH(eight_half + delta);
307 tegra_hdmi_writel(hdmi, value, HDMI_NV_PDISP_AUDIO_FS(i));
308 }
309}
310
311static int tegra_hdmi_setup_audio(struct tegra_hdmi *hdmi, unsigned int pclk)
312{
313 struct device_node *node = hdmi->dev->of_node;
314 const struct tegra_hdmi_audio_config *config;
315 unsigned int offset = 0;
316 unsigned long value;
317
318 switch (hdmi->audio_source) {
319 case HDA:
320 value = AUDIO_CNTRL0_SOURCE_SELECT_HDAL;
321 break;
322
323 case SPDIF:
324 value = AUDIO_CNTRL0_SOURCE_SELECT_SPDIF;
325 break;
326
327 default:
328 value = AUDIO_CNTRL0_SOURCE_SELECT_AUTO;
329 break;
330 }
331
332 if (of_device_is_compatible(node, "nvidia,tegra30-hdmi")) {
333 value |= AUDIO_CNTRL0_ERROR_TOLERANCE(6) |
334 AUDIO_CNTRL0_FRAMES_PER_BLOCK(0xc0);
335 tegra_hdmi_writel(hdmi, value, HDMI_NV_PDISP_AUDIO_CNTRL0);
336 } else {
337 value |= AUDIO_CNTRL0_INJECT_NULLSMPL;
338 tegra_hdmi_writel(hdmi, value, HDMI_NV_PDISP_SOR_AUDIO_CNTRL0);
339
340 value = AUDIO_CNTRL0_ERROR_TOLERANCE(6) |
341 AUDIO_CNTRL0_FRAMES_PER_BLOCK(0xc0);
342 tegra_hdmi_writel(hdmi, value, HDMI_NV_PDISP_AUDIO_CNTRL0);
343 }
344
345 config = tegra_hdmi_get_audio_config(hdmi->audio_freq, pclk);
346 if (!config) {
347 dev_err(hdmi->dev, "cannot set audio to %u at %u pclk\n",
348 hdmi->audio_freq, pclk);
349 return -EINVAL;
350 }
351
352 tegra_hdmi_writel(hdmi, 0, HDMI_NV_PDISP_HDMI_ACR_CTRL);
353
354 value = AUDIO_N_RESETF | AUDIO_N_GENERATE_ALTERNATE |
355 AUDIO_N_VALUE(config->n - 1);
356 tegra_hdmi_writel(hdmi, value, HDMI_NV_PDISP_AUDIO_N);
357
358 tegra_hdmi_writel(hdmi, ACR_SUBPACK_N(config->n) | ACR_ENABLE,
359 HDMI_NV_PDISP_HDMI_ACR_0441_SUBPACK_HIGH);
360
361 value = ACR_SUBPACK_CTS(config->cts);
362 tegra_hdmi_writel(hdmi, value, HDMI_NV_PDISP_HDMI_ACR_0441_SUBPACK_LOW);
363
364 value = SPARE_HW_CTS | SPARE_FORCE_SW_CTS | SPARE_CTS_RESET_VAL(1);
365 tegra_hdmi_writel(hdmi, value, HDMI_NV_PDISP_HDMI_SPARE);
366
367 value = tegra_hdmi_readl(hdmi, HDMI_NV_PDISP_AUDIO_N);
368 value &= ~AUDIO_N_RESETF;
369 tegra_hdmi_writel(hdmi, value, HDMI_NV_PDISP_AUDIO_N);
370
371 if (of_device_is_compatible(node, "nvidia,tegra30-hdmi")) {
372 switch (hdmi->audio_freq) {
373 case 32000:
374 offset = HDMI_NV_PDISP_SOR_AUDIO_AVAL_0320;
375 break;
376
377 case 44100:
378 offset = HDMI_NV_PDISP_SOR_AUDIO_AVAL_0441;
379 break;
380
381 case 48000:
382 offset = HDMI_NV_PDISP_SOR_AUDIO_AVAL_0480;
383 break;
384
385 case 88200:
386 offset = HDMI_NV_PDISP_SOR_AUDIO_AVAL_0882;
387 break;
388
389 case 96000:
390 offset = HDMI_NV_PDISP_SOR_AUDIO_AVAL_0960;
391 break;
392
393 case 176400:
394 offset = HDMI_NV_PDISP_SOR_AUDIO_AVAL_1764;
395 break;
396
397 case 192000:
398 offset = HDMI_NV_PDISP_SOR_AUDIO_AVAL_1920;
399 break;
400 }
401
402 tegra_hdmi_writel(hdmi, config->aval, offset);
403 }
404
405 tegra_hdmi_setup_audio_fs_tables(hdmi);
406
407 return 0;
408}
409
Thierry Redingac24c222012-11-23 15:14:00 +0100410static inline unsigned long tegra_hdmi_subpack(const u8 *ptr, size_t size)
Thierry Redingedec4af2012-11-15 21:28:23 +0000411{
Thierry Redingac24c222012-11-23 15:14:00 +0100412 unsigned long value = 0;
Thierry Redingedec4af2012-11-15 21:28:23 +0000413 size_t i;
Thierry Redingedec4af2012-11-15 21:28:23 +0000414
Thierry Redingac24c222012-11-23 15:14:00 +0100415 for (i = size; i > 0; i--)
416 value = (value << 8) | ptr[i - 1];
Thierry Redingedec4af2012-11-15 21:28:23 +0000417
Thierry Redingac24c222012-11-23 15:14:00 +0100418 return value;
419}
Thierry Redingedec4af2012-11-15 21:28:23 +0000420
Thierry Redingac24c222012-11-23 15:14:00 +0100421static void tegra_hdmi_write_infopack(struct tegra_hdmi *hdmi, const void *data,
422 size_t size)
423{
424 const u8 *ptr = data;
425 unsigned long offset;
426 unsigned long value;
427 size_t i, j;
Thierry Redingedec4af2012-11-15 21:28:23 +0000428
Thierry Redingac24c222012-11-23 15:14:00 +0100429 switch (ptr[0]) {
430 case HDMI_INFOFRAME_TYPE_AVI:
431 offset = HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_HEADER;
432 break;
433
434 case HDMI_INFOFRAME_TYPE_AUDIO:
435 offset = HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_HEADER;
436 break;
437
438 case HDMI_INFOFRAME_TYPE_VENDOR:
439 offset = HDMI_NV_PDISP_HDMI_GENERIC_HEADER;
440 break;
441
442 default:
443 dev_err(hdmi->dev, "unsupported infoframe type: %02x\n",
444 ptr[0]);
445 return;
446 }
447
448 value = INFOFRAME_HEADER_TYPE(ptr[0]) |
449 INFOFRAME_HEADER_VERSION(ptr[1]) |
450 INFOFRAME_HEADER_LEN(ptr[2]);
Thierry Redingedec4af2012-11-15 21:28:23 +0000451 tegra_hdmi_writel(hdmi, value, offset);
Thierry Redingac24c222012-11-23 15:14:00 +0100452 offset++;
Thierry Redingedec4af2012-11-15 21:28:23 +0000453
Thierry Redingac24c222012-11-23 15:14:00 +0100454 /*
455 * Each subpack contains 7 bytes, divided into:
456 * - subpack_low: bytes 0 - 3
457 * - subpack_high: bytes 4 - 6 (with byte 7 padded to 0x00)
Thierry Redingedec4af2012-11-15 21:28:23 +0000458 */
Thierry Redingac24c222012-11-23 15:14:00 +0100459 for (i = 3, j = 0; i < size; i += 7, j += 8) {
460 size_t rem = size - i, num = min_t(size_t, rem, 4);
Thierry Redingedec4af2012-11-15 21:28:23 +0000461
Thierry Redingac24c222012-11-23 15:14:00 +0100462 value = tegra_hdmi_subpack(&ptr[i], num);
463 tegra_hdmi_writel(hdmi, value, offset++);
Thierry Redingedec4af2012-11-15 21:28:23 +0000464
Thierry Redingac24c222012-11-23 15:14:00 +0100465 num = min_t(size_t, rem - num, 3);
Thierry Redingedec4af2012-11-15 21:28:23 +0000466
Thierry Redingac24c222012-11-23 15:14:00 +0100467 value = tegra_hdmi_subpack(&ptr[i + 4], num);
468 tegra_hdmi_writel(hdmi, value, offset++);
Thierry Redingedec4af2012-11-15 21:28:23 +0000469 }
470}
471
472static void tegra_hdmi_setup_avi_infoframe(struct tegra_hdmi *hdmi,
473 struct drm_display_mode *mode)
474{
475 struct hdmi_avi_infoframe frame;
Thierry Redingac24c222012-11-23 15:14:00 +0100476 u8 buffer[17];
477 ssize_t err;
Thierry Redingedec4af2012-11-15 21:28:23 +0000478
479 if (hdmi->dvi) {
480 tegra_hdmi_writel(hdmi, 0,
481 HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_CTRL);
482 return;
483 }
484
Thierry Redingac24c222012-11-23 15:14:00 +0100485 err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode);
486 if (err < 0) {
487 dev_err(hdmi->dev, "failed to setup AVI infoframe: %zd\n", err);
488 return;
Thierry Redingedec4af2012-11-15 21:28:23 +0000489 }
490
Thierry Redingac24c222012-11-23 15:14:00 +0100491 err = hdmi_avi_infoframe_pack(&frame, buffer, sizeof(buffer));
492 if (err < 0) {
493 dev_err(hdmi->dev, "failed to pack AVI infoframe: %zd\n", err);
494 return;
495 }
496
497 tegra_hdmi_write_infopack(hdmi, buffer, err);
Thierry Redingedec4af2012-11-15 21:28:23 +0000498
499 tegra_hdmi_writel(hdmi, INFOFRAME_CTRL_ENABLE,
500 HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_CTRL);
501}
502
503static void tegra_hdmi_setup_audio_infoframe(struct tegra_hdmi *hdmi)
504{
505 struct hdmi_audio_infoframe frame;
Thierry Redingac24c222012-11-23 15:14:00 +0100506 u8 buffer[14];
507 ssize_t err;
Thierry Redingedec4af2012-11-15 21:28:23 +0000508
509 if (hdmi->dvi) {
510 tegra_hdmi_writel(hdmi, 0,
511 HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_CTRL);
512 return;
513 }
514
Thierry Redingac24c222012-11-23 15:14:00 +0100515 err = hdmi_audio_infoframe_init(&frame);
516 if (err < 0) {
517 dev_err(hdmi->dev, "failed to initialize audio infoframe: %d\n",
518 err);
519 return;
520 }
Thierry Redingedec4af2012-11-15 21:28:23 +0000521
Thierry Redingac24c222012-11-23 15:14:00 +0100522 frame.channels = 2;
523
524 err = hdmi_audio_infoframe_pack(&frame, buffer, sizeof(buffer));
525 if (err < 0) {
526 dev_err(hdmi->dev, "failed to pack audio infoframe: %zd\n",
527 err);
528 return;
529 }
530
531 /*
532 * The audio infoframe has only one set of subpack registers, so the
533 * infoframe needs to be truncated. One set of subpack registers can
534 * contain 7 bytes. Including the 3 byte header only the first 10
535 * bytes can be programmed.
536 */
537 tegra_hdmi_write_infopack(hdmi, buffer, min(10, err));
Thierry Redingedec4af2012-11-15 21:28:23 +0000538
539 tegra_hdmi_writel(hdmi, INFOFRAME_CTRL_ENABLE,
540 HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_CTRL);
541}
542
543static void tegra_hdmi_setup_stereo_infoframe(struct tegra_hdmi *hdmi)
544{
Lespiau, Damienae84b902013-08-19 16:59:02 +0100545 struct hdmi_vendor_infoframe frame;
Thierry Redingedec4af2012-11-15 21:28:23 +0000546 unsigned long value;
Thierry Redingac24c222012-11-23 15:14:00 +0100547 u8 buffer[10];
548 ssize_t err;
Thierry Redingedec4af2012-11-15 21:28:23 +0000549
550 if (!hdmi->stereo) {
551 value = tegra_hdmi_readl(hdmi, HDMI_NV_PDISP_HDMI_GENERIC_CTRL);
552 value &= ~GENERIC_CTRL_ENABLE;
553 tegra_hdmi_writel(hdmi, value, HDMI_NV_PDISP_HDMI_GENERIC_CTRL);
554 return;
555 }
556
Lespiau, Damienae84b902013-08-19 16:59:02 +0100557 hdmi_vendor_infoframe_init(&frame);
Lespiau, Damiena26a58e82013-08-19 16:58:59 +0100558 frame.s3d_struct = HDMI_3D_STRUCTURE_FRAME_PACKING;
Thierry Redingac24c222012-11-23 15:14:00 +0100559
Lespiau, Damienae84b902013-08-19 16:59:02 +0100560 err = hdmi_vendor_infoframe_pack(&frame, buffer, sizeof(buffer));
Thierry Redingac24c222012-11-23 15:14:00 +0100561 if (err < 0) {
562 dev_err(hdmi->dev, "failed to pack vendor infoframe: %zd\n",
563 err);
564 return;
565 }
566
567 tegra_hdmi_write_infopack(hdmi, buffer, err);
Thierry Redingedec4af2012-11-15 21:28:23 +0000568
569 value = tegra_hdmi_readl(hdmi, HDMI_NV_PDISP_HDMI_GENERIC_CTRL);
570 value |= GENERIC_CTRL_ENABLE;
571 tegra_hdmi_writel(hdmi, value, HDMI_NV_PDISP_HDMI_GENERIC_CTRL);
572}
573
574static void tegra_hdmi_setup_tmds(struct tegra_hdmi *hdmi,
575 const struct tmds_config *tmds)
576{
577 unsigned long value;
578
579 tegra_hdmi_writel(hdmi, tmds->pll0, HDMI_NV_PDISP_SOR_PLL0);
580 tegra_hdmi_writel(hdmi, tmds->pll1, HDMI_NV_PDISP_SOR_PLL1);
581 tegra_hdmi_writel(hdmi, tmds->pe_current, HDMI_NV_PDISP_PE_CURRENT);
582
Thierry Reding59af0592013-10-14 09:43:05 +0200583 tegra_hdmi_writel(hdmi, tmds->drive_current,
584 HDMI_NV_PDISP_SOR_LANE_DRIVE_CURRENT);
585
586 value = tegra_hdmi_readl(hdmi, hdmi->config->fuse_override_offset);
587 value |= hdmi->config->fuse_override_value;
588 tegra_hdmi_writel(hdmi, value, hdmi->config->fuse_override_offset);
Thierry Redingedec4af2012-11-15 21:28:23 +0000589}
590
591static int tegra_output_hdmi_enable(struct tegra_output *output)
592{
593 unsigned int h_sync_width, h_front_porch, h_back_porch, i, rekey;
594 struct tegra_dc *dc = to_tegra_dc(output->encoder.crtc);
595 struct drm_display_mode *mode = &dc->base.mode;
596 struct tegra_hdmi *hdmi = to_hdmi(output);
597 struct device_node *node = hdmi->dev->of_node;
598 unsigned int pulse_start, div82, pclk;
Thierry Redingedec4af2012-11-15 21:28:23 +0000599 unsigned long value;
600 int retries = 1000;
601 int err;
602
603 pclk = mode->clock * 1000;
604 h_sync_width = mode->hsync_end - mode->hsync_start;
Lucas Stach40495082012-12-19 21:38:52 +0000605 h_back_porch = mode->htotal - mode->hsync_end;
606 h_front_porch = mode->hsync_start - mode->hdisplay;
Thierry Redingedec4af2012-11-15 21:28:23 +0000607
608 err = regulator_enable(hdmi->vdd);
609 if (err < 0) {
610 dev_err(hdmi->dev, "failed to enable VDD regulator: %d\n", err);
611 return err;
612 }
613
614 err = regulator_enable(hdmi->pll);
615 if (err < 0) {
616 dev_err(hdmi->dev, "failed to enable PLL regulator: %d\n", err);
617 return err;
618 }
619
620 /*
621 * This assumes that the display controller will divide its parent
622 * clock by 2 to generate the pixel clock.
623 */
624 err = tegra_output_setup_clock(output, hdmi->clk, pclk * 2);
625 if (err < 0) {
626 dev_err(hdmi->dev, "failed to setup clock: %d\n", err);
627 return err;
628 }
629
630 err = clk_set_rate(hdmi->clk, pclk);
631 if (err < 0)
632 return err;
633
634 err = clk_enable(hdmi->clk);
635 if (err < 0) {
636 dev_err(hdmi->dev, "failed to enable clock: %d\n", err);
637 return err;
638 }
639
640 tegra_periph_reset_assert(hdmi->clk);
641 usleep_range(1000, 2000);
642 tegra_periph_reset_deassert(hdmi->clk);
643
644 tegra_dc_writel(dc, VSYNC_H_POSITION(1),
645 DC_DISP_DISP_TIMING_OPTIONS);
646 tegra_dc_writel(dc, DITHER_CONTROL_DISABLE | BASE_COLOR_SIZE888,
647 DC_DISP_DISP_COLOR_CONTROL);
648
649 /* video_preamble uses h_pulse2 */
650 pulse_start = 1 + h_sync_width + h_back_porch - 10;
651
652 tegra_dc_writel(dc, H_PULSE_2_ENABLE, DC_DISP_DISP_SIGNAL_OPTIONS0);
653
654 value = PULSE_MODE_NORMAL | PULSE_POLARITY_HIGH | PULSE_QUAL_VACTIVE |
655 PULSE_LAST_END_A;
656 tegra_dc_writel(dc, value, DC_DISP_H_PULSE2_CONTROL);
657
658 value = PULSE_START(pulse_start) | PULSE_END(pulse_start + 8);
659 tegra_dc_writel(dc, value, DC_DISP_H_PULSE2_POSITION_A);
660
661 value = VSYNC_WINDOW_END(0x210) | VSYNC_WINDOW_START(0x200) |
662 VSYNC_WINDOW_ENABLE;
663 tegra_hdmi_writel(hdmi, value, HDMI_NV_PDISP_HDMI_VSYNC_WINDOW);
664
665 if (dc->pipe)
666 value = HDMI_SRC_DISPLAYB;
667 else
668 value = HDMI_SRC_DISPLAYA;
669
670 if ((mode->hdisplay == 720) && ((mode->vdisplay == 480) ||
671 (mode->vdisplay == 576)))
672 tegra_hdmi_writel(hdmi,
673 value | ARM_VIDEO_RANGE_FULL,
674 HDMI_NV_PDISP_INPUT_CONTROL);
675 else
676 tegra_hdmi_writel(hdmi,
677 value | ARM_VIDEO_RANGE_LIMITED,
678 HDMI_NV_PDISP_INPUT_CONTROL);
679
680 div82 = clk_get_rate(hdmi->clk) / 1000000 * 4;
681 value = SOR_REFCLK_DIV_INT(div82 >> 2) | SOR_REFCLK_DIV_FRAC(div82);
682 tegra_hdmi_writel(hdmi, value, HDMI_NV_PDISP_SOR_REFCLK);
683
684 if (!hdmi->dvi) {
685 err = tegra_hdmi_setup_audio(hdmi, pclk);
686 if (err < 0)
687 hdmi->dvi = true;
688 }
689
690 if (of_device_is_compatible(node, "nvidia,tegra20-hdmi")) {
691 /*
692 * TODO: add ELD support
693 */
694 }
695
696 rekey = HDMI_REKEY_DEFAULT;
697 value = HDMI_CTRL_REKEY(rekey);
698 value |= HDMI_CTRL_MAX_AC_PACKET((h_sync_width + h_back_porch +
699 h_front_porch - rekey - 18) / 32);
700
701 if (!hdmi->dvi)
702 value |= HDMI_CTRL_ENABLE;
703
704 tegra_hdmi_writel(hdmi, value, HDMI_NV_PDISP_HDMI_CTRL);
705
706 if (hdmi->dvi)
707 tegra_hdmi_writel(hdmi, 0x0,
708 HDMI_NV_PDISP_HDMI_GENERIC_CTRL);
709 else
710 tegra_hdmi_writel(hdmi, GENERIC_CTRL_AUDIO,
711 HDMI_NV_PDISP_HDMI_GENERIC_CTRL);
712
713 tegra_hdmi_setup_avi_infoframe(hdmi, mode);
714 tegra_hdmi_setup_audio_infoframe(hdmi);
715 tegra_hdmi_setup_stereo_infoframe(hdmi);
716
717 /* TMDS CONFIG */
Thierry Reding59af0592013-10-14 09:43:05 +0200718 for (i = 0; i < hdmi->config->num_tmds; i++) {
719 if (pclk <= hdmi->config->tmds[i].pclk) {
720 tegra_hdmi_setup_tmds(hdmi, &hdmi->config->tmds[i]);
Thierry Redingedec4af2012-11-15 21:28:23 +0000721 break;
722 }
723 }
724
725 tegra_hdmi_writel(hdmi,
726 SOR_SEQ_CTL_PU_PC(0) |
727 SOR_SEQ_PU_PC_ALT(0) |
728 SOR_SEQ_PD_PC(8) |
729 SOR_SEQ_PD_PC_ALT(8),
730 HDMI_NV_PDISP_SOR_SEQ_CTL);
731
732 value = SOR_SEQ_INST_WAIT_TIME(1) |
733 SOR_SEQ_INST_WAIT_UNITS_VSYNC |
734 SOR_SEQ_INST_HALT |
735 SOR_SEQ_INST_PIN_A_LOW |
736 SOR_SEQ_INST_PIN_B_LOW |
737 SOR_SEQ_INST_DRIVE_PWM_OUT_LO;
738
739 tegra_hdmi_writel(hdmi, value, HDMI_NV_PDISP_SOR_SEQ_INST(0));
740 tegra_hdmi_writel(hdmi, value, HDMI_NV_PDISP_SOR_SEQ_INST(8));
741
742 value = 0x1c800;
743 value &= ~SOR_CSTM_ROTCLK(~0);
744 value |= SOR_CSTM_ROTCLK(2);
745 tegra_hdmi_writel(hdmi, value, HDMI_NV_PDISP_SOR_CSTM);
746
747 tegra_dc_writel(dc, DISP_CTRL_MODE_STOP, DC_CMD_DISPLAY_COMMAND);
748 tegra_dc_writel(dc, GENERAL_ACT_REQ << 8, DC_CMD_STATE_CONTROL);
749 tegra_dc_writel(dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL);
750
751 /* start SOR */
752 tegra_hdmi_writel(hdmi,
753 SOR_PWR_NORMAL_STATE_PU |
754 SOR_PWR_NORMAL_START_NORMAL |
755 SOR_PWR_SAFE_STATE_PD |
756 SOR_PWR_SETTING_NEW_TRIGGER,
757 HDMI_NV_PDISP_SOR_PWR);
758 tegra_hdmi_writel(hdmi,
759 SOR_PWR_NORMAL_STATE_PU |
760 SOR_PWR_NORMAL_START_NORMAL |
761 SOR_PWR_SAFE_STATE_PD |
762 SOR_PWR_SETTING_NEW_DONE,
763 HDMI_NV_PDISP_SOR_PWR);
764
765 do {
766 BUG_ON(--retries < 0);
767 value = tegra_hdmi_readl(hdmi, HDMI_NV_PDISP_SOR_PWR);
768 } while (value & SOR_PWR_SETTING_NEW_PENDING);
769
770 value = SOR_STATE_ASY_CRCMODE_COMPLETE |
771 SOR_STATE_ASY_OWNER_HEAD0 |
772 SOR_STATE_ASY_SUBOWNER_BOTH |
773 SOR_STATE_ASY_PROTOCOL_SINGLE_TMDS_A |
774 SOR_STATE_ASY_DEPOL_POS;
775
776 /* setup sync polarities */
777 if (mode->flags & DRM_MODE_FLAG_PHSYNC)
778 value |= SOR_STATE_ASY_HSYNCPOL_POS;
779
780 if (mode->flags & DRM_MODE_FLAG_NHSYNC)
781 value |= SOR_STATE_ASY_HSYNCPOL_NEG;
782
783 if (mode->flags & DRM_MODE_FLAG_PVSYNC)
784 value |= SOR_STATE_ASY_VSYNCPOL_POS;
785
786 if (mode->flags & DRM_MODE_FLAG_NVSYNC)
787 value |= SOR_STATE_ASY_VSYNCPOL_NEG;
788
789 tegra_hdmi_writel(hdmi, value, HDMI_NV_PDISP_SOR_STATE2);
790
791 value = SOR_STATE_ASY_HEAD_OPMODE_AWAKE | SOR_STATE_ASY_ORMODE_NORMAL;
792 tegra_hdmi_writel(hdmi, value, HDMI_NV_PDISP_SOR_STATE1);
793
794 tegra_hdmi_writel(hdmi, 0, HDMI_NV_PDISP_SOR_STATE0);
795 tegra_hdmi_writel(hdmi, SOR_STATE_UPDATE, HDMI_NV_PDISP_SOR_STATE0);
796 tegra_hdmi_writel(hdmi, value | SOR_STATE_ATTACHED,
797 HDMI_NV_PDISP_SOR_STATE1);
798 tegra_hdmi_writel(hdmi, 0, HDMI_NV_PDISP_SOR_STATE0);
799
800 tegra_dc_writel(dc, HDMI_ENABLE, DC_DISP_DISP_WIN_OPTIONS);
801
802 value = PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE |
803 PW4_ENABLE | PM0_ENABLE | PM1_ENABLE;
804 tegra_dc_writel(dc, value, DC_CMD_DISPLAY_POWER_CONTROL);
805
806 value = DISP_CTRL_MODE_C_DISPLAY;
807 tegra_dc_writel(dc, value, DC_CMD_DISPLAY_COMMAND);
808
809 tegra_dc_writel(dc, GENERAL_ACT_REQ << 8, DC_CMD_STATE_CONTROL);
810 tegra_dc_writel(dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL);
811
812 /* TODO: add HDCP support */
813
814 return 0;
815}
816
817static int tegra_output_hdmi_disable(struct tegra_output *output)
818{
819 struct tegra_hdmi *hdmi = to_hdmi(output);
820
821 tegra_periph_reset_assert(hdmi->clk);
822 clk_disable(hdmi->clk);
823 regulator_disable(hdmi->pll);
824 regulator_disable(hdmi->vdd);
825
826 return 0;
827}
828
829static int tegra_output_hdmi_setup_clock(struct tegra_output *output,
830 struct clk *clk, unsigned long pclk)
831{
832 struct tegra_hdmi *hdmi = to_hdmi(output);
833 struct clk *base;
834 int err;
835
836 err = clk_set_parent(clk, hdmi->clk_parent);
837 if (err < 0) {
838 dev_err(output->dev, "failed to set parent: %d\n", err);
839 return err;
840 }
841
842 base = clk_get_parent(hdmi->clk_parent);
843
844 /*
845 * This assumes that the parent clock is pll_d_out0 or pll_d2_out
846 * respectively, each of which divides the base pll_d by 2.
847 */
848 err = clk_set_rate(base, pclk * 2);
849 if (err < 0)
850 dev_err(output->dev,
851 "failed to set base clock rate to %lu Hz\n",
852 pclk * 2);
853
854 return 0;
855}
856
857static int tegra_output_hdmi_check_mode(struct tegra_output *output,
858 struct drm_display_mode *mode,
859 enum drm_mode_status *status)
860{
861 struct tegra_hdmi *hdmi = to_hdmi(output);
862 unsigned long pclk = mode->clock * 1000;
863 struct clk *parent;
864 long err;
865
866 parent = clk_get_parent(hdmi->clk_parent);
867
868 err = clk_round_rate(parent, pclk * 4);
869 if (err < 0)
870 *status = MODE_NOCLOCK;
871 else
872 *status = MODE_OK;
873
874 return 0;
875}
876
877static const struct tegra_output_ops hdmi_ops = {
878 .enable = tegra_output_hdmi_enable,
879 .disable = tegra_output_hdmi_disable,
880 .setup_clock = tegra_output_hdmi_setup_clock,
881 .check_mode = tegra_output_hdmi_check_mode,
882};
883
884static int tegra_hdmi_show_regs(struct seq_file *s, void *data)
885{
886 struct drm_info_node *node = s->private;
887 struct tegra_hdmi *hdmi = node->info_ent->data;
Mikko Perttunenccaddfe2013-07-30 11:35:03 +0300888 int err;
889
890 err = clk_enable(hdmi->clk);
891 if (err)
892 return err;
Thierry Redingedec4af2012-11-15 21:28:23 +0000893
894#define DUMP_REG(name) \
895 seq_printf(s, "%-56s %#05x %08lx\n", #name, name, \
896 tegra_hdmi_readl(hdmi, name))
897
898 DUMP_REG(HDMI_CTXSW);
899 DUMP_REG(HDMI_NV_PDISP_SOR_STATE0);
900 DUMP_REG(HDMI_NV_PDISP_SOR_STATE1);
901 DUMP_REG(HDMI_NV_PDISP_SOR_STATE2);
902 DUMP_REG(HDMI_NV_PDISP_RG_HDCP_AN_MSB);
903 DUMP_REG(HDMI_NV_PDISP_RG_HDCP_AN_LSB);
904 DUMP_REG(HDMI_NV_PDISP_RG_HDCP_CN_MSB);
905 DUMP_REG(HDMI_NV_PDISP_RG_HDCP_CN_LSB);
906 DUMP_REG(HDMI_NV_PDISP_RG_HDCP_AKSV_MSB);
907 DUMP_REG(HDMI_NV_PDISP_RG_HDCP_AKSV_LSB);
908 DUMP_REG(HDMI_NV_PDISP_RG_HDCP_BKSV_MSB);
909 DUMP_REG(HDMI_NV_PDISP_RG_HDCP_BKSV_LSB);
910 DUMP_REG(HDMI_NV_PDISP_RG_HDCP_CKSV_MSB);
911 DUMP_REG(HDMI_NV_PDISP_RG_HDCP_CKSV_LSB);
912 DUMP_REG(HDMI_NV_PDISP_RG_HDCP_DKSV_MSB);
913 DUMP_REG(HDMI_NV_PDISP_RG_HDCP_DKSV_LSB);
914 DUMP_REG(HDMI_NV_PDISP_RG_HDCP_CTRL);
915 DUMP_REG(HDMI_NV_PDISP_RG_HDCP_CMODE);
916 DUMP_REG(HDMI_NV_PDISP_RG_HDCP_MPRIME_MSB);
917 DUMP_REG(HDMI_NV_PDISP_RG_HDCP_MPRIME_LSB);
918 DUMP_REG(HDMI_NV_PDISP_RG_HDCP_SPRIME_MSB);
919 DUMP_REG(HDMI_NV_PDISP_RG_HDCP_SPRIME_LSB2);
920 DUMP_REG(HDMI_NV_PDISP_RG_HDCP_SPRIME_LSB1);
921 DUMP_REG(HDMI_NV_PDISP_RG_HDCP_RI);
922 DUMP_REG(HDMI_NV_PDISP_RG_HDCP_CS_MSB);
923 DUMP_REG(HDMI_NV_PDISP_RG_HDCP_CS_LSB);
924 DUMP_REG(HDMI_NV_PDISP_HDMI_AUDIO_EMU0);
925 DUMP_REG(HDMI_NV_PDISP_HDMI_AUDIO_EMU_RDATA0);
926 DUMP_REG(HDMI_NV_PDISP_HDMI_AUDIO_EMU1);
927 DUMP_REG(HDMI_NV_PDISP_HDMI_AUDIO_EMU2);
928 DUMP_REG(HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_CTRL);
929 DUMP_REG(HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_STATUS);
930 DUMP_REG(HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_HEADER);
931 DUMP_REG(HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_SUBPACK0_LOW);
932 DUMP_REG(HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_SUBPACK0_HIGH);
933 DUMP_REG(HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_CTRL);
934 DUMP_REG(HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_STATUS);
935 DUMP_REG(HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_HEADER);
936 DUMP_REG(HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_SUBPACK0_LOW);
937 DUMP_REG(HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_SUBPACK0_HIGH);
938 DUMP_REG(HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_SUBPACK1_LOW);
939 DUMP_REG(HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_SUBPACK1_HIGH);
940 DUMP_REG(HDMI_NV_PDISP_HDMI_GENERIC_CTRL);
941 DUMP_REG(HDMI_NV_PDISP_HDMI_GENERIC_STATUS);
942 DUMP_REG(HDMI_NV_PDISP_HDMI_GENERIC_HEADER);
943 DUMP_REG(HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK0_LOW);
944 DUMP_REG(HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK0_HIGH);
945 DUMP_REG(HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK1_LOW);
946 DUMP_REG(HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK1_HIGH);
947 DUMP_REG(HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK2_LOW);
948 DUMP_REG(HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK2_HIGH);
949 DUMP_REG(HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK3_LOW);
950 DUMP_REG(HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK3_HIGH);
951 DUMP_REG(HDMI_NV_PDISP_HDMI_ACR_CTRL);
952 DUMP_REG(HDMI_NV_PDISP_HDMI_ACR_0320_SUBPACK_LOW);
953 DUMP_REG(HDMI_NV_PDISP_HDMI_ACR_0320_SUBPACK_HIGH);
954 DUMP_REG(HDMI_NV_PDISP_HDMI_ACR_0441_SUBPACK_LOW);
955 DUMP_REG(HDMI_NV_PDISP_HDMI_ACR_0441_SUBPACK_HIGH);
956 DUMP_REG(HDMI_NV_PDISP_HDMI_ACR_0882_SUBPACK_LOW);
957 DUMP_REG(HDMI_NV_PDISP_HDMI_ACR_0882_SUBPACK_HIGH);
958 DUMP_REG(HDMI_NV_PDISP_HDMI_ACR_1764_SUBPACK_LOW);
959 DUMP_REG(HDMI_NV_PDISP_HDMI_ACR_1764_SUBPACK_HIGH);
960 DUMP_REG(HDMI_NV_PDISP_HDMI_ACR_0480_SUBPACK_LOW);
961 DUMP_REG(HDMI_NV_PDISP_HDMI_ACR_0480_SUBPACK_HIGH);
962 DUMP_REG(HDMI_NV_PDISP_HDMI_ACR_0960_SUBPACK_LOW);
963 DUMP_REG(HDMI_NV_PDISP_HDMI_ACR_0960_SUBPACK_HIGH);
964 DUMP_REG(HDMI_NV_PDISP_HDMI_ACR_1920_SUBPACK_LOW);
965 DUMP_REG(HDMI_NV_PDISP_HDMI_ACR_1920_SUBPACK_HIGH);
966 DUMP_REG(HDMI_NV_PDISP_HDMI_CTRL);
967 DUMP_REG(HDMI_NV_PDISP_HDMI_VSYNC_KEEPOUT);
968 DUMP_REG(HDMI_NV_PDISP_HDMI_VSYNC_WINDOW);
969 DUMP_REG(HDMI_NV_PDISP_HDMI_GCP_CTRL);
970 DUMP_REG(HDMI_NV_PDISP_HDMI_GCP_STATUS);
971 DUMP_REG(HDMI_NV_PDISP_HDMI_GCP_SUBPACK);
972 DUMP_REG(HDMI_NV_PDISP_HDMI_CHANNEL_STATUS1);
973 DUMP_REG(HDMI_NV_PDISP_HDMI_CHANNEL_STATUS2);
974 DUMP_REG(HDMI_NV_PDISP_HDMI_EMU0);
975 DUMP_REG(HDMI_NV_PDISP_HDMI_EMU1);
976 DUMP_REG(HDMI_NV_PDISP_HDMI_EMU1_RDATA);
977 DUMP_REG(HDMI_NV_PDISP_HDMI_SPARE);
978 DUMP_REG(HDMI_NV_PDISP_HDMI_SPDIF_CHN_STATUS1);
979 DUMP_REG(HDMI_NV_PDISP_HDMI_SPDIF_CHN_STATUS2);
980 DUMP_REG(HDMI_NV_PDISP_HDMI_HDCPRIF_ROM_CTRL);
981 DUMP_REG(HDMI_NV_PDISP_SOR_CAP);
982 DUMP_REG(HDMI_NV_PDISP_SOR_PWR);
983 DUMP_REG(HDMI_NV_PDISP_SOR_TEST);
984 DUMP_REG(HDMI_NV_PDISP_SOR_PLL0);
985 DUMP_REG(HDMI_NV_PDISP_SOR_PLL1);
986 DUMP_REG(HDMI_NV_PDISP_SOR_PLL2);
987 DUMP_REG(HDMI_NV_PDISP_SOR_CSTM);
988 DUMP_REG(HDMI_NV_PDISP_SOR_LVDS);
989 DUMP_REG(HDMI_NV_PDISP_SOR_CRCA);
990 DUMP_REG(HDMI_NV_PDISP_SOR_CRCB);
991 DUMP_REG(HDMI_NV_PDISP_SOR_BLANK);
992 DUMP_REG(HDMI_NV_PDISP_SOR_SEQ_CTL);
993 DUMP_REG(HDMI_NV_PDISP_SOR_SEQ_INST(0));
994 DUMP_REG(HDMI_NV_PDISP_SOR_SEQ_INST(1));
995 DUMP_REG(HDMI_NV_PDISP_SOR_SEQ_INST(2));
996 DUMP_REG(HDMI_NV_PDISP_SOR_SEQ_INST(3));
997 DUMP_REG(HDMI_NV_PDISP_SOR_SEQ_INST(4));
998 DUMP_REG(HDMI_NV_PDISP_SOR_SEQ_INST(5));
999 DUMP_REG(HDMI_NV_PDISP_SOR_SEQ_INST(6));
1000 DUMP_REG(HDMI_NV_PDISP_SOR_SEQ_INST(7));
1001 DUMP_REG(HDMI_NV_PDISP_SOR_SEQ_INST(8));
1002 DUMP_REG(HDMI_NV_PDISP_SOR_SEQ_INST(9));
1003 DUMP_REG(HDMI_NV_PDISP_SOR_SEQ_INST(10));
1004 DUMP_REG(HDMI_NV_PDISP_SOR_SEQ_INST(11));
1005 DUMP_REG(HDMI_NV_PDISP_SOR_SEQ_INST(12));
1006 DUMP_REG(HDMI_NV_PDISP_SOR_SEQ_INST(13));
1007 DUMP_REG(HDMI_NV_PDISP_SOR_SEQ_INST(14));
1008 DUMP_REG(HDMI_NV_PDISP_SOR_SEQ_INST(15));
1009 DUMP_REG(HDMI_NV_PDISP_SOR_VCRCA0);
1010 DUMP_REG(HDMI_NV_PDISP_SOR_VCRCA1);
1011 DUMP_REG(HDMI_NV_PDISP_SOR_CCRCA0);
1012 DUMP_REG(HDMI_NV_PDISP_SOR_CCRCA1);
1013 DUMP_REG(HDMI_NV_PDISP_SOR_EDATAA0);
1014 DUMP_REG(HDMI_NV_PDISP_SOR_EDATAA1);
1015 DUMP_REG(HDMI_NV_PDISP_SOR_COUNTA0);
1016 DUMP_REG(HDMI_NV_PDISP_SOR_COUNTA1);
1017 DUMP_REG(HDMI_NV_PDISP_SOR_DEBUGA0);
1018 DUMP_REG(HDMI_NV_PDISP_SOR_DEBUGA1);
1019 DUMP_REG(HDMI_NV_PDISP_SOR_TRIG);
1020 DUMP_REG(HDMI_NV_PDISP_SOR_MSCHECK);
1021 DUMP_REG(HDMI_NV_PDISP_SOR_LANE_DRIVE_CURRENT);
1022 DUMP_REG(HDMI_NV_PDISP_AUDIO_DEBUG0);
1023 DUMP_REG(HDMI_NV_PDISP_AUDIO_DEBUG1);
1024 DUMP_REG(HDMI_NV_PDISP_AUDIO_DEBUG2);
1025 DUMP_REG(HDMI_NV_PDISP_AUDIO_FS(0));
1026 DUMP_REG(HDMI_NV_PDISP_AUDIO_FS(1));
1027 DUMP_REG(HDMI_NV_PDISP_AUDIO_FS(2));
1028 DUMP_REG(HDMI_NV_PDISP_AUDIO_FS(3));
1029 DUMP_REG(HDMI_NV_PDISP_AUDIO_FS(4));
1030 DUMP_REG(HDMI_NV_PDISP_AUDIO_FS(5));
1031 DUMP_REG(HDMI_NV_PDISP_AUDIO_FS(6));
1032 DUMP_REG(HDMI_NV_PDISP_AUDIO_PULSE_WIDTH);
1033 DUMP_REG(HDMI_NV_PDISP_AUDIO_THRESHOLD);
1034 DUMP_REG(HDMI_NV_PDISP_AUDIO_CNTRL0);
1035 DUMP_REG(HDMI_NV_PDISP_AUDIO_N);
1036 DUMP_REG(HDMI_NV_PDISP_HDCPRIF_ROM_TIMING);
1037 DUMP_REG(HDMI_NV_PDISP_SOR_REFCLK);
1038 DUMP_REG(HDMI_NV_PDISP_CRC_CONTROL);
1039 DUMP_REG(HDMI_NV_PDISP_INPUT_CONTROL);
1040 DUMP_REG(HDMI_NV_PDISP_SCRATCH);
1041 DUMP_REG(HDMI_NV_PDISP_PE_CURRENT);
1042 DUMP_REG(HDMI_NV_PDISP_KEY_CTRL);
1043 DUMP_REG(HDMI_NV_PDISP_KEY_DEBUG0);
1044 DUMP_REG(HDMI_NV_PDISP_KEY_DEBUG1);
1045 DUMP_REG(HDMI_NV_PDISP_KEY_DEBUG2);
1046 DUMP_REG(HDMI_NV_PDISP_KEY_HDCP_KEY_0);
1047 DUMP_REG(HDMI_NV_PDISP_KEY_HDCP_KEY_1);
1048 DUMP_REG(HDMI_NV_PDISP_KEY_HDCP_KEY_2);
1049 DUMP_REG(HDMI_NV_PDISP_KEY_HDCP_KEY_3);
1050 DUMP_REG(HDMI_NV_PDISP_KEY_HDCP_KEY_TRIG);
1051 DUMP_REG(HDMI_NV_PDISP_KEY_SKEY_INDEX);
1052 DUMP_REG(HDMI_NV_PDISP_SOR_AUDIO_CNTRL0);
1053 DUMP_REG(HDMI_NV_PDISP_SOR_AUDIO_HDA_ELD_BUFWR);
1054 DUMP_REG(HDMI_NV_PDISP_SOR_AUDIO_HDA_PRESENSE);
1055
1056#undef DUMP_REG
1057
Mikko Perttunenccaddfe2013-07-30 11:35:03 +03001058 clk_disable(hdmi->clk);
1059
Thierry Redingedec4af2012-11-15 21:28:23 +00001060 return 0;
1061}
1062
1063static struct drm_info_list debugfs_files[] = {
1064 { "regs", tegra_hdmi_show_regs, 0, NULL },
1065};
1066
1067static int tegra_hdmi_debugfs_init(struct tegra_hdmi *hdmi,
1068 struct drm_minor *minor)
1069{
1070 unsigned int i;
1071 int err;
1072
1073 hdmi->debugfs = debugfs_create_dir("hdmi", minor->debugfs_root);
1074 if (!hdmi->debugfs)
1075 return -ENOMEM;
1076
1077 hdmi->debugfs_files = kmemdup(debugfs_files, sizeof(debugfs_files),
1078 GFP_KERNEL);
1079 if (!hdmi->debugfs_files) {
1080 err = -ENOMEM;
1081 goto remove;
1082 }
1083
1084 for (i = 0; i < ARRAY_SIZE(debugfs_files); i++)
1085 hdmi->debugfs_files[i].data = hdmi;
1086
1087 err = drm_debugfs_create_files(hdmi->debugfs_files,
1088 ARRAY_SIZE(debugfs_files),
1089 hdmi->debugfs, minor);
1090 if (err < 0)
1091 goto free;
1092
1093 hdmi->minor = minor;
1094
1095 return 0;
1096
1097free:
1098 kfree(hdmi->debugfs_files);
1099 hdmi->debugfs_files = NULL;
1100remove:
1101 debugfs_remove(hdmi->debugfs);
1102 hdmi->debugfs = NULL;
1103
1104 return err;
1105}
1106
1107static int tegra_hdmi_debugfs_exit(struct tegra_hdmi *hdmi)
1108{
1109 drm_debugfs_remove_files(hdmi->debugfs_files, ARRAY_SIZE(debugfs_files),
1110 hdmi->minor);
1111 hdmi->minor = NULL;
1112
1113 kfree(hdmi->debugfs_files);
1114 hdmi->debugfs_files = NULL;
1115
1116 debugfs_remove(hdmi->debugfs);
1117 hdmi->debugfs = NULL;
1118
1119 return 0;
1120}
1121
Thierry Reding53fa7f72013-09-24 15:35:40 +02001122static int tegra_hdmi_init(struct host1x_client *client)
Thierry Redingedec4af2012-11-15 21:28:23 +00001123{
Thierry Reding776dc382013-10-14 14:43:22 +02001124 struct tegra_drm *tegra = dev_get_drvdata(client->parent);
1125 struct tegra_hdmi *hdmi = host1x_client_to_hdmi(client);
Thierry Redingedec4af2012-11-15 21:28:23 +00001126 int err;
1127
1128 hdmi->output.type = TEGRA_OUTPUT_HDMI;
1129 hdmi->output.dev = client->dev;
1130 hdmi->output.ops = &hdmi_ops;
1131
Thierry Reding776dc382013-10-14 14:43:22 +02001132 err = tegra_output_init(tegra->drm, &hdmi->output);
Thierry Redingedec4af2012-11-15 21:28:23 +00001133 if (err < 0) {
1134 dev_err(client->dev, "output setup failed: %d\n", err);
1135 return err;
1136 }
1137
1138 if (IS_ENABLED(CONFIG_DEBUG_FS)) {
Thierry Reding776dc382013-10-14 14:43:22 +02001139 err = tegra_hdmi_debugfs_init(hdmi, tegra->drm->primary);
Thierry Redingedec4af2012-11-15 21:28:23 +00001140 if (err < 0)
1141 dev_err(client->dev, "debugfs setup failed: %d\n", err);
1142 }
1143
1144 return 0;
1145}
1146
Thierry Reding53fa7f72013-09-24 15:35:40 +02001147static int tegra_hdmi_exit(struct host1x_client *client)
Thierry Redingedec4af2012-11-15 21:28:23 +00001148{
Thierry Reding776dc382013-10-14 14:43:22 +02001149 struct tegra_hdmi *hdmi = host1x_client_to_hdmi(client);
Thierry Redingedec4af2012-11-15 21:28:23 +00001150 int err;
1151
1152 if (IS_ENABLED(CONFIG_DEBUG_FS)) {
1153 err = tegra_hdmi_debugfs_exit(hdmi);
1154 if (err < 0)
1155 dev_err(client->dev, "debugfs cleanup failed: %d\n",
1156 err);
1157 }
1158
1159 err = tegra_output_disable(&hdmi->output);
1160 if (err < 0) {
1161 dev_err(client->dev, "output failed to disable: %d\n", err);
1162 return err;
1163 }
1164
1165 err = tegra_output_exit(&hdmi->output);
1166 if (err < 0) {
1167 dev_err(client->dev, "output cleanup failed: %d\n", err);
1168 return err;
1169 }
1170
1171 return 0;
1172}
1173
1174static const struct host1x_client_ops hdmi_client_ops = {
Thierry Reding53fa7f72013-09-24 15:35:40 +02001175 .init = tegra_hdmi_init,
1176 .exit = tegra_hdmi_exit,
Thierry Redingedec4af2012-11-15 21:28:23 +00001177};
1178
Thierry Reding59af0592013-10-14 09:43:05 +02001179static const struct tegra_hdmi_config tegra20_hdmi_config = {
1180 .tmds = tegra20_tmds_config,
1181 .num_tmds = ARRAY_SIZE(tegra20_tmds_config),
1182 .fuse_override_offset = HDMI_NV_PDISP_SOR_LANE_DRIVE_CURRENT,
1183 .fuse_override_value = 1 << 31,
1184};
1185
1186static const struct tegra_hdmi_config tegra30_hdmi_config = {
1187 .tmds = tegra30_tmds_config,
1188 .num_tmds = ARRAY_SIZE(tegra30_tmds_config),
1189 .fuse_override_offset = HDMI_NV_PDISP_SOR_LANE_DRIVE_CURRENT,
1190 .fuse_override_value = 1 << 31,
1191};
1192
1193static const struct of_device_id tegra_hdmi_of_match[] = {
1194 { .compatible = "nvidia,tegra30-hdmi", .data = &tegra30_hdmi_config },
1195 { .compatible = "nvidia,tegra20-hdmi", .data = &tegra20_hdmi_config },
1196 { },
1197};
1198
Thierry Redingedec4af2012-11-15 21:28:23 +00001199static int tegra_hdmi_probe(struct platform_device *pdev)
1200{
Thierry Reding59af0592013-10-14 09:43:05 +02001201 const struct of_device_id *match;
Thierry Redingedec4af2012-11-15 21:28:23 +00001202 struct tegra_hdmi *hdmi;
1203 struct resource *regs;
1204 int err;
1205
Thierry Reding59af0592013-10-14 09:43:05 +02001206 match = of_match_node(tegra_hdmi_of_match, pdev->dev.of_node);
1207 if (!match)
1208 return -ENODEV;
1209
Thierry Redingedec4af2012-11-15 21:28:23 +00001210 hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL);
1211 if (!hdmi)
1212 return -ENOMEM;
1213
Thierry Reding59af0592013-10-14 09:43:05 +02001214 hdmi->config = match->data;
Thierry Redingedec4af2012-11-15 21:28:23 +00001215 hdmi->dev = &pdev->dev;
1216 hdmi->audio_source = AUTO;
1217 hdmi->audio_freq = 44100;
1218 hdmi->stereo = false;
1219 hdmi->dvi = false;
1220
1221 hdmi->clk = devm_clk_get(&pdev->dev, NULL);
1222 if (IS_ERR(hdmi->clk)) {
1223 dev_err(&pdev->dev, "failed to get clock\n");
1224 return PTR_ERR(hdmi->clk);
1225 }
1226
1227 err = clk_prepare(hdmi->clk);
1228 if (err < 0)
1229 return err;
1230
1231 hdmi->clk_parent = devm_clk_get(&pdev->dev, "parent");
1232 if (IS_ERR(hdmi->clk_parent))
1233 return PTR_ERR(hdmi->clk_parent);
1234
1235 err = clk_prepare(hdmi->clk_parent);
1236 if (err < 0)
1237 return err;
1238
1239 err = clk_set_parent(hdmi->clk, hdmi->clk_parent);
1240 if (err < 0) {
1241 dev_err(&pdev->dev, "failed to setup clocks: %d\n", err);
1242 return err;
1243 }
1244
1245 hdmi->vdd = devm_regulator_get(&pdev->dev, "vdd");
1246 if (IS_ERR(hdmi->vdd)) {
1247 dev_err(&pdev->dev, "failed to get VDD regulator\n");
1248 return PTR_ERR(hdmi->vdd);
1249 }
1250
1251 hdmi->pll = devm_regulator_get(&pdev->dev, "pll");
1252 if (IS_ERR(hdmi->pll)) {
1253 dev_err(&pdev->dev, "failed to get PLL regulator\n");
1254 return PTR_ERR(hdmi->pll);
1255 }
1256
1257 hdmi->output.dev = &pdev->dev;
1258
Thierry Reding59d29c02013-10-14 14:26:42 +02001259 err = tegra_output_probe(&hdmi->output);
Thierry Redingedec4af2012-11-15 21:28:23 +00001260 if (err < 0)
1261 return err;
1262
1263 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1264 if (!regs)
1265 return -ENXIO;
1266
Thierry Redingd4ed6022013-01-21 11:09:02 +01001267 hdmi->regs = devm_ioremap_resource(&pdev->dev, regs);
1268 if (IS_ERR(hdmi->regs))
1269 return PTR_ERR(hdmi->regs);
Thierry Redingedec4af2012-11-15 21:28:23 +00001270
1271 err = platform_get_irq(pdev, 0);
1272 if (err < 0)
1273 return err;
1274
1275 hdmi->irq = err;
1276
Thierry Reding776dc382013-10-14 14:43:22 +02001277 INIT_LIST_HEAD(&hdmi->client.list);
1278 hdmi->client.ops = &hdmi_client_ops;
1279 hdmi->client.dev = &pdev->dev;
Thierry Redingedec4af2012-11-15 21:28:23 +00001280
Thierry Reding776dc382013-10-14 14:43:22 +02001281 err = host1x_client_register(&hdmi->client);
Thierry Redingedec4af2012-11-15 21:28:23 +00001282 if (err < 0) {
1283 dev_err(&pdev->dev, "failed to register host1x client: %d\n",
1284 err);
1285 return err;
1286 }
1287
1288 platform_set_drvdata(pdev, hdmi);
1289
1290 return 0;
1291}
1292
1293static int tegra_hdmi_remove(struct platform_device *pdev)
1294{
Thierry Redingedec4af2012-11-15 21:28:23 +00001295 struct tegra_hdmi *hdmi = platform_get_drvdata(pdev);
1296 int err;
1297
Thierry Reding776dc382013-10-14 14:43:22 +02001298 err = host1x_client_unregister(&hdmi->client);
Thierry Redingedec4af2012-11-15 21:28:23 +00001299 if (err < 0) {
1300 dev_err(&pdev->dev, "failed to unregister host1x client: %d\n",
1301 err);
1302 return err;
1303 }
1304
Thierry Reding59d29c02013-10-14 14:26:42 +02001305 err = tegra_output_remove(&hdmi->output);
1306 if (err < 0) {
1307 dev_err(&pdev->dev, "failed to remove output: %d\n", err);
1308 return err;
1309 }
1310
Thierry Redingedec4af2012-11-15 21:28:23 +00001311 clk_unprepare(hdmi->clk_parent);
1312 clk_unprepare(hdmi->clk);
1313
1314 return 0;
1315}
1316
Thierry Redingedec4af2012-11-15 21:28:23 +00001317struct platform_driver tegra_hdmi_driver = {
1318 .driver = {
1319 .name = "tegra-hdmi",
1320 .owner = THIS_MODULE,
1321 .of_match_table = tegra_hdmi_of_match,
1322 },
1323 .probe = tegra_hdmi_probe,
1324 .remove = tegra_hdmi_remove,
1325};