22 #define DSS_SUBSYS_NAME "HDMI"
24 #include <linux/kernel.h>
25 #include <linux/module.h>
31 #include <linux/string.h>
44 #define HDMI_CORE_SYS 0x400
45 #define HDMI_CORE_AV 0x900
46 #define HDMI_PLLCTRL 0x200
47 #define HDMI_PHY 0x300
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
57 #define HDMI_DEFAULT_REGN 16
58 #define HDMI_DEFAULT_REGM2 1
91 { 640, 480, 25200, 96, 16, 48, 2, 10, 33,
97 { 720, 480, 27027, 62, 16, 60, 6, 9, 30,
103 { 1280, 720, 74250, 40, 110, 220, 5, 5, 20,
109 { 1920, 540, 74250, 44, 88, 148, 5, 2, 15,
115 { 1440, 240, 27027, 124, 38, 114, 3, 4, 15,
121 { 1920, 1080, 148500, 44, 88, 148, 5, 4, 36,
127 { 720, 576, 27000, 64, 12, 68, 5, 5, 39,
133 { 1280, 720, 74250, 40, 440, 220, 5, 5, 20,
139 { 1920, 540, 74250, 44, 528, 148, 5, 2, 15,
145 { 1440, 288, 27000, 126, 24, 138, 3, 2, 19,
151 { 1440, 576, 54000, 128, 24, 136, 5, 5, 39,
157 { 1920, 1080, 148500, 44, 528, 148, 5, 4, 36,
163 { 1920, 1080, 74250, 44, 638, 148, 5, 4, 36,
169 { 2880, 480, 108108, 248, 64, 240, 6, 9, 30,
175 { 2880, 576, 108000, 256, 48, 272, 5, 5, 39,
185 { 640, 480, 25175, 96, 16, 48, 2, 11, 31,
191 { 800, 600, 40000, 128, 40, 88, 4, 1, 23,
197 { 848, 480, 33750, 112, 16, 112, 8, 6, 23,
203 { 1280, 768, 79500, 128, 64, 192, 7, 3, 20,
209 { 1280, 800, 83500, 128, 72, 200, 6, 3, 22,
215 { 1360, 768, 85500, 112, 64, 256, 6, 3, 18,
221 { 1280, 960, 108000, 112, 96, 312, 3, 1, 36,
227 { 1280, 1024, 108000, 112, 48, 248, 3, 1, 38,
233 { 1024, 768, 65000, 136, 24, 160, 6, 3, 29,
239 { 1400, 1050, 121750, 144, 88, 232, 4, 3, 32,
245 { 1440, 900, 106500, 152, 80, 232, 6, 3, 25,
251 { 1680, 1050, 146250, 176 , 104, 280, 6, 3, 30,
257 { 1366, 768, 85500, 143, 70, 213, 3, 3, 24,
263 { 1920, 1080, 148500, 44, 148, 80, 5, 4, 36,
269 { 1280, 768, 68250, 32, 48, 80, 7, 3, 12,
275 { 1400, 1050, 101000, 32, 48, 80, 4, 3, 23,
281 { 1680, 1050, 119000, 32, 48, 80, 6, 3, 21,
287 { 1280, 800, 79500, 32, 48, 80, 6, 3, 14,
293 { 1280, 720, 74250, 40, 110, 220, 5, 5, 20,
300 static int hdmi_runtime_get(
void)
304 DSSDBG(
"hdmi_runtime_get\n");
306 r = pm_runtime_get_sync(&hdmi.pdev->dev);
314 static void hdmi_runtime_put(
void)
318 DSSDBG(
"hdmi_runtime_put\n");
320 r = pm_runtime_put_sync(&hdmi.pdev->dev);
328 struct gpio gpios[] = {
336 dss_init_hdmi_ip_ops(&hdmi.ip_data);
338 if (hdmi.vdda_hdmi_dac_reg ==
NULL) {
344 DSSERR(
"can't get VDDA_HDMI_DAC regulator\n");
348 hdmi.vdda_hdmi_dac_reg =
reg;
360 DSSDBG(
"uninit_display\n");
373 for (i = 0; i < len; i++) {
374 if (timings_arr[i].
cm.code == hdmi.ip_data.cfg.cm.code)
375 return &timings_arr[
i];
380 static const struct hdmi_config *hdmi_get_timings(
void)
385 if (hdmi.ip_data.cfg.cm.mode ==
HDMI_DVI) {
393 return hdmi_find_timing(arr, len);
399 int timing1_vsync, timing1_hsync, timing2_vsync, timing2_hsync;
405 timing2_hsync = timing2->
hfp + timing2->
hsw + timing2->
hbp;
406 timing1_hsync = timing1->
hfp + timing1->
hsw + timing1->
hbp;
407 timing2_vsync = timing2->
vfp + timing2->
vsw + timing2->
vbp;
408 timing1_vsync = timing2->
vfp + timing2->
vsw + timing2->
vbp;
410 DSSDBG(
"timing1_hsync = %d timing1_vsync = %d"\
411 "timing2_hsync = %d timing2_vsync = %d\n",
412 timing1_hsync, timing1_vsync,
413 timing2_hsync, timing2_vsync);
415 if ((timing1_hsync == timing2_hsync) &&
416 (timing1_vsync == timing2_vsync)) {
427 DSSDBG(
"hdmi_get_code\n");
429 for (i = 0; i <
ARRAY_SIZE(cea_timings); i++) {
430 if (hdmi_timings_compare(
timing, &cea_timings[i].timings)) {
431 cm = cea_timings[
i].
cm;
435 for (i = 0; i <
ARRAY_SIZE(vesa_timings); i++) {
436 if (hdmi_timings_compare(
timing, &vesa_timings[i].timings)) {
437 cm = vesa_timings[
i].
cm;
449 return hdmi.ip_data.cfg.timings.pixel_clock * 1000;
455 unsigned long clkin, refclk;
463 if (dssdev->
clocks.hdmi.regn == 0)
468 refclk = clkin / pi->
regn;
470 if (dssdev->
clocks.hdmi.regm2 == 0)
486 mf = (phy - pi->
regm / pi->
regm2 * refclk) * 262144;
493 pi->
dcofreq = phy > 1000 * 100;
494 pi->
regsd = ((pi->
regm * clkin / 10) / (pi->
regn * 250) + 5) / 10;
518 goto err_vdac_enable;
520 r = hdmi_runtime_get();
522 goto err_runtime_get;
526 p = &hdmi.ip_data.cfg.timings;
532 hdmi_compute_pll(dssdev, phy, &hdmi.ip_data.pll_data);
534 hdmi.ip_data.ops->video_disable(&hdmi.ip_data);
537 r = hdmi.ip_data.ops->pll_enable(&hdmi.ip_data);
539 DSSDBG(
"Failed to lock PLL\n");
543 r = hdmi.ip_data.ops->phy_enable(&hdmi.ip_data);
545 DSSDBG(
"Failed to start PHY\n");
549 hdmi.ip_data.ops->video_configure(&hdmi.ip_data);
568 r = hdmi.ip_data.ops->video_enable(&hdmi.ip_data);
579 hdmi.ip_data.ops->video_disable(&hdmi.ip_data);
581 hdmi.ip_data.ops->phy_disable(&hdmi.ip_data);
583 hdmi.ip_data.ops->pll_disable(&hdmi.ip_data);
600 hdmi.ip_data.ops->video_disable(&hdmi.ip_data);
601 hdmi.ip_data.ops->phy_disable(&hdmi.ip_data);
602 hdmi.ip_data.ops->pll_disable(&hdmi.ip_data);
616 cm = hdmi_get_code(timings);
633 cm = hdmi_get_code(timings);
634 hdmi.ip_data.cfg.cm =
cm;
636 t = hdmi_get_timings();
638 hdmi.ip_data.cfg = *
t;
643 static void hdmi_dump_regs(
struct seq_file *
s)
647 if (hdmi_runtime_get()) {
652 hdmi.ip_data.ops->dump_wrapper(&hdmi.ip_data, s);
653 hdmi.ip_data.ops->dump_pll(&hdmi.ip_data, s);
654 hdmi.ip_data.ops->dump_phy(&hdmi.ip_data, s);
655 hdmi.ip_data.ops->dump_core(&hdmi.ip_data, s);
667 r = hdmi_runtime_get();
670 r = hdmi.ip_data.ops->read_edid(&hdmi.ip_data, buf, len);
684 r = hdmi_runtime_get();
687 r = hdmi.ip_data.ops->detect(&hdmi.ip_data);
700 DSSDBG(
"ENTER hdmi_display_enable\n");
705 DSSERR(
"failed to enable display: no output/manager\n");
710 hdmi.ip_data.hpd_gpio = hdmi.hpd_gpio;
714 DSSERR(
"failed to start device\n");
718 r = hdmi_power_on(dssdev);
720 DSSERR(
"failed to power on device\n");
736 DSSDBG(
"Enter hdmi_display_disable\n");
740 hdmi_power_off(dssdev);
753 DSSERR(
"can't get sys_clk\n");
762 static void hdmi_put_clocks(
void)
768 #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO)
769 int hdmi_compute_acr(
u32 sample_freq,
u32 *
n,
u32 *cts)
772 bool deep_color_correct =
false;
773 u32 pclk = hdmi.ip_data.cfg.timings.pixel_clock;
787 switch (sample_freq) {
792 if (deep_color == 125)
793 if (pclk == 27027 || pclk == 74250)
794 deep_color_correct =
true;
795 if (deep_color == 150)
797 deep_color_correct =
true;
802 if (deep_color == 125)
804 deep_color_correct =
true;
810 if (deep_color_correct) {
811 switch (sample_freq) {
837 switch (sample_freq) {
864 *cts = pclk * (*n / 128) * deep_color / (sample_freq / 10);
869 int hdmi_audio_enable(
void)
873 return hdmi.ip_data.ops->audio_enable(&hdmi.ip_data);
876 void hdmi_audio_disable(
void)
878 DSSDBG(
"audio_disable\n");
880 hdmi.ip_data.ops->audio_disable(&hdmi.ip_data);
883 int hdmi_audio_start(
void)
887 return hdmi.ip_data.ops->audio_start(&hdmi.ip_data);
890 void hdmi_audio_stop(
void)
894 hdmi.ip_data.ops->audio_stop(&hdmi.ip_data);
897 bool hdmi_mode_has_audio(
void)
899 if (hdmi.ip_data.cfg.cm.mode ==
HDMI_HDMI)
907 return hdmi.ip_data.ops->audio_config(&hdmi.ip_data, audio);
927 if (def_dssdev ==
NULL)
930 if (def_disp_name !=
NULL &&
947 plat_dssdev = hdmi_find_dssdev(pdev);
966 r = hdmi_init_display(dssdev);
968 DSSERR(
"device %s init failed: %d\n", dssdev->
name, r);
975 DSSERR(
"device %s register failed: %d\n", dssdev->
name, r);
1011 DSSERR(
"can't get IORESOURCE_MEM HDMI\n");
1017 resource_size(hdmi_mem));
1018 if (!hdmi.ip_data.base_wp) {
1019 DSSERR(
"can't ioremap WP\n");
1023 r = hdmi_get_clocks(pdev);
1025 iounmap(hdmi.ip_data.base_wp);
1034 hdmi.ip_data.phy_offset =
HDMI_PHY;
1042 hdmi_init_output(pdev);
1044 hdmi_probe_pdata(pdev);
1052 hdmi_uninit_display(dssdev);
1064 hdmi_uninit_output(pdev);
1066 pm_runtime_disable(&pdev->
dev);
1075 static int hdmi_runtime_suspend(
struct device *
dev)
1077 clk_disable_unprepare(
hdmi.sys_clk);
1084 static int hdmi_runtime_resume(
struct device *
dev)
1092 clk_prepare_enable(
hdmi.sys_clk);
1097 static const struct dev_pm_ops hdmi_pm_ops = {
1098 .runtime_suspend = hdmi_runtime_suspend,
1099 .runtime_resume = hdmi_runtime_resume,
1103 .remove =
__exit_p(omapdss_hdmihw_remove),
1105 .name =
"omapdss_hdmi",