Lines Matching full:hdmi
2 * DesignWare High-Definition Multimedia Interface (HDMI) driver
19 #include <linux/hdmi.h>
36 #include "dw-hdmi.h"
37 #include "dw-hdmi-audio.h"
38 #include "dw-hdmi-cec.h"
126 int (*configure)(struct dw_hdmi *hdmi,
183 void (*enable_audio)(struct dw_hdmi *hdmi);
184 void (*disable_audio)(struct dw_hdmi *hdmi);
197 static inline void hdmi_writeb(struct dw_hdmi *hdmi, u8 val, int offset) in hdmi_writeb() argument
199 regmap_write(hdmi->regm, offset << hdmi->reg_shift, val); in hdmi_writeb()
202 static inline u8 hdmi_readb(struct dw_hdmi *hdmi, int offset) in hdmi_readb() argument
206 regmap_read(hdmi->regm, offset << hdmi->reg_shift, &val); in hdmi_readb()
211 static void hdmi_modb(struct dw_hdmi *hdmi, u8 data, u8 mask, unsigned reg) in hdmi_modb() argument
213 regmap_update_bits(hdmi->regm, reg << hdmi->reg_shift, mask, data); in hdmi_modb()
216 static void hdmi_mask_writeb(struct dw_hdmi *hdmi, u8 data, unsigned int reg, in hdmi_mask_writeb() argument
219 hdmi_modb(hdmi, data << shift, mask, reg); in hdmi_mask_writeb()
222 static void dw_hdmi_i2c_init(struct dw_hdmi *hdmi) in dw_hdmi_i2c_init() argument
225 hdmi_writeb(hdmi, 0x00, HDMI_I2CM_SOFTRSTZ); in dw_hdmi_i2c_init()
228 hdmi_writeb(hdmi, 0x00, HDMI_I2CM_DIV); in dw_hdmi_i2c_init()
231 hdmi_writeb(hdmi, HDMI_I2CM_INT_DONE_POL, HDMI_I2CM_INT); in dw_hdmi_i2c_init()
232 hdmi_writeb(hdmi, HDMI_I2CM_CTLINT_NAC_POL | HDMI_I2CM_CTLINT_ARB_POL, in dw_hdmi_i2c_init()
236 hdmi_writeb(hdmi, HDMI_IH_I2CM_STAT0_ERROR | HDMI_IH_I2CM_STAT0_DONE, in dw_hdmi_i2c_init()
240 hdmi_writeb(hdmi, HDMI_IH_I2CM_STAT0_ERROR | HDMI_IH_I2CM_STAT0_DONE, in dw_hdmi_i2c_init()
244 static int dw_hdmi_i2c_read(struct dw_hdmi *hdmi, in dw_hdmi_i2c_read() argument
247 struct dw_hdmi_i2c *i2c = hdmi->i2c; in dw_hdmi_i2c_read()
251 dev_dbg(hdmi->dev, "set read register address to 0\n"); in dw_hdmi_i2c_read()
259 hdmi_writeb(hdmi, i2c->slave_reg++, HDMI_I2CM_ADDRESS); in dw_hdmi_i2c_read()
261 hdmi_writeb(hdmi, HDMI_I2CM_OPERATION_READ_EXT, in dw_hdmi_i2c_read()
264 hdmi_writeb(hdmi, HDMI_I2CM_OPERATION_READ, in dw_hdmi_i2c_read()
275 *buf++ = hdmi_readb(hdmi, HDMI_I2CM_DATAI); in dw_hdmi_i2c_read()
282 static int dw_hdmi_i2c_write(struct dw_hdmi *hdmi, in dw_hdmi_i2c_write() argument
285 struct dw_hdmi_i2c *i2c = hdmi->i2c; in dw_hdmi_i2c_write()
299 hdmi_writeb(hdmi, *buf++, HDMI_I2CM_DATAO); in dw_hdmi_i2c_write()
300 hdmi_writeb(hdmi, i2c->slave_reg++, HDMI_I2CM_ADDRESS); in dw_hdmi_i2c_write()
301 hdmi_writeb(hdmi, HDMI_I2CM_OPERATION_WRITE, in dw_hdmi_i2c_write()
319 struct dw_hdmi *hdmi = i2c_get_adapdata(adap); in dw_hdmi_i2c_xfer() local
320 struct dw_hdmi_i2c *i2c = hdmi->i2c; in dw_hdmi_i2c_xfer()
333 dev_dbg(hdmi->dev, "xfer: num: %d, addr: %#x\n", num, addr); in dw_hdmi_i2c_xfer()
337 dev_dbg(hdmi->dev, in dw_hdmi_i2c_xfer()
347 hdmi_writeb(hdmi, 0x00, HDMI_IH_MUTE_I2CM_STAT0); in dw_hdmi_i2c_xfer()
350 hdmi_writeb(hdmi, addr, HDMI_I2CM_SLAVE); in dw_hdmi_i2c_xfer()
359 dev_dbg(hdmi->dev, "xfer: num: %d/%d, len: %d, flags: %#x\n", in dw_hdmi_i2c_xfer()
363 hdmi_writeb(hdmi, DDC_SEGMENT_ADDR, HDMI_I2CM_SEGADDR); in dw_hdmi_i2c_xfer()
364 hdmi_writeb(hdmi, *msgs[i].buf, HDMI_I2CM_SEGPTR); in dw_hdmi_i2c_xfer()
367 ret = dw_hdmi_i2c_read(hdmi, msgs[i].buf, in dw_hdmi_i2c_xfer()
370 ret = dw_hdmi_i2c_write(hdmi, msgs[i].buf, in dw_hdmi_i2c_xfer()
381 hdmi_writeb(hdmi, HDMI_IH_I2CM_STAT0_ERROR | HDMI_IH_I2CM_STAT0_DONE, in dw_hdmi_i2c_xfer()
399 static struct i2c_adapter *dw_hdmi_i2c_adapter(struct dw_hdmi *hdmi) in dw_hdmi_i2c_adapter() argument
405 i2c = devm_kzalloc(hdmi->dev, sizeof(*i2c), GFP_KERNEL); in dw_hdmi_i2c_adapter()
415 adap->dev.parent = hdmi->dev; in dw_hdmi_i2c_adapter()
417 strlcpy(adap->name, "DesignWare HDMI", sizeof(adap->name)); in dw_hdmi_i2c_adapter()
418 i2c_set_adapdata(adap, hdmi); in dw_hdmi_i2c_adapter()
422 dev_warn(hdmi->dev, "cannot add %s I2C adapter\n", adap->name); in dw_hdmi_i2c_adapter()
423 devm_kfree(hdmi->dev, i2c); in dw_hdmi_i2c_adapter()
427 hdmi->i2c = i2c; in dw_hdmi_i2c_adapter()
429 dev_info(hdmi->dev, "registered %s I2C bus driver\n", adap->name); in dw_hdmi_i2c_adapter()
434 static void hdmi_set_cts_n(struct dw_hdmi *hdmi, unsigned int cts, in hdmi_set_cts_n() argument
438 hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3); in hdmi_set_cts_n()
441 hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_N_SHIFT_MASK, HDMI_AUD_CTS3); in hdmi_set_cts_n()
443 hdmi_writeb(hdmi, ((cts >> 16) & HDMI_AUD_CTS3_AUDCTS19_16_MASK) | in hdmi_set_cts_n()
445 hdmi_writeb(hdmi, (cts >> 8) & 0xff, HDMI_AUD_CTS2); in hdmi_set_cts_n()
446 hdmi_writeb(hdmi, cts & 0xff, HDMI_AUD_CTS1); in hdmi_set_cts_n()
448 hdmi_writeb(hdmi, (n >> 16) & 0x0f, HDMI_AUD_N3); in hdmi_set_cts_n()
449 hdmi_writeb(hdmi, (n >> 8) & 0xff, HDMI_AUD_N2); in hdmi_set_cts_n()
450 hdmi_writeb(hdmi, n & 0xff, HDMI_AUD_N1); in hdmi_set_cts_n()
509 static void hdmi_set_clk_regenerator(struct dw_hdmi *hdmi, in hdmi_set_clk_regenerator() argument
529 dev_dbg(hdmi->dev, "%s: fs=%uHz ftdms=%lu.%03luMHz N=%d cts=%d\n", in hdmi_set_clk_regenerator()
533 spin_lock_irq(&hdmi->audio_lock); in hdmi_set_clk_regenerator()
534 hdmi->audio_n = n; in hdmi_set_clk_regenerator()
535 hdmi->audio_cts = cts; in hdmi_set_clk_regenerator()
536 hdmi_set_cts_n(hdmi, cts, hdmi->audio_enable ? n : 0); in hdmi_set_clk_regenerator()
537 spin_unlock_irq(&hdmi->audio_lock); in hdmi_set_clk_regenerator()
540 static void hdmi_init_clk_regenerator(struct dw_hdmi *hdmi) in hdmi_init_clk_regenerator() argument
542 mutex_lock(&hdmi->audio_mutex); in hdmi_init_clk_regenerator()
543 hdmi_set_clk_regenerator(hdmi, 74250000, hdmi->sample_rate); in hdmi_init_clk_regenerator()
544 mutex_unlock(&hdmi->audio_mutex); in hdmi_init_clk_regenerator()
547 static void hdmi_clk_regenerator_update_pixel_clock(struct dw_hdmi *hdmi) in hdmi_clk_regenerator_update_pixel_clock() argument
549 mutex_lock(&hdmi->audio_mutex); in hdmi_clk_regenerator_update_pixel_clock()
550 hdmi_set_clk_regenerator(hdmi, hdmi->hdmi_data.video_mode.mpixelclock, in hdmi_clk_regenerator_update_pixel_clock()
551 hdmi->sample_rate); in hdmi_clk_regenerator_update_pixel_clock()
552 mutex_unlock(&hdmi->audio_mutex); in hdmi_clk_regenerator_update_pixel_clock()
555 void dw_hdmi_set_sample_rate(struct dw_hdmi *hdmi, unsigned int rate) in dw_hdmi_set_sample_rate() argument
557 mutex_lock(&hdmi->audio_mutex); in dw_hdmi_set_sample_rate()
558 hdmi->sample_rate = rate; in dw_hdmi_set_sample_rate()
559 hdmi_set_clk_regenerator(hdmi, hdmi->hdmi_data.video_mode.mpixelclock, in dw_hdmi_set_sample_rate()
560 hdmi->sample_rate); in dw_hdmi_set_sample_rate()
561 mutex_unlock(&hdmi->audio_mutex); in dw_hdmi_set_sample_rate()
565 static void hdmi_enable_audio_clk(struct dw_hdmi *hdmi, bool enable) in hdmi_enable_audio_clk() argument
568 hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_AUDCLK_DISABLE; in hdmi_enable_audio_clk()
570 hdmi->mc_clkdis |= HDMI_MC_CLKDIS_AUDCLK_DISABLE; in hdmi_enable_audio_clk()
571 hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS); in hdmi_enable_audio_clk()
574 static void dw_hdmi_ahb_audio_enable(struct dw_hdmi *hdmi) in dw_hdmi_ahb_audio_enable() argument
576 hdmi_set_cts_n(hdmi, hdmi->audio_cts, hdmi->audio_n); in dw_hdmi_ahb_audio_enable()
579 static void dw_hdmi_ahb_audio_disable(struct dw_hdmi *hdmi) in dw_hdmi_ahb_audio_disable() argument
581 hdmi_set_cts_n(hdmi, hdmi->audio_cts, 0); in dw_hdmi_ahb_audio_disable()
584 static void dw_hdmi_i2s_audio_enable(struct dw_hdmi *hdmi) in dw_hdmi_i2s_audio_enable() argument
586 hdmi_set_cts_n(hdmi, hdmi->audio_cts, hdmi->audio_n); in dw_hdmi_i2s_audio_enable()
587 hdmi_enable_audio_clk(hdmi, true); in dw_hdmi_i2s_audio_enable()
590 static void dw_hdmi_i2s_audio_disable(struct dw_hdmi *hdmi) in dw_hdmi_i2s_audio_disable() argument
592 hdmi_enable_audio_clk(hdmi, false); in dw_hdmi_i2s_audio_disable()
595 void dw_hdmi_audio_enable(struct dw_hdmi *hdmi) in dw_hdmi_audio_enable() argument
599 spin_lock_irqsave(&hdmi->audio_lock, flags); in dw_hdmi_audio_enable()
600 hdmi->audio_enable = true; in dw_hdmi_audio_enable()
601 if (hdmi->enable_audio) in dw_hdmi_audio_enable()
602 hdmi->enable_audio(hdmi); in dw_hdmi_audio_enable()
603 spin_unlock_irqrestore(&hdmi->audio_lock, flags); in dw_hdmi_audio_enable()
607 void dw_hdmi_audio_disable(struct dw_hdmi *hdmi) in dw_hdmi_audio_disable() argument
611 spin_lock_irqsave(&hdmi->audio_lock, flags); in dw_hdmi_audio_disable()
612 hdmi->audio_enable = false; in dw_hdmi_audio_disable()
613 if (hdmi->disable_audio) in dw_hdmi_audio_disable()
614 hdmi->disable_audio(hdmi); in dw_hdmi_audio_disable()
615 spin_unlock_irqrestore(&hdmi->audio_lock, flags); in dw_hdmi_audio_disable()
698 static void hdmi_video_sample(struct dw_hdmi *hdmi) in hdmi_video_sample() argument
703 switch (hdmi->hdmi_data.enc_in_bus_format) { in hdmi_video_sample()
751 hdmi_writeb(hdmi, val, HDMI_TX_INVID0); in hdmi_video_sample()
757 hdmi_writeb(hdmi, val, HDMI_TX_INSTUFFING); in hdmi_video_sample()
758 hdmi_writeb(hdmi, 0x0, HDMI_TX_GYDATA0); in hdmi_video_sample()
759 hdmi_writeb(hdmi, 0x0, HDMI_TX_GYDATA1); in hdmi_video_sample()
760 hdmi_writeb(hdmi, 0x0, HDMI_TX_RCRDATA0); in hdmi_video_sample()
761 hdmi_writeb(hdmi, 0x0, HDMI_TX_RCRDATA1); in hdmi_video_sample()
762 hdmi_writeb(hdmi, 0x0, HDMI_TX_BCBDATA0); in hdmi_video_sample()
763 hdmi_writeb(hdmi, 0x0, HDMI_TX_BCBDATA1); in hdmi_video_sample()
766 static int is_color_space_conversion(struct dw_hdmi *hdmi) in is_color_space_conversion() argument
768 return hdmi->hdmi_data.enc_in_bus_format != hdmi->hdmi_data.enc_out_bus_format; in is_color_space_conversion()
771 static int is_color_space_decimation(struct dw_hdmi *hdmi) in is_color_space_decimation() argument
773 if (!hdmi_bus_fmt_is_yuv422(hdmi->hdmi_data.enc_out_bus_format)) in is_color_space_decimation()
776 if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_in_bus_format) || in is_color_space_decimation()
777 hdmi_bus_fmt_is_yuv444(hdmi->hdmi_data.enc_in_bus_format)) in is_color_space_decimation()
783 static int is_color_space_interpolation(struct dw_hdmi *hdmi) in is_color_space_interpolation() argument
785 if (!hdmi_bus_fmt_is_yuv422(hdmi->hdmi_data.enc_in_bus_format)) in is_color_space_interpolation()
788 if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format) || in is_color_space_interpolation()
789 hdmi_bus_fmt_is_yuv444(hdmi->hdmi_data.enc_out_bus_format)) in is_color_space_interpolation()
795 static void dw_hdmi_update_csc_coeffs(struct dw_hdmi *hdmi) in dw_hdmi_update_csc_coeffs() argument
801 if (is_color_space_conversion(hdmi)) { in dw_hdmi_update_csc_coeffs()
802 if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format)) { in dw_hdmi_update_csc_coeffs()
803 if (hdmi->hdmi_data.enc_out_encoding == in dw_hdmi_update_csc_coeffs()
809 hdmi->hdmi_data.enc_in_bus_format)) { in dw_hdmi_update_csc_coeffs()
810 if (hdmi->hdmi_data.enc_out_encoding == in dw_hdmi_update_csc_coeffs()
825 hdmi_writeb(hdmi, coeff_a & 0xff, HDMI_CSC_COEF_A1_LSB + i * 2); in dw_hdmi_update_csc_coeffs()
826 hdmi_writeb(hdmi, coeff_a >> 8, HDMI_CSC_COEF_A1_MSB + i * 2); in dw_hdmi_update_csc_coeffs()
827 hdmi_writeb(hdmi, coeff_b & 0xff, HDMI_CSC_COEF_B1_LSB + i * 2); in dw_hdmi_update_csc_coeffs()
828 hdmi_writeb(hdmi, coeff_b >> 8, HDMI_CSC_COEF_B1_MSB + i * 2); in dw_hdmi_update_csc_coeffs()
829 hdmi_writeb(hdmi, coeff_c & 0xff, HDMI_CSC_COEF_C1_LSB + i * 2); in dw_hdmi_update_csc_coeffs()
830 hdmi_writeb(hdmi, coeff_c >> 8, HDMI_CSC_COEF_C1_MSB + i * 2); in dw_hdmi_update_csc_coeffs()
833 hdmi_modb(hdmi, csc_scale, HDMI_CSC_SCALE_CSCSCALE_MASK, in dw_hdmi_update_csc_coeffs()
837 static void hdmi_video_csc(struct dw_hdmi *hdmi) in hdmi_video_csc() argument
844 if (is_color_space_interpolation(hdmi)) in hdmi_video_csc()
846 else if (is_color_space_decimation(hdmi)) in hdmi_video_csc()
849 switch (hdmi_bus_fmt_color_depth(hdmi->hdmi_data.enc_out_bus_format)) { in hdmi_video_csc()
868 hdmi_writeb(hdmi, interpolation | decimation, HDMI_CSC_CFG); in hdmi_video_csc()
869 hdmi_modb(hdmi, color_depth, HDMI_CSC_SCALE_CSC_COLORDE_PTH_MASK, in hdmi_video_csc()
872 dw_hdmi_update_csc_coeffs(hdmi); in hdmi_video_csc()
876 * HDMI video packetizer is used to packetize the data.
880 static void hdmi_video_packetize(struct dw_hdmi *hdmi) in hdmi_video_packetize() argument
885 struct hdmi_data_info *hdmi_data = &hdmi->hdmi_data; in hdmi_video_packetize()
888 if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format) || in hdmi_video_packetize()
889 hdmi_bus_fmt_is_yuv444(hdmi->hdmi_data.enc_out_bus_format)) { in hdmi_video_packetize()
891 hdmi->hdmi_data.enc_out_bus_format)) { in hdmi_video_packetize()
908 } else if (hdmi_bus_fmt_is_yuv422(hdmi->hdmi_data.enc_out_bus_format)) { in hdmi_video_packetize()
910 hdmi->hdmi_data.enc_out_bus_format)) { in hdmi_video_packetize()
936 hdmi_writeb(hdmi, val, HDMI_VP_PR_CD); in hdmi_video_packetize()
938 hdmi_modb(hdmi, HDMI_VP_STUFF_PR_STUFFING_STUFFING_MODE, in hdmi_video_packetize()
950 hdmi_modb(hdmi, vp_conf, in hdmi_video_packetize()
954 hdmi_modb(hdmi, 1 << HDMI_VP_STUFF_IDEFAULT_PHASE_OFFSET, in hdmi_video_packetize()
957 hdmi_writeb(hdmi, remap_size, HDMI_VP_REMAP); in hdmi_video_packetize()
975 hdmi_modb(hdmi, vp_conf, in hdmi_video_packetize()
979 hdmi_modb(hdmi, HDMI_VP_STUFF_PP_STUFFING_STUFFING_MODE | in hdmi_video_packetize()
984 hdmi_modb(hdmi, output_select, HDMI_VP_CONF_OUTPUT_SELECTOR_MASK, in hdmi_video_packetize()
992 static inline void hdmi_phy_test_clear(struct dw_hdmi *hdmi, in hdmi_phy_test_clear() argument
995 hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTCLR_OFFSET, in hdmi_phy_test_clear()
999 static bool hdmi_phy_wait_i2c_done(struct dw_hdmi *hdmi, int msec) in hdmi_phy_wait_i2c_done() argument
1003 while ((val = hdmi_readb(hdmi, HDMI_IH_I2CMPHY_STAT0) & 0x3) == 0) { in hdmi_phy_wait_i2c_done()
1008 hdmi_writeb(hdmi, val, HDMI_IH_I2CMPHY_STAT0); in hdmi_phy_wait_i2c_done()
1013 void dw_hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data, in dw_hdmi_phy_i2c_write() argument
1016 hdmi_writeb(hdmi, 0xFF, HDMI_IH_I2CMPHY_STAT0); in dw_hdmi_phy_i2c_write()
1017 hdmi_writeb(hdmi, addr, HDMI_PHY_I2CM_ADDRESS_ADDR); in dw_hdmi_phy_i2c_write()
1018 hdmi_writeb(hdmi, (unsigned char)(data >> 8), in dw_hdmi_phy_i2c_write()
1020 hdmi_writeb(hdmi, (unsigned char)(data >> 0), in dw_hdmi_phy_i2c_write()
1022 hdmi_writeb(hdmi, HDMI_PHY_I2CM_OPERATION_ADDR_WRITE, in dw_hdmi_phy_i2c_write()
1024 hdmi_phy_wait_i2c_done(hdmi, 1000); in dw_hdmi_phy_i2c_write()
1028 static void dw_hdmi_phy_enable_powerdown(struct dw_hdmi *hdmi, bool enable) in dw_hdmi_phy_enable_powerdown() argument
1030 hdmi_mask_writeb(hdmi, !enable, HDMI_PHY_CONF0, in dw_hdmi_phy_enable_powerdown()
1035 static void dw_hdmi_phy_enable_tmds(struct dw_hdmi *hdmi, u8 enable) in dw_hdmi_phy_enable_tmds() argument
1037 hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, in dw_hdmi_phy_enable_tmds()
1042 static void dw_hdmi_phy_enable_svsret(struct dw_hdmi *hdmi, u8 enable) in dw_hdmi_phy_enable_svsret() argument
1044 hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, in dw_hdmi_phy_enable_svsret()
1049 void dw_hdmi_phy_gen2_pddq(struct dw_hdmi *hdmi, u8 enable) in dw_hdmi_phy_gen2_pddq() argument
1051 hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, in dw_hdmi_phy_gen2_pddq()
1057 void dw_hdmi_phy_gen2_txpwron(struct dw_hdmi *hdmi, u8 enable) in dw_hdmi_phy_gen2_txpwron() argument
1059 hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, in dw_hdmi_phy_gen2_txpwron()
1065 static void dw_hdmi_phy_sel_data_en_pol(struct dw_hdmi *hdmi, u8 enable) in dw_hdmi_phy_sel_data_en_pol() argument
1067 hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, in dw_hdmi_phy_sel_data_en_pol()
1072 static void dw_hdmi_phy_sel_interface_control(struct dw_hdmi *hdmi, u8 enable) in dw_hdmi_phy_sel_interface_control() argument
1074 hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, in dw_hdmi_phy_sel_interface_control()
1079 void dw_hdmi_phy_reset(struct dw_hdmi *hdmi) in dw_hdmi_phy_reset() argument
1082 hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_PHYRSTZ, HDMI_MC_PHYRSTZ); in dw_hdmi_phy_reset()
1083 hdmi_writeb(hdmi, 0, HDMI_MC_PHYRSTZ); in dw_hdmi_phy_reset()
1087 void dw_hdmi_phy_i2c_set_addr(struct dw_hdmi *hdmi, u8 address) in dw_hdmi_phy_i2c_set_addr() argument
1089 hdmi_phy_test_clear(hdmi, 1); in dw_hdmi_phy_i2c_set_addr()
1090 hdmi_writeb(hdmi, address, HDMI_PHY_I2CM_SLAVE_ADDR); in dw_hdmi_phy_i2c_set_addr()
1091 hdmi_phy_test_clear(hdmi, 0); in dw_hdmi_phy_i2c_set_addr()
1095 static void dw_hdmi_phy_power_off(struct dw_hdmi *hdmi) in dw_hdmi_phy_power_off() argument
1097 const struct dw_hdmi_phy_data *phy = hdmi->phy.data; in dw_hdmi_phy_power_off()
1102 dw_hdmi_phy_enable_tmds(hdmi, 0); in dw_hdmi_phy_power_off()
1103 dw_hdmi_phy_enable_powerdown(hdmi, true); in dw_hdmi_phy_power_off()
1107 dw_hdmi_phy_gen2_txpwron(hdmi, 0); in dw_hdmi_phy_power_off()
1114 val = hdmi_readb(hdmi, HDMI_PHY_STAT0); in dw_hdmi_phy_power_off()
1122 dev_warn(hdmi->dev, "PHY failed to power down\n"); in dw_hdmi_phy_power_off()
1124 dev_dbg(hdmi->dev, "PHY powered down in %u iterations\n", i); in dw_hdmi_phy_power_off()
1126 dw_hdmi_phy_gen2_pddq(hdmi, 1); in dw_hdmi_phy_power_off()
1129 static int dw_hdmi_phy_power_on(struct dw_hdmi *hdmi) in dw_hdmi_phy_power_on() argument
1131 const struct dw_hdmi_phy_data *phy = hdmi->phy.data; in dw_hdmi_phy_power_on()
1136 dw_hdmi_phy_enable_powerdown(hdmi, false); in dw_hdmi_phy_power_on()
1139 dw_hdmi_phy_enable_tmds(hdmi, 0); in dw_hdmi_phy_power_on()
1140 dw_hdmi_phy_enable_tmds(hdmi, 1); in dw_hdmi_phy_power_on()
1144 dw_hdmi_phy_gen2_txpwron(hdmi, 1); in dw_hdmi_phy_power_on()
1145 dw_hdmi_phy_gen2_pddq(hdmi, 0); in dw_hdmi_phy_power_on()
1149 val = hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_TX_PHY_LOCK; in dw_hdmi_phy_power_on()
1157 dev_err(hdmi->dev, "PHY PLL failed to lock\n"); in dw_hdmi_phy_power_on()
1161 dev_dbg(hdmi->dev, "PHY PLL locked %u iterations\n", i); in dw_hdmi_phy_power_on()
1166 * PHY configuration function for the DWC HDMI 3D TX PHY. Based on the available
1170 static int hdmi_phy_configure_dwc_hdmi_3d_tx(struct dw_hdmi *hdmi, in hdmi_phy_configure_dwc_hdmi_3d_tx() argument
1196 dw_hdmi_phy_i2c_write(hdmi, mpll_config->res[0].cpce, in hdmi_phy_configure_dwc_hdmi_3d_tx()
1198 dw_hdmi_phy_i2c_write(hdmi, mpll_config->res[0].gmp, in hdmi_phy_configure_dwc_hdmi_3d_tx()
1200 dw_hdmi_phy_i2c_write(hdmi, curr_ctrl->curr[0], in hdmi_phy_configure_dwc_hdmi_3d_tx()
1203 dw_hdmi_phy_i2c_write(hdmi, 0, HDMI_3D_TX_PHY_PLLPHBYCTRL); in hdmi_phy_configure_dwc_hdmi_3d_tx()
1204 dw_hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_MSM_CTRL_CKO_SEL_FB_CLK, in hdmi_phy_configure_dwc_hdmi_3d_tx()
1207 dw_hdmi_phy_i2c_write(hdmi, phy_config->term, HDMI_3D_TX_PHY_TXTERM); in hdmi_phy_configure_dwc_hdmi_3d_tx()
1208 dw_hdmi_phy_i2c_write(hdmi, phy_config->sym_ctr, in hdmi_phy_configure_dwc_hdmi_3d_tx()
1210 dw_hdmi_phy_i2c_write(hdmi, phy_config->vlev_ctr, in hdmi_phy_configure_dwc_hdmi_3d_tx()
1214 dw_hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_CKCALCTRL_OVERRIDE, in hdmi_phy_configure_dwc_hdmi_3d_tx()
1220 static int hdmi_phy_configure(struct dw_hdmi *hdmi) in hdmi_phy_configure() argument
1222 const struct dw_hdmi_phy_data *phy = hdmi->phy.data; in hdmi_phy_configure()
1223 const struct dw_hdmi_plat_data *pdata = hdmi->plat_data; in hdmi_phy_configure()
1224 unsigned long mpixelclock = hdmi->hdmi_data.video_mode.mpixelclock; in hdmi_phy_configure()
1227 dw_hdmi_phy_power_off(hdmi); in hdmi_phy_configure()
1231 dw_hdmi_phy_enable_svsret(hdmi, 1); in hdmi_phy_configure()
1233 dw_hdmi_phy_reset(hdmi); in hdmi_phy_configure()
1235 hdmi_writeb(hdmi, HDMI_MC_HEACPHY_RST_ASSERT, HDMI_MC_HEACPHY_RST); in hdmi_phy_configure()
1237 dw_hdmi_phy_i2c_set_addr(hdmi, HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2); in hdmi_phy_configure()
1241 ret = pdata->configure_phy(hdmi, pdata, mpixelclock); in hdmi_phy_configure()
1243 ret = phy->configure(hdmi, pdata, mpixelclock); in hdmi_phy_configure()
1245 dev_err(hdmi->dev, "PHY configuration failed (clock %lu)\n", in hdmi_phy_configure()
1250 return dw_hdmi_phy_power_on(hdmi); in hdmi_phy_configure()
1253 static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data, in dw_hdmi_phy_init() argument
1258 /* HDMI Phy spec says to do the phy initialization sequence twice */ in dw_hdmi_phy_init()
1260 dw_hdmi_phy_sel_data_en_pol(hdmi, 1); in dw_hdmi_phy_init()
1261 dw_hdmi_phy_sel_interface_control(hdmi, 0); in dw_hdmi_phy_init()
1263 ret = hdmi_phy_configure(hdmi); in dw_hdmi_phy_init()
1271 static void dw_hdmi_phy_disable(struct dw_hdmi *hdmi, void *data) in dw_hdmi_phy_disable() argument
1273 dw_hdmi_phy_power_off(hdmi); in dw_hdmi_phy_disable()
1276 enum drm_connector_status dw_hdmi_phy_read_hpd(struct dw_hdmi *hdmi, in dw_hdmi_phy_read_hpd() argument
1279 return hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD ? in dw_hdmi_phy_read_hpd()
1284 void dw_hdmi_phy_update_hpd(struct dw_hdmi *hdmi, void *data, in dw_hdmi_phy_update_hpd() argument
1287 u8 old_mask = hdmi->phy_mask; in dw_hdmi_phy_update_hpd()
1290 hdmi->phy_mask |= HDMI_PHY_RX_SENSE; in dw_hdmi_phy_update_hpd()
1292 hdmi->phy_mask &= ~HDMI_PHY_RX_SENSE; in dw_hdmi_phy_update_hpd()
1294 if (old_mask != hdmi->phy_mask) in dw_hdmi_phy_update_hpd()
1295 hdmi_writeb(hdmi, hdmi->phy_mask, HDMI_PHY_MASK0); in dw_hdmi_phy_update_hpd()
1299 void dw_hdmi_phy_setup_hpd(struct dw_hdmi *hdmi, void *data) in dw_hdmi_phy_setup_hpd() argument
1305 hdmi_writeb(hdmi, HDMI_PHY_HPD | HDMI_PHY_RX_SENSE, HDMI_PHY_POL0); in dw_hdmi_phy_setup_hpd()
1306 hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE, in dw_hdmi_phy_setup_hpd()
1310 hdmi_writeb(hdmi, hdmi->phy_mask, HDMI_PHY_MASK0); in dw_hdmi_phy_setup_hpd()
1313 hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE, in dw_hdmi_phy_setup_hpd()
1315 hdmi_writeb(hdmi, ~(HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE), in dw_hdmi_phy_setup_hpd()
1329 * HDMI TX Setup
1332 static void hdmi_tx_hdcp_config(struct dw_hdmi *hdmi) in hdmi_tx_hdcp_config() argument
1336 if (hdmi->hdmi_data.video_mode.mdataenablepolarity) in hdmi_tx_hdcp_config()
1342 hdmi_modb(hdmi, HDMI_A_HDCPCFG0_RXDETECT_DISABLE, in hdmi_tx_hdcp_config()
1345 hdmi_modb(hdmi, de, HDMI_A_VIDPOLCFG_DATAENPOL_MASK, HDMI_A_VIDPOLCFG); in hdmi_tx_hdcp_config()
1347 hdmi_modb(hdmi, HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_DISABLE, in hdmi_tx_hdcp_config()
1351 static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode) in hdmi_config_AVI() argument
1359 if (hdmi_bus_fmt_is_yuv444(hdmi->hdmi_data.enc_out_bus_format)) in hdmi_config_AVI()
1361 else if (hdmi_bus_fmt_is_yuv422(hdmi->hdmi_data.enc_out_bus_format)) in hdmi_config_AVI()
1367 if (!hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format)) { in hdmi_config_AVI()
1368 switch (hdmi->hdmi_data.enc_out_encoding) { in hdmi_config_AVI()
1370 if (hdmi->hdmi_data.enc_in_encoding == V4L2_YCBCR_ENC_XV601) in hdmi_config_AVI()
1378 if (hdmi->hdmi_data.enc_in_encoding == V4L2_YCBCR_ENC_XV709) in hdmi_config_AVI()
1417 hdmi_writeb(hdmi, val, HDMI_FC_AVICONF0); in hdmi_config_AVI()
1423 hdmi_writeb(hdmi, val, HDMI_FC_AVICONF1); in hdmi_config_AVI()
1431 hdmi_writeb(hdmi, val, HDMI_FC_AVICONF2); in hdmi_config_AVI()
1435 hdmi_writeb(hdmi, val, HDMI_FC_AVIVID); in hdmi_config_AVI()
1438 val = (((hdmi->hdmi_data.video_mode.mpixelrepetitioninput + 1) << in hdmi_config_AVI()
1441 ((hdmi->hdmi_data.video_mode.mpixelrepetitionoutput << in hdmi_config_AVI()
1444 hdmi_writeb(hdmi, val, HDMI_FC_PRCONF); in hdmi_config_AVI()
1452 hdmi_writeb(hdmi, val, HDMI_FC_AVICONF3); in hdmi_config_AVI()
1455 hdmi_writeb(hdmi, frame.top_bar & 0xff, HDMI_FC_AVIETB0); in hdmi_config_AVI()
1456 hdmi_writeb(hdmi, (frame.top_bar >> 8) & 0xff, HDMI_FC_AVIETB1); in hdmi_config_AVI()
1457 hdmi_writeb(hdmi, frame.bottom_bar & 0xff, HDMI_FC_AVISBB0); in hdmi_config_AVI()
1458 hdmi_writeb(hdmi, (frame.bottom_bar >> 8) & 0xff, HDMI_FC_AVISBB1); in hdmi_config_AVI()
1459 hdmi_writeb(hdmi, frame.left_bar & 0xff, HDMI_FC_AVIELB0); in hdmi_config_AVI()
1460 hdmi_writeb(hdmi, (frame.left_bar >> 8) & 0xff, HDMI_FC_AVIELB1); in hdmi_config_AVI()
1461 hdmi_writeb(hdmi, frame.right_bar & 0xff, HDMI_FC_AVISRB0); in hdmi_config_AVI()
1462 hdmi_writeb(hdmi, (frame.right_bar >> 8) & 0xff, HDMI_FC_AVISRB1); in hdmi_config_AVI()
1465 static void hdmi_config_vendor_specific_infoframe(struct dw_hdmi *hdmi, in hdmi_config_vendor_specific_infoframe() argument
1473 &hdmi->connector, in hdmi_config_vendor_specific_infoframe()
1486 dev_err(hdmi->dev, "Failed to pack vendor infoframe: %zd\n", in hdmi_config_vendor_specific_infoframe()
1490 hdmi_mask_writeb(hdmi, 0, HDMI_FC_DATAUTO0, HDMI_FC_DATAUTO0_VSD_OFFSET, in hdmi_config_vendor_specific_infoframe()
1493 /* Set the length of HDMI vendor specific InfoFrame payload */ in hdmi_config_vendor_specific_infoframe()
1494 hdmi_writeb(hdmi, buffer[2], HDMI_FC_VSDSIZE); in hdmi_config_vendor_specific_infoframe()
1497 hdmi_writeb(hdmi, buffer[4], HDMI_FC_VSDIEEEID0); in hdmi_config_vendor_specific_infoframe()
1498 hdmi_writeb(hdmi, buffer[5], HDMI_FC_VSDIEEEID1); in hdmi_config_vendor_specific_infoframe()
1499 hdmi_writeb(hdmi, buffer[6], HDMI_FC_VSDIEEEID2); in hdmi_config_vendor_specific_infoframe()
1502 hdmi_writeb(hdmi, buffer[7], HDMI_FC_VSDPAYLOAD0); in hdmi_config_vendor_specific_infoframe()
1503 hdmi_writeb(hdmi, buffer[8], HDMI_FC_VSDPAYLOAD1); in hdmi_config_vendor_specific_infoframe()
1506 hdmi_writeb(hdmi, buffer[9], HDMI_FC_VSDPAYLOAD2); in hdmi_config_vendor_specific_infoframe()
1509 hdmi_writeb(hdmi, 1, HDMI_FC_DATAUTO1); in hdmi_config_vendor_specific_infoframe()
1512 hdmi_writeb(hdmi, 0x11, HDMI_FC_DATAUTO2); in hdmi_config_vendor_specific_infoframe()
1515 hdmi_mask_writeb(hdmi, 1, HDMI_FC_DATAUTO0, HDMI_FC_DATAUTO0_VSD_OFFSET, in hdmi_config_vendor_specific_infoframe()
1519 static void hdmi_av_composer(struct dw_hdmi *hdmi, in hdmi_av_composer() argument
1523 struct hdmi_vmode *vmode = &hdmi->hdmi_data.video_mode; in hdmi_av_composer()
1529 dev_dbg(hdmi->dev, "final pixclk = %d\n", vmode->mpixelclock); in hdmi_av_composer()
1532 inv_val = (hdmi->hdmi_data.hdcp_enable ? in hdmi_av_composer()
1548 if (hdmi->vic == 39) in hdmi_av_composer()
1559 inv_val |= hdmi->sink_is_hdmi ? in hdmi_av_composer()
1563 hdmi_writeb(hdmi, inv_val, HDMI_FC_INVIDCONF); in hdmi_av_composer()
1582 hdmi_writeb(hdmi, mode->hdisplay >> 8, HDMI_FC_INHACTV1); in hdmi_av_composer()
1583 hdmi_writeb(hdmi, mode->hdisplay, HDMI_FC_INHACTV0); in hdmi_av_composer()
1586 hdmi_writeb(hdmi, vdisplay >> 8, HDMI_FC_INVACTV1); in hdmi_av_composer()
1587 hdmi_writeb(hdmi, vdisplay, HDMI_FC_INVACTV0); in hdmi_av_composer()
1591 hdmi_writeb(hdmi, hblank >> 8, HDMI_FC_INHBLANK1); in hdmi_av_composer()
1592 hdmi_writeb(hdmi, hblank, HDMI_FC_INHBLANK0); in hdmi_av_composer()
1595 hdmi_writeb(hdmi, vblank, HDMI_FC_INVBLANK); in hdmi_av_composer()
1599 hdmi_writeb(hdmi, h_de_hs >> 8, HDMI_FC_HSYNCINDELAY1); in hdmi_av_composer()
1600 hdmi_writeb(hdmi, h_de_hs, HDMI_FC_HSYNCINDELAY0); in hdmi_av_composer()
1603 hdmi_writeb(hdmi, v_de_vs, HDMI_FC_VSYNCINDELAY); in hdmi_av_composer()
1607 hdmi_writeb(hdmi, hsync_len >> 8, HDMI_FC_HSYNCINWIDTH1); in hdmi_av_composer()
1608 hdmi_writeb(hdmi, hsync_len, HDMI_FC_HSYNCINWIDTH0); in hdmi_av_composer()
1611 hdmi_writeb(hdmi, vsync_len, HDMI_FC_VSYNCINWIDTH); in hdmi_av_composer()
1614 /* HDMI Initialization Step B.4 */
1615 static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi) in dw_hdmi_enable_video_path() argument
1618 hdmi_writeb(hdmi, 12, HDMI_FC_CTRLDUR); in dw_hdmi_enable_video_path()
1619 hdmi_writeb(hdmi, 32, HDMI_FC_EXCTRLDUR); in dw_hdmi_enable_video_path()
1620 hdmi_writeb(hdmi, 1, HDMI_FC_EXCTRLSPAC); in dw_hdmi_enable_video_path()
1623 hdmi_writeb(hdmi, 0x0B, HDMI_FC_CH0PREAM); in dw_hdmi_enable_video_path()
1624 hdmi_writeb(hdmi, 0x16, HDMI_FC_CH1PREAM); in dw_hdmi_enable_video_path()
1625 hdmi_writeb(hdmi, 0x21, HDMI_FC_CH2PREAM); in dw_hdmi_enable_video_path()
1628 hdmi->mc_clkdis |= HDMI_MC_CLKDIS_HDCPCLK_DISABLE | in dw_hdmi_enable_video_path()
1633 hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE; in dw_hdmi_enable_video_path()
1634 hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS); in dw_hdmi_enable_video_path()
1636 hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE; in dw_hdmi_enable_video_path()
1637 hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS); in dw_hdmi_enable_video_path()
1640 if (is_color_space_conversion(hdmi)) { in dw_hdmi_enable_video_path()
1641 hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE; in dw_hdmi_enable_video_path()
1642 hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS); in dw_hdmi_enable_video_path()
1646 if (is_color_space_conversion(hdmi)) in dw_hdmi_enable_video_path()
1647 hdmi_writeb(hdmi, HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH, in dw_hdmi_enable_video_path()
1650 hdmi_writeb(hdmi, HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS, in dw_hdmi_enable_video_path()
1655 static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi) in dw_hdmi_clear_overflow() argument
1667 * The number of iterations matters and depends on the HDMI TX revision in dw_hdmi_clear_overflow()
1676 switch (hdmi->version) { in dw_hdmi_clear_overflow()
1690 hdmi_writeb(hdmi, (u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ, HDMI_MC_SWRSTZ); in dw_hdmi_clear_overflow()
1692 val = hdmi_readb(hdmi, HDMI_FC_INVIDCONF); in dw_hdmi_clear_overflow()
1694 hdmi_writeb(hdmi, val, HDMI_FC_INVIDCONF); in dw_hdmi_clear_overflow()
1697 static void hdmi_disable_overflow_interrupts(struct dw_hdmi *hdmi) in hdmi_disable_overflow_interrupts() argument
1699 hdmi_writeb(hdmi, HDMI_IH_MUTE_FC_STAT2_OVERFLOW_MASK, in hdmi_disable_overflow_interrupts()
1703 static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode) in dw_hdmi_setup() argument
1707 hdmi_disable_overflow_interrupts(hdmi); in dw_hdmi_setup()
1709 hdmi->vic = drm_match_cea_mode(mode); in dw_hdmi_setup()
1711 if (!hdmi->vic) { in dw_hdmi_setup()
1712 dev_dbg(hdmi->dev, "Non-CEA mode used in HDMI\n"); in dw_hdmi_setup()
1714 dev_dbg(hdmi->dev, "CEA mode used vic=%d\n", hdmi->vic); in dw_hdmi_setup()
1717 if ((hdmi->vic == 6) || (hdmi->vic == 7) || in dw_hdmi_setup()
1718 (hdmi->vic == 21) || (hdmi->vic == 22) || in dw_hdmi_setup()
1719 (hdmi->vic == 2) || (hdmi->vic == 3) || in dw_hdmi_setup()
1720 (hdmi->vic == 17) || (hdmi->vic == 18)) in dw_hdmi_setup()
1721 hdmi->hdmi_data.enc_out_encoding = V4L2_YCBCR_ENC_601; in dw_hdmi_setup()
1723 hdmi->hdmi_data.enc_out_encoding = V4L2_YCBCR_ENC_709; in dw_hdmi_setup()
1725 hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 0; in dw_hdmi_setup()
1726 hdmi->hdmi_data.video_mode.mpixelrepetitioninput = 0; in dw_hdmi_setup()
1729 if (hdmi->plat_data->input_bus_format) in dw_hdmi_setup()
1730 hdmi->hdmi_data.enc_in_bus_format = in dw_hdmi_setup()
1731 hdmi->plat_data->input_bus_format; in dw_hdmi_setup()
1733 hdmi->hdmi_data.enc_in_bus_format = MEDIA_BUS_FMT_RGB888_1X24; in dw_hdmi_setup()
1736 if (hdmi->plat_data->input_bus_encoding) in dw_hdmi_setup()
1737 hdmi->hdmi_data.enc_in_encoding = in dw_hdmi_setup()
1738 hdmi->plat_data->input_bus_encoding; in dw_hdmi_setup()
1740 hdmi->hdmi_data.enc_in_encoding = V4L2_YCBCR_ENC_DEFAULT; in dw_hdmi_setup()
1743 hdmi->hdmi_data.enc_out_bus_format = MEDIA_BUS_FMT_RGB888_1X24; in dw_hdmi_setup()
1745 hdmi->hdmi_data.pix_repet_factor = 0; in dw_hdmi_setup()
1746 hdmi->hdmi_data.hdcp_enable = 0; in dw_hdmi_setup()
1747 hdmi->hdmi_data.video_mode.mdataenablepolarity = true; in dw_hdmi_setup()
1749 /* HDMI Initialization Step B.1 */ in dw_hdmi_setup()
1750 hdmi_av_composer(hdmi, mode); in dw_hdmi_setup()
1752 /* HDMI Initializateion Step B.2 */ in dw_hdmi_setup()
1753 ret = hdmi->phy.ops->init(hdmi, hdmi->phy.data, &hdmi->previous_mode); in dw_hdmi_setup()
1756 hdmi->phy.enabled = true; in dw_hdmi_setup()
1758 /* HDMI Initialization Step B.3 */ in dw_hdmi_setup()
1759 dw_hdmi_enable_video_path(hdmi); in dw_hdmi_setup()
1761 if (hdmi->sink_has_audio) { in dw_hdmi_setup()
1762 dev_dbg(hdmi->dev, "sink has audio support\n"); in dw_hdmi_setup()
1764 /* HDMI Initialization Step E - Configure audio */ in dw_hdmi_setup()
1765 hdmi_clk_regenerator_update_pixel_clock(hdmi); in dw_hdmi_setup()
1766 hdmi_enable_audio_clk(hdmi, hdmi->audio_enable); in dw_hdmi_setup()
1770 if (hdmi->sink_is_hdmi) { in dw_hdmi_setup()
1771 dev_dbg(hdmi->dev, "%s HDMI mode\n", __func__); in dw_hdmi_setup()
1773 /* HDMI Initialization Step F - Configure AVI InfoFrame */ in dw_hdmi_setup()
1774 hdmi_config_AVI(hdmi, mode); in dw_hdmi_setup()
1775 hdmi_config_vendor_specific_infoframe(hdmi, mode); in dw_hdmi_setup()
1777 dev_dbg(hdmi->dev, "%s DVI mode\n", __func__); in dw_hdmi_setup()
1780 hdmi_video_packetize(hdmi); in dw_hdmi_setup()
1781 hdmi_video_csc(hdmi); in dw_hdmi_setup()
1782 hdmi_video_sample(hdmi); in dw_hdmi_setup()
1783 hdmi_tx_hdcp_config(hdmi); in dw_hdmi_setup()
1785 dw_hdmi_clear_overflow(hdmi); in dw_hdmi_setup()
1790 static void dw_hdmi_setup_i2c(struct dw_hdmi *hdmi) in dw_hdmi_setup_i2c() argument
1792 hdmi_writeb(hdmi, HDMI_PHY_I2CM_INT_ADDR_DONE_POL, in dw_hdmi_setup_i2c()
1795 hdmi_writeb(hdmi, HDMI_PHY_I2CM_CTLINT_ADDR_NAC_POL | in dw_hdmi_setup_i2c()
1800 static void initialize_hdmi_ih_mutes(struct dw_hdmi *hdmi) in initialize_hdmi_ih_mutes() argument
1809 * Disable top level interrupt bits in HDMI block in initialize_hdmi_ih_mutes()
1811 ih_mute = hdmi_readb(hdmi, HDMI_IH_MUTE) | in initialize_hdmi_ih_mutes()
1815 hdmi_writeb(hdmi, ih_mute, HDMI_IH_MUTE); in initialize_hdmi_ih_mutes()
1818 hdmi_writeb(hdmi, 0xff, HDMI_VP_MASK); in initialize_hdmi_ih_mutes()
1819 hdmi_writeb(hdmi, 0xff, HDMI_FC_MASK0); in initialize_hdmi_ih_mutes()
1820 hdmi_writeb(hdmi, 0xff, HDMI_FC_MASK1); in initialize_hdmi_ih_mutes()
1821 hdmi_writeb(hdmi, 0xff, HDMI_FC_MASK2); in initialize_hdmi_ih_mutes()
1822 hdmi_writeb(hdmi, 0xff, HDMI_PHY_MASK0); in initialize_hdmi_ih_mutes()
1823 hdmi_writeb(hdmi, 0xff, HDMI_PHY_I2CM_INT_ADDR); in initialize_hdmi_ih_mutes()
1824 hdmi_writeb(hdmi, 0xff, HDMI_PHY_I2CM_CTLINT_ADDR); in initialize_hdmi_ih_mutes()
1825 hdmi_writeb(hdmi, 0xff, HDMI_AUD_INT); in initialize_hdmi_ih_mutes()
1826 hdmi_writeb(hdmi, 0xff, HDMI_AUD_SPDIFINT); in initialize_hdmi_ih_mutes()
1827 hdmi_writeb(hdmi, 0xff, HDMI_AUD_HBR_MASK); in initialize_hdmi_ih_mutes()
1828 hdmi_writeb(hdmi, 0xff, HDMI_GP_MASK); in initialize_hdmi_ih_mutes()
1829 hdmi_writeb(hdmi, 0xff, HDMI_A_APIINTMSK); in initialize_hdmi_ih_mutes()
1830 hdmi_writeb(hdmi, 0xff, HDMI_I2CM_INT); in initialize_hdmi_ih_mutes()
1831 hdmi_writeb(hdmi, 0xff, HDMI_I2CM_CTLINT); in initialize_hdmi_ih_mutes()
1834 hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_FC_STAT0); in initialize_hdmi_ih_mutes()
1835 hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_FC_STAT1); in initialize_hdmi_ih_mutes()
1836 hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_FC_STAT2); in initialize_hdmi_ih_mutes()
1837 hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_AS_STAT0); in initialize_hdmi_ih_mutes()
1838 hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_PHY_STAT0); in initialize_hdmi_ih_mutes()
1839 hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_I2CM_STAT0); in initialize_hdmi_ih_mutes()
1840 hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_CEC_STAT0); in initialize_hdmi_ih_mutes()
1841 hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_VP_STAT0); in initialize_hdmi_ih_mutes()
1842 hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_I2CMPHY_STAT0); in initialize_hdmi_ih_mutes()
1843 hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_AHBDMAAUD_STAT0); in initialize_hdmi_ih_mutes()
1845 /* Enable top level interrupt bits in HDMI block */ in initialize_hdmi_ih_mutes()
1848 hdmi_writeb(hdmi, ih_mute, HDMI_IH_MUTE); in initialize_hdmi_ih_mutes()
1851 static void dw_hdmi_poweron(struct dw_hdmi *hdmi) in dw_hdmi_poweron() argument
1853 hdmi->bridge_is_on = true; in dw_hdmi_poweron()
1854 dw_hdmi_setup(hdmi, &hdmi->previous_mode); in dw_hdmi_poweron()
1857 static void dw_hdmi_poweroff(struct dw_hdmi *hdmi) in dw_hdmi_poweroff() argument
1859 if (hdmi->phy.enabled) { in dw_hdmi_poweroff()
1860 hdmi->phy.ops->disable(hdmi, hdmi->phy.data); in dw_hdmi_poweroff()
1861 hdmi->phy.enabled = false; in dw_hdmi_poweroff()
1864 hdmi->bridge_is_on = false; in dw_hdmi_poweroff()
1867 static void dw_hdmi_update_power(struct dw_hdmi *hdmi) in dw_hdmi_update_power() argument
1869 int force = hdmi->force; in dw_hdmi_update_power()
1871 if (hdmi->disabled) { in dw_hdmi_update_power()
1874 if (hdmi->rxsense) in dw_hdmi_update_power()
1881 if (hdmi->bridge_is_on) in dw_hdmi_update_power()
1882 dw_hdmi_poweroff(hdmi); in dw_hdmi_update_power()
1884 if (!hdmi->bridge_is_on) in dw_hdmi_update_power()
1885 dw_hdmi_poweron(hdmi); in dw_hdmi_update_power()
1901 static void dw_hdmi_update_phy_mask(struct dw_hdmi *hdmi) in dw_hdmi_update_phy_mask() argument
1903 if (hdmi->phy.ops->update_hpd) in dw_hdmi_update_phy_mask()
1904 hdmi->phy.ops->update_hpd(hdmi, hdmi->phy.data, in dw_hdmi_update_phy_mask()
1905 hdmi->force, hdmi->disabled, in dw_hdmi_update_phy_mask()
1906 hdmi->rxsense); in dw_hdmi_update_phy_mask()
1912 struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi, in dw_hdmi_connector_detect() local
1915 mutex_lock(&hdmi->mutex); in dw_hdmi_connector_detect()
1916 hdmi->force = DRM_FORCE_UNSPECIFIED; in dw_hdmi_connector_detect()
1917 dw_hdmi_update_power(hdmi); in dw_hdmi_connector_detect()
1918 dw_hdmi_update_phy_mask(hdmi); in dw_hdmi_connector_detect()
1919 mutex_unlock(&hdmi->mutex); in dw_hdmi_connector_detect()
1921 return hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data); in dw_hdmi_connector_detect()
1926 struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi, in dw_hdmi_connector_get_modes() local
1931 if (!hdmi->ddc) in dw_hdmi_connector_get_modes()
1934 edid = drm_get_edid(connector, hdmi->ddc); in dw_hdmi_connector_get_modes()
1936 dev_dbg(hdmi->dev, "got edid: width[%d] x height[%d]\n", in dw_hdmi_connector_get_modes()
1939 hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid); in dw_hdmi_connector_get_modes()
1940 hdmi->sink_has_audio = drm_detect_monitor_audio(edid); in dw_hdmi_connector_get_modes()
1942 cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid); in dw_hdmi_connector_get_modes()
1946 dev_dbg(hdmi->dev, "failed to get edid\n"); in dw_hdmi_connector_get_modes()
1954 struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi, in dw_hdmi_connector_force() local
1957 mutex_lock(&hdmi->mutex); in dw_hdmi_connector_force()
1958 hdmi->force = connector->force; in dw_hdmi_connector_force()
1959 dw_hdmi_update_power(hdmi); in dw_hdmi_connector_force()
1960 dw_hdmi_update_phy_mask(hdmi); in dw_hdmi_connector_force()
1961 mutex_unlock(&hdmi->mutex); in dw_hdmi_connector_force()
1981 struct dw_hdmi *hdmi = bridge->driver_private; in dw_hdmi_bridge_attach() local
1983 struct drm_connector *connector = &hdmi->connector; in dw_hdmi_bridge_attach()
2002 struct dw_hdmi *hdmi = bridge->driver_private; in dw_hdmi_bridge_mode_valid() local
2003 struct drm_connector *connector = &hdmi->connector; in dw_hdmi_bridge_mode_valid()
2010 if (hdmi->plat_data->mode_valid) in dw_hdmi_bridge_mode_valid()
2011 mode_status = hdmi->plat_data->mode_valid(connector, mode); in dw_hdmi_bridge_mode_valid()
2020 struct dw_hdmi *hdmi = bridge->driver_private; in dw_hdmi_bridge_mode_set() local
2022 mutex_lock(&hdmi->mutex); in dw_hdmi_bridge_mode_set()
2025 memcpy(&hdmi->previous_mode, mode, sizeof(hdmi->previous_mode)); in dw_hdmi_bridge_mode_set()
2027 mutex_unlock(&hdmi->mutex); in dw_hdmi_bridge_mode_set()
2032 struct dw_hdmi *hdmi = bridge->driver_private; in dw_hdmi_bridge_disable() local
2034 mutex_lock(&hdmi->mutex); in dw_hdmi_bridge_disable()
2035 hdmi->disabled = true; in dw_hdmi_bridge_disable()
2036 dw_hdmi_update_power(hdmi); in dw_hdmi_bridge_disable()
2037 dw_hdmi_update_phy_mask(hdmi); in dw_hdmi_bridge_disable()
2038 mutex_unlock(&hdmi->mutex); in dw_hdmi_bridge_disable()
2043 struct dw_hdmi *hdmi = bridge->driver_private; in dw_hdmi_bridge_enable() local
2045 mutex_lock(&hdmi->mutex); in dw_hdmi_bridge_enable()
2046 hdmi->disabled = false; in dw_hdmi_bridge_enable()
2047 dw_hdmi_update_power(hdmi); in dw_hdmi_bridge_enable()
2048 dw_hdmi_update_phy_mask(hdmi); in dw_hdmi_bridge_enable()
2049 mutex_unlock(&hdmi->mutex); in dw_hdmi_bridge_enable()
2060 static irqreturn_t dw_hdmi_i2c_irq(struct dw_hdmi *hdmi) in dw_hdmi_i2c_irq() argument
2062 struct dw_hdmi_i2c *i2c = hdmi->i2c; in dw_hdmi_i2c_irq()
2065 stat = hdmi_readb(hdmi, HDMI_IH_I2CM_STAT0); in dw_hdmi_i2c_irq()
2069 hdmi_writeb(hdmi, stat, HDMI_IH_I2CM_STAT0); in dw_hdmi_i2c_irq()
2080 struct dw_hdmi *hdmi = dev_id; in dw_hdmi_hardirq() local
2084 if (hdmi->i2c) in dw_hdmi_hardirq()
2085 ret = dw_hdmi_i2c_irq(hdmi); in dw_hdmi_hardirq()
2087 intr_stat = hdmi_readb(hdmi, HDMI_IH_PHY_STAT0); in dw_hdmi_hardirq()
2089 hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0); in dw_hdmi_hardirq()
2096 void dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool hpd, bool rx_sense) in dw_hdmi_setup_rx_sense() argument
2098 mutex_lock(&hdmi->mutex); in dw_hdmi_setup_rx_sense()
2100 if (!hdmi->force) { in dw_hdmi_setup_rx_sense()
2106 hdmi->rxsense = false; in dw_hdmi_setup_rx_sense()
2115 hdmi->rxsense = true; in dw_hdmi_setup_rx_sense()
2117 dw_hdmi_update_power(hdmi); in dw_hdmi_setup_rx_sense()
2118 dw_hdmi_update_phy_mask(hdmi); in dw_hdmi_setup_rx_sense()
2120 mutex_unlock(&hdmi->mutex); in dw_hdmi_setup_rx_sense()
2126 struct dw_hdmi *hdmi = dev_id; in dw_hdmi_irq() local
2129 intr_stat = hdmi_readb(hdmi, HDMI_IH_PHY_STAT0); in dw_hdmi_irq()
2130 phy_int_pol = hdmi_readb(hdmi, HDMI_PHY_POL0); in dw_hdmi_irq()
2131 phy_stat = hdmi_readb(hdmi, HDMI_PHY_STAT0); in dw_hdmi_irq()
2146 hdmi_modb(hdmi, ~phy_int_pol, phy_pol_mask, HDMI_PHY_POL0); in dw_hdmi_irq()
2157 dw_hdmi_setup_rx_sense(hdmi, in dw_hdmi_irq()
2162 cec_notifier_set_phys_addr(hdmi->cec_notifier, in dw_hdmi_irq()
2167 dev_dbg(hdmi->dev, "EVENT=%s\n", in dw_hdmi_irq()
2169 if (hdmi->bridge.dev) in dw_hdmi_irq()
2170 drm_helper_hpd_irq_event(hdmi->bridge.dev); in dw_hdmi_irq()
2173 hdmi_writeb(hdmi, intr_stat, HDMI_IH_PHY_STAT0); in dw_hdmi_irq()
2174 hdmi_writeb(hdmi, ~(HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE), in dw_hdmi_irq()
2183 .name = "DWC HDMI TX PHY",
2199 .name = "DWC HDMI 3D TX PHY + HEAC PHY",
2204 .name = "DWC HDMI 3D TX PHY",
2209 .name = "DWC HDMI 2.0 TX PHY",
2219 static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi) in dw_hdmi_detect_phy() argument
2224 phy_type = hdmi_readb(hdmi, HDMI_CONFIG2_ID); in dw_hdmi_detect_phy()
2228 if (!hdmi->plat_data->phy_ops || !hdmi->plat_data->phy_name) { in dw_hdmi_detect_phy()
2229 dev_err(hdmi->dev, in dw_hdmi_detect_phy()
2230 "Vendor HDMI PHY not supported by glue layer\n"); in dw_hdmi_detect_phy()
2234 hdmi->phy.ops = hdmi->plat_data->phy_ops; in dw_hdmi_detect_phy()
2235 hdmi->phy.data = hdmi->plat_data->phy_data; in dw_hdmi_detect_phy()
2236 hdmi->phy.name = hdmi->plat_data->phy_name; in dw_hdmi_detect_phy()
2243 hdmi->phy.ops = &dw_hdmi_synopsys_phy_ops; in dw_hdmi_detect_phy()
2244 hdmi->phy.name = dw_hdmi_phys[i].name; in dw_hdmi_detect_phy()
2245 hdmi->phy.data = (void *)&dw_hdmi_phys[i]; in dw_hdmi_detect_phy()
2248 !hdmi->plat_data->configure_phy) { in dw_hdmi_detect_phy()
2249 dev_err(hdmi->dev, "%s requires platform support\n", in dw_hdmi_detect_phy()
2250 hdmi->phy.name); in dw_hdmi_detect_phy()
2258 dev_err(hdmi->dev, "Unsupported HDMI PHY type (%02x)\n", phy_type); in dw_hdmi_detect_phy()
2262 static void dw_hdmi_cec_enable(struct dw_hdmi *hdmi) in dw_hdmi_cec_enable() argument
2264 mutex_lock(&hdmi->mutex); in dw_hdmi_cec_enable()
2265 hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_CECCLK_DISABLE; in dw_hdmi_cec_enable()
2266 hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS); in dw_hdmi_cec_enable()
2267 mutex_unlock(&hdmi->mutex); in dw_hdmi_cec_enable()
2270 static void dw_hdmi_cec_disable(struct dw_hdmi *hdmi) in dw_hdmi_cec_disable() argument
2272 mutex_lock(&hdmi->mutex); in dw_hdmi_cec_disable()
2273 hdmi->mc_clkdis |= HDMI_MC_CLKDIS_CECCLK_DISABLE; in dw_hdmi_cec_disable()
2274 hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS); in dw_hdmi_cec_disable()
2275 mutex_unlock(&hdmi->mutex); in dw_hdmi_cec_disable()
2308 struct dw_hdmi *hdmi; in __dw_hdmi_probe() local
2318 hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL); in __dw_hdmi_probe()
2319 if (!hdmi) in __dw_hdmi_probe()
2322 hdmi->plat_data = plat_data; in __dw_hdmi_probe()
2323 hdmi->dev = dev; in __dw_hdmi_probe()
2324 hdmi->sample_rate = 48000; in __dw_hdmi_probe()
2325 hdmi->disabled = true; in __dw_hdmi_probe()
2326 hdmi->rxsense = true; in __dw_hdmi_probe()
2327 hdmi->phy_mask = (u8)~(HDMI_PHY_HPD | HDMI_PHY_RX_SENSE); in __dw_hdmi_probe()
2328 hdmi->mc_clkdis = 0x7f; in __dw_hdmi_probe()
2330 mutex_init(&hdmi->mutex); in __dw_hdmi_probe()
2331 mutex_init(&hdmi->audio_mutex); in __dw_hdmi_probe()
2332 spin_lock_init(&hdmi->audio_lock); in __dw_hdmi_probe()
2336 hdmi->ddc = of_get_i2c_adapter_by_node(ddc_node); in __dw_hdmi_probe()
2338 if (!hdmi->ddc) { in __dw_hdmi_probe()
2339 dev_dbg(hdmi->dev, "failed to read ddc node\n"); in __dw_hdmi_probe()
2344 dev_dbg(hdmi->dev, "no ddc property found\n"); in __dw_hdmi_probe()
2354 hdmi->reg_shift = 2; in __dw_hdmi_probe()
2365 hdmi->regs = devm_ioremap_resource(dev, iores); in __dw_hdmi_probe()
2366 if (IS_ERR(hdmi->regs)) { in __dw_hdmi_probe()
2367 ret = PTR_ERR(hdmi->regs); in __dw_hdmi_probe()
2371 hdmi->regm = devm_regmap_init_mmio(dev, hdmi->regs, reg_config); in __dw_hdmi_probe()
2372 if (IS_ERR(hdmi->regm)) { in __dw_hdmi_probe()
2374 ret = PTR_ERR(hdmi->regm); in __dw_hdmi_probe()
2378 hdmi->regm = plat_data->regm; in __dw_hdmi_probe()
2381 hdmi->isfr_clk = devm_clk_get(hdmi->dev, "isfr"); in __dw_hdmi_probe()
2382 if (IS_ERR(hdmi->isfr_clk)) { in __dw_hdmi_probe()
2383 ret = PTR_ERR(hdmi->isfr_clk); in __dw_hdmi_probe()
2384 dev_err(hdmi->dev, "Unable to get HDMI isfr clk: %d\n", ret); in __dw_hdmi_probe()
2388 ret = clk_prepare_enable(hdmi->isfr_clk); in __dw_hdmi_probe()
2390 dev_err(hdmi->dev, "Cannot enable HDMI isfr clock: %d\n", ret); in __dw_hdmi_probe()
2394 hdmi->iahb_clk = devm_clk_get(hdmi->dev, "iahb"); in __dw_hdmi_probe()
2395 if (IS_ERR(hdmi->iahb_clk)) { in __dw_hdmi_probe()
2396 ret = PTR_ERR(hdmi->iahb_clk); in __dw_hdmi_probe()
2397 dev_err(hdmi->dev, "Unable to get HDMI iahb clk: %d\n", ret); in __dw_hdmi_probe()
2401 ret = clk_prepare_enable(hdmi->iahb_clk); in __dw_hdmi_probe()
2403 dev_err(hdmi->dev, "Cannot enable HDMI iahb clock: %d\n", ret); in __dw_hdmi_probe()
2407 hdmi->cec_clk = devm_clk_get(hdmi->dev, "cec"); in __dw_hdmi_probe()
2408 if (PTR_ERR(hdmi->cec_clk) == -ENOENT) { in __dw_hdmi_probe()
2409 hdmi->cec_clk = NULL; in __dw_hdmi_probe()
2410 } else if (IS_ERR(hdmi->cec_clk)) { in __dw_hdmi_probe()
2411 ret = PTR_ERR(hdmi->cec_clk); in __dw_hdmi_probe()
2413 dev_err(hdmi->dev, "Cannot get HDMI cec clock: %d\n", in __dw_hdmi_probe()
2416 hdmi->cec_clk = NULL; in __dw_hdmi_probe()
2419 ret = clk_prepare_enable(hdmi->cec_clk); in __dw_hdmi_probe()
2421 dev_err(hdmi->dev, "Cannot enable HDMI cec clock: %d\n", in __dw_hdmi_probe()
2428 hdmi->version = (hdmi_readb(hdmi, HDMI_DESIGN_ID) << 8) in __dw_hdmi_probe()
2429 | (hdmi_readb(hdmi, HDMI_REVISION_ID) << 0); in __dw_hdmi_probe()
2430 prod_id0 = hdmi_readb(hdmi, HDMI_PRODUCT_ID0); in __dw_hdmi_probe()
2431 prod_id1 = hdmi_readb(hdmi, HDMI_PRODUCT_ID1); in __dw_hdmi_probe()
2435 dev_err(dev, "Unsupported HDMI controller (%04x:%02x:%02x)\n", in __dw_hdmi_probe()
2436 hdmi->version, prod_id0, prod_id1); in __dw_hdmi_probe()
2441 ret = dw_hdmi_detect_phy(hdmi); in __dw_hdmi_probe()
2445 dev_info(dev, "Detected HDMI TX controller v%x.%03x %s HDCP (%s)\n", in __dw_hdmi_probe()
2446 hdmi->version >> 12, hdmi->version & 0xfff, in __dw_hdmi_probe()
2448 hdmi->phy.name); in __dw_hdmi_probe()
2450 initialize_hdmi_ih_mutes(hdmi); in __dw_hdmi_probe()
2460 dev_name(dev), hdmi); in __dw_hdmi_probe()
2464 hdmi->cec_notifier = cec_notifier_get(dev); in __dw_hdmi_probe()
2465 if (!hdmi->cec_notifier) { in __dw_hdmi_probe()
2474 hdmi_init_clk_regenerator(hdmi); in __dw_hdmi_probe()
2476 /* If DDC bus is not specified, try to register HDMI I2C bus */ in __dw_hdmi_probe()
2477 if (!hdmi->ddc) { in __dw_hdmi_probe()
2478 hdmi->ddc = dw_hdmi_i2c_adapter(hdmi); in __dw_hdmi_probe()
2479 if (IS_ERR(hdmi->ddc)) in __dw_hdmi_probe()
2480 hdmi->ddc = NULL; in __dw_hdmi_probe()
2483 hdmi->bridge.driver_private = hdmi; in __dw_hdmi_probe()
2484 hdmi->bridge.funcs = &dw_hdmi_bridge_funcs; in __dw_hdmi_probe()
2486 hdmi->bridge.of_node = pdev->dev.of_node; in __dw_hdmi_probe()
2489 dw_hdmi_setup_i2c(hdmi); in __dw_hdmi_probe()
2490 if (hdmi->phy.ops->setup_hpd) in __dw_hdmi_probe()
2491 hdmi->phy.ops->setup_hpd(hdmi, hdmi->phy.data); in __dw_hdmi_probe()
2497 config0 = hdmi_readb(hdmi, HDMI_CONFIG0_ID); in __dw_hdmi_probe()
2498 config3 = hdmi_readb(hdmi, HDMI_CONFIG3_ID); in __dw_hdmi_probe()
2504 audio.base = hdmi->regs; in __dw_hdmi_probe()
2506 audio.hdmi = hdmi; in __dw_hdmi_probe()
2507 audio.eld = hdmi->connector.eld; in __dw_hdmi_probe()
2508 hdmi->enable_audio = dw_hdmi_ahb_audio_enable; in __dw_hdmi_probe()
2509 hdmi->disable_audio = dw_hdmi_ahb_audio_disable; in __dw_hdmi_probe()
2511 pdevinfo.name = "dw-hdmi-ahb-audio"; in __dw_hdmi_probe()
2515 hdmi->audio = platform_device_register_full(&pdevinfo); in __dw_hdmi_probe()
2519 audio.hdmi = hdmi; in __dw_hdmi_probe()
2522 hdmi->enable_audio = dw_hdmi_i2s_audio_enable; in __dw_hdmi_probe()
2523 hdmi->disable_audio = dw_hdmi_i2s_audio_disable; in __dw_hdmi_probe()
2525 pdevinfo.name = "dw-hdmi-i2s-audio"; in __dw_hdmi_probe()
2529 hdmi->audio = platform_device_register_full(&pdevinfo); in __dw_hdmi_probe()
2533 cec.hdmi = hdmi; in __dw_hdmi_probe()
2537 pdevinfo.name = "dw-hdmi-cec"; in __dw_hdmi_probe()
2542 hdmi->cec = platform_device_register_full(&pdevinfo); in __dw_hdmi_probe()
2545 /* Reset HDMI DDC I2C master controller and mute I2CM interrupts */ in __dw_hdmi_probe()
2546 if (hdmi->i2c) in __dw_hdmi_probe()
2547 dw_hdmi_i2c_init(hdmi); in __dw_hdmi_probe()
2549 return hdmi; in __dw_hdmi_probe()
2552 if (hdmi->i2c) { in __dw_hdmi_probe()
2553 i2c_del_adapter(&hdmi->i2c->adap); in __dw_hdmi_probe()
2554 hdmi->ddc = NULL; in __dw_hdmi_probe()
2557 if (hdmi->cec_notifier) in __dw_hdmi_probe()
2558 cec_notifier_put(hdmi->cec_notifier); in __dw_hdmi_probe()
2560 clk_disable_unprepare(hdmi->iahb_clk); in __dw_hdmi_probe()
2561 if (hdmi->cec_clk) in __dw_hdmi_probe()
2562 clk_disable_unprepare(hdmi->cec_clk); in __dw_hdmi_probe()
2564 clk_disable_unprepare(hdmi->isfr_clk); in __dw_hdmi_probe()
2566 i2c_put_adapter(hdmi->ddc); in __dw_hdmi_probe()
2571 static void __dw_hdmi_remove(struct dw_hdmi *hdmi) in __dw_hdmi_remove() argument
2573 if (hdmi->audio && !IS_ERR(hdmi->audio)) in __dw_hdmi_remove()
2574 platform_device_unregister(hdmi->audio); in __dw_hdmi_remove()
2575 if (!IS_ERR(hdmi->cec)) in __dw_hdmi_remove()
2576 platform_device_unregister(hdmi->cec); in __dw_hdmi_remove()
2579 hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0); in __dw_hdmi_remove()
2581 if (hdmi->cec_notifier) in __dw_hdmi_remove()
2582 cec_notifier_put(hdmi->cec_notifier); in __dw_hdmi_remove()
2584 clk_disable_unprepare(hdmi->iahb_clk); in __dw_hdmi_remove()
2585 clk_disable_unprepare(hdmi->isfr_clk); in __dw_hdmi_remove()
2586 if (hdmi->cec_clk) in __dw_hdmi_remove()
2587 clk_disable_unprepare(hdmi->cec_clk); in __dw_hdmi_remove()
2589 if (hdmi->i2c) in __dw_hdmi_remove()
2590 i2c_del_adapter(&hdmi->i2c->adap); in __dw_hdmi_remove()
2592 i2c_put_adapter(hdmi->ddc); in __dw_hdmi_remove()
2601 struct dw_hdmi *hdmi; in dw_hdmi_probe() local
2603 hdmi = __dw_hdmi_probe(pdev, plat_data); in dw_hdmi_probe()
2604 if (IS_ERR(hdmi)) in dw_hdmi_probe()
2605 return hdmi; in dw_hdmi_probe()
2607 drm_bridge_add(&hdmi->bridge); in dw_hdmi_probe()
2609 return hdmi; in dw_hdmi_probe()
2613 void dw_hdmi_remove(struct dw_hdmi *hdmi) in dw_hdmi_remove() argument
2615 drm_bridge_remove(&hdmi->bridge); in dw_hdmi_remove()
2617 __dw_hdmi_remove(hdmi); in dw_hdmi_remove()
2628 struct dw_hdmi *hdmi; in dw_hdmi_bind() local
2631 hdmi = __dw_hdmi_probe(pdev, plat_data); in dw_hdmi_bind()
2632 if (IS_ERR(hdmi)) in dw_hdmi_bind()
2633 return hdmi; in dw_hdmi_bind()
2635 ret = drm_bridge_attach(encoder, &hdmi->bridge, NULL); in dw_hdmi_bind()
2637 dw_hdmi_remove(hdmi); in dw_hdmi_bind()
2642 return hdmi; in dw_hdmi_bind()
2646 void dw_hdmi_unbind(struct dw_hdmi *hdmi) in dw_hdmi_unbind() argument
2648 __dw_hdmi_remove(hdmi); in dw_hdmi_unbind()
2656 MODULE_DESCRIPTION("DW HDMI transmitter driver");
2658 MODULE_ALIAS("platform:dw-hdmi");