xref: /netbsd-src/sys/external/bsd/drm2/dist/drm/i915/intel_csr.c (revision 9fb66d812c00ebfb445c0b47dea128f32aa6fe96)
1 /*	$NetBSD: intel_csr.c,v 1.6 2020/02/14 14:34:58 maya 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.6 2020/02/14 14:34:58 maya 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