Lines Matching full:hdmi

13 #include <linux/hdmi.h>
175 static void hdmi_writeb(struct inno_hdmi *hdmi, u16 offset, u32 val) in hdmi_writeb() argument
177 writel(val, hdmi->regs + (offset << 2)); in hdmi_writeb()
180 static u32 hdmi_readb(struct inno_hdmi *hdmi, u16 offset) in hdmi_readb() argument
182 return readl(hdmi->regs + (offset << 2)); in hdmi_readb()
185 static void hdmi_modb(struct inno_hdmi *hdmi, u16 offset, u32 msk, u32 val) in hdmi_modb() argument
187 u32 temp = hdmi_readb(hdmi, offset) & ~msk; in hdmi_modb()
190 hdmi_writeb(hdmi, offset, temp); in hdmi_modb()
193 static void inno_hdmi_sys_power(struct inno_hdmi *hdmi, bool enable) in inno_hdmi_sys_power() argument
196 hdmi_modb(hdmi, HDMI_SYS_CTRL, m_POWER, v_PWR_ON); in inno_hdmi_sys_power()
198 hdmi_modb(hdmi, HDMI_SYS_CTRL, m_POWER, v_PWR_OFF); in inno_hdmi_sys_power()
201 static void inno_hdmi_set_pwr_mode(struct inno_hdmi *hdmi, int mode) in inno_hdmi_set_pwr_mode() argument
204 hdmi->plat_data->phy_config; in inno_hdmi_set_pwr_mode()
208 inno_hdmi_sys_power(hdmi, false); in inno_hdmi_set_pwr_mode()
210 if (hdmi->tmds_rate <= phy_config->mpixelclock) in inno_hdmi_set_pwr_mode()
214 hdmi_writeb(hdmi, HDMI_PHY_PRE_EMPHASIS, in inno_hdmi_set_pwr_mode()
216 hdmi_writeb(hdmi, HDMI_PHY_DRIVER, phy_config->vlev_ctr); in inno_hdmi_set_pwr_mode()
218 hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x15); in inno_hdmi_set_pwr_mode()
219 hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x14); in inno_hdmi_set_pwr_mode()
220 hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x10); in inno_hdmi_set_pwr_mode()
222 hdmi_writeb(hdmi, HDMI_PHY_CHG_PWR, 0x0f); in inno_hdmi_set_pwr_mode()
223 hdmi_writeb(hdmi, HDMI_PHY_SYNC, 0x00); in inno_hdmi_set_pwr_mode()
224 hdmi_writeb(hdmi, HDMI_PHY_SYNC, 0x01); in inno_hdmi_set_pwr_mode()
225 inno_hdmi_sys_power(hdmi, true); in inno_hdmi_set_pwr_mode()
230 inno_hdmi_sys_power(hdmi, false); in inno_hdmi_set_pwr_mode()
231 hdmi_writeb(hdmi, HDMI_PHY_DRIVER, 0x00); in inno_hdmi_set_pwr_mode()
232 hdmi_writeb(hdmi, HDMI_PHY_PRE_EMPHASIS, 0x00); in inno_hdmi_set_pwr_mode()
233 hdmi_writeb(hdmi, HDMI_PHY_CHG_PWR, 0x00); in inno_hdmi_set_pwr_mode()
234 hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x15); in inno_hdmi_set_pwr_mode()
239 dev_err(hdmi->dev, "Unknown power mode %d\n", mode); in inno_hdmi_set_pwr_mode()
243 static void inno_hdmi_i2c_init(struct inno_hdmi *hdmi) in inno_hdmi_i2c_init() argument
247 ddc_bus_freq = (hdmi->tmds_rate >> 2) / HDMI_SCL_RATE; in inno_hdmi_i2c_init()
248 hdmi_writeb(hdmi, DDC_BUS_FREQ_L, ddc_bus_freq & 0xFF); in inno_hdmi_i2c_init()
249 hdmi_writeb(hdmi, DDC_BUS_FREQ_H, (ddc_bus_freq >> 8) & 0xFF); in inno_hdmi_i2c_init()
252 hdmi_writeb(hdmi, HDMI_INTERRUPT_MASK1, 0); in inno_hdmi_i2c_init()
253 hdmi_writeb(hdmi, HDMI_INTERRUPT_STATUS1, m_INT_EDID_READY); in inno_hdmi_i2c_init()
256 static void inno_hdmi_reset(struct inno_hdmi *hdmi) in inno_hdmi_reset() argument
261 hdmi_modb(hdmi, HDMI_SYS_CTRL, m_RST_DIGITAL, v_NOT_RST_DIGITAL); in inno_hdmi_reset()
264 hdmi_modb(hdmi, HDMI_SYS_CTRL, m_RST_ANALOG, v_NOT_RST_ANALOG); in inno_hdmi_reset()
270 hdmi_modb(hdmi, HDMI_SYS_CTRL, msk, val); in inno_hdmi_reset()
272 inno_hdmi_set_pwr_mode(hdmi, NORMAL); in inno_hdmi_reset()
275 static int inno_hdmi_upload_frame(struct inno_hdmi *hdmi, int setup_rc, in inno_hdmi_upload_frame() argument
280 hdmi_modb(hdmi, HDMI_PACKET_SEND_AUTO, mask, disable); in inno_hdmi_upload_frame()
282 hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_BUF_INDEX, frame_index); in inno_hdmi_upload_frame()
294 hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_ADDR + i, in inno_hdmi_upload_frame()
298 hdmi_modb(hdmi, HDMI_PACKET_SEND_AUTO, mask, enable); in inno_hdmi_upload_frame()
304 static int inno_hdmi_config_video_vsi(struct inno_hdmi *hdmi, in inno_hdmi_config_video_vsi() argument
310 rc = drm_hdmi_vendor_infoframe_from_display_mode(&frame.vendor.hdmi, in inno_hdmi_config_video_vsi()
313 return inno_hdmi_upload_frame(hdmi, rc, &frame, INFOFRAME_VSI, in inno_hdmi_config_video_vsi()
317 static int inno_hdmi_config_video_avi(struct inno_hdmi *hdmi, in inno_hdmi_config_video_avi() argument
325 if (hdmi->hdmi_data.enc_out_format == HDMI_COLORSPACE_YUV444) in inno_hdmi_config_video_avi()
327 else if (hdmi->hdmi_data.enc_out_format == HDMI_COLORSPACE_YUV422) in inno_hdmi_config_video_avi()
333 frame.avi.colorimetry = hdmi->hdmi_data.colorimetry; in inno_hdmi_config_video_avi()
337 return inno_hdmi_upload_frame(hdmi, rc, &frame, INFOFRAME_AVI, 0, 0, 0); in inno_hdmi_config_video_avi()
340 static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi) in inno_hdmi_config_video_csc() argument
342 struct hdmi_data_info *data = &hdmi->hdmi_data; in inno_hdmi_config_video_csc()
351 hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL1, v_DE_EXTERNAL | in inno_hdmi_config_video_csc()
358 hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL2, value); in inno_hdmi_config_video_csc()
364 hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL3, value); in inno_hdmi_config_video_csc()
366 hdmi_modb(hdmi, HDMI_VIDEO_CONTRL, in inno_hdmi_config_video_csc()
405 hdmi_writeb(hdmi, HDMI_VIDEO_CSC_COEF + i, in inno_hdmi_config_video_csc()
409 hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL3, value); in inno_hdmi_config_video_csc()
410 hdmi_modb(hdmi, HDMI_VIDEO_CONTRL, m_VIDEO_AUTO_CSC | in inno_hdmi_config_video_csc()
417 static int inno_hdmi_config_video_timing(struct inno_hdmi *hdmi, in inno_hdmi_config_video_timing() argument
422 if (hdmi->plat_data->dev_type == RK3036_HDMI) { in inno_hdmi_config_video_timing()
426 writel(value, hdmi->grf + 0x148); in inno_hdmi_config_video_timing()
436 hdmi_writeb(hdmi, HDMI_VIDEO_TIMING_CTL, value); in inno_hdmi_config_video_timing()
440 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HTOTAL_L, value & 0xFF); in inno_hdmi_config_video_timing()
441 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HTOTAL_H, (value >> 8) & 0xFF); in inno_hdmi_config_video_timing()
444 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HBLANK_L, value & 0xFF); in inno_hdmi_config_video_timing()
445 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HBLANK_H, (value >> 8) & 0xFF); in inno_hdmi_config_video_timing()
448 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDELAY_L, value & 0xFF); in inno_hdmi_config_video_timing()
449 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDELAY_H, (value >> 8) & 0xFF); in inno_hdmi_config_video_timing()
452 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDURATION_L, value & 0xFF); in inno_hdmi_config_video_timing()
453 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDURATION_H, (value >> 8) & 0xFF); in inno_hdmi_config_video_timing()
456 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VTOTAL_L, value & 0xFF); in inno_hdmi_config_video_timing()
457 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VTOTAL_H, (value >> 8) & 0xFF); in inno_hdmi_config_video_timing()
460 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VBLANK, value & 0xFF); in inno_hdmi_config_video_timing()
463 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VDELAY, value & 0xFF); in inno_hdmi_config_video_timing()
466 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VDURATION, value & 0xFF); in inno_hdmi_config_video_timing()
468 hdmi_writeb(hdmi, HDMI_PHY_PRE_DIV_RATIO, 0x1e); in inno_hdmi_config_video_timing()
469 hdmi_writeb(hdmi, HDMI_PHY_FEEDBACK_DIV_RATIO_LOW, 0x2c); in inno_hdmi_config_video_timing()
470 hdmi_writeb(hdmi, HDMI_PHY_FEEDBACK_DIV_RATIO_HIGH, 0x01); in inno_hdmi_config_video_timing()
475 static int inno_hdmi_setup(struct inno_hdmi *hdmi, in inno_hdmi_setup() argument
478 hdmi->hdmi_data.vic = drm_match_cea_mode(mode); in inno_hdmi_setup()
480 hdmi->hdmi_data.enc_in_format = HDMI_COLORSPACE_RGB; in inno_hdmi_setup()
481 hdmi->hdmi_data.enc_out_format = HDMI_COLORSPACE_RGB; in inno_hdmi_setup()
483 if (hdmi->hdmi_data.vic == 6 || hdmi->hdmi_data.vic == 7 || in inno_hdmi_setup()
484 hdmi->hdmi_data.vic == 21 || hdmi->hdmi_data.vic == 22 || in inno_hdmi_setup()
485 hdmi->hdmi_data.vic == 2 || hdmi->hdmi_data.vic == 3 || in inno_hdmi_setup()
486 hdmi->hdmi_data.vic == 17 || hdmi->hdmi_data.vic == 18) in inno_hdmi_setup()
487 hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_601; in inno_hdmi_setup()
489 hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_709; in inno_hdmi_setup()
492 hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_VIDEO_BLACK, in inno_hdmi_setup()
495 /* Set HDMI Mode */ in inno_hdmi_setup()
496 hdmi_writeb(hdmi, HDMI_HDCP_CTRL, in inno_hdmi_setup()
497 v_HDMI_DVI(hdmi->hdmi_data.sink_is_hdmi)); in inno_hdmi_setup()
499 inno_hdmi_config_video_timing(hdmi, mode); in inno_hdmi_setup()
501 inno_hdmi_config_video_csc(hdmi); in inno_hdmi_setup()
503 if (hdmi->hdmi_data.sink_is_hdmi) { in inno_hdmi_setup()
504 inno_hdmi_config_video_avi(hdmi, mode); in inno_hdmi_setup()
505 inno_hdmi_config_video_vsi(hdmi, mode); in inno_hdmi_setup()
514 hdmi->tmds_rate = mode->clock * 1000; in inno_hdmi_setup()
515 inno_hdmi_i2c_init(hdmi); in inno_hdmi_setup()
517 hdmi_modb(hdmi, HDMI_AV_MUTE, m_VIDEO_BLACK, v_VIDEO_MUTE(0)); in inno_hdmi_setup()
518 if (hdmi->audio_enable) in inno_hdmi_setup()
519 hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE, v_AUDIO_MUTE(0)); in inno_hdmi_setup()
524 static int inno_hdmi_i2c_read(struct inno_hdmi *hdmi, in inno_hdmi_i2c_read() argument
527 struct inno_hdmi_i2c *i2c = hdmi->i2c; in inno_hdmi_i2c_read()
535 interrupt = hdmi_readb(hdmi, HDMI_INTERRUPT_STATUS1); in inno_hdmi_i2c_read()
547 /* Clear HDMI EDID interrupt flag */ in inno_hdmi_i2c_read()
548 hdmi_writeb(hdmi, HDMI_INTERRUPT_STATUS1, m_INT_EDID_READY); in inno_hdmi_i2c_read()
551 *buf++ = hdmi_readb(hdmi, HDMI_EDID_FIFO_ADDR); in inno_hdmi_i2c_read()
556 static int inno_hdmi_i2c_write(struct inno_hdmi *hdmi, in inno_hdmi_i2c_write() argument
561 hdmi->i2c->segment_addr = 0; in inno_hdmi_i2c_write()
562 hdmi->i2c->ddc_addr = 0; in inno_hdmi_i2c_write()
576 hdmi->i2c->segment_addr = msgs->buf[0]; in inno_hdmi_i2c_write()
578 hdmi->i2c->ddc_addr = msgs->buf[0]; in inno_hdmi_i2c_write()
581 hdmi_writeb(hdmi, HDMI_EDID_FIFO_OFFSET, 0x00); in inno_hdmi_i2c_write()
584 hdmi_writeb(hdmi, HDMI_EDID_WORD_ADDR, hdmi->i2c->ddc_addr); in inno_hdmi_i2c_write()
587 hdmi_writeb(hdmi, HDMI_EDID_SEGMENT_POINTER, hdmi->i2c->segment_addr); in inno_hdmi_i2c_write()
595 struct inno_hdmi *hdmi = container_of(adap, struct inno_hdmi, adap); in inno_hdmi_i2c_xfer() local
599 hdmi_writeb(hdmi, HDMI_INTERRUPT_MASK1, m_INT_EDID_READY); in inno_hdmi_i2c_xfer()
600 hdmi_writeb(hdmi, HDMI_INTERRUPT_STATUS1, m_INT_EDID_READY); in inno_hdmi_i2c_xfer()
603 dev_dbg(hdmi->dev, "xfer: num: %d/%d, len: %d, flags: %#x\n", in inno_hdmi_i2c_xfer()
607 ret = inno_hdmi_i2c_read(hdmi, &msgs[i]); in inno_hdmi_i2c_xfer()
609 ret = inno_hdmi_i2c_write(hdmi, &msgs[i]); in inno_hdmi_i2c_xfer()
618 /* Mute HDMI EDID interrupt */ in inno_hdmi_i2c_xfer()
619 hdmi_writeb(hdmi, HDMI_INTERRUPT_MASK1, 0); in inno_hdmi_i2c_xfer()
627 struct inno_hdmi *hdmi; in rockchip_inno_hdmi_init() local
632 hdmi = calloc(1, sizeof(struct inno_hdmi)); in rockchip_inno_hdmi_init()
633 if (!hdmi) in rockchip_inno_hdmi_init()
640 hdmi->regs = dev_read_addr_ptr(conn->dev); in rockchip_inno_hdmi_init()
642 hdmi->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); in rockchip_inno_hdmi_init()
643 if (hdmi->grf <= 0) { in rockchip_inno_hdmi_init()
645 __func__, hdmi->grf); in rockchip_inno_hdmi_init()
649 hdmi->i2c = malloc(sizeof(struct inno_hdmi_i2c)); in rockchip_inno_hdmi_init()
650 if (!hdmi->i2c) in rockchip_inno_hdmi_init()
653 hdmi->adap.ddc_xfer = inno_hdmi_i2c_xfer; in rockchip_inno_hdmi_init()
659 hdmi->i2c->scl_high_ns = in rockchip_inno_hdmi_init()
662 hdmi->i2c->scl_low_ns = in rockchip_inno_hdmi_init()
669 hdmi->plat_data = (struct inno_hdmi_plat_data *)dev_get_driver_data(conn->dev); in rockchip_inno_hdmi_init()
670 hdmi->edid_data.mode_buf = mode_buf; in rockchip_inno_hdmi_init()
671 hdmi->sample_rate = 48000; in rockchip_inno_hdmi_init()
673 conn->data = hdmi; in rockchip_inno_hdmi_init()
675 inno_hdmi_reset(hdmi); in rockchip_inno_hdmi_init()
676 ret = clk_get_by_name(conn->dev, "pclk", &hdmi->pclk); in rockchip_inno_hdmi_init()
678 dev_err(hdmi->dev, "failed to get pclk: %d\n", ret); in rockchip_inno_hdmi_init()
681 hdmi->tmds_rate = clk_get_rate(&hdmi->pclk); in rockchip_inno_hdmi_init()
682 inno_hdmi_i2c_init(hdmi); in rockchip_inno_hdmi_init()
685 hdmi_modb(hdmi, HDMI_STATUS, m_MASK_INT_HOTPLUG, v_MASK_INT_HOTPLUG(1)); in rockchip_inno_hdmi_init()
694 struct inno_hdmi *hdmi = conn->data; in rockchip_inno_hdmi_enable() local
696 if (!hdmi) in rockchip_inno_hdmi_enable()
700 memcpy(&hdmi->previous_mode, mode, sizeof(hdmi->previous_mode)); in rockchip_inno_hdmi_enable()
702 inno_hdmi_setup(hdmi, mode); in rockchip_inno_hdmi_enable()
703 inno_hdmi_set_pwr_mode(hdmi, NORMAL); in rockchip_inno_hdmi_enable()
710 struct inno_hdmi *hdmi = conn->data; in rockchip_inno_hdmi_deinit() local
712 if (hdmi->i2c) in rockchip_inno_hdmi_deinit()
713 free(hdmi->i2c); in rockchip_inno_hdmi_deinit()
714 if (hdmi) in rockchip_inno_hdmi_deinit()
715 free(hdmi); in rockchip_inno_hdmi_deinit()
725 struct inno_hdmi *hdmi = conn->data; in rockchip_inno_hdmi_disable() local
727 inno_hdmi_set_pwr_mode(hdmi, LOWER_PWR); in rockchip_inno_hdmi_disable()
733 struct inno_hdmi *hdmi = conn->data; in rockchip_inno_hdmi_detect() local
735 return (hdmi_readb(hdmi, HDMI_STATUS) & m_HOTPLUG) ? in rockchip_inno_hdmi_detect()
745 struct inno_hdmi *hdmi = conn->data; in rockchip_inno_hdmi_get_timing() local
749 if (!hdmi) in rockchip_inno_hdmi_get_timing()
752 ret = drm_do_get_edid(&hdmi->adap, conn_state->edid); in rockchip_inno_hdmi_get_timing()
754 hdmi->hdmi_data.sink_is_hdmi = in rockchip_inno_hdmi_get_timing()
756 hdmi->hdmi_data.sink_has_audio = drm_detect_monitor_audio(edid); in rockchip_inno_hdmi_get_timing()
757 ret = drm_add_edid_modes(&hdmi->edid_data, conn_state->edid); in rockchip_inno_hdmi_get_timing()
760 hdmi->hdmi_data.sink_is_hdmi = true; in rockchip_inno_hdmi_get_timing()
761 hdmi->hdmi_data.sink_has_audio = true; in rockchip_inno_hdmi_get_timing()
762 do_cea_modes(&hdmi->edid_data, def_modes_vic, in rockchip_inno_hdmi_get_timing()
764 hdmi->edid_data.preferred_mode = &hdmi->edid_data.mode_buf[0]; in rockchip_inno_hdmi_get_timing()
767 drm_rk_filter_whitelist(&hdmi->edid_data); in rockchip_inno_hdmi_get_timing()
769 if (!drm_mode_prune_invalid(&hdmi->edid_data)) { in rockchip_inno_hdmi_get_timing()
770 printf("can't find valid hdmi mode\n"); in rockchip_inno_hdmi_get_timing()
774 for (i = 0; i < hdmi->edid_data.modes; i++) in rockchip_inno_hdmi_get_timing()
775 hdmi->edid_data.mode_buf[i].vrefresh = in rockchip_inno_hdmi_get_timing()
776 drm_mode_vrefresh(&hdmi->edid_data.mode_buf[i]); in rockchip_inno_hdmi_get_timing()
778 drm_mode_sort(&hdmi->edid_data); in rockchip_inno_hdmi_get_timing()
780 *mode = *hdmi->edid_data.preferred_mode; in rockchip_inno_hdmi_get_timing()
781 hdmi->vic = drm_match_cea_mode(mode); in rockchip_inno_hdmi_get_timing()
805 id = of_alias_get_id(ofnode_to_np(dev->node), "hdmi"); in rockchip_inno_hdmi_probe()
832 .compatible = "rockchip,rk3036-inno-hdmi",
836 .compatible = "rockchip,rk3128-inno-hdmi",