1 /* $NetBSD: nouveau_nvkm_subdev_pci_g84.c,v 1.3 2021/12/18 23:45:41 riastradh Exp $ */ 2 3 /* 4 * Copyright 2015 Red Hat Inc. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 * OTHER DEALINGS IN THE SOFTWARE. 23 * 24 * Authors: Ben Skeggs <bskeggs (at) redhat.com> 25 */ 26 #include <sys/cdefs.h> 27 __KERNEL_RCSID(0, "$NetBSD: nouveau_nvkm_subdev_pci_g84.c,v 1.3 2021/12/18 23:45:41 riastradh Exp $"); 28 29 #include "priv.h" 30 31 #include <core/pci.h> 32 33 static int 34 g84_pcie_version_supported(struct nvkm_pci *pci) 35 { 36 /* g84 and g86 report wrong information about what they support */ 37 return 1; 38 } 39 40 int 41 g84_pcie_version(struct nvkm_pci *pci) 42 { 43 struct nvkm_device *device = pci->subdev.device; 44 return (nvkm_rd32(device, 0x00154c) & 0x1) + 1; 45 } 46 47 void 48 g84_pcie_set_version(struct nvkm_pci *pci, u8 ver) 49 { 50 struct nvkm_device *device = pci->subdev.device; 51 nvkm_mask(device, 0x00154c, 0x1, (ver >= 2 ? 0x1 : 0x0)); 52 } 53 54 static void 55 g84_pcie_set_cap_speed(struct nvkm_pci *pci, bool full_speed) 56 { 57 struct nvkm_device *device = pci->subdev.device; 58 nvkm_mask(device, 0x00154c, 0x80, full_speed ? 0x80 : 0x0); 59 } 60 61 enum nvkm_pcie_speed 62 g84_pcie_cur_speed(struct nvkm_pci *pci) 63 { 64 u32 reg_v = nvkm_pci_rd32(pci, 0x88) & 0x30000; 65 switch (reg_v) { 66 case 0x30000: 67 return NVKM_PCIE_SPEED_8_0; 68 case 0x20000: 69 return NVKM_PCIE_SPEED_5_0; 70 case 0x10000: 71 default: 72 return NVKM_PCIE_SPEED_2_5; 73 } 74 } 75 76 enum nvkm_pcie_speed 77 g84_pcie_max_speed(struct nvkm_pci *pci) 78 { 79 u32 reg_v = nvkm_pci_rd32(pci, 0x460) & 0x3300; 80 if (reg_v == 0x2200) 81 return NVKM_PCIE_SPEED_5_0; 82 return NVKM_PCIE_SPEED_2_5; 83 } 84 85 void 86 g84_pcie_set_link_speed(struct nvkm_pci *pci, enum nvkm_pcie_speed speed) 87 { 88 u32 mask_value; 89 90 if (speed == NVKM_PCIE_SPEED_5_0) 91 mask_value = 0x20; 92 else 93 mask_value = 0x10; 94 95 nvkm_pci_mask(pci, 0x460, 0x30, mask_value); 96 nvkm_pci_mask(pci, 0x460, 0x1, 0x1); 97 } 98 99 int 100 g84_pcie_set_link(struct nvkm_pci *pci, enum nvkm_pcie_speed speed, u8 width) 101 { 102 g84_pcie_set_cap_speed(pci, speed == NVKM_PCIE_SPEED_5_0); 103 g84_pcie_set_link_speed(pci, speed); 104 return 0; 105 } 106 107 void 108 g84_pci_init(struct nvkm_pci *pci) 109 { 110 /* The following only concerns PCIe cards. */ 111 if (!pci_is_pcie(pci->pdev)) 112 return; 113 114 /* Tag field is 8-bit long, regardless of EXT_TAG. 115 * However, if EXT_TAG is disabled, only the lower 5 bits of the tag 116 * field should be used, limiting the number of request to 32. 117 * 118 * Apparently, 0x041c stores some limit on the number of requests 119 * possible, so if EXT_TAG is disabled, limit that requests number to 120 * 32 121 * 122 * Fixes fdo#86537 123 */ 124 if (nvkm_pci_rd32(pci, 0x007c) & 0x00000020) 125 nvkm_pci_mask(pci, 0x0080, 0x00000100, 0x00000100); 126 else 127 nvkm_pci_mask(pci, 0x041c, 0x00000060, 0x00000000); 128 } 129 130 int 131 g84_pcie_init(struct nvkm_pci *pci) 132 { 133 bool full_speed = g84_pcie_cur_speed(pci) == NVKM_PCIE_SPEED_5_0; 134 g84_pcie_set_cap_speed(pci, full_speed); 135 return 0; 136 } 137 138 static const struct nvkm_pci_func 139 g84_pci_func = { 140 .init = g84_pci_init, 141 .rd32 = nv40_pci_rd32, 142 .wr08 = nv40_pci_wr08, 143 .wr32 = nv40_pci_wr32, 144 .msi_rearm = nv46_pci_msi_rearm, 145 146 .pcie.init = g84_pcie_init, 147 .pcie.set_link = g84_pcie_set_link, 148 149 .pcie.max_speed = g84_pcie_max_speed, 150 .pcie.cur_speed = g84_pcie_cur_speed, 151 152 .pcie.set_version = g84_pcie_set_version, 153 .pcie.version = g84_pcie_version, 154 .pcie.version_supported = g84_pcie_version_supported, 155 }; 156 157 int 158 g84_pci_new(struct nvkm_device *device, int index, struct nvkm_pci **ppci) 159 { 160 return nvkm_pci_new_(&g84_pci_func, device, index, ppci); 161 } 162