]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/video/omap2/dss/hdmi.c
OMAPDSS: HDMI: Create platform device for audio support
[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 <linux/gpio.h>
36 #include <linux/regulator/consumer.h>
37 #include <video/omapdss.h>
38
39 #include "ti_hdmi.h"
40 #include "dss.h"
41 #include "dss_features.h"
42
43 #define HDMI_WP                 0x0
44 #define HDMI_CORE_SYS           0x400
45 #define HDMI_CORE_AV            0x900
46 #define HDMI_PLLCTRL            0x200
47 #define HDMI_PHY                0x300
48
49 /* HDMI EDID Length move this */
50 #define HDMI_EDID_MAX_LENGTH                    256
51 #define EDID_TIMING_DESCRIPTOR_SIZE             0x12
52 #define EDID_DESCRIPTOR_BLOCK0_ADDRESS          0x36
53 #define EDID_DESCRIPTOR_BLOCK1_ADDRESS          0x80
54 #define EDID_SIZE_BLOCK0_TIMING_DESCRIPTOR      4
55 #define EDID_SIZE_BLOCK1_TIMING_DESCRIPTOR      4
56
57 #define HDMI_DEFAULT_REGN 16
58 #define HDMI_DEFAULT_REGM2 1
59
60 static struct {
61         struct mutex lock;
62         struct platform_device *pdev;
63 #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO)
64         struct platform_device *audio_pdev;
65 #endif
66
67         struct hdmi_ip_data ip_data;
68
69         struct clk *sys_clk;
70         struct regulator *vdda_hdmi_dac_reg;
71
72         int ct_cp_hpd_gpio;
73         int ls_oe_gpio;
74         int hpd_gpio;
75
76         struct omap_dss_output output;
77 } hdmi;
78
79 /*
80  * Logic for the below structure :
81  * user enters the CEA or VESA timings by specifying the HDMI/DVI code.
82  * There is a correspondence between CEA/VESA timing and code, please
83  * refer to section 6.3 in HDMI 1.3 specification for timing code.
84  *
85  * In the below structure, cea_vesa_timings corresponds to all OMAP4
86  * supported CEA and VESA timing values.code_cea corresponds to the CEA
87  * code, It is used to get the timing from cea_vesa_timing array.Similarly
88  * with code_vesa. Code_index is used for back mapping, that is once EDID
89  * is read from the TV, EDID is parsed to find the timing values and then
90  * map it to corresponding CEA or VESA index.
91  */
92
93 static const struct hdmi_config cea_timings[] = {
94         {
95                 { 640, 480, 25200, 96, 16, 48, 2, 10, 33,
96                         OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
97                         false, },
98                 { 1, HDMI_HDMI },
99         },
100         {
101                 { 720, 480, 27027, 62, 16, 60, 6, 9, 30,
102                         OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
103                         false, },
104                 { 2, HDMI_HDMI },
105         },
106         {
107                 { 1280, 720, 74250, 40, 110, 220, 5, 5, 20,
108                         OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
109                         false, },
110                 { 4, HDMI_HDMI },
111         },
112         {
113                 { 1920, 540, 74250, 44, 88, 148, 5, 2, 15,
114                         OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
115                         true, },
116                 { 5, HDMI_HDMI },
117         },
118         {
119                 { 1440, 240, 27027, 124, 38, 114, 3, 4, 15,
120                         OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
121                         true, },
122                 { 6, HDMI_HDMI },
123         },
124         {
125                 { 1920, 1080, 148500, 44, 88, 148, 5, 4, 36,
126                         OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
127                         false, },
128                 { 16, HDMI_HDMI },
129         },
130         {
131                 { 720, 576, 27000, 64, 12, 68, 5, 5, 39,
132                         OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
133                         false, },
134                 { 17, HDMI_HDMI },
135         },
136         {
137                 { 1280, 720, 74250, 40, 440, 220, 5, 5, 20,
138                         OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
139                         false, },
140                 { 19, HDMI_HDMI },
141         },
142         {
143                 { 1920, 540, 74250, 44, 528, 148, 5, 2, 15,
144                         OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
145                         true, },
146                 { 20, HDMI_HDMI },
147         },
148         {
149                 { 1440, 288, 27000, 126, 24, 138, 3, 2, 19,
150                         OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
151                         true, },
152                 { 21, HDMI_HDMI },
153         },
154         {
155                 { 1440, 576, 54000, 128, 24, 136, 5, 5, 39,
156                         OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
157                         false, },
158                 { 29, HDMI_HDMI },
159         },
160         {
161                 { 1920, 1080, 148500, 44, 528, 148, 5, 4, 36,
162                         OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
163                         false, },
164                 { 31, HDMI_HDMI },
165         },
166         {
167                 { 1920, 1080, 74250, 44, 638, 148, 5, 4, 36,
168                         OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
169                         false, },
170                 { 32, HDMI_HDMI },
171         },
172         {
173                 { 2880, 480, 108108, 248, 64, 240, 6, 9, 30,
174                         OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
175                         false, },
176                 { 35, HDMI_HDMI },
177         },
178         {
179                 { 2880, 576, 108000, 256, 48, 272, 5, 5, 39,
180                         OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
181                         false, },
182                 { 37, HDMI_HDMI },
183         },
184 };
185
186 static const struct hdmi_config vesa_timings[] = {
187 /* VESA From Here */
188         {
189                 { 640, 480, 25175, 96, 16, 48, 2, 11, 31,
190                         OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
191                         false, },
192                 { 4, HDMI_DVI },
193         },
194         {
195                 { 800, 600, 40000, 128, 40, 88, 4, 1, 23,
196                         OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
197                         false, },
198                 { 9, HDMI_DVI },
199         },
200         {
201                 { 848, 480, 33750, 112, 16, 112, 8, 6, 23,
202                         OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
203                         false, },
204                 { 0xE, HDMI_DVI },
205         },
206         {
207                 { 1280, 768, 79500, 128, 64, 192, 7, 3, 20,
208                         OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
209                         false, },
210                 { 0x17, HDMI_DVI },
211         },
212         {
213                 { 1280, 800, 83500, 128, 72, 200, 6, 3, 22,
214                         OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
215                         false, },
216                 { 0x1C, HDMI_DVI },
217         },
218         {
219                 { 1360, 768, 85500, 112, 64, 256, 6, 3, 18,
220                         OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
221                         false, },
222                 { 0x27, HDMI_DVI },
223         },
224         {
225                 { 1280, 960, 108000, 112, 96, 312, 3, 1, 36,
226                         OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
227                         false, },
228                 { 0x20, HDMI_DVI },
229         },
230         {
231                 { 1280, 1024, 108000, 112, 48, 248, 3, 1, 38,
232                         OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
233                         false, },
234                 { 0x23, HDMI_DVI },
235         },
236         {
237                 { 1024, 768, 65000, 136, 24, 160, 6, 3, 29,
238                         OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
239                         false, },
240                 { 0x10, HDMI_DVI },
241         },
242         {
243                 { 1400, 1050, 121750, 144, 88, 232, 4, 3, 32,
244                         OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
245                         false, },
246                 { 0x2A, HDMI_DVI },
247         },
248         {
249                 { 1440, 900, 106500, 152, 80, 232, 6, 3, 25,
250                         OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
251                         false, },
252                 { 0x2F, HDMI_DVI },
253         },
254         {
255                 { 1680, 1050, 146250, 176 , 104, 280, 6, 3, 30,
256                         OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
257                         false, },
258                 { 0x3A, HDMI_DVI },
259         },
260         {
261                 { 1366, 768, 85500, 143, 70, 213, 3, 3, 24,
262                         OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
263                         false, },
264                 { 0x51, HDMI_DVI },
265         },
266         {
267                 { 1920, 1080, 148500, 44, 148, 80, 5, 4, 36,
268                         OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
269                         false, },
270                 { 0x52, HDMI_DVI },
271         },
272         {
273                 { 1280, 768, 68250, 32, 48, 80, 7, 3, 12,
274                         OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
275                         false, },
276                 { 0x16, HDMI_DVI },
277         },
278         {
279                 { 1400, 1050, 101000, 32, 48, 80, 4, 3, 23,
280                         OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
281                         false, },
282                 { 0x29, HDMI_DVI },
283         },
284         {
285                 { 1680, 1050, 119000, 32, 48, 80, 6, 3, 21,
286                         OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
287                         false, },
288                 { 0x39, HDMI_DVI },
289         },
290         {
291                 { 1280, 800, 79500, 32, 48, 80, 6, 3, 14,
292                         OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
293                         false, },
294                 { 0x1B, HDMI_DVI },
295         },
296         {
297                 { 1280, 720, 74250, 40, 110, 220, 5, 5, 20,
298                         OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
299                         false, },
300                 { 0x55, HDMI_DVI },
301         },
302         {
303                 { 1920, 1200, 154000, 32, 48, 80, 6, 3, 26,
304                         OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
305                         false, },
306                 { 0x44, HDMI_DVI },
307         },
308 };
309
310 static int hdmi_runtime_get(void)
311 {
312         int r;
313
314         DSSDBG("hdmi_runtime_get\n");
315
316         r = pm_runtime_get_sync(&hdmi.pdev->dev);
317         WARN_ON(r < 0);
318         if (r < 0)
319                 return r;
320
321         return 0;
322 }
323
324 static void hdmi_runtime_put(void)
325 {
326         int r;
327
328         DSSDBG("hdmi_runtime_put\n");
329
330         r = pm_runtime_put_sync(&hdmi.pdev->dev);
331         WARN_ON(r < 0 && r != -ENOSYS);
332 }
333
334 static int __init hdmi_init_display(struct omap_dss_device *dssdev)
335 {
336         int r;
337
338         struct gpio gpios[] = {
339                 { hdmi.ct_cp_hpd_gpio, GPIOF_OUT_INIT_LOW, "hdmi_ct_cp_hpd" },
340                 { hdmi.ls_oe_gpio, GPIOF_OUT_INIT_LOW, "hdmi_ls_oe" },
341                 { hdmi.hpd_gpio, GPIOF_DIR_IN, "hdmi_hpd" },
342         };
343
344         DSSDBG("init_display\n");
345
346         dss_init_hdmi_ip_ops(&hdmi.ip_data, omapdss_get_version());
347
348         if (hdmi.vdda_hdmi_dac_reg == NULL) {
349                 struct regulator *reg;
350
351                 reg = devm_regulator_get(&hdmi.pdev->dev, "vdda_hdmi_dac");
352
353                 if (IS_ERR(reg)) {
354                         DSSERR("can't get VDDA_HDMI_DAC regulator\n");
355                         return PTR_ERR(reg);
356                 }
357
358                 hdmi.vdda_hdmi_dac_reg = reg;
359         }
360
361         r = gpio_request_array(gpios, ARRAY_SIZE(gpios));
362         if (r)
363                 return r;
364
365         return 0;
366 }
367
368 static void __exit hdmi_uninit_display(struct omap_dss_device *dssdev)
369 {
370         DSSDBG("uninit_display\n");
371
372         gpio_free(hdmi.ct_cp_hpd_gpio);
373         gpio_free(hdmi.ls_oe_gpio);
374         gpio_free(hdmi.hpd_gpio);
375 }
376
377 static const struct hdmi_config *hdmi_find_timing(
378                                         const struct hdmi_config *timings_arr,
379                                         int len)
380 {
381         int i;
382
383         for (i = 0; i < len; i++) {
384                 if (timings_arr[i].cm.code == hdmi.ip_data.cfg.cm.code)
385                         return &timings_arr[i];
386         }
387         return NULL;
388 }
389
390 static const struct hdmi_config *hdmi_get_timings(void)
391 {
392        const struct hdmi_config *arr;
393        int len;
394
395        if (hdmi.ip_data.cfg.cm.mode == HDMI_DVI) {
396                arr = vesa_timings;
397                len = ARRAY_SIZE(vesa_timings);
398        } else {
399                arr = cea_timings;
400                len = ARRAY_SIZE(cea_timings);
401        }
402
403        return hdmi_find_timing(arr, len);
404 }
405
406 static bool hdmi_timings_compare(struct omap_video_timings *timing1,
407                                 const struct omap_video_timings *timing2)
408 {
409         int timing1_vsync, timing1_hsync, timing2_vsync, timing2_hsync;
410
411         if ((DIV_ROUND_CLOSEST(timing2->pixel_clock, 1000) ==
412                         DIV_ROUND_CLOSEST(timing1->pixel_clock, 1000)) &&
413                 (timing2->x_res == timing1->x_res) &&
414                 (timing2->y_res == timing1->y_res)) {
415
416                 timing2_hsync = timing2->hfp + timing2->hsw + timing2->hbp;
417                 timing1_hsync = timing1->hfp + timing1->hsw + timing1->hbp;
418                 timing2_vsync = timing2->vfp + timing2->vsw + timing2->vbp;
419                 timing1_vsync = timing2->vfp + timing2->vsw + timing2->vbp;
420
421                 DSSDBG("timing1_hsync = %d timing1_vsync = %d"\
422                         "timing2_hsync = %d timing2_vsync = %d\n",
423                         timing1_hsync, timing1_vsync,
424                         timing2_hsync, timing2_vsync);
425
426                 if ((timing1_hsync == timing2_hsync) &&
427                         (timing1_vsync == timing2_vsync)) {
428                         return true;
429                 }
430         }
431         return false;
432 }
433
434 static struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing)
435 {
436         int i;
437         struct hdmi_cm cm = {-1};
438         DSSDBG("hdmi_get_code\n");
439
440         for (i = 0; i < ARRAY_SIZE(cea_timings); i++) {
441                 if (hdmi_timings_compare(timing, &cea_timings[i].timings)) {
442                         cm = cea_timings[i].cm;
443                         goto end;
444                 }
445         }
446         for (i = 0; i < ARRAY_SIZE(vesa_timings); i++) {
447                 if (hdmi_timings_compare(timing, &vesa_timings[i].timings)) {
448                         cm = vesa_timings[i].cm;
449                         goto end;
450                 }
451         }
452
453 end:    return cm;
454
455 }
456
457 unsigned long hdmi_get_pixel_clock(void)
458 {
459         /* HDMI Pixel Clock in Mhz */
460         return hdmi.ip_data.cfg.timings.pixel_clock * 1000;
461 }
462
463 static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy,
464                 struct hdmi_pll_info *pi)
465 {
466         unsigned long clkin, refclk;
467         u32 mf;
468
469         clkin = clk_get_rate(hdmi.sys_clk) / 10000;
470         /*
471          * Input clock is predivided by N + 1
472          * out put of which is reference clk
473          */
474         if (dssdev->clocks.hdmi.regn == 0)
475                 pi->regn = HDMI_DEFAULT_REGN;
476         else
477                 pi->regn = dssdev->clocks.hdmi.regn;
478
479         refclk = clkin / pi->regn;
480
481         if (dssdev->clocks.hdmi.regm2 == 0)
482                 pi->regm2 = HDMI_DEFAULT_REGM2;
483         else
484                 pi->regm2 = dssdev->clocks.hdmi.regm2;
485
486         /*
487          * multiplier is pixel_clk/ref_clk
488          * Multiplying by 100 to avoid fractional part removal
489          */
490         pi->regm = phy * pi->regm2 / refclk;
491
492         /*
493          * fractional multiplier is remainder of the difference between
494          * multiplier and actual phy(required pixel clock thus should be
495          * multiplied by 2^18(262144) divided by the reference clock
496          */
497         mf = (phy - pi->regm / pi->regm2 * refclk) * 262144;
498         pi->regmf = pi->regm2 * mf / refclk;
499
500         /*
501          * Dcofreq should be set to 1 if required pixel clock
502          * is greater than 1000MHz
503          */
504         pi->dcofreq = phy > 1000 * 100;
505         pi->regsd = ((pi->regm * clkin / 10) / (pi->regn * 250) + 5) / 10;
506
507         /* Set the reference clock to sysclk reference */
508         pi->refsel = HDMI_REFSEL_SYSCLK;
509
510         DSSDBG("M = %d Mf = %d\n", pi->regm, pi->regmf);
511         DSSDBG("range = %d sd = %d\n", pi->dcofreq, pi->regsd);
512 }
513
514 static int hdmi_power_on_core(struct omap_dss_device *dssdev)
515 {
516         int r;
517
518         gpio_set_value(hdmi.ct_cp_hpd_gpio, 1);
519         gpio_set_value(hdmi.ls_oe_gpio, 1);
520
521         /* wait 300us after CT_CP_HPD for the 5V power output to reach 90% */
522         udelay(300);
523
524         r = regulator_enable(hdmi.vdda_hdmi_dac_reg);
525         if (r)
526                 goto err_vdac_enable;
527
528         r = hdmi_runtime_get();
529         if (r)
530                 goto err_runtime_get;
531
532         /* Make selection of HDMI in DSS */
533         dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK);
534
535         return 0;
536
537 err_runtime_get:
538         regulator_disable(hdmi.vdda_hdmi_dac_reg);
539 err_vdac_enable:
540         gpio_set_value(hdmi.ct_cp_hpd_gpio, 0);
541         gpio_set_value(hdmi.ls_oe_gpio, 0);
542         return r;
543 }
544
545 static void hdmi_power_off_core(struct omap_dss_device *dssdev)
546 {
547         hdmi_runtime_put();
548         regulator_disable(hdmi.vdda_hdmi_dac_reg);
549         gpio_set_value(hdmi.ct_cp_hpd_gpio, 0);
550         gpio_set_value(hdmi.ls_oe_gpio, 0);
551 }
552
553 static int hdmi_power_on_full(struct omap_dss_device *dssdev)
554 {
555         int r;
556         struct omap_video_timings *p;
557         struct omap_overlay_manager *mgr = dssdev->output->manager;
558         unsigned long phy;
559
560         r = hdmi_power_on_core(dssdev);
561         if (r)
562                 return r;
563
564         dss_mgr_disable(mgr);
565
566         p = &hdmi.ip_data.cfg.timings;
567
568         DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res);
569
570         phy = p->pixel_clock;
571
572         hdmi_compute_pll(dssdev, phy, &hdmi.ip_data.pll_data);
573
574         hdmi.ip_data.ops->video_disable(&hdmi.ip_data);
575
576         /* config the PLL and PHY hdmi_set_pll_pwrfirst */
577         r = hdmi.ip_data.ops->pll_enable(&hdmi.ip_data);
578         if (r) {
579                 DSSDBG("Failed to lock PLL\n");
580                 goto err_pll_enable;
581         }
582
583         r = hdmi.ip_data.ops->phy_enable(&hdmi.ip_data);
584         if (r) {
585                 DSSDBG("Failed to start PHY\n");
586                 goto err_phy_enable;
587         }
588
589         hdmi.ip_data.ops->video_configure(&hdmi.ip_data);
590
591         /* bypass TV gamma table */
592         dispc_enable_gamma_table(0);
593
594         /* tv size */
595         dss_mgr_set_timings(mgr, p);
596
597         r = hdmi.ip_data.ops->video_enable(&hdmi.ip_data);
598         if (r)
599                 goto err_vid_enable;
600
601         r = dss_mgr_enable(mgr);
602         if (r)
603                 goto err_mgr_enable;
604
605         return 0;
606
607 err_mgr_enable:
608         hdmi.ip_data.ops->video_disable(&hdmi.ip_data);
609 err_vid_enable:
610         hdmi.ip_data.ops->phy_disable(&hdmi.ip_data);
611 err_phy_enable:
612         hdmi.ip_data.ops->pll_disable(&hdmi.ip_data);
613 err_pll_enable:
614         hdmi_power_off_core(dssdev);
615         return -EIO;
616 }
617
618 static void hdmi_power_off_full(struct omap_dss_device *dssdev)
619 {
620         struct omap_overlay_manager *mgr = dssdev->output->manager;
621
622         dss_mgr_disable(mgr);
623
624         hdmi.ip_data.ops->video_disable(&hdmi.ip_data);
625         hdmi.ip_data.ops->phy_disable(&hdmi.ip_data);
626         hdmi.ip_data.ops->pll_disable(&hdmi.ip_data);
627
628         hdmi_power_off_core(dssdev);
629 }
630
631 int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
632                                         struct omap_video_timings *timings)
633 {
634         struct hdmi_cm cm;
635
636         cm = hdmi_get_code(timings);
637         if (cm.code == -1) {
638                 return -EINVAL;
639         }
640
641         return 0;
642
643 }
644
645 void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev,
646                 struct omap_video_timings *timings)
647 {
648         struct hdmi_cm cm;
649         const struct hdmi_config *t;
650
651         mutex_lock(&hdmi.lock);
652
653         cm = hdmi_get_code(timings);
654         hdmi.ip_data.cfg.cm = cm;
655
656         t = hdmi_get_timings();
657         if (t != NULL)
658                 hdmi.ip_data.cfg = *t;
659
660         mutex_unlock(&hdmi.lock);
661 }
662
663 static void hdmi_dump_regs(struct seq_file *s)
664 {
665         mutex_lock(&hdmi.lock);
666
667         if (hdmi_runtime_get()) {
668                 mutex_unlock(&hdmi.lock);
669                 return;
670         }
671
672         hdmi.ip_data.ops->dump_wrapper(&hdmi.ip_data, s);
673         hdmi.ip_data.ops->dump_pll(&hdmi.ip_data, s);
674         hdmi.ip_data.ops->dump_phy(&hdmi.ip_data, s);
675         hdmi.ip_data.ops->dump_core(&hdmi.ip_data, s);
676
677         hdmi_runtime_put();
678         mutex_unlock(&hdmi.lock);
679 }
680
681 int omapdss_hdmi_read_edid(u8 *buf, int len)
682 {
683         int r;
684
685         mutex_lock(&hdmi.lock);
686
687         r = hdmi_runtime_get();
688         BUG_ON(r);
689
690         r = hdmi.ip_data.ops->read_edid(&hdmi.ip_data, buf, len);
691
692         hdmi_runtime_put();
693         mutex_unlock(&hdmi.lock);
694
695         return r;
696 }
697
698 bool omapdss_hdmi_detect(void)
699 {
700         int r;
701
702         mutex_lock(&hdmi.lock);
703
704         r = hdmi_runtime_get();
705         BUG_ON(r);
706
707         r = hdmi.ip_data.ops->detect(&hdmi.ip_data);
708
709         hdmi_runtime_put();
710         mutex_unlock(&hdmi.lock);
711
712         return r == 1;
713 }
714
715 int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
716 {
717         struct omap_dss_output *out = dssdev->output;
718         int r = 0;
719
720         DSSDBG("ENTER hdmi_display_enable\n");
721
722         mutex_lock(&hdmi.lock);
723
724         if (out == NULL || out->manager == NULL) {
725                 DSSERR("failed to enable display: no output/manager\n");
726                 r = -ENODEV;
727                 goto err0;
728         }
729
730         hdmi.ip_data.hpd_gpio = hdmi.hpd_gpio;
731
732         r = omap_dss_start_device(dssdev);
733         if (r) {
734                 DSSERR("failed to start device\n");
735                 goto err0;
736         }
737
738         r = hdmi_power_on_full(dssdev);
739         if (r) {
740                 DSSERR("failed to power on device\n");
741                 goto err1;
742         }
743
744         mutex_unlock(&hdmi.lock);
745         return 0;
746
747 err1:
748         omap_dss_stop_device(dssdev);
749 err0:
750         mutex_unlock(&hdmi.lock);
751         return r;
752 }
753
754 void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev)
755 {
756         DSSDBG("Enter hdmi_display_disable\n");
757
758         mutex_lock(&hdmi.lock);
759
760         hdmi_power_off_full(dssdev);
761
762         omap_dss_stop_device(dssdev);
763
764         mutex_unlock(&hdmi.lock);
765 }
766
767 int omapdss_hdmi_core_enable(struct omap_dss_device *dssdev)
768 {
769         int r = 0;
770
771         DSSDBG("ENTER omapdss_hdmi_core_enable\n");
772
773         mutex_lock(&hdmi.lock);
774
775         hdmi.ip_data.hpd_gpio = hdmi.hpd_gpio;
776
777         r = hdmi_power_on_core(dssdev);
778         if (r) {
779                 DSSERR("failed to power on device\n");
780                 goto err0;
781         }
782
783         mutex_unlock(&hdmi.lock);
784         return 0;
785
786 err0:
787         mutex_unlock(&hdmi.lock);
788         return r;
789 }
790
791 void omapdss_hdmi_core_disable(struct omap_dss_device *dssdev)
792 {
793         DSSDBG("Enter omapdss_hdmi_core_disable\n");
794
795         mutex_lock(&hdmi.lock);
796
797         hdmi_power_off_core(dssdev);
798
799         mutex_unlock(&hdmi.lock);
800 }
801
802 static int hdmi_get_clocks(struct platform_device *pdev)
803 {
804         struct clk *clk;
805
806         clk = clk_get(&pdev->dev, "sys_clk");
807         if (IS_ERR(clk)) {
808                 DSSERR("can't get sys_clk\n");
809                 return PTR_ERR(clk);
810         }
811
812         hdmi.sys_clk = clk;
813
814         return 0;
815 }
816
817 static void hdmi_put_clocks(void)
818 {
819         if (hdmi.sys_clk)
820                 clk_put(hdmi.sys_clk);
821 }
822
823 #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO)
824 static int hdmi_probe_audio(struct platform_device *pdev)
825 {
826         struct resource *res;
827         struct platform_device *aud_pdev;
828         u32 port_offset, port_size;
829         struct resource aud_res[2] = {
830                 DEFINE_RES_MEM(-1, -1),
831                 DEFINE_RES_DMA(-1),
832         };
833
834         res = platform_get_resource(hdmi.pdev, IORESOURCE_MEM, 0);
835         if (!res) {
836                 DSSERR("can't get IORESOURCE_MEM HDMI\n");
837                 return -EINVAL;
838         }
839
840         /*
841          * Pass DMA audio port to audio drivers.
842          * Audio drivers should not ioremap it.
843          */
844         hdmi.ip_data.ops->audio_get_dma_port(&port_offset, &port_size);
845
846         aud_res[0].start = res->start + port_offset;
847         aud_res[0].end = aud_res[0].start + port_size - 1;
848
849         res = platform_get_resource(hdmi.pdev, IORESOURCE_DMA, 0);
850         if (!res) {
851                 DSSERR("can't get IORESOURCE_DMA HDMI\n");
852                 return -EINVAL;
853         }
854
855         /* Pass the audio DMA request resource to audio drivers. */
856         aud_res[1].start = res->start;
857
858         /* create platform device for HDMI audio driver */
859         aud_pdev = platform_device_register_simple("omap_hdmi_audio",
860                                                    pdev->id, aud_res,
861                                                    ARRAY_SIZE(aud_res));
862         if (IS_ERR(aud_pdev)) {
863                 DSSERR("Can't instantiate hdmi-audio\n");
864                 return -ENODEV;
865         }
866
867         hdmi.audio_pdev = aud_pdev;
868
869         return 0;
870 }
871
872 int hdmi_compute_acr(u32 sample_freq, u32 *n, u32 *cts)
873 {
874         u32 deep_color;
875         bool deep_color_correct = false;
876         u32 pclk = hdmi.ip_data.cfg.timings.pixel_clock;
877
878         if (n == NULL || cts == NULL)
879                 return -EINVAL;
880
881         /* TODO: When implemented, query deep color mode here. */
882         deep_color = 100;
883
884         /*
885          * When using deep color, the default N value (as in the HDMI
886          * specification) yields to an non-integer CTS. Hence, we
887          * modify it while keeping the restrictions described in
888          * section 7.2.1 of the HDMI 1.4a specification.
889          */
890         switch (sample_freq) {
891         case 32000:
892         case 48000:
893         case 96000:
894         case 192000:
895                 if (deep_color == 125)
896                         if (pclk == 27027 || pclk == 74250)
897                                 deep_color_correct = true;
898                 if (deep_color == 150)
899                         if (pclk == 27027)
900                                 deep_color_correct = true;
901                 break;
902         case 44100:
903         case 88200:
904         case 176400:
905                 if (deep_color == 125)
906                         if (pclk == 27027)
907                                 deep_color_correct = true;
908                 break;
909         default:
910                 return -EINVAL;
911         }
912
913         if (deep_color_correct) {
914                 switch (sample_freq) {
915                 case 32000:
916                         *n = 8192;
917                         break;
918                 case 44100:
919                         *n = 12544;
920                         break;
921                 case 48000:
922                         *n = 8192;
923                         break;
924                 case 88200:
925                         *n = 25088;
926                         break;
927                 case 96000:
928                         *n = 16384;
929                         break;
930                 case 176400:
931                         *n = 50176;
932                         break;
933                 case 192000:
934                         *n = 32768;
935                         break;
936                 default:
937                         return -EINVAL;
938                 }
939         } else {
940                 switch (sample_freq) {
941                 case 32000:
942                         *n = 4096;
943                         break;
944                 case 44100:
945                         *n = 6272;
946                         break;
947                 case 48000:
948                         *n = 6144;
949                         break;
950                 case 88200:
951                         *n = 12544;
952                         break;
953                 case 96000:
954                         *n = 12288;
955                         break;
956                 case 176400:
957                         *n = 25088;
958                         break;
959                 case 192000:
960                         *n = 24576;
961                         break;
962                 default:
963                         return -EINVAL;
964                 }
965         }
966         /* Calculate CTS. See HDMI 1.3a or 1.4a specifications */
967         *cts = pclk * (*n / 128) * deep_color / (sample_freq / 10);
968
969         return 0;
970 }
971
972 int hdmi_audio_enable(void)
973 {
974         DSSDBG("audio_enable\n");
975
976         return hdmi.ip_data.ops->audio_enable(&hdmi.ip_data);
977 }
978
979 void hdmi_audio_disable(void)
980 {
981         DSSDBG("audio_disable\n");
982
983         hdmi.ip_data.ops->audio_disable(&hdmi.ip_data);
984 }
985
986 int hdmi_audio_start(void)
987 {
988         DSSDBG("audio_start\n");
989
990         return hdmi.ip_data.ops->audio_start(&hdmi.ip_data);
991 }
992
993 void hdmi_audio_stop(void)
994 {
995         DSSDBG("audio_stop\n");
996
997         hdmi.ip_data.ops->audio_stop(&hdmi.ip_data);
998 }
999
1000 bool hdmi_mode_has_audio(void)
1001 {
1002         if (hdmi.ip_data.cfg.cm.mode == HDMI_HDMI)
1003                 return true;
1004         else
1005                 return false;
1006 }
1007
1008 int hdmi_audio_config(struct omap_dss_audio *audio)
1009 {
1010         return hdmi.ip_data.ops->audio_config(&hdmi.ip_data, audio);
1011 }
1012
1013 #endif
1014
1015 static struct omap_dss_device * __init hdmi_find_dssdev(struct platform_device *pdev)
1016 {
1017         struct omap_dss_board_info *pdata = pdev->dev.platform_data;
1018         const char *def_disp_name = omapdss_get_default_display_name();
1019         struct omap_dss_device *def_dssdev;
1020         int i;
1021
1022         def_dssdev = NULL;
1023
1024         for (i = 0; i < pdata->num_devices; ++i) {
1025                 struct omap_dss_device *dssdev = pdata->devices[i];
1026
1027                 if (dssdev->type != OMAP_DISPLAY_TYPE_HDMI)
1028                         continue;
1029
1030                 if (def_dssdev == NULL)
1031                         def_dssdev = dssdev;
1032
1033                 if (def_disp_name != NULL &&
1034                                 strcmp(dssdev->name, def_disp_name) == 0) {
1035                         def_dssdev = dssdev;
1036                         break;
1037                 }
1038         }
1039
1040         return def_dssdev;
1041 }
1042
1043 static void __init hdmi_probe_pdata(struct platform_device *pdev)
1044 {
1045         struct omap_dss_device *plat_dssdev;
1046         struct omap_dss_device *dssdev;
1047         struct omap_dss_hdmi_data *priv;
1048         int r;
1049
1050         plat_dssdev = hdmi_find_dssdev(pdev);
1051
1052         if (!plat_dssdev)
1053                 return;
1054
1055         dssdev = dss_alloc_and_init_device(&pdev->dev);
1056         if (!dssdev)
1057                 return;
1058
1059         dss_copy_device_pdata(dssdev, plat_dssdev);
1060
1061         priv = dssdev->data;
1062
1063         hdmi.ct_cp_hpd_gpio = priv->ct_cp_hpd_gpio;
1064         hdmi.ls_oe_gpio = priv->ls_oe_gpio;
1065         hdmi.hpd_gpio = priv->hpd_gpio;
1066
1067         dssdev->channel = OMAP_DSS_CHANNEL_DIGIT;
1068
1069         r = hdmi_init_display(dssdev);
1070         if (r) {
1071                 DSSERR("device %s init failed: %d\n", dssdev->name, r);
1072                 dss_put_device(dssdev);
1073                 return;
1074         }
1075
1076         r = dss_add_device(dssdev);
1077         if (r) {
1078                 DSSERR("device %s register failed: %d\n", dssdev->name, r);
1079                 hdmi_uninit_display(dssdev);
1080                 dss_put_device(dssdev);
1081                 return;
1082         }
1083 }
1084
1085 static void __init hdmi_init_output(struct platform_device *pdev)
1086 {
1087         struct omap_dss_output *out = &hdmi.output;
1088
1089         out->pdev = pdev;
1090         out->id = OMAP_DSS_OUTPUT_HDMI;
1091         out->type = OMAP_DISPLAY_TYPE_HDMI;
1092
1093         dss_register_output(out);
1094 }
1095
1096 static void __exit hdmi_uninit_output(struct platform_device *pdev)
1097 {
1098         struct omap_dss_output *out = &hdmi.output;
1099
1100         dss_unregister_output(out);
1101 }
1102
1103 /* HDMI HW IP initialisation */
1104 static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
1105 {
1106         struct resource *res;
1107         int r;
1108
1109         hdmi.pdev = pdev;
1110
1111         mutex_init(&hdmi.lock);
1112         mutex_init(&hdmi.ip_data.lock);
1113
1114         res = platform_get_resource(hdmi.pdev, IORESOURCE_MEM, 0);
1115         if (!res) {
1116                 DSSERR("can't get IORESOURCE_MEM HDMI\n");
1117                 return -EINVAL;
1118         }
1119
1120         /* Base address taken from platform */
1121         hdmi.ip_data.base_wp = devm_request_and_ioremap(&pdev->dev, res);
1122         if (!hdmi.ip_data.base_wp) {
1123                 DSSERR("can't ioremap WP\n");
1124                 return -ENOMEM;
1125         }
1126
1127         r = hdmi_get_clocks(pdev);
1128         if (r) {
1129                 DSSERR("can't get clocks\n");
1130                 return r;
1131         }
1132
1133         pm_runtime_enable(&pdev->dev);
1134
1135         hdmi.ip_data.core_sys_offset = HDMI_CORE_SYS;
1136         hdmi.ip_data.core_av_offset = HDMI_CORE_AV;
1137         hdmi.ip_data.pll_offset = HDMI_PLLCTRL;
1138         hdmi.ip_data.phy_offset = HDMI_PHY;
1139
1140         r = hdmi_panel_init();
1141         if (r) {
1142                 DSSERR("can't init panel\n");
1143                 goto err_panel_init;
1144         }
1145
1146         dss_debugfs_create_file("hdmi", hdmi_dump_regs);
1147
1148         hdmi_init_output(pdev);
1149
1150         hdmi_probe_pdata(pdev);
1151
1152 #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO)
1153         r = hdmi_probe_audio(pdev);
1154         if (r)
1155                 DSSWARN("could not create platform device for audio");
1156 #endif
1157
1158         return 0;
1159
1160 err_panel_init:
1161         hdmi_put_clocks();
1162         return r;
1163 }
1164
1165 static int __exit hdmi_remove_child(struct device *dev, void *data)
1166 {
1167         struct omap_dss_device *dssdev = to_dss_device(dev);
1168         hdmi_uninit_display(dssdev);
1169         return 0;
1170 }
1171
1172 static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
1173 {
1174 #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO)
1175         if (hdmi.audio_pdev != NULL)
1176                 platform_device_unregister(hdmi.audio_pdev);
1177 #endif
1178
1179         device_for_each_child(&pdev->dev, NULL, hdmi_remove_child);
1180
1181         dss_unregister_child_devices(&pdev->dev);
1182
1183         hdmi_panel_exit();
1184
1185         hdmi_uninit_output(pdev);
1186
1187         pm_runtime_disable(&pdev->dev);
1188
1189         hdmi_put_clocks();
1190
1191         return 0;
1192 }
1193
1194 static int hdmi_runtime_suspend(struct device *dev)
1195 {
1196         clk_disable_unprepare(hdmi.sys_clk);
1197
1198         dispc_runtime_put();
1199
1200         return 0;
1201 }
1202
1203 static int hdmi_runtime_resume(struct device *dev)
1204 {
1205         int r;
1206
1207         r = dispc_runtime_get();
1208         if (r < 0)
1209                 return r;
1210
1211         clk_prepare_enable(hdmi.sys_clk);
1212
1213         return 0;
1214 }
1215
1216 static const struct dev_pm_ops hdmi_pm_ops = {
1217         .runtime_suspend = hdmi_runtime_suspend,
1218         .runtime_resume = hdmi_runtime_resume,
1219 };
1220
1221 static struct platform_driver omapdss_hdmihw_driver = {
1222         .remove         = __exit_p(omapdss_hdmihw_remove),
1223         .driver         = {
1224                 .name   = "omapdss_hdmi",
1225                 .owner  = THIS_MODULE,
1226                 .pm     = &hdmi_pm_ops,
1227         },
1228 };
1229
1230 int __init hdmi_init_platform_driver(void)
1231 {
1232         return platform_driver_probe(&omapdss_hdmihw_driver, omapdss_hdmihw_probe);
1233 }
1234
1235 void __exit hdmi_uninit_platform_driver(void)
1236 {
1237         platform_driver_unregister(&omapdss_hdmihw_driver);
1238 }