Received: by 10.223.164.202 with SMTP id h10csp158132wrb; Wed, 29 Nov 2017 19:10:55 -0800 (PST) X-Google-Smtp-Source: AGs4zMa9Xm8LEkOgJMm5Agnz123GynvurmvQe4uFr2f7oyY6jSuIbJY4q/zTIght9APCzrB0PRH3 X-Received: by 10.84.235.65 with SMTP id g1mr1088110plt.13.1512011454934; Wed, 29 Nov 2017 19:10:54 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512011454; cv=none; d=google.com; s=arc-20160816; b=Uneji9axzCcHCI4hm2yzjD6/kw3dTxHqO+Bf7hURetVe8nIYSpH6z5uwYQ27fJlHcC WsLpTzqVfnznsgP3NhJG/T7DY0XF4rQcG1QWPpT3lv4iaoYNcg39Uu7CvgH2iDLh07HF xtq6PBXae3Cd/8S4mMMbbvC5AEfNinva7xh72WxFwOjBsjmY6ITxmikrzIHyaRjs3r6b FOQNb/LiRE+unqP8pJS8tMYpvKCHWrUjm5vpJszfRsIf+siagJlqd0VieafedC+qkpay G1nR850VqiHq0dvXPP7XGoBAHYvXUUwYV7gQulHdmWljNm5CMG39GcV0dlat+CaSQGvM CJRw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=okzw3Ss5o9lOELWBU4B3eS001O2pulVJ0hdG3vDBd6s=; b=nTS5rzsTl9bEmjOZX6wqQUwSwiQ3Ax41WsQDI3GEJ4TXRDmFfaKHaxkDMGQdAHZZ8P UaoXnLgvxoZjVAYT8wuACjRq0cQT6h/YSAsg+QXkEcCbWDezPNLqeJLP5lnrygOcc7bc DJ+lghIfBNMQNPhJKsVuwcU5ZMWi2b868NnqOQAA9STc9x5ODLy8Da4SlATPJciMgbWU 4UMDySgXGJ6r0ts59V19MZjh4Ga0r/Z2F4vQn4CbjVL5RRV3jesNW3hF8hQnwz48vzZJ mWVqaC0YtuHXCNZkLgpP5adq4YIJbsFQ3ah3jw3VXWgExecnrgWXFc/tPXTZG9mFRk4Z QF4g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=coGWq+dg; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id g71si2405147pfg.124.2017.11.29.19.10.38; Wed, 29 Nov 2017 19:10:54 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=coGWq+dg; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753570AbdK3DKL (ORCPT + 99 others); Wed, 29 Nov 2017 22:10:11 -0500 Received: from mail-yb0-f195.google.com ([209.85.213.195]:46334 "EHLO mail-yb0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752639AbdK3DKG (ORCPT ); Wed, 29 Nov 2017 22:10:06 -0500 Received: by mail-yb0-f195.google.com with SMTP id g187so2179647yba.13 for ; Wed, 29 Nov 2017 19:10:06 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=okzw3Ss5o9lOELWBU4B3eS001O2pulVJ0hdG3vDBd6s=; b=coGWq+dgapuZhNnQBaiFQ9WIMRtk3JE3q6Z/LibItQI2cD7+jDHqP/JEIH1lGTE/GN MH+qAi6C16VgQ3V0iP0usZZ9Rs+pCqGrAxfabZ1PYBcleY4CCVGM71mg78+emGqJX67D nmIIMYPpTz1I6N32yAyL+8LekGiP0Ve/KxkwI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=okzw3Ss5o9lOELWBU4B3eS001O2pulVJ0hdG3vDBd6s=; b=aPGONhMNARR0SH/p8e77wZDHWaQ7UgbziBt2ccJ4OFMKVYgmPa+NOQfjgUoN/HSeBq GgRXZ9hGM8Am0f7666JezyHDjfDjhJwNMh4qWn6jB4C2y8gg/RakfmopEgdou9j74XV2 OyzXbjt4df8R9FAfDGqZa1yl6Uwdmxgb4BnMsCKyu6kPr8qhFl6YyAYMy+2/ap9+iXNW T06lEpZwu7EPvDii5uKi76jCwRZRhlmpwDBAP86pSwrK1O0/H68UApnGQtxKi/Hc+DzX 6NUvQcUuML+WZJaBUh8PcT3pYJoGuwEreTo+h2ClRXyIHkImJJTtEBHGUvX6vutx55ua ddJw== X-Gm-Message-State: AJaThX7jagoCnY9oG2YRf5qjbmIUyc6ko5gzhrkEquJ/JrgQsxjdxopf 45cKZ870SJgyQd8/y784AeC5KA== X-Received: by 10.37.49.68 with SMTP id x65mr611422ybx.261.1512011405623; Wed, 29 Nov 2017 19:10:05 -0800 (PST) Received: from rosewood.cam.corp.google.com ([2620:0:1013:11:d3af:69ac:1964:28e8]) by smtp.gmail.com with ESMTPSA id u24sm1460752ywh.84.2017.11.29.19.10.04 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 29 Nov 2017 19:10:05 -0800 (PST) From: Sean Paul To: dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org Cc: Sean Paul , Jani Nikula , Joonas Lahtinen , Rodrigo Vivi , David Airlie , linux-kernel@vger.kernel.org Subject: [RFC PATCH 4/6] drm/i915: Add function to output Aksv over GMBUS Date: Wed, 29 Nov 2017 22:08:59 -0500 Message-Id: <20171130030907.26848-5-seanpaul@chromium.org> X-Mailer: git-send-email 2.15.0.531.g2ccb3012c9-goog In-Reply-To: <20171130030907.26848-1-seanpaul@chromium.org> References: <20171130030907.26848-1-seanpaul@chromium.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Once the Aksv is available in the PCH, we need to get it on the wire to the receiver via DDC. The hardware doesn't allow us to read the value directly, so we need to tell GMBUS to source the Aksv internally and send it to the right offset on the receiver. The way we do this is to initiate an indexed write where the index is the Aksv register offset. We write dummy values to GMBUS3 as if we were sending the key, and the hardware slips in the "real" values when it goes out. Signed-off-by: Sean Paul --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/i915_reg.h | 1 + drivers/gpu/drm/i915/intel_i2c.c | 54 ++++++++++++++++++++++++++++++++++------ 3 files changed, 48 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 54b5d4c582b6..30fcd856ec23 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -4024,6 +4024,7 @@ extern int intel_setup_gmbus(struct drm_i915_private *dev_priv); extern void intel_teardown_gmbus(struct drm_i915_private *dev_priv); extern bool intel_gmbus_is_valid_pin(struct drm_i915_private *dev_priv, unsigned int pin); +extern int intel_gmbus_output_aksv(struct i2c_adapter *adapter); extern struct i2c_adapter * intel_gmbus_get_adapter(struct drm_i915_private *dev_priv, unsigned int pin); diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 43128030171d..78370877fea3 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -3009,6 +3009,7 @@ enum i915_power_well_id { # define GPIO_DATA_PULLUP_DISABLE (1 << 13) #define GMBUS0 _MMIO(dev_priv->gpio_mmio_base + 0x5100) /* clock/port select */ +#define GMBUS_AKSV_SELECT (1<<11) #define GMBUS_RATE_100KHZ (0<<8) #define GMBUS_RATE_50KHZ (1<<8) #define GMBUS_RATE_400KHZ (2<<8) /* reserved on Pineview */ diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c index eb5827110d8f..c01156bf0f27 100644 --- a/drivers/gpu/drm/i915/intel_i2c.c +++ b/drivers/gpu/drm/i915/intel_i2c.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "intel_drv.h" #include #include "i915_drv.h" @@ -373,7 +374,8 @@ gmbus_xfer_read(struct drm_i915_private *dev_priv, struct i2c_msg *msg, static int gmbus_xfer_write_chunk(struct drm_i915_private *dev_priv, - unsigned short addr, u8 *buf, unsigned int len) + unsigned short addr, u8 *buf, unsigned int len, + u32 gmbus1_index) { unsigned int chunk_size = len; u32 val, loop; @@ -386,7 +388,7 @@ gmbus_xfer_write_chunk(struct drm_i915_private *dev_priv, I915_WRITE_FW(GMBUS3, val); I915_WRITE_FW(GMBUS1, - GMBUS_CYCLE_WAIT | + gmbus1_index | GMBUS_CYCLE_WAIT | (chunk_size << GMBUS_BYTE_COUNT_SHIFT) | (addr << GMBUS_SLAVE_ADDR_SHIFT) | GMBUS_SLAVE_WRITE | GMBUS_SW_RDY); @@ -409,7 +411,8 @@ gmbus_xfer_write_chunk(struct drm_i915_private *dev_priv, } static int -gmbus_xfer_write(struct drm_i915_private *dev_priv, struct i2c_msg *msg) +gmbus_xfer_write(struct drm_i915_private *dev_priv, struct i2c_msg *msg, + u32 gmbus1_index) { u8 *buf = msg->buf; unsigned int tx_size = msg->len; @@ -419,7 +422,8 @@ gmbus_xfer_write(struct drm_i915_private *dev_priv, struct i2c_msg *msg) do { len = min(tx_size, GMBUS_BYTE_COUNT_MAX); - ret = gmbus_xfer_write_chunk(dev_priv, msg->addr, buf, len); + ret = gmbus_xfer_write_chunk(dev_priv, msg->addr, buf, len, + gmbus1_index); if (ret) return ret; @@ -470,7 +474,8 @@ gmbus_xfer_index_read(struct drm_i915_private *dev_priv, struct i2c_msg *msgs) } static int -do_gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num) +do_gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num, + u32 gmbus0_source, u32 gmbus1_index) { struct intel_gmbus *bus = container_of(adapter, struct intel_gmbus, @@ -480,7 +485,7 @@ do_gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num) int ret = 0; retry: - I915_WRITE_FW(GMBUS0, bus->reg0); + I915_WRITE_FW(GMBUS0, gmbus0_source | bus->reg0); for (; i < num; i += inc) { inc = 1; @@ -490,7 +495,8 @@ do_gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num) } else if (msgs[i].flags & I2C_M_RD) { ret = gmbus_xfer_read(dev_priv, &msgs[i], 0); } else { - ret = gmbus_xfer_write(dev_priv, &msgs[i]); + ret = gmbus_xfer_write(dev_priv, &msgs[i], + gmbus1_index); } if (!ret) @@ -598,7 +604,7 @@ gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num) if (ret < 0) bus->force_bit &= ~GMBUS_FORCE_BIT_RETRY; } else { - ret = do_gmbus_xfer(adapter, msgs, num); + ret = do_gmbus_xfer(adapter, msgs, num, 0, 0); if (ret == -EAGAIN) bus->force_bit |= GMBUS_FORCE_BIT_RETRY; } @@ -608,6 +614,38 @@ gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num) return ret; } +int intel_gmbus_output_aksv(struct i2c_adapter *adapter) +{ + struct intel_gmbus *bus = container_of(adapter, struct intel_gmbus, + adapter); + struct drm_i915_private *dev_priv = bus->dev_priv; + int ret; + u8 buf[DRM_HDCP_KSV_LEN] = { 0 }; + struct i2c_msg msg = { + .addr = DRM_HDCP_DDC_ADDR, + .flags = 0, + .len = sizeof(buf), + .buf = buf, + }; + + intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS); + mutex_lock(&dev_priv->gmbus_mutex); + + /* + * In order to output Aksv to the receiver, use an indexed write to + * pass the i2c command, and tell GMBUS to use the HW-provided value + * instead of sourcing GMBUS3 for the data. + */ + ret = do_gmbus_xfer(adapter, &msg, 1, GMBUS_AKSV_SELECT, + GMBUS_CYCLE_INDEX | + (DRM_HDCP_DDC_AKSV << GMBUS_SLAVE_INDEX_SHIFT)); + + mutex_unlock(&dev_priv->gmbus_mutex); + intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS); + + return ret; +} + static u32 gmbus_func(struct i2c_adapter *adapter) { return i2c_bit_algo.functionality(adapter) & -- 2.15.0.531.g2ccb3012c9-goog From 1584815082749062893@xxx Thu Nov 23 00:37:20 +0000 2017 X-GM-THRID: 1584815082749062893 X-Gmail-Labels: Inbox,Category Forums,HistoricalUnread