blob: e5155deee69e242564c5903b3a9a72e6b450ac42 [file] [log] [blame]
Arkadiusz Hiler2d803c22016-11-25 18:59:35 +01001/*
2 * Copyright © 2016 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 */
24
25#include "i915_drv.h"
26#include "intel_uc.h"
Arkadiusz Hiler4c0fed72017-03-14 15:28:08 +010027#include <linux/firmware.h>
Arkadiusz Hiler2d803c22016-11-25 18:59:35 +010028
Arkadiusz Hiler413e8fd2016-11-25 18:59:36 +010029void intel_uc_init_early(struct drm_i915_private *dev_priv)
30{
31 mutex_init(&dev_priv->guc.send_mutex);
32}
33
Arkadiusz Hiler29ad6a32017-03-14 15:28:09 +010034void intel_uc_init_fw(struct drm_i915_private *dev_priv)
35{
36 intel_huc_init_fw(&dev_priv->huc);
37 intel_guc_init_fw(&dev_priv->guc);
38}
39
Arkadiusz Hiler2d803c22016-11-25 18:59:35 +010040/*
41 * Read GuC command/status register (SOFT_SCRATCH_0)
42 * Return true if it contains a response rather than a command
43 */
Michal Wajdeczkobae3fdc2016-12-20 11:55:31 +000044static bool intel_guc_recv(struct intel_guc *guc, u32 *status)
Arkadiusz Hiler2d803c22016-11-25 18:59:35 +010045{
Michal Wajdeczkobae3fdc2016-12-20 11:55:31 +000046 struct drm_i915_private *dev_priv = guc_to_i915(guc);
47
Arkadiusz Hiler2d803c22016-11-25 18:59:35 +010048 u32 val = I915_READ(SOFT_SCRATCH(0));
49 *status = val;
50 return INTEL_GUC_RECV_IS_RESPONSE(val);
51}
52
53int intel_guc_send(struct intel_guc *guc, const u32 *action, u32 len)
54{
55 struct drm_i915_private *dev_priv = guc_to_i915(guc);
56 u32 status;
57 int i;
58 int ret;
59
60 if (WARN_ON(len < 1 || len > 15))
61 return -EINVAL;
62
63 mutex_lock(&guc->send_mutex);
64 intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
65
66 dev_priv->guc.action_count += 1;
67 dev_priv->guc.action_cmd = action[0];
68
69 for (i = 0; i < len; i++)
70 I915_WRITE(SOFT_SCRATCH(i), action[i]);
71
72 POSTING_READ(SOFT_SCRATCH(i - 1));
73
74 I915_WRITE(GUC_SEND_INTERRUPT, GUC_SEND_TRIGGER);
75
76 /*
77 * Fast commands should complete in less than 10us, so sample quickly
78 * up to that length of time, then switch to a slower sleep-wait loop.
79 * No inte_guc_send command should ever take longer than 10ms.
80 */
Michal Wajdeczkobae3fdc2016-12-20 11:55:31 +000081 ret = wait_for_us(intel_guc_recv(guc, &status), 10);
Arkadiusz Hiler2d803c22016-11-25 18:59:35 +010082 if (ret)
Michal Wajdeczkobae3fdc2016-12-20 11:55:31 +000083 ret = wait_for(intel_guc_recv(guc, &status), 10);
Arkadiusz Hiler2d803c22016-11-25 18:59:35 +010084 if (status != INTEL_GUC_STATUS_SUCCESS) {
85 /*
86 * Either the GuC explicitly returned an error (which
87 * we convert to -EIO here) or no response at all was
88 * received within the timeout limit (-ETIMEDOUT)
89 */
90 if (ret != -ETIMEDOUT)
91 ret = -EIO;
92
93 DRM_WARN("INTEL_GUC_SEND: Action 0x%X failed;"
94 " ret=%d status=0x%08X response=0x%08X\n",
95 action[0], ret, status, I915_READ(SOFT_SCRATCH(15)));
96
97 dev_priv->guc.action_fail += 1;
98 dev_priv->guc.action_err = ret;
99 }
100 dev_priv->guc.action_status = status;
101
102 intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
103 mutex_unlock(&guc->send_mutex);
104
105 return ret;
106}
107
108int intel_guc_sample_forcewake(struct intel_guc *guc)
109{
110 struct drm_i915_private *dev_priv = guc_to_i915(guc);
111 u32 action[2];
112
113 action[0] = INTEL_GUC_ACTION_SAMPLE_FORCEWAKE;
114 /* WaRsDisableCoarsePowerGating:skl,bxt */
115 if (!intel_enable_rc6() || NEEDS_WaRsDisableCoarsePowerGating(dev_priv))
116 action[1] = 0;
117 else
118 /* bit 0 and 1 are for Render and Media domain separately */
119 action[1] = GUC_FORCEWAKE_RENDER | GUC_FORCEWAKE_MEDIA;
120
121 return intel_guc_send(guc, action, ARRAY_SIZE(action));
122}
123
Arkadiusz Hiler4c0fed72017-03-14 15:28:08 +0100124void intel_uc_prepare_fw(struct drm_i915_private *dev_priv,
125 struct intel_uc_fw *uc_fw)
126{
127 struct pci_dev *pdev = dev_priv->drm.pdev;
128 struct drm_i915_gem_object *obj;
129 const struct firmware *fw = NULL;
130 struct uc_css_header *css;
131 size_t size;
132 int err;
133
134 DRM_DEBUG_DRIVER("before requesting firmware: uC fw fetch status %s\n",
135 intel_uc_fw_status_repr(uc_fw->fetch_status));
136
137 err = request_firmware(&fw, uc_fw->path, &pdev->dev);
138 if (err)
139 goto fail;
140 if (!fw)
141 goto fail;
142
143 DRM_DEBUG_DRIVER("fetch uC fw from %s succeeded, fw %p\n",
144 uc_fw->path, fw);
145
146 /* Check the size of the blob before examining buffer contents */
147 if (fw->size < sizeof(struct uc_css_header)) {
148 DRM_NOTE("Firmware header is missing\n");
149 goto fail;
150 }
151
152 css = (struct uc_css_header *)fw->data;
153
154 /* Firmware bits always start from header */
155 uc_fw->header_offset = 0;
156 uc_fw->header_size = (css->header_size_dw - css->modulus_size_dw -
157 css->key_size_dw - css->exponent_size_dw) * sizeof(u32);
158
159 if (uc_fw->header_size != sizeof(struct uc_css_header)) {
160 DRM_NOTE("CSS header definition mismatch\n");
161 goto fail;
162 }
163
164 /* then, uCode */
165 uc_fw->ucode_offset = uc_fw->header_offset + uc_fw->header_size;
166 uc_fw->ucode_size = (css->size_dw - css->header_size_dw) * sizeof(u32);
167
168 /* now RSA */
169 if (css->key_size_dw != UOS_RSA_SCRATCH_MAX_COUNT) {
170 DRM_NOTE("RSA key size is bad\n");
171 goto fail;
172 }
173 uc_fw->rsa_offset = uc_fw->ucode_offset + uc_fw->ucode_size;
174 uc_fw->rsa_size = css->key_size_dw * sizeof(u32);
175
176 /* At least, it should have header, uCode and RSA. Size of all three. */
177 size = uc_fw->header_size + uc_fw->ucode_size + uc_fw->rsa_size;
178 if (fw->size < size) {
179 DRM_NOTE("Missing firmware components\n");
180 goto fail;
181 }
182
183 /*
184 * The GuC firmware image has the version number embedded at a
185 * well-known offset within the firmware blob; note that major / minor
186 * version are TWO bytes each (i.e. u16), although all pointers and
187 * offsets are defined in terms of bytes (u8).
188 */
189 switch (uc_fw->fw) {
190 case INTEL_UC_FW_TYPE_GUC:
191 /* Header and uCode will be loaded to WOPCM. Size of the two. */
192 size = uc_fw->header_size + uc_fw->ucode_size;
193
194 /* Top 32k of WOPCM is reserved (8K stack + 24k RC6 context). */
195 if (size > intel_guc_wopcm_size(dev_priv)) {
196 DRM_ERROR("Firmware is too large to fit in WOPCM\n");
197 goto fail;
198 }
199 uc_fw->major_ver_found = css->guc.sw_version >> 16;
200 uc_fw->minor_ver_found = css->guc.sw_version & 0xFFFF;
201 break;
202
203 case INTEL_UC_FW_TYPE_HUC:
204 uc_fw->major_ver_found = css->huc.sw_version >> 16;
205 uc_fw->minor_ver_found = css->huc.sw_version & 0xFFFF;
206 break;
207
208 default:
209 DRM_ERROR("Unknown firmware type %d\n", uc_fw->fw);
210 err = -ENOEXEC;
211 goto fail;
212 }
213
214 if (uc_fw->major_ver_found != uc_fw->major_ver_wanted ||
215 uc_fw->minor_ver_found < uc_fw->minor_ver_wanted) {
216 DRM_NOTE("uC firmware version %d.%d, required %d.%d\n",
217 uc_fw->major_ver_found, uc_fw->minor_ver_found,
218 uc_fw->major_ver_wanted, uc_fw->minor_ver_wanted);
219 err = -ENOEXEC;
220 goto fail;
221 }
222
223 DRM_DEBUG_DRIVER("firmware version %d.%d OK (minimum %d.%d)\n",
224 uc_fw->major_ver_found, uc_fw->minor_ver_found,
225 uc_fw->major_ver_wanted, uc_fw->minor_ver_wanted);
226
227 mutex_lock(&dev_priv->drm.struct_mutex);
228 obj = i915_gem_object_create_from_data(dev_priv, fw->data, fw->size);
229 mutex_unlock(&dev_priv->drm.struct_mutex);
230 if (IS_ERR_OR_NULL(obj)) {
231 err = obj ? PTR_ERR(obj) : -ENOMEM;
232 goto fail;
233 }
234
235 uc_fw->obj = obj;
236 uc_fw->size = fw->size;
237
238 DRM_DEBUG_DRIVER("uC fw fetch status SUCCESS, obj %p\n",
239 uc_fw->obj);
240
241 release_firmware(fw);
242 uc_fw->fetch_status = INTEL_UC_FIRMWARE_SUCCESS;
243 return;
244
245fail:
246 DRM_WARN("Failed to fetch valid uC firmware from %s (error %d)\n",
247 uc_fw->path, err);
248 DRM_DEBUG_DRIVER("uC fw fetch status FAIL; err %d, fw %p, obj %p\n",
249 err, fw, uc_fw->obj);
250
251 release_firmware(fw); /* OK even if fw is NULL */
252 uc_fw->fetch_status = INTEL_UC_FIRMWARE_FAIL;
253}