From patchwork Tue May 31 09:25:43 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Sharma, Shashank" X-Patchwork-Id: 9143985 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 6B89F60777 for ; Tue, 31 May 2016 09:16:40 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5E42E2793B for ; Tue, 31 May 2016 09:16:40 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5307328185; Tue, 31 May 2016 09:16:40 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CDA1B2793B for ; Tue, 31 May 2016 09:16:39 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 56D186E33B; Tue, 31 May 2016 09:16:33 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by gabe.freedesktop.org (Postfix) with ESMTP id C5AF96E337 for ; Tue, 31 May 2016 09:16:24 +0000 (UTC) Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga101.fm.intel.com with ESMTP; 31 May 2016 02:16:25 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.26,395,1459839600"; d="scan'208";a="711474862" Received: from shashanks-desktop.iind.intel.com ([10.223.26.24]) by FMSMGA003.fm.intel.com with ESMTP; 31 May 2016 02:16:22 -0700 From: Shashank Sharma To: intel-gfx@lists.freedesktop.org, ville.syrjala@linux.intel.com, paulo.r.zanoni@intel.com Date: Tue, 31 May 2016 14:55:43 +0530 Message-Id: <1464686746-5099-3-git-send-email-shashank.sharma@intel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1464686746-5099-1-git-send-email-shashank.sharma@intel.com> References: <1464686746-5099-1-git-send-email-shashank.sharma@intel.com> MIME-Version: 1.0 Cc: daniel.vetter@intel.com Subject: [Intel-gfx] [PATCH 2/5] drm/i915: Add lspcon support for I915 driver 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: , Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP lspcon is a dp->hdmi adaptor has two modes of operation. ls mode: level shifter mode, passive dp->hdmi dongle pcon mode: protocol converter mode, active dp->hdmi 2.0 converter. This patch adds a new file, to accommodate lspcon support for I915 driver. These functions probe, detect, initialize and configure an on-board lspcon device during the driver init time. Also, this patch adds a small structure for lspcon device, which will provide the runtime status of the device. Signed-off-by: Shashank Sharma Signed-off-by: Akashdeep Sharma --- drivers/gpu/drm/i915/Makefile | 1 + drivers/gpu/drm/i915/intel_drv.h | 13 ++- drivers/gpu/drm/i915/intel_lspcon.c | 159 ++++++++++++++++++++++++++++++++++++ 3 files changed, 172 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/i915/intel_lspcon.c diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 7e29444..1bd6026 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -93,6 +93,7 @@ i915-y += dvo_ch7017.o \ intel_dvo.o \ intel_hdmi.o \ intel_i2c.o \ + intel_lspcon.o \ intel_lvds.o \ intel_panel.o \ intel_sdvo.o \ diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 9b5f663..205a463 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -896,12 +896,19 @@ struct intel_dp { bool compliance_test_active; }; +struct intel_lspcon { + bool active; + enum drm_lspcon_mode mode_of_op; + struct drm_dp_aux *aux; +}; + struct intel_digital_port { struct intel_encoder base; enum port port; u32 saved_port_bits; struct intel_dp dp; struct intel_hdmi hdmi; + struct intel_lspcon lspcon; enum irqreturn (*hpd_pulse)(struct intel_digital_port *, bool); bool release_cl2_override; uint8_t max_lanes; @@ -1446,7 +1453,6 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config); void intel_dp_dual_mode_set_tmds_output(struct intel_hdmi *hdmi, bool enable); - /* intel_lvds.c */ void intel_lvds_init(struct drm_device *dev); bool intel_is_dual_link_lvds(struct drm_device *dev); @@ -1734,4 +1740,9 @@ int intel_color_check(struct drm_crtc *crtc, struct drm_crtc_state *state); void intel_color_set_csc(struct drm_crtc_state *crtc_state); void intel_color_load_luts(struct drm_crtc_state *crtc_state); +/* intel_lspcon.c */ +bool lspcon_init(struct intel_digital_port *intel_dig_port); +enum drm_connector_status +lspcon_ls_mode_detect(struct drm_connector *connector, bool force); +bool is_lspcon_active(struct intel_digital_port *dig_port); #endif /* __INTEL_DRV_H__ */ diff --git a/drivers/gpu/drm/i915/intel_lspcon.c b/drivers/gpu/drm/i915/intel_lspcon.c new file mode 100644 index 0000000..dd50491 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_lspcon.c @@ -0,0 +1,159 @@ +/* + * Copyright © 2016 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * + */ +#include +#include +#include +#include "intel_drv.h" + +#define LSPCON_I2C_ADDRESS 0x80 +#define LSPCON_ADAPTER_SIGN_OFFSET 0x00 +#define LSPCON_IDENTIFIER_OFFSET 0x10 +#define LSPCON_IDENTIFIER_LENGTH 0x10 + +bool is_lspcon_active(struct intel_digital_port *dig_port) +{ + return dig_port->lspcon.active; +} + +enum drm_lspcon_mode lspcon_get_current_mode(struct intel_lspcon *lspcon) +{ + enum drm_lspcon_mode current_mode; + struct i2c_adapter *adapter = &lspcon->aux->ddc; + + current_mode = drm_lspcon_get_current_mode(adapter); + if (current_mode == DRM_LSPCON_MODE_INVALID) + DRM_ERROR("Error reading LSPCON mode\n"); + else + DRM_DEBUG_KMS("Current LSPCON mode %s\n", + current_mode == DRM_LSPCON_MODE_PCON ? "PCON" : "LS"); + return current_mode; +} + +int lspcon_change_mode(struct intel_lspcon *lspcon, + enum drm_lspcon_mode mode, bool force) +{ + int err; + enum drm_lspcon_mode current_mode; + struct i2c_adapter *adapter = &lspcon->aux->ddc; + + current_mode = drm_lspcon_get_current_mode(adapter); + if (current_mode == DRM_LSPCON_MODE_INVALID) { + DRM_ERROR("Failed to get current LSPCON mode\n"); + return -EFAULT; + } + + if (current_mode == mode && !force) { + DRM_DEBUG_KMS("Current mode = desired LSPCON mode\n"); + return 0; + } + + err = drm_lspcon_change_mode(adapter, mode); + if (err < 0) { + DRM_ERROR("LSPCON mode change failed\n"); + return err; + } + + lspcon->mode_of_op = mode; + DRM_DEBUG_KMS("LSPCON mode changed done\n"); + return 0; +} + +bool lspcon_detect_identifier(struct intel_lspcon *lspcon) +{ + enum drm_dp_dual_mode_type adaptor_type; + struct i2c_adapter *adapter = &lspcon->aux->ddc; + + /* Lets probe the adaptor and check its type */ + adaptor_type = drm_dp_dual_mode_detect(adapter); + if (adaptor_type != DRM_DP_DUAL_MODE_LSPCON) { + DRM_DEBUG_KMS("No LSPCON detected, found %s\n", + drm_dp_get_dual_mode_type_name(adaptor_type)); + return false; + } + + /* Yay ... got a LSPCON device */ + DRM_DEBUG_KMS("LSPCON detected\n"); + return true; +} + +enum drm_lspcon_mode lspcon_probe(struct intel_lspcon *lspcon) +{ + enum drm_lspcon_mode current_mode; + + /* Detect a valid lspcon adaptor */ + if (!lspcon_detect_identifier(lspcon)) { + DRM_DEBUG_KMS("No LSPCON identifier found\n"); + return false; + } + + /* Get LSPCON's mode of operation */ + current_mode = lspcon_get_current_mode(lspcon); + if (current_mode == DRM_LSPCON_MODE_INVALID) { + DRM_ERROR("Failed to read LSPCON mode\n"); + return false; + } + + /* All is well */ + lspcon->mode_of_op = current_mode; + lspcon->active = true; + return current_mode; +} + +bool lspcon_init(struct intel_digital_port *intel_dig_port) +{ + struct intel_dp *dp = &intel_dig_port->dp; + struct intel_lspcon *lspcon = &intel_dig_port->lspcon; + struct drm_device *dev = intel_dig_port->base.base.dev; + + if (!IS_GEN9(dev)) { + DRM_ERROR("LSPCON is supported on GEN9 only\n"); + return false; + } + + lspcon->active = false; + lspcon->mode_of_op = DRM_LSPCON_MODE_INVALID; + lspcon->aux = &dp->aux; + + if (!lspcon_probe(lspcon)) { + DRM_ERROR("Failed to probe lspcon\n"); + return false; + } + + /* + * In the SW state machine, lets Put LSPCON in PCON mode only. + * In this way, it will work with both HDMI 1.4 sinks as well as HDMI + * 2.0 sinks. + */ + if (lspcon->active && lspcon->mode_of_op != DRM_LSPCON_MODE_PCON) { + if (lspcon_change_mode(lspcon, DRM_LSPCON_MODE_PCON, + true) < 0) { + DRM_ERROR("LSPCON mode change to PCON failed\n"); + return false; + } + } + + DRM_DEBUG_KMS("Success: LSPCON init\n"); + return true; +}