From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753072AbdLERCN (ORCPT ); Tue, 5 Dec 2017 12:02:13 -0500 Received: from mail-wm0-f66.google.com ([74.125.82.66]:39578 "EHLO mail-wm0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753039AbdLERCJ (ORCPT ); Tue, 5 Dec 2017 12:02:09 -0500 X-Google-Smtp-Source: AGs4zMaiuuBWmn60QCfTQVe/JFuylugdcEKZVRbvGqSYOL3YnRnwT4Llwi8/Q2ST1UUJtTrPcQ7tHg== Date: Tue, 5 Dec 2017 18:02:03 +0100 From: Daniel Vetter To: Sean Paul Cc: dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org, seanpaul@google.com, David Airlie , linux-kernel@vger.kernel.org, Rodrigo Vivi , daniel.vetter@intel.com Subject: Re: [Intel-gfx] [PATCH v3 7/9] drm/i915: Add function to output Aksv over GMBUS Message-ID: <20171205170203.mlgwznpot2ap5na2@phenom.ffwll.local> Mail-Followup-To: Sean Paul , dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org, seanpaul@google.com, David Airlie , linux-kernel@vger.kernel.org, Rodrigo Vivi , daniel.vetter@intel.com References: <20171205051513.8603-1-seanpaul@chromium.org> <20171205051513.8603-8-seanpaul@chromium.org> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <20171205051513.8603-8-seanpaul@chromium.org> X-Operating-System: Linux phenom 4.13.0-1-amd64 User-Agent: NeoMutt/20170609 (1.8.3) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Tue, Dec 05, 2017 at 12:15:06AM -0500, Sean Paul wrote: > 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 > Changes in v3: > - Uses new index write feature (Ville) > > Cc: Ville Syrjälä > Signed-off-by: Sean Paul Reviewed-by: Daniel Vetter > --- > drivers/gpu/drm/i915/i915_drv.h | 1 + > drivers/gpu/drm/i915/i915_reg.h | 1 + > drivers/gpu/drm/i915/intel_i2c.c | 47 +++++++++++++++++++++++++++++++++++++--- > 3 files changed, 46 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h > index bddd65839f60..6b39081c5e53 100644 > --- a/drivers/gpu/drm/i915/i915_drv.h > +++ b/drivers/gpu/drm/i915/i915_drv.h > @@ -4049,6 +4049,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 2bd2cc8441d4..107e16392710 100644 > --- a/drivers/gpu/drm/i915/i915_reg.h > +++ b/drivers/gpu/drm/i915/i915_reg.h > @@ -3043,6 +3043,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 7399009aee0a..0a4c7486fc7b 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" > @@ -497,7 +498,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) > { > struct intel_gmbus *bus = container_of(adapter, > struct intel_gmbus, > @@ -507,7 +509,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; > @@ -629,7 +631,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); > if (ret == -EAGAIN) > bus->force_bit |= GMBUS_FORCE_BIT_RETRY; > } > @@ -639,6 +641,45 @@ 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 cmd = DRM_HDCP_DDC_AKSV ; > + u8 buf[DRM_HDCP_KSV_LEN] = { 0 }; > + struct i2c_msg msgs[] = { > + { > + .addr = DRM_HDCP_DDC_ADDR, > + .flags = 0, > + .len = sizeof(cmd), > + .buf = &cmd, > + }, > + { > + .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, msgs, ARRAY_SIZE(msgs), GMBUS_AKSV_SELECT); > + > + 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 > > _______________________________________________ > Intel-gfx mailing list > Intel-gfx@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch