aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ti.com>2013-05-24 06:20:17 -0400
committerTomi Valkeinen <tomi.valkeinen@ti.com>2013-06-17 07:01:00 -0400
commit0b450c31317914feb39616cb553b67c170aaf3d0 (patch)
tree098f3b4ff07fedb60392a562e9a73a25588069c7 /drivers/video
parentfb8efa49660ea450ad632c9d8b70f12e4a43a495 (diff)
OMAPDSS: HDMI: Add ops
Add "ops" style method for using HDMI functionality. Ops style calls will allow us to have arbitrarily long display pipelines, where each entity can call ops in the previous display entity. Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/omap2/dss/hdmi.c234
1 files changed, 228 insertions, 6 deletions
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 2b0a2aac8aed..44a885b92825 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -70,6 +70,8 @@ static struct {
70 int ls_oe_gpio; 70 int ls_oe_gpio;
71 int hpd_gpio; 71 int hpd_gpio;
72 72
73 bool core_enabled;
74
73 struct omap_dss_device output; 75 struct omap_dss_device output;
74} hdmi; 76} hdmi;
75 77
@@ -515,8 +517,10 @@ static int hdmi_power_on_core(struct omap_dss_device *dssdev)
515{ 517{
516 int r; 518 int r;
517 519
518 gpio_set_value(hdmi.ct_cp_hpd_gpio, 1); 520 if (gpio_is_valid(hdmi.ct_cp_hpd_gpio))
519 gpio_set_value(hdmi.ls_oe_gpio, 1); 521 gpio_set_value(hdmi.ct_cp_hpd_gpio, 1);
522 if (gpio_is_valid(hdmi.ls_oe_gpio))
523 gpio_set_value(hdmi.ls_oe_gpio, 1);
520 524
521 /* wait 300us after CT_CP_HPD for the 5V power output to reach 90% */ 525 /* wait 300us after CT_CP_HPD for the 5V power output to reach 90% */
522 udelay(300); 526 udelay(300);
@@ -532,22 +536,30 @@ static int hdmi_power_on_core(struct omap_dss_device *dssdev)
532 /* Make selection of HDMI in DSS */ 536 /* Make selection of HDMI in DSS */
533 dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK); 537 dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK);
534 538
539 hdmi.core_enabled = true;
540
535 return 0; 541 return 0;
536 542
537err_runtime_get: 543err_runtime_get:
538 regulator_disable(hdmi.vdda_hdmi_dac_reg); 544 regulator_disable(hdmi.vdda_hdmi_dac_reg);
539err_vdac_enable: 545err_vdac_enable:
540 gpio_set_value(hdmi.ct_cp_hpd_gpio, 0); 546 if (gpio_is_valid(hdmi.ct_cp_hpd_gpio))
541 gpio_set_value(hdmi.ls_oe_gpio, 0); 547 gpio_set_value(hdmi.ct_cp_hpd_gpio, 0);
548 if (gpio_is_valid(hdmi.ls_oe_gpio))
549 gpio_set_value(hdmi.ls_oe_gpio, 0);
542 return r; 550 return r;
543} 551}
544 552
545static void hdmi_power_off_core(struct omap_dss_device *dssdev) 553static void hdmi_power_off_core(struct omap_dss_device *dssdev)
546{ 554{
555 hdmi.core_enabled = false;
556
547 hdmi_runtime_put(); 557 hdmi_runtime_put();
548 regulator_disable(hdmi.vdda_hdmi_dac_reg); 558 regulator_disable(hdmi.vdda_hdmi_dac_reg);
549 gpio_set_value(hdmi.ct_cp_hpd_gpio, 0); 559 if (gpio_is_valid(hdmi.ct_cp_hpd_gpio))
550 gpio_set_value(hdmi.ls_oe_gpio, 0); 560 gpio_set_value(hdmi.ct_cp_hpd_gpio, 0);
561 if (gpio_is_valid(hdmi.ls_oe_gpio))
562 gpio_set_value(hdmi.ls_oe_gpio, 0);
551} 563}
552 564
553static int hdmi_power_on_full(struct omap_dss_device *dssdev) 565static int hdmi_power_on_full(struct omap_dss_device *dssdev)
@@ -662,6 +674,18 @@ void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev,
662 mutex_unlock(&hdmi.lock); 674 mutex_unlock(&hdmi.lock);
663} 675}
664 676
677static void omapdss_hdmi_display_get_timings(struct omap_dss_device *dssdev,
678 struct omap_video_timings *timings)
679{
680 const struct hdmi_config *cfg;
681
682 cfg = hdmi_get_timings();
683 if (cfg == NULL)
684 cfg = &vesa_timings[0];
685
686 memcpy(timings, &cfg->timings, sizeof(cfg->timings));
687}
688
665static void hdmi_dump_regs(struct seq_file *s) 689static void hdmi_dump_regs(struct seq_file *s)
666{ 690{
667 mutex_lock(&hdmi.lock); 691 mutex_lock(&hdmi.lock);
@@ -1025,6 +1049,199 @@ static int hdmi_probe_pdata(struct platform_device *pdev)
1025 return 0; 1049 return 0;
1026} 1050}
1027 1051
1052static int hdmi_connect(struct omap_dss_device *dssdev,
1053 struct omap_dss_device *dst)
1054{
1055 struct omap_overlay_manager *mgr;
1056 int r;
1057
1058 dss_init_hdmi_ip_ops(&hdmi.ip_data, omapdss_get_version());
1059
1060 r = hdmi_init_regulator();
1061 if (r)
1062 return r;
1063
1064 mgr = omap_dss_get_overlay_manager(dssdev->dispc_channel);
1065 if (!mgr)
1066 return -ENODEV;
1067
1068 r = dss_mgr_connect(mgr, dssdev);
1069 if (r)
1070 return r;
1071
1072 r = omapdss_output_set_device(dssdev, dst);
1073 if (r) {
1074 DSSERR("failed to connect output to new device: %s\n",
1075 dst->name);
1076 dss_mgr_disconnect(mgr, dssdev);
1077 return r;
1078 }
1079
1080 return 0;
1081}
1082
1083static void hdmi_disconnect(struct omap_dss_device *dssdev,
1084 struct omap_dss_device *dst)
1085{
1086 WARN_ON(dst != dssdev->device);
1087
1088 if (dst != dssdev->device)
1089 return;
1090
1091 omapdss_output_unset_device(dssdev);
1092
1093 if (dssdev->manager)
1094 dss_mgr_disconnect(dssdev->manager, dssdev);
1095}
1096
1097static int hdmi_read_edid(struct omap_dss_device *dssdev,
1098 u8 *edid, int len)
1099{
1100 bool need_enable;
1101 int r;
1102
1103 need_enable = hdmi.core_enabled == false;
1104
1105 if (need_enable) {
1106 r = omapdss_hdmi_core_enable(dssdev);
1107 if (r)
1108 return r;
1109 }
1110
1111 r = omapdss_hdmi_read_edid(edid, len);
1112
1113 if (need_enable)
1114 omapdss_hdmi_core_disable(dssdev);
1115
1116 return r;
1117}
1118
1119#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO)
1120static int omapdss_hdmi_audio_enable(struct omap_dss_device *dssdev)
1121{
1122 int r;
1123
1124 mutex_lock(&hdmi.lock);
1125
1126 if (!hdmi_mode_has_audio()) {
1127 r = -EPERM;
1128 goto err;
1129 }
1130
1131 r = hdmi_audio_enable();
1132 if (r)
1133 goto err;
1134
1135 mutex_unlock(&hdmi.lock);
1136 return 0;
1137
1138err:
1139 mutex_unlock(&hdmi.lock);
1140 return r;
1141}
1142
1143static void omapdss_hdmi_audio_disable(struct omap_dss_device *dssdev)
1144{
1145 hdmi_audio_disable();
1146}
1147
1148static int omapdss_hdmi_audio_start(struct omap_dss_device *dssdev)
1149{
1150 return hdmi_audio_start();
1151}
1152
1153static void omapdss_hdmi_audio_stop(struct omap_dss_device *dssdev)
1154{
1155 hdmi_audio_stop();
1156}
1157
1158static bool omapdss_hdmi_audio_supported(struct omap_dss_device *dssdev)
1159{
1160 bool r;
1161
1162 mutex_lock(&hdmi.lock);
1163
1164 r = hdmi_mode_has_audio();
1165
1166 mutex_unlock(&hdmi.lock);
1167 return r;
1168}
1169
1170static int omapdss_hdmi_audio_config(struct omap_dss_device *dssdev,
1171 struct omap_dss_audio *audio)
1172{
1173 int r;
1174
1175 mutex_lock(&hdmi.lock);
1176
1177 if (!hdmi_mode_has_audio()) {
1178 r = -EPERM;
1179 goto err;
1180 }
1181
1182 r = hdmi_audio_config(audio);
1183 if (r)
1184 goto err;
1185
1186 mutex_unlock(&hdmi.lock);
1187 return 0;
1188
1189err:
1190 mutex_unlock(&hdmi.lock);
1191 return r;
1192}
1193#else
1194static int omapdss_hdmi_audio_enable(struct omap_dss_device *dssdev)
1195{
1196 return -EPERM;
1197}
1198
1199static void omapdss_hdmi_audio_disable(struct omap_dss_device *dssdev)
1200{
1201}
1202
1203static int omapdss_hdmi_audio_start(struct omap_dss_device *dssdev)
1204{
1205 return -EPERM;
1206}
1207
1208static void omapdss_hdmi_audio_stop(struct omap_dss_device *dssdev)
1209{
1210}
1211
1212static bool omapdss_hdmi_audio_supported(struct omap_dss_device *dssdev)
1213{
1214 return false;
1215}
1216
1217static int omapdss_hdmi_audio_config(struct omap_dss_device *dssdev,
1218 struct omap_dss_audio *audio)
1219{
1220 return -EPERM;
1221}
1222#endif
1223
1224static const struct omapdss_hdmi_ops hdmi_ops = {
1225 .connect = hdmi_connect,
1226 .disconnect = hdmi_disconnect,
1227
1228 .enable = omapdss_hdmi_display_enable,
1229 .disable = omapdss_hdmi_display_disable,
1230
1231 .check_timings = omapdss_hdmi_display_check_timing,
1232 .set_timings = omapdss_hdmi_display_set_timing,
1233 .get_timings = omapdss_hdmi_display_get_timings,
1234
1235 .read_edid = hdmi_read_edid,
1236
1237 .audio_enable = omapdss_hdmi_audio_enable,
1238 .audio_disable = omapdss_hdmi_audio_disable,
1239 .audio_start = omapdss_hdmi_audio_start,
1240 .audio_stop = omapdss_hdmi_audio_stop,
1241 .audio_supported = omapdss_hdmi_audio_supported,
1242 .audio_config = omapdss_hdmi_audio_config,
1243};
1244
1028static void hdmi_init_output(struct platform_device *pdev) 1245static void hdmi_init_output(struct platform_device *pdev)
1029{ 1246{
1030 struct omap_dss_device *out = &hdmi.output; 1247 struct omap_dss_device *out = &hdmi.output;
@@ -1034,6 +1251,7 @@ static void hdmi_init_output(struct platform_device *pdev)
1034 out->output_type = OMAP_DISPLAY_TYPE_HDMI; 1251 out->output_type = OMAP_DISPLAY_TYPE_HDMI;
1035 out->name = "hdmi.0"; 1252 out->name = "hdmi.0";
1036 out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT; 1253 out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT;
1254 out->ops.hdmi = &hdmi_ops;
1037 out->owner = THIS_MODULE; 1255 out->owner = THIS_MODULE;
1038 1256
1039 omapdss_register_output(out); 1257 omapdss_register_output(out);
@@ -1083,6 +1301,10 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev)
1083 hdmi.ip_data.pll_offset = HDMI_PLLCTRL; 1301 hdmi.ip_data.pll_offset = HDMI_PLLCTRL;
1084 hdmi.ip_data.phy_offset = HDMI_PHY; 1302 hdmi.ip_data.phy_offset = HDMI_PHY;
1085 1303
1304 hdmi.ct_cp_hpd_gpio = -1;
1305 hdmi.ls_oe_gpio = -1;
1306 hdmi.hpd_gpio = -1;
1307
1086 hdmi_init_output(pdev); 1308 hdmi_init_output(pdev);
1087 1309
1088 r = hdmi_panel_init(); 1310 r = hdmi_panel_init();