diff --git a/drivers/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_compliance.c b/drivers/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_compliance.c index a920deb2b..c70d61695 100644 --- a/drivers/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_compliance.c +++ b/drivers/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_compliance.c @@ -32,10 +32,10 @@ bool hdmitx_find_vendor_6g(struct hdmitx_dev *hdev) { int i; - if (!hdev || !hdev->tx_comm.edid_ptr) + if (!hdev) return false; for (i = 0; i < ARRAY_SIZE(vendor_6g); i++) { - if (memcmp(&hdev->tx_comm.edid_ptr[8], vendor_6g[i].data, + if (memcmp(&hdev->tx_comm.EDID_buf[8], vendor_6g[i].data, sizeof(vendor_6g[i].data)) == 0) return true; } @@ -47,10 +47,10 @@ bool hdmitx_find_vendor_ratio(struct hdmitx_dev *hdev) { int i; - if (!hdev || !hdev->tx_comm.edid_ptr) + if (!hdev) return false; for (i = 0; i < ARRAY_SIZE(vendor_ratio); i++) { - if (memcmp(&hdev->tx_comm.edid_ptr[8], vendor_ratio[i].data, + if (memcmp(&hdev->tx_comm.EDID_buf[8], vendor_ratio[i].data, sizeof(vendor_ratio[i].data)) == 0) return true; } @@ -62,10 +62,10 @@ bool hdmitx_find_vendor_null_pkt(struct hdmitx_dev *hdev) { int i; - if (!hdev || !hdev->tx_comm.edid_ptr) + if (!hdev) return false; for (i = 0; i < ARRAY_SIZE(vendor_null_pkt); i++) { - if (memcmp(&hdev->tx_comm.edid_ptr[8], vendor_null_pkt[i].data, + if (memcmp(&hdev->tx_comm.EDID_buf[8], vendor_null_pkt[i].data, sizeof(vendor_null_pkt[i].data)) == 0) return true; } diff --git a/drivers/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main.c b/drivers/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main.c index 715f06ad1..5e0bd774d 100644 --- a/drivers/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main.c +++ b/drivers/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main.c @@ -52,8 +52,6 @@ #include #include -#include -#include #include "hw/tvenc_conf.h" #include "hw/common.h" @@ -82,7 +80,6 @@ #define to_hdmitx20_dev(x) container_of(x, struct hdmitx_dev, tx_comm) static struct class *hdmitx_class; -static void hdmitx_get_edid(struct hdmitx_dev *hdev); static void hdmitx_set_drm_pkt(struct master_display_info_s *data); static void hdmitx_set_vsif_pkt(enum eotf_type type, enum mode_type tunnel_mode, struct dv_vsif_para *data, bool signal_sdr); @@ -169,13 +166,9 @@ static const struct of_device_id meson_amhdmitx_of_match[] = { #define meson_amhdmitx_dt_match NULL #endif -/*global getedid mutex*/ -DEFINE_MUTEX(getedid_mutex); - static struct hdmitx_dev *tx20_dev; static const struct dv_info dv_dummy; int hdmitx_log_level; -static bool hdmitx_edid_done; /* for SONY-KD-55A8F TV, need to mute more frames * when switch DV(LL)->HLG @@ -264,9 +257,9 @@ static void hdmitx_early_suspend(struct early_suspend *h) hdmitx_set_drm_pkt(NULL); hdmitx_set_vsif_pkt(0, 0, NULL, true); hdmitx_set_hdr10plus_pkt(0, NULL); - hdmitx_edid_buffer_clear(&hdev->tx_comm); - hdmitx_edid_rxcap_clear(&hdev->tx_comm); - hdmitx_edid_done = false; + hdmitx_edid_buffer_clear(hdev->tx_comm.EDID_buf, sizeof(hdev->tx_comm.EDID_buf)); + hdmitx_edid_rxcap_clear(&hdev->tx_comm.rxcap); + hdev->tx_comm.hdmitx_edid_done = false; edidinfo_detach_to_vinfo(hdev); hdmitx_set_uevent(HDMITX_HDCPPWR_EVENT, HDMI_SUSPEND); @@ -318,12 +311,12 @@ static void hdmitx_late_resume(struct early_suspend *h) hdmitx_hw_cntl_ddc(&hdev->tx_hw.base, DDC_GLITCH_FILTER_RESET, 0); if (hdev->tx_hw.chip_data->chip_type >= MESON_CPU_ID_G12A) hdmitx_hw_cntl_misc(&hdev->tx_hw.base, MISC_I2C_RESET, 0); - hdmitx_get_edid(hdev); - hdmitx_edid_done = true; + hdmitx_get_edid(&hdev->tx_comm, &hdev->tx_hw.base); + hdev->tx_comm.hdmitx_edid_done = true; } hdmitx_notify_hpd(hpd_state, - hdev->tx_comm.edid_parsing ? - hdev->tx_comm.edid_ptr : NULL); + hdev->tx_comm.rxcap.edid_parsing ? + hdev->tx_comm.EDID_buf : NULL); /* recover attr (especially for HDR case) */ if (info && drm_hdmitx_chk_mode_attr_sup(info->name, @@ -477,29 +470,29 @@ static void edidinfo_attach_to_vinfo(struct hdmitx_dev *hdev) { struct vinfo_s *info = &hdev->tx_comm.hdmitx_vinfo; - mutex_lock(&getedid_mutex); + mutex_lock(&hdev->tx_comm.getedid_mutex); hdrinfo_to_vinfo(&info->hdr_info, hdev); if (hdev->tx_comm.fmt_para.cd == COLORDEPTH_24B) memset(&info->hdr_info, 0, sizeof(struct hdr_info)); rxlatency_to_vinfo(info, &hdev->tx_comm.rxcap); hdmitx_vdev.dv_info = &hdev->tx_comm.rxcap.dv_info; hdmi_physical_size_to_vinfo(hdev); - memcpy(info->hdmichecksum, hdev->tx_comm.rxcap.chksum, 10); - mutex_unlock(&getedid_mutex); + memcpy(info->hdmichecksum, hdev->tx_comm.rxcap.hdmichecksum, 10); + mutex_unlock(&hdev->tx_comm.getedid_mutex); } static void edidinfo_detach_to_vinfo(struct hdmitx_dev *hdev) { struct vinfo_s *info = &hdev->tx_comm.hdmitx_vinfo; - mutex_lock(&getedid_mutex); + mutex_lock(&hdev->tx_comm.getedid_mutex); memset(&info->hdr_info, 0, sizeof(info->hdr_info)); memset(&info->rx_latency, 0, sizeof(info->rx_latency)); hdmitx_vdev.dv_info = &dv_dummy; info->screen_real_width = 0; info->screen_real_height = 0; - mutex_unlock(&getedid_mutex); + mutex_unlock(&hdev->tx_comm.getedid_mutex); } /*disp_mode attr*/ @@ -881,7 +874,7 @@ static void hdmitx_set_drm_pkt(struct master_display_info_s *data) struct hdmitx_hw_common *tx_hw_base = &hdev->tx_hw.base; hdmi_debug(); - spin_lock_irqsave(&hdev->edid_spinlock, flags); + spin_lock_irqsave(&hdev->tx_comm.edid_spinlock, flags); if (data) memcpy(&drm_config_data, data, sizeof(struct master_display_info_s)); @@ -962,7 +955,7 @@ static void hdmitx_set_drm_pkt(struct master_display_info_s *data) hdmitx_hw_set_packet(tx_hw_base, HDMI_PACKET_DRM, NULL, NULL); hdmitx_hw_cntl_config(tx_hw_base, CONF_AVI_BT2020, hdev->colormetry); - spin_unlock_irqrestore(&hdev->edid_spinlock, flags); + spin_unlock_irqrestore(&hdev->tx_comm.edid_spinlock, flags); return; } @@ -1003,7 +996,7 @@ static void hdmitx_set_drm_pkt(struct master_display_info_s *data) __func__, hdev->tx_comm.fmt_para.cs, hdev->tx_comm.fmt_para.cd); } - spin_unlock_irqrestore(&hdev->edid_spinlock, flags); + spin_unlock_irqrestore(&hdev->tx_comm.edid_spinlock, flags); return; } @@ -1054,7 +1047,7 @@ static void hdmitx_set_drm_pkt(struct master_display_info_s *data) hdmitx_hw_cntl_config(tx_hw_base, CONF_AVI_BT2020, SET_AVI_BT2020); } - spin_unlock_irqrestore(&hdev->edid_spinlock, flags); + spin_unlock_irqrestore(&hdev->tx_comm.edid_spinlock, flags); return; } @@ -1146,7 +1139,7 @@ static void hdmitx_set_drm_pkt(struct master_display_info_s *data) pr_info("%s: switch to 422,12bit\n", __func__); } } - spin_unlock_irqrestore(&hdev->edid_spinlock, flags); + spin_unlock_irqrestore(&hdev->tx_comm.edid_spinlock, flags); } static int calc_vinfo_from_hdmi_timing(const struct hdmi_timing *timing, struct vinfo_s *tx_vinfo) @@ -1233,9 +1226,9 @@ static void hdmitx_set_vsif_pkt(enum eotf_type type, unsigned long flags = 0; hdmi_debug(); - spin_lock_irqsave(&hdev->edid_spinlock, flags); + spin_lock_irqsave(&hdev->tx_comm.edid_spinlock, flags); if (hdev->bist_lock) { - spin_unlock_irqrestore(&hdev->edid_spinlock, flags); + spin_unlock_irqrestore(&hdev->tx_comm.edid_spinlock, flags); return; } if (!data) @@ -1260,7 +1253,7 @@ static void hdmitx_set_vsif_pkt(enum eotf_type type, if (hdev->ready == 0) { ltype = EOTF_T_NULL; ltmode = -1; - spin_unlock_irqrestore(&hdev->edid_spinlock, flags); + spin_unlock_irqrestore(&hdev->tx_comm.edid_spinlock, flags); return; } if (hdev->tx_comm.rxcap.dv_info.ieeeoui != DV_IEEE_OUI) { @@ -1270,7 +1263,7 @@ static void hdmitx_set_vsif_pkt(enum eotf_type type, if (hdev->tx_hw.chip_data->chip_type < MESON_CPU_ID_GXL) { pr_info("hdmitx: not support DolbyVision\n"); - spin_unlock_irqrestore(&hdev->edid_spinlock, flags); + spin_unlock_irqrestore(&hdev->tx_comm.edid_spinlock, flags); return; } @@ -1341,7 +1334,7 @@ static void hdmitx_set_vsif_pkt(enum eotf_type type, } if (type == EOTF_T_DV_AHEAD) { hdmitx_hw_set_packet(tx_hw_base, HDMI_PACKET_VEND, VEN_DB1, VEN_HB); - spin_unlock_irqrestore(&hdev->edid_spinlock, flags); + spin_unlock_irqrestore(&hdev->tx_comm.edid_spinlock, flags); return; } if (type == EOTF_T_DOLBYVISION) { @@ -1447,7 +1440,7 @@ static void hdmitx_set_vsif_pkt(enum eotf_type type, } if (type == EOTF_T_DV_AHEAD) { hdmitx_hw_set_packet(tx_hw_base, HDMI_PACKET_VEND, VEN_DB2, VEN_HB); - spin_unlock_irqrestore(&hdev->edid_spinlock, flags); + spin_unlock_irqrestore(&hdev->tx_comm.edid_spinlock, flags); return; } /*Dolby Vision standard case*/ @@ -1529,7 +1522,7 @@ static void hdmitx_set_vsif_pkt(enum eotf_type type, } } } - spin_unlock_irqrestore(&hdev->edid_spinlock, flags); + spin_unlock_irqrestore(&hdev->tx_comm.edid_spinlock, flags); } struct hdr10plus_para hdr10p_config_data; @@ -1632,14 +1625,14 @@ static void hdmitx_set_cuva_hdr_vsif(struct cuva_hdr_vsif_para *data) const struct cuva_info *cuva = &hdev->tx_comm.rxcap.hdr_info.cuva_info; struct hdmitx_hw_common *tx_hw_base = &hdev->tx_hw.base; - spin_lock_irqsave(&hdev->edid_spinlock, flags); + spin_lock_irqsave(&hdev->tx_comm.edid_spinlock, flags); if (cuva->ieeeoui != CUVA_IEEEOUI) { - spin_unlock_irqrestore(&hdev->edid_spinlock, flags); + spin_unlock_irqrestore(&hdev->tx_comm.edid_spinlock, flags); return; } if (!data) { hdmitx_hw_set_packet(tx_hw_base, HDMI_PACKET_VEND, NULL, NULL); - spin_unlock_irqrestore(&hdev->edid_spinlock, flags); + spin_unlock_irqrestore(&hdev->tx_comm.edid_spinlock, flags); return; } ven_db[0] = GET_OUI_BYTE0(CUVA_IEEEOUI); @@ -1648,7 +1641,7 @@ static void hdmitx_set_cuva_hdr_vsif(struct cuva_hdr_vsif_para *data) ven_db[3] = data->system_start_code; ven_db[4] = (data->version_code & 0xf) << 4; hdmitx_hw_set_packet(tx_hw_base, HDMI_PACKET_VEND, ven_db, ven_hb); - spin_unlock_irqrestore(&hdev->edid_spinlock, flags); + spin_unlock_irqrestore(&hdev->tx_comm.edid_spinlock, flags); } struct hdmi_packet_t { @@ -1667,10 +1660,10 @@ static void hdmitx_set_cuva_hdr_vs_emds(struct cuva_hdr_vs_emds_para *data) unsigned long phys_ptr; memset(vs_emds, 0, sizeof(vs_emds)); - spin_lock_irqsave(&hdev->edid_spinlock, flags); + spin_lock_irqsave(&hdev->tx_comm.edid_spinlock, flags); if (!data) { hdmitx_hw_cntl_config(&hdev->tx_hw.base, CONF_EMP_NUMBER, 0); - spin_unlock_irqrestore(&hdev->edid_spinlock, flags); + spin_unlock_irqrestore(&hdev->tx_comm.edid_spinlock, flags); return; } @@ -1771,7 +1764,7 @@ static void hdmitx_set_cuva_hdr_vs_emds(struct cuva_hdr_vs_emds_para *data) hdmitx_hw_cntl_config(&hdev->tx_hw.base, CONF_EMP_NUMBER, sizeof(vs_emds) / (sizeof(struct hdmi_packet_t))); hdmitx_hw_cntl_config(&hdev->tx_hw.base, CONF_EMP_PHY_ADDR, phys_ptr); - spin_unlock_irqrestore(&hdev->edid_spinlock, flags); + spin_unlock_irqrestore(&hdev->tx_comm.edid_spinlock, flags); } #define EMP_FIRST 0x80 @@ -3988,70 +3981,6 @@ static int hdmitx_notify_callback_a(struct notifier_block *block, #endif -static void hdmitx_get_edid(struct hdmitx_dev *hdev) -{ - unsigned long flags = 0; - struct hdmitx_common *tx_comm = &hdev->tx_comm; - - mutex_lock(&getedid_mutex); - hdmitx_edid_buffer_clear(&hdev->tx_comm); - hdmitx_hw_cntl_ddc(&hdev->tx_hw.base, DDC_RESET_EDID, 0); - hdmitx_hw_cntl_ddc(&hdev->tx_hw.base, DDC_PIN_MUX_OP, PIN_MUX); - /* start reading edid first time */ - hdmitx_hw_cntl_ddc(&hdev->tx_hw.base, DDC_EDID_READ_DATA, 0); - if (hdmitx_edid_is_all_zeros(hdev->tx_comm.EDID_buf)) { - hdmitx_hw_cntl_ddc(&hdev->tx_hw.base, DDC_GLITCH_FILTER_RESET, 0); - hdmitx_hw_cntl_ddc(&hdev->tx_hw.base, DDC_EDID_READ_DATA, 0); - } - /* If EDID is not correct at first time, then retry */ - if (!check_dvi_hdmi_edid_valid(hdev->tx_comm.EDID_buf)) { - struct timespec64 kts; - struct rtc_time tm; - - msleep(20); - ktime_get_real_ts64(&kts); - rtc_time64_to_tm(kts.tv_sec, &tm); - if (hdev->hdmitx_gpios_scl != -EPROBE_DEFER) - pr_info("UTC+0 %ptRd %ptRt DDC SCL %s\n", &tm, &tm, - gpio_get_value(hdev->hdmitx_gpios_scl) ? "HIGH" : "LOW"); - if (hdev->hdmitx_gpios_sda != -EPROBE_DEFER) - pr_info("UTC+0 %ptRd %ptRt DDC SDA %s\n", &tm, &tm, - gpio_get_value(hdev->hdmitx_gpios_sda) ? "HIGH" : "LOW"); - msleep(80); - - /* start reading edid second time */ - hdmitx_hw_cntl_ddc(&hdev->tx_hw.base, DDC_EDID_READ_DATA, 0); - if (hdmitx_edid_is_all_zeros(hdev->tx_comm.EDID_buf)) { - hdmitx_hw_cntl_ddc(&hdev->tx_hw.base, DDC_GLITCH_FILTER_RESET, 0); - hdmitx_hw_cntl_ddc(&hdev->tx_hw.base, DDC_EDID_READ_DATA, 0); - } - } - spin_lock_irqsave(&hdev->edid_spinlock, flags); - hdmitx_edid_rxcap_clear(&hdev->tx_comm); - hdmitx_edid_parse(&hdev->tx_comm); - - if (tx_comm->hdr_priority == 1) { /* clear dv_info */ - struct dv_info *dv = &hdev->tx_comm.rxcap.dv_info; - - memset(dv, 0, sizeof(struct dv_info)); - pr_info("clear dv_info\n"); - } - if (tx_comm->hdr_priority == 2) { /* clear dv_info/hdr_info */ - struct dv_info *dv = &hdev->tx_comm.rxcap.dv_info; - struct hdr_info *hdr = &hdev->tx_comm.rxcap.hdr_info; - - memset(dv, 0, sizeof(struct dv_info)); - memset(hdr, 0, sizeof(struct hdr_info)); - pr_info("clear dv_info/hdr_info\n"); - } - spin_unlock_irqrestore(&hdev->edid_spinlock, flags); - hdmitx_event_mgr_notify(hdev->tx_comm.event_mgr, - HDMITX_PHY_ADDR_VALID, &hdev->tx_comm.rxcap.physical_addr); - hdmitx_edid_print(&hdev->tx_comm); - - mutex_unlock(&getedid_mutex); -} - static void hdmitx_rxsense_process(struct work_struct *work) { int sense; @@ -4087,9 +4016,8 @@ bool is_tv_changed(void) struct hdmitx_dev *hdev = get_hdmitx_device(); struct hdmitx_common *tx_comm = &hdev->tx_comm; - if (memcmp(tx_comm->hdmichecksum, hdev->tx_comm.rxcap.chksum, 10) && - memcmp(emptychecksum, hdev->tx_comm.rxcap.chksum, 10) && - memcmp(invalidchecksum, tx_comm->hdmichecksum, 10)) { + if (memcmp(emptychecksum, tx_comm->rxcap.hdmichecksum, 10) && + memcmp(invalidchecksum, tx_comm->rxcap.hdmichecksum, 10)) { ret = true; pr_info("hdmi crc is diff between uboot and kernel\n"); } @@ -4152,11 +4080,11 @@ static void hdmitx_hpd_plugin_handler(struct work_struct *work) * EDID, now EDID already read done and hdcp already started, * not read EDID again. */ - if (!hdmitx_edid_done) { + if (!hdev->tx_comm.hdmitx_edid_done) { if (hdev->tx_hw.chip_data->chip_type >= MESON_CPU_ID_G12A) hdmitx_hw_cntl_misc(&hdev->tx_hw.base, MISC_I2C_RESET, 0); - hdmitx_get_edid(hdev); - hdmitx_edid_done = true; + hdmitx_get_edid(&hdev->tx_comm, &hdev->tx_hw.base); + hdev->tx_comm.hdmitx_edid_done = true; } /* start reading E-EDID */ hdev->cedst_policy = hdev->cedst_en & hdev->tx_comm.rxcap.scdc_present; @@ -4166,10 +4094,10 @@ static void hdmitx_hpd_plugin_handler(struct work_struct *work) else hdmitx_hw_cntl_config(&hdev->tx_hw.base, CONF_HDMI_DVI_MODE, HDMI_MODE); - mutex_lock(&getedid_mutex); + mutex_lock(&hdev->tx_comm.getedid_mutex); if (hdev->tx_hw.chip_data->chip_type < MESON_CPU_ID_G12A) hdmitx_hw_cntl_misc(&hdev->tx_hw.base, MISC_I2C_REACTIVE, 0); - mutex_unlock(&getedid_mutex); + mutex_unlock(&hdev->tx_comm.getedid_mutex); if (hdev->tx_comm.repeater_mode) { rx_set_repeater_support(1); hdmitx_hw_cntl_ddc(&hdev->tx_hw.base, DDC_HDCP_GET_BKSV, @@ -4205,8 +4133,8 @@ static void hdmitx_hpd_plugin_handler(struct work_struct *work) } hdev->tx_comm.hpd_state = 1; hdmitx_notify_hpd(hdev->tx_comm.hpd_state, - hdev->tx_comm.edid_parsing ? - hdev->tx_comm.edid_ptr : NULL); + hdev->tx_comm.rxcap.edid_parsing ? + hdev->tx_comm.EDID_buf : NULL); /* audio uevent is used for android to * register hdmi audio device, it should * sync with hdmi hpd state. @@ -4266,9 +4194,9 @@ static void hdmitx_hpd_plugout_handler(struct work_struct *work) edidinfo_detach_to_vinfo(hdev); hdev->hdmitx_event &= ~HDMI_TX_HPD_PLUGOUT; rx_edid_physical_addr(0, 0, 0, 0); - hdmitx_edid_buffer_clear(&hdev->tx_comm); - hdmitx_edid_rxcap_clear(&hdev->tx_comm); - hdmitx_edid_done = false; + hdmitx_edid_buffer_clear(hdev->tx_comm.EDID_buf, sizeof(hdev->tx_comm.EDID_buf)); + hdmitx_edid_rxcap_clear(&hdev->tx_comm.rxcap); + hdev->tx_comm.hdmitx_edid_done = false; hdev->tx_comm.hpd_state = 0; hdmitx_notify_hpd(hdev->tx_comm.hpd_state, NULL); hdmitx_hw_cntl_misc(&hdev->tx_hw.base, MISC_AVMUTE_OP, SET_AVMUTE); @@ -4292,9 +4220,9 @@ static void hdmitx_hpd_plugout_handler(struct work_struct *work) /*edid info clear*/ rx_edid_physical_addr(0, 0, 0, 0); - hdmitx_edid_buffer_clear(&hdev->tx_comm); - hdmitx_edid_rxcap_clear(&hdev->tx_comm); - hdmitx_edid_done = false; + hdmitx_edid_buffer_clear(hdev->tx_comm.EDID_buf, sizeof(hdev->tx_comm.EDID_buf)); + hdmitx_edid_rxcap_clear(&hdev->tx_comm.rxcap); + hdev->tx_comm.hdmitx_edid_done = false; edidinfo_detach_to_vinfo(hdev); /*update hpd state*/ @@ -4432,8 +4360,8 @@ int hdmitx20_event_notifier_regist(struct notifier_block *nb) /* update status when register */ if (!ret && nb->notifier_call) { hdmitx_notify_hpd(hdev->tx_comm.hpd_state, - hdev->tx_comm.edid_parsing ? - hdev->tx_comm.edid_ptr : NULL); + hdev->tx_comm.rxcap.edid_parsing ? + hdev->tx_comm.EDID_buf : NULL); if (hdev->tx_comm.rxcap.physical_addr != 0xffff) hdmitx_event_mgr_notify(hdev->tx_comm.event_mgr, HDMITX_PHY_ADDR_VALID, &hdev->tx_comm.rxcap.physical_addr); @@ -4587,17 +4515,17 @@ static int amhdmitx_get_dt_info(struct platform_device *pdev, struct hdmitx_dev hdev->pinctrl_default); } - hdev->hdmitx_gpios_hpd = of_get_named_gpio_flags(pdev->dev.of_node, + hdev->tx_comm.hdmitx_gpios_hpd = of_get_named_gpio_flags(pdev->dev.of_node, "hdmitx-gpios-hpd", 0, NULL); - if (hdev->hdmitx_gpios_hpd == -EPROBE_DEFER) + if (hdev->tx_comm.hdmitx_gpios_hpd == -EPROBE_DEFER) pr_err("get hdmitx-gpios-hpd error\n"); - hdev->hdmitx_gpios_scl = of_get_named_gpio_flags(pdev->dev.of_node, + hdev->tx_comm.hdmitx_gpios_scl = of_get_named_gpio_flags(pdev->dev.of_node, "hdmitx-gpios-scl", 0, NULL); - if (hdev->hdmitx_gpios_scl == -EPROBE_DEFER) + if (hdev->tx_comm.hdmitx_gpios_scl == -EPROBE_DEFER) pr_err("get hdmitx-gpios-scl error\n"); - hdev->hdmitx_gpios_sda = of_get_named_gpio_flags(pdev->dev.of_node, + hdev->tx_comm.hdmitx_gpios_sda = of_get_named_gpio_flags(pdev->dev.of_node, "hdmitx-gpios-sda", 0, NULL); - if (hdev->hdmitx_gpios_sda == -EPROBE_DEFER) + if (hdev->tx_comm.hdmitx_gpios_sda == -EPROBE_DEFER) pr_err("get hdmitx-gpios-sda error\n"); #ifdef CONFIG_OF @@ -4947,8 +4875,8 @@ static int amhdmitx_probe(struct platform_device *pdev) hdev->tx_comm.fmt_attr, sizeof(hdev->tx_comm.fmt_attr)); /* When init hdmi, clear the hdmitx module edid ram and edid buffer. */ - hdmitx_edid_buffer_clear(&hdev->tx_comm); - hdmitx_edid_rxcap_clear(&hdev->tx_comm); + hdmitx_edid_buffer_clear(hdev->tx_comm.EDID_buf, sizeof(hdev->tx_comm.EDID_buf)); + hdmitx_edid_rxcap_clear(&hdev->tx_comm.rxcap); hdmitx_hdr_state_init(hdev); #ifdef CONFIG_AMLOGIC_VOUT_SERVE @@ -4969,7 +4897,7 @@ static int amhdmitx_probe(struct platform_device *pdev) hdmitx20_audio_mute_op(1); /* default audio clock is ON */ aout_register_client(&hdmitx_notifier_nb_a); #endif - spin_lock_init(&hdev->edid_spinlock); + spin_lock_init(&hdev->tx_comm.edid_spinlock); hdev->tx_comm.hpd_state = !!hdmitx_hw_cntl_misc(&hdev->tx_hw.base, MISC_HPD_GPI_ST, 0); @@ -5002,7 +4930,7 @@ static int amhdmitx_probe(struct platform_device *pdev) if (hdev->tx_comm.hpd_state) { /* need to get edid before vout probe */ hdev->tx_comm.already_used = 1; - hdmitx_get_edid(hdev); + hdmitx_get_edid(&hdev->tx_comm, &hdev->tx_hw.base); edidinfo_attach_to_vinfo(hdev); /* When bootup mbox and TV simultaneously, diff --git a/drivers/media/vout/hdmitx/hdmi_tx_20/hw/hdmi_tx_hw.c b/drivers/media/vout/hdmitx/hdmi_tx_20/hw/hdmi_tx_hw.c index 7492c7ab2..279d1261e 100644 --- a/drivers/media/vout/hdmitx/hdmi_tx_20/hw/hdmi_tx_hw.c +++ b/drivers/media/vout/hdmitx/hdmi_tx_20/hw/hdmi_tx_hw.c @@ -719,14 +719,14 @@ static irqreturn_t intr_handler(int irq, void *dev) pr_info(SYS "irq %x %x\n", dat_top, dat_dwc); /* bit[2:1] of dat_top means HPD falling and rising */ - if ((dat_top & 0x6) && hdev->hdmitx_gpios_hpd != -EPROBE_DEFER) { + if ((dat_top & 0x6) && hdev->tx_comm.hdmitx_gpios_hpd != -EPROBE_DEFER) { struct timespec64 kts; struct rtc_time tm; ktime_get_real_ts64(&kts); rtc_time64_to_tm(kts.tv_sec, &tm); pr_info("UTC+0 %ptRd %ptRt HPD %s\n", &tm, &tm, - gpio_get_value(hdev->hdmitx_gpios_hpd) ? "HIGH" : "LOW"); + gpio_get_value(hdev->tx_comm.hdmitx_gpios_hpd) ? "HIGH" : "LOW"); } if (hdev->tx_hw.debug_hpd_lock == 1) { diff --git a/drivers/media/vout/hdmitx/hdmi_tx_20/meson_hdcp.c b/drivers/media/vout/hdmitx/hdmi_tx_20/meson_hdcp.c index 5956fd832..c4c78d525 100644 --- a/drivers/media/vout/hdmitx/hdmi_tx_20/meson_hdcp.c +++ b/drivers/media/vout/hdmitx/hdmi_tx_20/meson_hdcp.c @@ -617,9 +617,9 @@ unsigned int meson_hdcp_get_rx_cap(void) return 0x1; /* Detect RX support HDCP22 */ - mutex_lock(&getedid_mutex); + mutex_lock(&hdev->tx_comm.getedid_mutex); ver = hdcp_rd_hdcp22_ver(); - mutex_unlock(&getedid_mutex); + mutex_unlock(&hdev->tx_comm.getedid_mutex); /* Here, must assume RX support HDCP14, otherwise affect 1A-03 */ if (ver) return 0x3; diff --git a/drivers/media/vout/hdmitx21/hdmi_tx_main.c b/drivers/media/vout/hdmitx21/hdmi_tx_main.c index 77b99aad1..adb6fec67 100644 --- a/drivers/media/vout/hdmitx21/hdmi_tx_main.c +++ b/drivers/media/vout/hdmitx21/hdmi_tx_main.c @@ -77,7 +77,6 @@ unsigned int rx_hdcp2_ver; #define to_hdmitx21_dev(x) container_of(x, struct hdmitx_dev, tx_comm) static struct class *hdmitx_class; -static void hdmitx_get_edid(struct hdmitx_dev *hdev); static void hdmitx_set_drm_pkt(struct master_display_info_s *data); static void hdmitx_set_vsif_pkt(enum eotf_type type, enum mode_type tunnel_mode, struct dv_vsif_para *data, bool signal_sdr); @@ -151,8 +150,6 @@ static const struct of_device_id meson_amhdmitx_of_match[] = { #define meson_amhdmitx_dt_match NULL #endif -static DEFINE_MUTEX(getedid_mutex); - static struct hdmitx_dev *tx21_dev; struct hdmitx_dev *get_hdmitx21_device(void) @@ -180,7 +177,6 @@ struct vsdb_phyaddr *get_hdmitx21_phy_addr(void) static const struct dv_info dv_dummy; static struct dv_info ext_dvinfo; static int log21_level; -static bool hdmitx_edid_done; static struct vout_device_s hdmitx_vdev = { .dv_info = &dv_dummy, @@ -197,10 +193,6 @@ static struct vout_device_s hdmitx_vdev = { /* indicate plugout before systemcontrol boot */ static bool plugout_mute_flg; -static char hdmichecksum[11] = { - 'i', 'n', 'v', 'a', 'l', 'i', 'd', 'c', 'r', 'c', '\0' -}; - static char invalidchecksum[11] = { 'i', 'n', 'v', 'a', 'l', 'i', 'd', 'c', 'r', 'c', '\0' }; @@ -297,9 +289,9 @@ static void hdmitx_early_suspend(struct early_suspend *h) hdev->tx_comm.cur_VIC = HDMI_0_UNKNOWN; hdmitx_set_vsif_pkt(0, 0, NULL, true); hdmitx_set_hdr10plus_pkt(0, NULL); - hdmitx_edid_buffer_clear(&hdev->tx_comm); - hdmitx_edid_rxcap_clear(&hdev->tx_comm); - hdmitx_edid_done = false; + hdmitx_edid_buffer_clear(hdev->tx_comm.EDID_buf, sizeof(hdev->tx_comm.EDID_buf)); + hdmitx_edid_rxcap_clear(&hdev->tx_comm.rxcap); + hdev->tx_comm.hdmitx_edid_done = false; edidinfo_detach_to_vinfo(hdev); /* clear audio/video mute flag of stream type */ hdmitx21_video_mute_op(1, VIDEO_MUTE_PATH_2); @@ -336,13 +328,13 @@ static void hdmitx_late_resume(struct early_suspend *h) /* add i2c soft reset before read EDID */ hdmitx_hw_cntl_ddc(&hdev->tx_hw.base, DDC_GLITCH_FILTER_RESET, 0); hdmitx_hw_cntl_misc(&hdev->tx_hw.base, MISC_I2C_RESET, 0); - hdmitx_get_edid(hdev); - hdmitx_edid_done = true; + hdmitx_get_edid(&hdev->tx_comm, &hdev->tx_hw.base); + hdev->tx_comm.hdmitx_edid_done = true; } if (hdev->tv_usage == 0) hdmitx_notify_hpd(hdev->tx_comm.hpd_state, - hdev->tx_comm.edid_parsing ? - hdev->tx_comm.edid_ptr : NULL); + hdev->tx_comm.rxcap.edid_parsing ? + hdev->tx_comm.EDID_buf : NULL); hdmitx_hw_cntl_config(&hdev->tx_hw.base, CONF_AUDIO_MUTE_OP, AUDIO_MUTE); /* set_disp_mode_auto(); */ @@ -498,7 +490,7 @@ static void edidinfo_attach_to_vinfo(struct hdmitx_dev *hdev) struct vinfo_s *info = &hdev->tx_comm.hdmitx_vinfo; struct hdmi_format_para *para = &hdev->tx_comm.fmt_para; - mutex_lock(&getedid_mutex); + mutex_lock(&hdev->tx_comm.getedid_mutex); hdrinfo_to_vinfo(&info->hdr_info, hdev); memcpy(&ext_dvinfo, &hdev->tx_comm.rxcap.dv_info, sizeof(ext_dvinfo)); if (para->cd == COLORDEPTH_24B) @@ -506,7 +498,7 @@ static void edidinfo_attach_to_vinfo(struct hdmitx_dev *hdev) rxlatency_to_vinfo(info, &hdev->tx_comm.rxcap); hdmitx_vdev.dv_info = &hdev->tx_comm.rxcap.dv_info; hdmi_physical_size_to_vinfo(hdev); - mutex_unlock(&getedid_mutex); + mutex_unlock(&hdev->tx_comm.getedid_mutex); } static void edidinfo_detach_to_vinfo(struct hdmitx_dev *hdev) @@ -845,7 +837,7 @@ static void hdmitx_set_drm_pkt(struct master_display_info_s *data) if (!_check_hdmi_mode()) return; hdmi_debug(); - spin_lock_irqsave(&hdev->edid_spinlock, flags); + spin_lock_irqsave(&hdev->tx_comm.edid_spinlock, flags); if (hdr_status_pos == 4) { /* zero hdr10+ VSIF being sent - disable it */ pr_info("%s: disable hdr10+ zero vsif\n", __func__); @@ -898,7 +890,7 @@ static void hdmitx_set_drm_pkt(struct master_display_info_s *data) drm_db[0] = 0; hdmi_drm_infoframe_set(NULL); hdmi_avi_infoframe_config(CONF_AVI_BT2020, hdev->colormetry); - spin_unlock_irqrestore(&hdev->edid_spinlock, flags); + spin_unlock_irqrestore(&hdev->tx_comm.edid_spinlock, flags); return; } @@ -914,7 +906,7 @@ static void hdmitx_set_drm_pkt(struct master_display_info_s *data) schedule_work(&hdev->work_hdr); drm_db[0] = 0; } - spin_unlock_irqrestore(&hdev->edid_spinlock, flags); + spin_unlock_irqrestore(&hdev->tx_comm.edid_spinlock, flags); return; } @@ -959,7 +951,7 @@ static void hdmitx_set_drm_pkt(struct master_display_info_s *data) hdmi_drm_infoframe_rawset(drm_hb, db); hdmi_avi_infoframe_config(CONF_AVI_BT2020, SET_AVI_BT2020); } - spin_unlock_irqrestore(&hdev->edid_spinlock, flags); + spin_unlock_irqrestore(&hdev->tx_comm.edid_spinlock, flags); return; } @@ -1017,7 +1009,7 @@ static void hdmitx_set_drm_pkt(struct master_display_info_s *data) hdev->hdmi_last_hdr_mode = hdev->hdmi_current_hdr_mode; schedule_work(&hdev->work_hdr); } - spin_unlock_irqrestore(&hdev->edid_spinlock, flags); + spin_unlock_irqrestore(&hdev->tx_comm.edid_spinlock, flags); } static int calc_vinfo_from_hdmi_timing(const struct hdmi_timing *timing, struct vinfo_s *tx_vinfo) @@ -1103,9 +1095,9 @@ static void hdmitx_set_vsif_pkt(enum eotf_type type, if (!_check_hdmi_mode()) return; hdmi_debug(); - spin_lock_irqsave(&hdev->edid_spinlock, flags); + spin_lock_irqsave(&hdev->tx_comm.edid_spinlock, flags); if (hdev->bist_lock) { - spin_unlock_irqrestore(&hdev->edid_spinlock, flags); + spin_unlock_irqrestore(&hdev->tx_comm.edid_spinlock, flags); return; } @@ -1122,7 +1114,7 @@ static void hdmitx_set_vsif_pkt(enum eotf_type type, if (hdev->ready == 0) { ltype = EOTF_T_NULL; ltmode = -1; - spin_unlock_irqrestore(&hdev->edid_spinlock, flags); + spin_unlock_irqrestore(&hdev->tx_comm.edid_spinlock, flags); return; } if (hdev->tx_comm.rxcap.dv_info.ieeeoui != DV_IEEE_OUI) { @@ -1192,7 +1184,7 @@ static void hdmitx_set_vsif_pkt(enum eotf_type type, } if (type == EOTF_T_DV_AHEAD) { hdmi_vend_infoframe_rawset(ven_hb, db1); - spin_unlock_irqrestore(&hdev->edid_spinlock, flags); + spin_unlock_irqrestore(&hdev->tx_comm.edid_spinlock, flags); return; } if (type == EOTF_T_DOLBYVISION) { @@ -1297,7 +1289,7 @@ static void hdmitx_set_vsif_pkt(enum eotf_type type, } if (type == EOTF_T_DV_AHEAD) { hdmi_vend_infoframe_rawset(ven_hb, db2); - spin_unlock_irqrestore(&hdev->edid_spinlock, flags); + spin_unlock_irqrestore(&hdev->tx_comm.edid_spinlock, flags); return; } /*Dolby Vision standard case*/ @@ -1377,7 +1369,7 @@ static void hdmitx_set_vsif_pkt(enum eotf_type type, } } hdmitx21_dither_config(hdev); - spin_unlock_irqrestore(&hdev->edid_spinlock, flags); + spin_unlock_irqrestore(&hdev->tx_comm.edid_spinlock, flags); } static void hdmitx_set_hdr10plus_pkt(u32 flag, @@ -1463,10 +1455,10 @@ static void hdmitx_set_cuva_hdr_vsif(struct cuva_hdr_vsif_para *data) if (!_check_hdmi_mode()) return; - spin_lock_irqsave(&hdev->edid_spinlock, flags); + spin_lock_irqsave(&hdev->tx_comm.edid_spinlock, flags); if (!data) { hdmi_vend_infoframe_rawset(NULL, NULL); - spin_unlock_irqrestore(&hdev->edid_spinlock, flags); + spin_unlock_irqrestore(&hdev->tx_comm.edid_spinlock, flags); return; } ven_db[0] = GET_OUI_BYTE0(CUVA_IEEEOUI); @@ -1475,7 +1467,7 @@ static void hdmitx_set_cuva_hdr_vsif(struct cuva_hdr_vsif_para *data) ven_db[3] = data->system_start_code; ven_db[4] = (data->version_code & 0xf) << 4; hdmi_vend_infoframe_rawset(ven_hb, db); - spin_unlock_irqrestore(&hdev->edid_spinlock, flags); + spin_unlock_irqrestore(&hdev->tx_comm.edid_spinlock, flags); } static void hdmitx_set_cuva_hdr_vs_emds(struct cuva_hdr_vs_emds_para *data) @@ -1488,10 +1480,10 @@ static void hdmitx_set_cuva_hdr_vs_emds(struct cuva_hdr_vs_emds_para *data) if (!_check_hdmi_mode()) return; memset(vs_emds, 0, sizeof(vs_emds)); - spin_lock_irqsave(&hdev->edid_spinlock, flags); + spin_lock_irqsave(&hdev->tx_comm.edid_spinlock, flags); if (!data) { hdmitx_dhdr_send(NULL, 0); - spin_unlock_irqrestore(&hdev->edid_spinlock, flags); + spin_unlock_irqrestore(&hdev->tx_comm.edid_spinlock, flags); return; } @@ -1582,7 +1574,7 @@ static void hdmitx_set_cuva_hdr_vs_emds(struct cuva_hdr_vs_emds_para *data) vs_emds[2].pb[6] = data->max_display_mastering_lum & 0xff; hdmitx_dhdr_send((u8 *)&vs_emds, max_size); - spin_unlock_irqrestore(&hdev->edid_spinlock, flags); + spin_unlock_irqrestore(&hdev->tx_comm.edid_spinlock, flags); } /* reserved, left blank here, move to hdmi_tx_vrr.c file */ @@ -3797,53 +3789,6 @@ static int hdmitx_notify_callback_a(struct notifier_block *block, } #endif -static void hdmitx_get_edid(struct hdmitx_dev *hdev) -{ - struct hdmitx_common *tx_comm = &hdev->tx_comm; - struct hdmitx_hw_common *tx_hw_base = &hdev->tx_hw.base; - - mutex_lock(&getedid_mutex); - hdmitx_edid_buffer_clear(&hdev->tx_comm); - hdmitx_hw_cntl_ddc(tx_hw_base, DDC_RESET_EDID, 0); - hdmitx_hw_cntl_ddc(tx_hw_base, DDC_PIN_MUX_OP, PIN_MUX); - /* start reading edid first time */ - hdmitx_hw_cntl_ddc(tx_hw_base, DDC_EDID_READ_DATA, 0); - if (hdmitx_edid_is_all_zeros(tx_comm->EDID_buf)) { - hdmitx_hw_cntl_ddc(tx_hw_base, DDC_GLITCH_FILTER_RESET, 0); - hdmitx_hw_cntl_ddc(tx_hw_base, DDC_EDID_READ_DATA, 0); - } - /* If EDID is not correct at first time, then retry */ - if (!check_dvi_hdmi_edid_valid(hdev->tx_comm.EDID_buf)) { - msleep(100); - /* start reading edid second time */ - hdmitx_hw_cntl_ddc(tx_hw_base, DDC_EDID_READ_DATA, 0); - if (hdmitx_edid_is_all_zeros(hdev->tx_comm.EDID_buf)) { - hdmitx_hw_cntl_ddc(tx_hw_base, DDC_GLITCH_FILTER_RESET, 0); - hdmitx_hw_cntl_ddc(tx_hw_base, DDC_EDID_READ_DATA, 0); - } - } - hdmitx_edid_rxcap_clear(&hdev->tx_comm); - hdmitx_edid_parse(&hdev->tx_comm); - - if (tx_comm->hdr_priority == 1) { /* clear dv_info */ - struct dv_info *dv = &hdev->tx_comm.rxcap.dv_info; - - memset(dv, 0, sizeof(struct dv_info)); - pr_info("clear dv_info\n"); - } - if (tx_comm->hdr_priority == 2) { /* clear dv_info/hdr_info */ - struct dv_info *dv = &hdev->tx_comm.rxcap.dv_info; - struct hdr_info *hdr = &hdev->tx_comm.rxcap.hdr_info; - - memset(dv, 0, sizeof(struct dv_info)); - memset(hdr, 0, sizeof(struct hdr_info)); - pr_info("clear dv_info/hdr_info\n"); - } - hdmitx_edid_print(&hdev->tx_comm); - - mutex_unlock(&getedid_mutex); -} - static void hdmitx_rxsense_process(struct work_struct *work) { int sense; @@ -3874,9 +3819,8 @@ static bool is_tv_changed(void) bool ret = false; struct hdmitx_dev *hdev = get_hdmitx21_device(); - if (memcmp(hdmichecksum, hdev->tx_comm.rxcap.chksum, 10) && - memcmp(emptychecksum, hdev->tx_comm.rxcap.chksum, 10) && - memcmp(invalidchecksum, hdmichecksum, 10)) { + if (memcmp(emptychecksum, hdev->tx_comm.rxcap.hdmichecksum, 10) && + memcmp(invalidchecksum, hdev->tx_comm.rxcap.hdmichecksum, 10)) { ret = true; pr_info("hdmi crc is diff between uboot and kernel\n"); } @@ -3908,10 +3852,10 @@ static void hdmitx_hpd_plugin_handler(struct work_struct *work) * EDID, now EDID already read done and hdcp already started, * not read EDID again. */ - if (!hdmitx_edid_done) { + if (!hdev->tx_comm.rxcap.edid_parsing) { hdmitx_hw_cntl_misc(&hdev->tx_hw.base, MISC_I2C_RESET, 0); - hdmitx_get_edid(hdev); - hdmitx_edid_done = true; + hdmitx_get_edid(&hdev->tx_comm, &hdev->tx_hw.base); + hdev->tx_comm.hdmitx_edid_done = true; } hdev->hdmitx_event &= ~HDMI_TX_HPD_PLUGIN; /* start reading E-EDID */ @@ -3955,8 +3899,8 @@ static void hdmitx_hpd_plugin_handler(struct work_struct *work) hdev->tx_comm.hpd_state = 1; if (hdev->tv_usage == 0) hdmitx_notify_hpd(hdev->tx_comm.hpd_state, - hdev->tx_comm.edid_parsing ? - hdev->tx_comm.edid_ptr : NULL); + hdev->tx_comm.rxcap.edid_parsing ? + hdev->tx_comm.EDID_buf : NULL); /* Should be started at end of output */ cancel_delayed_work(&hdev->work_cedst); if (hdev->cedst_policy) @@ -3999,9 +3943,9 @@ static void hdmitx_hpd_plugout_handler(struct work_struct *work) plugout_mute_flg = true; /* edidinfo_detach_to_vinfo(hdev); */ hdev->hdmitx_event &= ~HDMI_TX_HPD_PLUGOUT; - hdmitx_edid_buffer_clear(&hdev->tx_comm); - hdmitx_edid_rxcap_clear(&hdev->tx_comm); - hdmitx_edid_done = false; + hdmitx_edid_buffer_clear(hdev->tx_comm.EDID_buf, sizeof(hdev->tx_comm.EDID_buf)); + hdmitx_edid_rxcap_clear(&hdev->tx_comm.rxcap); + hdev->tx_comm.hdmitx_edid_done = false; hdev->tx_comm.hpd_state = 0; if (hdev->tv_usage == 0) { rx_edid_physical_addr(0, 0, 0, 0); @@ -4035,9 +3979,9 @@ static void hdmitx_hpd_plugout_handler(struct work_struct *work) hdmitx21_rst_stream_type(hdev->am_hdcp); p_hdcp->saved_upstream_type = 0; p_hdcp->rx_update_flag = 0; - hdmitx_edid_buffer_clear(&hdev->tx_comm); - hdmitx_edid_rxcap_clear(&hdev->tx_comm); - hdmitx_edid_done = false; + hdmitx_edid_buffer_clear(hdev->tx_comm.EDID_buf, sizeof(hdev->tx_comm.EDID_buf)); + hdmitx_edid_rxcap_clear(&hdev->tx_comm.rxcap); + hdev->tx_comm.hdmitx_edid_done = false; hdev->tx_comm.hpd_state = 0; hdev->ll_enabled_in_auto_mode = false; if (hdev->tv_usage == 0) { @@ -4135,8 +4079,8 @@ int hdmitx21_event_notifier_regist(struct notifier_block *nb) if (!ret && nb->notifier_call) { if (hdev->tv_usage == 0) hdmitx_notify_hpd(hdev->tx_comm.hpd_state, - hdev->tx_comm.edid_parsing ? - hdev->tx_comm.edid_ptr : NULL); + hdev->tx_comm.rxcap.edid_parsing ? + hdev->tx_comm.EDID_buf : NULL); if (hdev->tx_comm.rxcap.physical_addr != 0xffff) { if (hdev->tv_usage == 0) hdmitx_event_mgr_notify(hdev->tx_comm.event_mgr, @@ -4681,7 +4625,6 @@ static int amhdmitx_probe(struct platform_device *pdev) hdmitx_format_para_rebuild_fmtattr_str(&hdev->tx_comm.fmt_para, hdev->tx_comm.fmt_attr, sizeof(hdev->tx_comm.fmt_attr)); - mutex_init(&hdev->tx_comm.hdmimode_mutex); tx_comm->hpd_state = !!(hdmitx_hw_cntl_misc(&hdev->tx_hw.base, MISC_HPD_GPI_ST, 0)); #ifdef CONFIG_AMLOGIC_VOUT_SERVE @@ -4712,8 +4655,8 @@ static int amhdmitx_probe(struct platform_device *pdev) INIT_WORK(&hdev->work_hdr, hdr_work_func); /* When init hdmi, clear the hdmitx module edid ram and edid buffer. */ - hdmitx_edid_buffer_clear(&hdev->tx_comm); - hdmitx_edid_rxcap_clear(&hdev->tx_comm); + hdmitx_edid_buffer_clear(hdev->tx_comm.EDID_buf, sizeof(hdev->tx_comm.EDID_buf)); + hdmitx_edid_rxcap_clear(&hdev->tx_comm.rxcap); hdev->hdmi_wq = alloc_workqueue(DEVICE_NAME, WQ_HIGHPRI | WQ_CPU_INTENSIVE, 0); INIT_DELAYED_WORK(&hdev->work_hpd_plugin, hdmitx_hpd_plugin_handler); @@ -4738,7 +4681,7 @@ static int amhdmitx_probe(struct platform_device *pdev) if (tx_comm->hpd_state) { /* need to get edid before vout probe */ hdev->tx_comm.already_used = 1; - hdmitx_get_edid(hdev); + hdmitx_get_edid(&hdev->tx_comm, &hdev->tx_hw.base); /* When bootup mbox and TV simultaneously, * TV may not handle SCDC/DIV40 diff --git a/drivers/media/vout/hdmitx_common/hdmitx_common.c b/drivers/media/vout/hdmitx_common/hdmitx_common.c index ccf6779e5..ba55332c9 100644 --- a/drivers/media/vout/hdmitx_common/hdmitx_common.c +++ b/drivers/media/vout/hdmitx_common/hdmitx_common.c @@ -6,6 +6,10 @@ #include #include #include +#include +#include +#include +#include #include #include #include @@ -42,14 +46,14 @@ int hdmitx_common_init(struct hdmitx_common *tx_comm, struct hdmitx_hw_common *h /*load tx boot params*/ tx_comm->hdr_priority = boot_param->hdr_mask; - memcpy(tx_comm->hdmichecksum, boot_param->edid_chksum, sizeof(tx_comm->hdmichecksum)); + memcpy(tx_comm->rxcap.hdmichecksum, boot_param->edid_chksum, + sizeof(tx_comm->rxcap.hdmichecksum)); memcpy(tx_comm->fmt_attr, boot_param->color_attr, sizeof(tx_comm->fmt_attr)); tx_comm->frac_rate_policy = boot_param->fraction_refreshrate; tx_comm->config_csc_en = boot_param->config_csc; tx_comm->res_1080p = 0; tx_comm->max_refreshrate = 60; - tx_comm->edid_ptr = tx_comm->EDID_buf; tx_comm->tx_hw = hw_comm; tx_comm->repeater_mode = 0; @@ -62,6 +66,7 @@ int hdmitx_common_init(struct hdmitx_common *tx_comm, struct hdmitx_hw_common *h /*mutex init*/ mutex_init(&tx_comm->setclk_mutex); mutex_init(&tx_comm->hdmimode_mutex); + mutex_init(&tx_comm->getedid_mutex); return 0; } @@ -102,21 +107,6 @@ int hdmitx_common_destroy(struct hdmitx_common *tx_comm) return 0; } -bool hdmitx_validate_y420_vic(enum hdmi_vic vic) -{ - const struct hdmi_timing *timing; - - /* In Spec2.1 Table 7-34, greater than 2160p30hz will support y420 */ - timing = hdmitx_mode_vic_to_hdmi_timing(vic); - if (!timing) - return 0; - if (timing->v_active >= 2160 && timing->v_freq > 30000) - return 1; - if (timing->v_active >= 4320) - return 1; - return 0; -} - int hdmitx_common_validate_vic(struct hdmitx_common *tx_comm, u32 vic) { const struct hdmi_timing *timing = hdmitx_mode_vic_to_hdmi_timing(vic); @@ -246,10 +236,7 @@ int hdmitx_register_hpd_cb(struct hdmitx_common *tx_comm, struct connector_hpd_c unsigned char *hdmitx_get_raw_edid(struct hdmitx_common *tx_comm) { - if (tx_comm->edid_ptr) - return tx_comm->edid_ptr; - else - return tx_comm->EDID_buf; + return tx_comm->EDID_buf; } int hdmitx_setup_attr(struct hdmitx_common *tx_comm, const char *buf) @@ -280,47 +267,6 @@ int hdmitx_get_hdrinfo(struct hdmitx_common *tx_comm, struct hdr_info *hdrinfo) return 0; } -static unsigned char __nosavedata edid_checkvalue[4] = {0}; - -static int xtochar(u8 value, u8 *checksum) -{ - if (((value >> 4) & 0xf) <= 9) - checksum[0] = ((value >> 4) & 0xf) + '0'; - else - checksum[0] = ((value >> 4) & 0xf) - 10 + 'a'; - - if ((value & 0xf) <= 9) - checksum[1] = (value & 0xf) + '0'; - else - checksum[1] = (value & 0xf) - 10 + 'a'; - - return 0; -} - -int hdmitx_update_edid_chksum(u8 *buf, u32 block_cnt, struct rx_cap *rxcap) -{ - u32 i, length, max; - - if (!buf) - return -EINVAL; - - length = sizeof(edid_checkvalue); - memset(edid_checkvalue, 0x00, length); - - max = (block_cnt > length) ? length : block_cnt; - - for (i = 0; i < max; i++) - edid_checkvalue[i] = *(buf + (i + 1) * 128 - 1); - - rxcap->chksum[0] = '0'; - rxcap->chksum[1] = 'x'; - - for (i = 0; i < 4; i++) - xtochar(edid_checkvalue[i], &rxcap->chksum[2 * i + 2]); - - return 0; -} - static enum hdmi_vic get_alternate_ar_vic(enum hdmi_vic vic) { int i = 0; @@ -464,10 +410,10 @@ int hdmitx_common_notify_hpd_status(struct hdmitx_common *tx_comm) HDMITX_AUDIO_EVENT, tx_comm->hpd_state); } - /*notify to other driver module:cec/rx TODO: need lock for edid_ptr */ + /*notify to other driver module:cec/rx TODO: need lock for EDID_buf */ /*if (tx_comm->hpd_state) * hdmitx_event_mgr_notify(tx_comm->event_mgr, HDMITX_PLUG, - * tx_comm->edid_parsing ? tx_comm->edid_ptr : NULL); + * tx_comm->edid_parsing ? tx_comm->EDID_buf : NULL); *else * hdmitx_event_mgr_notify(tx_comm->event_mgr, HDMITX_UNPLUG, NULL); */ @@ -765,12 +711,70 @@ int hdmitx_print_sink_cap(struct hdmitx_common *tx_comm, * whether edid is changed */ pos += snprintf(buffer + pos, buffer_len - pos, - "checkvalue: 0x%02x%02x%02x%02x\n", - edid_checkvalue[0], - edid_checkvalue[1], - edid_checkvalue[2], - edid_checkvalue[3]); + "checkvalue: %s\n", prxcap->hdmichecksum); return pos; } +void hdmitx_get_edid(struct hdmitx_common *tx_comm, struct hdmitx_hw_common *tx_hw_base) +{ + unsigned long flags = 0; + + mutex_lock(&tx_comm->getedid_mutex); + hdmitx_edid_buffer_clear(tx_comm->EDID_buf, sizeof(tx_comm->EDID_buf)); + hdmitx_hw_cntl_ddc(tx_hw_base, DDC_RESET_EDID, 0); + hdmitx_hw_cntl_ddc(tx_hw_base, DDC_PIN_MUX_OP, PIN_MUX); + /* start reading edid first time */ + hdmitx_hw_cntl_ddc(tx_hw_base, DDC_EDID_READ_DATA, 0); + if (hdmitx_edid_is_all_zeros(tx_comm->EDID_buf)) { + hdmitx_hw_cntl_ddc(tx_hw_base, DDC_GLITCH_FILTER_RESET, 0); + hdmitx_hw_cntl_ddc(tx_hw_base, DDC_EDID_READ_DATA, 0); + } + /* If EDID is not correct at first time, then retry */ + if (!check_dvi_hdmi_edid_valid(tx_comm->EDID_buf)) { + struct timespec64 kts; + struct rtc_time tm; + + msleep(20); + ktime_get_real_ts64(&kts); + rtc_time64_to_tm(kts.tv_sec, &tm); + if (tx_comm->hdmitx_gpios_scl != -EPROBE_DEFER) + pr_info("UTC+0 %ptRd %ptRt DDC SCL %s\n", &tm, &tm, + gpio_get_value(tx_comm->hdmitx_gpios_scl) ? "HIGH" : "LOW"); + if (tx_comm->hdmitx_gpios_sda != -EPROBE_DEFER) + pr_info("UTC+0 %ptRd %ptRt DDC SDA %s\n", &tm, &tm, + gpio_get_value(tx_comm->hdmitx_gpios_sda) ? "HIGH" : "LOW"); + msleep(80); + + /* start reading edid second time */ + hdmitx_hw_cntl_ddc(tx_hw_base, DDC_EDID_READ_DATA, 0); + if (hdmitx_edid_is_all_zeros(tx_comm->EDID_buf)) { + hdmitx_hw_cntl_ddc(tx_hw_base, DDC_GLITCH_FILTER_RESET, 0); + hdmitx_hw_cntl_ddc(tx_hw_base, DDC_EDID_READ_DATA, 0); + } + } + spin_lock_irqsave(&tx_comm->edid_spinlock, flags); + hdmitx_edid_rxcap_clear(&tx_comm->rxcap); + hdmitx_edid_parse(&tx_comm->rxcap, tx_comm->EDID_buf); + + if (tx_comm->hdr_priority == 1) { /* clear dv_info */ + struct dv_info *dv = &tx_comm->rxcap.dv_info; + + memset(dv, 0, sizeof(struct dv_info)); + pr_info("clear dv_info\n"); + } + if (tx_comm->hdr_priority == 2) { /* clear dv_info/hdr_info */ + struct dv_info *dv = &tx_comm->rxcap.dv_info; + struct hdr_info *hdr = &tx_comm->rxcap.hdr_info; + + memset(dv, 0, sizeof(struct dv_info)); + memset(hdr, 0, sizeof(struct hdr_info)); + pr_info("clear dv_info/hdr_info\n"); + } + spin_unlock_irqrestore(&tx_comm->edid_spinlock, flags); + hdmitx_event_mgr_notify(tx_comm->event_mgr, + HDMITX_PHY_ADDR_VALID, &tx_comm->rxcap.physical_addr); + hdmitx_edid_print(tx_comm->EDID_buf); + + mutex_unlock(&tx_comm->getedid_mutex); +} diff --git a/drivers/media/vout/hdmitx_common/hdmitx_edid.c b/drivers/media/vout/hdmitx_common/hdmitx_edid.c index 68a47cc95..a115f6159 100644 --- a/drivers/media/vout/hdmitx_common/hdmitx_edid.c +++ b/drivers/media/vout/hdmitx_common/hdmitx_edid.c @@ -20,14 +20,12 @@ #include #include #include -#include #include #include #include #include #include -#include #include #define CEA_DATA_BLOCK_COLLECTION_ADDR_1STP 0x04 @@ -84,7 +82,6 @@ (((val) >> (start)) & ((1 << (len)) - 1)) const struct hdmi_timing *hdmitx_mode_match_timing_name(const char *name); -static unsigned int hdmitx_edid_check_valid_blocks(unsigned char *buf); static void edid_dtd_parsing(struct rx_cap *prxcap, unsigned char *data); static void hdmitx_edid_set_default_aud(struct rx_cap *prxcap); /* Base Block, Vendor/Product Information, byte[8]~[18] */ @@ -2136,14 +2133,6 @@ static void hdmitx_edid_set_default_vic(struct rx_cap *prxcap) pr_info(EDID "set default vic\n"); } -#define PRINT_HASH(hash) - -static int edid_hash_calc(u8 *hash, const char *data, - u32 len) -{ - return 1; -} - static int hdmitx_edid_search_IEEEOUI(char *buf) { int i; @@ -2556,17 +2545,16 @@ static void check_dv_truly_support(struct rx_cap *prxcap, struct dv_info *dv) } } -int hdmitx_find_philips(struct hdmitx_common *tx_comm) +int hdmitx_find_philips(u8 *edid_buf) { int j; int length = sizeof(vendor_id) / sizeof(struct edid_venddat_t); - if (!tx_comm) + if (!edid_buf) return 0; for (j = 0; j < length; j++) { - if (memcmp(&tx_comm->EDID_buf[8], &vendor_id[j], - sizeof(struct edid_venddat_t)) == 0) + if (memcmp(edid_buf, &vendor_id[j], sizeof(struct edid_venddat_t)) == 0) return 1; } return 0; @@ -2662,27 +2650,63 @@ static void _edid_parse_base_structure(struct rx_cap *prxcap, unsigned char *EDI } } -int hdmitx_edid_parse(struct hdmitx_common *tx_comm) +static int xtochar(u8 value, u8 *checksum) +{ + if (!checksum) + return 0; + if (((value >> 4) & 0xf) <= 9) + checksum[0] = ((value >> 4) & 0xf) + '0'; + else + checksum[0] = ((value >> 4) & 0xf) - 10 + 'a'; + + if ((value & 0xf) <= 9) + checksum[1] = (value & 0xf) + '0'; + else + checksum[1] = (value & 0xf) - 10 + 'a'; + + return 0; +} + +static int update_edid_chksum(struct rx_cap *prxcap, u8 *edid_buf) +{ + u32 i; + unsigned char tmp_chksum[4] = {0}; + + if (!prxcap || !edid_buf) + return -EINVAL; + + memset(prxcap->hdmichecksum, 0, sizeof(prxcap->hdmichecksum)); + + /* get the first 4 sub-blocks chksum */ + for (i = 0; i < 4; i++) + tmp_chksum[i] = edid_buf[i * 128 + 127]; + + prxcap->hdmichecksum[0] = '0'; + prxcap->hdmichecksum[1] = 'x'; + + for (i = 0; i < 4; i++) + xtochar(tmp_chksum[i], &prxcap->hdmichecksum[2 * i + 2]); + + return 0; +} + +int hdmitx_edid_parse(struct rx_cap *prxcap, u8 *edid_buf) { unsigned char cta_block_count; - unsigned char *EDID_buf; int i; int idx[4]; - struct rx_cap *prxcap; struct dv_info *dv; - if (!tx_comm) - return 0; + if (!edid_buf || !prxcap) + return -1; - EDID_buf = tx_comm->EDID_buf; - prxcap = &tx_comm->rxcap; - dv = &tx_comm->rxcap.dv_info; - if (check_dvi_hdmi_edid_valid(tx_comm->EDID_buf)) - tx_comm->edid_parsing = 1; + dv = &prxcap->dv_info; + if (check_dvi_hdmi_edid_valid(edid_buf)) + prxcap->edid_parsing = 1; else - tx_comm->edid_parsing = 0; + prxcap->edid_parsing = 0; - prxcap->head_err = hdmitx_edid_header_invalid(&EDID_buf[0]); + prxcap->head_err = hdmitx_edid_header_invalid(&edid_buf[0]); // TODO /*if (prxcap->head_err) * hdmitx_current_status(HDMITX_EDID_HEAD_ERROR); @@ -2691,31 +2715,27 @@ int hdmitx_edid_parse(struct hdmitx_common *tx_comm) * hdmitx_current_status(HDMITX_EDID_CHECKSUM_ERROR); */ - tx_comm->edid_ptr = EDID_buf; pr_debug(EDID "EDID Parser:\n"); - /* Calculate the EDID hash for special use */ - memset(tx_comm->EDID_hash, 0, ARRAY_SIZE(tx_comm->EDID_hash)); - edid_hash_calc(tx_comm->EDID_hash, tx_comm->EDID_buf, 256); - if (!check_dvi_hdmi_edid_valid(EDID_buf)) { + if (!check_dvi_hdmi_edid_valid(edid_buf)) { edid_set_fallback_mode(prxcap); pr_info("set fallback mode\n"); return 0; } - if (_check_base_structure(EDID_buf)) - _edid_parse_base_structure(prxcap, EDID_buf); + if (_check_base_structure(edid_buf)) + _edid_parse_base_structure(prxcap, edid_buf); - cta_block_count = EDID_buf[0x7E]; + cta_block_count = edid_buf[0x7E]; /* HFR-EEODB */ - if (cta_block_count && EDID_buf[128 + 4] == EXTENSION_EEODB_EXT_TAG && - EDID_buf[128 + 5] == EXTENSION_EEODB_EXT_CODE) - cta_block_count = EDID_buf[128 + 6]; + if (cta_block_count && edid_buf[128 + 4] == EXTENSION_EEODB_EXT_TAG && + edid_buf[128 + 5] == EXTENSION_EEODB_EXT_CODE) + cta_block_count = edid_buf[128 + 6]; /* limit cta_block_count to EDID_MAX_BLOCK - 1 */ if (cta_block_count > EDID_MAX_BLOCK - 1) cta_block_count = EDID_MAX_BLOCK - 1; for (i = 1; i <= cta_block_count; i++) { - if (EDID_buf[i * 0x80] == 0x02) - hdmitx_edid_cta_block_parse(prxcap, &EDID_buf[i * 0x80]); + if (edid_buf[i * 0x80] == 0x02) + hdmitx_edid_cta_block_parse(prxcap, &edid_buf[i * 0x80]); } /* EDID parsing complete - check if 4k60/50 DV can be truly supported */ @@ -2723,13 +2743,13 @@ int hdmitx_edid_parse(struct hdmitx_common *tx_comm) check_dv_truly_support(prxcap, dv); dv = &prxcap->dv_info2; check_dv_truly_support(prxcap, dv); - edid_check_pcm_declare(&tx_comm->rxcap); + edid_check_pcm_declare(prxcap); /* move parts that may contain cea timing parse behind * VDB parse, so that to not affect VDB index which * will be used in Y420CMDB map */ - edid_standardtiming(&tx_comm->rxcap, &EDID_buf[0x26], 8); - edid_parseceatiming(&tx_comm->rxcap, &EDID_buf[0x36]); + edid_standardtiming(prxcap, &edid_buf[0x26], 8); + edid_parseceatiming(prxcap, &edid_buf[0x36]); /* * Because DTDs are not able to represent some Video Formats, which can be * represented as SVDs and might be preferred by Sinks, the first DTD in the @@ -2751,40 +2771,37 @@ int hdmitx_edid_parse(struct hdmitx_common *tx_comm) idx[2] = EDID_DETAILED_TIMING_DES_BLOCK2_POS; idx[3] = EDID_DETAILED_TIMING_DES_BLOCK3_POS; for (i = 0; i < 4; i++) { - if ((EDID_buf[idx[i]]) && (EDID_buf[idx[i] + 1])) { + if ((edid_buf[idx[i]]) && (edid_buf[idx[i] + 1])) { struct vesa_standard_timing t; memset(&t, 0, sizeof(struct vesa_standard_timing)); if (i == 0) - edid_descriptor_pmt(prxcap, &t, - &EDID_buf[idx[i]]); + edid_descriptor_pmt(prxcap, &t, &edid_buf[idx[i]]); if (i == 1) - edid_descriptor_pmt2(prxcap, &t, - &EDID_buf[idx[i]]); + edid_descriptor_pmt2(prxcap, &t, &edid_buf[idx[i]]); continue; } - switch (EDID_buf[idx[i] + 3]) { + switch (edid_buf[idx[i] + 3]) { case TAG_STANDARD_TIMINGS: - edid_standardtiming(prxcap, &EDID_buf[idx[i] + 5], 6); + edid_standardtiming(prxcap, &edid_buf[idx[i] + 5], 6); break; case TAG_CVT_TIMING_CODES: - edid_cvt_timing(prxcap, &EDID_buf[idx[i] + 6]); + edid_cvt_timing(prxcap, &edid_buf[idx[i] + 6]); break; case TAG_ESTABLISHED_TIMING_III: - edid_standard_timing_iii(prxcap, &EDID_buf[idx[i] + 6]); + edid_standard_timing_iii(prxcap, &edid_buf[idx[i] + 6]); break; case TAG_RANGE_LIMITS: break; case TAG_DISPLAY_PRODUCT_NAME_STRING: - edid_receiverproductnameparse(prxcap, - &EDID_buf[idx[i] + 5]); + edid_receiverproductnameparse(prxcap, &edid_buf[idx[i] + 5]); break; default: break; } } - if (hdmitx_edid_search_IEEEOUI(&EDID_buf[128])) { + if (hdmitx_edid_search_IEEEOUI(&edid_buf[128])) { prxcap->ieeeoui = HDMI_IEEE_OUI; pr_debug(EDID "find IEEEOUT\n"); } else { @@ -2794,14 +2811,14 @@ int hdmitx_edid_parse(struct hdmitx_common *tx_comm) /* strictly DVI device judgement */ /* valid EDID & no audio tag & no IEEEOUI */ - if (check_dvi_hdmi_edid_valid(&EDID_buf[0]) && - !hdmitx_edid_search_IEEEOUI(&EDID_buf[128])) { + if (check_dvi_hdmi_edid_valid(&edid_buf[0]) && + !hdmitx_edid_search_IEEEOUI(&edid_buf[128])) { prxcap->ieeeoui = 0x0; pr_debug(EDID "sink is DVI device\n"); } else { prxcap->ieeeoui = HDMI_IEEE_OUI; } - if (edid_zero_data(EDID_buf)) + if (edid_zero_data(edid_buf)) prxcap->ieeeoui = HDMI_IEEE_OUI; if (!prxcap->AUD_count && !prxcap->ieeeoui) @@ -2812,9 +2829,9 @@ int hdmitx_edid_parse(struct hdmitx_common *tx_comm) if (!prxcap->AUD_count) hdmitx_edid_set_default_aud(prxcap); - hdmitx_update_edid_chksum(EDID_buf, cta_block_count + 1, prxcap); + update_edid_chksum(prxcap, edid_buf); - if (!hdmitx_edid_check_valid_blocks(&EDID_buf[0])) { + if (!hdmitx_edid_valid_block_num(&edid_buf[0])) { prxcap->ieeeoui = HDMI_IEEE_OUI; pr_info(EDID "Invalid edid, consider RX as HDMI device\n"); } @@ -2846,7 +2863,7 @@ int hdmitx_edid_parse(struct hdmitx_common *tx_comm) } /* if edid are all zeroes, or no VIC, set default vic */ - if (edid_zero_data(EDID_buf) || prxcap->VIC_count == 0) + if (edid_zero_data(edid_buf) || prxcap->VIC_count == 0) hdmitx_edid_set_default_vic(prxcap); if (prxcap->ieeeoui == HDMI_IEEE_OUI) { // hdmitx_current_status(HDMITX_EDID_HDMI_DEVICE); @@ -2857,24 +2874,22 @@ int hdmitx_edid_parse(struct hdmitx_common *tx_comm) return 0; } -void hdmitx_edid_buffer_clear(struct hdmitx_common *tx_comm) +void hdmitx_edid_buffer_clear(u8 *edid_buf, int size) { - if (!tx_comm) + if (!edid_buf) return; - memset(tx_comm->EDID_buf, 0, sizeof(tx_comm->EDID_buf)); + memset(edid_buf, 0, size); } /* Clear the Parse result of HDMI Sink's EDID. */ -void hdmitx_edid_rxcap_clear(struct hdmitx_common *tx_comm) +void hdmitx_edid_rxcap_clear(struct rx_cap *prxcap) { char tmp[2] = {0}; - struct rx_cap *prxcap; - if (!tx_comm) + if (!prxcap) return; - prxcap = &tx_comm->rxcap; memset(prxcap, 0, sizeof(struct rx_cap)); /* Note: in most cases, we think that rx is tv and the default @@ -2882,8 +2897,7 @@ void hdmitx_edid_rxcap_clear(struct hdmitx_common *tx_comm) */ prxcap->ieeeoui = HDMI_IEEE_OUI; - memset(&tx_comm->EDID_hash[0], 0, sizeof(tx_comm->EDID_hash)); - tx_comm->edid_parsing = 0; + prxcap->edid_parsing = 0; hdmitx_edid_set_default_aud(prxcap); rx_set_hdr_lumi(&tmp[0], 2); rx_set_receiver_edid(&tmp[0], 2); @@ -2925,18 +2939,18 @@ static void hdmitx_edid_blk_print(unsigned char *blk, unsigned int blk_idx) /* * check EDID buf contains valid block numbers */ -static unsigned int hdmitx_edid_check_valid_blocks(unsigned char *buf) +unsigned int hdmitx_edid_valid_block_num(unsigned char *edid_buf) { unsigned int valid_blk_no = 0; unsigned int i = 0, j = 0; unsigned int tmp_chksum = 0; - if (!buf) + if (!edid_buf) return 0; for (j = 0; j < EDID_MAX_BLOCK; j++) { for (i = 0; i < 128; i++) - tmp_chksum += buf[i + j * 128]; + tmp_chksum += edid_buf[i + j * 128]; if (tmp_chksum != 0) { valid_blk_no++; if ((tmp_chksum & 0xff) == 0) @@ -2946,30 +2960,32 @@ static unsigned int hdmitx_edid_check_valid_blocks(unsigned char *buf) } tmp_chksum = 0; } + /* EEODB case */ + if (edid_buf[128 + 4] == EXTENSION_EEODB_EXT_TAG && + edid_buf[128 + 5] == EXTENSION_EEODB_EXT_CODE) + valid_blk_no = edid_buf[128 + 6] + 1; return valid_blk_no; } /* * print out EDID_buf */ -void hdmitx_edid_print(struct hdmitx_common *tx_comm) +void hdmitx_edid_print(u8 *edid_buf) { - u8 *buf0 = tx_comm->EDID_buf; u32 valid_blk_no = 0; u32 blk_idx = 0; - if (!tx_comm) + if (!edid_buf) return; /* calculate valid edid block numbers */ - valid_blk_no = hdmitx_edid_check_valid_blocks(buf0); + valid_blk_no = hdmitx_edid_valid_block_num(edid_buf); if (valid_blk_no == 0) { pr_debug(EDID "raw data are all zeroes\n"); } else { for (blk_idx = 0; blk_idx < valid_blk_no; blk_idx++) - hdmitx_edid_blk_print(&buf0[blk_idx * 128], - blk_idx); + hdmitx_edid_blk_print(&edid_buf[blk_idx * 128], blk_idx); } } diff --git a/drivers/media/vout/hdmitx_common/hdmitx_mode.c b/drivers/media/vout/hdmitx_common/hdmitx_mode.c index 7c3bdcc35..fc38088d8 100644 --- a/drivers/media/vout/hdmitx_common/hdmitx_mode.c +++ b/drivers/media/vout/hdmitx_common/hdmitx_mode.c @@ -560,6 +560,22 @@ const struct hdmi_timing *hdmitx_mode_match_timing_name(const char *name) } EXPORT_SYMBOL(hdmitx_mode_match_timing_name); +bool hdmitx_validate_y420_vic(enum hdmi_vic vic) +{ + const struct hdmi_timing *timing; + + /* In Spec2.1 Table 7-34, greater than 2160p30hz will support y420 */ + timing = hdmitx_mode_vic_to_hdmi_timing(vic); + if (!timing) + return 0; + if (timing->v_active >= 2160 && timing->v_freq > 30000) + return 1; + if (timing->v_active >= 4320) + return 1; + return 0; +} +EXPORT_SYMBOL(hdmitx_validate_y420_vic); + const char *hdmitx_mode_get_timing_name(enum hdmi_vic vic) { const struct hdmi_timing *timing = diff --git a/drivers/media/vout/hdmitx_common/hdmitx_mode_set.c b/drivers/media/vout/hdmitx_common/hdmitx_mode_set.c index b2a6f4169..2cd37787e 100644 --- a/drivers/media/vout/hdmitx_common/hdmitx_mode_set.c +++ b/drivers/media/vout/hdmitx_common/hdmitx_mode_set.c @@ -23,7 +23,7 @@ static int hdmitx_common_pre_enable_mode(struct hdmitx_common *tx_comm, return -1; } - memcpy(vinfo->hdmichecksum, tx_comm->rxcap.chksum, 10); + memcpy(vinfo->hdmichecksum, tx_comm->rxcap.hdmichecksum, 10); if (vinfo->mode == VMODE_HDMI) { width = tx_comm->rxcap.physical_width; height = tx_comm->rxcap.physical_height; diff --git a/drivers/media/vout/hdmitx_common/hdmitx_sysfs_common.c b/drivers/media/vout/hdmitx_common/hdmitx_sysfs_common.c index f0c7cff1b..d80da5f84 100644 --- a/drivers/media/vout/hdmitx_common/hdmitx_sysfs_common.c +++ b/drivers/media/vout/hdmitx_common/hdmitx_sysfs_common.c @@ -58,24 +58,17 @@ static ssize_t rawedid_show(struct device *dev, int pos = 0; int i; int num; - int ext_block_num = 0; + int block_num = 0; - /* prevent null prt */ - if (!global_tx_common->edid_ptr) - global_tx_common->edid_ptr = global_tx_common->EDID_buf; - - ext_block_num = global_tx_common->edid_ptr[126]; - if (ext_block_num && global_tx_common->edid_ptr[128 + 4] == EXTENSION_EEODB_EXT_TAG && - global_tx_common->edid_ptr[128 + 5] == EXTENSION_EEODB_EXT_CODE) - ext_block_num = global_tx_common->edid_ptr[128 + 6]; //EEODB - if (ext_block_num < 8) - num = (ext_block_num + 1) * 128; + block_num = hdmitx_edid_valid_block_num(global_tx_common->EDID_buf); + if (block_num <= 8) + num = block_num * 128; else num = 8 * 128; for (i = 0; i < num; i++) pos += snprintf(buf + pos, PAGE_SIZE, "%02x", - global_tx_common->edid_ptr[i]); + global_tx_common->EDID_buf[i]); pos += snprintf(buf + pos, PAGE_SIZE, "\n"); @@ -98,7 +91,7 @@ static ssize_t edid_parsing_show(struct device *dev, { int pos = 0; - if (check_dvi_hdmi_edid_valid(global_tx_common->edid_ptr)) + if (check_dvi_hdmi_edid_valid(global_tx_common->EDID_buf)) pos += snprintf(buf + pos, PAGE_SIZE, "ok\n"); else pos += snprintf(buf + pos, PAGE_SIZE, "ng\n"); diff --git a/include/linux/amlogic/media/vout/hdmi_tx/hdmi_tx_module.h b/include/linux/amlogic/media/vout/hdmi_tx/hdmi_tx_module.h index da4fa0c51..c68298c9f 100644 --- a/include/linux/amlogic/media/vout/hdmi_tx/hdmi_tx_module.h +++ b/include/linux/amlogic/media/vout/hdmi_tx/hdmi_tx_module.h @@ -207,12 +207,7 @@ struct hdmitx_dev { bool systemcontrol_on; unsigned char vid_mute_op; atomic_t kref_video_mute; - spinlock_t edid_spinlock; /* edid hdr/dv cap lock */ - /*hw members*/ - int hdmitx_gpios_hpd; - int hdmitx_gpios_scl; - int hdmitx_gpios_sda; unsigned int hdmi_rext; /* Rext resistor */ struct hdmitx_clk_tree_s hdmitx_clk_tree; bool pre_tmds_clk_div40; @@ -243,7 +238,6 @@ void hdmitx_current_status(enum hdmitx_event_log_bits event); extern struct aud_para hdmiaud_config_data; extern struct aud_para hsty_hdmiaud_config_data[8]; extern unsigned int hsty_hdmiaud_config_loc, hsty_hdmiaud_config_num; -extern struct mutex getedid_mutex; int hdmitx_set_display(struct hdmitx_dev *hdmitx_device, enum hdmi_vic videocode); diff --git a/include/linux/amlogic/media/vout/hdmi_tx21/hdmi_tx_module.h b/include/linux/amlogic/media/vout/hdmi_tx21/hdmi_tx_module.h index c59e8a14c..adc100ae1 100644 --- a/include/linux/amlogic/media/vout/hdmi_tx21/hdmi_tx_module.h +++ b/include/linux/amlogic/media/vout/hdmi_tx21/hdmi_tx_module.h @@ -192,7 +192,6 @@ struct hdmitx_dev { u32 aon_output:1; /* always output in bl30 */ u32 bist_lock:1; u32 fr_duration; - spinlock_t edid_spinlock; /* edid hdr/dv cap lock */ struct vpu_dev_s *hdmitx_vpu_clk_gate_dev; /*DRM related*/ diff --git a/include/linux/amlogic/media/vout/hdmitx_common/hdmitx_common.h b/include/linux/amlogic/media/vout/hdmitx_common/hdmitx_common.h index 664e2a01c..43f584af9 100644 --- a/include/linux/amlogic/media/vout/hdmitx_common/hdmitx_common.h +++ b/include/linux/amlogic/media/vout/hdmitx_common/hdmitx_common.h @@ -36,8 +36,6 @@ struct hdmitx_common { */ u32 hdr_priority; - char hdmichecksum[11]; - char fmt_attr[16]; /* 0.1% clock shift, 1080p60hz->59.94hz */ @@ -63,13 +61,18 @@ struct hdmitx_common { u32 already_used; /*edid related*/ - unsigned char *edid_ptr; unsigned char EDID_buf[EDID_MAX_BLOCK * 128]; // TODO - unsigned char EDID_hash[20]; + /* the checksum of current edid */ /* indicate RX edid data integrated, HEAD valid and checksum pass */ - unsigned int edid_parsing; struct rx_cap rxcap; - /*edid related end*/ + bool hdmitx_edid_done; + /* edid related end */ + struct mutex getedid_mutex; + spinlock_t edid_spinlock; /* edid hdr/dv cap lock */ + /* GPIO hpd/scl/sda members*/ + int hdmitx_gpios_hpd; + int hdmitx_gpios_scl; + int hdmitx_gpios_sda; /*DRM related*/ struct connector_hpd_cb drm_hpd_cb; @@ -197,13 +200,7 @@ int hdmitx_get_attr(struct hdmitx_common *tx_comm, char attr[16]); int hdmitx_get_hdrinfo(struct hdmitx_common *tx_comm, struct hdr_info *hdrinfo); /*edid related function.*/ -int hdmitx_update_edid_chksum(u8 *buf, u32 block_cnt, struct rx_cap *rxcap); -int hdmitx_edid_parse(struct hdmitx_common *tx_comm); // TODO -void hdmitx_edid_print(struct hdmitx_common *tx_comm); // TODO, remove compare -void hdmitx_edid_buffer_clear(struct hdmitx_common *tx_comm); -void hdmitx_edid_rxcap_clear(struct hdmitx_common *tx_comm); -bool hdmitx_edid_only_support_sd(struct rx_cap *prxcap); -bool hdmitx_validate_y420_vic(enum hdmi_vic vic); +void hdmitx_get_edid(struct hdmitx_common *tx_comm, struct hdmitx_hw_common *tx_hw_base); /*debug functions*/ int hdmitx_load_edid_file(char *path); diff --git a/include/linux/amlogic/media/vout/hdmitx_common/hdmitx_edid.h b/include/linux/amlogic/media/vout/hdmitx_common/hdmitx_edid.h index 95fbd992a..65ffabfee 100644 --- a/include/linux/amlogic/media/vout/hdmitx_common/hdmitx_edid.h +++ b/include/linux/amlogic/media/vout/hdmitx_common/hdmitx_edid.h @@ -199,9 +199,10 @@ struct rx_cap { bool ifdb_present; /* IFDB, currently only use below node */ u8 additional_vsif_num; + u8 edid_parsing; /*blk0 check sum*/ u8 blk0_chksum; - u8 chksum[10]; + u8 hdmichecksum[11]; /* string with 0xAABBCCDD */ u8 head_err; u8 chksum_err; }; @@ -261,5 +262,12 @@ bool hdmitx_edid_is_all_zeros(unsigned char *rawedid); int _check_base_structure(unsigned char *buf); int _check_edid_blk_chksum(unsigned char *block); int check_dvi_hdmi_edid_valid(unsigned char *buf); +int hdmitx_edid_parse(struct rx_cap *prxcap, u8 *edid_buf); +unsigned int hdmitx_edid_valid_block_num(unsigned char *edid_buf); +bool hdmitx_validate_y420_vic(enum hdmi_vic vic); +void hdmitx_edid_print(u8 *edid_buf); +void hdmitx_edid_buffer_clear(u8 *edid_buf, int size); +void hdmitx_edid_rxcap_clear(struct rx_cap *prxcap); +bool hdmitx_edid_only_support_sd(struct rx_cap *prxcap); #endif