From patchwork Fri Dec 1 17:20:28 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Paul X-Patchwork-Id: 10087571 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 830F860327 for ; Fri, 1 Dec 2017 17:21:44 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6B8162A586 for ; Fri, 1 Dec 2017 17:21:44 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 606812A5F0; Fri, 1 Dec 2017 17:21:44 +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.1 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id B6D022A603 for ; Fri, 1 Dec 2017 17:21:43 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id F355D6EDD2; Fri, 1 Dec 2017 17:21:38 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mail-yw0-x241.google.com (mail-yw0-x241.google.com [IPv6:2607:f8b0:4002:c05::241]) by gabe.freedesktop.org (Postfix) with ESMTPS id 45BBE6EDD3 for ; Fri, 1 Dec 2017 17:21:37 +0000 (UTC) Received: by mail-yw0-x241.google.com with SMTP id r205so4310061ywb.3 for ; Fri, 01 Dec 2017 09:21:37 -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=DMTqUMniFRrMUxsAShRz0pFcWR474mr3jjLMXdRIKo8=; b=EfkT7KAbER/8+OSFqFPD8YZETn3eh5M/Tr13w+VMU9qKi8e5l+i9PMggXnjTqwbNDq hzBHeu7DDVkWULTfOa3UpUO1PsK4yFxw9XYkwXWjkgZ6/80BkGVGG64vJr3dYMR5NrF7 Fggp7qG5UEAetQ8zbVtcNyrWfCGyC7xGBynGk= 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=DMTqUMniFRrMUxsAShRz0pFcWR474mr3jjLMXdRIKo8=; b=R56tqXIeQTqPLeFCLzu8AqU4mSatK+tGi5POpJgRvNh8toalDUpsZK1+0/JrOZrYcC 8shP73bAC44sB1dJ10LzMFbEEniP4AOM3ne1+6jzu4gyVgyvo2rHqbXylJMntBef3IJO G6zqbz10UHwZf0u6j/zR7vDL5TIlahx3qElq0g++UZrwIwUUEhPTsWBtY+rjlf2DqOOT sQ24oMzziouUJLxoZIAFAf+7E0SgmQod+8tTWMWyGW5F8y/D767f/SsmVnTIlqnTxjOx DQRfoVjM3LM7KSX+6wT3DhBt2HxzmgQ9C85Ra+DxcN/0lPozkGNqn1+PVWkOpWrDVMC0 RKSg== X-Gm-Message-State: AJaThX6VsWeaiVAYWgTrBAylv1+CpE8Uwk0n0diIlQ5l1Sjo+yZ8TUsT cGHGwF+kuRlHAs8gwTDD2tdSWw== X-Google-Smtp-Source: AGs4zMY9Cda6U0M8TZNwD4bBPUzN9pshm5QGRG3fLBZ6NHrlS9ilzoOFFe6nqbBIQ5he2iwrSdOkEg== X-Received: by 10.13.194.132 with SMTP id e126mr1697925ywd.357.1512148896328; Fri, 01 Dec 2017 09:21:36 -0800 (PST) Received: from rosewood.cam.corp.google.com ([2620:0:1013:11:d3af:69ac:1964:28e8]) by smtp.gmail.com with ESMTPSA id l33sm3751928ywh.6.2017.12.01.09.21.35 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 01 Dec 2017 09:21:35 -0800 (PST) From: Sean Paul To: dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org Date: Fri, 1 Dec 2017 12:20:28 -0500 Message-Id: <20171201172032.47357-7-seanpaul@chromium.org> X-Mailer: git-send-email 2.15.0.531.g2ccb3012c9-goog In-Reply-To: <20171201172032.47357-1-seanpaul@chromium.org> References: <20171201172032.47357-1-seanpaul@chromium.org> Cc: David Airlie , linux-kernel@vger.kernel.org, Rodrigo Vivi , daniel.vetter@intel.com Subject: [Intel-gfx] [PATCH v2 6/8] drm/i915: Add function to output Aksv over GMBUS 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-Virus-Scanned: ClamAV using ClamSMTP 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. Changes in v2: - None 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 36bb4927484a..10f740c9e571 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -4043,6 +4043,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 6dca305ccbf7..8b71a20882ca 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -3040,6 +3040,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) &