| .. | .. |
|---|
| 23 | 23 | */ |
|---|
| 24 | 24 | |
|---|
| 25 | 25 | #include <drm/drm_print.h> |
|---|
| 26 | +#include <drm/i915_pciids.h> |
|---|
| 26 | 27 | |
|---|
| 28 | +#include "display/intel_cdclk.h" |
|---|
| 29 | +#include "display/intel_de.h" |
|---|
| 27 | 30 | #include "intel_device_info.h" |
|---|
| 28 | 31 | #include "i915_drv.h" |
|---|
| 29 | 32 | |
|---|
| .. | .. |
|---|
| 55 | 58 | PLATFORM_NAME(KABYLAKE), |
|---|
| 56 | 59 | PLATFORM_NAME(GEMINILAKE), |
|---|
| 57 | 60 | PLATFORM_NAME(COFFEELAKE), |
|---|
| 61 | + PLATFORM_NAME(COMETLAKE), |
|---|
| 58 | 62 | PLATFORM_NAME(CANNONLAKE), |
|---|
| 59 | 63 | PLATFORM_NAME(ICELAKE), |
|---|
| 64 | + PLATFORM_NAME(ELKHARTLAKE), |
|---|
| 65 | + PLATFORM_NAME(TIGERLAKE), |
|---|
| 66 | + PLATFORM_NAME(ROCKETLAKE), |
|---|
| 67 | + PLATFORM_NAME(DG1), |
|---|
| 60 | 68 | }; |
|---|
| 61 | 69 | #undef PLATFORM_NAME |
|---|
| 62 | 70 | |
|---|
| .. | .. |
|---|
| 71 | 79 | return platform_names[platform]; |
|---|
| 72 | 80 | } |
|---|
| 73 | 81 | |
|---|
| 74 | | -void intel_device_info_dump_flags(const struct intel_device_info *info, |
|---|
| 75 | | - struct drm_printer *p) |
|---|
| 82 | +static const char *iommu_name(void) |
|---|
| 76 | 83 | { |
|---|
| 84 | + const char *msg = "n/a"; |
|---|
| 85 | + |
|---|
| 86 | +#ifdef CONFIG_INTEL_IOMMU |
|---|
| 87 | + msg = enableddisabled(intel_iommu_gfx_mapped); |
|---|
| 88 | +#endif |
|---|
| 89 | + |
|---|
| 90 | + return msg; |
|---|
| 91 | +} |
|---|
| 92 | + |
|---|
| 93 | +void intel_device_info_print_static(const struct intel_device_info *info, |
|---|
| 94 | + struct drm_printer *p) |
|---|
| 95 | +{ |
|---|
| 96 | + drm_printf(p, "gen: %d\n", info->gen); |
|---|
| 97 | + drm_printf(p, "gt: %d\n", info->gt); |
|---|
| 98 | + drm_printf(p, "iommu: %s\n", iommu_name()); |
|---|
| 99 | + drm_printf(p, "memory-regions: %x\n", info->memory_regions); |
|---|
| 100 | + drm_printf(p, "page-sizes: %x\n", info->page_sizes); |
|---|
| 101 | + drm_printf(p, "platform: %s\n", intel_platform_name(info->platform)); |
|---|
| 102 | + drm_printf(p, "ppgtt-size: %d\n", info->ppgtt_size); |
|---|
| 103 | + drm_printf(p, "ppgtt-type: %d\n", info->ppgtt_type); |
|---|
| 104 | + drm_printf(p, "dma_mask_size: %u\n", info->dma_mask_size); |
|---|
| 105 | + |
|---|
| 77 | 106 | #define PRINT_FLAG(name) drm_printf(p, "%s: %s\n", #name, yesno(info->name)); |
|---|
| 78 | 107 | DEV_INFO_FOR_EACH_FLAG(PRINT_FLAG); |
|---|
| 79 | 108 | #undef PRINT_FLAG |
|---|
| 109 | + |
|---|
| 110 | +#define PRINT_FLAG(name) drm_printf(p, "%s: %s\n", #name, yesno(info->display.name)); |
|---|
| 111 | + DEV_INFO_DISPLAY_FOR_EACH_FLAG(PRINT_FLAG); |
|---|
| 112 | +#undef PRINT_FLAG |
|---|
| 80 | 113 | } |
|---|
| 81 | 114 | |
|---|
| 82 | | -static void sseu_dump(const struct sseu_dev_info *sseu, struct drm_printer *p) |
|---|
| 83 | | -{ |
|---|
| 84 | | - int s; |
|---|
| 85 | | - |
|---|
| 86 | | - drm_printf(p, "slice total: %u, mask=%04x\n", |
|---|
| 87 | | - hweight8(sseu->slice_mask), sseu->slice_mask); |
|---|
| 88 | | - drm_printf(p, "subslice total: %u\n", sseu_subslice_total(sseu)); |
|---|
| 89 | | - for (s = 0; s < sseu->max_slices; s++) { |
|---|
| 90 | | - drm_printf(p, "slice%d: %u subslices, mask=%04x\n", |
|---|
| 91 | | - s, hweight8(sseu->subslice_mask[s]), |
|---|
| 92 | | - sseu->subslice_mask[s]); |
|---|
| 93 | | - } |
|---|
| 94 | | - drm_printf(p, "EU total: %u\n", sseu->eu_total); |
|---|
| 95 | | - drm_printf(p, "EU per subslice: %u\n", sseu->eu_per_subslice); |
|---|
| 96 | | - drm_printf(p, "has slice power gating: %s\n", |
|---|
| 97 | | - yesno(sseu->has_slice_pg)); |
|---|
| 98 | | - drm_printf(p, "has subslice power gating: %s\n", |
|---|
| 99 | | - yesno(sseu->has_subslice_pg)); |
|---|
| 100 | | - drm_printf(p, "has EU power gating: %s\n", yesno(sseu->has_eu_pg)); |
|---|
| 101 | | -} |
|---|
| 102 | | - |
|---|
| 103 | | -void intel_device_info_dump_runtime(const struct intel_device_info *info, |
|---|
| 104 | | - struct drm_printer *p) |
|---|
| 105 | | -{ |
|---|
| 106 | | - sseu_dump(&info->sseu, p); |
|---|
| 107 | | - |
|---|
| 108 | | - drm_printf(p, "CS timestamp frequency: %u kHz\n", |
|---|
| 109 | | - info->cs_timestamp_frequency_khz); |
|---|
| 110 | | -} |
|---|
| 111 | | - |
|---|
| 112 | | -void intel_device_info_dump(const struct intel_device_info *info, |
|---|
| 113 | | - struct drm_printer *p) |
|---|
| 114 | | -{ |
|---|
| 115 | | - struct drm_i915_private *dev_priv = |
|---|
| 116 | | - container_of(info, struct drm_i915_private, info); |
|---|
| 117 | | - |
|---|
| 118 | | - drm_printf(p, "pciid=0x%04x rev=0x%02x platform=%s gen=%i\n", |
|---|
| 119 | | - INTEL_DEVID(dev_priv), |
|---|
| 120 | | - INTEL_REVID(dev_priv), |
|---|
| 121 | | - intel_platform_name(info->platform), |
|---|
| 122 | | - info->gen); |
|---|
| 123 | | - |
|---|
| 124 | | - intel_device_info_dump_flags(info, p); |
|---|
| 125 | | -} |
|---|
| 126 | | - |
|---|
| 127 | | -void intel_device_info_dump_topology(const struct sseu_dev_info *sseu, |
|---|
| 115 | +void intel_device_info_print_runtime(const struct intel_runtime_info *info, |
|---|
| 128 | 116 | struct drm_printer *p) |
|---|
| 129 | 117 | { |
|---|
| 130 | | - int s, ss; |
|---|
| 131 | | - |
|---|
| 132 | | - if (sseu->max_slices == 0) { |
|---|
| 133 | | - drm_printf(p, "Unavailable\n"); |
|---|
| 134 | | - return; |
|---|
| 135 | | - } |
|---|
| 136 | | - |
|---|
| 137 | | - for (s = 0; s < sseu->max_slices; s++) { |
|---|
| 138 | | - drm_printf(p, "slice%d: %u subslice(s) (0x%hhx):\n", |
|---|
| 139 | | - s, hweight8(sseu->subslice_mask[s]), |
|---|
| 140 | | - sseu->subslice_mask[s]); |
|---|
| 141 | | - |
|---|
| 142 | | - for (ss = 0; ss < sseu->max_subslices; ss++) { |
|---|
| 143 | | - u16 enabled_eus = sseu_get_eus(sseu, s, ss); |
|---|
| 144 | | - |
|---|
| 145 | | - drm_printf(p, "\tsubslice%d: %u EUs (0x%hx)\n", |
|---|
| 146 | | - ss, hweight16(enabled_eus), enabled_eus); |
|---|
| 147 | | - } |
|---|
| 148 | | - } |
|---|
| 149 | | -} |
|---|
| 150 | | - |
|---|
| 151 | | -static u16 compute_eu_total(const struct sseu_dev_info *sseu) |
|---|
| 152 | | -{ |
|---|
| 153 | | - u16 i, total = 0; |
|---|
| 154 | | - |
|---|
| 155 | | - for (i = 0; i < ARRAY_SIZE(sseu->eu_mask); i++) |
|---|
| 156 | | - total += hweight8(sseu->eu_mask[i]); |
|---|
| 157 | | - |
|---|
| 158 | | - return total; |
|---|
| 159 | | -} |
|---|
| 160 | | - |
|---|
| 161 | | -static void gen11_sseu_info_init(struct drm_i915_private *dev_priv) |
|---|
| 162 | | -{ |
|---|
| 163 | | - struct sseu_dev_info *sseu = &mkwrite_device_info(dev_priv)->sseu; |
|---|
| 164 | | - u8 s_en; |
|---|
| 165 | | - u32 ss_en, ss_en_mask; |
|---|
| 166 | | - u8 eu_en; |
|---|
| 167 | | - int s; |
|---|
| 168 | | - |
|---|
| 169 | | - sseu->max_slices = 1; |
|---|
| 170 | | - sseu->max_subslices = 8; |
|---|
| 171 | | - sseu->max_eus_per_subslice = 8; |
|---|
| 172 | | - |
|---|
| 173 | | - s_en = I915_READ(GEN11_GT_SLICE_ENABLE) & GEN11_GT_S_ENA_MASK; |
|---|
| 174 | | - ss_en = ~I915_READ(GEN11_GT_SUBSLICE_DISABLE); |
|---|
| 175 | | - ss_en_mask = BIT(sseu->max_subslices) - 1; |
|---|
| 176 | | - eu_en = ~(I915_READ(GEN11_EU_DISABLE) & GEN11_EU_DIS_MASK); |
|---|
| 177 | | - |
|---|
| 178 | | - for (s = 0; s < sseu->max_slices; s++) { |
|---|
| 179 | | - if (s_en & BIT(s)) { |
|---|
| 180 | | - int ss_idx = sseu->max_subslices * s; |
|---|
| 181 | | - int ss; |
|---|
| 182 | | - |
|---|
| 183 | | - sseu->slice_mask |= BIT(s); |
|---|
| 184 | | - sseu->subslice_mask[s] = (ss_en >> ss_idx) & ss_en_mask; |
|---|
| 185 | | - for (ss = 0; ss < sseu->max_subslices; ss++) { |
|---|
| 186 | | - if (sseu->subslice_mask[s] & BIT(ss)) |
|---|
| 187 | | - sseu_set_eus(sseu, s, ss, eu_en); |
|---|
| 188 | | - } |
|---|
| 189 | | - } |
|---|
| 190 | | - } |
|---|
| 191 | | - sseu->eu_per_subslice = hweight8(eu_en); |
|---|
| 192 | | - sseu->eu_total = compute_eu_total(sseu); |
|---|
| 193 | | - |
|---|
| 194 | | - /* ICL has no power gating restrictions. */ |
|---|
| 195 | | - sseu->has_slice_pg = 1; |
|---|
| 196 | | - sseu->has_subslice_pg = 1; |
|---|
| 197 | | - sseu->has_eu_pg = 1; |
|---|
| 198 | | -} |
|---|
| 199 | | - |
|---|
| 200 | | -static void gen10_sseu_info_init(struct drm_i915_private *dev_priv) |
|---|
| 201 | | -{ |
|---|
| 202 | | - struct sseu_dev_info *sseu = &mkwrite_device_info(dev_priv)->sseu; |
|---|
| 203 | | - const u32 fuse2 = I915_READ(GEN8_FUSE2); |
|---|
| 204 | | - int s, ss; |
|---|
| 205 | | - const int eu_mask = 0xff; |
|---|
| 206 | | - u32 subslice_mask, eu_en; |
|---|
| 207 | | - |
|---|
| 208 | | - sseu->slice_mask = (fuse2 & GEN10_F2_S_ENA_MASK) >> |
|---|
| 209 | | - GEN10_F2_S_ENA_SHIFT; |
|---|
| 210 | | - sseu->max_slices = 6; |
|---|
| 211 | | - sseu->max_subslices = 4; |
|---|
| 212 | | - sseu->max_eus_per_subslice = 8; |
|---|
| 213 | | - |
|---|
| 214 | | - subslice_mask = (1 << 4) - 1; |
|---|
| 215 | | - subslice_mask &= ~((fuse2 & GEN10_F2_SS_DIS_MASK) >> |
|---|
| 216 | | - GEN10_F2_SS_DIS_SHIFT); |
|---|
| 217 | | - |
|---|
| 218 | | - /* |
|---|
| 219 | | - * Slice0 can have up to 3 subslices, but there are only 2 in |
|---|
| 220 | | - * slice1/2. |
|---|
| 221 | | - */ |
|---|
| 222 | | - sseu->subslice_mask[0] = subslice_mask; |
|---|
| 223 | | - for (s = 1; s < sseu->max_slices; s++) |
|---|
| 224 | | - sseu->subslice_mask[s] = subslice_mask & 0x3; |
|---|
| 225 | | - |
|---|
| 226 | | - /* Slice0 */ |
|---|
| 227 | | - eu_en = ~I915_READ(GEN8_EU_DISABLE0); |
|---|
| 228 | | - for (ss = 0; ss < sseu->max_subslices; ss++) |
|---|
| 229 | | - sseu_set_eus(sseu, 0, ss, (eu_en >> (8 * ss)) & eu_mask); |
|---|
| 230 | | - /* Slice1 */ |
|---|
| 231 | | - sseu_set_eus(sseu, 1, 0, (eu_en >> 24) & eu_mask); |
|---|
| 232 | | - eu_en = ~I915_READ(GEN8_EU_DISABLE1); |
|---|
| 233 | | - sseu_set_eus(sseu, 1, 1, eu_en & eu_mask); |
|---|
| 234 | | - /* Slice2 */ |
|---|
| 235 | | - sseu_set_eus(sseu, 2, 0, (eu_en >> 8) & eu_mask); |
|---|
| 236 | | - sseu_set_eus(sseu, 2, 1, (eu_en >> 16) & eu_mask); |
|---|
| 237 | | - /* Slice3 */ |
|---|
| 238 | | - sseu_set_eus(sseu, 3, 0, (eu_en >> 24) & eu_mask); |
|---|
| 239 | | - eu_en = ~I915_READ(GEN8_EU_DISABLE2); |
|---|
| 240 | | - sseu_set_eus(sseu, 3, 1, eu_en & eu_mask); |
|---|
| 241 | | - /* Slice4 */ |
|---|
| 242 | | - sseu_set_eus(sseu, 4, 0, (eu_en >> 8) & eu_mask); |
|---|
| 243 | | - sseu_set_eus(sseu, 4, 1, (eu_en >> 16) & eu_mask); |
|---|
| 244 | | - /* Slice5 */ |
|---|
| 245 | | - sseu_set_eus(sseu, 5, 0, (eu_en >> 24) & eu_mask); |
|---|
| 246 | | - eu_en = ~I915_READ(GEN10_EU_DISABLE3); |
|---|
| 247 | | - sseu_set_eus(sseu, 5, 1, eu_en & eu_mask); |
|---|
| 248 | | - |
|---|
| 249 | | - /* Do a second pass where we mark the subslices disabled if all their |
|---|
| 250 | | - * eus are off. |
|---|
| 251 | | - */ |
|---|
| 252 | | - for (s = 0; s < sseu->max_slices; s++) { |
|---|
| 253 | | - for (ss = 0; ss < sseu->max_subslices; ss++) { |
|---|
| 254 | | - if (sseu_get_eus(sseu, s, ss) == 0) |
|---|
| 255 | | - sseu->subslice_mask[s] &= ~BIT(ss); |
|---|
| 256 | | - } |
|---|
| 257 | | - } |
|---|
| 258 | | - |
|---|
| 259 | | - sseu->eu_total = compute_eu_total(sseu); |
|---|
| 260 | | - |
|---|
| 261 | | - /* |
|---|
| 262 | | - * CNL is expected to always have a uniform distribution |
|---|
| 263 | | - * of EU across subslices with the exception that any one |
|---|
| 264 | | - * EU in any one subslice may be fused off for die |
|---|
| 265 | | - * recovery. |
|---|
| 266 | | - */ |
|---|
| 267 | | - sseu->eu_per_subslice = sseu_subslice_total(sseu) ? |
|---|
| 268 | | - DIV_ROUND_UP(sseu->eu_total, |
|---|
| 269 | | - sseu_subslice_total(sseu)) : 0; |
|---|
| 270 | | - |
|---|
| 271 | | - /* No restrictions on Power Gating */ |
|---|
| 272 | | - sseu->has_slice_pg = 1; |
|---|
| 273 | | - sseu->has_subslice_pg = 1; |
|---|
| 274 | | - sseu->has_eu_pg = 1; |
|---|
| 275 | | -} |
|---|
| 276 | | - |
|---|
| 277 | | -static void cherryview_sseu_info_init(struct drm_i915_private *dev_priv) |
|---|
| 278 | | -{ |
|---|
| 279 | | - struct sseu_dev_info *sseu = &mkwrite_device_info(dev_priv)->sseu; |
|---|
| 280 | | - u32 fuse; |
|---|
| 281 | | - |
|---|
| 282 | | - fuse = I915_READ(CHV_FUSE_GT); |
|---|
| 283 | | - |
|---|
| 284 | | - sseu->slice_mask = BIT(0); |
|---|
| 285 | | - sseu->max_slices = 1; |
|---|
| 286 | | - sseu->max_subslices = 2; |
|---|
| 287 | | - sseu->max_eus_per_subslice = 8; |
|---|
| 288 | | - |
|---|
| 289 | | - if (!(fuse & CHV_FGT_DISABLE_SS0)) { |
|---|
| 290 | | - u8 disabled_mask = |
|---|
| 291 | | - ((fuse & CHV_FGT_EU_DIS_SS0_R0_MASK) >> |
|---|
| 292 | | - CHV_FGT_EU_DIS_SS0_R0_SHIFT) | |
|---|
| 293 | | - (((fuse & CHV_FGT_EU_DIS_SS0_R1_MASK) >> |
|---|
| 294 | | - CHV_FGT_EU_DIS_SS0_R1_SHIFT) << 4); |
|---|
| 295 | | - |
|---|
| 296 | | - sseu->subslice_mask[0] |= BIT(0); |
|---|
| 297 | | - sseu_set_eus(sseu, 0, 0, ~disabled_mask); |
|---|
| 298 | | - } |
|---|
| 299 | | - |
|---|
| 300 | | - if (!(fuse & CHV_FGT_DISABLE_SS1)) { |
|---|
| 301 | | - u8 disabled_mask = |
|---|
| 302 | | - ((fuse & CHV_FGT_EU_DIS_SS1_R0_MASK) >> |
|---|
| 303 | | - CHV_FGT_EU_DIS_SS1_R0_SHIFT) | |
|---|
| 304 | | - (((fuse & CHV_FGT_EU_DIS_SS1_R1_MASK) >> |
|---|
| 305 | | - CHV_FGT_EU_DIS_SS1_R1_SHIFT) << 4); |
|---|
| 306 | | - |
|---|
| 307 | | - sseu->subslice_mask[0] |= BIT(1); |
|---|
| 308 | | - sseu_set_eus(sseu, 0, 1, ~disabled_mask); |
|---|
| 309 | | - } |
|---|
| 310 | | - |
|---|
| 311 | | - sseu->eu_total = compute_eu_total(sseu); |
|---|
| 312 | | - |
|---|
| 313 | | - /* |
|---|
| 314 | | - * CHV expected to always have a uniform distribution of EU |
|---|
| 315 | | - * across subslices. |
|---|
| 316 | | - */ |
|---|
| 317 | | - sseu->eu_per_subslice = sseu_subslice_total(sseu) ? |
|---|
| 318 | | - sseu->eu_total / sseu_subslice_total(sseu) : |
|---|
| 319 | | - 0; |
|---|
| 320 | | - /* |
|---|
| 321 | | - * CHV supports subslice power gating on devices with more than |
|---|
| 322 | | - * one subslice, and supports EU power gating on devices with |
|---|
| 323 | | - * more than one EU pair per subslice. |
|---|
| 324 | | - */ |
|---|
| 325 | | - sseu->has_slice_pg = 0; |
|---|
| 326 | | - sseu->has_subslice_pg = sseu_subslice_total(sseu) > 1; |
|---|
| 327 | | - sseu->has_eu_pg = (sseu->eu_per_subslice > 2); |
|---|
| 328 | | -} |
|---|
| 329 | | - |
|---|
| 330 | | -static void gen9_sseu_info_init(struct drm_i915_private *dev_priv) |
|---|
| 331 | | -{ |
|---|
| 332 | | - struct intel_device_info *info = mkwrite_device_info(dev_priv); |
|---|
| 333 | | - struct sseu_dev_info *sseu = &info->sseu; |
|---|
| 334 | | - int s, ss; |
|---|
| 335 | | - u32 fuse2, eu_disable, subslice_mask; |
|---|
| 336 | | - const u8 eu_mask = 0xff; |
|---|
| 337 | | - |
|---|
| 338 | | - fuse2 = I915_READ(GEN8_FUSE2); |
|---|
| 339 | | - sseu->slice_mask = (fuse2 & GEN8_F2_S_ENA_MASK) >> GEN8_F2_S_ENA_SHIFT; |
|---|
| 340 | | - |
|---|
| 341 | | - /* BXT has a single slice and at most 3 subslices. */ |
|---|
| 342 | | - sseu->max_slices = IS_GEN9_LP(dev_priv) ? 1 : 3; |
|---|
| 343 | | - sseu->max_subslices = IS_GEN9_LP(dev_priv) ? 3 : 4; |
|---|
| 344 | | - sseu->max_eus_per_subslice = 8; |
|---|
| 345 | | - |
|---|
| 346 | | - /* |
|---|
| 347 | | - * The subslice disable field is global, i.e. it applies |
|---|
| 348 | | - * to each of the enabled slices. |
|---|
| 349 | | - */ |
|---|
| 350 | | - subslice_mask = (1 << sseu->max_subslices) - 1; |
|---|
| 351 | | - subslice_mask &= ~((fuse2 & GEN9_F2_SS_DIS_MASK) >> |
|---|
| 352 | | - GEN9_F2_SS_DIS_SHIFT); |
|---|
| 353 | | - |
|---|
| 354 | | - /* |
|---|
| 355 | | - * Iterate through enabled slices and subslices to |
|---|
| 356 | | - * count the total enabled EU. |
|---|
| 357 | | - */ |
|---|
| 358 | | - for (s = 0; s < sseu->max_slices; s++) { |
|---|
| 359 | | - if (!(sseu->slice_mask & BIT(s))) |
|---|
| 360 | | - /* skip disabled slice */ |
|---|
| 361 | | - continue; |
|---|
| 362 | | - |
|---|
| 363 | | - sseu->subslice_mask[s] = subslice_mask; |
|---|
| 364 | | - |
|---|
| 365 | | - eu_disable = I915_READ(GEN9_EU_DISABLE(s)); |
|---|
| 366 | | - for (ss = 0; ss < sseu->max_subslices; ss++) { |
|---|
| 367 | | - int eu_per_ss; |
|---|
| 368 | | - u8 eu_disabled_mask; |
|---|
| 369 | | - |
|---|
| 370 | | - if (!(sseu->subslice_mask[s] & BIT(ss))) |
|---|
| 371 | | - /* skip disabled subslice */ |
|---|
| 372 | | - continue; |
|---|
| 373 | | - |
|---|
| 374 | | - eu_disabled_mask = (eu_disable >> (ss * 8)) & eu_mask; |
|---|
| 375 | | - |
|---|
| 376 | | - sseu_set_eus(sseu, s, ss, ~eu_disabled_mask); |
|---|
| 377 | | - |
|---|
| 378 | | - eu_per_ss = sseu->max_eus_per_subslice - |
|---|
| 379 | | - hweight8(eu_disabled_mask); |
|---|
| 380 | | - |
|---|
| 381 | | - /* |
|---|
| 382 | | - * Record which subslice(s) has(have) 7 EUs. we |
|---|
| 383 | | - * can tune the hash used to spread work among |
|---|
| 384 | | - * subslices if they are unbalanced. |
|---|
| 385 | | - */ |
|---|
| 386 | | - if (eu_per_ss == 7) |
|---|
| 387 | | - sseu->subslice_7eu[s] |= BIT(ss); |
|---|
| 388 | | - } |
|---|
| 389 | | - } |
|---|
| 390 | | - |
|---|
| 391 | | - sseu->eu_total = compute_eu_total(sseu); |
|---|
| 392 | | - |
|---|
| 393 | | - /* |
|---|
| 394 | | - * SKL is expected to always have a uniform distribution |
|---|
| 395 | | - * of EU across subslices with the exception that any one |
|---|
| 396 | | - * EU in any one subslice may be fused off for die |
|---|
| 397 | | - * recovery. BXT is expected to be perfectly uniform in EU |
|---|
| 398 | | - * distribution. |
|---|
| 399 | | - */ |
|---|
| 400 | | - sseu->eu_per_subslice = sseu_subslice_total(sseu) ? |
|---|
| 401 | | - DIV_ROUND_UP(sseu->eu_total, |
|---|
| 402 | | - sseu_subslice_total(sseu)) : 0; |
|---|
| 403 | | - /* |
|---|
| 404 | | - * SKL+ supports slice power gating on devices with more than |
|---|
| 405 | | - * one slice, and supports EU power gating on devices with |
|---|
| 406 | | - * more than one EU pair per subslice. BXT+ supports subslice |
|---|
| 407 | | - * power gating on devices with more than one subslice, and |
|---|
| 408 | | - * supports EU power gating on devices with more than one EU |
|---|
| 409 | | - * pair per subslice. |
|---|
| 410 | | - */ |
|---|
| 411 | | - sseu->has_slice_pg = |
|---|
| 412 | | - !IS_GEN9_LP(dev_priv) && hweight8(sseu->slice_mask) > 1; |
|---|
| 413 | | - sseu->has_subslice_pg = |
|---|
| 414 | | - IS_GEN9_LP(dev_priv) && sseu_subslice_total(sseu) > 1; |
|---|
| 415 | | - sseu->has_eu_pg = sseu->eu_per_subslice > 2; |
|---|
| 416 | | - |
|---|
| 417 | | - if (IS_GEN9_LP(dev_priv)) { |
|---|
| 418 | | -#define IS_SS_DISABLED(ss) (!(sseu->subslice_mask[0] & BIT(ss))) |
|---|
| 419 | | - info->has_pooled_eu = hweight8(sseu->subslice_mask[0]) == 3; |
|---|
| 420 | | - |
|---|
| 421 | | - sseu->min_eu_in_pool = 0; |
|---|
| 422 | | - if (info->has_pooled_eu) { |
|---|
| 423 | | - if (IS_SS_DISABLED(2) || IS_SS_DISABLED(0)) |
|---|
| 424 | | - sseu->min_eu_in_pool = 3; |
|---|
| 425 | | - else if (IS_SS_DISABLED(1)) |
|---|
| 426 | | - sseu->min_eu_in_pool = 6; |
|---|
| 427 | | - else |
|---|
| 428 | | - sseu->min_eu_in_pool = 9; |
|---|
| 429 | | - } |
|---|
| 430 | | -#undef IS_SS_DISABLED |
|---|
| 431 | | - } |
|---|
| 432 | | -} |
|---|
| 433 | | - |
|---|
| 434 | | -static void broadwell_sseu_info_init(struct drm_i915_private *dev_priv) |
|---|
| 435 | | -{ |
|---|
| 436 | | - struct sseu_dev_info *sseu = &mkwrite_device_info(dev_priv)->sseu; |
|---|
| 437 | | - int s, ss; |
|---|
| 438 | | - u32 fuse2, subslice_mask, eu_disable[3]; /* s_max */ |
|---|
| 439 | | - |
|---|
| 440 | | - fuse2 = I915_READ(GEN8_FUSE2); |
|---|
| 441 | | - sseu->slice_mask = (fuse2 & GEN8_F2_S_ENA_MASK) >> GEN8_F2_S_ENA_SHIFT; |
|---|
| 442 | | - sseu->max_slices = 3; |
|---|
| 443 | | - sseu->max_subslices = 3; |
|---|
| 444 | | - sseu->max_eus_per_subslice = 8; |
|---|
| 445 | | - |
|---|
| 446 | | - /* |
|---|
| 447 | | - * The subslice disable field is global, i.e. it applies |
|---|
| 448 | | - * to each of the enabled slices. |
|---|
| 449 | | - */ |
|---|
| 450 | | - subslice_mask = GENMASK(sseu->max_subslices - 1, 0); |
|---|
| 451 | | - subslice_mask &= ~((fuse2 & GEN8_F2_SS_DIS_MASK) >> |
|---|
| 452 | | - GEN8_F2_SS_DIS_SHIFT); |
|---|
| 453 | | - |
|---|
| 454 | | - eu_disable[0] = I915_READ(GEN8_EU_DISABLE0) & GEN8_EU_DIS0_S0_MASK; |
|---|
| 455 | | - eu_disable[1] = (I915_READ(GEN8_EU_DISABLE0) >> GEN8_EU_DIS0_S1_SHIFT) | |
|---|
| 456 | | - ((I915_READ(GEN8_EU_DISABLE1) & GEN8_EU_DIS1_S1_MASK) << |
|---|
| 457 | | - (32 - GEN8_EU_DIS0_S1_SHIFT)); |
|---|
| 458 | | - eu_disable[2] = (I915_READ(GEN8_EU_DISABLE1) >> GEN8_EU_DIS1_S2_SHIFT) | |
|---|
| 459 | | - ((I915_READ(GEN8_EU_DISABLE2) & GEN8_EU_DIS2_S2_MASK) << |
|---|
| 460 | | - (32 - GEN8_EU_DIS1_S2_SHIFT)); |
|---|
| 461 | | - |
|---|
| 462 | | - /* |
|---|
| 463 | | - * Iterate through enabled slices and subslices to |
|---|
| 464 | | - * count the total enabled EU. |
|---|
| 465 | | - */ |
|---|
| 466 | | - for (s = 0; s < sseu->max_slices; s++) { |
|---|
| 467 | | - if (!(sseu->slice_mask & BIT(s))) |
|---|
| 468 | | - /* skip disabled slice */ |
|---|
| 469 | | - continue; |
|---|
| 470 | | - |
|---|
| 471 | | - sseu->subslice_mask[s] = subslice_mask; |
|---|
| 472 | | - |
|---|
| 473 | | - for (ss = 0; ss < sseu->max_subslices; ss++) { |
|---|
| 474 | | - u8 eu_disabled_mask; |
|---|
| 475 | | - u32 n_disabled; |
|---|
| 476 | | - |
|---|
| 477 | | - if (!(sseu->subslice_mask[s] & BIT(ss))) |
|---|
| 478 | | - /* skip disabled subslice */ |
|---|
| 479 | | - continue; |
|---|
| 480 | | - |
|---|
| 481 | | - eu_disabled_mask = |
|---|
| 482 | | - eu_disable[s] >> (ss * sseu->max_eus_per_subslice); |
|---|
| 483 | | - |
|---|
| 484 | | - sseu_set_eus(sseu, s, ss, ~eu_disabled_mask); |
|---|
| 485 | | - |
|---|
| 486 | | - n_disabled = hweight8(eu_disabled_mask); |
|---|
| 487 | | - |
|---|
| 488 | | - /* |
|---|
| 489 | | - * Record which subslices have 7 EUs. |
|---|
| 490 | | - */ |
|---|
| 491 | | - if (sseu->max_eus_per_subslice - n_disabled == 7) |
|---|
| 492 | | - sseu->subslice_7eu[s] |= 1 << ss; |
|---|
| 493 | | - } |
|---|
| 494 | | - } |
|---|
| 495 | | - |
|---|
| 496 | | - sseu->eu_total = compute_eu_total(sseu); |
|---|
| 497 | | - |
|---|
| 498 | | - /* |
|---|
| 499 | | - * BDW is expected to always have a uniform distribution of EU across |
|---|
| 500 | | - * subslices with the exception that any one EU in any one subslice may |
|---|
| 501 | | - * be fused off for die recovery. |
|---|
| 502 | | - */ |
|---|
| 503 | | - sseu->eu_per_subslice = sseu_subslice_total(sseu) ? |
|---|
| 504 | | - DIV_ROUND_UP(sseu->eu_total, |
|---|
| 505 | | - sseu_subslice_total(sseu)) : 0; |
|---|
| 506 | | - |
|---|
| 507 | | - /* |
|---|
| 508 | | - * BDW supports slice power gating on devices with more than |
|---|
| 509 | | - * one slice. |
|---|
| 510 | | - */ |
|---|
| 511 | | - sseu->has_slice_pg = hweight8(sseu->slice_mask) > 1; |
|---|
| 512 | | - sseu->has_subslice_pg = 0; |
|---|
| 513 | | - sseu->has_eu_pg = 0; |
|---|
| 514 | | -} |
|---|
| 515 | | - |
|---|
| 516 | | -static void haswell_sseu_info_init(struct drm_i915_private *dev_priv) |
|---|
| 517 | | -{ |
|---|
| 518 | | - struct intel_device_info *info = mkwrite_device_info(dev_priv); |
|---|
| 519 | | - struct sseu_dev_info *sseu = &info->sseu; |
|---|
| 520 | | - u32 fuse1; |
|---|
| 521 | | - int s, ss; |
|---|
| 522 | | - |
|---|
| 523 | | - /* |
|---|
| 524 | | - * There isn't a register to tell us how many slices/subslices. We |
|---|
| 525 | | - * work off the PCI-ids here. |
|---|
| 526 | | - */ |
|---|
| 527 | | - switch (info->gt) { |
|---|
| 528 | | - default: |
|---|
| 529 | | - MISSING_CASE(info->gt); |
|---|
| 530 | | - /* fall through */ |
|---|
| 531 | | - case 1: |
|---|
| 532 | | - sseu->slice_mask = BIT(0); |
|---|
| 533 | | - sseu->subslice_mask[0] = BIT(0); |
|---|
| 534 | | - break; |
|---|
| 535 | | - case 2: |
|---|
| 536 | | - sseu->slice_mask = BIT(0); |
|---|
| 537 | | - sseu->subslice_mask[0] = BIT(0) | BIT(1); |
|---|
| 538 | | - break; |
|---|
| 539 | | - case 3: |
|---|
| 540 | | - sseu->slice_mask = BIT(0) | BIT(1); |
|---|
| 541 | | - sseu->subslice_mask[0] = BIT(0) | BIT(1); |
|---|
| 542 | | - sseu->subslice_mask[1] = BIT(0) | BIT(1); |
|---|
| 543 | | - break; |
|---|
| 544 | | - } |
|---|
| 545 | | - |
|---|
| 546 | | - sseu->max_slices = hweight8(sseu->slice_mask); |
|---|
| 547 | | - sseu->max_subslices = hweight8(sseu->subslice_mask[0]); |
|---|
| 548 | | - |
|---|
| 549 | | - fuse1 = I915_READ(HSW_PAVP_FUSE1); |
|---|
| 550 | | - switch ((fuse1 & HSW_F1_EU_DIS_MASK) >> HSW_F1_EU_DIS_SHIFT) { |
|---|
| 551 | | - default: |
|---|
| 552 | | - MISSING_CASE((fuse1 & HSW_F1_EU_DIS_MASK) >> |
|---|
| 553 | | - HSW_F1_EU_DIS_SHIFT); |
|---|
| 554 | | - /* fall through */ |
|---|
| 555 | | - case HSW_F1_EU_DIS_10EUS: |
|---|
| 556 | | - sseu->eu_per_subslice = 10; |
|---|
| 557 | | - break; |
|---|
| 558 | | - case HSW_F1_EU_DIS_8EUS: |
|---|
| 559 | | - sseu->eu_per_subslice = 8; |
|---|
| 560 | | - break; |
|---|
| 561 | | - case HSW_F1_EU_DIS_6EUS: |
|---|
| 562 | | - sseu->eu_per_subslice = 6; |
|---|
| 563 | | - break; |
|---|
| 564 | | - } |
|---|
| 565 | | - sseu->max_eus_per_subslice = sseu->eu_per_subslice; |
|---|
| 566 | | - |
|---|
| 567 | | - for (s = 0; s < sseu->max_slices; s++) { |
|---|
| 568 | | - for (ss = 0; ss < sseu->max_subslices; ss++) { |
|---|
| 569 | | - sseu_set_eus(sseu, s, ss, |
|---|
| 570 | | - (1UL << sseu->eu_per_subslice) - 1); |
|---|
| 571 | | - } |
|---|
| 572 | | - } |
|---|
| 573 | | - |
|---|
| 574 | | - sseu->eu_total = compute_eu_total(sseu); |
|---|
| 575 | | - |
|---|
| 576 | | - /* No powergating for you. */ |
|---|
| 577 | | - sseu->has_slice_pg = 0; |
|---|
| 578 | | - sseu->has_subslice_pg = 0; |
|---|
| 579 | | - sseu->has_eu_pg = 0; |
|---|
| 118 | + drm_printf(p, "rawclk rate: %u kHz\n", info->rawclk_freq); |
|---|
| 119 | + drm_printf(p, "CS timestamp frequency: %u Hz\n", |
|---|
| 120 | + info->cs_timestamp_frequency_hz); |
|---|
| 580 | 121 | } |
|---|
| 581 | 122 | |
|---|
| 582 | 123 | static u32 read_reference_ts_freq(struct drm_i915_private *dev_priv) |
|---|
| 583 | 124 | { |
|---|
| 584 | | - u32 ts_override = I915_READ(GEN9_TIMESTAMP_OVERRIDE); |
|---|
| 125 | + u32 ts_override = intel_uncore_read(&dev_priv->uncore, |
|---|
| 126 | + GEN9_TIMESTAMP_OVERRIDE); |
|---|
| 585 | 127 | u32 base_freq, frac_freq; |
|---|
| 586 | 128 | |
|---|
| 587 | 129 | base_freq = ((ts_override & GEN9_TIMESTAMP_OVERRIDE_US_COUNTER_DIVIDER_MASK) >> |
|---|
| 588 | 130 | GEN9_TIMESTAMP_OVERRIDE_US_COUNTER_DIVIDER_SHIFT) + 1; |
|---|
| 589 | | - base_freq *= 1000; |
|---|
| 131 | + base_freq *= 1000000; |
|---|
| 590 | 132 | |
|---|
| 591 | 133 | frac_freq = ((ts_override & |
|---|
| 592 | 134 | GEN9_TIMESTAMP_OVERRIDE_US_COUNTER_DENOMINATOR_MASK) >> |
|---|
| 593 | 135 | GEN9_TIMESTAMP_OVERRIDE_US_COUNTER_DENOMINATOR_SHIFT); |
|---|
| 594 | | - frac_freq = 1000 / (frac_freq + 1); |
|---|
| 136 | + frac_freq = 1000000 / (frac_freq + 1); |
|---|
| 595 | 137 | |
|---|
| 596 | 138 | return base_freq + frac_freq; |
|---|
| 597 | 139 | } |
|---|
| .. | .. |
|---|
| 599 | 141 | static u32 gen10_get_crystal_clock_freq(struct drm_i915_private *dev_priv, |
|---|
| 600 | 142 | u32 rpm_config_reg) |
|---|
| 601 | 143 | { |
|---|
| 602 | | - u32 f19_2_mhz = 19200; |
|---|
| 603 | | - u32 f24_mhz = 24000; |
|---|
| 144 | + u32 f19_2_mhz = 19200000; |
|---|
| 145 | + u32 f24_mhz = 24000000; |
|---|
| 604 | 146 | u32 crystal_clock = (rpm_config_reg & |
|---|
| 605 | 147 | GEN9_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_MASK) >> |
|---|
| 606 | 148 | GEN9_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_SHIFT; |
|---|
| .. | .. |
|---|
| 619 | 161 | static u32 gen11_get_crystal_clock_freq(struct drm_i915_private *dev_priv, |
|---|
| 620 | 162 | u32 rpm_config_reg) |
|---|
| 621 | 163 | { |
|---|
| 622 | | - u32 f19_2_mhz = 19200; |
|---|
| 623 | | - u32 f24_mhz = 24000; |
|---|
| 624 | | - u32 f25_mhz = 25000; |
|---|
| 625 | | - u32 f38_4_mhz = 38400; |
|---|
| 164 | + u32 f19_2_mhz = 19200000; |
|---|
| 165 | + u32 f24_mhz = 24000000; |
|---|
| 166 | + u32 f25_mhz = 25000000; |
|---|
| 167 | + u32 f38_4_mhz = 38400000; |
|---|
| 626 | 168 | u32 crystal_clock = (rpm_config_reg & |
|---|
| 627 | 169 | GEN11_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_MASK) >> |
|---|
| 628 | 170 | GEN11_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_SHIFT; |
|---|
| .. | .. |
|---|
| 644 | 186 | |
|---|
| 645 | 187 | static u32 read_timestamp_frequency(struct drm_i915_private *dev_priv) |
|---|
| 646 | 188 | { |
|---|
| 647 | | - u32 f12_5_mhz = 12500; |
|---|
| 648 | | - u32 f19_2_mhz = 19200; |
|---|
| 649 | | - u32 f24_mhz = 24000; |
|---|
| 189 | + struct intel_uncore *uncore = &dev_priv->uncore; |
|---|
| 190 | + u32 f12_5_mhz = 12500000; |
|---|
| 191 | + u32 f19_2_mhz = 19200000; |
|---|
| 192 | + u32 f24_mhz = 24000000; |
|---|
| 650 | 193 | |
|---|
| 651 | 194 | if (INTEL_GEN(dev_priv) <= 4) { |
|---|
| 652 | 195 | /* PRMs say: |
|---|
| .. | .. |
|---|
| 655 | 198 | * hclks." (through the “Clocking Configuration” |
|---|
| 656 | 199 | * (“CLKCFG”) MCHBAR register) |
|---|
| 657 | 200 | */ |
|---|
| 658 | | - return dev_priv->rawclk_freq / 16; |
|---|
| 201 | + return RUNTIME_INFO(dev_priv)->rawclk_freq * 1000 / 16; |
|---|
| 659 | 202 | } else if (INTEL_GEN(dev_priv) <= 8) { |
|---|
| 660 | 203 | /* PRMs say: |
|---|
| 661 | 204 | * |
|---|
| .. | .. |
|---|
| 665 | 208 | */ |
|---|
| 666 | 209 | return f12_5_mhz; |
|---|
| 667 | 210 | } else if (INTEL_GEN(dev_priv) <= 9) { |
|---|
| 668 | | - u32 ctc_reg = I915_READ(CTC_MODE); |
|---|
| 211 | + u32 ctc_reg = intel_uncore_read(uncore, CTC_MODE); |
|---|
| 669 | 212 | u32 freq = 0; |
|---|
| 670 | 213 | |
|---|
| 671 | 214 | if ((ctc_reg & CTC_SOURCE_PARAMETER_MASK) == CTC_SOURCE_DIVIDE_LOGIC) { |
|---|
| .. | .. |
|---|
| 682 | 225 | } |
|---|
| 683 | 226 | |
|---|
| 684 | 227 | return freq; |
|---|
| 685 | | - } else if (INTEL_GEN(dev_priv) <= 11) { |
|---|
| 686 | | - u32 ctc_reg = I915_READ(CTC_MODE); |
|---|
| 228 | + } else if (INTEL_GEN(dev_priv) <= 12) { |
|---|
| 229 | + u32 ctc_reg = intel_uncore_read(uncore, CTC_MODE); |
|---|
| 687 | 230 | u32 freq = 0; |
|---|
| 688 | 231 | |
|---|
| 689 | 232 | /* First figure out the reference frequency. There are 2 ways |
|---|
| .. | .. |
|---|
| 694 | 237 | if ((ctc_reg & CTC_SOURCE_PARAMETER_MASK) == CTC_SOURCE_DIVIDE_LOGIC) { |
|---|
| 695 | 238 | freq = read_reference_ts_freq(dev_priv); |
|---|
| 696 | 239 | } else { |
|---|
| 697 | | - u32 rpm_config_reg = I915_READ(RPM_CONFIG0); |
|---|
| 240 | + u32 rpm_config_reg = intel_uncore_read(uncore, RPM_CONFIG0); |
|---|
| 698 | 241 | |
|---|
| 699 | 242 | if (INTEL_GEN(dev_priv) <= 10) |
|---|
| 700 | 243 | freq = gen10_get_crystal_clock_freq(dev_priv, |
|---|
| .. | .. |
|---|
| 719 | 262 | return 0; |
|---|
| 720 | 263 | } |
|---|
| 721 | 264 | |
|---|
| 265 | +#undef INTEL_VGA_DEVICE |
|---|
| 266 | +#define INTEL_VGA_DEVICE(id, info) (id) |
|---|
| 267 | + |
|---|
| 268 | +static const u16 subplatform_ult_ids[] = { |
|---|
| 269 | + INTEL_HSW_ULT_GT1_IDS(0), |
|---|
| 270 | + INTEL_HSW_ULT_GT2_IDS(0), |
|---|
| 271 | + INTEL_HSW_ULT_GT3_IDS(0), |
|---|
| 272 | + INTEL_BDW_ULT_GT1_IDS(0), |
|---|
| 273 | + INTEL_BDW_ULT_GT2_IDS(0), |
|---|
| 274 | + INTEL_BDW_ULT_GT3_IDS(0), |
|---|
| 275 | + INTEL_BDW_ULT_RSVD_IDS(0), |
|---|
| 276 | + INTEL_SKL_ULT_GT1_IDS(0), |
|---|
| 277 | + INTEL_SKL_ULT_GT2_IDS(0), |
|---|
| 278 | + INTEL_SKL_ULT_GT3_IDS(0), |
|---|
| 279 | + INTEL_KBL_ULT_GT1_IDS(0), |
|---|
| 280 | + INTEL_KBL_ULT_GT2_IDS(0), |
|---|
| 281 | + INTEL_KBL_ULT_GT3_IDS(0), |
|---|
| 282 | + INTEL_CFL_U_GT2_IDS(0), |
|---|
| 283 | + INTEL_CFL_U_GT3_IDS(0), |
|---|
| 284 | + INTEL_WHL_U_GT1_IDS(0), |
|---|
| 285 | + INTEL_WHL_U_GT2_IDS(0), |
|---|
| 286 | + INTEL_WHL_U_GT3_IDS(0), |
|---|
| 287 | + INTEL_CML_U_GT1_IDS(0), |
|---|
| 288 | + INTEL_CML_U_GT2_IDS(0), |
|---|
| 289 | +}; |
|---|
| 290 | + |
|---|
| 291 | +static const u16 subplatform_ulx_ids[] = { |
|---|
| 292 | + INTEL_HSW_ULX_GT1_IDS(0), |
|---|
| 293 | + INTEL_HSW_ULX_GT2_IDS(0), |
|---|
| 294 | + INTEL_BDW_ULX_GT1_IDS(0), |
|---|
| 295 | + INTEL_BDW_ULX_GT2_IDS(0), |
|---|
| 296 | + INTEL_BDW_ULX_GT3_IDS(0), |
|---|
| 297 | + INTEL_BDW_ULX_RSVD_IDS(0), |
|---|
| 298 | + INTEL_SKL_ULX_GT1_IDS(0), |
|---|
| 299 | + INTEL_SKL_ULX_GT2_IDS(0), |
|---|
| 300 | + INTEL_KBL_ULX_GT1_IDS(0), |
|---|
| 301 | + INTEL_KBL_ULX_GT2_IDS(0), |
|---|
| 302 | + INTEL_AML_KBL_GT2_IDS(0), |
|---|
| 303 | + INTEL_AML_CFL_GT2_IDS(0), |
|---|
| 304 | +}; |
|---|
| 305 | + |
|---|
| 306 | +static const u16 subplatform_portf_ids[] = { |
|---|
| 307 | + INTEL_CNL_PORT_F_IDS(0), |
|---|
| 308 | + INTEL_ICL_PORT_F_IDS(0), |
|---|
| 309 | +}; |
|---|
| 310 | + |
|---|
| 311 | +static bool find_devid(u16 id, const u16 *p, unsigned int num) |
|---|
| 312 | +{ |
|---|
| 313 | + for (; num; num--, p++) { |
|---|
| 314 | + if (*p == id) |
|---|
| 315 | + return true; |
|---|
| 316 | + } |
|---|
| 317 | + |
|---|
| 318 | + return false; |
|---|
| 319 | +} |
|---|
| 320 | + |
|---|
| 321 | +void intel_device_info_subplatform_init(struct drm_i915_private *i915) |
|---|
| 322 | +{ |
|---|
| 323 | + const struct intel_device_info *info = INTEL_INFO(i915); |
|---|
| 324 | + const struct intel_runtime_info *rinfo = RUNTIME_INFO(i915); |
|---|
| 325 | + const unsigned int pi = __platform_mask_index(rinfo, info->platform); |
|---|
| 326 | + const unsigned int pb = __platform_mask_bit(rinfo, info->platform); |
|---|
| 327 | + u16 devid = INTEL_DEVID(i915); |
|---|
| 328 | + u32 mask = 0; |
|---|
| 329 | + |
|---|
| 330 | + /* Make sure IS_<platform> checks are working. */ |
|---|
| 331 | + RUNTIME_INFO(i915)->platform_mask[pi] = BIT(pb); |
|---|
| 332 | + |
|---|
| 333 | + /* Find and mark subplatform bits based on the PCI device id. */ |
|---|
| 334 | + if (find_devid(devid, subplatform_ult_ids, |
|---|
| 335 | + ARRAY_SIZE(subplatform_ult_ids))) { |
|---|
| 336 | + mask = BIT(INTEL_SUBPLATFORM_ULT); |
|---|
| 337 | + } else if (find_devid(devid, subplatform_ulx_ids, |
|---|
| 338 | + ARRAY_SIZE(subplatform_ulx_ids))) { |
|---|
| 339 | + mask = BIT(INTEL_SUBPLATFORM_ULX); |
|---|
| 340 | + if (IS_HASWELL(i915) || IS_BROADWELL(i915)) { |
|---|
| 341 | + /* ULX machines are also considered ULT. */ |
|---|
| 342 | + mask |= BIT(INTEL_SUBPLATFORM_ULT); |
|---|
| 343 | + } |
|---|
| 344 | + } else if (find_devid(devid, subplatform_portf_ids, |
|---|
| 345 | + ARRAY_SIZE(subplatform_portf_ids))) { |
|---|
| 346 | + mask = BIT(INTEL_SUBPLATFORM_PORTF); |
|---|
| 347 | + } |
|---|
| 348 | + |
|---|
| 349 | + if (IS_TIGERLAKE(i915)) { |
|---|
| 350 | + struct pci_dev *root, *pdev = i915->drm.pdev; |
|---|
| 351 | + |
|---|
| 352 | + root = list_first_entry(&pdev->bus->devices, typeof(*root), bus_list); |
|---|
| 353 | + |
|---|
| 354 | + drm_WARN_ON(&i915->drm, mask); |
|---|
| 355 | + drm_WARN_ON(&i915->drm, (root->device & TGL_ROOT_DEVICE_MASK) != |
|---|
| 356 | + TGL_ROOT_DEVICE_ID); |
|---|
| 357 | + |
|---|
| 358 | + switch (root->device & TGL_ROOT_DEVICE_SKU_MASK) { |
|---|
| 359 | + case TGL_ROOT_DEVICE_SKU_ULX: |
|---|
| 360 | + mask = BIT(INTEL_SUBPLATFORM_ULX); |
|---|
| 361 | + break; |
|---|
| 362 | + case TGL_ROOT_DEVICE_SKU_ULT: |
|---|
| 363 | + mask = BIT(INTEL_SUBPLATFORM_ULT); |
|---|
| 364 | + break; |
|---|
| 365 | + } |
|---|
| 366 | + } |
|---|
| 367 | + |
|---|
| 368 | + GEM_BUG_ON(mask & ~INTEL_SUBPLATFORM_BITS); |
|---|
| 369 | + |
|---|
| 370 | + RUNTIME_INFO(i915)->platform_mask[pi] |= mask; |
|---|
| 371 | +} |
|---|
| 372 | + |
|---|
| 722 | 373 | /** |
|---|
| 723 | 374 | * intel_device_info_runtime_init - initialize runtime info |
|---|
| 724 | | - * @info: intel device info struct |
|---|
| 375 | + * @dev_priv: the i915 device |
|---|
| 725 | 376 | * |
|---|
| 726 | 377 | * Determine various intel_device_info fields at runtime. |
|---|
| 727 | 378 | * |
|---|
| .. | .. |
|---|
| 735 | 386 | * - after the PCH has been detected, |
|---|
| 736 | 387 | * - before the first usage of the fields it can tweak. |
|---|
| 737 | 388 | */ |
|---|
| 738 | | -void intel_device_info_runtime_init(struct intel_device_info *info) |
|---|
| 389 | +void intel_device_info_runtime_init(struct drm_i915_private *dev_priv) |
|---|
| 739 | 390 | { |
|---|
| 740 | | - struct drm_i915_private *dev_priv = |
|---|
| 741 | | - container_of(info, struct drm_i915_private, info); |
|---|
| 391 | + struct intel_device_info *info = mkwrite_device_info(dev_priv); |
|---|
| 392 | + struct intel_runtime_info *runtime = RUNTIME_INFO(dev_priv); |
|---|
| 742 | 393 | enum pipe pipe; |
|---|
| 743 | 394 | |
|---|
| 744 | 395 | if (INTEL_GEN(dev_priv) >= 10) { |
|---|
| 745 | 396 | for_each_pipe(dev_priv, pipe) |
|---|
| 746 | | - info->num_scalers[pipe] = 2; |
|---|
| 747 | | - } else if (INTEL_GEN(dev_priv) == 9) { |
|---|
| 748 | | - info->num_scalers[PIPE_A] = 2; |
|---|
| 749 | | - info->num_scalers[PIPE_B] = 2; |
|---|
| 750 | | - info->num_scalers[PIPE_C] = 1; |
|---|
| 397 | + runtime->num_scalers[pipe] = 2; |
|---|
| 398 | + } else if (IS_GEN(dev_priv, 9)) { |
|---|
| 399 | + runtime->num_scalers[PIPE_A] = 2; |
|---|
| 400 | + runtime->num_scalers[PIPE_B] = 2; |
|---|
| 401 | + runtime->num_scalers[PIPE_C] = 1; |
|---|
| 751 | 402 | } |
|---|
| 752 | 403 | |
|---|
| 753 | | - BUILD_BUG_ON(I915_NUM_ENGINES > |
|---|
| 754 | | - sizeof(intel_ring_mask_t) * BITS_PER_BYTE); |
|---|
| 404 | + BUILD_BUG_ON(BITS_PER_TYPE(intel_engine_mask_t) < I915_NUM_ENGINES); |
|---|
| 755 | 405 | |
|---|
| 756 | | - /* |
|---|
| 757 | | - * Skylake and Broxton currently don't expose the topmost plane as its |
|---|
| 758 | | - * use is exclusive with the legacy cursor and we only want to expose |
|---|
| 759 | | - * one of those, not both. Until we can safely expose the topmost plane |
|---|
| 760 | | - * as a DRM_PLANE_TYPE_CURSOR with all the features exposed/supported, |
|---|
| 761 | | - * we don't expose the topmost plane at all to prevent ABI breakage |
|---|
| 762 | | - * down the line. |
|---|
| 763 | | - */ |
|---|
| 764 | | - if (IS_GEN10(dev_priv) || IS_GEMINILAKE(dev_priv)) |
|---|
| 406 | + if (IS_ROCKETLAKE(dev_priv)) |
|---|
| 765 | 407 | for_each_pipe(dev_priv, pipe) |
|---|
| 766 | | - info->num_sprites[pipe] = 3; |
|---|
| 408 | + runtime->num_sprites[pipe] = 4; |
|---|
| 409 | + else if (INTEL_GEN(dev_priv) >= 11) |
|---|
| 410 | + for_each_pipe(dev_priv, pipe) |
|---|
| 411 | + runtime->num_sprites[pipe] = 6; |
|---|
| 412 | + else if (IS_GEN(dev_priv, 10) || IS_GEMINILAKE(dev_priv)) |
|---|
| 413 | + for_each_pipe(dev_priv, pipe) |
|---|
| 414 | + runtime->num_sprites[pipe] = 3; |
|---|
| 767 | 415 | else if (IS_BROXTON(dev_priv)) { |
|---|
| 768 | | - info->num_sprites[PIPE_A] = 2; |
|---|
| 769 | | - info->num_sprites[PIPE_B] = 2; |
|---|
| 770 | | - info->num_sprites[PIPE_C] = 1; |
|---|
| 416 | + /* |
|---|
| 417 | + * Skylake and Broxton currently don't expose the topmost plane as its |
|---|
| 418 | + * use is exclusive with the legacy cursor and we only want to expose |
|---|
| 419 | + * one of those, not both. Until we can safely expose the topmost plane |
|---|
| 420 | + * as a DRM_PLANE_TYPE_CURSOR with all the features exposed/supported, |
|---|
| 421 | + * we don't expose the topmost plane at all to prevent ABI breakage |
|---|
| 422 | + * down the line. |
|---|
| 423 | + */ |
|---|
| 424 | + |
|---|
| 425 | + runtime->num_sprites[PIPE_A] = 2; |
|---|
| 426 | + runtime->num_sprites[PIPE_B] = 2; |
|---|
| 427 | + runtime->num_sprites[PIPE_C] = 1; |
|---|
| 771 | 428 | } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { |
|---|
| 772 | 429 | for_each_pipe(dev_priv, pipe) |
|---|
| 773 | | - info->num_sprites[pipe] = 2; |
|---|
| 430 | + runtime->num_sprites[pipe] = 2; |
|---|
| 774 | 431 | } else if (INTEL_GEN(dev_priv) >= 5 || IS_G4X(dev_priv)) { |
|---|
| 775 | 432 | for_each_pipe(dev_priv, pipe) |
|---|
| 776 | | - info->num_sprites[pipe] = 1; |
|---|
| 433 | + runtime->num_sprites[pipe] = 1; |
|---|
| 777 | 434 | } |
|---|
| 778 | 435 | |
|---|
| 779 | | - if (i915_modparams.disable_display) { |
|---|
| 780 | | - DRM_INFO("Display disabled (module parameter)\n"); |
|---|
| 781 | | - info->num_pipes = 0; |
|---|
| 782 | | - } else if (info->num_pipes > 0 && |
|---|
| 783 | | - (IS_GEN7(dev_priv) || IS_GEN8(dev_priv)) && |
|---|
| 784 | | - HAS_PCH_SPLIT(dev_priv)) { |
|---|
| 785 | | - u32 fuse_strap = I915_READ(FUSE_STRAP); |
|---|
| 786 | | - u32 sfuse_strap = I915_READ(SFUSE_STRAP); |
|---|
| 436 | + if (HAS_DISPLAY(dev_priv) && IS_GEN_RANGE(dev_priv, 7, 8) && |
|---|
| 437 | + HAS_PCH_SPLIT(dev_priv)) { |
|---|
| 438 | + u32 fuse_strap = intel_de_read(dev_priv, FUSE_STRAP); |
|---|
| 439 | + u32 sfuse_strap = intel_de_read(dev_priv, SFUSE_STRAP); |
|---|
| 787 | 440 | |
|---|
| 788 | 441 | /* |
|---|
| 789 | 442 | * SFUSE_STRAP is supposed to have a bit signalling the display |
|---|
| .. | .. |
|---|
| 798 | 451 | sfuse_strap & SFUSE_STRAP_DISPLAY_DISABLED || |
|---|
| 799 | 452 | (HAS_PCH_CPT(dev_priv) && |
|---|
| 800 | 453 | !(sfuse_strap & SFUSE_STRAP_FUSE_LOCK))) { |
|---|
| 801 | | - DRM_INFO("Display fused off, disabling\n"); |
|---|
| 802 | | - info->num_pipes = 0; |
|---|
| 454 | + drm_info(&dev_priv->drm, |
|---|
| 455 | + "Display fused off, disabling\n"); |
|---|
| 456 | + info->pipe_mask = 0; |
|---|
| 457 | + info->cpu_transcoder_mask = 0; |
|---|
| 803 | 458 | } else if (fuse_strap & IVB_PIPE_C_DISABLE) { |
|---|
| 804 | | - DRM_INFO("PipeC fused off\n"); |
|---|
| 805 | | - info->num_pipes -= 1; |
|---|
| 459 | + drm_info(&dev_priv->drm, "PipeC fused off\n"); |
|---|
| 460 | + info->pipe_mask &= ~BIT(PIPE_C); |
|---|
| 461 | + info->cpu_transcoder_mask &= ~BIT(TRANSCODER_C); |
|---|
| 806 | 462 | } |
|---|
| 807 | | - } else if (info->num_pipes > 0 && IS_GEN9(dev_priv)) { |
|---|
| 808 | | - u32 dfsm = I915_READ(SKL_DFSM); |
|---|
| 809 | | - u8 disabled_mask = 0; |
|---|
| 810 | | - bool invalid; |
|---|
| 811 | | - int num_bits; |
|---|
| 463 | + } else if (HAS_DISPLAY(dev_priv) && INTEL_GEN(dev_priv) >= 9) { |
|---|
| 464 | + u32 dfsm = intel_de_read(dev_priv, SKL_DFSM); |
|---|
| 812 | 465 | |
|---|
| 813 | | - if (dfsm & SKL_DFSM_PIPE_A_DISABLE) |
|---|
| 814 | | - disabled_mask |= BIT(PIPE_A); |
|---|
| 815 | | - if (dfsm & SKL_DFSM_PIPE_B_DISABLE) |
|---|
| 816 | | - disabled_mask |= BIT(PIPE_B); |
|---|
| 817 | | - if (dfsm & SKL_DFSM_PIPE_C_DISABLE) |
|---|
| 818 | | - disabled_mask |= BIT(PIPE_C); |
|---|
| 819 | | - |
|---|
| 820 | | - num_bits = hweight8(disabled_mask); |
|---|
| 821 | | - |
|---|
| 822 | | - switch (disabled_mask) { |
|---|
| 823 | | - case BIT(PIPE_A): |
|---|
| 824 | | - case BIT(PIPE_B): |
|---|
| 825 | | - case BIT(PIPE_A) | BIT(PIPE_B): |
|---|
| 826 | | - case BIT(PIPE_A) | BIT(PIPE_C): |
|---|
| 827 | | - invalid = true; |
|---|
| 828 | | - break; |
|---|
| 829 | | - default: |
|---|
| 830 | | - invalid = false; |
|---|
| 466 | + if (dfsm & SKL_DFSM_PIPE_A_DISABLE) { |
|---|
| 467 | + info->pipe_mask &= ~BIT(PIPE_A); |
|---|
| 468 | + info->cpu_transcoder_mask &= ~BIT(TRANSCODER_A); |
|---|
| 469 | + } |
|---|
| 470 | + if (dfsm & SKL_DFSM_PIPE_B_DISABLE) { |
|---|
| 471 | + info->pipe_mask &= ~BIT(PIPE_B); |
|---|
| 472 | + info->cpu_transcoder_mask &= ~BIT(TRANSCODER_B); |
|---|
| 473 | + } |
|---|
| 474 | + if (dfsm & SKL_DFSM_PIPE_C_DISABLE) { |
|---|
| 475 | + info->pipe_mask &= ~BIT(PIPE_C); |
|---|
| 476 | + info->cpu_transcoder_mask &= ~BIT(TRANSCODER_C); |
|---|
| 477 | + } |
|---|
| 478 | + if (INTEL_GEN(dev_priv) >= 12 && |
|---|
| 479 | + (dfsm & TGL_DFSM_PIPE_D_DISABLE)) { |
|---|
| 480 | + info->pipe_mask &= ~BIT(PIPE_D); |
|---|
| 481 | + info->cpu_transcoder_mask &= ~BIT(TRANSCODER_D); |
|---|
| 831 | 482 | } |
|---|
| 832 | 483 | |
|---|
| 833 | | - if (num_bits > info->num_pipes || invalid) |
|---|
| 834 | | - DRM_ERROR("invalid pipe fuse configuration: 0x%x\n", |
|---|
| 835 | | - disabled_mask); |
|---|
| 836 | | - else |
|---|
| 837 | | - info->num_pipes -= num_bits; |
|---|
| 484 | + if (dfsm & SKL_DFSM_DISPLAY_HDCP_DISABLE) |
|---|
| 485 | + info->display.has_hdcp = 0; |
|---|
| 486 | + |
|---|
| 487 | + if (dfsm & SKL_DFSM_DISPLAY_PM_DISABLE) |
|---|
| 488 | + info->display.has_fbc = 0; |
|---|
| 489 | + |
|---|
| 490 | + if (INTEL_GEN(dev_priv) >= 11 && (dfsm & ICL_DFSM_DMC_DISABLE)) |
|---|
| 491 | + info->display.has_csr = 0; |
|---|
| 492 | + |
|---|
| 493 | + if (INTEL_GEN(dev_priv) >= 10 && |
|---|
| 494 | + (dfsm & CNL_DFSM_DISPLAY_DSC_DISABLE)) |
|---|
| 495 | + info->display.has_dsc = 0; |
|---|
| 838 | 496 | } |
|---|
| 839 | 497 | |
|---|
| 840 | | - /* Initialize slice/subslice/EU info */ |
|---|
| 841 | | - if (IS_HASWELL(dev_priv)) |
|---|
| 842 | | - haswell_sseu_info_init(dev_priv); |
|---|
| 843 | | - else if (IS_CHERRYVIEW(dev_priv)) |
|---|
| 844 | | - cherryview_sseu_info_init(dev_priv); |
|---|
| 845 | | - else if (IS_BROADWELL(dev_priv)) |
|---|
| 846 | | - broadwell_sseu_info_init(dev_priv); |
|---|
| 847 | | - else if (INTEL_GEN(dev_priv) == 9) |
|---|
| 848 | | - gen9_sseu_info_init(dev_priv); |
|---|
| 849 | | - else if (INTEL_GEN(dev_priv) == 10) |
|---|
| 850 | | - gen10_sseu_info_init(dev_priv); |
|---|
| 851 | | - else if (INTEL_GEN(dev_priv) >= 11) |
|---|
| 852 | | - gen11_sseu_info_init(dev_priv); |
|---|
| 498 | + if (IS_GEN(dev_priv, 6) && intel_vtd_active()) { |
|---|
| 499 | + drm_info(&dev_priv->drm, |
|---|
| 500 | + "Disabling ppGTT for VT-d support\n"); |
|---|
| 501 | + info->ppgtt_type = INTEL_PPGTT_NONE; |
|---|
| 502 | + } |
|---|
| 503 | + |
|---|
| 504 | + runtime->rawclk_freq = intel_read_rawclk(dev_priv); |
|---|
| 505 | + drm_dbg(&dev_priv->drm, "rawclk rate: %d kHz\n", runtime->rawclk_freq); |
|---|
| 853 | 506 | |
|---|
| 854 | 507 | /* Initialize command stream timestamp frequency */ |
|---|
| 855 | | - info->cs_timestamp_frequency_khz = read_timestamp_frequency(dev_priv); |
|---|
| 508 | + runtime->cs_timestamp_frequency_hz = |
|---|
| 509 | + read_timestamp_frequency(dev_priv); |
|---|
| 510 | + if (runtime->cs_timestamp_frequency_hz) { |
|---|
| 511 | + runtime->cs_timestamp_period_ns = |
|---|
| 512 | + i915_cs_timestamp_ticks_to_ns(dev_priv, 1); |
|---|
| 513 | + drm_dbg(&dev_priv->drm, |
|---|
| 514 | + "CS timestamp wraparound in %lldms\n", |
|---|
| 515 | + div_u64(mul_u32_u32(runtime->cs_timestamp_period_ns, |
|---|
| 516 | + S32_MAX), |
|---|
| 517 | + USEC_PER_SEC)); |
|---|
| 518 | + } |
|---|
| 519 | + |
|---|
| 520 | + if (!HAS_DISPLAY(dev_priv)) { |
|---|
| 521 | + dev_priv->drm.driver_features &= ~(DRIVER_MODESET | |
|---|
| 522 | + DRIVER_ATOMIC); |
|---|
| 523 | + memset(&info->display, 0, sizeof(info->display)); |
|---|
| 524 | + memset(runtime->num_sprites, 0, sizeof(runtime->num_sprites)); |
|---|
| 525 | + memset(runtime->num_scalers, 0, sizeof(runtime->num_scalers)); |
|---|
| 526 | + } |
|---|
| 856 | 527 | } |
|---|
| 857 | 528 | |
|---|
| 858 | 529 | void intel_driver_caps_print(const struct intel_driver_caps *caps, |
|---|
| .. | .. |
|---|
| 861 | 532 | drm_printf(p, "Has logical contexts? %s\n", |
|---|
| 862 | 533 | yesno(caps->has_logical_contexts)); |
|---|
| 863 | 534 | drm_printf(p, "scheduler: %x\n", caps->scheduler); |
|---|
| 864 | | -} |
|---|
| 865 | | - |
|---|
| 866 | | -/* |
|---|
| 867 | | - * Determine which engines are fused off in our particular hardware. Since the |
|---|
| 868 | | - * fuse register is in the blitter powerwell, we need forcewake to be ready at |
|---|
| 869 | | - * this point (but later we need to prune the forcewake domains for engines that |
|---|
| 870 | | - * are indeed fused off). |
|---|
| 871 | | - */ |
|---|
| 872 | | -void intel_device_info_init_mmio(struct drm_i915_private *dev_priv) |
|---|
| 873 | | -{ |
|---|
| 874 | | - struct intel_device_info *info = mkwrite_device_info(dev_priv); |
|---|
| 875 | | - u8 vdbox_disable, vebox_disable; |
|---|
| 876 | | - u32 media_fuse; |
|---|
| 877 | | - int i; |
|---|
| 878 | | - |
|---|
| 879 | | - if (INTEL_GEN(dev_priv) < 11) |
|---|
| 880 | | - return; |
|---|
| 881 | | - |
|---|
| 882 | | - media_fuse = I915_READ(GEN11_GT_VEBOX_VDBOX_DISABLE); |
|---|
| 883 | | - |
|---|
| 884 | | - vdbox_disable = media_fuse & GEN11_GT_VDBOX_DISABLE_MASK; |
|---|
| 885 | | - vebox_disable = (media_fuse & GEN11_GT_VEBOX_DISABLE_MASK) >> |
|---|
| 886 | | - GEN11_GT_VEBOX_DISABLE_SHIFT; |
|---|
| 887 | | - |
|---|
| 888 | | - DRM_DEBUG_DRIVER("vdbox disable: %04x\n", vdbox_disable); |
|---|
| 889 | | - for (i = 0; i < I915_MAX_VCS; i++) { |
|---|
| 890 | | - if (!HAS_ENGINE(dev_priv, _VCS(i))) |
|---|
| 891 | | - continue; |
|---|
| 892 | | - |
|---|
| 893 | | - if (!(BIT(i) & vdbox_disable)) |
|---|
| 894 | | - continue; |
|---|
| 895 | | - |
|---|
| 896 | | - info->ring_mask &= ~ENGINE_MASK(_VCS(i)); |
|---|
| 897 | | - DRM_DEBUG_DRIVER("vcs%u fused off\n", i); |
|---|
| 898 | | - } |
|---|
| 899 | | - |
|---|
| 900 | | - DRM_DEBUG_DRIVER("vebox disable: %04x\n", vebox_disable); |
|---|
| 901 | | - for (i = 0; i < I915_MAX_VECS; i++) { |
|---|
| 902 | | - if (!HAS_ENGINE(dev_priv, _VECS(i))) |
|---|
| 903 | | - continue; |
|---|
| 904 | | - |
|---|
| 905 | | - if (!(BIT(i) & vebox_disable)) |
|---|
| 906 | | - continue; |
|---|
| 907 | | - |
|---|
| 908 | | - info->ring_mask &= ~ENGINE_MASK(_VECS(i)); |
|---|
| 909 | | - DRM_DEBUG_DRIVER("vecs%u fused off\n", i); |
|---|
| 910 | | - } |
|---|
| 911 | 535 | } |
|---|