root/drivers/gpu/drm/nouveau/nvkm/subdev/pci/gk104.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. gk104_pcie_version_supported
  2. gk104_pcie_set_cap_speed
  3. gk104_pcie_cap_speed
  4. gk104_pcie_set_lnkctl_speed
  5. gk104_pcie_lnkctl_speed
  6. gk104_pcie_max_speed
  7. gk104_pcie_set_link_speed
  8. gk104_pcie_init
  9. gk104_pcie_set_link
  10. gk104_pci_new

   1 /*
   2  * Copyright 2015 Karol Herbst <nouveau@karolherbst.de>
   3  *
   4  * Permission is hereby granted, free of charge, to any person obtaining a
   5  * copy of this software and associated documentation files (the "Software"),
   6  * to deal in the Software without restriction, including without limitation
   7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   8  * and/or sell copies of the Software, and to permit persons to whom the
   9  * Software is furnished to do so, subject to the following conditions:
  10  *
  11  * The above copyright notice and this permission notice shall be included in
  12  * all copies or substantial portions of the Software.
  13  *
  14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20  * OTHER DEALINGS IN THE SOFTWARE.
  21  *
  22  * Authors: Karol Herbst <nouveau@karolherbst.de>
  23  */
  24 #include "priv.h"
  25 
  26 static int
  27 gk104_pcie_version_supported(struct nvkm_pci *pci)
  28 {
  29         return (nvkm_rd32(pci->subdev.device, 0x8c1c0) & 0x4) == 0x4 ? 2 : 1;
  30 }
  31 
  32 static void
  33 gk104_pcie_set_cap_speed(struct nvkm_pci *pci, enum nvkm_pcie_speed speed)
  34 {
  35         struct nvkm_device *device = pci->subdev.device;
  36 
  37         switch (speed) {
  38         case NVKM_PCIE_SPEED_2_5:
  39                 gf100_pcie_set_cap_speed(pci, false);
  40                 nvkm_mask(device, 0x8c1c0, 0x30000, 0x10000);
  41                 break;
  42         case NVKM_PCIE_SPEED_5_0:
  43                 gf100_pcie_set_cap_speed(pci, true);
  44                 nvkm_mask(device, 0x8c1c0, 0x30000, 0x20000);
  45                 break;
  46         case NVKM_PCIE_SPEED_8_0:
  47                 gf100_pcie_set_cap_speed(pci, true);
  48                 nvkm_mask(device, 0x8c1c0, 0x30000, 0x30000);
  49                 break;
  50         }
  51 }
  52 
  53 static enum nvkm_pcie_speed
  54 gk104_pcie_cap_speed(struct nvkm_pci *pci)
  55 {
  56         int speed = gf100_pcie_cap_speed(pci);
  57 
  58         if (speed == 0)
  59                 return NVKM_PCIE_SPEED_2_5;
  60 
  61         if (speed >= 1) {
  62                 int speed2 = nvkm_rd32(pci->subdev.device, 0x8c1c0) & 0x30000;
  63                 switch (speed2) {
  64                 case 0x00000:
  65                 case 0x10000:
  66                         return NVKM_PCIE_SPEED_2_5;
  67                 case 0x20000:
  68                         return NVKM_PCIE_SPEED_5_0;
  69                 case 0x30000:
  70                         return NVKM_PCIE_SPEED_8_0;
  71                 }
  72         }
  73 
  74         return -EINVAL;
  75 }
  76 
  77 static void
  78 gk104_pcie_set_lnkctl_speed(struct nvkm_pci *pci, enum nvkm_pcie_speed speed)
  79 {
  80         u8 reg_v = 0;
  81         switch (speed) {
  82         case NVKM_PCIE_SPEED_2_5:
  83                 reg_v = 1;
  84                 break;
  85         case NVKM_PCIE_SPEED_5_0:
  86                 reg_v = 2;
  87                 break;
  88         case NVKM_PCIE_SPEED_8_0:
  89                 reg_v = 3;
  90                 break;
  91         }
  92         nvkm_pci_mask(pci, 0xa8, 0x3, reg_v);
  93 }
  94 
  95 static enum nvkm_pcie_speed
  96 gk104_pcie_lnkctl_speed(struct nvkm_pci *pci)
  97 {
  98         u8 reg_v = nvkm_pci_rd32(pci, 0xa8) & 0x3;
  99         switch (reg_v) {
 100         case 0:
 101         case 1:
 102                 return NVKM_PCIE_SPEED_2_5;
 103         case 2:
 104                 return NVKM_PCIE_SPEED_5_0;
 105         case 3:
 106                 return NVKM_PCIE_SPEED_8_0;
 107         }
 108         return -1;
 109 }
 110 
 111 static enum nvkm_pcie_speed
 112 gk104_pcie_max_speed(struct nvkm_pci *pci)
 113 {
 114         u32 max_speed = nvkm_rd32(pci->subdev.device, 0x8c1c0) & 0x300000;
 115         switch (max_speed) {
 116         case 0x000000:
 117                 return NVKM_PCIE_SPEED_8_0;
 118         case 0x100000:
 119                 return NVKM_PCIE_SPEED_5_0;
 120         case 0x200000:
 121                 return NVKM_PCIE_SPEED_2_5;
 122         }
 123         return NVKM_PCIE_SPEED_2_5;
 124 }
 125 
 126 static void
 127 gk104_pcie_set_link_speed(struct nvkm_pci *pci, enum nvkm_pcie_speed speed)
 128 {
 129         struct nvkm_device *device = pci->subdev.device;
 130         u32 mask_value;
 131 
 132         switch (speed) {
 133         case NVKM_PCIE_SPEED_8_0:
 134                 mask_value = 0x00000;
 135                 break;
 136         case NVKM_PCIE_SPEED_5_0:
 137                 mask_value = 0x40000;
 138                 break;
 139         case NVKM_PCIE_SPEED_2_5:
 140         default:
 141                 mask_value = 0x80000;
 142                 break;
 143         }
 144 
 145         nvkm_mask(device, 0x8c040, 0xc0000, mask_value);
 146         nvkm_mask(device, 0x8c040, 0x1, 0x1);
 147 }
 148 
 149 static int
 150 gk104_pcie_init(struct nvkm_pci * pci)
 151 {
 152         enum nvkm_pcie_speed lnkctl_speed, max_speed, cap_speed;
 153         struct nvkm_subdev *subdev = &pci->subdev;
 154 
 155         if (gf100_pcie_version(pci) < 2)
 156                 return 0;
 157 
 158         lnkctl_speed = gk104_pcie_lnkctl_speed(pci);
 159         max_speed = gk104_pcie_max_speed(pci);
 160         cap_speed = gk104_pcie_cap_speed(pci);
 161 
 162         if (cap_speed != max_speed) {
 163                 nvkm_trace(subdev, "adjusting cap to max speed\n");
 164                 gk104_pcie_set_cap_speed(pci, max_speed);
 165                 cap_speed = gk104_pcie_cap_speed(pci);
 166                 if (cap_speed != max_speed)
 167                         nvkm_warn(subdev, "failed to adjust cap speed\n");
 168         }
 169 
 170         if (lnkctl_speed != max_speed) {
 171                 nvkm_debug(subdev, "adjusting lnkctl to max speed\n");
 172                 gk104_pcie_set_lnkctl_speed(pci, max_speed);
 173                 lnkctl_speed = gk104_pcie_lnkctl_speed(pci);
 174                 if (lnkctl_speed != max_speed)
 175                         nvkm_error(subdev, "failed to adjust lnkctl speed\n");
 176         }
 177 
 178         return 0;
 179 }
 180 
 181 static int
 182 gk104_pcie_set_link(struct nvkm_pci *pci, enum nvkm_pcie_speed speed, u8 width)
 183 {
 184         struct nvkm_subdev *subdev = &pci->subdev;
 185         enum nvkm_pcie_speed lnk_ctl_speed = gk104_pcie_lnkctl_speed(pci);
 186         enum nvkm_pcie_speed lnk_cap_speed = gk104_pcie_cap_speed(pci);
 187 
 188         if (speed > lnk_cap_speed) {
 189                 speed = lnk_cap_speed;
 190                 nvkm_warn(subdev, "dropping requested speed due too low cap"
 191                           " speed\n");
 192         }
 193 
 194         if (speed > lnk_ctl_speed) {
 195                 speed = lnk_ctl_speed;
 196                 nvkm_warn(subdev, "dropping requested speed due too low"
 197                           " lnkctl speed\n");
 198         }
 199 
 200         gk104_pcie_set_link_speed(pci, speed);
 201         return 0;
 202 }
 203 
 204 
 205 static const struct nvkm_pci_func
 206 gk104_pci_func = {
 207         .init = g84_pci_init,
 208         .rd32 = nv40_pci_rd32,
 209         .wr08 = nv40_pci_wr08,
 210         .wr32 = nv40_pci_wr32,
 211         .msi_rearm = nv40_pci_msi_rearm,
 212 
 213         .pcie.init = gk104_pcie_init,
 214         .pcie.set_link = gk104_pcie_set_link,
 215 
 216         .pcie.max_speed = gk104_pcie_max_speed,
 217         .pcie.cur_speed = g84_pcie_cur_speed,
 218 
 219         .pcie.set_version = gf100_pcie_set_version,
 220         .pcie.version = gf100_pcie_version,
 221         .pcie.version_supported = gk104_pcie_version_supported,
 222 };
 223 
 224 int
 225 gk104_pci_new(struct nvkm_device *device, int index, struct nvkm_pci **ppci)
 226 {
 227         return nvkm_pci_new_(&gk104_pci_func, device, index, ppci);
 228 }

/* [<][>][^][v][top][bottom][index][help] */