Lines Matching full:hdmi
12 #include <linux/hdmi.h>
159 static inline u8 hdmi_readb(struct inno_hdmi *hdmi, u16 offset) in hdmi_readb() argument
161 return readl_relaxed(hdmi->regs + (offset) * 0x04); in hdmi_readb()
164 static inline void hdmi_writeb(struct inno_hdmi *hdmi, u16 offset, u32 val) in hdmi_writeb() argument
166 writel_relaxed(val, hdmi->regs + (offset) * 0x04); in hdmi_writeb()
169 static inline void hdmi_modb(struct inno_hdmi *hdmi, u16 offset, in hdmi_modb() argument
172 u8 temp = hdmi_readb(hdmi, offset) & ~msk; in hdmi_modb()
175 hdmi_writeb(hdmi, offset, temp); in hdmi_modb()
178 static void inno_hdmi_i2c_init(struct inno_hdmi *hdmi) in inno_hdmi_i2c_init() argument
182 ddc_bus_freq = (hdmi->tmds_rate >> 2) / HDMI_SCL_RATE; in inno_hdmi_i2c_init()
184 hdmi_writeb(hdmi, DDC_BUS_FREQ_L, ddc_bus_freq & 0xFF); in inno_hdmi_i2c_init()
185 hdmi_writeb(hdmi, DDC_BUS_FREQ_H, (ddc_bus_freq >> 8) & 0xFF); in inno_hdmi_i2c_init()
188 hdmi_writeb(hdmi, HDMI_INTERRUPT_MASK1, 0); in inno_hdmi_i2c_init()
189 hdmi_writeb(hdmi, HDMI_INTERRUPT_STATUS1, m_INT_EDID_READY); in inno_hdmi_i2c_init()
192 static void inno_hdmi_sys_power(struct inno_hdmi *hdmi, bool enable) in inno_hdmi_sys_power() argument
195 hdmi_modb(hdmi, HDMI_SYS_CTRL, m_POWER, v_PWR_ON); in inno_hdmi_sys_power()
197 hdmi_modb(hdmi, HDMI_SYS_CTRL, m_POWER, v_PWR_OFF); in inno_hdmi_sys_power()
200 static void inno_hdmi_set_pwr_mode(struct inno_hdmi *hdmi, int mode) in inno_hdmi_set_pwr_mode() argument
204 inno_hdmi_sys_power(hdmi, false); in inno_hdmi_set_pwr_mode()
206 hdmi_writeb(hdmi, HDMI_PHY_PRE_EMPHASIS, 0x6f); in inno_hdmi_set_pwr_mode()
207 hdmi_writeb(hdmi, HDMI_PHY_DRIVER, 0xbb); in inno_hdmi_set_pwr_mode()
209 hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x15); in inno_hdmi_set_pwr_mode()
210 hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x14); in inno_hdmi_set_pwr_mode()
211 hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x10); in inno_hdmi_set_pwr_mode()
212 hdmi_writeb(hdmi, HDMI_PHY_CHG_PWR, 0x0f); in inno_hdmi_set_pwr_mode()
213 hdmi_writeb(hdmi, HDMI_PHY_SYNC, 0x00); in inno_hdmi_set_pwr_mode()
214 hdmi_writeb(hdmi, HDMI_PHY_SYNC, 0x01); in inno_hdmi_set_pwr_mode()
216 inno_hdmi_sys_power(hdmi, true); in inno_hdmi_set_pwr_mode()
220 inno_hdmi_sys_power(hdmi, false); in inno_hdmi_set_pwr_mode()
221 hdmi_writeb(hdmi, HDMI_PHY_DRIVER, 0x00); in inno_hdmi_set_pwr_mode()
222 hdmi_writeb(hdmi, HDMI_PHY_PRE_EMPHASIS, 0x00); in inno_hdmi_set_pwr_mode()
223 hdmi_writeb(hdmi, HDMI_PHY_CHG_PWR, 0x00); in inno_hdmi_set_pwr_mode()
224 hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x15); in inno_hdmi_set_pwr_mode()
229 DRM_DEV_ERROR(hdmi->dev, "Unknown power mode %d\n", mode); in inno_hdmi_set_pwr_mode()
233 static void inno_hdmi_reset(struct inno_hdmi *hdmi) in inno_hdmi_reset() argument
238 hdmi_modb(hdmi, HDMI_SYS_CTRL, m_RST_DIGITAL, v_NOT_RST_DIGITAL); in inno_hdmi_reset()
241 hdmi_modb(hdmi, HDMI_SYS_CTRL, m_RST_ANALOG, v_NOT_RST_ANALOG); in inno_hdmi_reset()
246 hdmi_modb(hdmi, HDMI_SYS_CTRL, msk, val); in inno_hdmi_reset()
248 inno_hdmi_set_pwr_mode(hdmi, NORMAL); in inno_hdmi_reset()
251 static int inno_hdmi_upload_frame(struct inno_hdmi *hdmi, int setup_rc, in inno_hdmi_upload_frame() argument
256 hdmi_modb(hdmi, HDMI_PACKET_SEND_AUTO, mask, disable); in inno_hdmi_upload_frame()
258 hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_BUF_INDEX, frame_index); in inno_hdmi_upload_frame()
270 hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_ADDR + i, in inno_hdmi_upload_frame()
274 hdmi_modb(hdmi, HDMI_PACKET_SEND_AUTO, mask, enable); in inno_hdmi_upload_frame()
280 static int inno_hdmi_config_video_vsi(struct inno_hdmi *hdmi, in inno_hdmi_config_video_vsi() argument
286 rc = drm_hdmi_vendor_infoframe_from_display_mode(&frame.vendor.hdmi, in inno_hdmi_config_video_vsi()
287 &hdmi->connector, in inno_hdmi_config_video_vsi()
290 return inno_hdmi_upload_frame(hdmi, rc, &frame, INFOFRAME_VSI, in inno_hdmi_config_video_vsi()
294 static int inno_hdmi_config_video_avi(struct inno_hdmi *hdmi, in inno_hdmi_config_video_avi() argument
301 &hdmi->connector, in inno_hdmi_config_video_avi()
304 if (hdmi->hdmi_data.enc_out_format == HDMI_COLORSPACE_YUV444) in inno_hdmi_config_video_avi()
306 else if (hdmi->hdmi_data.enc_out_format == HDMI_COLORSPACE_YUV422) in inno_hdmi_config_video_avi()
311 return inno_hdmi_upload_frame(hdmi, rc, &frame, INFOFRAME_AVI, 0, 0, 0); in inno_hdmi_config_video_avi()
314 static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi) in inno_hdmi_config_video_csc() argument
316 struct hdmi_data_info *data = &hdmi->hdmi_data; in inno_hdmi_config_video_csc()
325 hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL1, v_DE_EXTERNAL | in inno_hdmi_config_video_csc()
332 hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL2, value); in inno_hdmi_config_video_csc()
338 hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL3, value); in inno_hdmi_config_video_csc()
340 hdmi_modb(hdmi, HDMI_VIDEO_CONTRL, in inno_hdmi_config_video_csc()
379 hdmi_writeb(hdmi, HDMI_VIDEO_CSC_COEF + i, in inno_hdmi_config_video_csc()
383 hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL3, value); in inno_hdmi_config_video_csc()
384 hdmi_modb(hdmi, HDMI_VIDEO_CONTRL, m_VIDEO_AUTO_CSC | in inno_hdmi_config_video_csc()
391 static int inno_hdmi_config_video_timing(struct inno_hdmi *hdmi, in inno_hdmi_config_video_timing() argument
404 hdmi_writeb(hdmi, HDMI_VIDEO_TIMING_CTL, value); in inno_hdmi_config_video_timing()
408 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HTOTAL_L, value & 0xFF); in inno_hdmi_config_video_timing()
409 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HTOTAL_H, (value >> 8) & 0xFF); in inno_hdmi_config_video_timing()
412 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HBLANK_L, value & 0xFF); in inno_hdmi_config_video_timing()
413 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HBLANK_H, (value >> 8) & 0xFF); in inno_hdmi_config_video_timing()
416 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDELAY_L, value & 0xFF); in inno_hdmi_config_video_timing()
417 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDELAY_H, (value >> 8) & 0xFF); in inno_hdmi_config_video_timing()
420 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDURATION_L, value & 0xFF); in inno_hdmi_config_video_timing()
421 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDURATION_H, (value >> 8) & 0xFF); in inno_hdmi_config_video_timing()
424 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VTOTAL_L, value & 0xFF); in inno_hdmi_config_video_timing()
425 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VTOTAL_H, (value >> 8) & 0xFF); in inno_hdmi_config_video_timing()
428 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VBLANK, value & 0xFF); in inno_hdmi_config_video_timing()
431 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VDELAY, value & 0xFF); in inno_hdmi_config_video_timing()
434 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VDURATION, value & 0xFF); in inno_hdmi_config_video_timing()
436 hdmi_writeb(hdmi, HDMI_PHY_PRE_DIV_RATIO, 0x1e); in inno_hdmi_config_video_timing()
437 hdmi_writeb(hdmi, HDMI_PHY_FEEDBACK_DIV_RATIO_LOW, 0x2c); in inno_hdmi_config_video_timing()
438 hdmi_writeb(hdmi, HDMI_PHY_FEEDBACK_DIV_RATIO_HIGH, 0x01); in inno_hdmi_config_video_timing()
443 static int inno_hdmi_setup(struct inno_hdmi *hdmi, in inno_hdmi_setup() argument
446 struct drm_display_info *display = &hdmi->connector.display_info; in inno_hdmi_setup()
448 hdmi->hdmi_data.vic = drm_match_cea_mode(mode); in inno_hdmi_setup()
450 hdmi->hdmi_data.enc_in_format = HDMI_COLORSPACE_RGB; in inno_hdmi_setup()
451 hdmi->hdmi_data.enc_out_format = HDMI_COLORSPACE_RGB; in inno_hdmi_setup()
453 if ((hdmi->hdmi_data.vic == 6) || (hdmi->hdmi_data.vic == 7) || in inno_hdmi_setup()
454 (hdmi->hdmi_data.vic == 21) || (hdmi->hdmi_data.vic == 22) || in inno_hdmi_setup()
455 (hdmi->hdmi_data.vic == 2) || (hdmi->hdmi_data.vic == 3) || in inno_hdmi_setup()
456 (hdmi->hdmi_data.vic == 17) || (hdmi->hdmi_data.vic == 18)) in inno_hdmi_setup()
457 hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_601; in inno_hdmi_setup()
459 hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_709; in inno_hdmi_setup()
462 hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_VIDEO_BLACK, in inno_hdmi_setup()
465 /* Set HDMI Mode */ in inno_hdmi_setup()
466 hdmi_writeb(hdmi, HDMI_HDCP_CTRL, in inno_hdmi_setup()
469 inno_hdmi_config_video_timing(hdmi, mode); in inno_hdmi_setup()
471 inno_hdmi_config_video_csc(hdmi); in inno_hdmi_setup()
474 inno_hdmi_config_video_avi(hdmi, mode); in inno_hdmi_setup()
475 inno_hdmi_config_video_vsi(hdmi, mode); in inno_hdmi_setup()
484 hdmi->tmds_rate = mode->clock * 1000; in inno_hdmi_setup()
485 inno_hdmi_i2c_init(hdmi); in inno_hdmi_setup()
488 hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_VIDEO_BLACK, in inno_hdmi_setup()
498 struct inno_hdmi *hdmi = encoder_to_inno_hdmi(encoder); in inno_hdmi_encoder_mode_set() local
500 inno_hdmi_setup(hdmi, adj_mode); in inno_hdmi_encoder_mode_set()
503 drm_mode_copy(&hdmi->previous_mode, adj_mode); in inno_hdmi_encoder_mode_set()
508 struct inno_hdmi *hdmi = encoder_to_inno_hdmi(encoder); in inno_hdmi_encoder_enable() local
510 inno_hdmi_set_pwr_mode(hdmi, NORMAL); in inno_hdmi_encoder_enable()
515 struct inno_hdmi *hdmi = encoder_to_inno_hdmi(encoder); in inno_hdmi_encoder_disable() local
517 inno_hdmi_set_pwr_mode(hdmi, LOWER_PWR); in inno_hdmi_encoder_disable()
551 struct inno_hdmi *hdmi = connector_to_inno_hdmi(connector); in inno_hdmi_connector_detect() local
553 return (hdmi_readb(hdmi, HDMI_STATUS) & m_HOTPLUG) ? in inno_hdmi_connector_detect()
559 struct inno_hdmi *hdmi = connector_to_inno_hdmi(connector); in inno_hdmi_connector_get_modes() local
563 if (!hdmi->ddc) in inno_hdmi_connector_get_modes()
566 edid = drm_get_edid(connector, hdmi->ddc); in inno_hdmi_connector_get_modes()
568 hdmi->hdmi_data.sink_has_audio = drm_detect_monitor_audio(edid); in inno_hdmi_connector_get_modes()
611 static int inno_hdmi_register(struct drm_device *drm, struct inno_hdmi *hdmi) in inno_hdmi_register() argument
613 struct drm_encoder *encoder = &hdmi->encoder.encoder; in inno_hdmi_register()
614 struct device *dev = hdmi->dev; in inno_hdmi_register()
630 hdmi->connector.polled = DRM_CONNECTOR_POLL_HPD; in inno_hdmi_register()
632 drm_connector_helper_add(&hdmi->connector, in inno_hdmi_register()
634 drm_connector_init_with_ddc(drm, &hdmi->connector, in inno_hdmi_register()
637 hdmi->ddc); in inno_hdmi_register()
639 drm_connector_attach_encoder(&hdmi->connector, encoder); in inno_hdmi_register()
644 static irqreturn_t inno_hdmi_i2c_irq(struct inno_hdmi *hdmi) in inno_hdmi_i2c_irq() argument
646 struct inno_hdmi_i2c *i2c = hdmi->i2c; in inno_hdmi_i2c_irq()
649 stat = hdmi_readb(hdmi, HDMI_INTERRUPT_STATUS1); in inno_hdmi_i2c_irq()
653 /* Clear HDMI EDID interrupt flag */ in inno_hdmi_i2c_irq()
654 hdmi_writeb(hdmi, HDMI_INTERRUPT_STATUS1, m_INT_EDID_READY); in inno_hdmi_i2c_irq()
663 struct inno_hdmi *hdmi = dev_id; in inno_hdmi_hardirq() local
667 if (hdmi->i2c) in inno_hdmi_hardirq()
668 ret = inno_hdmi_i2c_irq(hdmi); in inno_hdmi_hardirq()
670 interrupt = hdmi_readb(hdmi, HDMI_STATUS); in inno_hdmi_hardirq()
672 hdmi_modb(hdmi, HDMI_STATUS, m_INT_HOTPLUG, m_INT_HOTPLUG); in inno_hdmi_hardirq()
681 struct inno_hdmi *hdmi = dev_id; in inno_hdmi_irq() local
683 drm_helper_hpd_irq_event(hdmi->connector.dev); in inno_hdmi_irq()
688 static int inno_hdmi_i2c_read(struct inno_hdmi *hdmi, struct i2c_msg *msgs) in inno_hdmi_i2c_read() argument
694 ret = wait_for_completion_timeout(&hdmi->i2c->cmp, HZ / 10); in inno_hdmi_i2c_read()
699 *buf++ = hdmi_readb(hdmi, HDMI_EDID_FIFO_ADDR); in inno_hdmi_i2c_read()
704 static int inno_hdmi_i2c_write(struct inno_hdmi *hdmi, struct i2c_msg *msgs) in inno_hdmi_i2c_write() argument
715 reinit_completion(&hdmi->i2c->cmp); in inno_hdmi_i2c_write()
718 hdmi->i2c->segment_addr = msgs->buf[0]; in inno_hdmi_i2c_write()
720 hdmi->i2c->ddc_addr = msgs->buf[0]; in inno_hdmi_i2c_write()
723 hdmi_writeb(hdmi, HDMI_EDID_FIFO_OFFSET, 0x00); in inno_hdmi_i2c_write()
726 hdmi_writeb(hdmi, HDMI_EDID_WORD_ADDR, hdmi->i2c->ddc_addr); in inno_hdmi_i2c_write()
729 hdmi_writeb(hdmi, HDMI_EDID_SEGMENT_POINTER, hdmi->i2c->segment_addr); in inno_hdmi_i2c_write()
737 struct inno_hdmi *hdmi = i2c_get_adapdata(adap); in inno_hdmi_i2c_xfer() local
738 struct inno_hdmi_i2c *i2c = hdmi->i2c; in inno_hdmi_i2c_xfer()
744 hdmi_writeb(hdmi, HDMI_INTERRUPT_MASK1, m_INT_EDID_READY); in inno_hdmi_i2c_xfer()
745 hdmi_writeb(hdmi, HDMI_INTERRUPT_STATUS1, m_INT_EDID_READY); in inno_hdmi_i2c_xfer()
748 DRM_DEV_DEBUG(hdmi->dev, in inno_hdmi_i2c_xfer()
753 ret = inno_hdmi_i2c_read(hdmi, &msgs[i]); in inno_hdmi_i2c_xfer()
755 ret = inno_hdmi_i2c_write(hdmi, &msgs[i]); in inno_hdmi_i2c_xfer()
764 /* Mute HDMI EDID interrupt */ in inno_hdmi_i2c_xfer()
765 hdmi_writeb(hdmi, HDMI_INTERRUPT_MASK1, 0); in inno_hdmi_i2c_xfer()
782 static struct i2c_adapter *inno_hdmi_i2c_adapter(struct inno_hdmi *hdmi) in inno_hdmi_i2c_adapter() argument
788 i2c = devm_kzalloc(hdmi->dev, sizeof(*i2c), GFP_KERNEL); in inno_hdmi_i2c_adapter()
798 adap->dev.parent = hdmi->dev; in inno_hdmi_i2c_adapter()
799 adap->dev.of_node = hdmi->dev->of_node; in inno_hdmi_i2c_adapter()
801 strscpy(adap->name, "Inno HDMI", sizeof(adap->name)); in inno_hdmi_i2c_adapter()
802 i2c_set_adapdata(adap, hdmi); in inno_hdmi_i2c_adapter()
806 dev_warn(hdmi->dev, "cannot add %s I2C adapter\n", adap->name); in inno_hdmi_i2c_adapter()
807 devm_kfree(hdmi->dev, i2c); in inno_hdmi_i2c_adapter()
811 hdmi->i2c = i2c; in inno_hdmi_i2c_adapter()
813 DRM_DEV_INFO(hdmi->dev, "registered %s I2C bus driver\n", adap->name); in inno_hdmi_i2c_adapter()
823 struct inno_hdmi *hdmi; in inno_hdmi_bind() local
827 hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL); in inno_hdmi_bind()
828 if (!hdmi) in inno_hdmi_bind()
831 hdmi->dev = dev; in inno_hdmi_bind()
832 hdmi->drm_dev = drm; in inno_hdmi_bind()
834 hdmi->regs = devm_platform_ioremap_resource(pdev, 0); in inno_hdmi_bind()
835 if (IS_ERR(hdmi->regs)) in inno_hdmi_bind()
836 return PTR_ERR(hdmi->regs); in inno_hdmi_bind()
838 hdmi->pclk = devm_clk_get(hdmi->dev, "pclk"); in inno_hdmi_bind()
839 if (IS_ERR(hdmi->pclk)) { in inno_hdmi_bind()
840 DRM_DEV_ERROR(hdmi->dev, "Unable to get HDMI pclk clk\n"); in inno_hdmi_bind()
841 return PTR_ERR(hdmi->pclk); in inno_hdmi_bind()
844 ret = clk_prepare_enable(hdmi->pclk); in inno_hdmi_bind()
846 DRM_DEV_ERROR(hdmi->dev, in inno_hdmi_bind()
847 "Cannot enable HDMI pclk clock: %d\n", ret); in inno_hdmi_bind()
857 inno_hdmi_reset(hdmi); in inno_hdmi_bind()
859 hdmi->ddc = inno_hdmi_i2c_adapter(hdmi); in inno_hdmi_bind()
860 if (IS_ERR(hdmi->ddc)) { in inno_hdmi_bind()
861 ret = PTR_ERR(hdmi->ddc); in inno_hdmi_bind()
862 hdmi->ddc = NULL; in inno_hdmi_bind()
872 hdmi->tmds_rate = clk_get_rate(hdmi->pclk); in inno_hdmi_bind()
873 inno_hdmi_i2c_init(hdmi); in inno_hdmi_bind()
875 ret = inno_hdmi_register(drm, hdmi); in inno_hdmi_bind()
879 dev_set_drvdata(dev, hdmi); in inno_hdmi_bind()
882 hdmi_modb(hdmi, HDMI_STATUS, m_MASK_INT_HOTPLUG, v_MASK_INT_HOTPLUG(1)); in inno_hdmi_bind()
886 dev_name(dev), hdmi); in inno_hdmi_bind()
892 hdmi->connector.funcs->destroy(&hdmi->connector); in inno_hdmi_bind()
893 hdmi->encoder.encoder.funcs->destroy(&hdmi->encoder.encoder); in inno_hdmi_bind()
895 i2c_put_adapter(hdmi->ddc); in inno_hdmi_bind()
897 clk_disable_unprepare(hdmi->pclk); in inno_hdmi_bind()
904 struct inno_hdmi *hdmi = dev_get_drvdata(dev); in inno_hdmi_unbind() local
906 hdmi->connector.funcs->destroy(&hdmi->connector); in inno_hdmi_unbind()
907 hdmi->encoder.encoder.funcs->destroy(&hdmi->encoder.encoder); in inno_hdmi_unbind()
909 i2c_put_adapter(hdmi->ddc); in inno_hdmi_unbind()
910 clk_disable_unprepare(hdmi->pclk); in inno_hdmi_unbind()
929 { .compatible = "rockchip,rk3036-inno-hdmi",