From patchwork Tue Jul 14 11:51:22 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: sonika.jindal@intel.com X-Patchwork-Id: 6786741 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id C162D9F2F0 for ; Tue, 14 Jul 2015 12:01:58 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id C27E3206D4 for ; Tue, 14 Jul 2015 12:01:57 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id B7E6E206BA for ; Tue, 14 Jul 2015 12:01:56 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 2D68A6E99C; Tue, 14 Jul 2015 05:01:56 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by gabe.freedesktop.org (Postfix) with ESMTP id B06F26E99C for ; Tue, 14 Jul 2015 05:01:54 -0700 (PDT) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga102.fm.intel.com with ESMTP; 14 Jul 2015 05:01:54 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.15,471,1432623600"; d="scan'208";a="728572503" Received: from sonikaji-desktop.iind.intel.com ([10.223.25.81]) by orsmga001.jf.intel.com with ESMTP; 14 Jul 2015 05:01:52 -0700 From: Sonika Jindal To: intel-gfx@lists.freedesktop.org Date: Tue, 14 Jul 2015 17:21:22 +0530 Message-Id: <1436874683-24090-3-git-send-email-sonika.jindal@intel.com> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1436874683-24090-1-git-send-email-sonika.jindal@intel.com> References: <1436874683-24090-1-git-send-email-sonika.jindal@intel.com> Subject: [Intel-gfx] [PATCH 2/3] drm/i915: Add HDMI probe function X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Spam-Status: No, score=-5.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Shashank Sharma This patch adds a separate probe function for HDMI EDID read over DDC channel. This function has been registered as a .hot_plug handler for HDMI encoder. The current implementation of hdmi_detect() function re-sets the cached HDMI edid (in connector->detect_edid) in every detect call.This function gets called many times, sometimes directly from userspace probes, forcing drivers to read EDID every detect function call.This causes several problems like: 1. Race conditions in multiple hot_plug / unplug cases, between interrupts bottom halves and userspace detections. 2. Many Un-necessary EDID reads for single hotplug/unplug 3. HDMI complaince failures which expects only one EDID read per hotplug This function will be serving the purpose of really reading the EDID by really probing the DDC channel, and updating the cached EDID. The plan is to: 1. i915 IRQ handler bottom half function already calls intel_encoder->hotplug() function. Adding This probe function which will read the EDID only in case of a hotplug / unplug. 2. During init_connector this probe will be called to read the edid 3. Reuse the cached EDID in hdmi_detect() function. The "< gen7" check is there because this was tested only for >=gen7 platforms. For older platforms the hotplug/reading edid path remains same. Signed-off-by: Shashank Sharma Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/intel_hdmi.c | 49 ++++++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index af4d1e6..c4b82ce 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -1340,23 +1340,56 @@ intel_hdmi_set_edid(struct drm_connector *connector) return connected; } +void intel_hdmi_probe(struct intel_encoder *intel_encoder) +{ + struct intel_hdmi *intel_hdmi = + enc_to_intel_hdmi(&intel_encoder->base); + struct intel_connector *intel_connector = + intel_hdmi->attached_connector; + /* + * We are here, means there is a hotplug or a force + * detection. Clear the cached EDID and probe the + * DDC bus to check the current status of HDMI. + */ + intel_hdmi_unset_edid(&intel_connector->base); + if (intel_hdmi_set_edid(&intel_connector->base)) + DRM_DEBUG_DRIVER("DDC probe: got EDID\n"); + else + DRM_DEBUG_DRIVER("DDC probe: no EDID\n"); +} + static enum drm_connector_status intel_hdmi_detect(struct drm_connector *connector, bool force) { enum drm_connector_status status; + struct intel_connector *intel_connector = + to_intel_connector(connector); + struct drm_device *dev = connector->dev; DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id, connector->name); + /* + * There are many userspace calls which probe EDID from + * detect path. In case of multiple hotplug/unplug, these + * can cause race conditions while probing EDID. Also its + * waste of CPU cycles to read the EDID again and again + * unless there is a real hotplug. + * So, reading edid in detect only for older platforms (< gen7) + * Letting the newer platforms rely on hotplugs and init to read edid. + * Check connector status based on availability of cached EDID. + */ + if (INTEL_INFO(dev)->gen < 7) + intel_hdmi_probe(intel_connector->encoder); - intel_hdmi_unset_edid(connector); - - if (intel_hdmi_set_edid(connector)) { + if (intel_connector->detect_edid) { struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); - - hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI; status = connector_status_connected; - } else + hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI; + DRM_DEBUG_DRIVER("hdmi status = connected\n"); + } else { status = connector_status_disconnected; + DRM_DEBUG_DRIVER("hdmi status = disconnected\n"); + } return status; } @@ -1997,11 +2030,15 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, intel_connector->unregister = intel_connector_unregister; intel_hdmi_add_properties(intel_hdmi, connector); + intel_encoder->hot_plug = intel_hdmi_probe; intel_connector_attach_encoder(intel_connector, intel_encoder); drm_connector_register(connector); intel_hdmi->attached_connector = intel_connector; + /* Set edid during init */ + intel_hdmi_probe(intel_encoder); + /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written * 0xd. Failure to do so will result in spurious interrupts being * generated on the port when a cable is not attached.