intel_csr.c revision 1.5.8.1 1 /* $NetBSD: intel_csr.c,v 1.5.8.1 2020/02/29 20:20:14 ad Exp $ */
2
3 /*
4 * Copyright 2014 Intel Corporation
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
15 * Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23 * IN THE SOFTWARE.
24 *
25 */
26 #include <sys/cdefs.h>
27 __KERNEL_RCSID(0, "$NetBSD: intel_csr.c,v 1.5.8.1 2020/02/29 20:20:14 ad Exp $");
28
29 #include <linux/firmware.h>
30 #include "i915_drv.h"
31 #include "i915_reg.h"
32 #include "intel_drv.h"
33
34 /**
35 * DOC: csr support for dmc
36 *
37 * Display Context Save and Restore (CSR) firmware support added from gen9
38 * onwards to drive newly added DMC (Display microcontroller) in display
39 * engine to save and restore the state of display engine when it enter into
40 * low-power state and comes back to normal.
41 *
42 * Firmware loading status will be one of the below states: FW_UNINITIALIZED,
43 * FW_LOADED, FW_FAILED.
44 *
45 * Once the firmware is written into the registers status will be moved from
46 * FW_UNINITIALIZED to FW_LOADED and for any erroneous condition status will
47 * be moved to FW_FAILED.
48 */
49
50 #define I915_CSR_KBL "i915/kbl_dmc_ver1.bin"
51 #define I915_CSR_SKL "i915/skl_dmc_ver1.bin"
52 #define I915_CSR_BXT "i915/bxt_dmc_ver1.bin"
53
54 MODULE_FIRMWARE(I915_CSR_KBL);
55 MODULE_FIRMWARE(I915_CSR_SKL);
56 MODULE_FIRMWARE(I915_CSR_BXT);
57
58 /*
59 * SKL CSR registers for DC5 and DC6
60 */
61 #define CSR_PROGRAM(i) (0x80000 + (i) * 4)
62 #define CSR_SSP_BASE_ADDR_GEN9 0x00002FC0
63 #define CSR_HTP_ADDR_SKL 0x00500034
64 #define CSR_SSP_BASE 0x8F074
65 #define CSR_HTP_SKL 0x8F004
66 #define CSR_LAST_WRITE 0x8F034
67 #define CSR_LAST_WRITE_VALUE 0xc003b400
68 /* MMIO address range for CSR program (0x80000 - 0x82FFF) */
69 #define CSR_MAX_FW_SIZE 0x2FFF
70 #define CSR_DEFAULT_FW_OFFSET 0xFFFFFFFF
71 #define CSR_MMIO_START_RANGE 0x80000
72 #define CSR_MMIO_END_RANGE 0x8FFFF
73
74 struct intel_css_header {
75 /* 0x09 for DMC */
76 uint32_t module_type;
77
78 /* Includes the DMC specific header in dwords */
79 uint32_t header_len;
80
81 /* always value would be 0x10000 */
82 uint32_t header_ver;
83
84 /* Not used */
85 uint32_t module_id;
86
87 /* Not used */
88 uint32_t module_vendor;
89
90 /* in YYYYMMDD format */
91 uint32_t date;
92
93 /* Size in dwords (CSS_Headerlen + PackageHeaderLen + dmc FWsLen)/4 */
94 uint32_t size;
95
96 /* Not used */
97 uint32_t key_size;
98
99 /* Not used */
100 uint32_t modulus_size;
101
102 /* Not used */
103 uint32_t exponent_size;
104
105 /* Not used */
106 uint32_t reserved1[12];
107
108 /* Major Minor */
109 uint32_t version;
110
111 /* Not used */
112 uint32_t reserved2[8];
113
114 /* Not used */
115 uint32_t kernel_header_info;
116 } __packed;
117
118 struct intel_fw_info {
119 uint16_t reserved1;
120
121 /* Stepping (A, B, C, ..., *). * is a wildcard */
122 char stepping;
123
124 /* Sub-stepping (0, 1, ..., *). * is a wildcard */
125 char substepping;
126
127 uint32_t offset;
128 uint32_t reserved2;
129 } __packed;
130
131 struct intel_package_header {
132 /* DMC container header length in dwords */
133 unsigned char header_len;
134
135 /* always value would be 0x01 */
136 unsigned char header_ver;
137
138 unsigned char reserved[10];
139
140 /* Number of valid entries in the FWInfo array below */
141 uint32_t num_entries;
142
143 struct intel_fw_info fw_info[20];
144 } __packed;
145
146 struct intel_dmc_header {
147 /* always value would be 0x40403E3E */
148 uint32_t signature;
149
150 /* DMC binary header length */
151 unsigned char header_len;
152
153 /* 0x01 */
154 unsigned char header_ver;
155
156 /* Reserved */
157 uint16_t dmcc_ver;
158
159 /* Major, Minor */
160 uint32_t project;
161
162 /* Firmware program size (excluding header) in dwords */
163 uint32_t fw_size;
164
165 /* Major Minor version */
166 uint32_t fw_version;
167
168 /* Number of valid MMIO cycles present. */
169 uint32_t mmio_count;
170
171 /* MMIO address */
172 uint32_t mmioaddr[8];
173
174 /* MMIO data */
175 uint32_t mmiodata[8];
176
177 /* FW filename */
178 unsigned char dfile[32];
179
180 uint32_t reserved1[2];
181 } __packed;
182
183 struct stepping_info {
184 char stepping;
185 char substepping;
186 };
187
188 /*
189 * Kabylake derivated from Skylake H0, so SKL H0
190 * is the right firmware for KBL A0 (revid 0).
191 */
192 static const struct stepping_info kbl_stepping_info[] = {
193 {'H', '0'}, {'I', '0'}
194 };
195
196 static const struct stepping_info skl_stepping_info[] = {
197 {'A', '0'}, {'B', '0'}, {'C', '0'},
198 {'D', '0'}, {'E', '0'}, {'F', '0'},
199 {'G', '0'}, {'H', '0'}, {'I', '0'},
200 {'J', '0'}, {'K', '0'}
201 };
202
203 static struct stepping_info bxt_stepping_info[] = {
204 {'A', '0'}, {'A', '1'}, {'A', '2'},
205 {'B', '0'}, {'B', '1'}, {'B', '2'}
206 };
207
208 static char intel_get_stepping(struct drm_device *dev)
209 {
210 if (IS_KABYLAKE(dev) && (dev->pdev->revision <
211 ARRAY_SIZE(kbl_stepping_info)))
212 return kbl_stepping_info[dev->pdev->revision].stepping;
213 else if (IS_SKYLAKE(dev) && (dev->pdev->revision <
214 ARRAY_SIZE(skl_stepping_info)))
215 return skl_stepping_info[dev->pdev->revision].stepping;
216 else if (IS_BROXTON(dev) && (dev->pdev->revision <
217 ARRAY_SIZE(bxt_stepping_info)))
218 return bxt_stepping_info[dev->pdev->revision].stepping;
219 else
220 return -ENODATA;
221 }
222
223 static char intel_get_substepping(struct drm_device *dev)
224 {
225 if (IS_KABYLAKE(dev) && (dev->pdev->revision <
226 ARRAY_SIZE(kbl_stepping_info)))
227 return kbl_stepping_info[dev->pdev->revision].substepping;
228 else if (IS_SKYLAKE(dev) && (dev->pdev->revision <
229 ARRAY_SIZE(skl_stepping_info)))
230 return skl_stepping_info[dev->pdev->revision].substepping;
231 else if (IS_BROXTON(dev) && (dev->pdev->revision <
232 ARRAY_SIZE(bxt_stepping_info)))
233 return bxt_stepping_info[dev->pdev->revision].substepping;
234 else
235 return -ENODATA;
236 }
237
238 /**
239 * intel_csr_load_status_get() - to get firmware loading status.
240 * @dev_priv: i915 device.
241 *
242 * This function helps to get the firmware loading status.
243 *
244 * Return: Firmware loading status.
245 */
246 enum csr_state intel_csr_load_status_get(struct drm_i915_private *dev_priv)
247 {
248 enum csr_state state;
249
250 mutex_lock(&dev_priv->csr_lock);
251 state = dev_priv->csr.state;
252 mutex_unlock(&dev_priv->csr_lock);
253
254 return state;
255 }
256
257 /**
258 * intel_csr_load_status_set() - help to set firmware loading status.
259 * @dev_priv: i915 device.
260 * @state: enumeration of firmware loading status.
261 *
262 * Set the firmware loading status.
263 */
264 void intel_csr_load_status_set(struct drm_i915_private *dev_priv,
265 enum csr_state state)
266 {
267 mutex_lock(&dev_priv->csr_lock);
268 dev_priv->csr.state = state;
269 mutex_unlock(&dev_priv->csr_lock);
270 }
271
272 /**
273 * intel_csr_load_program() - write the firmware from memory to register.
274 * @dev: drm device.
275 *
276 * CSR firmware is read from a .bin file and kept in internal memory one time.
277 * Everytime display comes back from low power state this function is called to
278 * copy the firmware from internal memory to registers.
279 */
280 void intel_csr_load_program(struct drm_device *dev)
281 {
282 struct drm_i915_private *dev_priv = dev->dev_private;
283 u32 *payload = dev_priv->csr.dmc_payload;
284 uint32_t i, fw_size;
285
286 if (!IS_GEN9(dev)) {
287 DRM_ERROR("No CSR support available for this platform\n");
288 return;
289 }
290
291 /*
292 * FIXME: Firmware gets lost on S3/S4, but not when entering system
293 * standby or suspend-to-idle (which is just like forced runtime pm).
294 * Unfortunately the ACPI subsystem doesn't yet give us a way to
295 * differentiate this, hence figure it out with this hack.
296 */
297 if (I915_READ(CSR_PROGRAM(0)))
298 return;
299
300 mutex_lock(&dev_priv->csr_lock);
301 fw_size = dev_priv->csr.dmc_fw_size;
302 for (i = 0; i < fw_size; i++)
303 I915_WRITE(CSR_PROGRAM(i), payload[i]);
304
305 for (i = 0; i < dev_priv->csr.mmio_count; i++) {
306 I915_WRITE(dev_priv->csr.mmioaddr[i],
307 dev_priv->csr.mmiodata[i]);
308 }
309
310 dev_priv->csr.state = FW_LOADED;
311 mutex_unlock(&dev_priv->csr_lock);
312 }
313
314 static void finish_csr_load(const struct firmware *fw, void *context)
315 {
316 struct drm_i915_private *dev_priv = context;
317 struct drm_device *dev = dev_priv->dev;
318 struct intel_css_header *css_header;
319 struct intel_package_header *package_header;
320 struct intel_dmc_header *dmc_header;
321 struct intel_csr *csr = &dev_priv->csr;
322 char stepping = intel_get_stepping(dev);
323 char substepping = intel_get_substepping(dev);
324 uint32_t dmc_offset = CSR_DEFAULT_FW_OFFSET, readcount = 0, nbytes;
325 uint32_t i;
326 uint32_t *dmc_payload;
327 bool fw_loaded = false;
328
329 if (!fw) {
330 i915_firmware_load_error_print(csr->fw_path, 0);
331 goto out;
332 }
333
334 if ((stepping == -ENODATA) || (substepping == -ENODATA)) {
335 DRM_ERROR("Unknown stepping info, firmware loading failed\n");
336 goto out;
337 }
338
339 /* Extract CSS Header information*/
340 css_header = (struct intel_css_header *)fw->data;
341 if (sizeof(struct intel_css_header) !=
342 (css_header->header_len * 4)) {
343 DRM_ERROR("Firmware has wrong CSS header length %u bytes\n",
344 (css_header->header_len * 4));
345 goto out;
346 }
347 readcount += sizeof(struct intel_css_header);
348
349 /* Extract Package Header information*/
350 package_header = (struct intel_package_header *)
351 &fw->data[readcount];
352 if (sizeof(struct intel_package_header) !=
353 (package_header->header_len * 4)) {
354 DRM_ERROR("Firmware has wrong package header length %u bytes\n",
355 (package_header->header_len * 4));
356 goto out;
357 }
358 readcount += sizeof(struct intel_package_header);
359
360 /* Search for dmc_offset to find firware binary. */
361 for (i = 0; i < package_header->num_entries; i++) {
362 if (package_header->fw_info[i].substepping == '*' &&
363 stepping == package_header->fw_info[i].stepping) {
364 dmc_offset = package_header->fw_info[i].offset;
365 break;
366 } else if (stepping == package_header->fw_info[i].stepping &&
367 substepping == package_header->fw_info[i].substepping) {
368 dmc_offset = package_header->fw_info[i].offset;
369 break;
370 } else if (package_header->fw_info[i].stepping == '*' &&
371 package_header->fw_info[i].substepping == '*')
372 dmc_offset = package_header->fw_info[i].offset;
373 }
374 if (dmc_offset == CSR_DEFAULT_FW_OFFSET) {
375 DRM_ERROR("Firmware not supported for %c stepping\n", stepping);
376 goto out;
377 }
378 readcount += dmc_offset;
379
380 /* Extract dmc_header information. */
381 dmc_header = (struct intel_dmc_header *)&fw->data[readcount];
382 if (sizeof(struct intel_dmc_header) != (dmc_header->header_len)) {
383 DRM_ERROR("Firmware has wrong dmc header length %u bytes\n",
384 (dmc_header->header_len));
385 goto out;
386 }
387 readcount += sizeof(struct intel_dmc_header);
388
389 /* Cache the dmc header info. */
390 if (dmc_header->mmio_count > ARRAY_SIZE(csr->mmioaddr)) {
391 DRM_ERROR("Firmware has wrong mmio count %u\n",
392 dmc_header->mmio_count);
393 goto out;
394 }
395 csr->mmio_count = dmc_header->mmio_count;
396 for (i = 0; i < dmc_header->mmio_count; i++) {
397 if (dmc_header->mmioaddr[i] < CSR_MMIO_START_RANGE ||
398 dmc_header->mmioaddr[i] > CSR_MMIO_END_RANGE) {
399 DRM_ERROR(" Firmware has wrong mmio address 0x%x\n",
400 dmc_header->mmioaddr[i]);
401 goto out;
402 }
403 csr->mmioaddr[i] = dmc_header->mmioaddr[i];
404 csr->mmiodata[i] = dmc_header->mmiodata[i];
405 }
406
407 /* fw_size is in dwords, so multiplied by 4 to convert into bytes. */
408 nbytes = dmc_header->fw_size * 4;
409 if (nbytes > CSR_MAX_FW_SIZE) {
410 DRM_ERROR("CSR firmware too big (%u) bytes\n", nbytes);
411 goto out;
412 }
413 csr->dmc_fw_size = dmc_header->fw_size;
414
415 csr->dmc_payload = kmalloc(nbytes, GFP_KERNEL);
416 if (!csr->dmc_payload) {
417 DRM_ERROR("Memory allocation failed for dmc payload\n");
418 goto out;
419 }
420
421 dmc_payload = csr->dmc_payload;
422 memcpy(dmc_payload, &fw->data[readcount], nbytes);
423
424 /* load csr program during system boot, as needed for DC states */
425 intel_csr_load_program(dev);
426 fw_loaded = true;
427
428 DRM_DEBUG_KMS("Finished loading %s\n", dev_priv->csr.fw_path);
429 out:
430 if (fw_loaded)
431 intel_runtime_pm_put(dev_priv);
432 else
433 intel_csr_load_status_set(dev_priv, FW_FAILED);
434
435 release_firmware(fw);
436 }
437
438 /**
439 * intel_csr_ucode_init() - initialize the firmware loading.
440 * @dev: drm device.
441 *
442 * This function is called at the time of loading the display driver to read
443 * firmware from a .bin file and copied into a internal memory.
444 */
445 void intel_csr_ucode_init(struct drm_device *dev)
446 {
447 struct drm_i915_private *dev_priv = dev->dev_private;
448 struct intel_csr *csr = &dev_priv->csr;
449 int ret;
450
451 if (!HAS_CSR(dev))
452 return;
453
454 if (IS_KABYLAKE(dev))
455 csr->fw_path = I915_CSR_KBL;
456 else if (IS_SKYLAKE(dev))
457 csr->fw_path = I915_CSR_SKL;
458 else if (IS_BROXTON(dev_priv))
459 csr->fw_path = I915_CSR_BXT;
460 else {
461 DRM_ERROR("Unexpected: no known CSR firmware for platform\n");
462 intel_csr_load_status_set(dev_priv, FW_FAILED);
463 return;
464 }
465
466 DRM_DEBUG_KMS("Loading %s\n", csr->fw_path);
467
468 /*
469 * Obtain a runtime pm reference, until CSR is loaded,
470 * to avoid entering runtime-suspend.
471 */
472 intel_runtime_pm_get(dev_priv);
473
474 /* CSR supported for platform, load firmware */
475 ret = request_firmware_nowait(THIS_MODULE, true, csr->fw_path,
476 dev_priv->dev->dev,
477 GFP_KERNEL, dev_priv,
478 finish_csr_load);
479 if (ret) {
480 i915_firmware_load_error_print(csr->fw_path, ret);
481 intel_csr_load_status_set(dev_priv, FW_FAILED);
482 }
483 }
484
485 /**
486 * intel_csr_ucode_fini() - unload the CSR firmware.
487 * @dev: drm device.
488 *
489 * Firmmware unloading includes freeing the internal momory and reset the
490 * firmware loading status.
491 */
492 void intel_csr_ucode_fini(struct drm_device *dev)
493 {
494 struct drm_i915_private *dev_priv = dev->dev_private;
495
496 if (!HAS_CSR(dev))
497 return;
498
499 intel_csr_load_status_set(dev_priv, FW_FAILED);
500 kfree(dev_priv->csr.dmc_payload);
501 }
502
503 void assert_csr_loaded(struct drm_i915_private *dev_priv)
504 {
505 WARN_ONCE(intel_csr_load_status_get(dev_priv) != FW_LOADED,
506 "CSR is not loaded.\n");
507 WARN_ONCE(!I915_READ(CSR_PROGRAM(0)),
508 "CSR program storage start is NULL\n");
509 WARN_ONCE(!I915_READ(CSR_SSP_BASE), "CSR SSP Base Not fine\n");
510 WARN_ONCE(!I915_READ(CSR_HTP_SKL), "CSR HTP Not fine\n");
511 }
512