]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/video/omap2/dss/hdmi.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph...
[karo-tx-linux.git] / drivers / video / omap2 / dss / hdmi.c
1 /*
2  * hdmi.c
3  *
4  * HDMI interface DSS driver setting for TI's OMAP4 family of processor.
5  * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/
6  * Authors: Yong Zhi
7  *      Mythri pk <mythripk@ti.com>
8  *
9  * This program is free software; you can redistribute it and/or modify it
10  * under the terms of the GNU General Public License version 2 as published by
11  * the Free Software Foundation.
12  *
13  * This program is distributed in the hope that it will be useful, but WITHOUT
14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
16  * more details.
17  *
18  * You should have received a copy of the GNU General Public License along with
19  * this program.  If not, see <http://www.gnu.org/licenses/>.
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 /* HDMI EDID Length move this */
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 HDMI_DEFAULT_REGN 16
62 #define HDMI_DEFAULT_REGM2 1
63
64 static struct {
65         struct mutex lock;
66         struct omap_display_platform_data *pdata;
67         struct platform_device *pdev;
68         struct hdmi_ip_data ip_data;
69
70         struct clk *sys_clk;
71 } hdmi;
72
73 /*
74  * Logic for the below structure :
75  * user enters the CEA or VESA timings by specifying the HDMI/DVI code.
76  * There is a correspondence between CEA/VESA timing and code, please
77  * refer to section 6.3 in HDMI 1.3 specification for timing code.
78  *
79  * In the below structure, cea_vesa_timings corresponds to all OMAP4
80  * supported CEA and VESA timing values.code_cea corresponds to the CEA
81  * code, It is used to get the timing from cea_vesa_timing array.Similarly
82  * with code_vesa. Code_index is used for back mapping, that is once EDID
83  * is read from the TV, EDID is parsed to find the timing values and then
84  * map it to corresponding CEA or VESA index.
85  */
86
87 static const struct hdmi_config cea_timings[] = {
88 { {640, 480, 25200, 96, 16, 48, 2, 10, 33, 0, 0, 0}, {1, HDMI_HDMI} },
89 { {720, 480, 27027, 62, 16, 60, 6, 9, 30, 0, 0, 0}, {2, HDMI_HDMI} },
90 { {1280, 720, 74250, 40, 110, 220, 5, 5, 20, 1, 1, 0}, {4, HDMI_HDMI} },
91 { {1920, 540, 74250, 44, 88, 148, 5, 2, 15, 1, 1, 1}, {5, HDMI_HDMI} },
92 { {1440, 240, 27027, 124, 38, 114, 3, 4, 15, 0, 0, 1}, {6, HDMI_HDMI} },
93 { {1920, 1080, 148500, 44, 88, 148, 5, 4, 36, 1, 1, 0}, {16, HDMI_HDMI} },
94 { {720, 576, 27000, 64, 12, 68, 5, 5, 39, 0, 0, 0}, {17, HDMI_HDMI} },
95 { {1280, 720, 74250, 40, 440, 220, 5, 5, 20, 1, 1, 0}, {19, HDMI_HDMI} },
96 { {1920, 540, 74250, 44, 528, 148, 5, 2, 15, 1, 1, 1}, {20, HDMI_HDMI} },
97 { {1440, 288, 27000, 126, 24, 138, 3, 2, 19, 0, 0, 1}, {21, HDMI_HDMI} },
98 { {1440, 576, 54000, 128, 24, 136, 5, 5, 39, 0, 0, 0}, {29, HDMI_HDMI} },
99 { {1920, 1080, 148500, 44, 528, 148, 5, 4, 36, 1, 1, 0}, {31, HDMI_HDMI} },
100 { {1920, 1080, 74250, 44, 638, 148, 5, 4, 36, 1, 1, 0}, {32, HDMI_HDMI} },
101 { {2880, 480, 108108, 248, 64, 240, 6, 9, 30, 0, 0, 0}, {35, HDMI_HDMI} },
102 { {2880, 576, 108000, 256, 48, 272, 5, 5, 39, 0, 0, 0}, {37, HDMI_HDMI} },
103 };
104 static const struct hdmi_config vesa_timings[] = {
105 /* VESA From Here */
106 { {640, 480, 25175, 96, 16, 48, 2 , 11, 31, 0, 0, 0}, {4, HDMI_DVI} },
107 { {800, 600, 40000, 128, 40, 88, 4 , 1, 23, 1, 1, 0}, {9, HDMI_DVI} },
108 { {848, 480, 33750, 112, 16, 112, 8 , 6, 23, 1, 1, 0}, {0xE, HDMI_DVI} },
109 { {1280, 768, 79500, 128, 64, 192, 7 , 3, 20, 1, 0, 0}, {0x17, HDMI_DVI} },
110 { {1280, 800, 83500, 128, 72, 200, 6 , 3, 22, 1, 0, 0}, {0x1C, HDMI_DVI} },
111 { {1360, 768, 85500, 112, 64, 256, 6 , 3, 18, 1, 1, 0}, {0x27, HDMI_DVI} },
112 { {1280, 960, 108000, 112, 96, 312, 3 , 1, 36, 1, 1, 0}, {0x20, HDMI_DVI} },
113 { {1280, 1024, 108000, 112, 48, 248, 3 , 1, 38, 1, 1, 0}, {0x23, HDMI_DVI} },
114 { {1024, 768, 65000, 136, 24, 160, 6, 3, 29, 0, 0, 0}, {0x10, HDMI_DVI} },
115 { {1400, 1050, 121750, 144, 88, 232, 4, 3, 32, 1, 0, 0}, {0x2A, HDMI_DVI} },
116 { {1440, 900, 106500, 152, 80, 232, 6, 3, 25, 1, 0, 0}, {0x2F, HDMI_DVI} },
117 { {1680, 1050, 146250, 176 , 104, 280, 6, 3, 30, 1, 0, 0}, {0x3A, HDMI_DVI} },
118 { {1366, 768, 85500, 143, 70, 213, 3, 3, 24, 1, 1, 0}, {0x51, HDMI_DVI} },
119 { {1920, 1080, 148500, 44, 148, 80, 5, 4, 36, 1, 1, 0}, {0x52, HDMI_DVI} },
120 { {1280, 768, 68250, 32, 48, 80, 7, 3, 12, 0, 1, 0}, {0x16, HDMI_DVI} },
121 { {1400, 1050, 101000, 32, 48, 80, 4, 3, 23, 0, 1, 0}, {0x29, HDMI_DVI} },
122 { {1680, 1050, 119000, 32, 48, 80, 6, 3, 21, 0, 1, 0}, {0x39, HDMI_DVI} },
123 { {1280, 800, 79500, 32, 48, 80, 6, 3, 14, 0, 1, 0}, {0x1B, HDMI_DVI} },
124 { {1280, 720, 74250, 40, 110, 220, 5, 5, 20, 1, 1, 0}, {0x55, HDMI_DVI} }
125 };
126
127 static int hdmi_runtime_get(void)
128 {
129         int r;
130
131         DSSDBG("hdmi_runtime_get\n");
132
133         /*
134          * HACK: Add dss_runtime_get() to ensure DSS clock domain is enabled.
135          * This should be removed later.
136          */
137         r = dss_runtime_get();
138         if (r < 0)
139                 goto err_get_dss;
140
141         r = pm_runtime_get_sync(&hdmi.pdev->dev);
142         WARN_ON(r < 0);
143         if (r < 0)
144                 goto err_get_hdmi;
145
146         return 0;
147
148 err_get_hdmi:
149         dss_runtime_put();
150 err_get_dss:
151         return r;
152 }
153
154 static void hdmi_runtime_put(void)
155 {
156         int r;
157
158         DSSDBG("hdmi_runtime_put\n");
159
160         r = pm_runtime_put_sync(&hdmi.pdev->dev);
161         WARN_ON(r < 0);
162
163         /*
164          * HACK: This is added to complement the dss_runtime_get() call in
165          * hdmi_runtime_get(). This should be removed later.
166          */
167         dss_runtime_put();
168 }
169
170 int hdmi_init_display(struct omap_dss_device *dssdev)
171 {
172         DSSDBG("init_display\n");
173
174         dss_init_hdmi_ip_ops(&hdmi.ip_data);
175         return 0;
176 }
177
178 static const struct hdmi_config *hdmi_find_timing(
179                                         const struct hdmi_config *timings_arr,
180                                         int len)
181 {
182         int i;
183
184         for (i = 0; i < len; i++) {
185                 if (timings_arr[i].cm.code == hdmi.ip_data.cfg.cm.code)
186                         return &timings_arr[i];
187         }
188         return NULL;
189 }
190
191 static const struct hdmi_config *hdmi_get_timings(void)
192 {
193        const struct hdmi_config *arr;
194        int len;
195
196        if (hdmi.ip_data.cfg.cm.mode == HDMI_DVI) {
197                arr = vesa_timings;
198                len = ARRAY_SIZE(vesa_timings);
199        } else {
200                arr = cea_timings;
201                len = ARRAY_SIZE(cea_timings);
202        }
203
204        return hdmi_find_timing(arr, len);
205 }
206
207 static bool hdmi_timings_compare(struct omap_video_timings *timing1,
208                                 const struct hdmi_video_timings *timing2)
209 {
210         int timing1_vsync, timing1_hsync, timing2_vsync, timing2_hsync;
211
212         if ((timing2->pixel_clock == timing1->pixel_clock) &&
213                 (timing2->x_res == timing1->x_res) &&
214                 (timing2->y_res == timing1->y_res)) {
215
216                 timing2_hsync = timing2->hfp + timing2->hsw + timing2->hbp;
217                 timing1_hsync = timing1->hfp + timing1->hsw + timing1->hbp;
218                 timing2_vsync = timing2->vfp + timing2->vsw + timing2->vbp;
219                 timing1_vsync = timing2->vfp + timing2->vsw + timing2->vbp;
220
221                 DSSDBG("timing1_hsync = %d timing1_vsync = %d"\
222                         "timing2_hsync = %d timing2_vsync = %d\n",
223                         timing1_hsync, timing1_vsync,
224                         timing2_hsync, timing2_vsync);
225
226                 if ((timing1_hsync == timing2_hsync) &&
227                         (timing1_vsync == timing2_vsync)) {
228                         return true;
229                 }
230         }
231         return false;
232 }
233
234 static struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing)
235 {
236         int i;
237         struct hdmi_cm cm = {-1};
238         DSSDBG("hdmi_get_code\n");
239
240         for (i = 0; i < ARRAY_SIZE(cea_timings); i++) {
241                 if (hdmi_timings_compare(timing, &cea_timings[i].timings)) {
242                         cm = cea_timings[i].cm;
243                         goto end;
244                 }
245         }
246         for (i = 0; i < ARRAY_SIZE(vesa_timings); i++) {
247                 if (hdmi_timings_compare(timing, &vesa_timings[i].timings)) {
248                         cm = vesa_timings[i].cm;
249                         goto end;
250                 }
251         }
252
253 end:    return cm;
254
255 }
256
257 unsigned long hdmi_get_pixel_clock(void)
258 {
259         /* HDMI Pixel Clock in Mhz */
260         return hdmi.ip_data.cfg.timings.pixel_clock * 1000;
261 }
262
263 static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy,
264                 struct hdmi_pll_info *pi)
265 {
266         unsigned long clkin, refclk;
267         u32 mf;
268
269         clkin = clk_get_rate(hdmi.sys_clk) / 10000;
270         /*
271          * Input clock is predivided by N + 1
272          * out put of which is reference clk
273          */
274         if (dssdev->clocks.hdmi.regn == 0)
275                 pi->regn = HDMI_DEFAULT_REGN;
276         else
277                 pi->regn = dssdev->clocks.hdmi.regn;
278
279         refclk = clkin / pi->regn;
280
281         if (dssdev->clocks.hdmi.regm2 == 0)
282                 pi->regm2 = HDMI_DEFAULT_REGM2;
283         else
284                 pi->regm2 = dssdev->clocks.hdmi.regm2;
285
286         /*
287          * multiplier is pixel_clk/ref_clk
288          * Multiplying by 100 to avoid fractional part removal
289          */
290         pi->regm = phy * pi->regm2 / refclk;
291
292         /*
293          * fractional multiplier is remainder of the difference between
294          * multiplier and actual phy(required pixel clock thus should be
295          * multiplied by 2^18(262144) divided by the reference clock
296          */
297         mf = (phy - pi->regm / pi->regm2 * refclk) * 262144;
298         pi->regmf = pi->regm2 * mf / refclk;
299
300         /*
301          * Dcofreq should be set to 1 if required pixel clock
302          * is greater than 1000MHz
303          */
304         pi->dcofreq = phy > 1000 * 100;
305         pi->regsd = ((pi->regm * clkin / 10) / (pi->regn * 250) + 5) / 10;
306
307         /* Set the reference clock to sysclk reference */
308         pi->refsel = HDMI_REFSEL_SYSCLK;
309
310         DSSDBG("M = %d Mf = %d\n", pi->regm, pi->regmf);
311         DSSDBG("range = %d sd = %d\n", pi->dcofreq, pi->regsd);
312 }
313
314 static int hdmi_power_on(struct omap_dss_device *dssdev)
315 {
316         int r;
317         const struct hdmi_config *timing;
318         struct omap_video_timings *p;
319         unsigned long phy;
320
321         r = hdmi_runtime_get();
322         if (r)
323                 return r;
324
325         dss_mgr_disable(dssdev->manager);
326
327         p = &dssdev->panel.timings;
328
329         DSSDBG("hdmi_power_on x_res= %d y_res = %d\n",
330                 dssdev->panel.timings.x_res,
331                 dssdev->panel.timings.y_res);
332
333         timing = hdmi_get_timings();
334         if (timing == NULL) {
335                 /* HDMI code 4 corresponds to 640 * 480 VGA */
336                 hdmi.ip_data.cfg.cm.code = 4;
337                 /* DVI mode 1 corresponds to HDMI 0 to DVI */
338                 hdmi.ip_data.cfg.cm.mode = HDMI_DVI;
339                 hdmi.ip_data.cfg = vesa_timings[0];
340         } else {
341                 hdmi.ip_data.cfg = *timing;
342         }
343         phy = p->pixel_clock;
344
345         hdmi_compute_pll(dssdev, phy, &hdmi.ip_data.pll_data);
346
347         hdmi.ip_data.ops->video_enable(&hdmi.ip_data, 0);
348
349         /* config the PLL and PHY hdmi_set_pll_pwrfirst */
350         r = hdmi.ip_data.ops->pll_enable(&hdmi.ip_data);
351         if (r) {
352                 DSSDBG("Failed to lock PLL\n");
353                 goto err;
354         }
355
356         r = hdmi.ip_data.ops->phy_enable(&hdmi.ip_data);
357         if (r) {
358                 DSSDBG("Failed to start PHY\n");
359                 goto err;
360         }
361
362         hdmi.ip_data.ops->video_configure(&hdmi.ip_data);
363
364         /* Make selection of HDMI in DSS */
365         dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK);
366
367         /* Select the dispc clock source as PRCM clock, to ensure that it is not
368          * DSI PLL source as the clock selected by DSI PLL might not be
369          * sufficient for the resolution selected / that can be changed
370          * dynamically by user. This can be moved to single location , say
371          * Boardfile.
372          */
373         dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src);
374
375         /* bypass TV gamma table */
376         dispc_enable_gamma_table(0);
377
378         /* tv size */
379         dispc_set_digit_size(dssdev->panel.timings.x_res,
380                         dssdev->panel.timings.y_res);
381
382         hdmi.ip_data.ops->video_enable(&hdmi.ip_data, 1);
383
384         r = dss_mgr_enable(dssdev->manager);
385         if (r)
386                 goto err_mgr_enable;
387
388         return 0;
389
390 err_mgr_enable:
391         hdmi.ip_data.ops->video_enable(&hdmi.ip_data, 0);
392         hdmi.ip_data.ops->phy_disable(&hdmi.ip_data);
393         hdmi.ip_data.ops->pll_disable(&hdmi.ip_data);
394 err:
395         hdmi_runtime_put();
396         return -EIO;
397 }
398
399 static void hdmi_power_off(struct omap_dss_device *dssdev)
400 {
401         dss_mgr_disable(dssdev->manager);
402
403         hdmi.ip_data.ops->video_enable(&hdmi.ip_data, 0);
404         hdmi.ip_data.ops->phy_disable(&hdmi.ip_data);
405         hdmi.ip_data.ops->pll_disable(&hdmi.ip_data);
406         hdmi_runtime_put();
407 }
408
409 int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
410                                         struct omap_video_timings *timings)
411 {
412         struct hdmi_cm cm;
413
414         cm = hdmi_get_code(timings);
415         if (cm.code == -1) {
416                 return -EINVAL;
417         }
418
419         return 0;
420
421 }
422
423 void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev)
424 {
425         struct hdmi_cm cm;
426
427         cm = hdmi_get_code(&dssdev->panel.timings);
428         hdmi.ip_data.cfg.cm.code = cm.code;
429         hdmi.ip_data.cfg.cm.mode = cm.mode;
430
431         if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
432                 int r;
433
434                 hdmi_power_off(dssdev);
435
436                 r = hdmi_power_on(dssdev);
437                 if (r)
438                         DSSERR("failed to power on device\n");
439         }
440 }
441
442 void hdmi_dump_regs(struct seq_file *s)
443 {
444         mutex_lock(&hdmi.lock);
445
446         if (hdmi_runtime_get())
447                 return;
448
449         hdmi.ip_data.ops->dump_wrapper(&hdmi.ip_data, s);
450         hdmi.ip_data.ops->dump_pll(&hdmi.ip_data, s);
451         hdmi.ip_data.ops->dump_phy(&hdmi.ip_data, s);
452         hdmi.ip_data.ops->dump_core(&hdmi.ip_data, s);
453
454         hdmi_runtime_put();
455         mutex_unlock(&hdmi.lock);
456 }
457
458 int omapdss_hdmi_read_edid(u8 *buf, int len)
459 {
460         int r;
461
462         mutex_lock(&hdmi.lock);
463
464         r = hdmi_runtime_get();
465         BUG_ON(r);
466
467         r = hdmi.ip_data.ops->read_edid(&hdmi.ip_data, buf, len);
468
469         hdmi_runtime_put();
470         mutex_unlock(&hdmi.lock);
471
472         return r;
473 }
474
475 bool omapdss_hdmi_detect(void)
476 {
477         int r;
478
479         mutex_lock(&hdmi.lock);
480
481         r = hdmi_runtime_get();
482         BUG_ON(r);
483
484         r = hdmi.ip_data.ops->detect(&hdmi.ip_data);
485
486         hdmi_runtime_put();
487         mutex_unlock(&hdmi.lock);
488
489         return r == 1;
490 }
491
492 int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
493 {
494         struct omap_dss_hdmi_data *priv = dssdev->data;
495         int r = 0;
496
497         DSSDBG("ENTER hdmi_display_enable\n");
498
499         mutex_lock(&hdmi.lock);
500
501         if (dssdev->manager == NULL) {
502                 DSSERR("failed to enable display: no manager\n");
503                 r = -ENODEV;
504                 goto err0;
505         }
506
507         hdmi.ip_data.hpd_gpio = priv->hpd_gpio;
508
509         r = omap_dss_start_device(dssdev);
510         if (r) {
511                 DSSERR("failed to start device\n");
512                 goto err0;
513         }
514
515         if (dssdev->platform_enable) {
516                 r = dssdev->platform_enable(dssdev);
517                 if (r) {
518                         DSSERR("failed to enable GPIO's\n");
519                         goto err1;
520                 }
521         }
522
523         r = hdmi_power_on(dssdev);
524         if (r) {
525                 DSSERR("failed to power on device\n");
526                 goto err2;
527         }
528
529         mutex_unlock(&hdmi.lock);
530         return 0;
531
532 err2:
533         if (dssdev->platform_disable)
534                 dssdev->platform_disable(dssdev);
535 err1:
536         omap_dss_stop_device(dssdev);
537 err0:
538         mutex_unlock(&hdmi.lock);
539         return r;
540 }
541
542 void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev)
543 {
544         DSSDBG("Enter hdmi_display_disable\n");
545
546         mutex_lock(&hdmi.lock);
547
548         hdmi_power_off(dssdev);
549
550         if (dssdev->platform_disable)
551                 dssdev->platform_disable(dssdev);
552
553         omap_dss_stop_device(dssdev);
554
555         mutex_unlock(&hdmi.lock);
556 }
557
558 #if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
559         defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
560
561 static int hdmi_audio_trigger(struct snd_pcm_substream *substream, int cmd,
562                                 struct snd_soc_dai *dai)
563 {
564         struct snd_soc_pcm_runtime *rtd = substream->private_data;
565         struct snd_soc_codec *codec = rtd->codec;
566         struct platform_device *pdev = to_platform_device(codec->dev);
567         struct hdmi_ip_data *ip_data = snd_soc_codec_get_drvdata(codec);
568         int err = 0;
569
570         if (!(ip_data->ops) && !(ip_data->ops->audio_enable)) {
571                 dev_err(&pdev->dev, "Cannot enable/disable audio\n");
572                 return -ENODEV;
573         }
574
575         switch (cmd) {
576         case SNDRV_PCM_TRIGGER_START:
577         case SNDRV_PCM_TRIGGER_RESUME:
578         case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
579                 ip_data->ops->audio_enable(ip_data, true);
580                 break;
581         case SNDRV_PCM_TRIGGER_STOP:
582         case SNDRV_PCM_TRIGGER_SUSPEND:
583         case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
584                 ip_data->ops->audio_enable(ip_data, false);
585                 break;
586         default:
587                 err = -EINVAL;
588         }
589         return err;
590 }
591
592 static int hdmi_audio_hw_params(struct snd_pcm_substream *substream,
593                                     struct snd_pcm_hw_params *params,
594                                     struct snd_soc_dai *dai)
595 {
596         struct snd_soc_pcm_runtime *rtd = substream->private_data;
597         struct snd_soc_codec *codec = rtd->codec;
598         struct hdmi_ip_data *ip_data = snd_soc_codec_get_drvdata(codec);
599         struct hdmi_audio_format audio_format;
600         struct hdmi_audio_dma audio_dma;
601         struct hdmi_core_audio_config core_cfg;
602         struct hdmi_core_infoframe_audio aud_if_cfg;
603         int err, n, cts;
604         enum hdmi_core_audio_sample_freq sample_freq;
605
606         switch (params_format(params)) {
607         case SNDRV_PCM_FORMAT_S16_LE:
608                 core_cfg.i2s_cfg.word_max_length =
609                         HDMI_AUDIO_I2S_MAX_WORD_20BITS;
610                 core_cfg.i2s_cfg.word_length = HDMI_AUDIO_I2S_CHST_WORD_16_BITS;
611                 core_cfg.i2s_cfg.in_length_bits =
612                         HDMI_AUDIO_I2S_INPUT_LENGTH_16;
613                 core_cfg.i2s_cfg.justification = HDMI_AUDIO_JUSTIFY_LEFT;
614                 audio_format.samples_per_word = HDMI_AUDIO_ONEWORD_TWOSAMPLES;
615                 audio_format.sample_size = HDMI_AUDIO_SAMPLE_16BITS;
616                 audio_format.justification = HDMI_AUDIO_JUSTIFY_LEFT;
617                 audio_dma.transfer_size = 0x10;
618                 break;
619         case SNDRV_PCM_FORMAT_S24_LE:
620                 core_cfg.i2s_cfg.word_max_length =
621                         HDMI_AUDIO_I2S_MAX_WORD_24BITS;
622                 core_cfg.i2s_cfg.word_length = HDMI_AUDIO_I2S_CHST_WORD_24_BITS;
623                 core_cfg.i2s_cfg.in_length_bits =
624                         HDMI_AUDIO_I2S_INPUT_LENGTH_24;
625                 audio_format.samples_per_word = HDMI_AUDIO_ONEWORD_ONESAMPLE;
626                 audio_format.sample_size = HDMI_AUDIO_SAMPLE_24BITS;
627                 audio_format.justification = HDMI_AUDIO_JUSTIFY_RIGHT;
628                 core_cfg.i2s_cfg.justification = HDMI_AUDIO_JUSTIFY_RIGHT;
629                 audio_dma.transfer_size = 0x20;
630                 break;
631         default:
632                 return -EINVAL;
633         }
634
635         switch (params_rate(params)) {
636         case 32000:
637                 sample_freq = HDMI_AUDIO_FS_32000;
638                 break;
639         case 44100:
640                 sample_freq = HDMI_AUDIO_FS_44100;
641                 break;
642         case 48000:
643                 sample_freq = HDMI_AUDIO_FS_48000;
644                 break;
645         default:
646                 return -EINVAL;
647         }
648
649         err = hdmi_config_audio_acr(ip_data, params_rate(params), &n, &cts);
650         if (err < 0)
651                 return err;
652
653         /* Audio wrapper config */
654         audio_format.stereo_channels = HDMI_AUDIO_STEREO_ONECHANNEL;
655         audio_format.active_chnnls_msk = 0x03;
656         audio_format.type = HDMI_AUDIO_TYPE_LPCM;
657         audio_format.sample_order = HDMI_AUDIO_SAMPLE_LEFT_FIRST;
658         /* Disable start/stop signals of IEC 60958 blocks */
659         audio_format.en_sig_blk_strt_end = HDMI_AUDIO_BLOCK_SIG_STARTEND_OFF;
660
661         audio_dma.block_size = 0xC0;
662         audio_dma.mode = HDMI_AUDIO_TRANSF_DMA;
663         audio_dma.fifo_threshold = 0x20; /* in number of samples */
664
665         hdmi_wp_audio_config_dma(ip_data, &audio_dma);
666         hdmi_wp_audio_config_format(ip_data, &audio_format);
667
668         /*
669          * I2S config
670          */
671         core_cfg.i2s_cfg.en_high_bitrate_aud = false;
672         /* Only used with high bitrate audio */
673         core_cfg.i2s_cfg.cbit_order = false;
674         /* Serial data and word select should change on sck rising edge */
675         core_cfg.i2s_cfg.sck_edge_mode = HDMI_AUDIO_I2S_SCK_EDGE_RISING;
676         core_cfg.i2s_cfg.vbit = HDMI_AUDIO_I2S_VBIT_FOR_PCM;
677         /* Set I2S word select polarity */
678         core_cfg.i2s_cfg.ws_polarity = HDMI_AUDIO_I2S_WS_POLARITY_LOW_IS_LEFT;
679         core_cfg.i2s_cfg.direction = HDMI_AUDIO_I2S_MSB_SHIFTED_FIRST;
680         /* Set serial data to word select shift. See Phillips spec. */
681         core_cfg.i2s_cfg.shift = HDMI_AUDIO_I2S_FIRST_BIT_SHIFT;
682         /* Enable one of the four available serial data channels */
683         core_cfg.i2s_cfg.active_sds = HDMI_AUDIO_I2S_SD0_EN;
684
685         /* Core audio config */
686         core_cfg.freq_sample = sample_freq;
687         core_cfg.n = n;
688         core_cfg.cts = cts;
689         if (dss_has_feature(FEAT_HDMI_CTS_SWMODE)) {
690                 core_cfg.aud_par_busclk = 0;
691                 core_cfg.cts_mode = HDMI_AUDIO_CTS_MODE_SW;
692                 core_cfg.use_mclk = dss_has_feature(FEAT_HDMI_AUDIO_USE_MCLK);
693         } else {
694                 core_cfg.aud_par_busclk = (((128 * 31) - 1) << 8);
695                 core_cfg.cts_mode = HDMI_AUDIO_CTS_MODE_HW;
696                 core_cfg.use_mclk = true;
697         }
698
699         if (core_cfg.use_mclk)
700                 core_cfg.mclk_mode = HDMI_AUDIO_MCLK_128FS;
701         core_cfg.layout = HDMI_AUDIO_LAYOUT_2CH;
702         core_cfg.en_spdif = false;
703         /* Use sample frequency from channel status word */
704         core_cfg.fs_override = true;
705         /* Enable ACR packets */
706         core_cfg.en_acr_pkt = true;
707         /* Disable direct streaming digital audio */
708         core_cfg.en_dsd_audio = false;
709         /* Use parallel audio interface */
710         core_cfg.en_parallel_aud_input = true;
711
712         hdmi_core_audio_config(ip_data, &core_cfg);
713
714         /*
715          * Configure packet
716          * info frame audio see doc CEA861-D page 74
717          */
718         aud_if_cfg.db1_coding_type = HDMI_INFOFRAME_AUDIO_DB1CT_FROM_STREAM;
719         aud_if_cfg.db1_channel_count = 2;
720         aud_if_cfg.db2_sample_freq = HDMI_INFOFRAME_AUDIO_DB2SF_FROM_STREAM;
721         aud_if_cfg.db2_sample_size = HDMI_INFOFRAME_AUDIO_DB2SS_FROM_STREAM;
722         aud_if_cfg.db4_channel_alloc = 0x00;
723         aud_if_cfg.db5_downmix_inh = false;
724         aud_if_cfg.db5_lsv = 0;
725
726         hdmi_core_audio_infoframe_config(ip_data, &aud_if_cfg);
727         return 0;
728 }
729
730 static int hdmi_audio_startup(struct snd_pcm_substream *substream,
731                                   struct snd_soc_dai *dai)
732 {
733         if (!hdmi.ip_data.cfg.cm.mode) {
734                 pr_err("Current video settings do not support audio.\n");
735                 return -EIO;
736         }
737         return 0;
738 }
739
740 static int hdmi_audio_codec_probe(struct snd_soc_codec *codec)
741 {
742         struct hdmi_ip_data *priv = &hdmi.ip_data;
743
744         snd_soc_codec_set_drvdata(codec, priv);
745         return 0;
746 }
747
748 static struct snd_soc_codec_driver hdmi_audio_codec_drv = {
749         .probe = hdmi_audio_codec_probe,
750 };
751
752 static struct snd_soc_dai_ops hdmi_audio_codec_ops = {
753         .hw_params = hdmi_audio_hw_params,
754         .trigger = hdmi_audio_trigger,
755         .startup = hdmi_audio_startup,
756 };
757
758 static struct snd_soc_dai_driver hdmi_codec_dai_drv = {
759                 .name = "hdmi-audio-codec",
760                 .playback = {
761                         .channels_min = 2,
762                         .channels_max = 2,
763                         .rates = SNDRV_PCM_RATE_32000 |
764                                 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
765                         .formats = SNDRV_PCM_FMTBIT_S16_LE |
766                                 SNDRV_PCM_FMTBIT_S24_LE,
767                 },
768                 .ops = &hdmi_audio_codec_ops,
769 };
770 #endif
771
772 static int hdmi_get_clocks(struct platform_device *pdev)
773 {
774         struct clk *clk;
775
776         clk = clk_get(&pdev->dev, "sys_clk");
777         if (IS_ERR(clk)) {
778                 DSSERR("can't get sys_clk\n");
779                 return PTR_ERR(clk);
780         }
781
782         hdmi.sys_clk = clk;
783
784         return 0;
785 }
786
787 static void hdmi_put_clocks(void)
788 {
789         if (hdmi.sys_clk)
790                 clk_put(hdmi.sys_clk);
791 }
792
793 /* HDMI HW IP initialisation */
794 static int omapdss_hdmihw_probe(struct platform_device *pdev)
795 {
796         struct resource *hdmi_mem;
797         int r;
798
799         hdmi.pdata = pdev->dev.platform_data;
800         hdmi.pdev = pdev;
801
802         mutex_init(&hdmi.lock);
803
804         hdmi_mem = platform_get_resource(hdmi.pdev, IORESOURCE_MEM, 0);
805         if (!hdmi_mem) {
806                 DSSERR("can't get IORESOURCE_MEM HDMI\n");
807                 return -EINVAL;
808         }
809
810         /* Base address taken from platform */
811         hdmi.ip_data.base_wp = ioremap(hdmi_mem->start,
812                                                 resource_size(hdmi_mem));
813         if (!hdmi.ip_data.base_wp) {
814                 DSSERR("can't ioremap WP\n");
815                 return -ENOMEM;
816         }
817
818         r = hdmi_get_clocks(pdev);
819         if (r) {
820                 iounmap(hdmi.ip_data.base_wp);
821                 return r;
822         }
823
824         pm_runtime_enable(&pdev->dev);
825
826         hdmi.ip_data.core_sys_offset = HDMI_CORE_SYS;
827         hdmi.ip_data.core_av_offset = HDMI_CORE_AV;
828         hdmi.ip_data.pll_offset = HDMI_PLLCTRL;
829         hdmi.ip_data.phy_offset = HDMI_PHY;
830
831         hdmi_panel_init();
832
833 #if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
834         defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
835
836         /* Register ASoC codec DAI */
837         r = snd_soc_register_codec(&pdev->dev, &hdmi_audio_codec_drv,
838                                         &hdmi_codec_dai_drv, 1);
839         if (r) {
840                 DSSERR("can't register ASoC HDMI audio codec\n");
841                 return r;
842         }
843 #endif
844         return 0;
845 }
846
847 static int omapdss_hdmihw_remove(struct platform_device *pdev)
848 {
849         hdmi_panel_exit();
850
851 #if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
852         defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
853         snd_soc_unregister_codec(&pdev->dev);
854 #endif
855
856         pm_runtime_disable(&pdev->dev);
857
858         hdmi_put_clocks();
859
860         iounmap(hdmi.ip_data.base_wp);
861
862         return 0;
863 }
864
865 static int hdmi_runtime_suspend(struct device *dev)
866 {
867         clk_disable(hdmi.sys_clk);
868
869         dispc_runtime_put();
870         dss_runtime_put();
871
872         return 0;
873 }
874
875 static int hdmi_runtime_resume(struct device *dev)
876 {
877         int r;
878
879         r = dss_runtime_get();
880         if (r < 0)
881                 goto err_get_dss;
882
883         r = dispc_runtime_get();
884         if (r < 0)
885                 goto err_get_dispc;
886
887
888         clk_enable(hdmi.sys_clk);
889
890         return 0;
891
892 err_get_dispc:
893         dss_runtime_put();
894 err_get_dss:
895         return r;
896 }
897
898 static const struct dev_pm_ops hdmi_pm_ops = {
899         .runtime_suspend = hdmi_runtime_suspend,
900         .runtime_resume = hdmi_runtime_resume,
901 };
902
903 static struct platform_driver omapdss_hdmihw_driver = {
904         .probe          = omapdss_hdmihw_probe,
905         .remove         = omapdss_hdmihw_remove,
906         .driver         = {
907                 .name   = "omapdss_hdmi",
908                 .owner  = THIS_MODULE,
909                 .pm     = &hdmi_pm_ops,
910         },
911 };
912
913 int hdmi_init_platform_driver(void)
914 {
915         return platform_driver_register(&omapdss_hdmihw_driver);
916 }
917
918 void hdmi_uninit_platform_driver(void)
919 {
920         return platform_driver_unregister(&omapdss_hdmihw_driver);
921 }