1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22#define DSS_SUBSYS_NAME "HDMI"
23
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/err.h>
27#include <linux/io.h>
28#include <linux/interrupt.h>
29#include <linux/mutex.h>
30#include <linux/delay.h>
31#include <linux/string.h>
32#include <linux/platform_device.h>
33#include <linux/pm_runtime.h>
34#include <linux/clk.h>
35#include <video/omapdss.h>
36#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
37 defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
38#include <sound/soc.h>
39#include <sound/pcm_params.h>
40#include "ti_hdmi_4xxx_ip.h"
41#endif
42
43#include "ti_hdmi.h"
44#include "dss.h"
45#include "dss_features.h"
46
47#define HDMI_WP 0x0
48#define HDMI_CORE_SYS 0x400
49#define HDMI_CORE_AV 0x900
50#define HDMI_PLLCTRL 0x200
51#define HDMI_PHY 0x300
52
53
54#define HDMI_EDID_MAX_LENGTH 256
55#define EDID_TIMING_DESCRIPTOR_SIZE 0x12
56#define EDID_DESCRIPTOR_BLOCK0_ADDRESS 0x36
57#define EDID_DESCRIPTOR_BLOCK1_ADDRESS 0x80
58#define EDID_SIZE_BLOCK0_TIMING_DESCRIPTOR 4
59#define EDID_SIZE_BLOCK1_TIMING_DESCRIPTOR 4
60
61#define OMAP_HDMI_TIMINGS_NB 34
62
63#define HDMI_DEFAULT_REGN 16
64#define HDMI_DEFAULT_REGM2 1
65
66static struct {
67 struct mutex lock;
68 struct omap_display_platform_data *pdata;
69 struct platform_device *pdev;
70 struct hdmi_ip_data ip_data;
71 int code;
72 int mode;
73
74 struct clk *sys_clk;
75} hdmi;
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91static const struct hdmi_timings cea_vesa_timings[OMAP_HDMI_TIMINGS_NB] = {
92 { {640, 480, 25200, 96, 16, 48, 2, 10, 33} , 0 , 0},
93 { {1280, 720, 74250, 40, 440, 220, 5, 5, 20}, 1, 1},
94 { {1280, 720, 74250, 40, 110, 220, 5, 5, 20}, 1, 1},
95 { {720, 480, 27027, 62, 16, 60, 6, 9, 30}, 0, 0},
96 { {2880, 576, 108000, 256, 48, 272, 5, 5, 39}, 0, 0},
97 { {1440, 240, 27027, 124, 38, 114, 3, 4, 15}, 0, 0},
98 { {1440, 288, 27000, 126, 24, 138, 3, 2, 19}, 0, 0},
99 { {1920, 540, 74250, 44, 528, 148, 5, 2, 15}, 1, 1},
100 { {1920, 540, 74250, 44, 88, 148, 5, 2, 15}, 1, 1},
101 { {1920, 1080, 148500, 44, 88, 148, 5, 4, 36}, 1, 1},
102 { {720, 576, 27000, 64, 12, 68, 5, 5, 39}, 0, 0},
103 { {1440, 576, 54000, 128, 24, 136, 5, 5, 39}, 0, 0},
104 { {1920, 1080, 148500, 44, 528, 148, 5, 4, 36}, 1, 1},
105 { {2880, 480, 108108, 248, 64, 240, 6, 9, 30}, 0, 0},
106 { {1920, 1080, 74250, 44, 638, 148, 5, 4, 36}, 1, 1},
107
108 { {640, 480, 25175, 96, 16, 48, 2 , 11, 31}, 0, 0},
109 { {800, 600, 40000, 128, 40, 88, 4 , 1, 23}, 1, 1},
110 { {848, 480, 33750, 112, 16, 112, 8 , 6, 23}, 1, 1},
111 { {1280, 768, 79500, 128, 64, 192, 7 , 3, 20}, 1, 0},
112 { {1280, 800, 83500, 128, 72, 200, 6 , 3, 22}, 1, 0},
113 { {1360, 768, 85500, 112, 64, 256, 6 , 3, 18}, 1, 1},
114 { {1280, 960, 108000, 112, 96, 312, 3 , 1, 36}, 1, 1},
115 { {1280, 1024, 108000, 112, 48, 248, 3 , 1, 38}, 1, 1},
116 { {1024, 768, 65000, 136, 24, 160, 6, 3, 29}, 0, 0},
117 { {1400, 1050, 121750, 144, 88, 232, 4, 3, 32}, 1, 0},
118 { {1440, 900, 106500, 152, 80, 232, 6, 3, 25}, 1, 0},
119 { {1680, 1050, 146250, 176 , 104, 280, 6, 3, 30}, 1, 0},
120 { {1366, 768, 85500, 143, 70, 213, 3, 3, 24}, 1, 1},
121 { {1920, 1080, 148500, 44, 148, 80, 5, 4, 36}, 1, 1},
122 { {1280, 768, 68250, 32, 48, 80, 7, 3, 12}, 0, 1},
123 { {1400, 1050, 101000, 32, 48, 80, 4, 3, 23}, 0, 1},
124 { {1680, 1050, 119000, 32, 48, 80, 6, 3, 21}, 0, 1},
125 { {1280, 800, 79500, 32, 48, 80, 6, 3, 14}, 0, 1},
126 { {1280, 720, 74250, 40, 110, 220, 5, 5, 20}, 1, 1}
127};
128
129
130
131
132
133static const int code_index[OMAP_HDMI_TIMINGS_NB] = {
134 1, 19, 4, 2, 37, 6, 21, 20, 5, 16, 17, 29, 31, 35, 32,
135
136 4, 9, 0xE, 0x17, 0x1C, 0x27, 0x20, 0x23, 0x10, 0x2A,
137 0X2F, 0x3A, 0X51, 0X52, 0x16, 0x29, 0x39, 0x1B
138};
139
140
141
142
143
144static const int code_cea[39] = {
145 -1, 0, 3, 3, 2, 8, 5, 5, -1, -1,
146 -1, -1, -1, -1, -1, -1, 9, 10, 10, 1,
147 7, 6, 6, -1, -1, -1, -1, -1, -1, 11,
148 11, 12, 14, -1, -1, 13, 13, 4, 4
149};
150
151static const int code_vesa[85] = {
152 -1, -1, -1, -1, 15, -1, -1, -1, -1, 16,
153 -1, -1, -1, -1, 17, -1, 23, -1, -1, -1,
154 -1, -1, 29, 18, -1, -1, -1, 32, 19, -1,
155 -1, -1, 21, -1, -1, 22, -1, -1, -1, 20,
156 -1, 30, 24, -1, -1, -1, -1, 25, -1, -1,
157 -1, -1, -1, -1, -1, -1, -1, 31, 26, -1,
158 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
159 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
160 -1, 27, 28, -1, 33};
161
162static int hdmi_runtime_get(void)
163{
164 int r;
165
166 DSSDBG("hdmi_runtime_get\n");
167
168
169
170
171
172 r = dss_runtime_get();
173 if (r < 0)
174 goto err_get_dss;
175
176 r = pm_runtime_get_sync(&hdmi.pdev->dev);
177 WARN_ON(r < 0);
178 if (r < 0)
179 goto err_get_hdmi;
180
181 return 0;
182
183err_get_hdmi:
184 dss_runtime_put();
185err_get_dss:
186 return r;
187}
188
189static void hdmi_runtime_put(void)
190{
191 int r;
192
193 DSSDBG("hdmi_runtime_put\n");
194
195 r = pm_runtime_put_sync(&hdmi.pdev->dev);
196 WARN_ON(r < 0);
197
198
199
200
201
202 dss_runtime_put();
203}
204
205int hdmi_init_display(struct omap_dss_device *dssdev)
206{
207 DSSDBG("init_display\n");
208
209 dss_init_hdmi_ip_ops(&hdmi.ip_data);
210 return 0;
211}
212
213static int get_timings_index(void)
214{
215 int code;
216
217 if (hdmi.mode == 0)
218 code = code_vesa[hdmi.code];
219 else
220 code = code_cea[hdmi.code];
221
222 if (code == -1) {
223
224 hdmi.code = 4;
225
226 hdmi.mode = HDMI_DVI;
227
228 code = code_vesa[hdmi.code];
229 }
230 return code;
231}
232
233static struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing)
234{
235 int i = 0, code = -1, temp_vsync = 0, temp_hsync = 0;
236 int timing_vsync = 0, timing_hsync = 0;
237 struct hdmi_video_timings temp;
238 struct hdmi_cm cm = {-1};
239 DSSDBG("hdmi_get_code\n");
240
241 for (i = 0; i < OMAP_HDMI_TIMINGS_NB; i++) {
242 temp = cea_vesa_timings[i].timings;
243 if ((temp.pixel_clock == timing->pixel_clock) &&
244 (temp.x_res == timing->x_res) &&
245 (temp.y_res == timing->y_res)) {
246
247 temp_hsync = temp.hfp + temp.hsw + temp.hbp;
248 timing_hsync = timing->hfp + timing->hsw + timing->hbp;
249 temp_vsync = temp.vfp + temp.vsw + temp.vbp;
250 timing_vsync = timing->vfp + timing->vsw + timing->vbp;
251
252 DSSDBG("temp_hsync = %d , temp_vsync = %d"
253 "timing_hsync = %d, timing_vsync = %d\n",
254 temp_hsync, temp_hsync,
255 timing_hsync, timing_vsync);
256
257 if ((temp_hsync == timing_hsync) &&
258 (temp_vsync == timing_vsync)) {
259 code = i;
260 cm.code = code_index[i];
261 if (code < 14)
262 cm.mode = HDMI_HDMI;
263 else
264 cm.mode = HDMI_DVI;
265 DSSDBG("Hdmi_code = %d mode = %d\n",
266 cm.code, cm.mode);
267 break;
268 }
269 }
270 }
271
272 return cm;
273}
274
275static void update_hdmi_timings(struct hdmi_config *cfg,
276 struct omap_video_timings *timings, int code)
277{
278 cfg->timings.timings.x_res = timings->x_res;
279 cfg->timings.timings.y_res = timings->y_res;
280 cfg->timings.timings.hbp = timings->hbp;
281 cfg->timings.timings.hfp = timings->hfp;
282 cfg->timings.timings.hsw = timings->hsw;
283 cfg->timings.timings.vbp = timings->vbp;
284 cfg->timings.timings.vfp = timings->vfp;
285 cfg->timings.timings.vsw = timings->vsw;
286 cfg->timings.timings.pixel_clock = timings->pixel_clock;
287 cfg->timings.vsync_pol = cea_vesa_timings[code].vsync_pol;
288 cfg->timings.hsync_pol = cea_vesa_timings[code].hsync_pol;
289}
290
291unsigned long hdmi_get_pixel_clock(void)
292{
293
294 return hdmi.ip_data.cfg.timings.timings.pixel_clock * 1000;
295}
296
297static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy,
298 struct hdmi_pll_info *pi)
299{
300 unsigned long clkin, refclk;
301 u32 mf;
302
303 clkin = clk_get_rate(hdmi.sys_clk) / 10000;
304
305
306
307
308 if (dssdev->clocks.hdmi.regn == 0)
309 pi->regn = HDMI_DEFAULT_REGN;
310 else
311 pi->regn = dssdev->clocks.hdmi.regn;
312
313 refclk = clkin / pi->regn;
314
315
316
317
318
319 pi->regm = (phy * 100 / (refclk)) / 100;
320
321 if (dssdev->clocks.hdmi.regm2 == 0)
322 pi->regm2 = HDMI_DEFAULT_REGM2;
323 else
324 pi->regm2 = dssdev->clocks.hdmi.regm2;
325
326
327
328
329
330
331 mf = (phy - pi->regm * refclk) * 262144;
332 pi->regmf = mf / (refclk);
333
334
335
336
337
338 pi->dcofreq = phy > 1000 * 100;
339 pi->regsd = ((pi->regm * clkin / 10) / (pi->regn * 250) + 5) / 10;
340
341
342 pi->refsel = HDMI_REFSEL_SYSCLK;
343
344 DSSDBG("M = %d Mf = %d\n", pi->regm, pi->regmf);
345 DSSDBG("range = %d sd = %d\n", pi->dcofreq, pi->regsd);
346}
347
348static int hdmi_power_on(struct omap_dss_device *dssdev)
349{
350 int r, code = 0;
351 struct omap_video_timings *p;
352 unsigned long phy;
353
354 r = hdmi_runtime_get();
355 if (r)
356 return r;
357
358 dss_mgr_disable(dssdev->manager);
359
360 p = &dssdev->panel.timings;
361
362 DSSDBG("hdmi_power_on x_res= %d y_res = %d\n",
363 dssdev->panel.timings.x_res,
364 dssdev->panel.timings.y_res);
365
366 code = get_timings_index();
367 update_hdmi_timings(&hdmi.ip_data.cfg, p, code);
368
369 phy = p->pixel_clock;
370
371 hdmi_compute_pll(dssdev, phy, &hdmi.ip_data.pll_data);
372
373 hdmi.ip_data.ops->video_enable(&hdmi.ip_data, 0);
374
375
376 r = hdmi.ip_data.ops->pll_enable(&hdmi.ip_data);
377 if (r) {
378 DSSDBG("Failed to lock PLL\n");
379 goto err;
380 }
381
382 r = hdmi.ip_data.ops->phy_enable(&hdmi.ip_data);
383 if (r) {
384 DSSDBG("Failed to start PHY\n");
385 goto err;
386 }
387
388 hdmi.ip_data.cfg.cm.mode = hdmi.mode;
389 hdmi.ip_data.cfg.cm.code = hdmi.code;
390 hdmi.ip_data.ops->video_configure(&hdmi.ip_data);
391
392
393 dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK);
394
395
396
397
398
399
400
401 dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src);
402
403
404 dispc_enable_gamma_table(0);
405
406
407 dispc_set_digit_size(dssdev->panel.timings.x_res,
408 dssdev->panel.timings.y_res);
409
410 hdmi.ip_data.ops->video_enable(&hdmi.ip_data, 1);
411
412 r = dss_mgr_enable(dssdev->manager);
413 if (r)
414 goto err_mgr_enable;
415
416 return 0;
417
418err_mgr_enable:
419 hdmi.ip_data.ops->video_enable(&hdmi.ip_data, 0);
420 hdmi.ip_data.ops->phy_disable(&hdmi.ip_data);
421 hdmi.ip_data.ops->pll_disable(&hdmi.ip_data);
422err:
423 hdmi_runtime_put();
424 return -EIO;
425}
426
427static void hdmi_power_off(struct omap_dss_device *dssdev)
428{
429 dss_mgr_disable(dssdev->manager);
430
431 hdmi.ip_data.ops->video_enable(&hdmi.ip_data, 0);
432 hdmi.ip_data.ops->phy_disable(&hdmi.ip_data);
433 hdmi.ip_data.ops->pll_disable(&hdmi.ip_data);
434 hdmi_runtime_put();
435}
436
437int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
438 struct omap_video_timings *timings)
439{
440 struct hdmi_cm cm;
441
442 cm = hdmi_get_code(timings);
443 if (cm.code == -1) {
444 return -EINVAL;
445 }
446
447 return 0;
448
449}
450
451void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev)
452{
453 struct hdmi_cm cm;
454
455 cm = hdmi_get_code(&dssdev->panel.timings);
456 hdmi.code = cm.code;
457 hdmi.mode = cm.mode;
458
459 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
460 int r;
461
462 hdmi_power_off(dssdev);
463
464 r = hdmi_power_on(dssdev);
465 if (r)
466 DSSERR("failed to power on device\n");
467 }
468}
469
470void hdmi_dump_regs(struct seq_file *s)
471{
472 mutex_lock(&hdmi.lock);
473
474 if (hdmi_runtime_get())
475 return;
476
477 hdmi.ip_data.ops->dump_wrapper(&hdmi.ip_data, s);
478 hdmi.ip_data.ops->dump_pll(&hdmi.ip_data, s);
479 hdmi.ip_data.ops->dump_phy(&hdmi.ip_data, s);
480 hdmi.ip_data.ops->dump_core(&hdmi.ip_data, s);
481
482 hdmi_runtime_put();
483 mutex_unlock(&hdmi.lock);
484}
485
486int omapdss_hdmi_read_edid(u8 *buf, int len)
487{
488 int r;
489
490 mutex_lock(&hdmi.lock);
491
492 r = hdmi_runtime_get();
493 BUG_ON(r);
494
495 r = hdmi.ip_data.ops->read_edid(&hdmi.ip_data, buf, len);
496
497 hdmi_runtime_put();
498 mutex_unlock(&hdmi.lock);
499
500 return r;
501}
502
503bool omapdss_hdmi_detect(void)
504{
505 int r;
506
507 mutex_lock(&hdmi.lock);
508
509 r = hdmi_runtime_get();
510 BUG_ON(r);
511
512 r = hdmi.ip_data.ops->detect(&hdmi.ip_data);
513
514 hdmi_runtime_put();
515 mutex_unlock(&hdmi.lock);
516
517 return r == 1;
518}
519
520int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
521{
522 struct omap_dss_hdmi_data *priv = dssdev->data;
523 int r = 0;
524
525 DSSDBG("ENTER hdmi_display_enable\n");
526
527 mutex_lock(&hdmi.lock);
528
529 if (dssdev->manager == NULL) {
530 DSSERR("failed to enable display: no manager\n");
531 r = -ENODEV;
532 goto err0;
533 }
534
535 hdmi.ip_data.hpd_gpio = priv->hpd_gpio;
536
537 r = omap_dss_start_device(dssdev);
538 if (r) {
539 DSSERR("failed to start device\n");
540 goto err0;
541 }
542
543 if (dssdev->platform_enable) {
544 r = dssdev->platform_enable(dssdev);
545 if (r) {
546 DSSERR("failed to enable GPIO's\n");
547 goto err1;
548 }
549 }
550
551 r = hdmi_power_on(dssdev);
552 if (r) {
553 DSSERR("failed to power on device\n");
554 goto err2;
555 }
556
557 mutex_unlock(&hdmi.lock);
558 return 0;
559
560err2:
561 if (dssdev->platform_disable)
562 dssdev->platform_disable(dssdev);
563err1:
564 omap_dss_stop_device(dssdev);
565err0:
566 mutex_unlock(&hdmi.lock);
567 return r;
568}
569
570void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev)
571{
572 DSSDBG("Enter hdmi_display_disable\n");
573
574 mutex_lock(&hdmi.lock);
575
576 hdmi_power_off(dssdev);
577
578 if (dssdev->platform_disable)
579 dssdev->platform_disable(dssdev);
580
581 omap_dss_stop_device(dssdev);
582
583 mutex_unlock(&hdmi.lock);
584}
585
586#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
587 defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
588
589static int hdmi_audio_trigger(struct snd_pcm_substream *substream, int cmd,
590 struct snd_soc_dai *dai)
591{
592 struct snd_soc_pcm_runtime *rtd = substream->private_data;
593 struct snd_soc_codec *codec = rtd->codec;
594 struct platform_device *pdev = to_platform_device(codec->dev);
595 struct hdmi_ip_data *ip_data = snd_soc_codec_get_drvdata(codec);
596 int err = 0;
597
598 if (!(ip_data->ops) && !(ip_data->ops->audio_enable)) {
599 dev_err(&pdev->dev, "Cannot enable/disable audio\n");
600 return -ENODEV;
601 }
602
603 switch (cmd) {
604 case SNDRV_PCM_TRIGGER_START:
605 case SNDRV_PCM_TRIGGER_RESUME:
606 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
607 ip_data->ops->audio_enable(ip_data, true);
608 break;
609 case SNDRV_PCM_TRIGGER_STOP:
610 case SNDRV_PCM_TRIGGER_SUSPEND:
611 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
612 ip_data->ops->audio_enable(ip_data, false);
613 break;
614 default:
615 err = -EINVAL;
616 }
617 return err;
618}
619
620static int hdmi_audio_hw_params(struct snd_pcm_substream *substream,
621 struct snd_pcm_hw_params *params,
622 struct snd_soc_dai *dai)
623{
624 struct snd_soc_pcm_runtime *rtd = substream->private_data;
625 struct snd_soc_codec *codec = rtd->codec;
626 struct hdmi_ip_data *ip_data = snd_soc_codec_get_drvdata(codec);
627 struct hdmi_audio_format audio_format;
628 struct hdmi_audio_dma audio_dma;
629 struct hdmi_core_audio_config core_cfg;
630 struct hdmi_core_infoframe_audio aud_if_cfg;
631 int err, n, cts;
632 enum hdmi_core_audio_sample_freq sample_freq;
633
634 switch (params_format(params)) {
635 case SNDRV_PCM_FORMAT_S16_LE:
636 core_cfg.i2s_cfg.word_max_length =
637 HDMI_AUDIO_I2S_MAX_WORD_20BITS;
638 core_cfg.i2s_cfg.word_length = HDMI_AUDIO_I2S_CHST_WORD_16_BITS;
639 core_cfg.i2s_cfg.in_length_bits =
640 HDMI_AUDIO_I2S_INPUT_LENGTH_16;
641 core_cfg.i2s_cfg.justification = HDMI_AUDIO_JUSTIFY_LEFT;
642 audio_format.samples_per_word = HDMI_AUDIO_ONEWORD_TWOSAMPLES;
643 audio_format.sample_size = HDMI_AUDIO_SAMPLE_16BITS;
644 audio_format.justification = HDMI_AUDIO_JUSTIFY_LEFT;
645 audio_dma.transfer_size = 0x10;
646 break;
647 case SNDRV_PCM_FORMAT_S24_LE:
648 core_cfg.i2s_cfg.word_max_length =
649 HDMI_AUDIO_I2S_MAX_WORD_24BITS;
650 core_cfg.i2s_cfg.word_length = HDMI_AUDIO_I2S_CHST_WORD_24_BITS;
651 core_cfg.i2s_cfg.in_length_bits =
652 HDMI_AUDIO_I2S_INPUT_LENGTH_24;
653 audio_format.samples_per_word = HDMI_AUDIO_ONEWORD_ONESAMPLE;
654 audio_format.sample_size = HDMI_AUDIO_SAMPLE_24BITS;
655 audio_format.justification = HDMI_AUDIO_JUSTIFY_RIGHT;
656 core_cfg.i2s_cfg.justification = HDMI_AUDIO_JUSTIFY_RIGHT;
657 audio_dma.transfer_size = 0x20;
658 break;
659 default:
660 return -EINVAL;
661 }
662
663 switch (params_rate(params)) {
664 case 32000:
665 sample_freq = HDMI_AUDIO_FS_32000;
666 break;
667 case 44100:
668 sample_freq = HDMI_AUDIO_FS_44100;
669 break;
670 case 48000:
671 sample_freq = HDMI_AUDIO_FS_48000;
672 break;
673 default:
674 return -EINVAL;
675 }
676
677 err = hdmi_config_audio_acr(ip_data, params_rate(params), &n, &cts);
678 if (err < 0)
679 return err;
680
681
682 audio_format.stereo_channels = HDMI_AUDIO_STEREO_ONECHANNEL;
683 audio_format.active_chnnls_msk = 0x03;
684 audio_format.type = HDMI_AUDIO_TYPE_LPCM;
685 audio_format.sample_order = HDMI_AUDIO_SAMPLE_LEFT_FIRST;
686
687 audio_format.en_sig_blk_strt_end = HDMI_AUDIO_BLOCK_SIG_STARTEND_OFF;
688
689 audio_dma.block_size = 0xC0;
690 audio_dma.mode = HDMI_AUDIO_TRANSF_DMA;
691 audio_dma.fifo_threshold = 0x20;
692
693 hdmi_wp_audio_config_dma(ip_data, &audio_dma);
694 hdmi_wp_audio_config_format(ip_data, &audio_format);
695
696
697
698
699 core_cfg.i2s_cfg.en_high_bitrate_aud = false;
700
701 core_cfg.i2s_cfg.cbit_order = false;
702
703 core_cfg.i2s_cfg.sck_edge_mode = HDMI_AUDIO_I2S_SCK_EDGE_RISING;
704 core_cfg.i2s_cfg.vbit = HDMI_AUDIO_I2S_VBIT_FOR_PCM;
705
706 core_cfg.i2s_cfg.ws_polarity = HDMI_AUDIO_I2S_WS_POLARITY_LOW_IS_LEFT;
707 core_cfg.i2s_cfg.direction = HDMI_AUDIO_I2S_MSB_SHIFTED_FIRST;
708
709 core_cfg.i2s_cfg.shift = HDMI_AUDIO_I2S_FIRST_BIT_SHIFT;
710
711 core_cfg.i2s_cfg.active_sds = HDMI_AUDIO_I2S_SD0_EN;
712
713
714 core_cfg.freq_sample = sample_freq;
715 core_cfg.n = n;
716 core_cfg.cts = cts;
717 if (dss_has_feature(FEAT_HDMI_CTS_SWMODE)) {
718 core_cfg.aud_par_busclk = 0;
719 core_cfg.cts_mode = HDMI_AUDIO_CTS_MODE_SW;
720 core_cfg.use_mclk = false;
721 } else {
722 core_cfg.aud_par_busclk = (((128 * 31) - 1) << 8);
723 core_cfg.cts_mode = HDMI_AUDIO_CTS_MODE_HW;
724 core_cfg.use_mclk = true;
725 core_cfg.mclk_mode = HDMI_AUDIO_MCLK_128FS;
726 }
727 core_cfg.layout = HDMI_AUDIO_LAYOUT_2CH;
728 core_cfg.en_spdif = false;
729
730 core_cfg.fs_override = true;
731
732 core_cfg.en_acr_pkt = true;
733
734 core_cfg.en_dsd_audio = false;
735
736 core_cfg.en_parallel_aud_input = true;
737
738 hdmi_core_audio_config(ip_data, &core_cfg);
739
740
741
742
743
744 aud_if_cfg.db1_coding_type = HDMI_INFOFRAME_AUDIO_DB1CT_FROM_STREAM;
745 aud_if_cfg.db1_channel_count = 2;
746 aud_if_cfg.db2_sample_freq = HDMI_INFOFRAME_AUDIO_DB2SF_FROM_STREAM;
747 aud_if_cfg.db2_sample_size = HDMI_INFOFRAME_AUDIO_DB2SS_FROM_STREAM;
748 aud_if_cfg.db4_channel_alloc = 0x00;
749 aud_if_cfg.db5_downmix_inh = false;
750 aud_if_cfg.db5_lsv = 0;
751
752 hdmi_core_audio_infoframe_config(ip_data, &aud_if_cfg);
753 return 0;
754}
755
756static int hdmi_audio_startup(struct snd_pcm_substream *substream,
757 struct snd_soc_dai *dai)
758{
759 if (!hdmi.mode) {
760 pr_err("Current video settings do not support audio.\n");
761 return -EIO;
762 }
763 return 0;
764}
765
766static int hdmi_audio_codec_probe(struct snd_soc_codec *codec)
767{
768 struct hdmi_ip_data *priv = &hdmi.ip_data;
769
770 snd_soc_codec_set_drvdata(codec, priv);
771 return 0;
772}
773
774static struct snd_soc_codec_driver hdmi_audio_codec_drv = {
775 .probe = hdmi_audio_codec_probe,
776};
777
778static struct snd_soc_dai_ops hdmi_audio_codec_ops = {
779 .hw_params = hdmi_audio_hw_params,
780 .trigger = hdmi_audio_trigger,
781 .startup = hdmi_audio_startup,
782};
783
784static struct snd_soc_dai_driver hdmi_codec_dai_drv = {
785 .name = "hdmi-audio-codec",
786 .playback = {
787 .channels_min = 2,
788 .channels_max = 2,
789 .rates = SNDRV_PCM_RATE_32000 |
790 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
791 .formats = SNDRV_PCM_FMTBIT_S16_LE |
792 SNDRV_PCM_FMTBIT_S24_LE,
793 },
794 .ops = &hdmi_audio_codec_ops,
795};
796#endif
797
798static int hdmi_get_clocks(struct platform_device *pdev)
799{
800 struct clk *clk;
801
802 clk = clk_get(&pdev->dev, "sys_clk");
803 if (IS_ERR(clk)) {
804 DSSERR("can't get sys_clk\n");
805 return PTR_ERR(clk);
806 }
807
808 hdmi.sys_clk = clk;
809
810 return 0;
811}
812
813static void hdmi_put_clocks(void)
814{
815 if (hdmi.sys_clk)
816 clk_put(hdmi.sys_clk);
817}
818
819
820static int omapdss_hdmihw_probe(struct platform_device *pdev)
821{
822 struct resource *hdmi_mem;
823 int r;
824
825 hdmi.pdata = pdev->dev.platform_data;
826 hdmi.pdev = pdev;
827
828 mutex_init(&hdmi.lock);
829
830 hdmi_mem = platform_get_resource(hdmi.pdev, IORESOURCE_MEM, 0);
831 if (!hdmi_mem) {
832 DSSERR("can't get IORESOURCE_MEM HDMI\n");
833 return -EINVAL;
834 }
835
836
837 hdmi.ip_data.base_wp = ioremap(hdmi_mem->start,
838 resource_size(hdmi_mem));
839 if (!hdmi.ip_data.base_wp) {
840 DSSERR("can't ioremap WP\n");
841 return -ENOMEM;
842 }
843
844 r = hdmi_get_clocks(pdev);
845 if (r) {
846 iounmap(hdmi.ip_data.base_wp);
847 return r;
848 }
849
850 pm_runtime_enable(&pdev->dev);
851
852 hdmi.ip_data.core_sys_offset = HDMI_CORE_SYS;
853 hdmi.ip_data.core_av_offset = HDMI_CORE_AV;
854 hdmi.ip_data.pll_offset = HDMI_PLLCTRL;
855 hdmi.ip_data.phy_offset = HDMI_PHY;
856
857 hdmi_panel_init();
858
859#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
860 defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
861
862
863 r = snd_soc_register_codec(&pdev->dev, &hdmi_audio_codec_drv,
864 &hdmi_codec_dai_drv, 1);
865 if (r) {
866 DSSERR("can't register ASoC HDMI audio codec\n");
867 return r;
868 }
869#endif
870 return 0;
871}
872
873static int omapdss_hdmihw_remove(struct platform_device *pdev)
874{
875 hdmi_panel_exit();
876
877#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
878 defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
879 snd_soc_unregister_codec(&pdev->dev);
880#endif
881
882 pm_runtime_disable(&pdev->dev);
883
884 hdmi_put_clocks();
885
886 iounmap(hdmi.ip_data.base_wp);
887
888 return 0;
889}
890
891static int hdmi_runtime_suspend(struct device *dev)
892{
893 clk_disable(hdmi.sys_clk);
894
895 dispc_runtime_put();
896 dss_runtime_put();
897
898 return 0;
899}
900
901static int hdmi_runtime_resume(struct device *dev)
902{
903 int r;
904
905 r = dss_runtime_get();
906 if (r < 0)
907 goto err_get_dss;
908
909 r = dispc_runtime_get();
910 if (r < 0)
911 goto err_get_dispc;
912
913
914 clk_enable(hdmi.sys_clk);
915
916 return 0;
917
918err_get_dispc:
919 dss_runtime_put();
920err_get_dss:
921 return r;
922}
923
924static const struct dev_pm_ops hdmi_pm_ops = {
925 .runtime_suspend = hdmi_runtime_suspend,
926 .runtime_resume = hdmi_runtime_resume,
927};
928
929static struct platform_driver omapdss_hdmihw_driver = {
930 .probe = omapdss_hdmihw_probe,
931 .remove = omapdss_hdmihw_remove,
932 .driver = {
933 .name = "omapdss_hdmi",
934 .owner = THIS_MODULE,
935 .pm = &hdmi_pm_ops,
936 },
937};
938
939int hdmi_init_platform_driver(void)
940{
941 return platform_driver_register(&omapdss_hdmihw_driver);
942}
943
944void hdmi_uninit_platform_driver(void)
945{
946 return platform_driver_unregister(&omapdss_hdmihw_driver);
947}
948