blob: 17ce573b9162190f43206315ea6d01dfb46edd72 [file] [log] [blame]
Viresh Kumar90f1b612015-08-12 09:19:33 +05301/*
2 * FIRMWARE Greybus driver.
3 *
4 * Copyright 2015 Google Inc.
5 * Copyright 2015 Linaro Ltd.
6 *
7 * Released under the GPLv2 only.
8 */
9
10#include <linux/firmware.h>
11
Johan Hovold8ec589b2016-01-29 15:42:31 +010012#include "firmware.h"
Viresh Kumar90f1b612015-08-12 09:19:33 +053013#include "greybus.h"
14
Johan Hovold8ec589b2016-01-29 15:42:31 +010015
Viresh Kumar90f1b612015-08-12 09:19:33 +053016struct gb_firmware {
17 struct gb_connection *connection;
18 const struct firmware *fw;
Johan Hovold8ec589b2016-01-29 15:42:31 +010019 u8 protocol_major;
20 u8 protocol_minor;
Viresh Kumar90f1b612015-08-12 09:19:33 +053021};
22
23static void free_firmware(struct gb_firmware *firmware)
24{
25 release_firmware(firmware->fw);
26 firmware->fw = NULL;
27}
28
Viresh Kumarf1e941a2015-11-26 15:33:46 +053029/*
30 * The es2 chip doesn't have VID/PID programmed into the hardware and we need to
31 * hack that up to distinguish different modules and their firmware blobs.
32 *
33 * This fetches VID/PID (over firmware protocol) for es2 chip only, when VID/PID
34 * already sent during hotplug are 0.
35 *
Viresh Kumarf3e6c092016-01-22 16:16:08 +053036 * Otherwise, we keep intf->vendor_id/product_id same as what's passed
Viresh Kumarf1e941a2015-11-26 15:33:46 +053037 * during hotplug.
38 */
39static void firmware_es2_fixup_vid_pid(struct gb_firmware *firmware)
40{
41 struct gb_firmware_get_vid_pid_response response;
42 struct gb_connection *connection = firmware->connection;
43 struct gb_interface *intf = connection->bundle->intf;
44 int ret;
45
46 /*
47 * Use VID/PID specified at hotplug if:
48 * - Bridge ASIC chip isn't ES2
49 * - Received non-zero Vendor/Product ids
50 */
Viresh Kumarb32a5c52015-12-22 22:04:33 +053051 if (intf->ddbl1_manufacturer_id != ES2_DDBL1_MFR_ID ||
52 intf->ddbl1_product_id != ES2_DDBL1_PROD_ID ||
Viresh Kumarf1e941a2015-11-26 15:33:46 +053053 intf->vendor_id != 0 || intf->product_id != 0)
54 return;
55
56 ret = gb_operation_sync(connection, GB_FIRMWARE_TYPE_GET_VID_PID,
57 NULL, 0, &response, sizeof(response));
58 if (ret) {
59 dev_err(&connection->bundle->dev,
60 "Firmware get vid/pid operation failed (%d)\n", ret);
61 return;
62 }
63
Viresh Kumarf3e6c092016-01-22 16:16:08 +053064 /*
65 * NOTE: This is hacked, so that the same values of VID/PID can be used
66 * by next firmware level as well. The uevent for bootrom will still
67 * have VID/PID as 0, though after this point the sysfs files will start
68 * showing the updated values. But yeah, that's a bit racy as the same
69 * sysfs files would be showing 0 before this point.
70 */
71 intf->vendor_id = le32_to_cpu(response.vendor_id);
72 intf->product_id = le32_to_cpu(response.product_id);
Eli Senneshfc41c2d2016-01-08 14:11:29 -050073
74 dev_dbg(&connection->bundle->dev, "Firmware got vid (0x%x)/pid (0x%x)\n",
Viresh Kumarf3e6c092016-01-22 16:16:08 +053075 intf->vendor_id, intf->product_id);
Viresh Kumarf1e941a2015-11-26 15:33:46 +053076}
77
Viresh Kumar90f1b612015-08-12 09:19:33 +053078/* This returns path of the firmware blob on the disk */
79static int download_firmware(struct gb_firmware *firmware, u8 stage)
80{
81 struct gb_connection *connection = firmware->connection;
82 struct gb_interface *intf = connection->bundle->intf;
Viresh Kumar1a886282015-09-09 21:08:32 +053083 char firmware_name[48];
Eli Senneshfc41c2d2016-01-08 14:11:29 -050084 int rc;
Viresh Kumar90f1b612015-08-12 09:19:33 +053085
86 /* Already have a firmware, free it */
87 if (firmware->fw)
88 free_firmware(firmware);
89
90 /*
91 * Create firmware name
92 *
93 * XXX Name it properly..
94 */
Johan Hovoldaf0b4d52015-08-28 11:58:24 +020095 snprintf(firmware_name, sizeof(firmware_name),
Michael Scottb29906a2016-01-15 14:03:17 -080096 "ara_%08x_%08x_%08x_%08x_%02x.tftf",
Viresh Kumarb32a5c52015-12-22 22:04:33 +053097 intf->ddbl1_manufacturer_id, intf->ddbl1_product_id,
Viresh Kumarf3e6c092016-01-22 16:16:08 +053098 intf->vendor_id, intf->product_id, stage);
Viresh Kumar90f1b612015-08-12 09:19:33 +053099
Greg Kroah-Hartmaneb8fafd2016-01-20 09:27:05 -0800100 // FIXME:
101 // Turn to dev_dbg later after everyone has valid bootloaders with good
102 // ids, but leave this as dev_info for now to make it easier to track
103 // down "empty" vid/pid modules.
104 dev_info(&connection->bundle->dev, "Firmware file '%s' requested\n",
105 firmware_name);
106
Eli Senneshfc41c2d2016-01-08 14:11:29 -0500107 rc = request_firmware(&firmware->fw, firmware_name,
108 &connection->bundle->dev);
Greg Kroah-Hartmaneb8fafd2016-01-20 09:27:05 -0800109 if (rc)
110 dev_err(&connection->bundle->dev,
111 "Firware request for %s has failed : %d",
112 firmware_name, rc);
Eli Senneshfc41c2d2016-01-08 14:11:29 -0500113 return rc;
Viresh Kumar90f1b612015-08-12 09:19:33 +0530114}
115
116static int gb_firmware_size_request(struct gb_operation *op)
117{
118 struct gb_connection *connection = op->connection;
119 struct gb_firmware *firmware = connection->private;
120 struct gb_firmware_size_request *size_request = op->request->payload;
121 struct gb_firmware_size_response *size_response;
Greg Kroah-Hartman0a72bd32015-10-14 11:17:29 -0700122 struct device *dev = &connection->bundle->dev;
Viresh Kumar90f1b612015-08-12 09:19:33 +0530123 int ret;
124
125 if (op->request->payload_size != sizeof(*size_request)) {
126 dev_err(dev, "%s: illegal size of firmware size request (%zu != %zu)\n",
127 __func__, op->request->payload_size,
128 sizeof(*size_request));
129 return -EINVAL;
130 }
131
132 ret = download_firmware(firmware, size_request->stage);
133 if (ret) {
134 dev_err(dev, "%s: failed to download firmware (%d)\n", __func__,
135 ret);
136 return ret;
137 }
138
139 if (!gb_operation_response_alloc(op, sizeof(*size_response),
140 GFP_KERNEL)) {
141 dev_err(dev, "%s: error allocating response\n", __func__);
142 free_firmware(firmware);
143 return -ENOMEM;
144 }
145
146 size_response = op->response->payload;
147 size_response->size = cpu_to_le32(firmware->fw->size);
148
Eli Senneshfc41c2d2016-01-08 14:11:29 -0500149 dev_dbg(dev, "%s: firmware size %d bytes\n", __func__, size_response->size);
150
Viresh Kumar90f1b612015-08-12 09:19:33 +0530151 return 0;
152}
153
154static int gb_firmware_get_firmware(struct gb_operation *op)
155{
156 struct gb_connection *connection = op->connection;
157 struct gb_firmware *firmware = connection->private;
Johan Hovold98645a92015-11-19 18:27:59 +0100158 const struct firmware *fw = firmware->fw;
Johan Hovold87f6c972015-11-19 18:28:00 +0100159 struct gb_firmware_get_firmware_request *firmware_request;
Viresh Kumar90f1b612015-08-12 09:19:33 +0530160 struct gb_firmware_get_firmware_response *firmware_response;
Greg Kroah-Hartman0a72bd32015-10-14 11:17:29 -0700161 struct device *dev = &connection->bundle->dev;
Viresh Kumar90f1b612015-08-12 09:19:33 +0530162 unsigned int offset, size;
163
164 if (op->request->payload_size != sizeof(*firmware_request)) {
165 dev_err(dev, "%s: Illegal size of get firmware request (%zu %zu)\n",
166 __func__, op->request->payload_size,
167 sizeof(*firmware_request));
168 return -EINVAL;
169 }
170
Johan Hovold98645a92015-11-19 18:27:59 +0100171 if (!fw) {
Viresh Kumar90f1b612015-08-12 09:19:33 +0530172 dev_err(dev, "%s: firmware not available\n", __func__);
173 return -EINVAL;
174 }
175
Johan Hovold87f6c972015-11-19 18:28:00 +0100176 firmware_request = op->request->payload;
Viresh Kumar90f1b612015-08-12 09:19:33 +0530177 offset = le32_to_cpu(firmware_request->offset);
178 size = le32_to_cpu(firmware_request->size);
179
Johan Hovold98645a92015-11-19 18:27:59 +0100180 if (offset >= fw->size || size > fw->size - offset) {
181 dev_warn(dev, "bad firmware request (offs = %u, size = %u)\n",
182 offset, size);
183 return -EINVAL;
184 }
185
Viresh Kumar90f1b612015-08-12 09:19:33 +0530186 if (!gb_operation_response_alloc(op, sizeof(*firmware_response) + size,
187 GFP_KERNEL)) {
188 dev_err(dev, "%s: error allocating response\n", __func__);
189 return -ENOMEM;
190 }
191
192 firmware_response = op->response->payload;
Johan Hovold98645a92015-11-19 18:27:59 +0100193 memcpy(firmware_response->data, fw->data + offset, size);
Viresh Kumar90f1b612015-08-12 09:19:33 +0530194
Eli Senneshfc41c2d2016-01-08 14:11:29 -0500195 dev_dbg(dev, "responding with firmware (offs = %u, size = %u)\n", offset,
196 size);
197
Viresh Kumar90f1b612015-08-12 09:19:33 +0530198 return 0;
199}
200
201static int gb_firmware_ready_to_boot(struct gb_operation *op)
202{
203 struct gb_connection *connection = op->connection;
Johan Hovold87f6c972015-11-19 18:28:00 +0100204 struct gb_firmware_ready_to_boot_request *rtb_request;
Greg Kroah-Hartman0a72bd32015-10-14 11:17:29 -0700205 struct device *dev = &connection->bundle->dev;
Viresh Kumar06986a22015-09-23 16:48:12 -0700206 u8 status;
Viresh Kumar90f1b612015-08-12 09:19:33 +0530207
208 if (op->request->payload_size != sizeof(*rtb_request)) {
209 dev_err(dev, "%s: Illegal size of ready to boot request (%zu %zu)\n",
210 __func__, op->request->payload_size,
211 sizeof(*rtb_request));
212 return -EINVAL;
213 }
214
Johan Hovold87f6c972015-11-19 18:28:00 +0100215 rtb_request = op->request->payload;
Viresh Kumar90f1b612015-08-12 09:19:33 +0530216 status = rtb_request->status;
217
218 /* Return error if the blob was invalid */
219 if (status == GB_FIRMWARE_BOOT_STATUS_INVALID)
220 return -EINVAL;
221
222 /*
223 * XXX Should we return error for insecure firmware?
224 */
Eli Senneshfc41c2d2016-01-08 14:11:29 -0500225 dev_dbg(dev, "ready to boot: 0x%x, 0\n", status);
Viresh Kumar90f1b612015-08-12 09:19:33 +0530226
227 return 0;
228}
229
Johan Hovold8ec589b2016-01-29 15:42:31 +0100230static int gb_firmware_request_handler(struct gb_operation *op)
Viresh Kumar90f1b612015-08-12 09:19:33 +0530231{
Johan Hovold8ec589b2016-01-29 15:42:31 +0100232 u8 type = op->type;
233
Viresh Kumar90f1b612015-08-12 09:19:33 +0530234 switch (type) {
235 case GB_FIRMWARE_TYPE_FIRMWARE_SIZE:
236 return gb_firmware_size_request(op);
237 case GB_FIRMWARE_TYPE_GET_FIRMWARE:
238 return gb_firmware_get_firmware(op);
239 case GB_FIRMWARE_TYPE_READY_TO_BOOT:
240 return gb_firmware_ready_to_boot(op);
241 default:
Greg Kroah-Hartman0a72bd32015-10-14 11:17:29 -0700242 dev_err(&op->connection->bundle->dev,
Viresh Kumar2f3db922015-12-04 21:30:09 +0530243 "unsupported request: %u\n", type);
Viresh Kumar90f1b612015-08-12 09:19:33 +0530244 return -EINVAL;
245 }
246}
247
Johan Hovold8ec589b2016-01-29 15:42:31 +0100248static int gb_firmware_get_version(struct gb_firmware *firmware)
Viresh Kumar90f1b612015-08-12 09:19:33 +0530249{
Johan Hovold8ec589b2016-01-29 15:42:31 +0100250 struct gb_bundle *bundle = firmware->connection->bundle;
251 struct gb_firmware_version_request request;
252 struct gb_firmware_version_response response;
253 int ret;
254
255 request.major = GB_FIRMWARE_VERSION_MAJOR;
256 request.minor = GB_FIRMWARE_VERSION_MINOR;
257
258 ret = gb_operation_sync(firmware->connection,
259 GB_FIRMWARE_TYPE_VERSION,
260 &request, sizeof(request), &response,
261 sizeof(response));
262 if (ret) {
263 dev_err(&bundle->dev,
264 "failed to get protocol version: %d\n",
265 ret);
266 return ret;
267 }
268
269 if (response.major > request.major) {
270 dev_err(&bundle->dev,
271 "unsupported major protocol version (%u > %u)\n",
272 response.major, request.major);
273 return -ENOTSUPP;
274 }
275
276 firmware->protocol_major = response.major;
277 firmware->protocol_minor = response.minor;
278
279 dev_dbg(&bundle->dev, "%s - %u.%u\n", __func__, response.major,
280 response.minor);
281
282 return 0;
283}
284
285static int gb_firmware_probe(struct gb_bundle *bundle,
286 const struct greybus_bundle_id *id)
287{
288 struct greybus_descriptor_cport *cport_desc;
289 struct gb_connection *connection;
Viresh Kumar90f1b612015-08-12 09:19:33 +0530290 struct gb_firmware *firmware;
Viresh Kumar4c9e2282015-09-09 21:08:33 +0530291 int ret;
Viresh Kumar90f1b612015-08-12 09:19:33 +0530292
Johan Hovold8ec589b2016-01-29 15:42:31 +0100293 if (bundle->num_cports != 1)
294 return -ENODEV;
295
296 cport_desc = &bundle->cport_desc[0];
297 if (cport_desc->protocol_id != GREYBUS_PROTOCOL_FIRMWARE)
298 return -ENODEV;
299
Viresh Kumar90f1b612015-08-12 09:19:33 +0530300 firmware = kzalloc(sizeof(*firmware), GFP_KERNEL);
301 if (!firmware)
302 return -ENOMEM;
303
Johan Hovold8ec589b2016-01-29 15:42:31 +0100304 connection = gb_connection_create(bundle,
305 le16_to_cpu(cport_desc->id),
306 gb_firmware_request_handler);
307 if (IS_ERR(connection)) {
308 ret = PTR_ERR(connection);
309 goto err_free_firmware;
310 }
311
Viresh Kumar90f1b612015-08-12 09:19:33 +0530312 connection->private = firmware;
313
Johan Hovold8ec589b2016-01-29 15:42:31 +0100314 firmware->connection = connection;
315
316 greybus_set_drvdata(bundle, firmware);
317
318 ret = gb_connection_enable_tx(connection);
319 if (ret)
320 goto err_connection_destroy;
321
322 ret = gb_firmware_get_version(firmware);
323 if (ret)
324 goto err_connection_disable;
325
Viresh Kumarf1e941a2015-11-26 15:33:46 +0530326 firmware_es2_fixup_vid_pid(firmware);
327
Johan Hovold8ec589b2016-01-29 15:42:31 +0100328 ret = gb_connection_enable(connection);
329 if (ret)
330 goto err_connection_disable;
331
Johan Hovold8eff5102016-01-21 17:34:26 +0100332 /* Tell bootrom we're ready. */
Viresh Kumar4c9e2282015-09-09 21:08:33 +0530333 ret = gb_operation_sync(connection, GB_FIRMWARE_TYPE_AP_READY, NULL, 0,
334 NULL, 0);
Johan Hovold87f6c972015-11-19 18:28:00 +0100335 if (ret) {
336 dev_err(&connection->bundle->dev,
337 "failed to send AP READY: %d\n", ret);
Johan Hovold8ec589b2016-01-29 15:42:31 +0100338 goto err_connection_disable;
Johan Hovold87f6c972015-11-19 18:28:00 +0100339 }
Viresh Kumar4c9e2282015-09-09 21:08:33 +0530340
Johan Hovold8ec589b2016-01-29 15:42:31 +0100341 dev_dbg(&bundle->dev, "AP_READY sent\n");
Eli Senneshfc41c2d2016-01-08 14:11:29 -0500342
Viresh Kumar90f1b612015-08-12 09:19:33 +0530343 return 0;
Johan Hovold8eff5102016-01-21 17:34:26 +0100344
Johan Hovold8ec589b2016-01-29 15:42:31 +0100345err_connection_disable:
346 gb_connection_disable(connection);
347err_connection_destroy:
348 gb_connection_destroy(connection);
Johan Hovold8eff5102016-01-21 17:34:26 +0100349err_free_firmware:
350 kfree(firmware);
351
352 return ret;
Viresh Kumar90f1b612015-08-12 09:19:33 +0530353}
354
Johan Hovold8ec589b2016-01-29 15:42:31 +0100355static void gb_firmware_disconnect(struct gb_bundle *bundle)
Viresh Kumar90f1b612015-08-12 09:19:33 +0530356{
Johan Hovold8ec589b2016-01-29 15:42:31 +0100357 struct gb_firmware *firmware = greybus_get_drvdata(bundle);
358
359 dev_dbg(&bundle->dev, "%s\n", __func__);
360
361 gb_connection_disable(firmware->connection);
Viresh Kumar90f1b612015-08-12 09:19:33 +0530362
363 /* Release firmware */
364 if (firmware->fw)
365 free_firmware(firmware);
366
Johan Hovold8ec589b2016-01-29 15:42:31 +0100367 gb_connection_destroy(firmware->connection);
Viresh Kumar90f1b612015-08-12 09:19:33 +0530368 kfree(firmware);
369}
370
Johan Hovold8ec589b2016-01-29 15:42:31 +0100371static const struct greybus_bundle_id gb_firmware_id_table[] = {
372 { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_FIRMWARE) },
373 { }
Viresh Kumar90f1b612015-08-12 09:19:33 +0530374};
Johan Hovold8ec589b2016-01-29 15:42:31 +0100375
376static struct greybus_driver gb_firmware_driver = {
377 .name = "firmware",
378 .probe = gb_firmware_probe,
379 .disconnect = gb_firmware_disconnect,
380 .id_table = gb_firmware_id_table,
381};
382
383int gb_firmware_init(void)
384{
385 return greybus_register(&gb_firmware_driver);
386}
387
388void gb_firmware_exit(void)
389{
390 greybus_deregister(&gb_firmware_driver);
391}