Lines Matching +full:hdmi +full:- +full:connector

1 // SPDX-License-Identifier: GPL-2.0-only
4 * Zheng Yang <zhengyang@rock-chips.com>
5 * Yakir Yang <ykk@rock-chips.com>
12 #include <linux/hdmi.h>
58 struct drm_connector connector; member
82 * R = 1.164*Y + 1.596*V - 204
83 * G = 1.164*Y - 0.391*U - 0.813*V + 154
84 * B = 1.164*Y + 2.018*U - 258
93 * R = Y + 1.402*V - 248
94 * G = Y - 0.344*U - 0.714*V + 135
95 * B = Y + 1.772*U - 227
104 * R = 1.164*Y + 1.793*V - 248
105 * G = 1.164*Y - 0.213*U - 0.534*V + 77
106 * B = 1.164*Y + 2.115*U - 289
116 * Cb = -0.291G - 0.148R + 0.439B + 128
118 * Cr = -0.368G + 0.439R - 0.071B + 128
127 * Cb = - 0.338G - 0.101R + 0.439B + 128
129 * Cr = - 0.399G + 0.439R - 0.040B + 128
138 * R' = R x (235-16)/255 + 16;
139 * G' = G x (235-16)/255 + 16;
140 * B' = B x (235-16)/255 + 16;
149 static inline u8 hdmi_readb(struct inno_hdmi *hdmi, u16 offset) in hdmi_readb() argument
151 return readl_relaxed(hdmi->regs + (offset) * 0x04); in hdmi_readb()
154 static inline void hdmi_writeb(struct inno_hdmi *hdmi, u16 offset, u32 val) in hdmi_writeb() argument
156 writel_relaxed(val, hdmi->regs + (offset) * 0x04); in hdmi_writeb()
159 static inline void hdmi_modb(struct inno_hdmi *hdmi, u16 offset, in hdmi_modb() argument
162 u8 temp = hdmi_readb(hdmi, offset) & ~msk; in hdmi_modb()
165 hdmi_writeb(hdmi, offset, temp); in hdmi_modb()
168 static void inno_hdmi_i2c_init(struct inno_hdmi *hdmi) in inno_hdmi_i2c_init() argument
172 ddc_bus_freq = (hdmi->tmds_rate >> 2) / HDMI_SCL_RATE; in inno_hdmi_i2c_init()
174 hdmi_writeb(hdmi, DDC_BUS_FREQ_L, ddc_bus_freq & 0xFF); in inno_hdmi_i2c_init()
175 hdmi_writeb(hdmi, DDC_BUS_FREQ_H, (ddc_bus_freq >> 8) & 0xFF); in inno_hdmi_i2c_init()
178 hdmi_writeb(hdmi, HDMI_INTERRUPT_MASK1, 0); in inno_hdmi_i2c_init()
179 hdmi_writeb(hdmi, HDMI_INTERRUPT_STATUS1, m_INT_EDID_READY); in inno_hdmi_i2c_init()
182 static void inno_hdmi_sys_power(struct inno_hdmi *hdmi, bool enable) in inno_hdmi_sys_power() argument
185 hdmi_modb(hdmi, HDMI_SYS_CTRL, m_POWER, v_PWR_ON); in inno_hdmi_sys_power()
187 hdmi_modb(hdmi, HDMI_SYS_CTRL, m_POWER, v_PWR_OFF); in inno_hdmi_sys_power()
190 static void inno_hdmi_set_pwr_mode(struct inno_hdmi *hdmi, int mode) in inno_hdmi_set_pwr_mode() argument
194 inno_hdmi_sys_power(hdmi, false); in inno_hdmi_set_pwr_mode()
196 hdmi_writeb(hdmi, HDMI_PHY_PRE_EMPHASIS, 0x6f); in inno_hdmi_set_pwr_mode()
197 hdmi_writeb(hdmi, HDMI_PHY_DRIVER, 0xbb); in inno_hdmi_set_pwr_mode()
199 hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x15); in inno_hdmi_set_pwr_mode()
200 hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x14); in inno_hdmi_set_pwr_mode()
201 hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x10); in inno_hdmi_set_pwr_mode()
202 hdmi_writeb(hdmi, HDMI_PHY_CHG_PWR, 0x0f); in inno_hdmi_set_pwr_mode()
203 hdmi_writeb(hdmi, HDMI_PHY_SYNC, 0x00); in inno_hdmi_set_pwr_mode()
204 hdmi_writeb(hdmi, HDMI_PHY_SYNC, 0x01); in inno_hdmi_set_pwr_mode()
206 inno_hdmi_sys_power(hdmi, true); in inno_hdmi_set_pwr_mode()
210 inno_hdmi_sys_power(hdmi, false); in inno_hdmi_set_pwr_mode()
211 hdmi_writeb(hdmi, HDMI_PHY_DRIVER, 0x00); in inno_hdmi_set_pwr_mode()
212 hdmi_writeb(hdmi, HDMI_PHY_PRE_EMPHASIS, 0x00); in inno_hdmi_set_pwr_mode()
213 hdmi_writeb(hdmi, HDMI_PHY_CHG_PWR, 0x00); in inno_hdmi_set_pwr_mode()
214 hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x15); in inno_hdmi_set_pwr_mode()
219 DRM_DEV_ERROR(hdmi->dev, "Unknown power mode %d\n", mode); in inno_hdmi_set_pwr_mode()
223 static void inno_hdmi_reset(struct inno_hdmi *hdmi) in inno_hdmi_reset() argument
228 hdmi_modb(hdmi, HDMI_SYS_CTRL, m_RST_DIGITAL, v_NOT_RST_DIGITAL); in inno_hdmi_reset()
231 hdmi_modb(hdmi, HDMI_SYS_CTRL, m_RST_ANALOG, v_NOT_RST_ANALOG); in inno_hdmi_reset()
236 hdmi_modb(hdmi, HDMI_SYS_CTRL, msk, val); in inno_hdmi_reset()
238 inno_hdmi_set_pwr_mode(hdmi, NORMAL); in inno_hdmi_reset()
241 static int inno_hdmi_upload_frame(struct inno_hdmi *hdmi, int setup_rc, in inno_hdmi_upload_frame() argument
246 hdmi_modb(hdmi, HDMI_PACKET_SEND_AUTO, mask, disable); in inno_hdmi_upload_frame()
248 hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_BUF_INDEX, frame_index); in inno_hdmi_upload_frame()
260 hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_ADDR + i, in inno_hdmi_upload_frame()
264 hdmi_modb(hdmi, HDMI_PACKET_SEND_AUTO, mask, enable); in inno_hdmi_upload_frame()
270 static int inno_hdmi_config_video_vsi(struct inno_hdmi *hdmi, in inno_hdmi_config_video_vsi() argument
276 rc = drm_hdmi_vendor_infoframe_from_display_mode(&frame.vendor.hdmi, in inno_hdmi_config_video_vsi()
277 &hdmi->connector, in inno_hdmi_config_video_vsi()
280 return inno_hdmi_upload_frame(hdmi, rc, &frame, INFOFRAME_VSI, in inno_hdmi_config_video_vsi()
284 static int inno_hdmi_config_video_avi(struct inno_hdmi *hdmi, in inno_hdmi_config_video_avi() argument
291 &hdmi->connector, in inno_hdmi_config_video_avi()
294 if (hdmi->hdmi_data.enc_out_format == HDMI_COLORSPACE_YUV444) in inno_hdmi_config_video_avi()
296 else if (hdmi->hdmi_data.enc_out_format == HDMI_COLORSPACE_YUV422) in inno_hdmi_config_video_avi()
301 return inno_hdmi_upload_frame(hdmi, rc, &frame, INFOFRAME_AVI, 0, 0, 0); in inno_hdmi_config_video_avi()
304 static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi) in inno_hdmi_config_video_csc() argument
306 struct hdmi_data_info *data = &hdmi->hdmi_data; in inno_hdmi_config_video_csc()
315 hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL1, v_DE_EXTERNAL | in inno_hdmi_config_video_csc()
322 hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL2, value); in inno_hdmi_config_video_csc()
324 if (data->enc_in_format == data->enc_out_format) { in inno_hdmi_config_video_csc()
325 if ((data->enc_in_format == HDMI_COLORSPACE_RGB) || in inno_hdmi_config_video_csc()
326 (data->enc_in_format >= HDMI_COLORSPACE_YUV444)) { in inno_hdmi_config_video_csc()
328 hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL3, value); in inno_hdmi_config_video_csc()
330 hdmi_modb(hdmi, HDMI_VIDEO_CONTRL, in inno_hdmi_config_video_csc()
338 if (data->colorimetry == HDMI_COLORIMETRY_ITU_601) { in inno_hdmi_config_video_csc()
339 if ((data->enc_in_format == HDMI_COLORSPACE_RGB) && in inno_hdmi_config_video_csc()
340 (data->enc_out_format == HDMI_COLORSPACE_YUV444)) { in inno_hdmi_config_video_csc()
345 } else if ((data->enc_in_format == HDMI_COLORSPACE_YUV444) && in inno_hdmi_config_video_csc()
346 (data->enc_out_format == HDMI_COLORSPACE_RGB)) { in inno_hdmi_config_video_csc()
353 if ((data->enc_in_format == HDMI_COLORSPACE_RGB) && in inno_hdmi_config_video_csc()
354 (data->enc_out_format == HDMI_COLORSPACE_YUV444)) { in inno_hdmi_config_video_csc()
359 } else if ((data->enc_in_format == HDMI_COLORSPACE_YUV444) && in inno_hdmi_config_video_csc()
360 (data->enc_out_format == HDMI_COLORSPACE_RGB)) { in inno_hdmi_config_video_csc()
369 hdmi_writeb(hdmi, HDMI_VIDEO_CSC_COEF + i, in inno_hdmi_config_video_csc()
373 hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL3, value); in inno_hdmi_config_video_csc()
374 hdmi_modb(hdmi, HDMI_VIDEO_CONTRL, m_VIDEO_AUTO_CSC | in inno_hdmi_config_video_csc()
381 static int inno_hdmi_config_video_timing(struct inno_hdmi *hdmi, in inno_hdmi_config_video_timing() argument
388 value |= mode->flags & DRM_MODE_FLAG_PHSYNC ? in inno_hdmi_config_video_timing()
390 value |= mode->flags & DRM_MODE_FLAG_PVSYNC ? in inno_hdmi_config_video_timing()
392 value |= mode->flags & DRM_MODE_FLAG_INTERLACE ? in inno_hdmi_config_video_timing()
394 hdmi_writeb(hdmi, HDMI_VIDEO_TIMING_CTL, value); in inno_hdmi_config_video_timing()
397 value = mode->htotal; in inno_hdmi_config_video_timing()
398 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HTOTAL_L, value & 0xFF); in inno_hdmi_config_video_timing()
399 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HTOTAL_H, (value >> 8) & 0xFF); in inno_hdmi_config_video_timing()
401 value = mode->htotal - mode->hdisplay; in inno_hdmi_config_video_timing()
402 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HBLANK_L, value & 0xFF); in inno_hdmi_config_video_timing()
403 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HBLANK_H, (value >> 8) & 0xFF); in inno_hdmi_config_video_timing()
405 value = mode->hsync_start - mode->hdisplay; in inno_hdmi_config_video_timing()
406 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDELAY_L, value & 0xFF); in inno_hdmi_config_video_timing()
407 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDELAY_H, (value >> 8) & 0xFF); in inno_hdmi_config_video_timing()
409 value = mode->hsync_end - mode->hsync_start; in inno_hdmi_config_video_timing()
410 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDURATION_L, value & 0xFF); in inno_hdmi_config_video_timing()
411 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDURATION_H, (value >> 8) & 0xFF); in inno_hdmi_config_video_timing()
413 value = mode->vtotal; in inno_hdmi_config_video_timing()
414 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VTOTAL_L, value & 0xFF); in inno_hdmi_config_video_timing()
415 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VTOTAL_H, (value >> 8) & 0xFF); in inno_hdmi_config_video_timing()
417 value = mode->vtotal - mode->vdisplay; in inno_hdmi_config_video_timing()
418 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VBLANK, value & 0xFF); in inno_hdmi_config_video_timing()
420 value = mode->vsync_start - mode->vdisplay; in inno_hdmi_config_video_timing()
421 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VDELAY, value & 0xFF); in inno_hdmi_config_video_timing()
423 value = mode->vsync_end - mode->vsync_start; in inno_hdmi_config_video_timing()
424 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VDURATION, value & 0xFF); in inno_hdmi_config_video_timing()
426 hdmi_writeb(hdmi, HDMI_PHY_PRE_DIV_RATIO, 0x1e); in inno_hdmi_config_video_timing()
427 hdmi_writeb(hdmi, HDMI_PHY_FEEDBACK_DIV_RATIO_LOW, 0x2c); in inno_hdmi_config_video_timing()
428 hdmi_writeb(hdmi, HDMI_PHY_FEEDBACK_DIV_RATIO_HIGH, 0x01); in inno_hdmi_config_video_timing()
433 static int inno_hdmi_setup(struct inno_hdmi *hdmi, in inno_hdmi_setup() argument
436 hdmi->hdmi_data.vic = drm_match_cea_mode(mode); in inno_hdmi_setup()
438 hdmi->hdmi_data.enc_in_format = HDMI_COLORSPACE_RGB; in inno_hdmi_setup()
439 hdmi->hdmi_data.enc_out_format = HDMI_COLORSPACE_RGB; in inno_hdmi_setup()
441 if ((hdmi->hdmi_data.vic == 6) || (hdmi->hdmi_data.vic == 7) || in inno_hdmi_setup()
442 (hdmi->hdmi_data.vic == 21) || (hdmi->hdmi_data.vic == 22) || in inno_hdmi_setup()
443 (hdmi->hdmi_data.vic == 2) || (hdmi->hdmi_data.vic == 3) || in inno_hdmi_setup()
444 (hdmi->hdmi_data.vic == 17) || (hdmi->hdmi_data.vic == 18)) in inno_hdmi_setup()
445 hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_601; in inno_hdmi_setup()
447 hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_709; in inno_hdmi_setup()
450 hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_VIDEO_BLACK, in inno_hdmi_setup()
453 /* Set HDMI Mode */ in inno_hdmi_setup()
454 hdmi_writeb(hdmi, HDMI_HDCP_CTRL, in inno_hdmi_setup()
455 v_HDMI_DVI(hdmi->hdmi_data.sink_is_hdmi)); in inno_hdmi_setup()
457 inno_hdmi_config_video_timing(hdmi, mode); in inno_hdmi_setup()
459 inno_hdmi_config_video_csc(hdmi); in inno_hdmi_setup()
461 if (hdmi->hdmi_data.sink_is_hdmi) { in inno_hdmi_setup()
462 inno_hdmi_config_video_avi(hdmi, mode); in inno_hdmi_setup()
463 inno_hdmi_config_video_vsi(hdmi, mode); in inno_hdmi_setup()
472 hdmi->tmds_rate = mode->clock * 1000; in inno_hdmi_setup()
473 inno_hdmi_i2c_init(hdmi); in inno_hdmi_setup()
476 hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_VIDEO_BLACK, in inno_hdmi_setup()
486 struct inno_hdmi *hdmi = to_inno_hdmi(encoder); in inno_hdmi_encoder_mode_set() local
488 inno_hdmi_setup(hdmi, adj_mode); in inno_hdmi_encoder_mode_set()
491 memcpy(&hdmi->previous_mode, adj_mode, sizeof(hdmi->previous_mode)); in inno_hdmi_encoder_mode_set()
496 struct inno_hdmi *hdmi = to_inno_hdmi(encoder); in inno_hdmi_encoder_enable() local
498 inno_hdmi_set_pwr_mode(hdmi, NORMAL); in inno_hdmi_encoder_enable()
503 struct inno_hdmi *hdmi = to_inno_hdmi(encoder); in inno_hdmi_encoder_disable() local
505 inno_hdmi_set_pwr_mode(hdmi, LOWER_PWR); in inno_hdmi_encoder_disable()
522 s->output_mode = ROCKCHIP_OUT_MODE_P888; in inno_hdmi_encoder_atomic_check()
523 s->output_type = DRM_MODE_CONNECTOR_HDMIA; in inno_hdmi_encoder_atomic_check()
537 inno_hdmi_connector_detect(struct drm_connector *connector, bool force) in inno_hdmi_connector_detect() argument
539 struct inno_hdmi *hdmi = to_inno_hdmi(connector); in inno_hdmi_connector_detect() local
541 return (hdmi_readb(hdmi, HDMI_STATUS) & m_HOTPLUG) ? in inno_hdmi_connector_detect()
545 static int inno_hdmi_connector_get_modes(struct drm_connector *connector) in inno_hdmi_connector_get_modes() argument
547 struct inno_hdmi *hdmi = to_inno_hdmi(connector); in inno_hdmi_connector_get_modes() local
551 if (!hdmi->ddc) in inno_hdmi_connector_get_modes()
554 edid = drm_get_edid(connector, hdmi->ddc); in inno_hdmi_connector_get_modes()
556 hdmi->hdmi_data.sink_is_hdmi = drm_detect_hdmi_monitor(edid); in inno_hdmi_connector_get_modes()
557 hdmi->hdmi_data.sink_has_audio = drm_detect_monitor_audio(edid); in inno_hdmi_connector_get_modes()
558 drm_connector_update_edid_property(connector, edid); in inno_hdmi_connector_get_modes()
559 ret = drm_add_edid_modes(connector, edid); in inno_hdmi_connector_get_modes()
567 inno_hdmi_connector_mode_valid(struct drm_connector *connector, in inno_hdmi_connector_mode_valid() argument
574 inno_hdmi_probe_single_connector_modes(struct drm_connector *connector, in inno_hdmi_probe_single_connector_modes() argument
577 return drm_helper_probe_single_connector_modes(connector, 1920, 1080); in inno_hdmi_probe_single_connector_modes()
580 static void inno_hdmi_connector_destroy(struct drm_connector *connector) in inno_hdmi_connector_destroy() argument
582 drm_connector_unregister(connector); in inno_hdmi_connector_destroy()
583 drm_connector_cleanup(connector); in inno_hdmi_connector_destroy()
600 static int inno_hdmi_register(struct drm_device *drm, struct inno_hdmi *hdmi) in inno_hdmi_register() argument
602 struct drm_encoder *encoder = &hdmi->encoder; in inno_hdmi_register()
603 struct device *dev = hdmi->dev; in inno_hdmi_register()
605 encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node); in inno_hdmi_register()
613 if (encoder->possible_crtcs == 0) in inno_hdmi_register()
614 return -EPROBE_DEFER; in inno_hdmi_register()
619 hdmi->connector.polled = DRM_CONNECTOR_POLL_HPD; in inno_hdmi_register()
621 drm_connector_helper_add(&hdmi->connector, in inno_hdmi_register()
623 drm_connector_init_with_ddc(drm, &hdmi->connector, in inno_hdmi_register()
626 hdmi->ddc); in inno_hdmi_register()
628 drm_connector_attach_encoder(&hdmi->connector, encoder); in inno_hdmi_register()
633 static irqreturn_t inno_hdmi_i2c_irq(struct inno_hdmi *hdmi) in inno_hdmi_i2c_irq() argument
635 struct inno_hdmi_i2c *i2c = hdmi->i2c; in inno_hdmi_i2c_irq()
638 stat = hdmi_readb(hdmi, HDMI_INTERRUPT_STATUS1); in inno_hdmi_i2c_irq()
642 /* Clear HDMI EDID interrupt flag */ in inno_hdmi_i2c_irq()
643 hdmi_writeb(hdmi, HDMI_INTERRUPT_STATUS1, m_INT_EDID_READY); in inno_hdmi_i2c_irq()
645 complete(&i2c->cmp); in inno_hdmi_i2c_irq()
652 struct inno_hdmi *hdmi = dev_id; in inno_hdmi_hardirq() local
656 if (hdmi->i2c) in inno_hdmi_hardirq()
657 ret = inno_hdmi_i2c_irq(hdmi); in inno_hdmi_hardirq()
659 interrupt = hdmi_readb(hdmi, HDMI_STATUS); in inno_hdmi_hardirq()
661 hdmi_modb(hdmi, HDMI_STATUS, m_INT_HOTPLUG, m_INT_HOTPLUG); in inno_hdmi_hardirq()
670 struct inno_hdmi *hdmi = dev_id; in inno_hdmi_irq() local
672 drm_helper_hpd_irq_event(hdmi->connector.dev); in inno_hdmi_irq()
677 static int inno_hdmi_i2c_read(struct inno_hdmi *hdmi, struct i2c_msg *msgs) in inno_hdmi_i2c_read() argument
679 int length = msgs->len; in inno_hdmi_i2c_read()
680 u8 *buf = msgs->buf; in inno_hdmi_i2c_read()
683 ret = wait_for_completion_timeout(&hdmi->i2c->cmp, HZ / 10); in inno_hdmi_i2c_read()
685 return -EAGAIN; in inno_hdmi_i2c_read()
687 while (length--) in inno_hdmi_i2c_read()
688 *buf++ = hdmi_readb(hdmi, HDMI_EDID_FIFO_ADDR); in inno_hdmi_i2c_read()
693 static int inno_hdmi_i2c_write(struct inno_hdmi *hdmi, struct i2c_msg *msgs) in inno_hdmi_i2c_write() argument
700 if ((msgs->len != 1) || in inno_hdmi_i2c_write()
701 ((msgs->addr != DDC_ADDR) && (msgs->addr != DDC_SEGMENT_ADDR))) in inno_hdmi_i2c_write()
702 return -EINVAL; in inno_hdmi_i2c_write()
704 reinit_completion(&hdmi->i2c->cmp); in inno_hdmi_i2c_write()
706 if (msgs->addr == DDC_SEGMENT_ADDR) in inno_hdmi_i2c_write()
707 hdmi->i2c->segment_addr = msgs->buf[0]; in inno_hdmi_i2c_write()
708 if (msgs->addr == DDC_ADDR) in inno_hdmi_i2c_write()
709 hdmi->i2c->ddc_addr = msgs->buf[0]; in inno_hdmi_i2c_write()
712 hdmi_writeb(hdmi, HDMI_EDID_FIFO_OFFSET, 0x00); in inno_hdmi_i2c_write()
715 hdmi_writeb(hdmi, HDMI_EDID_WORD_ADDR, hdmi->i2c->ddc_addr); in inno_hdmi_i2c_write()
718 hdmi_writeb(hdmi, HDMI_EDID_SEGMENT_POINTER, hdmi->i2c->segment_addr); in inno_hdmi_i2c_write()
726 struct inno_hdmi *hdmi = i2c_get_adapdata(adap); in inno_hdmi_i2c_xfer() local
727 struct inno_hdmi_i2c *i2c = hdmi->i2c; in inno_hdmi_i2c_xfer()
730 mutex_lock(&i2c->lock); in inno_hdmi_i2c_xfer()
733 hdmi_writeb(hdmi, HDMI_INTERRUPT_MASK1, m_INT_EDID_READY); in inno_hdmi_i2c_xfer()
734 hdmi_writeb(hdmi, HDMI_INTERRUPT_STATUS1, m_INT_EDID_READY); in inno_hdmi_i2c_xfer()
737 DRM_DEV_DEBUG(hdmi->dev, in inno_hdmi_i2c_xfer()
742 ret = inno_hdmi_i2c_read(hdmi, &msgs[i]); in inno_hdmi_i2c_xfer()
744 ret = inno_hdmi_i2c_write(hdmi, &msgs[i]); in inno_hdmi_i2c_xfer()
753 /* Mute HDMI EDID interrupt */ in inno_hdmi_i2c_xfer()
754 hdmi_writeb(hdmi, HDMI_INTERRUPT_MASK1, 0); in inno_hdmi_i2c_xfer()
756 mutex_unlock(&i2c->lock); in inno_hdmi_i2c_xfer()
771 static struct i2c_adapter *inno_hdmi_i2c_adapter(struct inno_hdmi *hdmi) in inno_hdmi_i2c_adapter() argument
777 i2c = devm_kzalloc(hdmi->dev, sizeof(*i2c), GFP_KERNEL); in inno_hdmi_i2c_adapter()
779 return ERR_PTR(-ENOMEM); in inno_hdmi_i2c_adapter()
781 mutex_init(&i2c->lock); in inno_hdmi_i2c_adapter()
782 init_completion(&i2c->cmp); in inno_hdmi_i2c_adapter()
784 adap = &i2c->adap; in inno_hdmi_i2c_adapter()
785 adap->class = I2C_CLASS_DDC; in inno_hdmi_i2c_adapter()
786 adap->owner = THIS_MODULE; in inno_hdmi_i2c_adapter()
787 adap->dev.parent = hdmi->dev; in inno_hdmi_i2c_adapter()
788 adap->dev.of_node = hdmi->dev->of_node; in inno_hdmi_i2c_adapter()
789 adap->algo = &inno_hdmi_algorithm; in inno_hdmi_i2c_adapter()
790 strlcpy(adap->name, "Inno HDMI", sizeof(adap->name)); in inno_hdmi_i2c_adapter()
791 i2c_set_adapdata(adap, hdmi); in inno_hdmi_i2c_adapter()
795 dev_warn(hdmi->dev, "cannot add %s I2C adapter\n", adap->name); in inno_hdmi_i2c_adapter()
796 devm_kfree(hdmi->dev, i2c); in inno_hdmi_i2c_adapter()
800 hdmi->i2c = i2c; in inno_hdmi_i2c_adapter()
802 DRM_DEV_INFO(hdmi->dev, "registered %s I2C bus driver\n", adap->name); in inno_hdmi_i2c_adapter()
812 struct inno_hdmi *hdmi; in inno_hdmi_bind() local
817 hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL); in inno_hdmi_bind()
818 if (!hdmi) in inno_hdmi_bind()
819 return -ENOMEM; in inno_hdmi_bind()
821 hdmi->dev = dev; in inno_hdmi_bind()
822 hdmi->drm_dev = drm; in inno_hdmi_bind()
825 hdmi->regs = devm_ioremap_resource(dev, iores); in inno_hdmi_bind()
826 if (IS_ERR(hdmi->regs)) in inno_hdmi_bind()
827 return PTR_ERR(hdmi->regs); in inno_hdmi_bind()
829 hdmi->pclk = devm_clk_get(hdmi->dev, "pclk"); in inno_hdmi_bind()
830 if (IS_ERR(hdmi->pclk)) { in inno_hdmi_bind()
831 DRM_DEV_ERROR(hdmi->dev, "Unable to get HDMI pclk clk\n"); in inno_hdmi_bind()
832 return PTR_ERR(hdmi->pclk); in inno_hdmi_bind()
835 ret = clk_prepare_enable(hdmi->pclk); in inno_hdmi_bind()
837 DRM_DEV_ERROR(hdmi->dev, in inno_hdmi_bind()
838 "Cannot enable HDMI pclk clock: %d\n", ret); in inno_hdmi_bind()
848 inno_hdmi_reset(hdmi); in inno_hdmi_bind()
850 hdmi->ddc = inno_hdmi_i2c_adapter(hdmi); in inno_hdmi_bind()
851 if (IS_ERR(hdmi->ddc)) { in inno_hdmi_bind()
852 ret = PTR_ERR(hdmi->ddc); in inno_hdmi_bind()
853 hdmi->ddc = NULL; in inno_hdmi_bind()
863 hdmi->tmds_rate = clk_get_rate(hdmi->pclk); in inno_hdmi_bind()
864 inno_hdmi_i2c_init(hdmi); in inno_hdmi_bind()
866 ret = inno_hdmi_register(drm, hdmi); in inno_hdmi_bind()
870 dev_set_drvdata(dev, hdmi); in inno_hdmi_bind()
873 hdmi_modb(hdmi, HDMI_STATUS, m_MASK_INT_HOTPLUG, v_MASK_INT_HOTPLUG(1)); in inno_hdmi_bind()
877 dev_name(dev), hdmi); in inno_hdmi_bind()
883 hdmi->connector.funcs->destroy(&hdmi->connector); in inno_hdmi_bind()
884 hdmi->encoder.funcs->destroy(&hdmi->encoder); in inno_hdmi_bind()
886 i2c_put_adapter(hdmi->ddc); in inno_hdmi_bind()
888 clk_disable_unprepare(hdmi->pclk); in inno_hdmi_bind()
895 struct inno_hdmi *hdmi = dev_get_drvdata(dev); in inno_hdmi_unbind() local
897 hdmi->connector.funcs->destroy(&hdmi->connector); in inno_hdmi_unbind()
898 hdmi->encoder.funcs->destroy(&hdmi->encoder); in inno_hdmi_unbind()
900 i2c_put_adapter(hdmi->ddc); in inno_hdmi_unbind()
901 clk_disable_unprepare(hdmi->pclk); in inno_hdmi_unbind()
911 return component_add(&pdev->dev, &inno_hdmi_ops); in inno_hdmi_probe()
916 component_del(&pdev->dev, &inno_hdmi_ops); in inno_hdmi_remove()
922 { .compatible = "rockchip,rk3036-inno-hdmi",
932 .name = "innohdmi-rockchip",