]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.12-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 4 Sep 2017 12:11:22 +0000 (14:11 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 4 Sep 2017 12:11:22 +0000 (14:11 +0200)
added patches:
drm-nouveau-i2c-gf119-add-support-for-address-only-transactions.patch

queue-4.12/drm-nouveau-i2c-gf119-add-support-for-address-only-transactions.patch [new file with mode: 0644]
queue-4.12/series

diff --git a/queue-4.12/drm-nouveau-i2c-gf119-add-support-for-address-only-transactions.patch b/queue-4.12/drm-nouveau-i2c-gf119-add-support-for-address-only-transactions.patch
new file mode 100644 (file)
index 0000000..453357b
--- /dev/null
@@ -0,0 +1,262 @@
+From 13a86519202c5d119d83640d6f781f3181205d2c Mon Sep 17 00:00:00 2001
+From: Ben Skeggs <bskeggs@redhat.com>
+Date: Wed, 19 Jul 2017 16:49:59 +1000
+Subject: drm/nouveau/i2c/gf119-: add support for address-only transactions
+
+From: Ben Skeggs <bskeggs@redhat.com>
+
+commit 13a86519202c5d119d83640d6f781f3181205d2c upstream.
+
+Since switching the I2C-over-AUX helpers, there have been regressions on
+some display combinations due to us not having support for "address only"
+transactions.
+
+This commits enables support for them for GF119 and newer.
+
+Earlier GPUs have been reverted to a custom I2C-over-AUX algorithm.
+
+Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
+Cc: Ilia Mirkin <imirkin@alum.mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/nouveau/nouveau_connector.c        |    2 -
+ drivers/gpu/drm/nouveau/nv50_display.c             |   13 ++++++-
+ drivers/gpu/drm/nouveau/nvkm/subdev/i2c/Kbuild     |    1 
+ drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.c      |    4 ++
+ drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.h      |    6 +++
+ drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxg94.c   |   30 +++++++++++-------
+ drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgf119.c |   35 +++++++++++++++++++++
+ drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgm200.c |    5 +--
+ drivers/gpu/drm/nouveau/nvkm/subdev/i2c/padgf119.c |    4 +-
+ 9 files changed, 81 insertions(+), 19 deletions(-)
+
+--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
++++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
+@@ -1155,8 +1155,6 @@ nouveau_connector_aux_xfer(struct drm_dp
+               return -ENODEV;
+       if (WARN_ON(msg->size > 16))
+               return -E2BIG;
+-      if (msg->size == 0)
+-              return msg->size;
+       ret = nvkm_i2c_aux_acquire(aux);
+       if (ret)
+--- a/drivers/gpu/drm/nouveau/nv50_display.c
++++ b/drivers/gpu/drm/nouveau/nv50_display.c
+@@ -3618,15 +3618,24 @@ nv50_sor_create(struct drm_connector *co
+       drm_mode_connector_attach_encoder(connector, encoder);
+       if (dcbe->type == DCB_OUTPUT_DP) {
++              struct nv50_disp *disp = nv50_disp(encoder->dev);
+               struct nvkm_i2c_aux *aux =
+                       nvkm_i2c_aux_find(i2c, dcbe->i2c_index);
+               if (aux) {
+-                      nv_encoder->i2c = &nv_connector->aux.ddc;
++                      if (disp->disp->oclass < GF110_DISP) {
++                              /* HW has no support for address-only
++                               * transactions, so we're required to
++                               * use custom I2C-over-AUX code.
++                               */
++                              nv_encoder->i2c = &aux->i2c;
++                      } else {
++                              nv_encoder->i2c = &nv_connector->aux.ddc;
++                      }
+                       nv_encoder->aux = aux;
+               }
+               /*TODO: Use DP Info Table to check for support. */
+-              if (nv50_disp(encoder->dev)->disp->oclass >= GF110_DISP) {
++              if (disp->disp->oclass >= GF110_DISP) {
+                       ret = nv50_mstm_new(nv_encoder, &nv_connector->aux, 16,
+                                           nv_connector->base.base.id,
+                                           &nv_encoder->dp.mstm);
+--- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/Kbuild
++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/Kbuild
+@@ -25,6 +25,7 @@ nvkm-y += nvkm/subdev/i2c/bit.o
+ nvkm-y += nvkm/subdev/i2c/aux.o
+ nvkm-y += nvkm/subdev/i2c/auxg94.o
++nvkm-y += nvkm/subdev/i2c/auxgf119.o
+ nvkm-y += nvkm/subdev/i2c/auxgm200.o
+ nvkm-y += nvkm/subdev/i2c/anx9805.o
+--- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.c
++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.c
+@@ -117,6 +117,10 @@ int
+ nvkm_i2c_aux_xfer(struct nvkm_i2c_aux *aux, bool retry, u8 type,
+                 u32 addr, u8 *data, u8 *size)
+ {
++      if (!*size && !aux->func->address_only) {
++              AUX_ERR(aux, "address-only transaction dropped");
++              return -ENOSYS;
++      }
+       return aux->func->xfer(aux, retry, type, addr, data, size);
+ }
+--- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.h
++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.h
+@@ -3,6 +3,7 @@
+ #include "pad.h"
+ struct nvkm_i2c_aux_func {
++      bool address_only;
+       int  (*xfer)(struct nvkm_i2c_aux *, bool retry, u8 type,
+                    u32 addr, u8 *data, u8 *size);
+       int  (*lnk_ctl)(struct nvkm_i2c_aux *, int link_nr, int link_bw,
+@@ -17,7 +18,12 @@ void nvkm_i2c_aux_del(struct nvkm_i2c_au
+ int nvkm_i2c_aux_xfer(struct nvkm_i2c_aux *, bool retry, u8 type,
+                     u32 addr, u8 *data, u8 *size);
++int g94_i2c_aux_new_(const struct nvkm_i2c_aux_func *, struct nvkm_i2c_pad *,
++                   int, u8, struct nvkm_i2c_aux **);
++
+ int g94_i2c_aux_new(struct nvkm_i2c_pad *, int, u8, struct nvkm_i2c_aux **);
++int g94_i2c_aux_xfer(struct nvkm_i2c_aux *, bool, u8, u32, u8 *, u8 *);
++int gf119_i2c_aux_new(struct nvkm_i2c_pad *, int, u8, struct nvkm_i2c_aux **);
+ int gm200_i2c_aux_new(struct nvkm_i2c_pad *, int, u8, struct nvkm_i2c_aux **);
+ #define AUX_MSG(b,l,f,a...) do {                                               \
+--- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxg94.c
++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxg94.c
+@@ -72,7 +72,7 @@ g94_i2c_aux_init(struct g94_i2c_aux *aux
+       return 0;
+ }
+-static int
++int
+ g94_i2c_aux_xfer(struct nvkm_i2c_aux *obj, bool retry,
+                u8 type, u32 addr, u8 *data, u8 *size)
+ {
+@@ -105,9 +105,9 @@ g94_i2c_aux_xfer(struct nvkm_i2c_aux *ob
+       }
+       ctrl  = nvkm_rd32(device, 0x00e4e4 + base);
+-      ctrl &= ~0x0001f0ff;
++      ctrl &= ~0x0001f1ff;
+       ctrl |= type << 12;
+-      ctrl |= *size - 1;
++      ctrl |= (*size ? (*size - 1) : 0x00000100);
+       nvkm_wr32(device, 0x00e4e0 + base, addr);
+       /* (maybe) retry transaction a number of times on failure... */
+@@ -160,14 +160,10 @@ out:
+       return ret < 0 ? ret : (stat & 0x000f0000) >> 16;
+ }
+-static const struct nvkm_i2c_aux_func
+-g94_i2c_aux_func = {
+-      .xfer = g94_i2c_aux_xfer,
+-};
+-
+ int
+-g94_i2c_aux_new(struct nvkm_i2c_pad *pad, int index, u8 drive,
+-              struct nvkm_i2c_aux **paux)
++g94_i2c_aux_new_(const struct nvkm_i2c_aux_func *func,
++               struct nvkm_i2c_pad *pad, int index, u8 drive,
++               struct nvkm_i2c_aux **paux)
+ {
+       struct g94_i2c_aux *aux;
+@@ -175,8 +171,20 @@ g94_i2c_aux_new(struct nvkm_i2c_pad *pad
+               return -ENOMEM;
+       *paux = &aux->base;
+-      nvkm_i2c_aux_ctor(&g94_i2c_aux_func, pad, index, &aux->base);
++      nvkm_i2c_aux_ctor(func, pad, index, &aux->base);
+       aux->ch = drive;
+       aux->base.intr = 1 << aux->ch;
+       return 0;
+ }
++
++static const struct nvkm_i2c_aux_func
++g94_i2c_aux = {
++      .xfer = g94_i2c_aux_xfer,
++};
++
++int
++g94_i2c_aux_new(struct nvkm_i2c_pad *pad, int index, u8 drive,
++              struct nvkm_i2c_aux **paux)
++{
++      return g94_i2c_aux_new_(&g94_i2c_aux, pad, index, drive, paux);
++}
+--- /dev/null
++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgf119.c
+@@ -0,0 +1,35 @@
++/*
++ * Copyright 2017 Red Hat Inc.
++ *
++ * 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 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "aux.h"
++
++static const struct nvkm_i2c_aux_func
++gf119_i2c_aux = {
++      .address_only = true,
++      .xfer = g94_i2c_aux_xfer,
++};
++
++int
++gf119_i2c_aux_new(struct nvkm_i2c_pad *pad, int index, u8 drive,
++                struct nvkm_i2c_aux **paux)
++{
++      return g94_i2c_aux_new_(&gf119_i2c_aux, pad, index, drive, paux);
++}
+--- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgm200.c
++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgm200.c
+@@ -105,9 +105,9 @@ gm200_i2c_aux_xfer(struct nvkm_i2c_aux *
+       }
+       ctrl  = nvkm_rd32(device, 0x00d954 + base);
+-      ctrl &= ~0x0001f0ff;
++      ctrl &= ~0x0001f1ff;
+       ctrl |= type << 12;
+-      ctrl |= *size - 1;
++      ctrl |= (*size ? (*size - 1) : 0x00000100);
+       nvkm_wr32(device, 0x00d950 + base, addr);
+       /* (maybe) retry transaction a number of times on failure... */
+@@ -162,6 +162,7 @@ out:
+ static const struct nvkm_i2c_aux_func
+ gm200_i2c_aux_func = {
++      .address_only = true,
+       .xfer = gm200_i2c_aux_xfer,
+ };
+--- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/padgf119.c
++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/padgf119.c
+@@ -28,7 +28,7 @@
+ static const struct nvkm_i2c_pad_func
+ gf119_i2c_pad_s_func = {
+       .bus_new_4 = gf119_i2c_bus_new,
+-      .aux_new_6 = g94_i2c_aux_new,
++      .aux_new_6 = gf119_i2c_aux_new,
+       .mode = g94_i2c_pad_mode,
+ };
+@@ -41,7 +41,7 @@ gf119_i2c_pad_s_new(struct nvkm_i2c *i2c
+ static const struct nvkm_i2c_pad_func
+ gf119_i2c_pad_x_func = {
+       .bus_new_4 = gf119_i2c_bus_new,
+-      .aux_new_6 = g94_i2c_aux_new,
++      .aux_new_6 = gf119_i2c_aux_new,
+ };
+ int
index fa189c2382474f9febee7d425c09459e16f5a52e..d3347fa3ef4cdf183da8c2c7f8628df8ce904489 100644 (file)
@@ -23,3 +23,4 @@ lib-mpi-kunmap-after-finishing-accessing-buffer.patch
 xfrm-policy-check-policy-direction-value.patch
 drm-ttm-fix-accounting-error-when-fail-to-get-pages-for-pool.patch
 nvme-fix-the-definition-of-the-doorbell-buffer-config-support-bit.patch
+drm-nouveau-i2c-gf119-add-support-for-address-only-transactions.patch