1 1.3 riastrad /* $NetBSD: radeon_trinity_dpm.c,v 1.3 2021/12/18 23:45:43 riastradh Exp $ */ 2 1.1 riastrad 3 1.1 riastrad /* 4 1.1 riastrad * Copyright 2012 Advanced Micro Devices, Inc. 5 1.1 riastrad * 6 1.1 riastrad * Permission is hereby granted, free of charge, to any person obtaining a 7 1.1 riastrad * copy of this software and associated documentation files (the "Software"), 8 1.1 riastrad * to deal in the Software without restriction, including without limitation 9 1.1 riastrad * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 1.1 riastrad * and/or sell copies of the Software, and to permit persons to whom the 11 1.1 riastrad * Software is furnished to do so, subject to the following conditions: 12 1.1 riastrad * 13 1.1 riastrad * The above copyright notice and this permission notice shall be included in 14 1.1 riastrad * all copies or substantial portions of the Software. 15 1.1 riastrad * 16 1.1 riastrad * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 1.1 riastrad * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 1.1 riastrad * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 1.1 riastrad * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 1.1 riastrad * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 1.1 riastrad * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 1.1 riastrad * OTHER DEALINGS IN THE SOFTWARE. 23 1.1 riastrad * 24 1.1 riastrad */ 25 1.1 riastrad 26 1.1 riastrad #include <sys/cdefs.h> 27 1.3 riastrad __KERNEL_RCSID(0, "$NetBSD: radeon_trinity_dpm.c,v 1.3 2021/12/18 23:45:43 riastradh Exp $"); 28 1.1 riastrad 29 1.3 riastrad #include <linux/pci.h> 30 1.3 riastrad #include <linux/seq_file.h> 31 1.3 riastrad 32 1.3 riastrad #include "r600_dpm.h" 33 1.1 riastrad #include "radeon.h" 34 1.1 riastrad #include "radeon_asic.h" 35 1.3 riastrad #include "trinity_dpm.h" 36 1.1 riastrad #include "trinityd.h" 37 1.1 riastrad 38 1.1 riastrad #define TRINITY_MAX_DEEPSLEEP_DIVIDER_ID 5 39 1.1 riastrad #define TRINITY_MINIMUM_ENGINE_CLOCK 800 40 1.1 riastrad #define SCLK_MIN_DIV_INTV_SHIFT 12 41 1.1 riastrad #define TRINITY_DISPCLK_BYPASS_THRESHOLD 10000 42 1.1 riastrad 43 1.1 riastrad #ifndef TRINITY_MGCG_SEQUENCE 44 1.1 riastrad #define TRINITY_MGCG_SEQUENCE 100 45 1.1 riastrad 46 1.1 riastrad static const u32 trinity_mgcg_shls_default[] = 47 1.1 riastrad { 48 1.1 riastrad /* Register, Value, Mask */ 49 1.1 riastrad 0x0000802c, 0xc0000000, 0xffffffff, 50 1.1 riastrad 0x00003fc4, 0xc0000000, 0xffffffff, 51 1.1 riastrad 0x00005448, 0x00000100, 0xffffffff, 52 1.1 riastrad 0x000055e4, 0x00000100, 0xffffffff, 53 1.1 riastrad 0x0000160c, 0x00000100, 0xffffffff, 54 1.1 riastrad 0x00008984, 0x06000100, 0xffffffff, 55 1.1 riastrad 0x0000c164, 0x00000100, 0xffffffff, 56 1.1 riastrad 0x00008a18, 0x00000100, 0xffffffff, 57 1.1 riastrad 0x0000897c, 0x06000100, 0xffffffff, 58 1.1 riastrad 0x00008b28, 0x00000100, 0xffffffff, 59 1.1 riastrad 0x00009144, 0x00800200, 0xffffffff, 60 1.1 riastrad 0x00009a60, 0x00000100, 0xffffffff, 61 1.1 riastrad 0x00009868, 0x00000100, 0xffffffff, 62 1.1 riastrad 0x00008d58, 0x00000100, 0xffffffff, 63 1.1 riastrad 0x00009510, 0x00000100, 0xffffffff, 64 1.1 riastrad 0x0000949c, 0x00000100, 0xffffffff, 65 1.1 riastrad 0x00009654, 0x00000100, 0xffffffff, 66 1.1 riastrad 0x00009030, 0x00000100, 0xffffffff, 67 1.1 riastrad 0x00009034, 0x00000100, 0xffffffff, 68 1.1 riastrad 0x00009038, 0x00000100, 0xffffffff, 69 1.1 riastrad 0x0000903c, 0x00000100, 0xffffffff, 70 1.1 riastrad 0x00009040, 0x00000100, 0xffffffff, 71 1.1 riastrad 0x0000a200, 0x00000100, 0xffffffff, 72 1.1 riastrad 0x0000a204, 0x00000100, 0xffffffff, 73 1.1 riastrad 0x0000a208, 0x00000100, 0xffffffff, 74 1.1 riastrad 0x0000a20c, 0x00000100, 0xffffffff, 75 1.1 riastrad 0x00009744, 0x00000100, 0xffffffff, 76 1.1 riastrad 0x00003f80, 0x00000100, 0xffffffff, 77 1.1 riastrad 0x0000a210, 0x00000100, 0xffffffff, 78 1.1 riastrad 0x0000a214, 0x00000100, 0xffffffff, 79 1.1 riastrad 0x000004d8, 0x00000100, 0xffffffff, 80 1.1 riastrad 0x00009664, 0x00000100, 0xffffffff, 81 1.1 riastrad 0x00009698, 0x00000100, 0xffffffff, 82 1.1 riastrad 0x000004d4, 0x00000200, 0xffffffff, 83 1.1 riastrad 0x000004d0, 0x00000000, 0xffffffff, 84 1.1 riastrad 0x000030cc, 0x00000104, 0xffffffff, 85 1.1 riastrad 0x0000d0c0, 0x00000100, 0xffffffff, 86 1.1 riastrad 0x0000d8c0, 0x00000100, 0xffffffff, 87 1.1 riastrad 0x0000951c, 0x00010000, 0xffffffff, 88 1.1 riastrad 0x00009160, 0x00030002, 0xffffffff, 89 1.1 riastrad 0x00009164, 0x00050004, 0xffffffff, 90 1.1 riastrad 0x00009168, 0x00070006, 0xffffffff, 91 1.1 riastrad 0x00009178, 0x00070000, 0xffffffff, 92 1.1 riastrad 0x0000917c, 0x00030002, 0xffffffff, 93 1.1 riastrad 0x00009180, 0x00050004, 0xffffffff, 94 1.1 riastrad 0x0000918c, 0x00010006, 0xffffffff, 95 1.1 riastrad 0x00009190, 0x00090008, 0xffffffff, 96 1.1 riastrad 0x00009194, 0x00070000, 0xffffffff, 97 1.1 riastrad 0x00009198, 0x00030002, 0xffffffff, 98 1.1 riastrad 0x0000919c, 0x00050004, 0xffffffff, 99 1.1 riastrad 0x000091a8, 0x00010006, 0xffffffff, 100 1.1 riastrad 0x000091ac, 0x00090008, 0xffffffff, 101 1.1 riastrad 0x000091b0, 0x00070000, 0xffffffff, 102 1.1 riastrad 0x000091b4, 0x00030002, 0xffffffff, 103 1.1 riastrad 0x000091b8, 0x00050004, 0xffffffff, 104 1.1 riastrad 0x000091c4, 0x00010006, 0xffffffff, 105 1.1 riastrad 0x000091c8, 0x00090008, 0xffffffff, 106 1.1 riastrad 0x000091cc, 0x00070000, 0xffffffff, 107 1.1 riastrad 0x000091d0, 0x00030002, 0xffffffff, 108 1.1 riastrad 0x000091d4, 0x00050004, 0xffffffff, 109 1.1 riastrad 0x000091e0, 0x00010006, 0xffffffff, 110 1.1 riastrad 0x000091e4, 0x00090008, 0xffffffff, 111 1.1 riastrad 0x000091e8, 0x00000000, 0xffffffff, 112 1.1 riastrad 0x000091ec, 0x00070000, 0xffffffff, 113 1.1 riastrad 0x000091f0, 0x00030002, 0xffffffff, 114 1.1 riastrad 0x000091f4, 0x00050004, 0xffffffff, 115 1.1 riastrad 0x00009200, 0x00010006, 0xffffffff, 116 1.1 riastrad 0x00009204, 0x00090008, 0xffffffff, 117 1.1 riastrad 0x00009208, 0x00070000, 0xffffffff, 118 1.1 riastrad 0x0000920c, 0x00030002, 0xffffffff, 119 1.1 riastrad 0x00009210, 0x00050004, 0xffffffff, 120 1.1 riastrad 0x0000921c, 0x00010006, 0xffffffff, 121 1.1 riastrad 0x00009220, 0x00090008, 0xffffffff, 122 1.1 riastrad 0x00009294, 0x00000000, 0xffffffff 123 1.1 riastrad }; 124 1.1 riastrad 125 1.1 riastrad static const u32 trinity_mgcg_shls_enable[] = 126 1.1 riastrad { 127 1.1 riastrad /* Register, Value, Mask */ 128 1.1 riastrad 0x0000802c, 0xc0000000, 0xffffffff, 129 1.1 riastrad 0x000008f8, 0x00000000, 0xffffffff, 130 1.1 riastrad 0x000008fc, 0x00000000, 0x000133FF, 131 1.1 riastrad 0x000008f8, 0x00000001, 0xffffffff, 132 1.1 riastrad 0x000008fc, 0x00000000, 0xE00B03FC, 133 1.1 riastrad 0x00009150, 0x96944200, 0xffffffff 134 1.1 riastrad }; 135 1.1 riastrad 136 1.1 riastrad static const u32 trinity_mgcg_shls_disable[] = 137 1.1 riastrad { 138 1.1 riastrad /* Register, Value, Mask */ 139 1.1 riastrad 0x0000802c, 0xc0000000, 0xffffffff, 140 1.1 riastrad 0x00009150, 0x00600000, 0xffffffff, 141 1.1 riastrad 0x000008f8, 0x00000000, 0xffffffff, 142 1.1 riastrad 0x000008fc, 0xffffffff, 0x000133FF, 143 1.1 riastrad 0x000008f8, 0x00000001, 0xffffffff, 144 1.1 riastrad 0x000008fc, 0xffffffff, 0xE00B03FC 145 1.1 riastrad }; 146 1.1 riastrad #endif 147 1.1 riastrad 148 1.1 riastrad #ifndef TRINITY_SYSLS_SEQUENCE 149 1.1 riastrad #define TRINITY_SYSLS_SEQUENCE 100 150 1.1 riastrad 151 1.1 riastrad static const u32 trinity_sysls_default[] = 152 1.1 riastrad { 153 1.1 riastrad /* Register, Value, Mask */ 154 1.1 riastrad 0x000055e8, 0x00000000, 0xffffffff, 155 1.1 riastrad 0x0000d0bc, 0x00000000, 0xffffffff, 156 1.1 riastrad 0x0000d8bc, 0x00000000, 0xffffffff, 157 1.1 riastrad 0x000015c0, 0x000c1401, 0xffffffff, 158 1.1 riastrad 0x0000264c, 0x000c0400, 0xffffffff, 159 1.1 riastrad 0x00002648, 0x000c0400, 0xffffffff, 160 1.1 riastrad 0x00002650, 0x000c0400, 0xffffffff, 161 1.1 riastrad 0x000020b8, 0x000c0400, 0xffffffff, 162 1.1 riastrad 0x000020bc, 0x000c0400, 0xffffffff, 163 1.1 riastrad 0x000020c0, 0x000c0c80, 0xffffffff, 164 1.1 riastrad 0x0000f4a0, 0x000000c0, 0xffffffff, 165 1.1 riastrad 0x0000f4a4, 0x00680fff, 0xffffffff, 166 1.1 riastrad 0x00002f50, 0x00000404, 0xffffffff, 167 1.1 riastrad 0x000004c8, 0x00000001, 0xffffffff, 168 1.1 riastrad 0x0000641c, 0x00000000, 0xffffffff, 169 1.1 riastrad 0x00000c7c, 0x00000000, 0xffffffff, 170 1.1 riastrad 0x00006dfc, 0x00000000, 0xffffffff 171 1.1 riastrad }; 172 1.1 riastrad 173 1.1 riastrad static const u32 trinity_sysls_disable[] = 174 1.1 riastrad { 175 1.1 riastrad /* Register, Value, Mask */ 176 1.1 riastrad 0x0000d0c0, 0x00000000, 0xffffffff, 177 1.1 riastrad 0x0000d8c0, 0x00000000, 0xffffffff, 178 1.1 riastrad 0x000055e8, 0x00000000, 0xffffffff, 179 1.1 riastrad 0x0000d0bc, 0x00000000, 0xffffffff, 180 1.1 riastrad 0x0000d8bc, 0x00000000, 0xffffffff, 181 1.1 riastrad 0x000015c0, 0x00041401, 0xffffffff, 182 1.1 riastrad 0x0000264c, 0x00040400, 0xffffffff, 183 1.1 riastrad 0x00002648, 0x00040400, 0xffffffff, 184 1.1 riastrad 0x00002650, 0x00040400, 0xffffffff, 185 1.1 riastrad 0x000020b8, 0x00040400, 0xffffffff, 186 1.1 riastrad 0x000020bc, 0x00040400, 0xffffffff, 187 1.1 riastrad 0x000020c0, 0x00040c80, 0xffffffff, 188 1.1 riastrad 0x0000f4a0, 0x000000c0, 0xffffffff, 189 1.1 riastrad 0x0000f4a4, 0x00680000, 0xffffffff, 190 1.1 riastrad 0x00002f50, 0x00000404, 0xffffffff, 191 1.1 riastrad 0x000004c8, 0x00000001, 0xffffffff, 192 1.1 riastrad 0x0000641c, 0x00007ffd, 0xffffffff, 193 1.1 riastrad 0x00000c7c, 0x0000ff00, 0xffffffff, 194 1.1 riastrad 0x00006dfc, 0x0000007f, 0xffffffff 195 1.1 riastrad }; 196 1.1 riastrad 197 1.1 riastrad static const u32 trinity_sysls_enable[] = 198 1.1 riastrad { 199 1.1 riastrad /* Register, Value, Mask */ 200 1.1 riastrad 0x000055e8, 0x00000001, 0xffffffff, 201 1.1 riastrad 0x0000d0bc, 0x00000100, 0xffffffff, 202 1.1 riastrad 0x0000d8bc, 0x00000100, 0xffffffff, 203 1.1 riastrad 0x000015c0, 0x000c1401, 0xffffffff, 204 1.1 riastrad 0x0000264c, 0x000c0400, 0xffffffff, 205 1.1 riastrad 0x00002648, 0x000c0400, 0xffffffff, 206 1.1 riastrad 0x00002650, 0x000c0400, 0xffffffff, 207 1.1 riastrad 0x000020b8, 0x000c0400, 0xffffffff, 208 1.1 riastrad 0x000020bc, 0x000c0400, 0xffffffff, 209 1.1 riastrad 0x000020c0, 0x000c0c80, 0xffffffff, 210 1.1 riastrad 0x0000f4a0, 0x000000c0, 0xffffffff, 211 1.1 riastrad 0x0000f4a4, 0x00680fff, 0xffffffff, 212 1.1 riastrad 0x00002f50, 0x00000903, 0xffffffff, 213 1.1 riastrad 0x000004c8, 0x00000000, 0xffffffff, 214 1.1 riastrad 0x0000641c, 0x00000000, 0xffffffff, 215 1.1 riastrad 0x00000c7c, 0x00000000, 0xffffffff, 216 1.1 riastrad 0x00006dfc, 0x00000000, 0xffffffff 217 1.1 riastrad }; 218 1.1 riastrad #endif 219 1.1 riastrad 220 1.1 riastrad static const u32 trinity_override_mgpg_sequences[] = 221 1.1 riastrad { 222 1.1 riastrad /* Register, Value */ 223 1.1 riastrad 0x00000200, 0xE030032C, 224 1.1 riastrad 0x00000204, 0x00000FFF, 225 1.1 riastrad 0x00000200, 0xE0300058, 226 1.1 riastrad 0x00000204, 0x00030301, 227 1.1 riastrad 0x00000200, 0xE0300054, 228 1.1 riastrad 0x00000204, 0x500010FF, 229 1.1 riastrad 0x00000200, 0xE0300074, 230 1.1 riastrad 0x00000204, 0x00030301, 231 1.1 riastrad 0x00000200, 0xE0300070, 232 1.1 riastrad 0x00000204, 0x500010FF, 233 1.1 riastrad 0x00000200, 0xE0300090, 234 1.1 riastrad 0x00000204, 0x00030301, 235 1.1 riastrad 0x00000200, 0xE030008C, 236 1.1 riastrad 0x00000204, 0x500010FF, 237 1.1 riastrad 0x00000200, 0xE03000AC, 238 1.1 riastrad 0x00000204, 0x00030301, 239 1.1 riastrad 0x00000200, 0xE03000A8, 240 1.1 riastrad 0x00000204, 0x500010FF, 241 1.1 riastrad 0x00000200, 0xE03000C8, 242 1.1 riastrad 0x00000204, 0x00030301, 243 1.1 riastrad 0x00000200, 0xE03000C4, 244 1.1 riastrad 0x00000204, 0x500010FF, 245 1.1 riastrad 0x00000200, 0xE03000E4, 246 1.1 riastrad 0x00000204, 0x00030301, 247 1.1 riastrad 0x00000200, 0xE03000E0, 248 1.1 riastrad 0x00000204, 0x500010FF, 249 1.1 riastrad 0x00000200, 0xE0300100, 250 1.1 riastrad 0x00000204, 0x00030301, 251 1.1 riastrad 0x00000200, 0xE03000FC, 252 1.1 riastrad 0x00000204, 0x500010FF, 253 1.1 riastrad 0x00000200, 0xE0300058, 254 1.1 riastrad 0x00000204, 0x00030303, 255 1.1 riastrad 0x00000200, 0xE0300054, 256 1.1 riastrad 0x00000204, 0x600010FF, 257 1.1 riastrad 0x00000200, 0xE0300074, 258 1.1 riastrad 0x00000204, 0x00030303, 259 1.1 riastrad 0x00000200, 0xE0300070, 260 1.1 riastrad 0x00000204, 0x600010FF, 261 1.1 riastrad 0x00000200, 0xE0300090, 262 1.1 riastrad 0x00000204, 0x00030303, 263 1.1 riastrad 0x00000200, 0xE030008C, 264 1.1 riastrad 0x00000204, 0x600010FF, 265 1.1 riastrad 0x00000200, 0xE03000AC, 266 1.1 riastrad 0x00000204, 0x00030303, 267 1.1 riastrad 0x00000200, 0xE03000A8, 268 1.1 riastrad 0x00000204, 0x600010FF, 269 1.1 riastrad 0x00000200, 0xE03000C8, 270 1.1 riastrad 0x00000204, 0x00030303, 271 1.1 riastrad 0x00000200, 0xE03000C4, 272 1.1 riastrad 0x00000204, 0x600010FF, 273 1.1 riastrad 0x00000200, 0xE03000E4, 274 1.1 riastrad 0x00000204, 0x00030303, 275 1.1 riastrad 0x00000200, 0xE03000E0, 276 1.1 riastrad 0x00000204, 0x600010FF, 277 1.1 riastrad 0x00000200, 0xE0300100, 278 1.1 riastrad 0x00000204, 0x00030303, 279 1.1 riastrad 0x00000200, 0xE03000FC, 280 1.1 riastrad 0x00000204, 0x600010FF, 281 1.1 riastrad 0x00000200, 0xE0300058, 282 1.1 riastrad 0x00000204, 0x00030303, 283 1.1 riastrad 0x00000200, 0xE0300054, 284 1.1 riastrad 0x00000204, 0x700010FF, 285 1.1 riastrad 0x00000200, 0xE0300074, 286 1.1 riastrad 0x00000204, 0x00030303, 287 1.1 riastrad 0x00000200, 0xE0300070, 288 1.1 riastrad 0x00000204, 0x700010FF, 289 1.1 riastrad 0x00000200, 0xE0300090, 290 1.1 riastrad 0x00000204, 0x00030303, 291 1.1 riastrad 0x00000200, 0xE030008C, 292 1.1 riastrad 0x00000204, 0x700010FF, 293 1.1 riastrad 0x00000200, 0xE03000AC, 294 1.1 riastrad 0x00000204, 0x00030303, 295 1.1 riastrad 0x00000200, 0xE03000A8, 296 1.1 riastrad 0x00000204, 0x700010FF, 297 1.1 riastrad 0x00000200, 0xE03000C8, 298 1.1 riastrad 0x00000204, 0x00030303, 299 1.1 riastrad 0x00000200, 0xE03000C4, 300 1.1 riastrad 0x00000204, 0x700010FF, 301 1.1 riastrad 0x00000200, 0xE03000E4, 302 1.1 riastrad 0x00000204, 0x00030303, 303 1.1 riastrad 0x00000200, 0xE03000E0, 304 1.1 riastrad 0x00000204, 0x700010FF, 305 1.1 riastrad 0x00000200, 0xE0300100, 306 1.1 riastrad 0x00000204, 0x00030303, 307 1.1 riastrad 0x00000200, 0xE03000FC, 308 1.1 riastrad 0x00000204, 0x700010FF, 309 1.1 riastrad 0x00000200, 0xE0300058, 310 1.1 riastrad 0x00000204, 0x00010303, 311 1.1 riastrad 0x00000200, 0xE0300054, 312 1.1 riastrad 0x00000204, 0x800010FF, 313 1.1 riastrad 0x00000200, 0xE0300074, 314 1.1 riastrad 0x00000204, 0x00010303, 315 1.1 riastrad 0x00000200, 0xE0300070, 316 1.1 riastrad 0x00000204, 0x800010FF, 317 1.1 riastrad 0x00000200, 0xE0300090, 318 1.1 riastrad 0x00000204, 0x00010303, 319 1.1 riastrad 0x00000200, 0xE030008C, 320 1.1 riastrad 0x00000204, 0x800010FF, 321 1.1 riastrad 0x00000200, 0xE03000AC, 322 1.1 riastrad 0x00000204, 0x00010303, 323 1.1 riastrad 0x00000200, 0xE03000A8, 324 1.1 riastrad 0x00000204, 0x800010FF, 325 1.1 riastrad 0x00000200, 0xE03000C4, 326 1.1 riastrad 0x00000204, 0x800010FF, 327 1.1 riastrad 0x00000200, 0xE03000C8, 328 1.1 riastrad 0x00000204, 0x00010303, 329 1.1 riastrad 0x00000200, 0xE03000E4, 330 1.1 riastrad 0x00000204, 0x00010303, 331 1.1 riastrad 0x00000200, 0xE03000E0, 332 1.1 riastrad 0x00000204, 0x800010FF, 333 1.1 riastrad 0x00000200, 0xE0300100, 334 1.1 riastrad 0x00000204, 0x00010303, 335 1.1 riastrad 0x00000200, 0xE03000FC, 336 1.1 riastrad 0x00000204, 0x800010FF, 337 1.1 riastrad 0x00000200, 0x0001f198, 338 1.1 riastrad 0x00000204, 0x0003ffff, 339 1.1 riastrad 0x00000200, 0x0001f19C, 340 1.1 riastrad 0x00000204, 0x3fffffff, 341 1.1 riastrad 0x00000200, 0xE030032C, 342 1.1 riastrad 0x00000204, 0x00000000, 343 1.1 riastrad }; 344 1.1 riastrad 345 1.1 riastrad extern void vce_v1_0_enable_mgcg(struct radeon_device *rdev, bool enable); 346 1.1 riastrad static void trinity_program_clk_gating_hw_sequence(struct radeon_device *rdev, 347 1.1 riastrad const u32 *seq, u32 count); 348 1.1 riastrad static void trinity_override_dynamic_mg_powergating(struct radeon_device *rdev); 349 1.1 riastrad static void trinity_apply_state_adjust_rules(struct radeon_device *rdev, 350 1.1 riastrad struct radeon_ps *new_rps, 351 1.1 riastrad struct radeon_ps *old_rps); 352 1.1 riastrad 353 1.1 riastrad static struct trinity_ps *trinity_get_ps(struct radeon_ps *rps) 354 1.1 riastrad { 355 1.1 riastrad struct trinity_ps *ps = rps->ps_priv; 356 1.1 riastrad 357 1.1 riastrad return ps; 358 1.1 riastrad } 359 1.1 riastrad 360 1.1 riastrad static struct trinity_power_info *trinity_get_pi(struct radeon_device *rdev) 361 1.1 riastrad { 362 1.1 riastrad struct trinity_power_info *pi = rdev->pm.dpm.priv; 363 1.1 riastrad 364 1.1 riastrad return pi; 365 1.1 riastrad } 366 1.1 riastrad 367 1.1 riastrad static void trinity_gfx_powergating_initialize(struct radeon_device *rdev) 368 1.1 riastrad { 369 1.1 riastrad struct trinity_power_info *pi = trinity_get_pi(rdev); 370 1.1 riastrad u32 p, u; 371 1.1 riastrad u32 value; 372 1.1 riastrad struct atom_clock_dividers dividers; 373 1.1 riastrad u32 xclk = radeon_get_xclk(rdev); 374 1.1 riastrad u32 sssd = 1; 375 1.1 riastrad int ret; 376 1.1 riastrad u32 hw_rev = (RREG32(HW_REV) & ATI_REV_ID_MASK) >> ATI_REV_ID_SHIFT; 377 1.1 riastrad 378 1.3 riastrad ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM, 379 1.3 riastrad 25000, false, ÷rs); 380 1.1 riastrad if (ret) 381 1.1 riastrad return; 382 1.1 riastrad 383 1.1 riastrad value = RREG32_SMC(GFX_POWER_GATING_CNTL); 384 1.1 riastrad value &= ~(SSSD_MASK | PDS_DIV_MASK); 385 1.1 riastrad if (sssd) 386 1.1 riastrad value |= SSSD(1); 387 1.1 riastrad value |= PDS_DIV(dividers.post_div); 388 1.1 riastrad WREG32_SMC(GFX_POWER_GATING_CNTL, value); 389 1.1 riastrad 390 1.1 riastrad r600_calculate_u_and_p(500, xclk, 16, &p, &u); 391 1.1 riastrad 392 1.1 riastrad WREG32(CG_PG_CTRL, SP(p) | SU(u)); 393 1.1 riastrad 394 1.1 riastrad WREG32_P(CG_GIPOTS, CG_GIPOT(p), ~CG_GIPOT_MASK); 395 1.1 riastrad 396 1.1 riastrad /* XXX double check hw_rev */ 397 1.1 riastrad if (pi->override_dynamic_mgpg && (hw_rev == 0)) 398 1.1 riastrad trinity_override_dynamic_mg_powergating(rdev); 399 1.1 riastrad 400 1.1 riastrad } 401 1.1 riastrad 402 1.1 riastrad #define CGCG_CGTT_LOCAL0_MASK 0xFFFF33FF 403 1.1 riastrad #define CGCG_CGTT_LOCAL1_MASK 0xFFFB0FFE 404 1.1 riastrad #define CGTS_SM_CTRL_REG_DISABLE 0x00600000 405 1.1 riastrad #define CGTS_SM_CTRL_REG_ENABLE 0x96944200 406 1.1 riastrad 407 1.1 riastrad static void trinity_mg_clockgating_enable(struct radeon_device *rdev, 408 1.1 riastrad bool enable) 409 1.1 riastrad { 410 1.1 riastrad u32 local0; 411 1.1 riastrad u32 local1; 412 1.1 riastrad 413 1.1 riastrad if (enable) { 414 1.1 riastrad local0 = RREG32_CG(CG_CGTT_LOCAL_0); 415 1.1 riastrad local1 = RREG32_CG(CG_CGTT_LOCAL_1); 416 1.1 riastrad 417 1.1 riastrad WREG32_CG(CG_CGTT_LOCAL_0, 418 1.1 riastrad (0x00380000 & CGCG_CGTT_LOCAL0_MASK) | (local0 & ~CGCG_CGTT_LOCAL0_MASK) ); 419 1.1 riastrad WREG32_CG(CG_CGTT_LOCAL_1, 420 1.1 riastrad (0x0E000000 & CGCG_CGTT_LOCAL1_MASK) | (local1 & ~CGCG_CGTT_LOCAL1_MASK) ); 421 1.1 riastrad 422 1.1 riastrad WREG32(CGTS_SM_CTRL_REG, CGTS_SM_CTRL_REG_ENABLE); 423 1.1 riastrad } else { 424 1.1 riastrad WREG32(CGTS_SM_CTRL_REG, CGTS_SM_CTRL_REG_DISABLE); 425 1.1 riastrad 426 1.1 riastrad local0 = RREG32_CG(CG_CGTT_LOCAL_0); 427 1.1 riastrad local1 = RREG32_CG(CG_CGTT_LOCAL_1); 428 1.1 riastrad 429 1.1 riastrad WREG32_CG(CG_CGTT_LOCAL_0, 430 1.1 riastrad CGCG_CGTT_LOCAL0_MASK | (local0 & ~CGCG_CGTT_LOCAL0_MASK) ); 431 1.1 riastrad WREG32_CG(CG_CGTT_LOCAL_1, 432 1.1 riastrad CGCG_CGTT_LOCAL1_MASK | (local1 & ~CGCG_CGTT_LOCAL1_MASK) ); 433 1.1 riastrad } 434 1.1 riastrad } 435 1.1 riastrad 436 1.1 riastrad static void trinity_mg_clockgating_initialize(struct radeon_device *rdev) 437 1.1 riastrad { 438 1.1 riastrad u32 count; 439 1.1 riastrad const u32 *seq = NULL; 440 1.1 riastrad 441 1.1 riastrad seq = &trinity_mgcg_shls_default[0]; 442 1.1 riastrad count = sizeof(trinity_mgcg_shls_default) / (3 * sizeof(u32)); 443 1.1 riastrad 444 1.1 riastrad trinity_program_clk_gating_hw_sequence(rdev, seq, count); 445 1.1 riastrad } 446 1.1 riastrad 447 1.1 riastrad static void trinity_gfx_clockgating_enable(struct radeon_device *rdev, 448 1.1 riastrad bool enable) 449 1.1 riastrad { 450 1.1 riastrad if (enable) { 451 1.1 riastrad WREG32_P(SCLK_PWRMGT_CNTL, DYN_GFX_CLK_OFF_EN, ~DYN_GFX_CLK_OFF_EN); 452 1.1 riastrad } else { 453 1.1 riastrad WREG32_P(SCLK_PWRMGT_CNTL, 0, ~DYN_GFX_CLK_OFF_EN); 454 1.1 riastrad WREG32_P(SCLK_PWRMGT_CNTL, GFX_CLK_FORCE_ON, ~GFX_CLK_FORCE_ON); 455 1.1 riastrad WREG32_P(SCLK_PWRMGT_CNTL, 0, ~GFX_CLK_FORCE_ON); 456 1.1 riastrad RREG32(GB_ADDR_CONFIG); 457 1.1 riastrad } 458 1.1 riastrad } 459 1.1 riastrad 460 1.1 riastrad static void trinity_program_clk_gating_hw_sequence(struct radeon_device *rdev, 461 1.1 riastrad const u32 *seq, u32 count) 462 1.1 riastrad { 463 1.1 riastrad u32 i, length = count * 3; 464 1.1 riastrad 465 1.1 riastrad for (i = 0; i < length; i += 3) 466 1.1 riastrad WREG32_P(seq[i], seq[i+1], ~seq[i+2]); 467 1.1 riastrad } 468 1.1 riastrad 469 1.1 riastrad static void trinity_program_override_mgpg_sequences(struct radeon_device *rdev, 470 1.1 riastrad const u32 *seq, u32 count) 471 1.1 riastrad { 472 1.1 riastrad u32 i, length = count * 2; 473 1.1 riastrad 474 1.1 riastrad for (i = 0; i < length; i += 2) 475 1.1 riastrad WREG32(seq[i], seq[i+1]); 476 1.1 riastrad 477 1.1 riastrad } 478 1.1 riastrad 479 1.1 riastrad static void trinity_override_dynamic_mg_powergating(struct radeon_device *rdev) 480 1.1 riastrad { 481 1.1 riastrad u32 count; 482 1.1 riastrad const u32 *seq = NULL; 483 1.1 riastrad 484 1.1 riastrad seq = &trinity_override_mgpg_sequences[0]; 485 1.1 riastrad count = sizeof(trinity_override_mgpg_sequences) / (2 * sizeof(u32)); 486 1.1 riastrad 487 1.1 riastrad trinity_program_override_mgpg_sequences(rdev, seq, count); 488 1.1 riastrad } 489 1.1 riastrad 490 1.1 riastrad static void trinity_ls_clockgating_enable(struct radeon_device *rdev, 491 1.1 riastrad bool enable) 492 1.1 riastrad { 493 1.1 riastrad u32 count; 494 1.1 riastrad const u32 *seq = NULL; 495 1.1 riastrad 496 1.1 riastrad if (enable) { 497 1.1 riastrad seq = &trinity_sysls_enable[0]; 498 1.1 riastrad count = sizeof(trinity_sysls_enable) / (3 * sizeof(u32)); 499 1.1 riastrad } else { 500 1.1 riastrad seq = &trinity_sysls_disable[0]; 501 1.1 riastrad count = sizeof(trinity_sysls_disable) / (3 * sizeof(u32)); 502 1.1 riastrad } 503 1.1 riastrad 504 1.1 riastrad trinity_program_clk_gating_hw_sequence(rdev, seq, count); 505 1.1 riastrad } 506 1.1 riastrad 507 1.1 riastrad static void trinity_gfx_powergating_enable(struct radeon_device *rdev, 508 1.1 riastrad bool enable) 509 1.1 riastrad { 510 1.1 riastrad if (enable) { 511 1.1 riastrad if (RREG32_SMC(CC_SMU_TST_EFUSE1_MISC) & RB_BACKEND_DISABLE_MASK) 512 1.1 riastrad WREG32_SMC(SMU_SCRATCH_A, (RREG32_SMC(SMU_SCRATCH_A) | 0x01)); 513 1.1 riastrad 514 1.1 riastrad WREG32_P(SCLK_PWRMGT_CNTL, DYN_PWR_DOWN_EN, ~DYN_PWR_DOWN_EN); 515 1.1 riastrad } else { 516 1.1 riastrad WREG32_P(SCLK_PWRMGT_CNTL, 0, ~DYN_PWR_DOWN_EN); 517 1.1 riastrad RREG32(GB_ADDR_CONFIG); 518 1.1 riastrad } 519 1.1 riastrad } 520 1.1 riastrad 521 1.1 riastrad static void trinity_gfx_dynamic_mgpg_enable(struct radeon_device *rdev, 522 1.1 riastrad bool enable) 523 1.1 riastrad { 524 1.1 riastrad u32 value; 525 1.1 riastrad 526 1.1 riastrad if (enable) { 527 1.1 riastrad value = RREG32_SMC(PM_I_CNTL_1); 528 1.1 riastrad value &= ~DS_PG_CNTL_MASK; 529 1.1 riastrad value |= DS_PG_CNTL(1); 530 1.1 riastrad WREG32_SMC(PM_I_CNTL_1, value); 531 1.1 riastrad 532 1.1 riastrad value = RREG32_SMC(SMU_S_PG_CNTL); 533 1.1 riastrad value &= ~DS_PG_EN_MASK; 534 1.1 riastrad value |= DS_PG_EN(1); 535 1.1 riastrad WREG32_SMC(SMU_S_PG_CNTL, value); 536 1.1 riastrad } else { 537 1.1 riastrad value = RREG32_SMC(SMU_S_PG_CNTL); 538 1.1 riastrad value &= ~DS_PG_EN_MASK; 539 1.1 riastrad WREG32_SMC(SMU_S_PG_CNTL, value); 540 1.1 riastrad 541 1.1 riastrad value = RREG32_SMC(PM_I_CNTL_1); 542 1.1 riastrad value &= ~DS_PG_CNTL_MASK; 543 1.1 riastrad WREG32_SMC(PM_I_CNTL_1, value); 544 1.1 riastrad } 545 1.1 riastrad 546 1.1 riastrad trinity_gfx_dynamic_mgpg_config(rdev); 547 1.1 riastrad 548 1.1 riastrad } 549 1.1 riastrad 550 1.1 riastrad static void trinity_enable_clock_power_gating(struct radeon_device *rdev) 551 1.1 riastrad { 552 1.1 riastrad struct trinity_power_info *pi = trinity_get_pi(rdev); 553 1.1 riastrad 554 1.1 riastrad if (pi->enable_gfx_clock_gating) 555 1.1 riastrad sumo_gfx_clockgating_initialize(rdev); 556 1.1 riastrad if (pi->enable_mg_clock_gating) 557 1.1 riastrad trinity_mg_clockgating_initialize(rdev); 558 1.1 riastrad if (pi->enable_gfx_power_gating) 559 1.1 riastrad trinity_gfx_powergating_initialize(rdev); 560 1.1 riastrad if (pi->enable_mg_clock_gating) { 561 1.1 riastrad trinity_ls_clockgating_enable(rdev, true); 562 1.1 riastrad trinity_mg_clockgating_enable(rdev, true); 563 1.1 riastrad } 564 1.1 riastrad if (pi->enable_gfx_clock_gating) 565 1.1 riastrad trinity_gfx_clockgating_enable(rdev, true); 566 1.1 riastrad if (pi->enable_gfx_dynamic_mgpg) 567 1.1 riastrad trinity_gfx_dynamic_mgpg_enable(rdev, true); 568 1.1 riastrad if (pi->enable_gfx_power_gating) 569 1.1 riastrad trinity_gfx_powergating_enable(rdev, true); 570 1.1 riastrad } 571 1.1 riastrad 572 1.1 riastrad static void trinity_disable_clock_power_gating(struct radeon_device *rdev) 573 1.1 riastrad { 574 1.1 riastrad struct trinity_power_info *pi = trinity_get_pi(rdev); 575 1.1 riastrad 576 1.1 riastrad if (pi->enable_gfx_power_gating) 577 1.1 riastrad trinity_gfx_powergating_enable(rdev, false); 578 1.1 riastrad if (pi->enable_gfx_dynamic_mgpg) 579 1.1 riastrad trinity_gfx_dynamic_mgpg_enable(rdev, false); 580 1.1 riastrad if (pi->enable_gfx_clock_gating) 581 1.1 riastrad trinity_gfx_clockgating_enable(rdev, false); 582 1.1 riastrad if (pi->enable_mg_clock_gating) { 583 1.1 riastrad trinity_mg_clockgating_enable(rdev, false); 584 1.1 riastrad trinity_ls_clockgating_enable(rdev, false); 585 1.1 riastrad } 586 1.1 riastrad } 587 1.1 riastrad 588 1.1 riastrad static void trinity_set_divider_value(struct radeon_device *rdev, 589 1.1 riastrad u32 index, u32 sclk) 590 1.1 riastrad { 591 1.1 riastrad struct atom_clock_dividers dividers; 592 1.1 riastrad int ret; 593 1.1 riastrad u32 value; 594 1.1 riastrad u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE; 595 1.1 riastrad 596 1.3 riastrad ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM, 597 1.3 riastrad sclk, false, ÷rs); 598 1.1 riastrad if (ret) 599 1.1 riastrad return; 600 1.1 riastrad 601 1.1 riastrad value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_0 + ix); 602 1.1 riastrad value &= ~CLK_DIVIDER_MASK; 603 1.1 riastrad value |= CLK_DIVIDER(dividers.post_div); 604 1.1 riastrad WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_0 + ix, value); 605 1.1 riastrad 606 1.3 riastrad ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM, 607 1.3 riastrad sclk/2, false, ÷rs); 608 1.1 riastrad if (ret) 609 1.1 riastrad return; 610 1.1 riastrad 611 1.1 riastrad value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_PG_CNTL + ix); 612 1.1 riastrad value &= ~PD_SCLK_DIVIDER_MASK; 613 1.1 riastrad value |= PD_SCLK_DIVIDER(dividers.post_div); 614 1.1 riastrad WREG32_SMC(SMU_SCLK_DPM_STATE_0_PG_CNTL + ix, value); 615 1.1 riastrad } 616 1.1 riastrad 617 1.1 riastrad static void trinity_set_ds_dividers(struct radeon_device *rdev, 618 1.1 riastrad u32 index, u32 divider) 619 1.1 riastrad { 620 1.1 riastrad u32 value; 621 1.1 riastrad u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE; 622 1.1 riastrad 623 1.1 riastrad value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_1 + ix); 624 1.1 riastrad value &= ~DS_DIV_MASK; 625 1.1 riastrad value |= DS_DIV(divider); 626 1.1 riastrad WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_1 + ix, value); 627 1.1 riastrad } 628 1.1 riastrad 629 1.1 riastrad static void trinity_set_ss_dividers(struct radeon_device *rdev, 630 1.1 riastrad u32 index, u32 divider) 631 1.1 riastrad { 632 1.1 riastrad u32 value; 633 1.1 riastrad u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE; 634 1.1 riastrad 635 1.1 riastrad value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_1 + ix); 636 1.1 riastrad value &= ~DS_SH_DIV_MASK; 637 1.1 riastrad value |= DS_SH_DIV(divider); 638 1.1 riastrad WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_1 + ix, value); 639 1.1 riastrad } 640 1.1 riastrad 641 1.1 riastrad static void trinity_set_vid(struct radeon_device *rdev, u32 index, u32 vid) 642 1.1 riastrad { 643 1.1 riastrad struct trinity_power_info *pi = trinity_get_pi(rdev); 644 1.1 riastrad u32 vid_7bit = sumo_convert_vid2_to_vid7(rdev, &pi->sys_info.vid_mapping_table, vid); 645 1.1 riastrad u32 value; 646 1.1 riastrad u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE; 647 1.1 riastrad 648 1.1 riastrad value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_0 + ix); 649 1.1 riastrad value &= ~VID_MASK; 650 1.1 riastrad value |= VID(vid_7bit); 651 1.1 riastrad WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_0 + ix, value); 652 1.1 riastrad 653 1.1 riastrad value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_0 + ix); 654 1.1 riastrad value &= ~LVRT_MASK; 655 1.1 riastrad value |= LVRT(0); 656 1.1 riastrad WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_0 + ix, value); 657 1.1 riastrad } 658 1.1 riastrad 659 1.1 riastrad static void trinity_set_allos_gnb_slow(struct radeon_device *rdev, 660 1.1 riastrad u32 index, u32 gnb_slow) 661 1.1 riastrad { 662 1.1 riastrad u32 value; 663 1.1 riastrad u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE; 664 1.1 riastrad 665 1.1 riastrad value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_3 + ix); 666 1.1 riastrad value &= ~GNB_SLOW_MASK; 667 1.1 riastrad value |= GNB_SLOW(gnb_slow); 668 1.1 riastrad WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_3 + ix, value); 669 1.1 riastrad } 670 1.1 riastrad 671 1.1 riastrad static void trinity_set_force_nbp_state(struct radeon_device *rdev, 672 1.1 riastrad u32 index, u32 force_nbp_state) 673 1.1 riastrad { 674 1.1 riastrad u32 value; 675 1.1 riastrad u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE; 676 1.1 riastrad 677 1.1 riastrad value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_3 + ix); 678 1.1 riastrad value &= ~FORCE_NBPS1_MASK; 679 1.1 riastrad value |= FORCE_NBPS1(force_nbp_state); 680 1.1 riastrad WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_3 + ix, value); 681 1.1 riastrad } 682 1.1 riastrad 683 1.1 riastrad static void trinity_set_display_wm(struct radeon_device *rdev, 684 1.1 riastrad u32 index, u32 wm) 685 1.1 riastrad { 686 1.1 riastrad u32 value; 687 1.1 riastrad u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE; 688 1.1 riastrad 689 1.1 riastrad value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_1 + ix); 690 1.1 riastrad value &= ~DISPLAY_WM_MASK; 691 1.1 riastrad value |= DISPLAY_WM(wm); 692 1.1 riastrad WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_1 + ix, value); 693 1.1 riastrad } 694 1.1 riastrad 695 1.1 riastrad static void trinity_set_vce_wm(struct radeon_device *rdev, 696 1.1 riastrad u32 index, u32 wm) 697 1.1 riastrad { 698 1.1 riastrad u32 value; 699 1.1 riastrad u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE; 700 1.1 riastrad 701 1.1 riastrad value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_1 + ix); 702 1.1 riastrad value &= ~VCE_WM_MASK; 703 1.1 riastrad value |= VCE_WM(wm); 704 1.1 riastrad WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_1 + ix, value); 705 1.1 riastrad } 706 1.1 riastrad 707 1.1 riastrad static void trinity_set_at(struct radeon_device *rdev, 708 1.1 riastrad u32 index, u32 at) 709 1.1 riastrad { 710 1.1 riastrad u32 value; 711 1.1 riastrad u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE; 712 1.1 riastrad 713 1.1 riastrad value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_AT + ix); 714 1.1 riastrad value &= ~AT_MASK; 715 1.1 riastrad value |= AT(at); 716 1.1 riastrad WREG32_SMC(SMU_SCLK_DPM_STATE_0_AT + ix, value); 717 1.1 riastrad } 718 1.1 riastrad 719 1.1 riastrad static void trinity_program_power_level(struct radeon_device *rdev, 720 1.1 riastrad struct trinity_pl *pl, u32 index) 721 1.1 riastrad { 722 1.1 riastrad struct trinity_power_info *pi = trinity_get_pi(rdev); 723 1.1 riastrad 724 1.1 riastrad if (index >= SUMO_MAX_HARDWARE_POWERLEVELS) 725 1.1 riastrad return; 726 1.1 riastrad 727 1.1 riastrad trinity_set_divider_value(rdev, index, pl->sclk); 728 1.1 riastrad trinity_set_vid(rdev, index, pl->vddc_index); 729 1.1 riastrad trinity_set_ss_dividers(rdev, index, pl->ss_divider_index); 730 1.1 riastrad trinity_set_ds_dividers(rdev, index, pl->ds_divider_index); 731 1.1 riastrad trinity_set_allos_gnb_slow(rdev, index, pl->allow_gnb_slow); 732 1.1 riastrad trinity_set_force_nbp_state(rdev, index, pl->force_nbp_state); 733 1.1 riastrad trinity_set_display_wm(rdev, index, pl->display_wm); 734 1.1 riastrad trinity_set_vce_wm(rdev, index, pl->vce_wm); 735 1.1 riastrad trinity_set_at(rdev, index, pi->at[index]); 736 1.1 riastrad } 737 1.1 riastrad 738 1.1 riastrad static void trinity_power_level_enable_disable(struct radeon_device *rdev, 739 1.1 riastrad u32 index, bool enable) 740 1.1 riastrad { 741 1.1 riastrad u32 value; 742 1.1 riastrad u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE; 743 1.1 riastrad 744 1.1 riastrad value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_0 + ix); 745 1.1 riastrad value &= ~STATE_VALID_MASK; 746 1.1 riastrad if (enable) 747 1.1 riastrad value |= STATE_VALID(1); 748 1.1 riastrad WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_0 + ix, value); 749 1.1 riastrad } 750 1.1 riastrad 751 1.1 riastrad static bool trinity_dpm_enabled(struct radeon_device *rdev) 752 1.1 riastrad { 753 1.1 riastrad if (RREG32_SMC(SMU_SCLK_DPM_CNTL) & SCLK_DPM_EN(1)) 754 1.1 riastrad return true; 755 1.1 riastrad else 756 1.1 riastrad return false; 757 1.1 riastrad } 758 1.1 riastrad 759 1.1 riastrad static void trinity_start_dpm(struct radeon_device *rdev) 760 1.1 riastrad { 761 1.1 riastrad u32 value = RREG32_SMC(SMU_SCLK_DPM_CNTL); 762 1.1 riastrad 763 1.1 riastrad value &= ~(SCLK_DPM_EN_MASK | SCLK_DPM_BOOT_STATE_MASK | VOLTAGE_CHG_EN_MASK); 764 1.1 riastrad value |= SCLK_DPM_EN(1) | SCLK_DPM_BOOT_STATE(0) | VOLTAGE_CHG_EN(1); 765 1.1 riastrad WREG32_SMC(SMU_SCLK_DPM_CNTL, value); 766 1.1 riastrad 767 1.1 riastrad WREG32_P(GENERAL_PWRMGT, GLOBAL_PWRMGT_EN, ~GLOBAL_PWRMGT_EN); 768 1.1 riastrad WREG32_P(CG_CG_VOLTAGE_CNTL, 0, ~EN); 769 1.1 riastrad 770 1.1 riastrad trinity_dpm_config(rdev, true); 771 1.1 riastrad } 772 1.1 riastrad 773 1.1 riastrad static void trinity_wait_for_dpm_enabled(struct radeon_device *rdev) 774 1.1 riastrad { 775 1.1 riastrad int i; 776 1.1 riastrad 777 1.1 riastrad for (i = 0; i < rdev->usec_timeout; i++) { 778 1.1 riastrad if (RREG32(SCLK_PWRMGT_CNTL) & DYNAMIC_PM_EN) 779 1.1 riastrad break; 780 1.1 riastrad udelay(1); 781 1.1 riastrad } 782 1.1 riastrad for (i = 0; i < rdev->usec_timeout; i++) { 783 1.1 riastrad if ((RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & TARGET_STATE_MASK) == 0) 784 1.1 riastrad break; 785 1.1 riastrad udelay(1); 786 1.1 riastrad } 787 1.1 riastrad for (i = 0; i < rdev->usec_timeout; i++) { 788 1.1 riastrad if ((RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_STATE_MASK) == 0) 789 1.1 riastrad break; 790 1.1 riastrad udelay(1); 791 1.1 riastrad } 792 1.1 riastrad } 793 1.1 riastrad 794 1.1 riastrad static void trinity_stop_dpm(struct radeon_device *rdev) 795 1.1 riastrad { 796 1.1 riastrad u32 sclk_dpm_cntl; 797 1.1 riastrad 798 1.1 riastrad WREG32_P(CG_CG_VOLTAGE_CNTL, EN, ~EN); 799 1.1 riastrad 800 1.1 riastrad sclk_dpm_cntl = RREG32_SMC(SMU_SCLK_DPM_CNTL); 801 1.1 riastrad sclk_dpm_cntl &= ~(SCLK_DPM_EN_MASK | VOLTAGE_CHG_EN_MASK); 802 1.1 riastrad WREG32_SMC(SMU_SCLK_DPM_CNTL, sclk_dpm_cntl); 803 1.1 riastrad 804 1.1 riastrad trinity_dpm_config(rdev, false); 805 1.1 riastrad } 806 1.1 riastrad 807 1.1 riastrad static void trinity_start_am(struct radeon_device *rdev) 808 1.1 riastrad { 809 1.1 riastrad WREG32_P(SCLK_PWRMGT_CNTL, 0, ~(RESET_SCLK_CNT | RESET_BUSY_CNT)); 810 1.1 riastrad } 811 1.1 riastrad 812 1.1 riastrad static void trinity_reset_am(struct radeon_device *rdev) 813 1.1 riastrad { 814 1.1 riastrad WREG32_P(SCLK_PWRMGT_CNTL, RESET_SCLK_CNT | RESET_BUSY_CNT, 815 1.1 riastrad ~(RESET_SCLK_CNT | RESET_BUSY_CNT)); 816 1.1 riastrad } 817 1.1 riastrad 818 1.1 riastrad static void trinity_wait_for_level_0(struct radeon_device *rdev) 819 1.1 riastrad { 820 1.1 riastrad int i; 821 1.1 riastrad 822 1.1 riastrad for (i = 0; i < rdev->usec_timeout; i++) { 823 1.1 riastrad if ((RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_STATE_MASK) == 0) 824 1.1 riastrad break; 825 1.1 riastrad udelay(1); 826 1.1 riastrad } 827 1.1 riastrad } 828 1.1 riastrad 829 1.1 riastrad static void trinity_enable_power_level_0(struct radeon_device *rdev) 830 1.1 riastrad { 831 1.1 riastrad trinity_power_level_enable_disable(rdev, 0, true); 832 1.1 riastrad } 833 1.1 riastrad 834 1.1 riastrad static void trinity_force_level_0(struct radeon_device *rdev) 835 1.1 riastrad { 836 1.1 riastrad trinity_dpm_force_state(rdev, 0); 837 1.1 riastrad } 838 1.1 riastrad 839 1.1 riastrad static void trinity_unforce_levels(struct radeon_device *rdev) 840 1.1 riastrad { 841 1.1 riastrad trinity_dpm_no_forced_level(rdev); 842 1.1 riastrad } 843 1.1 riastrad 844 1.1 riastrad static void trinity_program_power_levels_0_to_n(struct radeon_device *rdev, 845 1.1 riastrad struct radeon_ps *new_rps, 846 1.1 riastrad struct radeon_ps *old_rps) 847 1.1 riastrad { 848 1.1 riastrad struct trinity_ps *new_ps = trinity_get_ps(new_rps); 849 1.1 riastrad struct trinity_ps *old_ps = trinity_get_ps(old_rps); 850 1.1 riastrad u32 i; 851 1.1 riastrad u32 n_current_state_levels = (old_ps == NULL) ? 1 : old_ps->num_levels; 852 1.1 riastrad 853 1.1 riastrad for (i = 0; i < new_ps->num_levels; i++) { 854 1.1 riastrad trinity_program_power_level(rdev, &new_ps->levels[i], i); 855 1.1 riastrad trinity_power_level_enable_disable(rdev, i, true); 856 1.1 riastrad } 857 1.1 riastrad 858 1.1 riastrad for (i = new_ps->num_levels; i < n_current_state_levels; i++) 859 1.1 riastrad trinity_power_level_enable_disable(rdev, i, false); 860 1.1 riastrad } 861 1.1 riastrad 862 1.1 riastrad static void trinity_program_bootup_state(struct radeon_device *rdev) 863 1.1 riastrad { 864 1.1 riastrad struct trinity_power_info *pi = trinity_get_pi(rdev); 865 1.1 riastrad u32 i; 866 1.1 riastrad 867 1.1 riastrad trinity_program_power_level(rdev, &pi->boot_pl, 0); 868 1.1 riastrad trinity_power_level_enable_disable(rdev, 0, true); 869 1.1 riastrad 870 1.1 riastrad for (i = 1; i < 8; i++) 871 1.1 riastrad trinity_power_level_enable_disable(rdev, i, false); 872 1.1 riastrad } 873 1.1 riastrad 874 1.1 riastrad static void trinity_setup_uvd_clock_table(struct radeon_device *rdev, 875 1.1 riastrad struct radeon_ps *rps) 876 1.1 riastrad { 877 1.1 riastrad struct trinity_ps *ps = trinity_get_ps(rps); 878 1.1 riastrad u32 uvdstates = (ps->vclk_low_divider | 879 1.1 riastrad ps->vclk_high_divider << 8 | 880 1.1 riastrad ps->dclk_low_divider << 16 | 881 1.1 riastrad ps->dclk_high_divider << 24); 882 1.1 riastrad 883 1.1 riastrad WREG32_SMC(SMU_UVD_DPM_STATES, uvdstates); 884 1.1 riastrad } 885 1.1 riastrad 886 1.1 riastrad static void trinity_setup_uvd_dpm_interval(struct radeon_device *rdev, 887 1.1 riastrad u32 interval) 888 1.1 riastrad { 889 1.1 riastrad u32 p, u; 890 1.1 riastrad u32 tp = RREG32_SMC(PM_TP); 891 1.1 riastrad u32 val; 892 1.1 riastrad u32 xclk = radeon_get_xclk(rdev); 893 1.1 riastrad 894 1.1 riastrad r600_calculate_u_and_p(interval, xclk, 16, &p, &u); 895 1.1 riastrad 896 1.1 riastrad val = (p + tp - 1) / tp; 897 1.1 riastrad 898 1.1 riastrad WREG32_SMC(SMU_UVD_DPM_CNTL, val); 899 1.1 riastrad } 900 1.1 riastrad 901 1.1 riastrad static bool trinity_uvd_clocks_zero(struct radeon_ps *rps) 902 1.1 riastrad { 903 1.1 riastrad if ((rps->vclk == 0) && (rps->dclk == 0)) 904 1.1 riastrad return true; 905 1.1 riastrad else 906 1.1 riastrad return false; 907 1.1 riastrad } 908 1.1 riastrad 909 1.1 riastrad static bool trinity_uvd_clocks_equal(struct radeon_ps *rps1, 910 1.1 riastrad struct radeon_ps *rps2) 911 1.1 riastrad { 912 1.1 riastrad struct trinity_ps *ps1 = trinity_get_ps(rps1); 913 1.1 riastrad struct trinity_ps *ps2 = trinity_get_ps(rps2); 914 1.1 riastrad 915 1.1 riastrad if ((rps1->vclk == rps2->vclk) && 916 1.1 riastrad (rps1->dclk == rps2->dclk) && 917 1.1 riastrad (ps1->vclk_low_divider == ps2->vclk_low_divider) && 918 1.1 riastrad (ps1->vclk_high_divider == ps2->vclk_high_divider) && 919 1.1 riastrad (ps1->dclk_low_divider == ps2->dclk_low_divider) && 920 1.1 riastrad (ps1->dclk_high_divider == ps2->dclk_high_divider)) 921 1.1 riastrad return true; 922 1.1 riastrad else 923 1.1 riastrad return false; 924 1.1 riastrad } 925 1.1 riastrad 926 1.1 riastrad static void trinity_setup_uvd_clocks(struct radeon_device *rdev, 927 1.1 riastrad struct radeon_ps *new_rps, 928 1.1 riastrad struct radeon_ps *old_rps) 929 1.1 riastrad { 930 1.1 riastrad struct trinity_power_info *pi = trinity_get_pi(rdev); 931 1.1 riastrad 932 1.1 riastrad if (pi->enable_gfx_power_gating) { 933 1.1 riastrad trinity_gfx_powergating_enable(rdev, false); 934 1.1 riastrad } 935 1.1 riastrad 936 1.1 riastrad if (pi->uvd_dpm) { 937 1.1 riastrad if (trinity_uvd_clocks_zero(new_rps) && 938 1.1 riastrad !trinity_uvd_clocks_zero(old_rps)) { 939 1.1 riastrad trinity_setup_uvd_dpm_interval(rdev, 0); 940 1.1 riastrad } else if (!trinity_uvd_clocks_zero(new_rps)) { 941 1.1 riastrad trinity_setup_uvd_clock_table(rdev, new_rps); 942 1.1 riastrad 943 1.1 riastrad if (trinity_uvd_clocks_zero(old_rps)) { 944 1.1 riastrad u32 tmp = RREG32(CG_MISC_REG); 945 1.1 riastrad tmp &= 0xfffffffd; 946 1.1 riastrad WREG32(CG_MISC_REG, tmp); 947 1.1 riastrad 948 1.1 riastrad radeon_set_uvd_clocks(rdev, new_rps->vclk, new_rps->dclk); 949 1.1 riastrad 950 1.1 riastrad trinity_setup_uvd_dpm_interval(rdev, 3000); 951 1.1 riastrad } 952 1.1 riastrad } 953 1.1 riastrad trinity_uvd_dpm_config(rdev); 954 1.1 riastrad } else { 955 1.1 riastrad if (trinity_uvd_clocks_zero(new_rps) || 956 1.1 riastrad trinity_uvd_clocks_equal(new_rps, old_rps)) 957 1.1 riastrad return; 958 1.1 riastrad 959 1.1 riastrad radeon_set_uvd_clocks(rdev, new_rps->vclk, new_rps->dclk); 960 1.1 riastrad } 961 1.1 riastrad 962 1.1 riastrad if (pi->enable_gfx_power_gating) { 963 1.1 riastrad trinity_gfx_powergating_enable(rdev, true); 964 1.1 riastrad } 965 1.1 riastrad } 966 1.1 riastrad 967 1.1 riastrad static void trinity_set_uvd_clock_before_set_eng_clock(struct radeon_device *rdev, 968 1.1 riastrad struct radeon_ps *new_rps, 969 1.1 riastrad struct radeon_ps *old_rps) 970 1.1 riastrad { 971 1.1 riastrad struct trinity_ps *new_ps = trinity_get_ps(new_rps); 972 1.1 riastrad struct trinity_ps *current_ps = trinity_get_ps(new_rps); 973 1.1 riastrad 974 1.1 riastrad if (new_ps->levels[new_ps->num_levels - 1].sclk >= 975 1.1 riastrad current_ps->levels[current_ps->num_levels - 1].sclk) 976 1.1 riastrad return; 977 1.1 riastrad 978 1.1 riastrad trinity_setup_uvd_clocks(rdev, new_rps, old_rps); 979 1.1 riastrad } 980 1.1 riastrad 981 1.1 riastrad static void trinity_set_uvd_clock_after_set_eng_clock(struct radeon_device *rdev, 982 1.1 riastrad struct radeon_ps *new_rps, 983 1.1 riastrad struct radeon_ps *old_rps) 984 1.1 riastrad { 985 1.1 riastrad struct trinity_ps *new_ps = trinity_get_ps(new_rps); 986 1.1 riastrad struct trinity_ps *current_ps = trinity_get_ps(old_rps); 987 1.1 riastrad 988 1.1 riastrad if (new_ps->levels[new_ps->num_levels - 1].sclk < 989 1.1 riastrad current_ps->levels[current_ps->num_levels - 1].sclk) 990 1.1 riastrad return; 991 1.1 riastrad 992 1.1 riastrad trinity_setup_uvd_clocks(rdev, new_rps, old_rps); 993 1.1 riastrad } 994 1.1 riastrad 995 1.1 riastrad static void trinity_set_vce_clock(struct radeon_device *rdev, 996 1.1 riastrad struct radeon_ps *new_rps, 997 1.1 riastrad struct radeon_ps *old_rps) 998 1.1 riastrad { 999 1.1 riastrad if ((old_rps->evclk != new_rps->evclk) || 1000 1.1 riastrad (old_rps->ecclk != new_rps->ecclk)) { 1001 1.1 riastrad /* turn the clocks on when encoding, off otherwise */ 1002 1.1 riastrad if (new_rps->evclk || new_rps->ecclk) 1003 1.1 riastrad vce_v1_0_enable_mgcg(rdev, false); 1004 1.1 riastrad else 1005 1.1 riastrad vce_v1_0_enable_mgcg(rdev, true); 1006 1.1 riastrad radeon_set_vce_clocks(rdev, new_rps->evclk, new_rps->ecclk); 1007 1.1 riastrad } 1008 1.1 riastrad } 1009 1.1 riastrad 1010 1.1 riastrad static void trinity_program_ttt(struct radeon_device *rdev) 1011 1.1 riastrad { 1012 1.1 riastrad struct trinity_power_info *pi = trinity_get_pi(rdev); 1013 1.1 riastrad u32 value = RREG32_SMC(SMU_SCLK_DPM_TTT); 1014 1.1 riastrad 1015 1.1 riastrad value &= ~(HT_MASK | LT_MASK); 1016 1.1 riastrad value |= HT((pi->thermal_auto_throttling + 49) * 8); 1017 1.1 riastrad value |= LT((pi->thermal_auto_throttling + 49 - pi->sys_info.htc_hyst_lmt) * 8); 1018 1.1 riastrad WREG32_SMC(SMU_SCLK_DPM_TTT, value); 1019 1.1 riastrad } 1020 1.1 riastrad 1021 1.1 riastrad static void trinity_enable_att(struct radeon_device *rdev) 1022 1.1 riastrad { 1023 1.1 riastrad u32 value = RREG32_SMC(SMU_SCLK_DPM_TT_CNTL); 1024 1.1 riastrad 1025 1.1 riastrad value &= ~SCLK_TT_EN_MASK; 1026 1.1 riastrad value |= SCLK_TT_EN(1); 1027 1.1 riastrad WREG32_SMC(SMU_SCLK_DPM_TT_CNTL, value); 1028 1.1 riastrad } 1029 1.1 riastrad 1030 1.1 riastrad static void trinity_program_sclk_dpm(struct radeon_device *rdev) 1031 1.1 riastrad { 1032 1.1 riastrad u32 p, u; 1033 1.1 riastrad u32 tp = RREG32_SMC(PM_TP); 1034 1.1 riastrad u32 ni; 1035 1.1 riastrad u32 xclk = radeon_get_xclk(rdev); 1036 1.1 riastrad u32 value; 1037 1.1 riastrad 1038 1.1 riastrad r600_calculate_u_and_p(400, xclk, 16, &p, &u); 1039 1.1 riastrad 1040 1.1 riastrad ni = (p + tp - 1) / tp; 1041 1.1 riastrad 1042 1.1 riastrad value = RREG32_SMC(PM_I_CNTL_1); 1043 1.1 riastrad value &= ~SCLK_DPM_MASK; 1044 1.1 riastrad value |= SCLK_DPM(ni); 1045 1.1 riastrad WREG32_SMC(PM_I_CNTL_1, value); 1046 1.1 riastrad } 1047 1.1 riastrad 1048 1.1 riastrad static int trinity_set_thermal_temperature_range(struct radeon_device *rdev, 1049 1.1 riastrad int min_temp, int max_temp) 1050 1.1 riastrad { 1051 1.1 riastrad int low_temp = 0 * 1000; 1052 1.1 riastrad int high_temp = 255 * 1000; 1053 1.1 riastrad 1054 1.3 riastrad if (low_temp < min_temp) 1055 1.1 riastrad low_temp = min_temp; 1056 1.3 riastrad if (high_temp > max_temp) 1057 1.1 riastrad high_temp = max_temp; 1058 1.3 riastrad if (high_temp < low_temp) { 1059 1.1 riastrad DRM_ERROR("invalid thermal range: %d - %d\n", low_temp, high_temp); 1060 1.3 riastrad return -EINVAL; 1061 1.3 riastrad } 1062 1.1 riastrad 1063 1.1 riastrad WREG32_P(CG_THERMAL_INT_CTRL, DIG_THERM_INTH(49 + (high_temp / 1000)), ~DIG_THERM_INTH_MASK); 1064 1.1 riastrad WREG32_P(CG_THERMAL_INT_CTRL, DIG_THERM_INTL(49 + (low_temp / 1000)), ~DIG_THERM_INTL_MASK); 1065 1.1 riastrad 1066 1.1 riastrad rdev->pm.dpm.thermal.min_temp = low_temp; 1067 1.1 riastrad rdev->pm.dpm.thermal.max_temp = high_temp; 1068 1.1 riastrad 1069 1.1 riastrad return 0; 1070 1.1 riastrad } 1071 1.1 riastrad 1072 1.1 riastrad static void trinity_update_current_ps(struct radeon_device *rdev, 1073 1.1 riastrad struct radeon_ps *rps) 1074 1.1 riastrad { 1075 1.1 riastrad struct trinity_ps *new_ps = trinity_get_ps(rps); 1076 1.1 riastrad struct trinity_power_info *pi = trinity_get_pi(rdev); 1077 1.1 riastrad 1078 1.1 riastrad pi->current_rps = *rps; 1079 1.1 riastrad pi->current_ps = *new_ps; 1080 1.1 riastrad pi->current_rps.ps_priv = &pi->current_ps; 1081 1.1 riastrad } 1082 1.1 riastrad 1083 1.1 riastrad static void trinity_update_requested_ps(struct radeon_device *rdev, 1084 1.1 riastrad struct radeon_ps *rps) 1085 1.1 riastrad { 1086 1.1 riastrad struct trinity_ps *new_ps = trinity_get_ps(rps); 1087 1.1 riastrad struct trinity_power_info *pi = trinity_get_pi(rdev); 1088 1.1 riastrad 1089 1.1 riastrad pi->requested_rps = *rps; 1090 1.1 riastrad pi->requested_ps = *new_ps; 1091 1.1 riastrad pi->requested_rps.ps_priv = &pi->requested_ps; 1092 1.1 riastrad } 1093 1.1 riastrad 1094 1.1 riastrad void trinity_dpm_enable_bapm(struct radeon_device *rdev, bool enable) 1095 1.1 riastrad { 1096 1.1 riastrad struct trinity_power_info *pi = trinity_get_pi(rdev); 1097 1.1 riastrad 1098 1.1 riastrad if (pi->enable_bapm) { 1099 1.1 riastrad trinity_acquire_mutex(rdev); 1100 1.1 riastrad trinity_dpm_bapm_enable(rdev, enable); 1101 1.1 riastrad trinity_release_mutex(rdev); 1102 1.1 riastrad } 1103 1.1 riastrad } 1104 1.1 riastrad 1105 1.1 riastrad int trinity_dpm_enable(struct radeon_device *rdev) 1106 1.1 riastrad { 1107 1.1 riastrad struct trinity_power_info *pi = trinity_get_pi(rdev); 1108 1.1 riastrad 1109 1.1 riastrad trinity_acquire_mutex(rdev); 1110 1.1 riastrad 1111 1.1 riastrad if (trinity_dpm_enabled(rdev)) { 1112 1.1 riastrad trinity_release_mutex(rdev); 1113 1.1 riastrad return -EINVAL; 1114 1.1 riastrad } 1115 1.1 riastrad 1116 1.1 riastrad trinity_program_bootup_state(rdev); 1117 1.1 riastrad sumo_program_vc(rdev, 0x00C00033); 1118 1.1 riastrad trinity_start_am(rdev); 1119 1.1 riastrad if (pi->enable_auto_thermal_throttling) { 1120 1.1 riastrad trinity_program_ttt(rdev); 1121 1.1 riastrad trinity_enable_att(rdev); 1122 1.1 riastrad } 1123 1.1 riastrad trinity_program_sclk_dpm(rdev); 1124 1.1 riastrad trinity_start_dpm(rdev); 1125 1.1 riastrad trinity_wait_for_dpm_enabled(rdev); 1126 1.1 riastrad trinity_dpm_bapm_enable(rdev, false); 1127 1.1 riastrad trinity_release_mutex(rdev); 1128 1.1 riastrad 1129 1.1 riastrad trinity_update_current_ps(rdev, rdev->pm.dpm.boot_ps); 1130 1.1 riastrad 1131 1.1 riastrad return 0; 1132 1.1 riastrad } 1133 1.1 riastrad 1134 1.1 riastrad int trinity_dpm_late_enable(struct radeon_device *rdev) 1135 1.1 riastrad { 1136 1.1 riastrad int ret; 1137 1.1 riastrad 1138 1.1 riastrad trinity_acquire_mutex(rdev); 1139 1.1 riastrad trinity_enable_clock_power_gating(rdev); 1140 1.1 riastrad 1141 1.1 riastrad if (rdev->irq.installed && 1142 1.1 riastrad r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) { 1143 1.1 riastrad ret = trinity_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX); 1144 1.1 riastrad if (ret) { 1145 1.1 riastrad trinity_release_mutex(rdev); 1146 1.1 riastrad return ret; 1147 1.1 riastrad } 1148 1.1 riastrad rdev->irq.dpm_thermal = true; 1149 1.1 riastrad radeon_irq_set(rdev); 1150 1.1 riastrad } 1151 1.1 riastrad trinity_release_mutex(rdev); 1152 1.1 riastrad 1153 1.1 riastrad return 0; 1154 1.1 riastrad } 1155 1.1 riastrad 1156 1.1 riastrad void trinity_dpm_disable(struct radeon_device *rdev) 1157 1.1 riastrad { 1158 1.1 riastrad trinity_acquire_mutex(rdev); 1159 1.1 riastrad if (!trinity_dpm_enabled(rdev)) { 1160 1.1 riastrad trinity_release_mutex(rdev); 1161 1.1 riastrad return; 1162 1.1 riastrad } 1163 1.1 riastrad trinity_dpm_bapm_enable(rdev, false); 1164 1.1 riastrad trinity_disable_clock_power_gating(rdev); 1165 1.1 riastrad sumo_clear_vc(rdev); 1166 1.1 riastrad trinity_wait_for_level_0(rdev); 1167 1.1 riastrad trinity_stop_dpm(rdev); 1168 1.1 riastrad trinity_reset_am(rdev); 1169 1.1 riastrad trinity_release_mutex(rdev); 1170 1.1 riastrad 1171 1.1 riastrad if (rdev->irq.installed && 1172 1.1 riastrad r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) { 1173 1.1 riastrad rdev->irq.dpm_thermal = false; 1174 1.1 riastrad radeon_irq_set(rdev); 1175 1.1 riastrad } 1176 1.1 riastrad 1177 1.1 riastrad trinity_update_current_ps(rdev, rdev->pm.dpm.boot_ps); 1178 1.1 riastrad } 1179 1.1 riastrad 1180 1.1 riastrad static void trinity_get_min_sclk_divider(struct radeon_device *rdev) 1181 1.1 riastrad { 1182 1.1 riastrad struct trinity_power_info *pi = trinity_get_pi(rdev); 1183 1.1 riastrad 1184 1.1 riastrad pi->min_sclk_did = 1185 1.1 riastrad (RREG32_SMC(CC_SMU_MISC_FUSES) & MinSClkDid_MASK) >> MinSClkDid_SHIFT; 1186 1.1 riastrad } 1187 1.1 riastrad 1188 1.1 riastrad static void trinity_setup_nbp_sim(struct radeon_device *rdev, 1189 1.1 riastrad struct radeon_ps *rps) 1190 1.1 riastrad { 1191 1.1 riastrad struct trinity_power_info *pi = trinity_get_pi(rdev); 1192 1.1 riastrad struct trinity_ps *new_ps = trinity_get_ps(rps); 1193 1.1 riastrad u32 nbpsconfig; 1194 1.1 riastrad 1195 1.1 riastrad if (pi->sys_info.nb_dpm_enable) { 1196 1.1 riastrad nbpsconfig = RREG32_SMC(NB_PSTATE_CONFIG); 1197 1.1 riastrad nbpsconfig &= ~(Dpm0PgNbPsLo_MASK | Dpm0PgNbPsHi_MASK | DpmXNbPsLo_MASK | DpmXNbPsHi_MASK); 1198 1.1 riastrad nbpsconfig |= (Dpm0PgNbPsLo(new_ps->Dpm0PgNbPsLo) | 1199 1.1 riastrad Dpm0PgNbPsHi(new_ps->Dpm0PgNbPsHi) | 1200 1.1 riastrad DpmXNbPsLo(new_ps->DpmXNbPsLo) | 1201 1.1 riastrad DpmXNbPsHi(new_ps->DpmXNbPsHi)); 1202 1.1 riastrad WREG32_SMC(NB_PSTATE_CONFIG, nbpsconfig); 1203 1.1 riastrad } 1204 1.1 riastrad } 1205 1.1 riastrad 1206 1.1 riastrad int trinity_dpm_force_performance_level(struct radeon_device *rdev, 1207 1.1 riastrad enum radeon_dpm_forced_level level) 1208 1.1 riastrad { 1209 1.1 riastrad struct trinity_power_info *pi = trinity_get_pi(rdev); 1210 1.1 riastrad struct radeon_ps *rps = &pi->current_rps; 1211 1.1 riastrad struct trinity_ps *ps = trinity_get_ps(rps); 1212 1.1 riastrad int i, ret; 1213 1.1 riastrad 1214 1.1 riastrad if (ps->num_levels <= 1) 1215 1.1 riastrad return 0; 1216 1.1 riastrad 1217 1.1 riastrad if (level == RADEON_DPM_FORCED_LEVEL_HIGH) { 1218 1.1 riastrad /* not supported by the hw */ 1219 1.1 riastrad return -EINVAL; 1220 1.1 riastrad } else if (level == RADEON_DPM_FORCED_LEVEL_LOW) { 1221 1.1 riastrad ret = trinity_dpm_n_levels_disabled(rdev, ps->num_levels - 1); 1222 1.1 riastrad if (ret) 1223 1.1 riastrad return ret; 1224 1.1 riastrad } else { 1225 1.1 riastrad for (i = 0; i < ps->num_levels; i++) { 1226 1.1 riastrad ret = trinity_dpm_n_levels_disabled(rdev, 0); 1227 1.1 riastrad if (ret) 1228 1.1 riastrad return ret; 1229 1.1 riastrad } 1230 1.1 riastrad } 1231 1.1 riastrad 1232 1.1 riastrad rdev->pm.dpm.forced_level = level; 1233 1.1 riastrad 1234 1.1 riastrad return 0; 1235 1.1 riastrad } 1236 1.1 riastrad 1237 1.1 riastrad int trinity_dpm_pre_set_power_state(struct radeon_device *rdev) 1238 1.1 riastrad { 1239 1.1 riastrad struct trinity_power_info *pi = trinity_get_pi(rdev); 1240 1.1 riastrad struct radeon_ps requested_ps = *rdev->pm.dpm.requested_ps; 1241 1.1 riastrad struct radeon_ps *new_ps = &requested_ps; 1242 1.1 riastrad 1243 1.1 riastrad trinity_update_requested_ps(rdev, new_ps); 1244 1.1 riastrad 1245 1.1 riastrad trinity_apply_state_adjust_rules(rdev, 1246 1.1 riastrad &pi->requested_rps, 1247 1.1 riastrad &pi->current_rps); 1248 1.1 riastrad 1249 1.1 riastrad return 0; 1250 1.1 riastrad } 1251 1.1 riastrad 1252 1.1 riastrad int trinity_dpm_set_power_state(struct radeon_device *rdev) 1253 1.1 riastrad { 1254 1.1 riastrad struct trinity_power_info *pi = trinity_get_pi(rdev); 1255 1.1 riastrad struct radeon_ps *new_ps = &pi->requested_rps; 1256 1.1 riastrad struct radeon_ps *old_ps = &pi->current_rps; 1257 1.1 riastrad 1258 1.1 riastrad trinity_acquire_mutex(rdev); 1259 1.1 riastrad if (pi->enable_dpm) { 1260 1.1 riastrad if (pi->enable_bapm) 1261 1.1 riastrad trinity_dpm_bapm_enable(rdev, rdev->pm.dpm.ac_power); 1262 1.1 riastrad trinity_set_uvd_clock_before_set_eng_clock(rdev, new_ps, old_ps); 1263 1.1 riastrad trinity_enable_power_level_0(rdev); 1264 1.1 riastrad trinity_force_level_0(rdev); 1265 1.1 riastrad trinity_wait_for_level_0(rdev); 1266 1.1 riastrad trinity_setup_nbp_sim(rdev, new_ps); 1267 1.1 riastrad trinity_program_power_levels_0_to_n(rdev, new_ps, old_ps); 1268 1.1 riastrad trinity_force_level_0(rdev); 1269 1.1 riastrad trinity_unforce_levels(rdev); 1270 1.1 riastrad trinity_set_uvd_clock_after_set_eng_clock(rdev, new_ps, old_ps); 1271 1.1 riastrad trinity_set_vce_clock(rdev, new_ps, old_ps); 1272 1.1 riastrad } 1273 1.1 riastrad trinity_release_mutex(rdev); 1274 1.1 riastrad 1275 1.1 riastrad return 0; 1276 1.1 riastrad } 1277 1.1 riastrad 1278 1.1 riastrad void trinity_dpm_post_set_power_state(struct radeon_device *rdev) 1279 1.1 riastrad { 1280 1.1 riastrad struct trinity_power_info *pi = trinity_get_pi(rdev); 1281 1.1 riastrad struct radeon_ps *new_ps = &pi->requested_rps; 1282 1.1 riastrad 1283 1.1 riastrad trinity_update_current_ps(rdev, new_ps); 1284 1.1 riastrad } 1285 1.1 riastrad 1286 1.1 riastrad void trinity_dpm_setup_asic(struct radeon_device *rdev) 1287 1.1 riastrad { 1288 1.1 riastrad trinity_acquire_mutex(rdev); 1289 1.1 riastrad sumo_program_sstp(rdev); 1290 1.1 riastrad sumo_take_smu_control(rdev, true); 1291 1.1 riastrad trinity_get_min_sclk_divider(rdev); 1292 1.1 riastrad trinity_release_mutex(rdev); 1293 1.1 riastrad } 1294 1.1 riastrad 1295 1.1 riastrad #if 0 1296 1.1 riastrad void trinity_dpm_reset_asic(struct radeon_device *rdev) 1297 1.1 riastrad { 1298 1.1 riastrad struct trinity_power_info *pi = trinity_get_pi(rdev); 1299 1.1 riastrad 1300 1.1 riastrad trinity_acquire_mutex(rdev); 1301 1.1 riastrad if (pi->enable_dpm) { 1302 1.1 riastrad trinity_enable_power_level_0(rdev); 1303 1.1 riastrad trinity_force_level_0(rdev); 1304 1.1 riastrad trinity_wait_for_level_0(rdev); 1305 1.1 riastrad trinity_program_bootup_state(rdev); 1306 1.1 riastrad trinity_force_level_0(rdev); 1307 1.1 riastrad trinity_unforce_levels(rdev); 1308 1.1 riastrad } 1309 1.1 riastrad trinity_release_mutex(rdev); 1310 1.1 riastrad } 1311 1.1 riastrad #endif 1312 1.1 riastrad 1313 1.1 riastrad static u16 trinity_convert_voltage_index_to_value(struct radeon_device *rdev, 1314 1.1 riastrad u32 vid_2bit) 1315 1.1 riastrad { 1316 1.1 riastrad struct trinity_power_info *pi = trinity_get_pi(rdev); 1317 1.1 riastrad u32 vid_7bit = sumo_convert_vid2_to_vid7(rdev, &pi->sys_info.vid_mapping_table, vid_2bit); 1318 1.1 riastrad u32 svi_mode = (RREG32_SMC(PM_CONFIG) & SVI_Mode) ? 1 : 0; 1319 1.1 riastrad u32 step = (svi_mode == 0) ? 1250 : 625; 1320 1.1 riastrad u32 delta = vid_7bit * step + 50; 1321 1.1 riastrad 1322 1.1 riastrad if (delta > 155000) 1323 1.1 riastrad return 0; 1324 1.1 riastrad 1325 1.1 riastrad return (155000 - delta) / 100; 1326 1.1 riastrad } 1327 1.1 riastrad 1328 1.1 riastrad static void trinity_patch_boot_state(struct radeon_device *rdev, 1329 1.1 riastrad struct trinity_ps *ps) 1330 1.1 riastrad { 1331 1.1 riastrad struct trinity_power_info *pi = trinity_get_pi(rdev); 1332 1.1 riastrad 1333 1.1 riastrad ps->num_levels = 1; 1334 1.1 riastrad ps->nbps_flags = 0; 1335 1.1 riastrad ps->bapm_flags = 0; 1336 1.1 riastrad ps->levels[0] = pi->boot_pl; 1337 1.1 riastrad } 1338 1.1 riastrad 1339 1.1 riastrad static u8 trinity_calculate_vce_wm(struct radeon_device *rdev, u32 sclk) 1340 1.1 riastrad { 1341 1.1 riastrad if (sclk < 20000) 1342 1.1 riastrad return 1; 1343 1.1 riastrad return 0; 1344 1.1 riastrad } 1345 1.1 riastrad 1346 1.1 riastrad static void trinity_construct_boot_state(struct radeon_device *rdev) 1347 1.1 riastrad { 1348 1.1 riastrad struct trinity_power_info *pi = trinity_get_pi(rdev); 1349 1.1 riastrad 1350 1.1 riastrad pi->boot_pl.sclk = pi->sys_info.bootup_sclk; 1351 1.1 riastrad pi->boot_pl.vddc_index = pi->sys_info.bootup_nb_voltage_index; 1352 1.1 riastrad pi->boot_pl.ds_divider_index = 0; 1353 1.1 riastrad pi->boot_pl.ss_divider_index = 0; 1354 1.1 riastrad pi->boot_pl.allow_gnb_slow = 1; 1355 1.1 riastrad pi->boot_pl.force_nbp_state = 0; 1356 1.1 riastrad pi->boot_pl.display_wm = 0; 1357 1.1 riastrad pi->boot_pl.vce_wm = 0; 1358 1.1 riastrad pi->current_ps.num_levels = 1; 1359 1.1 riastrad pi->current_ps.levels[0] = pi->boot_pl; 1360 1.1 riastrad } 1361 1.1 riastrad 1362 1.1 riastrad static u8 trinity_get_sleep_divider_id_from_clock(struct radeon_device *rdev, 1363 1.1 riastrad u32 sclk, u32 min_sclk_in_sr) 1364 1.1 riastrad { 1365 1.1 riastrad struct trinity_power_info *pi = trinity_get_pi(rdev); 1366 1.1 riastrad u32 i; 1367 1.1 riastrad u32 temp; 1368 1.2 riastrad u32 min = (min_sclk_in_sr > TRINITY_MINIMUM_ENGINE_CLOCK) ? 1369 1.1 riastrad min_sclk_in_sr : TRINITY_MINIMUM_ENGINE_CLOCK; 1370 1.1 riastrad 1371 1.2 riastrad if (sclk < min) 1372 1.1 riastrad return 0; 1373 1.1 riastrad 1374 1.1 riastrad if (!pi->enable_sclk_ds) 1375 1.1 riastrad return 0; 1376 1.1 riastrad 1377 1.1 riastrad for (i = TRINITY_MAX_DEEPSLEEP_DIVIDER_ID; ; i--) { 1378 1.1 riastrad temp = sclk / sumo_get_sleep_divider_from_id(i); 1379 1.2 riastrad if (temp >= min || i == 0) 1380 1.1 riastrad break; 1381 1.1 riastrad } 1382 1.1 riastrad 1383 1.1 riastrad return (u8)i; 1384 1.1 riastrad } 1385 1.1 riastrad 1386 1.1 riastrad static u32 trinity_get_valid_engine_clock(struct radeon_device *rdev, 1387 1.1 riastrad u32 lower_limit) 1388 1.1 riastrad { 1389 1.1 riastrad struct trinity_power_info *pi = trinity_get_pi(rdev); 1390 1.1 riastrad u32 i; 1391 1.1 riastrad 1392 1.1 riastrad for (i = 0; i < pi->sys_info.sclk_voltage_mapping_table.num_max_dpm_entries; i++) { 1393 1.1 riastrad if (pi->sys_info.sclk_voltage_mapping_table.entries[i].sclk_frequency >= lower_limit) 1394 1.1 riastrad return pi->sys_info.sclk_voltage_mapping_table.entries[i].sclk_frequency; 1395 1.1 riastrad } 1396 1.1 riastrad 1397 1.1 riastrad if (i == pi->sys_info.sclk_voltage_mapping_table.num_max_dpm_entries) 1398 1.1 riastrad DRM_ERROR("engine clock out of range!"); 1399 1.1 riastrad 1400 1.1 riastrad return 0; 1401 1.1 riastrad } 1402 1.1 riastrad 1403 1.1 riastrad static void trinity_patch_thermal_state(struct radeon_device *rdev, 1404 1.1 riastrad struct trinity_ps *ps, 1405 1.1 riastrad struct trinity_ps *current_ps) 1406 1.1 riastrad { 1407 1.1 riastrad struct trinity_power_info *pi = trinity_get_pi(rdev); 1408 1.1 riastrad u32 sclk_in_sr = pi->sys_info.min_sclk; /* ??? */ 1409 1.1 riastrad u32 current_vddc; 1410 1.1 riastrad u32 current_sclk; 1411 1.1 riastrad u32 current_index = 0; 1412 1.1 riastrad 1413 1.1 riastrad if (current_ps) { 1414 1.1 riastrad current_vddc = current_ps->levels[current_index].vddc_index; 1415 1.1 riastrad current_sclk = current_ps->levels[current_index].sclk; 1416 1.1 riastrad } else { 1417 1.1 riastrad current_vddc = pi->boot_pl.vddc_index; 1418 1.1 riastrad current_sclk = pi->boot_pl.sclk; 1419 1.1 riastrad } 1420 1.1 riastrad 1421 1.1 riastrad ps->levels[0].vddc_index = current_vddc; 1422 1.1 riastrad 1423 1.1 riastrad if (ps->levels[0].sclk > current_sclk) 1424 1.1 riastrad ps->levels[0].sclk = current_sclk; 1425 1.1 riastrad 1426 1.1 riastrad ps->levels[0].ds_divider_index = 1427 1.1 riastrad trinity_get_sleep_divider_id_from_clock(rdev, ps->levels[0].sclk, sclk_in_sr); 1428 1.1 riastrad ps->levels[0].ss_divider_index = ps->levels[0].ds_divider_index; 1429 1.1 riastrad ps->levels[0].allow_gnb_slow = 1; 1430 1.1 riastrad ps->levels[0].force_nbp_state = 0; 1431 1.1 riastrad ps->levels[0].display_wm = 0; 1432 1.1 riastrad ps->levels[0].vce_wm = 1433 1.1 riastrad trinity_calculate_vce_wm(rdev, ps->levels[0].sclk); 1434 1.1 riastrad } 1435 1.1 riastrad 1436 1.1 riastrad static u8 trinity_calculate_display_wm(struct radeon_device *rdev, 1437 1.1 riastrad struct trinity_ps *ps, u32 index) 1438 1.1 riastrad { 1439 1.1 riastrad if (ps == NULL || ps->num_levels <= 1) 1440 1.1 riastrad return 0; 1441 1.1 riastrad else if (ps->num_levels == 2) { 1442 1.1 riastrad if (index == 0) 1443 1.1 riastrad return 0; 1444 1.1 riastrad else 1445 1.1 riastrad return 1; 1446 1.1 riastrad } else { 1447 1.1 riastrad if (index == 0) 1448 1.1 riastrad return 0; 1449 1.1 riastrad else if (ps->levels[index].sclk < 30000) 1450 1.1 riastrad return 0; 1451 1.1 riastrad else 1452 1.1 riastrad return 1; 1453 1.1 riastrad } 1454 1.1 riastrad } 1455 1.1 riastrad 1456 1.1 riastrad static u32 trinity_get_uvd_clock_index(struct radeon_device *rdev, 1457 1.1 riastrad struct radeon_ps *rps) 1458 1.1 riastrad { 1459 1.1 riastrad struct trinity_power_info *pi = trinity_get_pi(rdev); 1460 1.1 riastrad u32 i = 0; 1461 1.1 riastrad 1462 1.1 riastrad for (i = 0; i < 4; i++) { 1463 1.1 riastrad if ((rps->vclk == pi->sys_info.uvd_clock_table_entries[i].vclk) && 1464 1.1 riastrad (rps->dclk == pi->sys_info.uvd_clock_table_entries[i].dclk)) 1465 1.1 riastrad break; 1466 1.1 riastrad } 1467 1.1 riastrad 1468 1.1 riastrad if (i >= 4) { 1469 1.1 riastrad DRM_ERROR("UVD clock index not found!\n"); 1470 1.1 riastrad i = 3; 1471 1.1 riastrad } 1472 1.1 riastrad return i; 1473 1.1 riastrad } 1474 1.1 riastrad 1475 1.1 riastrad static void trinity_adjust_uvd_state(struct radeon_device *rdev, 1476 1.1 riastrad struct radeon_ps *rps) 1477 1.1 riastrad { 1478 1.1 riastrad struct trinity_ps *ps = trinity_get_ps(rps); 1479 1.1 riastrad struct trinity_power_info *pi = trinity_get_pi(rdev); 1480 1.1 riastrad u32 high_index = 0; 1481 1.1 riastrad u32 low_index = 0; 1482 1.1 riastrad 1483 1.1 riastrad if (pi->uvd_dpm && r600_is_uvd_state(rps->class, rps->class2)) { 1484 1.1 riastrad high_index = trinity_get_uvd_clock_index(rdev, rps); 1485 1.1 riastrad 1486 1.1 riastrad switch(high_index) { 1487 1.1 riastrad case 3: 1488 1.1 riastrad case 2: 1489 1.1 riastrad low_index = 1; 1490 1.1 riastrad break; 1491 1.1 riastrad case 1: 1492 1.1 riastrad case 0: 1493 1.1 riastrad default: 1494 1.1 riastrad low_index = 0; 1495 1.1 riastrad break; 1496 1.1 riastrad } 1497 1.1 riastrad 1498 1.1 riastrad ps->vclk_low_divider = 1499 1.1 riastrad pi->sys_info.uvd_clock_table_entries[high_index].vclk_did; 1500 1.1 riastrad ps->dclk_low_divider = 1501 1.1 riastrad pi->sys_info.uvd_clock_table_entries[high_index].dclk_did; 1502 1.1 riastrad ps->vclk_high_divider = 1503 1.1 riastrad pi->sys_info.uvd_clock_table_entries[low_index].vclk_did; 1504 1.1 riastrad ps->dclk_high_divider = 1505 1.1 riastrad pi->sys_info.uvd_clock_table_entries[low_index].dclk_did; 1506 1.1 riastrad } 1507 1.1 riastrad } 1508 1.1 riastrad 1509 1.1 riastrad static int trinity_get_vce_clock_voltage(struct radeon_device *rdev, 1510 1.1 riastrad u32 evclk, u32 ecclk, u16 *voltage) 1511 1.1 riastrad { 1512 1.1 riastrad u32 i; 1513 1.1 riastrad int ret = -EINVAL; 1514 1.1 riastrad struct radeon_vce_clock_voltage_dependency_table *table = 1515 1.1 riastrad &rdev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table; 1516 1.1 riastrad 1517 1.1 riastrad if (((evclk == 0) && (ecclk == 0)) || 1518 1.1 riastrad (table && (table->count == 0))) { 1519 1.1 riastrad *voltage = 0; 1520 1.1 riastrad return 0; 1521 1.1 riastrad } 1522 1.1 riastrad 1523 1.1 riastrad for (i = 0; i < table->count; i++) { 1524 1.1 riastrad if ((evclk <= table->entries[i].evclk) && 1525 1.1 riastrad (ecclk <= table->entries[i].ecclk)) { 1526 1.1 riastrad *voltage = table->entries[i].v; 1527 1.1 riastrad ret = 0; 1528 1.1 riastrad break; 1529 1.1 riastrad } 1530 1.1 riastrad } 1531 1.1 riastrad 1532 1.1 riastrad /* if no match return the highest voltage */ 1533 1.1 riastrad if (ret) 1534 1.1 riastrad *voltage = table->entries[table->count - 1].v; 1535 1.1 riastrad 1536 1.1 riastrad return ret; 1537 1.1 riastrad } 1538 1.1 riastrad 1539 1.1 riastrad static void trinity_apply_state_adjust_rules(struct radeon_device *rdev, 1540 1.1 riastrad struct radeon_ps *new_rps, 1541 1.1 riastrad struct radeon_ps *old_rps) 1542 1.1 riastrad { 1543 1.1 riastrad struct trinity_ps *ps = trinity_get_ps(new_rps); 1544 1.1 riastrad struct trinity_ps *current_ps = trinity_get_ps(old_rps); 1545 1.1 riastrad struct trinity_power_info *pi = trinity_get_pi(rdev); 1546 1.1 riastrad u32 min_voltage = 0; /* ??? */ 1547 1.1 riastrad u32 min_sclk = pi->sys_info.min_sclk; /* XXX check against disp reqs */ 1548 1.1 riastrad u32 sclk_in_sr = pi->sys_info.min_sclk; /* ??? */ 1549 1.1 riastrad u32 i; 1550 1.1 riastrad u16 min_vce_voltage; 1551 1.1 riastrad bool force_high; 1552 1.1 riastrad u32 num_active_displays = rdev->pm.dpm.new_active_crtc_count; 1553 1.1 riastrad 1554 1.1 riastrad if (new_rps->class & ATOM_PPLIB_CLASSIFICATION_THERMAL) 1555 1.1 riastrad return trinity_patch_thermal_state(rdev, ps, current_ps); 1556 1.1 riastrad 1557 1.1 riastrad trinity_adjust_uvd_state(rdev, new_rps); 1558 1.1 riastrad 1559 1.1 riastrad if (new_rps->vce_active) { 1560 1.1 riastrad new_rps->evclk = rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].evclk; 1561 1.1 riastrad new_rps->ecclk = rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].ecclk; 1562 1.1 riastrad } else { 1563 1.1 riastrad new_rps->evclk = 0; 1564 1.1 riastrad new_rps->ecclk = 0; 1565 1.1 riastrad } 1566 1.1 riastrad 1567 1.1 riastrad for (i = 0; i < ps->num_levels; i++) { 1568 1.1 riastrad if (ps->levels[i].vddc_index < min_voltage) 1569 1.1 riastrad ps->levels[i].vddc_index = min_voltage; 1570 1.1 riastrad 1571 1.1 riastrad if (ps->levels[i].sclk < min_sclk) 1572 1.1 riastrad ps->levels[i].sclk = 1573 1.1 riastrad trinity_get_valid_engine_clock(rdev, min_sclk); 1574 1.1 riastrad 1575 1.1 riastrad /* patch in vce limits */ 1576 1.1 riastrad if (new_rps->vce_active) { 1577 1.1 riastrad /* sclk */ 1578 1.1 riastrad if (ps->levels[i].sclk < rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].sclk) 1579 1.1 riastrad ps->levels[i].sclk = rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].sclk; 1580 1.1 riastrad /* vddc */ 1581 1.1 riastrad trinity_get_vce_clock_voltage(rdev, new_rps->evclk, new_rps->ecclk, &min_vce_voltage); 1582 1.1 riastrad if (ps->levels[i].vddc_index < min_vce_voltage) 1583 1.1 riastrad ps->levels[i].vddc_index = min_vce_voltage; 1584 1.1 riastrad } 1585 1.1 riastrad 1586 1.1 riastrad ps->levels[i].ds_divider_index = 1587 1.1 riastrad sumo_get_sleep_divider_id_from_clock(rdev, ps->levels[i].sclk, sclk_in_sr); 1588 1.1 riastrad 1589 1.1 riastrad ps->levels[i].ss_divider_index = ps->levels[i].ds_divider_index; 1590 1.1 riastrad 1591 1.1 riastrad ps->levels[i].allow_gnb_slow = 1; 1592 1.1 riastrad ps->levels[i].force_nbp_state = 0; 1593 1.1 riastrad ps->levels[i].display_wm = 1594 1.1 riastrad trinity_calculate_display_wm(rdev, ps, i); 1595 1.1 riastrad ps->levels[i].vce_wm = 1596 1.1 riastrad trinity_calculate_vce_wm(rdev, ps->levels[0].sclk); 1597 1.1 riastrad } 1598 1.1 riastrad 1599 1.1 riastrad if ((new_rps->class & (ATOM_PPLIB_CLASSIFICATION_HDSTATE | ATOM_PPLIB_CLASSIFICATION_SDSTATE)) || 1600 1.1 riastrad ((new_rps->class & ATOM_PPLIB_CLASSIFICATION_UI_MASK) == ATOM_PPLIB_CLASSIFICATION_UI_BATTERY)) 1601 1.1 riastrad ps->bapm_flags |= TRINITY_POWERSTATE_FLAGS_BAPM_DISABLE; 1602 1.1 riastrad 1603 1.1 riastrad if (pi->sys_info.nb_dpm_enable) { 1604 1.1 riastrad ps->Dpm0PgNbPsLo = 0x1; 1605 1.1 riastrad ps->Dpm0PgNbPsHi = 0x0; 1606 1.1 riastrad ps->DpmXNbPsLo = 0x2; 1607 1.1 riastrad ps->DpmXNbPsHi = 0x1; 1608 1.1 riastrad 1609 1.1 riastrad if ((new_rps->class & (ATOM_PPLIB_CLASSIFICATION_HDSTATE | ATOM_PPLIB_CLASSIFICATION_SDSTATE)) || 1610 1.1 riastrad ((new_rps->class & ATOM_PPLIB_CLASSIFICATION_UI_MASK) == ATOM_PPLIB_CLASSIFICATION_UI_BATTERY)) { 1611 1.1 riastrad force_high = ((new_rps->class & ATOM_PPLIB_CLASSIFICATION_HDSTATE) || 1612 1.1 riastrad ((new_rps->class & ATOM_PPLIB_CLASSIFICATION_SDSTATE) && 1613 1.1 riastrad (pi->sys_info.uma_channel_number == 1))); 1614 1.1 riastrad force_high = (num_active_displays >= 3) || force_high; 1615 1.1 riastrad ps->Dpm0PgNbPsLo = force_high ? 0x2 : 0x3; 1616 1.1 riastrad ps->Dpm0PgNbPsHi = 0x1; 1617 1.1 riastrad ps->DpmXNbPsLo = force_high ? 0x2 : 0x3; 1618 1.1 riastrad ps->DpmXNbPsHi = 0x2; 1619 1.1 riastrad ps->levels[ps->num_levels - 1].allow_gnb_slow = 0; 1620 1.1 riastrad } 1621 1.1 riastrad } 1622 1.1 riastrad } 1623 1.1 riastrad 1624 1.1 riastrad static void trinity_cleanup_asic(struct radeon_device *rdev) 1625 1.1 riastrad { 1626 1.1 riastrad sumo_take_smu_control(rdev, false); 1627 1.1 riastrad } 1628 1.1 riastrad 1629 1.1 riastrad #if 0 1630 1.1 riastrad static void trinity_pre_display_configuration_change(struct radeon_device *rdev) 1631 1.1 riastrad { 1632 1.1 riastrad struct trinity_power_info *pi = trinity_get_pi(rdev); 1633 1.1 riastrad 1634 1.1 riastrad if (pi->voltage_drop_in_dce) 1635 1.1 riastrad trinity_dce_enable_voltage_adjustment(rdev, false); 1636 1.1 riastrad } 1637 1.1 riastrad #endif 1638 1.1 riastrad 1639 1.1 riastrad static void trinity_add_dccac_value(struct radeon_device *rdev) 1640 1.1 riastrad { 1641 1.1 riastrad u32 gpu_cac_avrg_cntl_window_size; 1642 1.1 riastrad u32 num_active_displays = rdev->pm.dpm.new_active_crtc_count; 1643 1.1 riastrad u64 disp_clk = rdev->clock.default_dispclk / 100; 1644 1.1 riastrad u32 dc_cac_value; 1645 1.1 riastrad 1646 1.1 riastrad gpu_cac_avrg_cntl_window_size = 1647 1.1 riastrad (RREG32_SMC(GPU_CAC_AVRG_CNTL) & WINDOW_SIZE_MASK) >> WINDOW_SIZE_SHIFT; 1648 1.1 riastrad 1649 1.1 riastrad dc_cac_value = (u32)((14213 * disp_clk * disp_clk * (u64)num_active_displays) >> 1650 1.1 riastrad (32 - gpu_cac_avrg_cntl_window_size)); 1651 1.1 riastrad 1652 1.1 riastrad WREG32_SMC(DC_CAC_VALUE, dc_cac_value); 1653 1.1 riastrad } 1654 1.1 riastrad 1655 1.1 riastrad void trinity_dpm_display_configuration_changed(struct radeon_device *rdev) 1656 1.1 riastrad { 1657 1.1 riastrad struct trinity_power_info *pi = trinity_get_pi(rdev); 1658 1.1 riastrad 1659 1.1 riastrad if (pi->voltage_drop_in_dce) 1660 1.1 riastrad trinity_dce_enable_voltage_adjustment(rdev, true); 1661 1.1 riastrad trinity_add_dccac_value(rdev); 1662 1.1 riastrad } 1663 1.1 riastrad 1664 1.1 riastrad union power_info { 1665 1.1 riastrad struct _ATOM_POWERPLAY_INFO info; 1666 1.1 riastrad struct _ATOM_POWERPLAY_INFO_V2 info_2; 1667 1.1 riastrad struct _ATOM_POWERPLAY_INFO_V3 info_3; 1668 1.1 riastrad struct _ATOM_PPLIB_POWERPLAYTABLE pplib; 1669 1.1 riastrad struct _ATOM_PPLIB_POWERPLAYTABLE2 pplib2; 1670 1.1 riastrad struct _ATOM_PPLIB_POWERPLAYTABLE3 pplib3; 1671 1.1 riastrad }; 1672 1.1 riastrad 1673 1.1 riastrad union pplib_clock_info { 1674 1.1 riastrad struct _ATOM_PPLIB_R600_CLOCK_INFO r600; 1675 1.1 riastrad struct _ATOM_PPLIB_RS780_CLOCK_INFO rs780; 1676 1.1 riastrad struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO evergreen; 1677 1.1 riastrad struct _ATOM_PPLIB_SUMO_CLOCK_INFO sumo; 1678 1.1 riastrad }; 1679 1.1 riastrad 1680 1.1 riastrad union pplib_power_state { 1681 1.1 riastrad struct _ATOM_PPLIB_STATE v1; 1682 1.1 riastrad struct _ATOM_PPLIB_STATE_V2 v2; 1683 1.1 riastrad }; 1684 1.1 riastrad 1685 1.1 riastrad static void trinity_parse_pplib_non_clock_info(struct radeon_device *rdev, 1686 1.1 riastrad struct radeon_ps *rps, 1687 1.1 riastrad struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info, 1688 1.1 riastrad u8 table_rev) 1689 1.1 riastrad { 1690 1.1 riastrad struct trinity_ps *ps = trinity_get_ps(rps); 1691 1.1 riastrad 1692 1.1 riastrad rps->caps = le32_to_cpu(non_clock_info->ulCapsAndSettings); 1693 1.1 riastrad rps->class = le16_to_cpu(non_clock_info->usClassification); 1694 1.1 riastrad rps->class2 = le16_to_cpu(non_clock_info->usClassification2); 1695 1.1 riastrad 1696 1.1 riastrad if (ATOM_PPLIB_NONCLOCKINFO_VER1 < table_rev) { 1697 1.1 riastrad rps->vclk = le32_to_cpu(non_clock_info->ulVCLK); 1698 1.1 riastrad rps->dclk = le32_to_cpu(non_clock_info->ulDCLK); 1699 1.1 riastrad } else { 1700 1.1 riastrad rps->vclk = 0; 1701 1.1 riastrad rps->dclk = 0; 1702 1.1 riastrad } 1703 1.1 riastrad 1704 1.1 riastrad if (rps->class & ATOM_PPLIB_CLASSIFICATION_BOOT) { 1705 1.1 riastrad rdev->pm.dpm.boot_ps = rps; 1706 1.1 riastrad trinity_patch_boot_state(rdev, ps); 1707 1.1 riastrad } 1708 1.1 riastrad if (rps->class & ATOM_PPLIB_CLASSIFICATION_UVDSTATE) 1709 1.1 riastrad rdev->pm.dpm.uvd_ps = rps; 1710 1.1 riastrad } 1711 1.1 riastrad 1712 1.1 riastrad static void trinity_parse_pplib_clock_info(struct radeon_device *rdev, 1713 1.1 riastrad struct radeon_ps *rps, int index, 1714 1.1 riastrad union pplib_clock_info *clock_info) 1715 1.1 riastrad { 1716 1.1 riastrad struct trinity_power_info *pi = trinity_get_pi(rdev); 1717 1.1 riastrad struct trinity_ps *ps = trinity_get_ps(rps); 1718 1.1 riastrad struct trinity_pl *pl = &ps->levels[index]; 1719 1.1 riastrad u32 sclk; 1720 1.1 riastrad 1721 1.1 riastrad sclk = le16_to_cpu(clock_info->sumo.usEngineClockLow); 1722 1.1 riastrad sclk |= clock_info->sumo.ucEngineClockHigh << 16; 1723 1.1 riastrad pl->sclk = sclk; 1724 1.1 riastrad pl->vddc_index = clock_info->sumo.vddcIndex; 1725 1.1 riastrad 1726 1.1 riastrad ps->num_levels = index + 1; 1727 1.1 riastrad 1728 1.1 riastrad if (pi->enable_sclk_ds) { 1729 1.1 riastrad pl->ds_divider_index = 5; 1730 1.1 riastrad pl->ss_divider_index = 5; 1731 1.1 riastrad } 1732 1.1 riastrad } 1733 1.1 riastrad 1734 1.1 riastrad static int trinity_parse_power_table(struct radeon_device *rdev) 1735 1.1 riastrad { 1736 1.1 riastrad struct radeon_mode_info *mode_info = &rdev->mode_info; 1737 1.1 riastrad struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info; 1738 1.1 riastrad union pplib_power_state *power_state; 1739 1.1 riastrad int i, j, k, non_clock_array_index, clock_array_index; 1740 1.1 riastrad union pplib_clock_info *clock_info; 1741 1.1 riastrad struct _StateArray *state_array; 1742 1.1 riastrad struct _ClockInfoArray *clock_info_array; 1743 1.1 riastrad struct _NonClockInfoArray *non_clock_info_array; 1744 1.1 riastrad union power_info *power_info; 1745 1.1 riastrad int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo); 1746 1.3 riastrad u16 data_offset; 1747 1.1 riastrad u8 frev, crev; 1748 1.1 riastrad u8 *power_state_offset; 1749 1.1 riastrad struct sumo_ps *ps; 1750 1.1 riastrad 1751 1.1 riastrad if (!atom_parse_data_header(mode_info->atom_context, index, NULL, 1752 1.1 riastrad &frev, &crev, &data_offset)) 1753 1.1 riastrad return -EINVAL; 1754 1.1 riastrad power_info = (union power_info *)(mode_info->atom_context->bios + data_offset); 1755 1.1 riastrad 1756 1.1 riastrad state_array = (struct _StateArray *) 1757 1.1 riastrad (mode_info->atom_context->bios + data_offset + 1758 1.1 riastrad le16_to_cpu(power_info->pplib.usStateArrayOffset)); 1759 1.1 riastrad clock_info_array = (struct _ClockInfoArray *) 1760 1.1 riastrad (mode_info->atom_context->bios + data_offset + 1761 1.1 riastrad le16_to_cpu(power_info->pplib.usClockInfoArrayOffset)); 1762 1.1 riastrad non_clock_info_array = (struct _NonClockInfoArray *) 1763 1.1 riastrad (mode_info->atom_context->bios + data_offset + 1764 1.1 riastrad le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset)); 1765 1.1 riastrad 1766 1.3 riastrad rdev->pm.dpm.ps = kcalloc(state_array->ucNumEntries, 1767 1.3 riastrad sizeof(struct radeon_ps), 1768 1.3 riastrad GFP_KERNEL); 1769 1.1 riastrad if (!rdev->pm.dpm.ps) 1770 1.1 riastrad return -ENOMEM; 1771 1.1 riastrad power_state_offset = (u8 *)state_array->states; 1772 1.1 riastrad for (i = 0; i < state_array->ucNumEntries; i++) { 1773 1.1 riastrad u8 *idx; 1774 1.1 riastrad power_state = (union pplib_power_state *)power_state_offset; 1775 1.1 riastrad non_clock_array_index = power_state->v2.nonClockInfoIndex; 1776 1.1 riastrad non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) 1777 1.1 riastrad &non_clock_info_array->nonClockInfo[non_clock_array_index]; 1778 1.1 riastrad if (!rdev->pm.power_state[i].clock_info) 1779 1.1 riastrad return -EINVAL; 1780 1.1 riastrad ps = kzalloc(sizeof(struct sumo_ps), GFP_KERNEL); 1781 1.1 riastrad if (ps == NULL) { 1782 1.1 riastrad kfree(rdev->pm.dpm.ps); 1783 1.1 riastrad return -ENOMEM; 1784 1.1 riastrad } 1785 1.1 riastrad rdev->pm.dpm.ps[i].ps_priv = ps; 1786 1.1 riastrad k = 0; 1787 1.1 riastrad idx = (u8 *)&power_state->v2.clockInfoIndex[0]; 1788 1.1 riastrad for (j = 0; j < power_state->v2.ucNumDPMLevels; j++) { 1789 1.1 riastrad clock_array_index = idx[j]; 1790 1.1 riastrad if (clock_array_index >= clock_info_array->ucNumEntries) 1791 1.1 riastrad continue; 1792 1.1 riastrad if (k >= SUMO_MAX_HARDWARE_POWERLEVELS) 1793 1.1 riastrad break; 1794 1.1 riastrad clock_info = (union pplib_clock_info *) 1795 1.1 riastrad ((u8 *)&clock_info_array->clockInfo[0] + 1796 1.1 riastrad (clock_array_index * clock_info_array->ucEntrySize)); 1797 1.1 riastrad trinity_parse_pplib_clock_info(rdev, 1798 1.1 riastrad &rdev->pm.dpm.ps[i], k, 1799 1.1 riastrad clock_info); 1800 1.1 riastrad k++; 1801 1.1 riastrad } 1802 1.1 riastrad trinity_parse_pplib_non_clock_info(rdev, &rdev->pm.dpm.ps[i], 1803 1.1 riastrad non_clock_info, 1804 1.1 riastrad non_clock_info_array->ucEntrySize); 1805 1.1 riastrad power_state_offset += 2 + power_state->v2.ucNumDPMLevels; 1806 1.1 riastrad } 1807 1.1 riastrad rdev->pm.dpm.num_ps = state_array->ucNumEntries; 1808 1.1 riastrad 1809 1.1 riastrad /* fill in the vce power states */ 1810 1.1 riastrad for (i = 0; i < RADEON_MAX_VCE_LEVELS; i++) { 1811 1.1 riastrad u32 sclk; 1812 1.1 riastrad clock_array_index = rdev->pm.dpm.vce_states[i].clk_idx; 1813 1.1 riastrad clock_info = (union pplib_clock_info *) 1814 1.1 riastrad &clock_info_array->clockInfo[clock_array_index * clock_info_array->ucEntrySize]; 1815 1.1 riastrad sclk = le16_to_cpu(clock_info->sumo.usEngineClockLow); 1816 1.1 riastrad sclk |= clock_info->sumo.ucEngineClockHigh << 16; 1817 1.1 riastrad rdev->pm.dpm.vce_states[i].sclk = sclk; 1818 1.1 riastrad rdev->pm.dpm.vce_states[i].mclk = 0; 1819 1.1 riastrad } 1820 1.1 riastrad 1821 1.1 riastrad return 0; 1822 1.1 riastrad } 1823 1.1 riastrad 1824 1.1 riastrad union igp_info { 1825 1.1 riastrad struct _ATOM_INTEGRATED_SYSTEM_INFO info; 1826 1.1 riastrad struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_2; 1827 1.1 riastrad struct _ATOM_INTEGRATED_SYSTEM_INFO_V5 info_5; 1828 1.1 riastrad struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 info_6; 1829 1.1 riastrad struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_7 info_7; 1830 1.1 riastrad }; 1831 1.1 riastrad 1832 1.1 riastrad static u32 trinity_convert_did_to_freq(struct radeon_device *rdev, u8 did) 1833 1.1 riastrad { 1834 1.1 riastrad struct trinity_power_info *pi = trinity_get_pi(rdev); 1835 1.1 riastrad u32 divider; 1836 1.1 riastrad 1837 1.1 riastrad if (did >= 8 && did <= 0x3f) 1838 1.1 riastrad divider = did * 25; 1839 1.1 riastrad else if (did > 0x3f && did <= 0x5f) 1840 1.1 riastrad divider = (did - 64) * 50 + 1600; 1841 1.1 riastrad else if (did > 0x5f && did <= 0x7e) 1842 1.1 riastrad divider = (did - 96) * 100 + 3200; 1843 1.1 riastrad else if (did == 0x7f) 1844 1.1 riastrad divider = 128 * 100; 1845 1.1 riastrad else 1846 1.1 riastrad return 10000; 1847 1.1 riastrad 1848 1.1 riastrad return ((pi->sys_info.dentist_vco_freq * 100) + (divider - 1)) / divider; 1849 1.1 riastrad } 1850 1.1 riastrad 1851 1.1 riastrad static int trinity_parse_sys_info_table(struct radeon_device *rdev) 1852 1.1 riastrad { 1853 1.1 riastrad struct trinity_power_info *pi = trinity_get_pi(rdev); 1854 1.1 riastrad struct radeon_mode_info *mode_info = &rdev->mode_info; 1855 1.1 riastrad int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo); 1856 1.1 riastrad union igp_info *igp_info; 1857 1.1 riastrad u8 frev, crev; 1858 1.1 riastrad u16 data_offset; 1859 1.1 riastrad int i; 1860 1.1 riastrad 1861 1.1 riastrad if (atom_parse_data_header(mode_info->atom_context, index, NULL, 1862 1.1 riastrad &frev, &crev, &data_offset)) { 1863 1.1 riastrad igp_info = (union igp_info *)(mode_info->atom_context->bios + 1864 1.1 riastrad data_offset); 1865 1.1 riastrad 1866 1.1 riastrad if (crev != 7) { 1867 1.1 riastrad DRM_ERROR("Unsupported IGP table: %d %d\n", frev, crev); 1868 1.1 riastrad return -EINVAL; 1869 1.1 riastrad } 1870 1.1 riastrad pi->sys_info.bootup_sclk = le32_to_cpu(igp_info->info_7.ulBootUpEngineClock); 1871 1.1 riastrad pi->sys_info.min_sclk = le32_to_cpu(igp_info->info_7.ulMinEngineClock); 1872 1.1 riastrad pi->sys_info.bootup_uma_clk = le32_to_cpu(igp_info->info_7.ulBootUpUMAClock); 1873 1.1 riastrad pi->sys_info.dentist_vco_freq = le32_to_cpu(igp_info->info_7.ulDentistVCOFreq); 1874 1.1 riastrad pi->sys_info.bootup_nb_voltage_index = 1875 1.1 riastrad le16_to_cpu(igp_info->info_7.usBootUpNBVoltage); 1876 1.1 riastrad if (igp_info->info_7.ucHtcTmpLmt == 0) 1877 1.1 riastrad pi->sys_info.htc_tmp_lmt = 203; 1878 1.1 riastrad else 1879 1.1 riastrad pi->sys_info.htc_tmp_lmt = igp_info->info_7.ucHtcTmpLmt; 1880 1.1 riastrad if (igp_info->info_7.ucHtcHystLmt == 0) 1881 1.1 riastrad pi->sys_info.htc_hyst_lmt = 5; 1882 1.1 riastrad else 1883 1.1 riastrad pi->sys_info.htc_hyst_lmt = igp_info->info_7.ucHtcHystLmt; 1884 1.1 riastrad if (pi->sys_info.htc_tmp_lmt <= pi->sys_info.htc_hyst_lmt) { 1885 1.1 riastrad DRM_ERROR("The htcTmpLmt should be larger than htcHystLmt.\n"); 1886 1.1 riastrad } 1887 1.1 riastrad 1888 1.1 riastrad if (pi->enable_nbps_policy) 1889 1.1 riastrad pi->sys_info.nb_dpm_enable = igp_info->info_7.ucNBDPMEnable; 1890 1.1 riastrad else 1891 1.1 riastrad pi->sys_info.nb_dpm_enable = 0; 1892 1.1 riastrad 1893 1.1 riastrad for (i = 0; i < TRINITY_NUM_NBPSTATES; i++) { 1894 1.1 riastrad pi->sys_info.nbp_mclk[i] = le32_to_cpu(igp_info->info_7.ulNbpStateMemclkFreq[i]); 1895 1.1 riastrad pi->sys_info.nbp_nclk[i] = le32_to_cpu(igp_info->info_7.ulNbpStateNClkFreq[i]); 1896 1.1 riastrad } 1897 1.1 riastrad 1898 1.1 riastrad pi->sys_info.nbp_voltage_index[0] = le16_to_cpu(igp_info->info_7.usNBP0Voltage); 1899 1.1 riastrad pi->sys_info.nbp_voltage_index[1] = le16_to_cpu(igp_info->info_7.usNBP1Voltage); 1900 1.1 riastrad pi->sys_info.nbp_voltage_index[2] = le16_to_cpu(igp_info->info_7.usNBP2Voltage); 1901 1.1 riastrad pi->sys_info.nbp_voltage_index[3] = le16_to_cpu(igp_info->info_7.usNBP3Voltage); 1902 1.1 riastrad 1903 1.1 riastrad if (!pi->sys_info.nb_dpm_enable) { 1904 1.1 riastrad for (i = 1; i < TRINITY_NUM_NBPSTATES; i++) { 1905 1.1 riastrad pi->sys_info.nbp_mclk[i] = pi->sys_info.nbp_mclk[0]; 1906 1.1 riastrad pi->sys_info.nbp_nclk[i] = pi->sys_info.nbp_nclk[0]; 1907 1.1 riastrad pi->sys_info.nbp_voltage_index[i] = pi->sys_info.nbp_voltage_index[0]; 1908 1.1 riastrad } 1909 1.1 riastrad } 1910 1.1 riastrad 1911 1.1 riastrad pi->sys_info.uma_channel_number = igp_info->info_7.ucUMAChannelNumber; 1912 1.1 riastrad 1913 1.1 riastrad sumo_construct_sclk_voltage_mapping_table(rdev, 1914 1.1 riastrad &pi->sys_info.sclk_voltage_mapping_table, 1915 1.1 riastrad igp_info->info_7.sAvail_SCLK); 1916 1.1 riastrad sumo_construct_vid_mapping_table(rdev, &pi->sys_info.vid_mapping_table, 1917 1.1 riastrad igp_info->info_7.sAvail_SCLK); 1918 1.1 riastrad 1919 1.1 riastrad pi->sys_info.uvd_clock_table_entries[0].vclk_did = 1920 1.1 riastrad igp_info->info_7.ucDPMState0VclkFid; 1921 1.1 riastrad pi->sys_info.uvd_clock_table_entries[1].vclk_did = 1922 1.1 riastrad igp_info->info_7.ucDPMState1VclkFid; 1923 1.1 riastrad pi->sys_info.uvd_clock_table_entries[2].vclk_did = 1924 1.1 riastrad igp_info->info_7.ucDPMState2VclkFid; 1925 1.1 riastrad pi->sys_info.uvd_clock_table_entries[3].vclk_did = 1926 1.1 riastrad igp_info->info_7.ucDPMState3VclkFid; 1927 1.1 riastrad 1928 1.1 riastrad pi->sys_info.uvd_clock_table_entries[0].dclk_did = 1929 1.1 riastrad igp_info->info_7.ucDPMState0DclkFid; 1930 1.1 riastrad pi->sys_info.uvd_clock_table_entries[1].dclk_did = 1931 1.1 riastrad igp_info->info_7.ucDPMState1DclkFid; 1932 1.1 riastrad pi->sys_info.uvd_clock_table_entries[2].dclk_did = 1933 1.1 riastrad igp_info->info_7.ucDPMState2DclkFid; 1934 1.1 riastrad pi->sys_info.uvd_clock_table_entries[3].dclk_did = 1935 1.1 riastrad igp_info->info_7.ucDPMState3DclkFid; 1936 1.1 riastrad 1937 1.1 riastrad for (i = 0; i < 4; i++) { 1938 1.1 riastrad pi->sys_info.uvd_clock_table_entries[i].vclk = 1939 1.1 riastrad trinity_convert_did_to_freq(rdev, 1940 1.1 riastrad pi->sys_info.uvd_clock_table_entries[i].vclk_did); 1941 1.1 riastrad pi->sys_info.uvd_clock_table_entries[i].dclk = 1942 1.1 riastrad trinity_convert_did_to_freq(rdev, 1943 1.1 riastrad pi->sys_info.uvd_clock_table_entries[i].dclk_did); 1944 1.1 riastrad } 1945 1.1 riastrad 1946 1.1 riastrad 1947 1.1 riastrad 1948 1.1 riastrad } 1949 1.1 riastrad return 0; 1950 1.1 riastrad } 1951 1.1 riastrad 1952 1.1 riastrad int trinity_dpm_init(struct radeon_device *rdev) 1953 1.1 riastrad { 1954 1.1 riastrad struct trinity_power_info *pi; 1955 1.1 riastrad int ret, i; 1956 1.1 riastrad 1957 1.1 riastrad pi = kzalloc(sizeof(struct trinity_power_info), GFP_KERNEL); 1958 1.1 riastrad if (pi == NULL) 1959 1.1 riastrad return -ENOMEM; 1960 1.1 riastrad rdev->pm.dpm.priv = pi; 1961 1.1 riastrad 1962 1.1 riastrad for (i = 0; i < SUMO_MAX_HARDWARE_POWERLEVELS; i++) 1963 1.1 riastrad pi->at[i] = TRINITY_AT_DFLT; 1964 1.1 riastrad 1965 1.1 riastrad if (radeon_bapm == -1) { 1966 1.1 riastrad /* There are stability issues reported on with 1967 1.1 riastrad * bapm enabled when switching between AC and battery 1968 1.1 riastrad * power. At the same time, some MSI boards hang 1969 1.1 riastrad * if it's not enabled and dpm is enabled. Just enable 1970 1.1 riastrad * it for MSI boards right now. 1971 1.1 riastrad */ 1972 1.1 riastrad if (rdev->pdev->subsystem_vendor == 0x1462) 1973 1.1 riastrad pi->enable_bapm = true; 1974 1.1 riastrad else 1975 1.1 riastrad pi->enable_bapm = false; 1976 1.1 riastrad } else if (radeon_bapm == 0) { 1977 1.1 riastrad pi->enable_bapm = false; 1978 1.1 riastrad } else { 1979 1.1 riastrad pi->enable_bapm = true; 1980 1.1 riastrad } 1981 1.1 riastrad pi->enable_nbps_policy = true; 1982 1.1 riastrad pi->enable_sclk_ds = true; 1983 1.1 riastrad pi->enable_gfx_power_gating = true; 1984 1.1 riastrad pi->enable_gfx_clock_gating = true; 1985 1.1 riastrad pi->enable_mg_clock_gating = false; 1986 1.1 riastrad pi->enable_gfx_dynamic_mgpg = false; 1987 1.1 riastrad pi->override_dynamic_mgpg = false; 1988 1.1 riastrad pi->enable_auto_thermal_throttling = true; 1989 1.1 riastrad pi->voltage_drop_in_dce = false; /* need to restructure dpm/modeset interaction */ 1990 1.1 riastrad pi->uvd_dpm = true; /* ??? */ 1991 1.1 riastrad 1992 1.1 riastrad ret = trinity_parse_sys_info_table(rdev); 1993 1.1 riastrad if (ret) 1994 1.1 riastrad return ret; 1995 1.1 riastrad 1996 1.1 riastrad trinity_construct_boot_state(rdev); 1997 1.1 riastrad 1998 1.1 riastrad ret = r600_get_platform_caps(rdev); 1999 1.1 riastrad if (ret) 2000 1.1 riastrad return ret; 2001 1.1 riastrad 2002 1.1 riastrad ret = r600_parse_extended_power_table(rdev); 2003 1.1 riastrad if (ret) 2004 1.1 riastrad return ret; 2005 1.1 riastrad 2006 1.1 riastrad ret = trinity_parse_power_table(rdev); 2007 1.1 riastrad if (ret) 2008 1.1 riastrad return ret; 2009 1.1 riastrad 2010 1.1 riastrad pi->thermal_auto_throttling = pi->sys_info.htc_tmp_lmt; 2011 1.1 riastrad pi->enable_dpm = true; 2012 1.1 riastrad 2013 1.1 riastrad return 0; 2014 1.1 riastrad } 2015 1.1 riastrad 2016 1.1 riastrad void trinity_dpm_print_power_state(struct radeon_device *rdev, 2017 1.1 riastrad struct radeon_ps *rps) 2018 1.1 riastrad { 2019 1.1 riastrad int i; 2020 1.1 riastrad struct trinity_ps *ps = trinity_get_ps(rps); 2021 1.1 riastrad 2022 1.1 riastrad r600_dpm_print_class_info(rps->class, rps->class2); 2023 1.1 riastrad r600_dpm_print_cap_info(rps->caps); 2024 1.1 riastrad printk("\tuvd vclk: %d dclk: %d\n", rps->vclk, rps->dclk); 2025 1.1 riastrad for (i = 0; i < ps->num_levels; i++) { 2026 1.1 riastrad struct trinity_pl *pl = &ps->levels[i]; 2027 1.1 riastrad printk("\t\tpower level %d sclk: %u vddc: %u\n", 2028 1.1 riastrad i, pl->sclk, 2029 1.1 riastrad trinity_convert_voltage_index_to_value(rdev, pl->vddc_index)); 2030 1.1 riastrad } 2031 1.1 riastrad r600_dpm_print_ps_status(rdev, rps); 2032 1.1 riastrad } 2033 1.1 riastrad 2034 1.1 riastrad #ifdef CONFIG_DEBUG_FS 2035 1.1 riastrad void trinity_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev, 2036 1.1 riastrad struct seq_file *m) 2037 1.1 riastrad { 2038 1.1 riastrad struct trinity_power_info *pi = trinity_get_pi(rdev); 2039 1.1 riastrad struct radeon_ps *rps = &pi->current_rps; 2040 1.1 riastrad struct trinity_ps *ps = trinity_get_ps(rps); 2041 1.1 riastrad struct trinity_pl *pl; 2042 1.1 riastrad u32 current_index = 2043 1.1 riastrad (RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_STATE_MASK) >> 2044 1.1 riastrad CURRENT_STATE_SHIFT; 2045 1.1 riastrad 2046 1.1 riastrad if (current_index >= ps->num_levels) { 2047 1.1 riastrad seq_printf(m, "invalid dpm profile %d\n", current_index); 2048 1.1 riastrad } else { 2049 1.1 riastrad pl = &ps->levels[current_index]; 2050 1.1 riastrad seq_printf(m, "uvd vclk: %d dclk: %d\n", rps->vclk, rps->dclk); 2051 1.1 riastrad seq_printf(m, "power level %d sclk: %u vddc: %u\n", 2052 1.1 riastrad current_index, pl->sclk, 2053 1.1 riastrad trinity_convert_voltage_index_to_value(rdev, pl->vddc_index)); 2054 1.1 riastrad } 2055 1.1 riastrad } 2056 1.1 riastrad #endif 2057 1.1 riastrad 2058 1.1 riastrad u32 trinity_dpm_get_current_sclk(struct radeon_device *rdev) 2059 1.1 riastrad { 2060 1.1 riastrad struct trinity_power_info *pi = trinity_get_pi(rdev); 2061 1.1 riastrad struct radeon_ps *rps = &pi->current_rps; 2062 1.1 riastrad struct trinity_ps *ps = trinity_get_ps(rps); 2063 1.1 riastrad struct trinity_pl *pl; 2064 1.1 riastrad u32 current_index = 2065 1.1 riastrad (RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_STATE_MASK) >> 2066 1.1 riastrad CURRENT_STATE_SHIFT; 2067 1.1 riastrad 2068 1.1 riastrad if (current_index >= ps->num_levels) { 2069 1.1 riastrad return 0; 2070 1.1 riastrad } else { 2071 1.1 riastrad pl = &ps->levels[current_index]; 2072 1.1 riastrad return pl->sclk; 2073 1.1 riastrad } 2074 1.1 riastrad } 2075 1.1 riastrad 2076 1.1 riastrad u32 trinity_dpm_get_current_mclk(struct radeon_device *rdev) 2077 1.1 riastrad { 2078 1.1 riastrad struct trinity_power_info *pi = trinity_get_pi(rdev); 2079 1.1 riastrad 2080 1.1 riastrad return pi->sys_info.bootup_uma_clk; 2081 1.1 riastrad } 2082 1.1 riastrad 2083 1.1 riastrad void trinity_dpm_fini(struct radeon_device *rdev) 2084 1.1 riastrad { 2085 1.1 riastrad int i; 2086 1.1 riastrad 2087 1.1 riastrad trinity_cleanup_asic(rdev); /* ??? */ 2088 1.1 riastrad 2089 1.1 riastrad for (i = 0; i < rdev->pm.dpm.num_ps; i++) { 2090 1.1 riastrad kfree(rdev->pm.dpm.ps[i].ps_priv); 2091 1.1 riastrad } 2092 1.1 riastrad kfree(rdev->pm.dpm.ps); 2093 1.1 riastrad kfree(rdev->pm.dpm.priv); 2094 1.1 riastrad r600_free_extended_power_table(rdev); 2095 1.1 riastrad } 2096 1.1 riastrad 2097 1.1 riastrad u32 trinity_dpm_get_sclk(struct radeon_device *rdev, bool low) 2098 1.1 riastrad { 2099 1.1 riastrad struct trinity_power_info *pi = trinity_get_pi(rdev); 2100 1.1 riastrad struct trinity_ps *requested_state = trinity_get_ps(&pi->requested_rps); 2101 1.1 riastrad 2102 1.1 riastrad if (low) 2103 1.1 riastrad return requested_state->levels[0].sclk; 2104 1.1 riastrad else 2105 1.1 riastrad return requested_state->levels[requested_state->num_levels - 1].sclk; 2106 1.1 riastrad } 2107 1.1 riastrad 2108 1.1 riastrad u32 trinity_dpm_get_mclk(struct radeon_device *rdev, bool low) 2109 1.1 riastrad { 2110 1.1 riastrad struct trinity_power_info *pi = trinity_get_pi(rdev); 2111 1.1 riastrad 2112 1.1 riastrad return pi->sys_info.bootup_uma_clk; 2113 1.1 riastrad } 2114