Lines Matching +full:needs +full:- +full:hpd

1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2019-2022 MediaTek Inc.
18 #include <linux/arm-smccc.h>
23 #include <linux/media-bus-format.h>
24 #include <linux/nvmem-consumer.h>
33 #include <sound/hdmi-codec.h>
402 .name = "mtk-dp-registers",
415 ret = regmap_read(mtk_dp->regs, offset, &read_val); in mtk_dp_read()
417 dev_err(mtk_dp->dev, "Failed to read register 0x%x: %d\n", in mtk_dp_read()
427 int ret = regmap_write(mtk_dp->regs, offset, val); in mtk_dp_write()
430 dev_err(mtk_dp->dev, in mtk_dp_write()
439 int ret = regmap_update_bits(mtk_dp->regs, offset, mask, val); in mtk_dp_update_bits()
442 dev_err(mtk_dp->dev, in mtk_dp_update_bits()
476 struct videomode *vm = &mtk_dp->info.vm; in mtk_dp_set_msa()
484 vm->hsync_len + vm->hback_porch, in mtk_dp_set_msa()
487 vm->hsync_len, HSW_SW_DP_ENC0_P0_MASK); in mtk_dp_set_msa()
491 vm->hactive, HWIDTH_SW_DP_ENC0_P0_MASK); in mtk_dp_set_msa()
497 vm->vsync_len + vm->vback_porch, in mtk_dp_set_msa()
500 vm->vsync_len, VSW_SW_DP_ENC0_P0_MASK); in mtk_dp_set_msa()
504 vm->vactive, VHEIGHT_SW_DP_ENC0_P0_MASK); in mtk_dp_set_msa()
508 vm->hactive, HDE_NUM_LAST_DP_ENC0_P0_MASK); in mtk_dp_set_msa()
512 vm->hfront_porch, in mtk_dp_set_msa()
515 vm->hsync_len, in mtk_dp_set_msa()
518 vm->hback_porch + vm->hsync_len, in mtk_dp_set_msa()
521 vm->hactive, in mtk_dp_set_msa()
529 vm->vfront_porch, in mtk_dp_set_msa()
532 vm->vsync_len, in mtk_dp_set_msa()
535 vm->vback_porch + vm->vsync_len, in mtk_dp_set_msa()
538 vm->vactive, in mtk_dp_set_msa()
558 drm_warn(mtk_dp->drm_dev, "Unsupported color format: %d\n", in mtk_dp_set_color_format()
560 return -EINVAL; in mtk_dp_set_color_format()
647 switch (cfg->channels) { in mtk_dp_audio_setup_channels()
680 switch (cfg->sample_rate) { in mtk_dp_audio_channel_status_set()
704 switch (cfg->word_length_bits) { in mtk_dp_audio_channel_status_set()
733 (min(8, channels) - 1) << 8, in mtk_dp_audio_sdp_asp_set_channels()
740 mtk_dp->data->audio_m_div2_bit, in mtk_dp_audio_set_divider()
761 u32 db_addr = MTK_DP_ENC0_P0_30D8 + (MTK_DP_SDP_AUI - 1) * 8; in mtk_dp_sdp_set_header_aui()
778 mtk_dp_sdp_set_data(mtk_dp, sdp->db); in mtk_dp_setup_sdp_aui()
779 mtk_dp_sdp_set_header_aui(mtk_dp, &sdp->sdp_header); in mtk_dp_setup_sdp_aui()
840 /* Hardware needs time to update the data */ in mtk_dp_aux_read_rx_fifo()
851 (length - 1) << 12, in mtk_dp_aux_set_length()
871 while (--wait_reply) { in mtk_dp_aux_wait_for_completion()
889 return -ETIMEDOUT; in mtk_dp_aux_wait_for_completion()
895 return -ETIMEDOUT; in mtk_dp_aux_wait_for_completion()
905 return -EINVAL; in mtk_dp_aux_do_transfer()
940 dev_err(mtk_dp->dev, in mtk_dp_aux_do_transfer()
942 return -EIO; in mtk_dp_aux_do_transfer()
945 return -ETIMEDOUT; in mtk_dp_aux_do_transfer()
974 dev_dbg(mtk_dp->dev, in mtk_dp_set_swing_pre_emphasis()
975 "link training: swing_val = 0x%x, pre-emphasis = 0x%x\n", in mtk_dp_set_swing_pre_emphasis()
1167 struct device *dev = mtk_dp->dev; in mtk_dp_get_calibration_data()
1169 u32 *cal_data = mtk_dp->cal_data; in mtk_dp_get_calibration_data()
1192 fmt = &mtk_dp->data->efuse_fmt[i]; in mtk_dp_get_calibration_data()
1194 if (fmt->idx >= len) { in mtk_dp_get_calibration_data()
1195 dev_warn(mtk_dp->dev, in mtk_dp_get_calibration_data()
1196 "Out-of-bound efuse data access, fmt idx = %d, buf len = %zu\n", in mtk_dp_get_calibration_data()
1197 fmt->idx, len); in mtk_dp_get_calibration_data()
1202 cal_data[i] = (buf[fmt->idx] >> fmt->shift) & fmt->mask; in mtk_dp_get_calibration_data()
1204 if (cal_data[i] < fmt->min_val || cal_data[i] > fmt->max_val) { in mtk_dp_get_calibration_data()
1205 dev_warn(mtk_dp->dev, "Invalid efuse data, idx = %d\n", i); in mtk_dp_get_calibration_data()
1215 dev_warn(mtk_dp->dev, "Use default calibration data\n"); in mtk_dp_get_calibration_data()
1217 cal_data[i] = mtk_dp->data->efuse_fmt[i].default_val; in mtk_dp_get_calibration_data()
1222 u32 *cal_data = mtk_dp->cal_data; in mtk_dp_set_calibration_data()
1266 .ssc = mtk_dp->train_info.sink_ssc, in mtk_dp_phy_configure()
1273 ret = phy_configure(mtk_dp->phy, &phy_opts); in mtk_dp_phy_configure()
1303 pattern ? BIT(pattern - 1) << 12 : 0, in mtk_dp_train_set_pattern()
1336 mtk_dp->data->smc_cmd, enable, in mtk_dp_video_mute()
1339 dev_dbg(mtk_dp->dev, "smc cmd: 0x%x, p1: %s, ret: 0x%lx-0x%lx\n", in mtk_dp_video_mute()
1340 mtk_dp->data->smc_cmd, enable ? "enable" : "disable", res.a0, res.a1); in mtk_dp_video_mute()
1378 drm_dp_dpcd_writeb(&mtk_dp->aux, DP_SET_POWER, DP_SET_POWER_D0); in mtk_dp_aux_panel_poweron()
1382 drm_dp_dpcd_writeb(&mtk_dp->aux, DP_SET_POWER, DP_SET_POWER_D3); in mtk_dp_aux_panel_poweron()
1425 bool plugged_in = (mtk_dp->bridge.type == DRM_MODE_CONNECTOR_eDP); in mtk_dp_initialize_priv_data()
1427 mtk_dp->train_info.link_rate = DP_LINK_BW_5_4; in mtk_dp_initialize_priv_data()
1428 mtk_dp->train_info.lane_count = mtk_dp->max_lanes; in mtk_dp_initialize_priv_data()
1429 mtk_dp->train_info.cable_plugged_in = plugged_in; in mtk_dp_initialize_priv_data()
1431 mtk_dp->info.format = DP_PIXELFORMAT_RGB; in mtk_dp_initialize_priv_data()
1432 memset(&mtk_dp->info.vm, 0, sizeof(struct videomode)); in mtk_dp_initialize_priv_data()
1433 mtk_dp->audio_enable = false; in mtk_dp_initialize_priv_data()
1441 struct videomode *vm = &mtk_dp->info.vm; in mtk_dp_sdp_set_down_cnt_init()
1447 mtk_dp->train_info.link_rate * 2700 * 8 / in mtk_dp_sdp_set_down_cnt_init()
1450 switch (mtk_dp->train_info.lane_count) { in mtk_dp_sdp_set_down_cnt_init()
1476 struct videomode *vm = &mtk_dp->info.vm; in mtk_dp_sdp_set_down_cnt_init_in_hblank()
1480 pix_clk_mhz = mtk_dp->info.format == DP_PIXELFORMAT_YUV420 ? in mtk_dp_sdp_set_down_cnt_init_in_hblank()
1483 switch (mtk_dp->train_info.lane_count) { in mtk_dp_sdp_set_down_cnt_init_in_hblank()
1494 if (pix_clk_mhz > mtk_dp->train_info.link_rate * 27) in mtk_dp_sdp_set_down_cnt_init_in_hblank()
1508 if (!mtk_dp->data->audio_pkt_in_hblank_area) in mtk_dp_audio_sample_arrange_disable()
1520 mtk_dp->info.vm.hactive / in mtk_dp_setup_tu()
1521 mtk_dp->train_info.lane_count / in mtk_dp_setup_tu()
1562 drm_dp_dpcd_writeb(&mtk_dp->aux, DP_TRAINING_LANE0_SET + lane, in mtk_dp_train_update_swing_pre()
1576 aux_offset = mtk_dp->train_info.channel_eq_pattern; in mtk_dp_pattern()
1578 switch (mtk_dp->train_info.channel_eq_pattern) { in mtk_dp_pattern()
1595 drm_dp_dpcd_writeb(&mtk_dp->aux, DP_TRAINING_PATTERN_SET, aux_offset); in mtk_dp_pattern()
1603 drm_dp_dpcd_writeb(&mtk_dp->aux, DP_LINK_BW_SET, target_link_rate); in mtk_dp_train_setting()
1604 drm_dp_dpcd_writeb(&mtk_dp->aux, DP_LANE_COUNT_SET, in mtk_dp_train_setting()
1607 if (mtk_dp->train_info.sink_ssc) in mtk_dp_train_setting()
1608 drm_dp_dpcd_writeb(&mtk_dp->aux, DP_DOWNSPREAD_CTRL, in mtk_dp_train_setting()
1616 dev_dbg(mtk_dp->dev, in mtk_dp_train_setting()
1636 if (!mtk_dp->train_info.cable_plugged_in) { in mtk_dp_train_cr()
1638 return -ENODEV; in mtk_dp_train_cr()
1641 drm_dp_dpcd_read(&mtk_dp->aux, DP_ADJUST_REQUEST_LANE0_1, in mtk_dp_train_cr()
1646 drm_dp_link_train_clock_recovery_delay(&mtk_dp->aux, in mtk_dp_train_cr()
1647 mtk_dp->rx_cap); in mtk_dp_train_cr()
1650 drm_dp_dpcd_read_link_status(&mtk_dp->aux, link_status); in mtk_dp_train_cr()
1653 dev_dbg(mtk_dp->dev, "Link train CR pass\n"); in mtk_dp_train_cr()
1673 dev_dbg(mtk_dp->dev, "Link train CR fail\n"); in mtk_dp_train_cr()
1679 * re-calculate this retry count. in mtk_dp_train_cr()
1687 drm_dp_dpcd_writeb(&mtk_dp->aux, DP_TRAINING_PATTERN_SET, in mtk_dp_train_cr()
1691 return -ETIMEDOUT; in mtk_dp_train_cr()
1704 if (!mtk_dp->train_info.cable_plugged_in) { in mtk_dp_train_eq()
1706 return -ENODEV; in mtk_dp_train_eq()
1709 drm_dp_dpcd_read(&mtk_dp->aux, DP_ADJUST_REQUEST_LANE0_1, in mtk_dp_train_eq()
1714 drm_dp_link_train_channel_eq_delay(&mtk_dp->aux, in mtk_dp_train_eq()
1715 mtk_dp->rx_cap); in mtk_dp_train_eq()
1718 drm_dp_dpcd_read_link_status(&mtk_dp->aux, link_status); in mtk_dp_train_eq()
1720 dev_dbg(mtk_dp->dev, "Link train EQ pass\n"); in mtk_dp_train_eq()
1723 drm_dp_dpcd_writeb(&mtk_dp->aux, DP_TRAINING_PATTERN_SET, in mtk_dp_train_eq()
1728 dev_dbg(mtk_dp->dev, "Link train EQ fail\n"); in mtk_dp_train_eq()
1732 drm_dp_dpcd_writeb(&mtk_dp->aux, DP_TRAINING_PATTERN_SET, in mtk_dp_train_eq()
1736 return -ETIMEDOUT; in mtk_dp_train_eq()
1749 if (mtk_dp->bridge.type == DRM_MODE_CONNECTOR_eDP && in mtk_dp_parse_capabilities()
1750 mtk_dp->rx_cap[DP_MAX_LINK_RATE] && in mtk_dp_parse_capabilities()
1751 mtk_dp->train_info.sink_ssc) in mtk_dp_parse_capabilities()
1754 ret = drm_dp_read_dpcd_caps(&mtk_dp->aux, mtk_dp->rx_cap); in mtk_dp_parse_capabilities()
1758 if (drm_dp_tps4_supported(mtk_dp->rx_cap)) in mtk_dp_parse_capabilities()
1759 mtk_dp->train_info.channel_eq_pattern = DP_TRAINING_PATTERN_4; in mtk_dp_parse_capabilities()
1760 else if (drm_dp_tps3_supported(mtk_dp->rx_cap)) in mtk_dp_parse_capabilities()
1761 mtk_dp->train_info.channel_eq_pattern = DP_TRAINING_PATTERN_3; in mtk_dp_parse_capabilities()
1763 mtk_dp->train_info.channel_eq_pattern = DP_TRAINING_PATTERN_2; in mtk_dp_parse_capabilities()
1765 mtk_dp->train_info.sink_ssc = drm_dp_max_downspread(mtk_dp->rx_cap); in mtk_dp_parse_capabilities()
1767 ret = drm_dp_dpcd_readb(&mtk_dp->aux, DP_MSTM_CAP, &val); in mtk_dp_parse_capabilities()
1769 dev_err(mtk_dp->dev, "Read mstm cap failed: %zd\n", ret); in mtk_dp_parse_capabilities()
1770 return ret == 0 ? -EIO : ret; in mtk_dp_parse_capabilities()
1775 ret = drm_dp_dpcd_readb(&mtk_dp->aux, in mtk_dp_parse_capabilities()
1779 dev_err(mtk_dp->dev, "Read irq vector failed: %zd\n", ret); in mtk_dp_parse_capabilities()
1780 return ret == 0 ? -EIO : ret; in mtk_dp_parse_capabilities()
1784 ret = drm_dp_dpcd_writeb(&mtk_dp->aux, in mtk_dp_parse_capabilities()
1798 if (!mtk_dp->data->audio_supported) in mtk_dp_edid_parse_audio_capabilities()
1801 if (mtk_dp->info.audio_cur_cfg.sad_count <= 0) { in mtk_dp_edid_parse_audio_capabilities()
1802 drm_info(mtk_dp->drm_dev, "The SADs is NULL\n"); in mtk_dp_edid_parse_audio_capabilities()
1811 phy_reset(mtk_dp->phy); in mtk_dp_train_change_mode()
1820 link_rate = min_t(u8, mtk_dp->max_linkrate, in mtk_dp_training()
1821 mtk_dp->rx_cap[DP_MAX_LINK_RATE]); in mtk_dp_training()
1823 lane_count = min_t(u8, mtk_dp->max_lanes, in mtk_dp_training()
1824 drm_dp_max_lane_count(mtk_dp->rx_cap)); in mtk_dp_training()
1833 for (train_limit = 6; train_limit > 0; train_limit--) { in mtk_dp_training()
1841 if (ret == -ENODEV) { in mtk_dp_training()
1850 return -EIO; in mtk_dp_training()
1862 return -EINVAL; in mtk_dp_training()
1868 if (ret == -ENODEV) { in mtk_dp_training()
1873 return -EIO; in mtk_dp_training()
1883 return -ETIMEDOUT; in mtk_dp_training()
1885 mtk_dp->train_info.link_rate = link_rate; in mtk_dp_training()
1886 mtk_dp->train_info.lane_count = lane_count; in mtk_dp_training()
1921 frame.channels = cfg->channels; in mtk_dp_audio_sdp_setup()
1922 frame.sample_frequency = cfg->sample_rate; in mtk_dp_audio_sdp_setup()
1924 switch (cfg->word_length_bits) { in mtk_dp_audio_sdp_setup()
1939 mtk_dp_audio_sdp_asp_set_channels(mtk_dp, cfg->channels); in mtk_dp_audio_sdp_setup()
1958 return mtk_dp_set_color_format(mtk_dp, mtk_dp->info.format); in mtk_dp_video_config()
1974 static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev) in mtk_dp_hpd_event_thread() argument
1980 if (mtk_dp->need_debounce && mtk_dp->train_info.cable_plugged_in) in mtk_dp_hpd_event_thread()
1983 spin_lock_irqsave(&mtk_dp->irq_thread_lock, flags); in mtk_dp_hpd_event_thread()
1984 status = mtk_dp->irq_thread_handle; in mtk_dp_hpd_event_thread()
1985 mtk_dp->irq_thread_handle = 0; in mtk_dp_hpd_event_thread()
1986 spin_unlock_irqrestore(&mtk_dp->irq_thread_lock, flags); in mtk_dp_hpd_event_thread()
1989 if (mtk_dp->bridge.dev) in mtk_dp_hpd_event_thread()
1990 drm_helper_hpd_irq_event(mtk_dp->bridge.dev); in mtk_dp_hpd_event_thread()
1992 if (!mtk_dp->train_info.cable_plugged_in) { in mtk_dp_hpd_event_thread()
1994 memset(&mtk_dp->info.audio_cur_cfg, 0, in mtk_dp_hpd_event_thread()
1995 sizeof(mtk_dp->info.audio_cur_cfg)); in mtk_dp_hpd_event_thread()
1997 mtk_dp->need_debounce = false; in mtk_dp_hpd_event_thread()
1998 mod_timer(&mtk_dp->debounce_timer, in mtk_dp_hpd_event_thread()
1999 jiffies + msecs_to_jiffies(100) - 1); in mtk_dp_hpd_event_thread()
2004 dev_dbg(mtk_dp->dev, "Receive IRQ from sink devices\n"); in mtk_dp_hpd_event_thread()
2009 static irqreturn_t mtk_dp_hpd_event(int hpd, void *dev) in mtk_dp_hpd_event() argument
2020 spin_lock_irqsave(&mtk_dp->irq_thread_lock, flags); in mtk_dp_hpd_event()
2023 mtk_dp->irq_thread_handle |= MTK_DP_THREAD_HPD_EVENT; in mtk_dp_hpd_event()
2027 mtk_dp->irq_thread_handle |= MTK_DP_THREAD_CABLE_STATE_CHG; in mtk_dp_hpd_event()
2031 spin_unlock_irqrestore(&mtk_dp->irq_thread_lock, flags); in mtk_dp_hpd_event()
2036 mtk_dp->train_info.cable_plugged_in = true; in mtk_dp_hpd_event()
2038 mtk_dp->train_info.cable_plugged_in = false; in mtk_dp_hpd_event()
2050 ret = regmap_read_poll_timeout(mtk_dp->regs, MTK_DP_TRANS_P0_3414, in mtk_dp_wait_hpd_asserted()
2054 mtk_dp->train_info.cable_plugged_in = false; in mtk_dp_wait_hpd_asserted()
2058 mtk_dp->train_info.cable_plugged_in = true; in mtk_dp_wait_hpd_asserted()
2062 dev_err(mtk_dp->dev, "Can't parse capabilities: %d\n", ret); in mtk_dp_wait_hpd_asserted()
2073 struct device *dev = &pdev->dev; in mtk_dp_dt_parse()
2083 mtk_dp->regs = devm_regmap_init_mmio(dev, base, &mtk_dp_regmap_config); in mtk_dp_dt_parse()
2084 if (IS_ERR(mtk_dp->regs)) in mtk_dp_dt_parse()
2085 return PTR_ERR(mtk_dp->regs); in mtk_dp_dt_parse()
2087 endpoint = of_graph_get_endpoint_by_regs(pdev->dev.of_node, 1, -1); in mtk_dp_dt_parse()
2089 "data-lanes", sizeof(u32)); in mtk_dp_dt_parse()
2092 return -EINVAL; in mtk_dp_dt_parse()
2095 mtk_dp->max_lanes = len; in mtk_dp_dt_parse()
2097 ret = device_property_read_u32(dev, "max-linkrate-mhz", &linkrate); in mtk_dp_dt_parse()
2103 mtk_dp->max_linkrate = drm_dp_link_rate_to_bw_code(linkrate * 100); in mtk_dp_dt_parse()
2110 if (!mtk_dp->data->audio_supported || !mtk_dp->audio_enable) in mtk_dp_update_plugged_status()
2113 mutex_lock(&mtk_dp->update_plugged_status_lock); in mtk_dp_update_plugged_status()
2114 if (mtk_dp->plugged_cb && mtk_dp->codec_dev) in mtk_dp_update_plugged_status()
2115 mtk_dp->plugged_cb(mtk_dp->codec_dev, in mtk_dp_update_plugged_status()
2116 mtk_dp->enabled & in mtk_dp_update_plugged_status()
2117 mtk_dp->info.audio_cur_cfg.detect_monitor); in mtk_dp_update_plugged_status()
2118 mutex_unlock(&mtk_dp->update_plugged_status_lock); in mtk_dp_update_plugged_status()
2126 bool enabled = mtk_dp->enabled; in mtk_dp_bdg_detect()
2128 if (!mtk_dp->train_info.cable_plugged_in) in mtk_dp_bdg_detect()
2135 * Some dongles still source HPD when they do not connect to any in mtk_dp_bdg_detect()
2138 * function, we just need to check the HPD connection to check in mtk_dp_bdg_detect()
2142 if (drm_dp_read_sink_count(&mtk_dp->aux) > 0) in mtk_dp_bdg_detect()
2155 bool enabled = mtk_dp->enabled; in mtk_dp_edid_read()
2157 struct mtk_dp_audio_cfg *audio_caps = &mtk_dp->info.audio_cur_cfg; in mtk_dp_edid_read()
2160 drm_atomic_bridge_chain_pre_enable(bridge, connector->state->state); in mtk_dp_edid_read()
2164 drm_edid = drm_edid_read_ddc(connector, &mtk_dp->aux.ddc); in mtk_dp_edid_read()
2171 drm_err(mtk_dp->drm_dev, "Can't parse capabilities\n"); in mtk_dp_edid_read()
2190 audio_caps->sad_count = ret; in mtk_dp_edid_read()
2193 * FIXME: This should use connector->display_info.has_audio from in mtk_dp_edid_read()
2197 audio_caps->detect_monitor = drm_detect_monitor_audio(edid); in mtk_dp_edid_read()
2202 drm_atomic_bridge_chain_post_disable(bridge, connector->state->state); in mtk_dp_edid_read()
2217 if (mtk_dp->bridge.type != DRM_MODE_CONNECTOR_eDP && in mtk_dp_aux_transfer()
2218 !mtk_dp->train_info.cable_plugged_in) { in mtk_dp_aux_transfer()
2219 ret = -EIO; in mtk_dp_aux_transfer()
2223 switch (msg->request) { in mtk_dp_aux_transfer()
2229 request = msg->request & ~DP_AUX_I2C_WRITE_STATUS_UPDATE; in mtk_dp_aux_transfer()
2235 request = msg->request; in mtk_dp_aux_transfer()
2239 dev_err(mtk_dp->dev, "invalid aux cmd = %d\n", in mtk_dp_aux_transfer()
2240 msg->request); in mtk_dp_aux_transfer()
2241 ret = -EINVAL; in mtk_dp_aux_transfer()
2247 msg->size - accessed_bytes); in mtk_dp_aux_transfer()
2250 msg->address + accessed_bytes, in mtk_dp_aux_transfer()
2251 msg->buffer + accessed_bytes, in mtk_dp_aux_transfer()
2252 to_access, &msg->reply); in mtk_dp_aux_transfer()
2255 dev_info(mtk_dp->dev, in mtk_dp_aux_transfer()
2260 } while (accessed_bytes < msg->size); in mtk_dp_aux_transfer()
2262 return msg->size; in mtk_dp_aux_transfer()
2264 msg->reply = DP_AUX_NATIVE_REPLY_NACK | DP_AUX_I2C_REPLY_NACK; in mtk_dp_aux_transfer()
2272 ret = phy_init(mtk_dp->phy); in mtk_dp_poweron()
2274 dev_err(mtk_dp->dev, "Failed to initialize phy: %d\n", ret); in mtk_dp_poweron()
2287 phy_exit(mtk_dp->phy); in mtk_dp_poweroff()
2298 dev_err(mtk_dp->dev, "Driver does not provide a connector!"); in mtk_dp_bridge_attach()
2299 return -EINVAL; in mtk_dp_bridge_attach()
2302 mtk_dp->aux.drm_dev = bridge->dev; in mtk_dp_bridge_attach()
2303 ret = drm_dp_aux_register(&mtk_dp->aux); in mtk_dp_bridge_attach()
2305 dev_err(mtk_dp->dev, in mtk_dp_bridge_attach()
2314 if (mtk_dp->next_bridge) { in mtk_dp_bridge_attach()
2315 ret = drm_bridge_attach(encoder, mtk_dp->next_bridge, in mtk_dp_bridge_attach()
2316 &mtk_dp->bridge, flags); in mtk_dp_bridge_attach()
2318 drm_warn(mtk_dp->drm_dev, in mtk_dp_bridge_attach()
2324 mtk_dp->drm_dev = bridge->dev; in mtk_dp_bridge_attach()
2326 if (mtk_dp->bridge.type != DRM_MODE_CONNECTOR_eDP) { in mtk_dp_bridge_attach()
2327 irq_clear_status_flags(mtk_dp->irq, IRQ_NOAUTOEN); in mtk_dp_bridge_attach()
2328 enable_irq(mtk_dp->irq); in mtk_dp_bridge_attach()
2337 drm_dp_aux_unregister(&mtk_dp->aux); in mtk_dp_bridge_attach()
2345 if (mtk_dp->bridge.type != DRM_MODE_CONNECTOR_eDP) { in mtk_dp_bridge_detach()
2347 disable_irq(mtk_dp->irq); in mtk_dp_bridge_detach()
2349 mtk_dp->drm_dev = NULL; in mtk_dp_bridge_detach()
2351 drm_dp_aux_unregister(&mtk_dp->aux); in mtk_dp_bridge_detach()
2360 mtk_dp->conn = drm_atomic_get_new_connector_for_encoder(state, in mtk_dp_bridge_atomic_enable()
2361 bridge->encoder); in mtk_dp_bridge_atomic_enable()
2362 if (!mtk_dp->conn) { in mtk_dp_bridge_atomic_enable()
2363 drm_err(mtk_dp->drm_dev, in mtk_dp_bridge_atomic_enable()
2373 drm_err(mtk_dp->drm_dev, "Training failed, %d\n", ret); in mtk_dp_bridge_atomic_enable()
2383 mtk_dp->audio_enable = in mtk_dp_bridge_atomic_enable()
2385 &mtk_dp->info.audio_cur_cfg); in mtk_dp_bridge_atomic_enable()
2386 if (mtk_dp->audio_enable) { in mtk_dp_bridge_atomic_enable()
2387 mtk_dp_audio_setup(mtk_dp, &mtk_dp->info.audio_cur_cfg); in mtk_dp_bridge_atomic_enable()
2390 memset(&mtk_dp->info.audio_cur_cfg, 0, in mtk_dp_bridge_atomic_enable()
2391 sizeof(mtk_dp->info.audio_cur_cfg)); in mtk_dp_bridge_atomic_enable()
2394 mtk_dp->enabled = true; in mtk_dp_bridge_atomic_enable()
2409 mtk_dp->enabled = false; in mtk_dp_bridge_atomic_disable()
2414 if (mtk_dp->train_info.cable_plugged_in) { in mtk_dp_bridge_atomic_disable()
2415 drm_dp_dpcd_writeb(&mtk_dp->aux, DP_SET_POWER, DP_SET_POWER_D3); in mtk_dp_bridge_atomic_disable()
2437 u32 bpp = info->color_formats & DRM_COLOR_FORMAT_YCBCR422 ? 16 : 24; in mtk_dp_bridge_mode_valid()
2438 u32 lane_count_min = mtk_dp->train_info.lane_count; in mtk_dp_bridge_mode_valid()
2439 u32 rate = drm_dp_bw_code_to_link_rate(mtk_dp->train_info.link_rate) * in mtk_dp_bridge_mode_valid()
2444 *The down-spread amplitude shall either be disabled (0.0%) or up in mtk_dp_bridge_mode_valid()
2448 *mode->clock does not need to be multiplied by 10 in mtk_dp_bridge_mode_valid()
2450 if ((rate * 97 / 100) < (mode->clock * bpp / 8)) in mtk_dp_bridge_mode_valid()
2488 struct drm_display_mode *mode = &crtc_state->adjusted_mode; in mtk_dp_bridge_atomic_get_input_bus_fmts()
2490 &conn_state->connector->display_info; in mtk_dp_bridge_atomic_get_input_bus_fmts()
2491 u32 lane_count_min = mtk_dp->train_info.lane_count; in mtk_dp_bridge_atomic_get_input_bus_fmts()
2492 u32 rate = drm_dp_bw_code_to_link_rate(mtk_dp->train_info.link_rate) * in mtk_dp_bridge_atomic_get_input_bus_fmts()
2502 if (((rate * 97 / 100) < (mode->clock * 24 / 8)) && in mtk_dp_bridge_atomic_get_input_bus_fmts()
2503 ((rate * 97 / 100) > (mode->clock * 16 / 8)) && in mtk_dp_bridge_atomic_get_input_bus_fmts()
2504 (display_info->color_formats & DRM_COLOR_FORMAT_YCBCR422)) { in mtk_dp_bridge_atomic_get_input_bus_fmts()
2530 struct drm_crtc *crtc = conn_state->crtc; in mtk_dp_bridge_atomic_check()
2533 input_bus_format = bridge_state->input_bus_cfg.format; in mtk_dp_bridge_atomic_check()
2535 dev_dbg(mtk_dp->dev, "input format 0x%04x, output format 0x%04x\n", in mtk_dp_bridge_atomic_check()
2536 bridge_state->input_bus_cfg.format, in mtk_dp_bridge_atomic_check()
2537 bridge_state->output_bus_cfg.format); in mtk_dp_bridge_atomic_check()
2540 mtk_dp->info.format = DP_PIXELFORMAT_YUV422; in mtk_dp_bridge_atomic_check()
2542 mtk_dp->info.format = DP_PIXELFORMAT_RGB; in mtk_dp_bridge_atomic_check()
2545 drm_err(mtk_dp->drm_dev, in mtk_dp_bridge_atomic_check()
2547 return -EINVAL; in mtk_dp_bridge_atomic_check()
2550 drm_display_mode_to_videomode(&crtc_state->adjusted_mode, &mtk_dp->info.vm); in mtk_dp_bridge_atomic_check()
2575 mtk_dp->need_debounce = true; in mtk_dp_debounce_timer()
2587 if (!mtk_dp->enabled) { in mtk_dp_audio_hw_params()
2588 dev_err(mtk_dp->dev, "%s, DP is not ready!\n", __func__); in mtk_dp_audio_hw_params()
2589 return -ENODEV; in mtk_dp_audio_hw_params()
2592 mtk_dp->info.audio_cur_cfg.channels = params->cea.channels; in mtk_dp_audio_hw_params()
2593 mtk_dp->info.audio_cur_cfg.sample_rate = params->sample_rate; in mtk_dp_audio_hw_params()
2595 mtk_dp_audio_setup(mtk_dp, &mtk_dp->info.audio_cur_cfg); in mtk_dp_audio_hw_params()
2621 if (mtk_dp->enabled) in mtk_dp_audio_get_eld()
2622 memcpy(buf, mtk_dp->conn->eld, len); in mtk_dp_audio_get_eld()
2635 mutex_lock(&mtk_dp->update_plugged_status_lock); in mtk_dp_audio_hook_plugged_cb()
2636 mtk_dp->plugged_cb = fn; in mtk_dp_audio_hook_plugged_cb()
2637 mtk_dp->codec_dev = codec_dev; in mtk_dp_audio_hook_plugged_cb()
2638 mutex_unlock(&mtk_dp->update_plugged_status_lock); in mtk_dp_audio_hook_plugged_cb()
2664 mtk_dp->audio_pdev = platform_device_register_data(dev, in mtk_dp_register_audio_driver()
2669 return PTR_ERR_OR_ZERO(mtk_dp->audio_pdev); in mtk_dp_register_audio_driver()
2674 struct device *dev = mtk_dp->dev; in mtk_dp_register_phy()
2676 mtk_dp->phy_dev = platform_device_register_data(dev, "mediatek-dp-phy", in mtk_dp_register_phy()
2678 &mtk_dp->regs, in mtk_dp_register_phy()
2680 if (IS_ERR(mtk_dp->phy_dev)) in mtk_dp_register_phy()
2681 return dev_err_probe(dev, PTR_ERR(mtk_dp->phy_dev), in mtk_dp_register_phy()
2682 "Failed to create device mediatek-dp-phy\n"); in mtk_dp_register_phy()
2686 mtk_dp->phy = devm_phy_get(&mtk_dp->phy_dev->dev, "dp"); in mtk_dp_register_phy()
2687 if (IS_ERR(mtk_dp->phy)) { in mtk_dp_register_phy()
2688 platform_device_unregister(mtk_dp->phy_dev); in mtk_dp_register_phy()
2689 return dev_err_probe(dev, PTR_ERR(mtk_dp->phy), "Failed to get phy\n"); in mtk_dp_register_phy()
2698 struct device *dev = mtk_aux->dev; in mtk_dp_edp_link_panel()
2701 mtk_dp->next_bridge = devm_drm_of_get_bridge(dev, dev->of_node, 1, 0); in mtk_dp_edp_link_panel()
2709 if (IS_ERR(mtk_dp->next_bridge)) { in mtk_dp_edp_link_panel()
2710 ret = PTR_ERR(mtk_dp->next_bridge); in mtk_dp_edp_link_panel()
2711 mtk_dp->next_bridge = NULL; in mtk_dp_edp_link_panel()
2716 ret = devm_drm_bridge_add(dev, &mtk_dp->bridge); in mtk_dp_edp_link_panel()
2726 struct device *dev = &pdev->dev; in mtk_dp_probe()
2734 mtk_dp->dev = dev; in mtk_dp_probe()
2735 mtk_dp->data = (struct mtk_dp_data *)of_device_get_match_data(dev); in mtk_dp_probe()
2744 * For eDP, polling the HPD instead is more convenient because we in mtk_dp_probe()
2748 if (mtk_dp->data->bridge_type != DRM_MODE_CONNECTOR_eDP) { in mtk_dp_probe()
2749 mtk_dp->irq = platform_get_irq(pdev, 0); in mtk_dp_probe()
2750 if (mtk_dp->irq < 0) in mtk_dp_probe()
2751 return dev_err_probe(dev, mtk_dp->irq, in mtk_dp_probe()
2754 spin_lock_init(&mtk_dp->irq_thread_lock); in mtk_dp_probe()
2756 irq_set_status_flags(mtk_dp->irq, IRQ_NOAUTOEN); in mtk_dp_probe()
2757 ret = devm_request_threaded_irq(dev, mtk_dp->irq, mtk_dp_hpd_event, in mtk_dp_probe()
2765 mtk_dp->need_debounce = true; in mtk_dp_probe()
2766 timer_setup(&mtk_dp->debounce_timer, mtk_dp_debounce_timer, 0); in mtk_dp_probe()
2769 mtk_dp->aux.name = "aux_mtk_dp"; in mtk_dp_probe()
2770 mtk_dp->aux.dev = dev; in mtk_dp_probe()
2771 mtk_dp->aux.transfer = mtk_dp_aux_transfer; in mtk_dp_probe()
2772 mtk_dp->aux.wait_hpd_asserted = mtk_dp_wait_hpd_asserted; in mtk_dp_probe()
2773 drm_dp_aux_init(&mtk_dp->aux); in mtk_dp_probe()
2777 if (mtk_dp->data->audio_supported) { in mtk_dp_probe()
2778 mutex_init(&mtk_dp->update_plugged_status_lock); in mtk_dp_probe()
2790 mtk_dp->bridge.of_node = dev->of_node; in mtk_dp_probe()
2791 mtk_dp->bridge.type = mtk_dp->data->bridge_type; in mtk_dp_probe()
2793 if (mtk_dp->bridge.type == DRM_MODE_CONNECTOR_eDP) { in mtk_dp_probe()
2807 * Power on the AUX to allow reading the EDID from aux-bus: in mtk_dp_probe()
2816 ret = devm_of_dp_aux_populate_bus(&mtk_dp->aux, mtk_dp_edp_link_panel); in mtk_dp_probe()
2818 /* -ENODEV this means that the panel is not on the aux-bus */ in mtk_dp_probe()
2819 if (ret == -ENODEV) { in mtk_dp_probe()
2820 ret = mtk_dp_edp_link_panel(&mtk_dp->aux); in mtk_dp_probe()
2832 mtk_dp->bridge.ops = DRM_BRIDGE_OP_DETECT | in mtk_dp_probe()
2834 ret = devm_drm_bridge_add(dev, &mtk_dp->bridge); in mtk_dp_probe()
2849 pm_runtime_put(&pdev->dev); in mtk_dp_remove()
2850 pm_runtime_disable(&pdev->dev); in mtk_dp_remove()
2851 if (mtk_dp->data->bridge_type != DRM_MODE_CONNECTOR_eDP) in mtk_dp_remove()
2852 timer_delete_sync(&mtk_dp->debounce_timer); in mtk_dp_remove()
2853 platform_device_unregister(mtk_dp->phy_dev); in mtk_dp_remove()
2854 if (mtk_dp->audio_pdev) in mtk_dp_remove()
2855 platform_device_unregister(mtk_dp->audio_pdev); in mtk_dp_remove()
2864 if (mtk_dp->bridge.type != DRM_MODE_CONNECTOR_eDP) in mtk_dp_suspend()
2877 if (mtk_dp->bridge.type != DRM_MODE_CONNECTOR_eDP) in mtk_dp_resume()
2914 .compatible = "mediatek,mt8188-edp-tx",
2918 .compatible = "mediatek,mt8188-dp-tx",
2922 .compatible = "mediatek,mt8195-edp-tx",
2926 .compatible = "mediatek,mt8195-dp-tx",
2937 .name = "mediatek-drm-dp",
2946 MODULE_AUTHOR("Markus Schneider-Pargmann <msp@baylibre.com>");
2947 MODULE_AUTHOR("Bo-Chen Chen <rex-bc.chen@mediatek.com>");