Lines Matching full:hdmi

10 #include <linux/hdmi.h>
28 #include <sound/hdmi-codec.h>
30 #include "dw-hdmi-qp.h"
65 static void dw_hdmi_qp_write(struct dw_hdmi_qp *hdmi, unsigned int val, in dw_hdmi_qp_write() argument
68 regmap_write(hdmi->regm, offset, val); in dw_hdmi_qp_write()
71 static unsigned int dw_hdmi_qp_read(struct dw_hdmi_qp *hdmi, int offset) in dw_hdmi_qp_read() argument
75 regmap_read(hdmi->regm, offset, &val); in dw_hdmi_qp_read()
80 static void dw_hdmi_qp_mod(struct dw_hdmi_qp *hdmi, unsigned int data, in dw_hdmi_qp_mod() argument
83 regmap_update_bits(hdmi->regm, reg, mask, data); in dw_hdmi_qp_mod()
86 static int dw_hdmi_qp_i2c_read(struct dw_hdmi_qp *hdmi, in dw_hdmi_qp_i2c_read() argument
89 struct dw_hdmi_qp_i2c *i2c = hdmi->i2c; in dw_hdmi_qp_i2c_read()
93 dev_dbg(hdmi->dev, "set read register address to 0\n"); in dw_hdmi_qp_i2c_read()
101 dw_hdmi_qp_mod(hdmi, i2c->slave_reg++ << 12, I2CM_ADDR, in dw_hdmi_qp_i2c_read()
105 dw_hdmi_qp_mod(hdmi, I2CM_EXT_READ, I2CM_WR_MASK, in dw_hdmi_qp_i2c_read()
108 dw_hdmi_qp_mod(hdmi, I2CM_FM_READ, I2CM_WR_MASK, in dw_hdmi_qp_i2c_read()
113 dev_err(hdmi->dev, "i2c read timed out\n"); in dw_hdmi_qp_i2c_read()
114 dw_hdmi_qp_write(hdmi, 0x01, I2CM_CONTROL0); in dw_hdmi_qp_i2c_read()
120 dev_err(hdmi->dev, "i2c read error\n"); in dw_hdmi_qp_i2c_read()
121 dw_hdmi_qp_write(hdmi, 0x01, I2CM_CONTROL0); in dw_hdmi_qp_i2c_read()
125 *buf++ = dw_hdmi_qp_read(hdmi, I2CM_INTERFACE_RDDATA_0_3) & 0xff; in dw_hdmi_qp_i2c_read()
126 dw_hdmi_qp_mod(hdmi, 0, I2CM_WR_MASK, I2CM_INTERFACE_CONTROL0); in dw_hdmi_qp_i2c_read()
134 static int dw_hdmi_qp_i2c_write(struct dw_hdmi_qp *hdmi, in dw_hdmi_qp_i2c_write() argument
137 struct dw_hdmi_qp_i2c *i2c = hdmi->i2c; in dw_hdmi_qp_i2c_write()
151 dw_hdmi_qp_write(hdmi, *buf++, I2CM_INTERFACE_WRDATA_0_3); in dw_hdmi_qp_i2c_write()
152 dw_hdmi_qp_mod(hdmi, i2c->slave_reg++ << 12, I2CM_ADDR, in dw_hdmi_qp_i2c_write()
154 dw_hdmi_qp_mod(hdmi, I2CM_FM_WRITE, I2CM_WR_MASK, in dw_hdmi_qp_i2c_write()
159 dev_err(hdmi->dev, "i2c write time out!\n"); in dw_hdmi_qp_i2c_write()
160 dw_hdmi_qp_write(hdmi, 0x01, I2CM_CONTROL0); in dw_hdmi_qp_i2c_write()
166 dev_err(hdmi->dev, "i2c write nack!\n"); in dw_hdmi_qp_i2c_write()
167 dw_hdmi_qp_write(hdmi, 0x01, I2CM_CONTROL0); in dw_hdmi_qp_i2c_write()
171 dw_hdmi_qp_mod(hdmi, 0, I2CM_WR_MASK, I2CM_INTERFACE_CONTROL0); in dw_hdmi_qp_i2c_write()
180 struct dw_hdmi_qp *hdmi = i2c_get_adapdata(adap); in dw_hdmi_qp_i2c_xfer() local
181 struct dw_hdmi_qp_i2c *i2c = hdmi->i2c; in dw_hdmi_qp_i2c_xfer()
196 dev_err(hdmi->dev, in dw_hdmi_qp_i2c_xfer()
206 dw_hdmi_qp_mod(hdmi, I2CM_NACK_RCVD_MASK_N | I2CM_OP_DONE_MASK_N, in dw_hdmi_qp_i2c_xfer()
214 dw_hdmi_qp_mod(hdmi, addr << 5, I2CM_SLVADDR, I2CM_INTERFACE_CONTROL0); in dw_hdmi_qp_i2c_xfer()
225 dw_hdmi_qp_mod(hdmi, DDC_SEGMENT_ADDR, I2CM_SEG_ADDR, in dw_hdmi_qp_i2c_xfer()
227 dw_hdmi_qp_mod(hdmi, *msgs[i].buf << 7, I2CM_SEG_PTR, in dw_hdmi_qp_i2c_xfer()
231 ret = dw_hdmi_qp_i2c_read(hdmi, msgs[i].buf, in dw_hdmi_qp_i2c_xfer()
234 ret = dw_hdmi_qp_i2c_write(hdmi, msgs[i].buf, in dw_hdmi_qp_i2c_xfer()
245 dw_hdmi_qp_mod(hdmi, 0, I2CM_OP_DONE_MASK_N | I2CM_NACK_RCVD_MASK_N, in dw_hdmi_qp_i2c_xfer()
261 static struct i2c_adapter *dw_hdmi_qp_i2c_adapter(struct dw_hdmi_qp *hdmi) in dw_hdmi_qp_i2c_adapter() argument
267 i2c = devm_kzalloc(hdmi->dev, sizeof(*i2c), GFP_KERNEL); in dw_hdmi_qp_i2c_adapter()
276 adap->dev.parent = hdmi->dev; in dw_hdmi_qp_i2c_adapter()
278 strscpy(adap->name, "DesignWare HDMI QP", sizeof(adap->name)); in dw_hdmi_qp_i2c_adapter()
280 i2c_set_adapdata(adap, hdmi); in dw_hdmi_qp_i2c_adapter()
282 ret = devm_i2c_add_adapter(hdmi->dev, adap); in dw_hdmi_qp_i2c_adapter()
284 dev_warn(hdmi->dev, "cannot add %s I2C adapter\n", adap->name); in dw_hdmi_qp_i2c_adapter()
285 devm_kfree(hdmi->dev, i2c); in dw_hdmi_qp_i2c_adapter()
289 hdmi->i2c = i2c; in dw_hdmi_qp_i2c_adapter()
290 dev_info(hdmi->dev, "registered %s I2C bus driver\n", adap->name); in dw_hdmi_qp_i2c_adapter()
295 static int dw_hdmi_qp_config_avi_infoframe(struct dw_hdmi_qp *hdmi, in dw_hdmi_qp_config_avi_infoframe() argument
301 dev_err(hdmi->dev, "failed to configure avi infoframe\n"); in dw_hdmi_qp_config_avi_infoframe()
306 * DW HDMI QP IP uses a different byte format from standard AVI info in dw_hdmi_qp_config_avi_infoframe()
310 dw_hdmi_qp_write(hdmi, val, PKT_AVI_CONTENTS0); in dw_hdmi_qp_config_avi_infoframe()
321 dw_hdmi_qp_write(hdmi, val, PKT_AVI_CONTENTS1 + i * 4); in dw_hdmi_qp_config_avi_infoframe()
324 dw_hdmi_qp_mod(hdmi, 0, PKTSCHED_AVI_FIELDRATE, PKTSCHED_PKT_CONFIG1); in dw_hdmi_qp_config_avi_infoframe()
326 dw_hdmi_qp_mod(hdmi, PKTSCHED_AVI_TX_EN | PKTSCHED_GCP_TX_EN, in dw_hdmi_qp_config_avi_infoframe()
332 static int dw_hdmi_qp_config_drm_infoframe(struct dw_hdmi_qp *hdmi, in dw_hdmi_qp_config_drm_infoframe() argument
338 dev_err(hdmi->dev, "failed to configure drm infoframe\n"); in dw_hdmi_qp_config_drm_infoframe()
342 dw_hdmi_qp_mod(hdmi, 0, PKTSCHED_DRMI_TX_EN, PKTSCHED_PKT_EN); in dw_hdmi_qp_config_drm_infoframe()
345 dw_hdmi_qp_write(hdmi, val, PKT_DRMI_CONTENTS0); in dw_hdmi_qp_config_drm_infoframe()
353 dw_hdmi_qp_write(hdmi, val, in dw_hdmi_qp_config_drm_infoframe()
357 dw_hdmi_qp_mod(hdmi, 0, PKTSCHED_DRMI_FIELDRATE, PKTSCHED_PKT_CONFIG1); in dw_hdmi_qp_config_drm_infoframe()
358 dw_hdmi_qp_mod(hdmi, PKTSCHED_DRMI_TX_EN, PKTSCHED_DRMI_TX_EN, in dw_hdmi_qp_config_drm_infoframe()
367 struct dw_hdmi_qp *hdmi = bridge->driver_private; in dw_hdmi_qp_bridge_atomic_enable() local
382 dev_dbg(hdmi->dev, "%s mode=HDMI rate=%llu\n", in dw_hdmi_qp_bridge_atomic_enable()
383 __func__, conn_state->hdmi.tmds_char_rate); in dw_hdmi_qp_bridge_atomic_enable()
386 dev_dbg(hdmi->dev, "%s mode=DVI\n", __func__); in dw_hdmi_qp_bridge_atomic_enable()
390 hdmi->phy.ops->init(hdmi, hdmi->phy.data); in dw_hdmi_qp_bridge_atomic_enable()
392 dw_hdmi_qp_mod(hdmi, HDCP2_BYPASS, HDCP2_BYPASS, HDCP2LOGIC_CONFIG0); in dw_hdmi_qp_bridge_atomic_enable()
393 dw_hdmi_qp_mod(hdmi, op_mode, OPMODE_DVI, LINK_CONFIG0); in dw_hdmi_qp_bridge_atomic_enable()
401 struct dw_hdmi_qp *hdmi = bridge->driver_private; in dw_hdmi_qp_bridge_atomic_disable() local
403 hdmi->phy.ops->disable(hdmi, hdmi->phy.data); in dw_hdmi_qp_bridge_atomic_disable()
409 struct dw_hdmi_qp *hdmi = bridge->driver_private; in dw_hdmi_qp_bridge_detect() local
411 return hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data); in dw_hdmi_qp_bridge_detect()
418 struct dw_hdmi_qp *hdmi = bridge->driver_private; in dw_hdmi_qp_bridge_edid_read() local
423 dev_dbg(hdmi->dev, "failed to get edid\n"); in dw_hdmi_qp_bridge_edid_read()
433 struct dw_hdmi_qp *hdmi = bridge->driver_private; in dw_hdmi_qp_bridge_tmds_char_rate_valid() local
436 dev_dbg(hdmi->dev, "Unsupported TMDS char rate: %lld\n", rate); in dw_hdmi_qp_bridge_tmds_char_rate_valid()
446 struct dw_hdmi_qp *hdmi = bridge->driver_private; in dw_hdmi_qp_bridge_clear_infoframe() local
450 dw_hdmi_qp_mod(hdmi, 0, PKTSCHED_AVI_TX_EN | PKTSCHED_GCP_TX_EN, in dw_hdmi_qp_bridge_clear_infoframe()
455 dw_hdmi_qp_mod(hdmi, 0, PKTSCHED_DRMI_TX_EN, PKTSCHED_PKT_EN); in dw_hdmi_qp_bridge_clear_infoframe()
459 dev_dbg(hdmi->dev, "Unsupported infoframe type %x\n", type); in dw_hdmi_qp_bridge_clear_infoframe()
469 struct dw_hdmi_qp *hdmi = bridge->driver_private; in dw_hdmi_qp_bridge_write_infoframe() local
475 return dw_hdmi_qp_config_avi_infoframe(hdmi, buffer, len); in dw_hdmi_qp_bridge_write_infoframe()
478 return dw_hdmi_qp_config_drm_infoframe(hdmi, buffer, len); in dw_hdmi_qp_bridge_write_infoframe()
481 dev_dbg(hdmi->dev, "Unsupported infoframe type %x\n", type); in dw_hdmi_qp_bridge_write_infoframe()
501 struct dw_hdmi_qp *hdmi = dev_id; in dw_hdmi_qp_main_hardirq() local
502 struct dw_hdmi_qp_i2c *i2c = hdmi->i2c; in dw_hdmi_qp_main_hardirq()
505 stat = dw_hdmi_qp_read(hdmi, MAINUNIT_1_INT_STATUS); in dw_hdmi_qp_main_hardirq()
511 dw_hdmi_qp_write(hdmi, i2c->stat, MAINUNIT_1_INT_CLEAR); in dw_hdmi_qp_main_hardirq()
528 static void dw_hdmi_qp_init_hw(struct dw_hdmi_qp *hdmi) in dw_hdmi_qp_init_hw() argument
530 dw_hdmi_qp_write(hdmi, 0, MAINUNIT_0_INT_MASK_N); in dw_hdmi_qp_init_hw()
531 dw_hdmi_qp_write(hdmi, 0, MAINUNIT_1_INT_MASK_N); in dw_hdmi_qp_init_hw()
532 dw_hdmi_qp_write(hdmi, 428571429, TIMER_BASE_CONFIG0); in dw_hdmi_qp_init_hw()
535 dw_hdmi_qp_write(hdmi, 0x01, I2CM_CONTROL0); in dw_hdmi_qp_init_hw()
537 dw_hdmi_qp_write(hdmi, 0x085c085c, I2CM_FM_SCL_CONFIG0); in dw_hdmi_qp_init_hw()
539 dw_hdmi_qp_mod(hdmi, 0, I2CM_FM_EN, I2CM_INTERFACE_CONTROL0); in dw_hdmi_qp_init_hw()
542 dw_hdmi_qp_write(hdmi, I2CM_OP_DONE_CLEAR | I2CM_NACK_RCVD_CLEAR, in dw_hdmi_qp_init_hw()
545 if (hdmi->phy.ops->setup_hpd) in dw_hdmi_qp_init_hw()
546 hdmi->phy.ops->setup_hpd(hdmi, hdmi->phy.data); in dw_hdmi_qp_init_hw()
554 struct dw_hdmi_qp *hdmi; in dw_hdmi_qp_bind() local
564 hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL); in dw_hdmi_qp_bind()
565 if (!hdmi) in dw_hdmi_qp_bind()
568 hdmi->dev = dev; in dw_hdmi_qp_bind()
574 hdmi->regm = devm_regmap_init_mmio(dev, regs, &dw_hdmi_qp_regmap_config); in dw_hdmi_qp_bind()
575 if (IS_ERR(hdmi->regm)) { in dw_hdmi_qp_bind()
577 return ERR_CAST(hdmi->regm); in dw_hdmi_qp_bind()
580 hdmi->phy.ops = plat_data->phy_ops; in dw_hdmi_qp_bind()
581 hdmi->phy.data = plat_data->phy_data; in dw_hdmi_qp_bind()
583 dw_hdmi_qp_init_hw(hdmi); in dw_hdmi_qp_bind()
587 IRQF_SHARED, dev_name(dev), hdmi); in dw_hdmi_qp_bind()
591 hdmi->bridge.driver_private = hdmi; in dw_hdmi_qp_bind()
592 hdmi->bridge.funcs = &dw_hdmi_qp_bridge_funcs; in dw_hdmi_qp_bind()
593 hdmi->bridge.ops = DRM_BRIDGE_OP_DETECT | in dw_hdmi_qp_bind()
597 hdmi->bridge.of_node = pdev->dev.of_node; in dw_hdmi_qp_bind()
598 hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA; in dw_hdmi_qp_bind()
599 hdmi->bridge.vendor = "Synopsys"; in dw_hdmi_qp_bind()
600 hdmi->bridge.product = "DW HDMI QP TX"; in dw_hdmi_qp_bind()
602 hdmi->bridge.ddc = dw_hdmi_qp_i2c_adapter(hdmi); in dw_hdmi_qp_bind()
603 if (IS_ERR(hdmi->bridge.ddc)) in dw_hdmi_qp_bind()
604 return ERR_CAST(hdmi->bridge.ddc); in dw_hdmi_qp_bind()
606 ret = devm_drm_bridge_add(dev, &hdmi->bridge); in dw_hdmi_qp_bind()
610 ret = drm_bridge_attach(encoder, &hdmi->bridge, NULL, in dw_hdmi_qp_bind()
615 return hdmi; in dw_hdmi_qp_bind()
619 void dw_hdmi_qp_resume(struct device *dev, struct dw_hdmi_qp *hdmi) in dw_hdmi_qp_resume() argument
621 dw_hdmi_qp_init_hw(hdmi); in dw_hdmi_qp_resume()
627 MODULE_DESCRIPTION("DW HDMI QP transmitter library");