]> Pileus Git - ~andy/linux/blob - drivers/video/omap2/dss/hdmi.c
Merge tag 'fbdev-updates-for-3.6' of git://github.com/schandinat/linux-2.6
[~andy/linux] / 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
37 #include "ti_hdmi.h"
38 #include "dss.h"
39 #include "dss_features.h"
40
41 #define HDMI_WP                 0x0
42 #define HDMI_CORE_SYS           0x400
43 #define HDMI_CORE_AV            0x900
44 #define HDMI_PLLCTRL            0x200
45 #define HDMI_PHY                0x300
46
47 /* HDMI EDID Length move this */
48 #define HDMI_EDID_MAX_LENGTH                    256
49 #define EDID_TIMING_DESCRIPTOR_SIZE             0x12
50 #define EDID_DESCRIPTOR_BLOCK0_ADDRESS          0x36
51 #define EDID_DESCRIPTOR_BLOCK1_ADDRESS          0x80
52 #define EDID_SIZE_BLOCK0_TIMING_DESCRIPTOR      4
53 #define EDID_SIZE_BLOCK1_TIMING_DESCRIPTOR      4
54
55 #define HDMI_DEFAULT_REGN 16
56 #define HDMI_DEFAULT_REGM2 1
57
58 static struct {
59         struct mutex lock;
60         struct platform_device *pdev;
61         struct hdmi_ip_data ip_data;
62
63         struct clk *sys_clk;
64 } hdmi;
65
66 /*
67  * Logic for the below structure :
68  * user enters the CEA or VESA timings by specifying the HDMI/DVI code.
69  * There is a correspondence between CEA/VESA timing and code, please
70  * refer to section 6.3 in HDMI 1.3 specification for timing code.
71  *
72  * In the below structure, cea_vesa_timings corresponds to all OMAP4
73  * supported CEA and VESA timing values.code_cea corresponds to the CEA
74  * code, It is used to get the timing from cea_vesa_timing array.Similarly
75  * with code_vesa. Code_index is used for back mapping, that is once EDID
76  * is read from the TV, EDID is parsed to find the timing values and then
77  * map it to corresponding CEA or VESA index.
78  */
79
80 static const struct hdmi_config cea_timings[] = {
81         {
82                 { 640, 480, 25200, 96, 16, 48, 2, 10, 33,
83                         OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
84                         false, },
85                 { 1, HDMI_HDMI },
86         },
87         {
88                 { 720, 480, 27027, 62, 16, 60, 6, 9, 30,
89                         OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
90                         false, },
91                 { 2, HDMI_HDMI },
92         },
93         {
94                 { 1280, 720, 74250, 40, 110, 220, 5, 5, 20,
95                         OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
96                         false, },
97                 { 4, HDMI_HDMI },
98         },
99         {
100                 { 1920, 540, 74250, 44, 88, 148, 5, 2, 15,
101                         OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
102                         true, },
103                 { 5, HDMI_HDMI },
104         },
105         {
106                 { 1440, 240, 27027, 124, 38, 114, 3, 4, 15,
107                         OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
108                         true, },
109                 { 6, HDMI_HDMI },
110         },
111         {
112                 { 1920, 1080, 148500, 44, 88, 148, 5, 4, 36,
113                         OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
114                         false, },
115                 { 16, HDMI_HDMI },
116         },
117         {
118                 { 720, 576, 27000, 64, 12, 68, 5, 5, 39,
119                         OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
120                         false, },
121                 { 17, HDMI_HDMI },
122         },
123         {
124                 { 1280, 720, 74250, 40, 440, 220, 5, 5, 20,
125                         OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
126                         false, },
127                 { 19, HDMI_HDMI },
128         },
129         {
130                 { 1920, 540, 74250, 44, 528, 148, 5, 2, 15,
131                         OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
132                         true, },
133                 { 20, HDMI_HDMI },
134         },
135         {
136                 { 1440, 288, 27000, 126, 24, 138, 3, 2, 19,
137                         OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
138                         true, },
139                 { 21, HDMI_HDMI },
140         },
141         {
142                 { 1440, 576, 54000, 128, 24, 136, 5, 5, 39,
143                         OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
144                         false, },
145                 { 29, HDMI_HDMI },
146         },
147         {
148                 { 1920, 1080, 148500, 44, 528, 148, 5, 4, 36,
149                         OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
150                         false, },
151                 { 31, HDMI_HDMI },
152         },
153         {
154                 { 1920, 1080, 74250, 44, 638, 148, 5, 4, 36,
155                         OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
156                         false, },
157                 { 32, HDMI_HDMI },
158         },
159         {
160                 { 2880, 480, 108108, 248, 64, 240, 6, 9, 30,
161                         OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
162                         false, },
163                 { 35, HDMI_HDMI },
164         },
165         {
166                 { 2880, 576, 108000, 256, 48, 272, 5, 5, 39,
167                         OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
168                         false, },
169                 { 37, HDMI_HDMI },
170         },
171 };
172
173 static const struct hdmi_config vesa_timings[] = {
174 /* VESA From Here */
175         {
176                 { 640, 480, 25175, 96, 16, 48, 2, 11, 31,
177                         OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
178                         false, },
179                 { 4, HDMI_DVI },
180         },
181         {
182                 { 800, 600, 40000, 128, 40, 88, 4, 1, 23,
183                         OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
184                         false, },
185                 { 9, HDMI_DVI },
186         },
187         {
188                 { 848, 480, 33750, 112, 16, 112, 8, 6, 23,
189                         OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
190                         false, },
191                 { 0xE, HDMI_DVI },
192         },
193         {
194                 { 1280, 768, 79500, 128, 64, 192, 7, 3, 20,
195                         OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
196                         false, },
197                 { 0x17, HDMI_DVI },
198         },
199         {
200                 { 1280, 800, 83500, 128, 72, 200, 6, 3, 22,
201                         OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
202                         false, },
203                 { 0x1C, HDMI_DVI },
204         },
205         {
206                 { 1360, 768, 85500, 112, 64, 256, 6, 3, 18,
207                         OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
208                         false, },
209                 { 0x27, HDMI_DVI },
210         },
211         {
212                 { 1280, 960, 108000, 112, 96, 312, 3, 1, 36,
213                         OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
214                         false, },
215                 { 0x20, HDMI_DVI },
216         },
217         {
218                 { 1280, 1024, 108000, 112, 48, 248, 3, 1, 38,
219                         OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
220                         false, },
221                 { 0x23, HDMI_DVI },
222         },
223         {
224                 { 1024, 768, 65000, 136, 24, 160, 6, 3, 29,
225                         OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
226                         false, },
227                 { 0x10, HDMI_DVI },
228         },
229         {
230                 { 1400, 1050, 121750, 144, 88, 232, 4, 3, 32,
231                         OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
232                         false, },
233                 { 0x2A, HDMI_DVI },
234         },
235         {
236                 { 1440, 900, 106500, 152, 80, 232, 6, 3, 25,
237                         OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
238                         false, },
239                 { 0x2F, HDMI_DVI },
240         },
241         {
242                 { 1680, 1050, 146250, 176 , 104, 280, 6, 3, 30,
243                         OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
244                         false, },
245                 { 0x3A, HDMI_DVI },
246         },
247         {
248                 { 1366, 768, 85500, 143, 70, 213, 3, 3, 24,
249                         OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
250                         false, },
251                 { 0x51, HDMI_DVI },
252         },
253         {
254                 { 1920, 1080, 148500, 44, 148, 80, 5, 4, 36,
255                         OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
256                         false, },
257                 { 0x52, HDMI_DVI },
258         },
259         {
260                 { 1280, 768, 68250, 32, 48, 80, 7, 3, 12,
261                         OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
262                         false, },
263                 { 0x16, HDMI_DVI },
264         },
265         {
266                 { 1400, 1050, 101000, 32, 48, 80, 4, 3, 23,
267                         OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
268                         false, },
269                 { 0x29, HDMI_DVI },
270         },
271         {
272                 { 1680, 1050, 119000, 32, 48, 80, 6, 3, 21,
273                         OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
274                         false, },
275                 { 0x39, HDMI_DVI },
276         },
277         {
278                 { 1280, 800, 79500, 32, 48, 80, 6, 3, 14,
279                         OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
280                         false, },
281                 { 0x1B, HDMI_DVI },
282         },
283         {
284                 { 1280, 720, 74250, 40, 110, 220, 5, 5, 20,
285                         OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
286                         false, },
287                 { 0x55, HDMI_DVI },
288         },
289 };
290
291 static int hdmi_runtime_get(void)
292 {
293         int r;
294
295         DSSDBG("hdmi_runtime_get\n");
296
297         r = pm_runtime_get_sync(&hdmi.pdev->dev);
298         WARN_ON(r < 0);
299         if (r < 0)
300                 return r;
301
302         return 0;
303 }
304
305 static void hdmi_runtime_put(void)
306 {
307         int r;
308
309         DSSDBG("hdmi_runtime_put\n");
310
311         r = pm_runtime_put_sync(&hdmi.pdev->dev);
312         WARN_ON(r < 0 && r != -ENOSYS);
313 }
314
315 static int __init hdmi_init_display(struct omap_dss_device *dssdev)
316 {
317         DSSDBG("init_display\n");
318
319         dss_init_hdmi_ip_ops(&hdmi.ip_data);
320         return 0;
321 }
322
323 static const struct hdmi_config *hdmi_find_timing(
324                                         const struct hdmi_config *timings_arr,
325                                         int len)
326 {
327         int i;
328
329         for (i = 0; i < len; i++) {
330                 if (timings_arr[i].cm.code == hdmi.ip_data.cfg.cm.code)
331                         return &timings_arr[i];
332         }
333         return NULL;
334 }
335
336 static const struct hdmi_config *hdmi_get_timings(void)
337 {
338        const struct hdmi_config *arr;
339        int len;
340
341        if (hdmi.ip_data.cfg.cm.mode == HDMI_DVI) {
342                arr = vesa_timings;
343                len = ARRAY_SIZE(vesa_timings);
344        } else {
345                arr = cea_timings;
346                len = ARRAY_SIZE(cea_timings);
347        }
348
349        return hdmi_find_timing(arr, len);
350 }
351
352 static bool hdmi_timings_compare(struct omap_video_timings *timing1,
353                                 const struct omap_video_timings *timing2)
354 {
355         int timing1_vsync, timing1_hsync, timing2_vsync, timing2_hsync;
356
357         if ((timing2->pixel_clock == timing1->pixel_clock) &&
358                 (timing2->x_res == timing1->x_res) &&
359                 (timing2->y_res == timing1->y_res)) {
360
361                 timing2_hsync = timing2->hfp + timing2->hsw + timing2->hbp;
362                 timing1_hsync = timing1->hfp + timing1->hsw + timing1->hbp;
363                 timing2_vsync = timing2->vfp + timing2->vsw + timing2->vbp;
364                 timing1_vsync = timing2->vfp + timing2->vsw + timing2->vbp;
365
366                 DSSDBG("timing1_hsync = %d timing1_vsync = %d"\
367                         "timing2_hsync = %d timing2_vsync = %d\n",
368                         timing1_hsync, timing1_vsync,
369                         timing2_hsync, timing2_vsync);
370
371                 if ((timing1_hsync == timing2_hsync) &&
372                         (timing1_vsync == timing2_vsync)) {
373                         return true;
374                 }
375         }
376         return false;
377 }
378
379 static struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing)
380 {
381         int i;
382         struct hdmi_cm cm = {-1};
383         DSSDBG("hdmi_get_code\n");
384
385         for (i = 0; i < ARRAY_SIZE(cea_timings); i++) {
386                 if (hdmi_timings_compare(timing, &cea_timings[i].timings)) {
387                         cm = cea_timings[i].cm;
388                         goto end;
389                 }
390         }
391         for (i = 0; i < ARRAY_SIZE(vesa_timings); i++) {
392                 if (hdmi_timings_compare(timing, &vesa_timings[i].timings)) {
393                         cm = vesa_timings[i].cm;
394                         goto end;
395                 }
396         }
397
398 end:    return cm;
399
400 }
401
402 unsigned long hdmi_get_pixel_clock(void)
403 {
404         /* HDMI Pixel Clock in Mhz */
405         return hdmi.ip_data.cfg.timings.pixel_clock * 1000;
406 }
407
408 static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy,
409                 struct hdmi_pll_info *pi)
410 {
411         unsigned long clkin, refclk;
412         u32 mf;
413
414         clkin = clk_get_rate(hdmi.sys_clk) / 10000;
415         /*
416          * Input clock is predivided by N + 1
417          * out put of which is reference clk
418          */
419         if (dssdev->clocks.hdmi.regn == 0)
420                 pi->regn = HDMI_DEFAULT_REGN;
421         else
422                 pi->regn = dssdev->clocks.hdmi.regn;
423
424         refclk = clkin / pi->regn;
425
426         if (dssdev->clocks.hdmi.regm2 == 0)
427                 pi->regm2 = HDMI_DEFAULT_REGM2;
428         else
429                 pi->regm2 = dssdev->clocks.hdmi.regm2;
430
431         /*
432          * multiplier is pixel_clk/ref_clk
433          * Multiplying by 100 to avoid fractional part removal
434          */
435         pi->regm = phy * pi->regm2 / refclk;
436
437         /*
438          * fractional multiplier is remainder of the difference between
439          * multiplier and actual phy(required pixel clock thus should be
440          * multiplied by 2^18(262144) divided by the reference clock
441          */
442         mf = (phy - pi->regm / pi->regm2 * refclk) * 262144;
443         pi->regmf = pi->regm2 * mf / refclk;
444
445         /*
446          * Dcofreq should be set to 1 if required pixel clock
447          * is greater than 1000MHz
448          */
449         pi->dcofreq = phy > 1000 * 100;
450         pi->regsd = ((pi->regm * clkin / 10) / (pi->regn * 250) + 5) / 10;
451
452         /* Set the reference clock to sysclk reference */
453         pi->refsel = HDMI_REFSEL_SYSCLK;
454
455         DSSDBG("M = %d Mf = %d\n", pi->regm, pi->regmf);
456         DSSDBG("range = %d sd = %d\n", pi->dcofreq, pi->regsd);
457 }
458
459 static int hdmi_power_on(struct omap_dss_device *dssdev)
460 {
461         int r;
462         const struct hdmi_config *timing;
463         struct omap_video_timings *p;
464         unsigned long phy;
465
466         r = hdmi_runtime_get();
467         if (r)
468                 return r;
469
470         dss_mgr_disable(dssdev->manager);
471
472         p = &dssdev->panel.timings;
473
474         DSSDBG("hdmi_power_on x_res= %d y_res = %d\n",
475                 dssdev->panel.timings.x_res,
476                 dssdev->panel.timings.y_res);
477
478         timing = hdmi_get_timings();
479         if (timing == NULL) {
480                 /* HDMI code 4 corresponds to 640 * 480 VGA */
481                 hdmi.ip_data.cfg.cm.code = 4;
482                 /* DVI mode 1 corresponds to HDMI 0 to DVI */
483                 hdmi.ip_data.cfg.cm.mode = HDMI_DVI;
484                 hdmi.ip_data.cfg = vesa_timings[0];
485         } else {
486                 hdmi.ip_data.cfg = *timing;
487         }
488         phy = p->pixel_clock;
489
490         hdmi_compute_pll(dssdev, phy, &hdmi.ip_data.pll_data);
491
492         hdmi.ip_data.ops->video_disable(&hdmi.ip_data);
493
494         /* config the PLL and PHY hdmi_set_pll_pwrfirst */
495         r = hdmi.ip_data.ops->pll_enable(&hdmi.ip_data);
496         if (r) {
497                 DSSDBG("Failed to lock PLL\n");
498                 goto err;
499         }
500
501         r = hdmi.ip_data.ops->phy_enable(&hdmi.ip_data);
502         if (r) {
503                 DSSDBG("Failed to start PHY\n");
504                 goto err;
505         }
506
507         hdmi.ip_data.ops->video_configure(&hdmi.ip_data);
508
509         /* Make selection of HDMI in DSS */
510         dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK);
511
512         /* Select the dispc clock source as PRCM clock, to ensure that it is not
513          * DSI PLL source as the clock selected by DSI PLL might not be
514          * sufficient for the resolution selected / that can be changed
515          * dynamically by user. This can be moved to single location , say
516          * Boardfile.
517          */
518         dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src);
519
520         /* bypass TV gamma table */
521         dispc_enable_gamma_table(0);
522
523         /* tv size */
524         dss_mgr_set_timings(dssdev->manager, &dssdev->panel.timings);
525
526         r = hdmi.ip_data.ops->video_enable(&hdmi.ip_data);
527         if (r)
528                 goto err_vid_enable;
529
530         r = dss_mgr_enable(dssdev->manager);
531         if (r)
532                 goto err_mgr_enable;
533
534         return 0;
535
536 err_mgr_enable:
537         hdmi.ip_data.ops->video_disable(&hdmi.ip_data);
538 err_vid_enable:
539         hdmi.ip_data.ops->phy_disable(&hdmi.ip_data);
540         hdmi.ip_data.ops->pll_disable(&hdmi.ip_data);
541 err:
542         hdmi_runtime_put();
543         return -EIO;
544 }
545
546 static void hdmi_power_off(struct omap_dss_device *dssdev)
547 {
548         dss_mgr_disable(dssdev->manager);
549
550         hdmi.ip_data.ops->video_disable(&hdmi.ip_data);
551         hdmi.ip_data.ops->phy_disable(&hdmi.ip_data);
552         hdmi.ip_data.ops->pll_disable(&hdmi.ip_data);
553         hdmi_runtime_put();
554 }
555
556 int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
557                                         struct omap_video_timings *timings)
558 {
559         struct hdmi_cm cm;
560
561         cm = hdmi_get_code(timings);
562         if (cm.code == -1) {
563                 return -EINVAL;
564         }
565
566         return 0;
567
568 }
569
570 void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev)
571 {
572         struct hdmi_cm cm;
573
574         cm = hdmi_get_code(&dssdev->panel.timings);
575         hdmi.ip_data.cfg.cm.code = cm.code;
576         hdmi.ip_data.cfg.cm.mode = cm.mode;
577
578         if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
579                 int r;
580
581                 hdmi_power_off(dssdev);
582
583                 r = hdmi_power_on(dssdev);
584                 if (r)
585                         DSSERR("failed to power on device\n");
586         } else {
587                 dss_mgr_set_timings(dssdev->manager, &dssdev->panel.timings);
588         }
589 }
590
591 static void hdmi_dump_regs(struct seq_file *s)
592 {
593         mutex_lock(&hdmi.lock);
594
595         if (hdmi_runtime_get())
596                 return;
597
598         hdmi.ip_data.ops->dump_wrapper(&hdmi.ip_data, s);
599         hdmi.ip_data.ops->dump_pll(&hdmi.ip_data, s);
600         hdmi.ip_data.ops->dump_phy(&hdmi.ip_data, s);
601         hdmi.ip_data.ops->dump_core(&hdmi.ip_data, s);
602
603         hdmi_runtime_put();
604         mutex_unlock(&hdmi.lock);
605 }
606
607 int omapdss_hdmi_read_edid(u8 *buf, int len)
608 {
609         int r;
610
611         mutex_lock(&hdmi.lock);
612
613         r = hdmi_runtime_get();
614         BUG_ON(r);
615
616         r = hdmi.ip_data.ops->read_edid(&hdmi.ip_data, buf, len);
617
618         hdmi_runtime_put();
619         mutex_unlock(&hdmi.lock);
620
621         return r;
622 }
623
624 bool omapdss_hdmi_detect(void)
625 {
626         int r;
627
628         mutex_lock(&hdmi.lock);
629
630         r = hdmi_runtime_get();
631         BUG_ON(r);
632
633         r = hdmi.ip_data.ops->detect(&hdmi.ip_data);
634
635         hdmi_runtime_put();
636         mutex_unlock(&hdmi.lock);
637
638         return r == 1;
639 }
640
641 int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
642 {
643         struct omap_dss_hdmi_data *priv = dssdev->data;
644         int r = 0;
645
646         DSSDBG("ENTER hdmi_display_enable\n");
647
648         mutex_lock(&hdmi.lock);
649
650         if (dssdev->manager == NULL) {
651                 DSSERR("failed to enable display: no manager\n");
652                 r = -ENODEV;
653                 goto err0;
654         }
655
656         hdmi.ip_data.hpd_gpio = priv->hpd_gpio;
657
658         r = omap_dss_start_device(dssdev);
659         if (r) {
660                 DSSERR("failed to start device\n");
661                 goto err0;
662         }
663
664         if (dssdev->platform_enable) {
665                 r = dssdev->platform_enable(dssdev);
666                 if (r) {
667                         DSSERR("failed to enable GPIO's\n");
668                         goto err1;
669                 }
670         }
671
672         r = hdmi_power_on(dssdev);
673         if (r) {
674                 DSSERR("failed to power on device\n");
675                 goto err2;
676         }
677
678         mutex_unlock(&hdmi.lock);
679         return 0;
680
681 err2:
682         if (dssdev->platform_disable)
683                 dssdev->platform_disable(dssdev);
684 err1:
685         omap_dss_stop_device(dssdev);
686 err0:
687         mutex_unlock(&hdmi.lock);
688         return r;
689 }
690
691 void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev)
692 {
693         DSSDBG("Enter hdmi_display_disable\n");
694
695         mutex_lock(&hdmi.lock);
696
697         hdmi_power_off(dssdev);
698
699         if (dssdev->platform_disable)
700                 dssdev->platform_disable(dssdev);
701
702         omap_dss_stop_device(dssdev);
703
704         mutex_unlock(&hdmi.lock);
705 }
706
707 static int hdmi_get_clocks(struct platform_device *pdev)
708 {
709         struct clk *clk;
710
711         clk = clk_get(&pdev->dev, "sys_clk");
712         if (IS_ERR(clk)) {
713                 DSSERR("can't get sys_clk\n");
714                 return PTR_ERR(clk);
715         }
716
717         hdmi.sys_clk = clk;
718
719         return 0;
720 }
721
722 static void hdmi_put_clocks(void)
723 {
724         if (hdmi.sys_clk)
725                 clk_put(hdmi.sys_clk);
726 }
727
728 #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO)
729 int hdmi_compute_acr(u32 sample_freq, u32 *n, u32 *cts)
730 {
731         u32 deep_color;
732         bool deep_color_correct = false;
733         u32 pclk = hdmi.ip_data.cfg.timings.pixel_clock;
734
735         if (n == NULL || cts == NULL)
736                 return -EINVAL;
737
738         /* TODO: When implemented, query deep color mode here. */
739         deep_color = 100;
740
741         /*
742          * When using deep color, the default N value (as in the HDMI
743          * specification) yields to an non-integer CTS. Hence, we
744          * modify it while keeping the restrictions described in
745          * section 7.2.1 of the HDMI 1.4a specification.
746          */
747         switch (sample_freq) {
748         case 32000:
749         case 48000:
750         case 96000:
751         case 192000:
752                 if (deep_color == 125)
753                         if (pclk == 27027 || pclk == 74250)
754                                 deep_color_correct = true;
755                 if (deep_color == 150)
756                         if (pclk == 27027)
757                                 deep_color_correct = true;
758                 break;
759         case 44100:
760         case 88200:
761         case 176400:
762                 if (deep_color == 125)
763                         if (pclk == 27027)
764                                 deep_color_correct = true;
765                 break;
766         default:
767                 return -EINVAL;
768         }
769
770         if (deep_color_correct) {
771                 switch (sample_freq) {
772                 case 32000:
773                         *n = 8192;
774                         break;
775                 case 44100:
776                         *n = 12544;
777                         break;
778                 case 48000:
779                         *n = 8192;
780                         break;
781                 case 88200:
782                         *n = 25088;
783                         break;
784                 case 96000:
785                         *n = 16384;
786                         break;
787                 case 176400:
788                         *n = 50176;
789                         break;
790                 case 192000:
791                         *n = 32768;
792                         break;
793                 default:
794                         return -EINVAL;
795                 }
796         } else {
797                 switch (sample_freq) {
798                 case 32000:
799                         *n = 4096;
800                         break;
801                 case 44100:
802                         *n = 6272;
803                         break;
804                 case 48000:
805                         *n = 6144;
806                         break;
807                 case 88200:
808                         *n = 12544;
809                         break;
810                 case 96000:
811                         *n = 12288;
812                         break;
813                 case 176400:
814                         *n = 25088;
815                         break;
816                 case 192000:
817                         *n = 24576;
818                         break;
819                 default:
820                         return -EINVAL;
821                 }
822         }
823         /* Calculate CTS. See HDMI 1.3a or 1.4a specifications */
824         *cts = pclk * (*n / 128) * deep_color / (sample_freq / 10);
825
826         return 0;
827 }
828
829 int hdmi_audio_enable(void)
830 {
831         DSSDBG("audio_enable\n");
832
833         return hdmi.ip_data.ops->audio_enable(&hdmi.ip_data);
834 }
835
836 void hdmi_audio_disable(void)
837 {
838         DSSDBG("audio_disable\n");
839
840         hdmi.ip_data.ops->audio_disable(&hdmi.ip_data);
841 }
842
843 int hdmi_audio_start(void)
844 {
845         DSSDBG("audio_start\n");
846
847         return hdmi.ip_data.ops->audio_start(&hdmi.ip_data);
848 }
849
850 void hdmi_audio_stop(void)
851 {
852         DSSDBG("audio_stop\n");
853
854         hdmi.ip_data.ops->audio_stop(&hdmi.ip_data);
855 }
856
857 bool hdmi_mode_has_audio(void)
858 {
859         if (hdmi.ip_data.cfg.cm.mode == HDMI_HDMI)
860                 return true;
861         else
862                 return false;
863 }
864
865 int hdmi_audio_config(struct omap_dss_audio *audio)
866 {
867         return hdmi.ip_data.ops->audio_config(&hdmi.ip_data, audio);
868 }
869
870 #endif
871
872 static void __init hdmi_probe_pdata(struct platform_device *pdev)
873 {
874         struct omap_dss_board_info *pdata = pdev->dev.platform_data;
875         int r, i;
876
877         for (i = 0; i < pdata->num_devices; ++i) {
878                 struct omap_dss_device *dssdev = pdata->devices[i];
879
880                 if (dssdev->type != OMAP_DISPLAY_TYPE_HDMI)
881                         continue;
882
883                 r = hdmi_init_display(dssdev);
884                 if (r) {
885                         DSSERR("device %s init failed: %d\n", dssdev->name, r);
886                         continue;
887                 }
888
889                 r = omap_dss_register_device(dssdev, &pdev->dev, i);
890                 if (r)
891                         DSSERR("device %s register failed: %d\n",
892                                         dssdev->name, r);
893         }
894 }
895
896 /* HDMI HW IP initialisation */
897 static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
898 {
899         struct resource *hdmi_mem;
900         int r;
901
902         hdmi.pdev = pdev;
903
904         mutex_init(&hdmi.lock);
905
906         hdmi_mem = platform_get_resource(hdmi.pdev, IORESOURCE_MEM, 0);
907         if (!hdmi_mem) {
908                 DSSERR("can't get IORESOURCE_MEM HDMI\n");
909                 return -EINVAL;
910         }
911
912         /* Base address taken from platform */
913         hdmi.ip_data.base_wp = ioremap(hdmi_mem->start,
914                                                 resource_size(hdmi_mem));
915         if (!hdmi.ip_data.base_wp) {
916                 DSSERR("can't ioremap WP\n");
917                 return -ENOMEM;
918         }
919
920         r = hdmi_get_clocks(pdev);
921         if (r) {
922                 iounmap(hdmi.ip_data.base_wp);
923                 return r;
924         }
925
926         pm_runtime_enable(&pdev->dev);
927
928         hdmi.ip_data.core_sys_offset = HDMI_CORE_SYS;
929         hdmi.ip_data.core_av_offset = HDMI_CORE_AV;
930         hdmi.ip_data.pll_offset = HDMI_PLLCTRL;
931         hdmi.ip_data.phy_offset = HDMI_PHY;
932         mutex_init(&hdmi.ip_data.lock);
933
934         hdmi_panel_init();
935
936         dss_debugfs_create_file("hdmi", hdmi_dump_regs);
937
938         hdmi_probe_pdata(pdev);
939
940         return 0;
941 }
942
943 static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
944 {
945         omap_dss_unregister_child_devices(&pdev->dev);
946
947         hdmi_panel_exit();
948
949         pm_runtime_disable(&pdev->dev);
950
951         hdmi_put_clocks();
952
953         iounmap(hdmi.ip_data.base_wp);
954
955         return 0;
956 }
957
958 static int hdmi_runtime_suspend(struct device *dev)
959 {
960         clk_disable_unprepare(hdmi.sys_clk);
961
962         dispc_runtime_put();
963
964         return 0;
965 }
966
967 static int hdmi_runtime_resume(struct device *dev)
968 {
969         int r;
970
971         r = dispc_runtime_get();
972         if (r < 0)
973                 return r;
974
975         clk_prepare_enable(hdmi.sys_clk);
976
977         return 0;
978 }
979
980 static const struct dev_pm_ops hdmi_pm_ops = {
981         .runtime_suspend = hdmi_runtime_suspend,
982         .runtime_resume = hdmi_runtime_resume,
983 };
984
985 static struct platform_driver omapdss_hdmihw_driver = {
986         .remove         = __exit_p(omapdss_hdmihw_remove),
987         .driver         = {
988                 .name   = "omapdss_hdmi",
989                 .owner  = THIS_MODULE,
990                 .pm     = &hdmi_pm_ops,
991         },
992 };
993
994 int __init hdmi_init_platform_driver(void)
995 {
996         return platform_driver_probe(&omapdss_hdmihw_driver, omapdss_hdmihw_probe);
997 }
998
999 void __exit hdmi_uninit_platform_driver(void)
1000 {
1001         platform_driver_unregister(&omapdss_hdmihw_driver);
1002 }