Lines Matching +full:hdmi +full:- +full:bridge

1 // SPDX-License-Identifier: GPL-2.0
10 #include <linux/hdmi.h>
26 #include <sound/hdmi-codec.h>
96 #define HDMI_IFRAME_CFG_DI_N(x, n) ((x) << ((n-1)*4)) /* n from 1 to 6 */
164 struct sti_hdmi *hdmi;
171 static struct sti_hdmi *drm_bridge_to_sti_hdmi(struct drm_bridge *bridge)
173 return container_of(bridge, struct sti_hdmi, bridge);
182 u32 hdmi_read(struct sti_hdmi *hdmi, int offset)
184 return readl(hdmi->regs + offset);
187 void hdmi_write(struct sti_hdmi *hdmi, u32 val, int offset)
189 writel(val, hdmi->regs + offset);
193 * HDMI interrupt handler threaded
200 struct sti_hdmi *hdmi = arg;
203 if (hdmi->irq_status & HDMI_INT_HOT_PLUG) {
204 hdmi->hpd = readl(hdmi->regs + HDMI_STA) & HDMI_STA_HOT_PLUG;
205 if (hdmi->drm_dev)
206 drm_helper_hpd_irq_event(hdmi->drm_dev);
212 if (hdmi->irq_status & (HDMI_INT_SW_RST | HDMI_INT_DLL_LCK)) {
213 hdmi->event_received = true;
214 wake_up_interruptible(&hdmi->wait_event);
218 if (hdmi->irq_status & HDMI_INT_AUDIO_FIFO_XRUN)
225 * HDMI interrupt handler
232 struct sti_hdmi *hdmi = arg;
235 hdmi->irq_status = hdmi_read(hdmi, HDMI_INT_STA);
238 hdmi_write(hdmi, hdmi->irq_status, HDMI_INT_CLR);
241 hdmi_read(hdmi, HDMI_INT_STA);
247 * Set hdmi active area depending on the drm display mode selected
249 * @hdmi: pointer on the hdmi internal structure
251 static void hdmi_active_area(struct sti_hdmi *hdmi)
256 xmin = sti_vtg_get_pixel_number(hdmi->mode, 1);
257 xmax = sti_vtg_get_pixel_number(hdmi->mode, hdmi->mode.hdisplay);
258 ymin = sti_vtg_get_line_number(hdmi->mode, 0);
259 ymax = sti_vtg_get_line_number(hdmi->mode, hdmi->mode.vdisplay - 1);
261 hdmi_write(hdmi, xmin, HDMI_ACTIVE_VID_XMIN);
262 hdmi_write(hdmi, xmax, HDMI_ACTIVE_VID_XMAX);
263 hdmi_write(hdmi, ymin, HDMI_ACTIVE_VID_YMIN);
264 hdmi_write(hdmi, ymax, HDMI_ACTIVE_VID_YMAX);
268 * Overall hdmi configuration
270 * @hdmi: pointer on the hdmi internal structure
272 static void hdmi_config(struct sti_hdmi *hdmi)
274 struct drm_connector *connector = hdmi->drm_connector;
284 if (connector->display_info.is_hdmi)
288 if (hdmi->mode.flags & DRM_MODE_FLAG_NHSYNC) {
294 if (hdmi->mode.flags & DRM_MODE_FLAG_NVSYNC) {
299 /* Enable HDMI */
302 hdmi_write(hdmi, conf, HDMI_CFG);
308 * @hdmi: pointer on the hdmi internal structure
311 static void hdmi_infoframe_reset(struct sti_hdmi *hdmi,
336 val = hdmi_read(hdmi, HDMI_SW_DI_CFG);
338 hdmi_write(hdmi, val, HDMI_SW_DI_CFG);
341 hdmi_write(hdmi, 0x0, head_offset);
343 hdmi_write(hdmi, 0x0, pack_offset + i);
349 * @ptr: pointer on the hdmi internal structure
357 for (i = size; i > 0; i--)
358 value = (value << 8) | ptr[i - 1];
366 * @hdmi: pointer on the hdmi internal structure
370 static void hdmi_infoframe_write_infopack(struct sti_hdmi *hdmi,
403 val = hdmi_read(hdmi, HDMI_SW_DI_CFG);
405 hdmi_write(hdmi, val, HDMI_SW_DI_CFG);
410 writel(val, hdmi->regs + head_offset);
417 size = size - HDMI_INFOFRAME_HEADER_SIZE + 1;
421 num = min_t(size_t, size - i, sizeof(u32));
424 writel(val, hdmi->regs + pack_offset + i);
428 val = hdmi_read(hdmi, HDMI_SW_DI_CFG);
430 hdmi_write(hdmi, val, HDMI_SW_DI_CFG);
437 * contains information about HDMI transmission mode such as color space,
440 * @hdmi: pointer on the hdmi internal structure
444 static int hdmi_avi_infoframe_config(struct sti_hdmi *hdmi)
446 struct drm_display_mode *mode = &hdmi->mode;
454 hdmi->drm_connector, mode);
461 infoframe.colorspace = hdmi->colorspace;
471 hdmi_infoframe_write_infopack(hdmi, buffer, ret);
480 * contains information about HDMI transmission mode such as audio codec,
483 * @hdmi: pointer on the hdmi internal structure
487 static int hdmi_audio_infoframe_config(struct sti_hdmi *hdmi)
489 struct hdmi_audio_params *audio = &hdmi->audio;
494 audio->enabled ? "enable" : "disable");
495 if (audio->enabled) {
497 ret = hdmi_audio_infoframe_pack(&audio->cea, buffer,
503 hdmi_infoframe_write_infopack(hdmi, buffer, ret);
506 val = hdmi_read(hdmi, HDMI_SW_DI_CFG);
509 hdmi_write(hdmi, val, HDMI_SW_DI_CFG);
521 * @hdmi: pointer on the hdmi internal structure
526 static int hdmi_vendor_infoframe_config(struct sti_hdmi *hdmi)
528 struct drm_display_mode *mode = &hdmi->mode;
536 hdmi->drm_connector,
554 hdmi_infoframe_write_infopack(hdmi, buffer, ret);
562 * Software reset of the hdmi subsystem
564 * @hdmi: pointer on the hdmi internal structure
567 static void hdmi_swreset(struct sti_hdmi *hdmi)
573 /* Enable hdmi_audio clock only during hdmi reset */
574 if (clk_prepare_enable(hdmi->clk_audio))
578 hdmi->event_received = false;
580 val = hdmi_read(hdmi, HDMI_CFG);
582 hdmi_write(hdmi, val, HDMI_CFG);
585 wait_event_interruptible_timeout(hdmi->wait_event,
586 hdmi->event_received,
594 if ((hdmi_read(hdmi, HDMI_STA) & HDMI_STA_SW_RST) == 0)
595 DRM_DEBUG_DRIVER("Warning: HDMI sw reset timeout occurs\n");
597 val = hdmi_read(hdmi, HDMI_CFG);
599 hdmi_write(hdmi, val, HDMI_CFG);
602 clk_disable_unprepare(hdmi->clk_audio);
605 #define DBGFS_PRINT_STR(str1, str2) seq_printf(s, "%-24s %s\n", str1, str2)
606 #define DBGFS_PRINT_INT(str1, int2) seq_printf(s, "%-24s %d\n", str1, int2)
607 #define DBGFS_DUMP(str, reg) seq_printf(s, "%s %-25s 0x%08X", str, #reg, \
608 hdmi_read(hdmi, reg))
617 DBGFS_PRINT_STR("mode:", tmp ? "HDMI" : "DVI");
644 DBGFS_PRINT_STR("hdmi cable:", tmp ? "connected" : "not connected");
677 struct drm_info_node *node = s->private;
678 struct sti_hdmi *hdmi = (struct sti_hdmi *)node->info_ent->data;
680 seq_printf(s, "HDMI: (vaddr = 0x%p)", hdmi->regs);
682 hdmi_dbg_cfg(s, hdmi_read(hdmi, HDMI_CFG));
685 hdmi_dbg_sta(s, hdmi_read(hdmi, HDMI_STA));
688 DBGFS_PRINT_INT("Xmin:", hdmi_read(hdmi, HDMI_ACTIVE_VID_XMIN));
691 DBGFS_PRINT_INT("Xmax:", hdmi_read(hdmi, HDMI_ACTIVE_VID_XMAX));
694 DBGFS_PRINT_INT("Ymin:", hdmi_read(hdmi, HDMI_ACTIVE_VID_YMIN));
697 DBGFS_PRINT_INT("Ymax:", hdmi_read(hdmi, HDMI_ACTIVE_VID_YMAX));
699 hdmi_dbg_sw_di_cfg(s, hdmi_read(hdmi, HDMI_SW_DI_CFG));
740 { "hdmi", hdmi_dbg_show, 0, NULL },
743 static void hdmi_debugfs_init(struct sti_hdmi *hdmi, struct drm_minor *minor)
748 hdmi_debugfs_files[i].data = hdmi;
752 minor->debugfs_root, minor);
755 static void sti_hdmi_disable(struct drm_bridge *bridge)
757 struct sti_hdmi *hdmi = drm_bridge_to_sti_hdmi(bridge);
759 u32 val = hdmi_read(hdmi, HDMI_CFG);
761 if (!hdmi->enabled)
766 /* Disable HDMI */
768 hdmi_write(hdmi, val, HDMI_CFG);
770 hdmi_write(hdmi, 0xffffffff, HDMI_INT_CLR);
773 hdmi->phy_ops->stop(hdmi);
776 hdmi_infoframe_reset(hdmi, HDMI_IFRAME_SLOT_AVI);
777 hdmi_infoframe_reset(hdmi, HDMI_IFRAME_SLOT_AUDIO);
778 hdmi_infoframe_reset(hdmi, HDMI_IFRAME_SLOT_VENDOR);
781 hdmi_write(hdmi, 0x0000, HDMI_DFLT_CHL0_DAT);
782 hdmi_write(hdmi, 0x0000, HDMI_DFLT_CHL1_DAT);
783 hdmi_write(hdmi, 0x0060, HDMI_DFLT_CHL2_DAT);
785 /* Disable/unprepare hdmi clock */
786 clk_disable_unprepare(hdmi->clk_phy);
787 clk_disable_unprepare(hdmi->clk_tmds);
788 clk_disable_unprepare(hdmi->clk_pix);
790 hdmi->enabled = false;
792 cec_notifier_set_phys_addr(hdmi->notifier, CEC_PHYS_ADDR_INVALID);
796 * sti_hdmi_audio_get_non_coherent_n() - get N parameter for non-coherent
797 * clocks. None-coherent clocks means that audio and TMDS clocks have not the
803 * Values computed are based on table described in HDMI specification 1.4b
834 /* Not pre-defined, recommended value: 128 * fs / 1000 */
841 static int hdmi_audio_configure(struct sti_hdmi *hdmi)
844 struct hdmi_audio_params *params = &hdmi->audio;
845 struct hdmi_audio_infoframe *info = &params->cea;
849 if (!hdmi->enabled)
853 n = sti_hdmi_audio_get_non_coherent_n(params->sample_rate);
856 params->sample_rate, hdmi->mode.clock * 1000, n);
857 hdmi_write(hdmi, n, HDMI_AUDN);
859 /* update HDMI registers according to configuration */
863 switch (info->channels) {
878 info->channels);
879 return -EINVAL;
882 hdmi_write(hdmi, audio_cfg, HDMI_AUDIO_CFG);
884 return hdmi_audio_infoframe_config(hdmi);
887 static void sti_hdmi_pre_enable(struct drm_bridge *bridge)
889 struct sti_hdmi *hdmi = drm_bridge_to_sti_hdmi(bridge);
893 if (hdmi->enabled)
897 if (clk_prepare_enable(hdmi->clk_pix))
899 if (clk_prepare_enable(hdmi->clk_tmds))
901 if (clk_prepare_enable(hdmi->clk_phy))
904 hdmi->enabled = true;
906 /* Program hdmi serializer and start phy */
907 if (!hdmi->phy_ops->start(hdmi)) {
908 DRM_ERROR("Unable to start hdmi phy\n");
912 /* Program hdmi active area */
913 hdmi_active_area(hdmi);
916 hdmi_write(hdmi, HDMI_WORKING_INT, HDMI_INT_EN);
918 /* Program hdmi config */
919 hdmi_config(hdmi);
922 if (hdmi_avi_infoframe_config(hdmi))
925 if (hdmi->audio.enabled) {
926 if (hdmi_audio_configure(hdmi))
929 hdmi_audio_infoframe_config(hdmi);
933 if (hdmi_vendor_infoframe_config(hdmi))
937 hdmi_swreset(hdmi);
940 static void sti_hdmi_set_mode(struct drm_bridge *bridge,
944 struct sti_hdmi *hdmi = drm_bridge_to_sti_hdmi(bridge);
950 drm_mode_copy(&hdmi->mode, mode);
953 ret = clk_set_rate(hdmi->clk_pix, mode->clock * 1000);
956 mode->clock * 1000);
959 ret = clk_set_rate(hdmi->clk_phy, mode->clock * 1000);
962 mode->clock * 1000);
967 static void sti_hdmi_bridge_nope(struct drm_bridge *bridge)
982 const struct drm_display_info *info = &connector->display_info;
985 struct sti_hdmi *hdmi = hdmi_connector->hdmi;
995 cec_notifier_set_phys_addr(hdmi->notifier,
996 connector->display_info.source_physical_address);
1004 info->is_hdmi ? "hdmi monitor" : "dvi monitor",
1005 info->width_mm / 10, info->height_mm / 10);
1011 DRM_ERROR("Can't read HDMI EDID\n");
1021 int target = mode->clock * 1000;
1022 int target_min = target - CLK_TOLERANCE_HZ;
1027 struct sti_hdmi *hdmi = hdmi_connector->hdmi;
1030 result = clk_round_rate(hdmi->clk_pix, target);
1036 DRM_DEBUG_DRIVER("hdmi pixclk=%d not supported\n", target);
1055 struct sti_hdmi *hdmi = hdmi_connector->hdmi;
1059 if (hdmi->hpd) {
1060 DRM_DEBUG_DRIVER("hdmi cable connected\n");
1064 DRM_DEBUG_DRIVER("hdmi cable disconnected\n");
1065 cec_notifier_set_phys_addr(hdmi->notifier, CEC_PHYS_ADDR_INVALID);
1074 struct sti_hdmi *hdmi = hdmi_connector->hdmi;
1078 hdmi->colorspace = DEFAULT_COLORSPACE_MODE;
1086 hdmi_connector->colorspace_property = prop;
1087 drm_object_attach_property(&connector->base, prop, hdmi->colorspace);
1098 struct sti_hdmi *hdmi = hdmi_connector->hdmi;
1100 if (property == hdmi_connector->colorspace_property) {
1101 hdmi->colorspace = val;
1105 DRM_ERROR("failed to set hdmi connector property\n");
1106 return -EINVAL;
1117 struct sti_hdmi *hdmi = hdmi_connector->hdmi;
1119 if (property == hdmi_connector->colorspace_property) {
1120 *val = hdmi->colorspace;
1124 DRM_ERROR("failed to get hdmi connector property\n");
1125 return -EINVAL;
1132 struct sti_hdmi *hdmi = hdmi_connector->hdmi;
1134 hdmi_debugfs_init(hdmi, hdmi->drm_dev->primary);
1155 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
1156 if (encoder->encoder_type == DRM_MODE_ENCODER_TMDS)
1165 struct sti_hdmi *hdmi = dev_get_drvdata(dev);
1173 hdmi_write(hdmi, audio_cfg, HDMI_AUDIO_CFG);
1175 hdmi->audio.enabled = false;
1176 hdmi_audio_infoframe_config(hdmi);
1184 struct sti_hdmi *hdmi = dev_get_drvdata(dev);
1189 if ((daifmt->fmt != HDMI_I2S) || daifmt->bit_clk_inv ||
1190 daifmt->frame_clk_inv || daifmt->bit_clk_provider ||
1191 daifmt->frame_clk_provider) {
1193 daifmt->bit_clk_inv, daifmt->frame_clk_inv,
1194 daifmt->bit_clk_provider,
1195 daifmt->frame_clk_provider);
1196 return -EINVAL;
1199 hdmi->audio.sample_width = params->sample_width;
1200 hdmi->audio.sample_rate = params->sample_rate;
1201 hdmi->audio.cea = params->cea;
1203 hdmi->audio.enabled = true;
1205 ret = hdmi_audio_configure(hdmi);
1215 struct sti_hdmi *hdmi = dev_get_drvdata(dev);
1220 hdmi_write(hdmi, HDMI_SAMPLE_FLAT_ALL, HDMI_SAMPLE_FLAT_MASK);
1222 hdmi_write(hdmi, HDMI_SAMPLE_FLAT_NO, HDMI_SAMPLE_FLAT_MASK);
1229 struct sti_hdmi *hdmi = dev_get_drvdata(dev);
1230 struct drm_connector *connector = hdmi->drm_connector;
1233 mutex_lock(&connector->eld_mutex);
1234 memcpy(buf, connector->eld, min(sizeof(connector->eld), len));
1235 mutex_unlock(&connector->eld_mutex);
1248 struct sti_hdmi *hdmi)
1259 hdmi->audio.enabled = false;
1261 hdmi->audio_pdev = platform_device_register_data(
1265 if (IS_ERR(hdmi->audio_pdev))
1266 return PTR_ERR(hdmi->audio_pdev);
1275 struct sti_hdmi *hdmi = dev_get_drvdata(dev);
1284 hdmi->drm_dev = drm_dev;
1288 return -EINVAL;
1292 return -EINVAL;
1294 connector->hdmi = hdmi;
1296 drm_bridge_attach(encoder, &hdmi->bridge, NULL, 0);
1298 connector->encoder = encoder;
1302 drm_connector->polled = DRM_CONNECTOR_POLL_HPD;
1307 hdmi->ddc_adapt);
1314 hdmi->drm_connector = drm_connector;
1322 err = sti_hdmi_register_audio_driver(dev, hdmi);
1329 err = hdmi_audio_infoframe_init(&hdmi->audio.cea);
1336 hdmi->notifier = cec_notifier_conn_register(&hdmi->dev, NULL,
1338 if (!hdmi->notifier) {
1339 hdmi->drm_connector = NULL;
1340 return -ENOMEM;
1344 hdmi_write(hdmi, HDMI_DEFAULT_INT, HDMI_INT_EN);
1349 hdmi->drm_connector = NULL;
1350 return -EINVAL;
1356 struct sti_hdmi *hdmi = dev_get_drvdata(dev);
1358 cec_notifier_conn_unregister(hdmi->notifier);
1368 .compatible = "st,stih407-hdmi",
1378 struct device *dev = &pdev->dev;
1379 struct sti_hdmi *hdmi;
1380 struct device_node *np = dev->of_node;
1386 hdmi = devm_drm_bridge_alloc(dev, struct sti_hdmi, bridge, &sti_hdmi_bridge_funcs);
1387 if (IS_ERR(hdmi))
1388 return PTR_ERR(hdmi);
1390 ddc = of_parse_phandle(pdev->dev.of_node, "ddc", 0);
1392 hdmi->ddc_adapt = of_get_i2c_adapter_by_node(ddc);
1394 if (!hdmi->ddc_adapt)
1395 return -EPROBE_DEFER;
1398 hdmi->dev = pdev->dev;
1399 hdmi->regs = devm_platform_ioremap_resource_byname(pdev, "hdmi-reg");
1400 if (IS_ERR(hdmi->regs)) {
1401 ret = PTR_ERR(hdmi->regs);
1405 hdmi->phy_ops = (struct hdmi_phy_ops *)
1406 of_match_node(hdmi_of_match, np)->data;
1409 hdmi->clk_pix = devm_clk_get(dev, "pix");
1410 if (IS_ERR(hdmi->clk_pix)) {
1412 ret = PTR_ERR(hdmi->clk_pix);
1416 hdmi->clk_tmds = devm_clk_get(dev, "tmds");
1417 if (IS_ERR(hdmi->clk_tmds)) {
1419 ret = PTR_ERR(hdmi->clk_tmds);
1423 hdmi->clk_phy = devm_clk_get(dev, "phy");
1424 if (IS_ERR(hdmi->clk_phy)) {
1426 ret = PTR_ERR(hdmi->clk_phy);
1430 hdmi->clk_audio = devm_clk_get(dev, "audio");
1431 if (IS_ERR(hdmi->clk_audio)) {
1433 ret = PTR_ERR(hdmi->clk_audio);
1437 hdmi->hpd = readl(hdmi->regs + HDMI_STA) & HDMI_STA_HOT_PLUG;
1439 init_waitqueue_head(&hdmi->wait_event);
1441 hdmi->irq = platform_get_irq_byname(pdev, "irq");
1442 if (hdmi->irq < 0) {
1443 DRM_ERROR("Cannot get HDMI irq\n");
1444 ret = hdmi->irq;
1448 ret = devm_request_threaded_irq(dev, hdmi->irq, hdmi_irq,
1449 hdmi_irq_thread, IRQF_ONESHOT, dev_name(dev), hdmi);
1451 DRM_ERROR("Failed to register HDMI interrupt\n");
1455 hdmi->reset = devm_reset_control_get(dev, "hdmi");
1456 /* Take hdmi out of reset */
1457 if (!IS_ERR(hdmi->reset))
1458 reset_control_deassert(hdmi->reset);
1460 platform_set_drvdata(pdev, hdmi);
1462 return component_add(&pdev->dev, &sti_hdmi_ops);
1465 i2c_put_adapter(hdmi->ddc_adapt);
1472 struct sti_hdmi *hdmi = dev_get_drvdata(&pdev->dev);
1474 i2c_put_adapter(hdmi->ddc_adapt);
1475 if (hdmi->audio_pdev)
1476 platform_device_unregister(hdmi->audio_pdev);
1477 component_del(&pdev->dev, &sti_hdmi_ops);
1482 .name = "sti-hdmi",