502 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * FPGA Manager Driver for Intel Stratix10 SoC4 *5 * Copyright (C) 2018 Intel Corporation6 */7#include <linux/completion.h>8#include <linux/fpga/fpga-mgr.h>9#include <linux/firmware/intel/stratix10-svc-client.h>10#include <linux/module.h>11#include <linux/of.h>12#include <linux/of_platform.h>13#include <linux/platform_device.h>14 15/*16 * FPGA programming requires a higher level of privilege (EL3), per the SoC17 * design.18 */19#define NUM_SVC_BUFS 420#define SVC_BUF_SIZE SZ_512K21 22/* Indicates buffer is in use if set */23#define SVC_BUF_LOCK 024 25#define S10_BUFFER_TIMEOUT (msecs_to_jiffies(SVC_RECONFIG_BUFFER_TIMEOUT_MS))26#define S10_RECONFIG_TIMEOUT (msecs_to_jiffies(SVC_RECONFIG_REQUEST_TIMEOUT_MS))27 28/*29 * struct s10_svc_buf30 * buf: virtual address of buf provided by service layer31 * lock: locked if buffer is in use32 */33struct s10_svc_buf {34 char *buf;35 unsigned long lock;36};37 38struct s10_priv {39 struct stratix10_svc_chan *chan;40 struct stratix10_svc_client client;41 struct completion status_return_completion;42 struct s10_svc_buf svc_bufs[NUM_SVC_BUFS];43 unsigned long status;44};45 46static int s10_svc_send_msg(struct s10_priv *priv,47 enum stratix10_svc_command_code command,48 void *payload, u32 payload_length)49{50 struct stratix10_svc_chan *chan = priv->chan;51 struct device *dev = priv->client.dev;52 struct stratix10_svc_client_msg msg;53 int ret;54 55 dev_dbg(dev, "%s cmd=%d payload=%p length=%d\n",56 __func__, command, payload, payload_length);57 58 msg.command = command;59 msg.payload = payload;60 msg.payload_length = payload_length;61 62 ret = stratix10_svc_send(chan, &msg);63 dev_dbg(dev, "stratix10_svc_send returned status %d\n", ret);64 65 return ret;66}67 68/*69 * Free buffers allocated from the service layer's pool that are not in use.70 * Return true when all buffers are freed.71 */72static bool s10_free_buffers(struct fpga_manager *mgr)73{74 struct s10_priv *priv = mgr->priv;75 uint num_free = 0;76 uint i;77 78 for (i = 0; i < NUM_SVC_BUFS; i++) {79 if (!priv->svc_bufs[i].buf) {80 num_free++;81 continue;82 }83 84 if (!test_and_set_bit_lock(SVC_BUF_LOCK,85 &priv->svc_bufs[i].lock)) {86 stratix10_svc_free_memory(priv->chan,87 priv->svc_bufs[i].buf);88 priv->svc_bufs[i].buf = NULL;89 num_free++;90 }91 }92 93 return num_free == NUM_SVC_BUFS;94}95 96/*97 * Returns count of how many buffers are not in use.98 */99static uint s10_free_buffer_count(struct fpga_manager *mgr)100{101 struct s10_priv *priv = mgr->priv;102 uint num_free = 0;103 uint i;104 105 for (i = 0; i < NUM_SVC_BUFS; i++)106 if (!priv->svc_bufs[i].buf)107 num_free++;108 109 return num_free;110}111 112/*113 * s10_unlock_bufs114 * Given the returned buffer address, match that address to our buffer struct115 * and unlock that buffer. This marks it as available to be refilled and sent116 * (or freed).117 * priv: private data118 * kaddr: kernel address of buffer that was returned from service layer119 */120static void s10_unlock_bufs(struct s10_priv *priv, void *kaddr)121{122 uint i;123 124 if (!kaddr)125 return;126 127 for (i = 0; i < NUM_SVC_BUFS; i++)128 if (priv->svc_bufs[i].buf == kaddr) {129 clear_bit_unlock(SVC_BUF_LOCK,130 &priv->svc_bufs[i].lock);131 return;132 }133 134 WARN(1, "Unknown buffer returned from service layer %p\n", kaddr);135}136 137/*138 * s10_receive_callback - callback for service layer to use to provide client139 * (this driver) messages received through the mailbox.140 * client: service layer client struct141 * data: message from service layer142 */143static void s10_receive_callback(struct stratix10_svc_client *client,144 struct stratix10_svc_cb_data *data)145{146 struct s10_priv *priv = client->priv;147 u32 status;148 int i;149 150 WARN_ONCE(!data, "%s: stratix10_svc_rc_data = NULL", __func__);151 152 status = data->status;153 154 /*155 * Here we set status bits as we receive them. Elsewhere, we always use156 * test_and_clear_bit() to check status in priv->status157 */158 for (i = 0; i <= SVC_STATUS_ERROR; i++)159 if (status & (1 << i))160 set_bit(i, &priv->status);161 162 if (status & BIT(SVC_STATUS_BUFFER_DONE)) {163 s10_unlock_bufs(priv, data->kaddr1);164 s10_unlock_bufs(priv, data->kaddr2);165 s10_unlock_bufs(priv, data->kaddr3);166 }167 168 complete(&priv->status_return_completion);169}170 171/*172 * s10_ops_write_init - prepare for FPGA reconfiguration by requesting173 * partial reconfig and allocating buffers from the service layer.174 */175static int s10_ops_write_init(struct fpga_manager *mgr,176 struct fpga_image_info *info,177 const char *buf, size_t count)178{179 struct s10_priv *priv = mgr->priv;180 struct device *dev = priv->client.dev;181 struct stratix10_svc_command_config_type ctype;182 char *kbuf;183 uint i;184 int ret;185 186 ctype.flags = 0;187 if (info->flags & FPGA_MGR_PARTIAL_RECONFIG) {188 dev_dbg(dev, "Requesting partial reconfiguration.\n");189 ctype.flags |= BIT(COMMAND_RECONFIG_FLAG_PARTIAL);190 } else {191 dev_dbg(dev, "Requesting full reconfiguration.\n");192 }193 194 reinit_completion(&priv->status_return_completion);195 ret = s10_svc_send_msg(priv, COMMAND_RECONFIG,196 &ctype, sizeof(ctype));197 if (ret < 0)198 goto init_done;199 200 ret = wait_for_completion_timeout(201 &priv->status_return_completion, S10_RECONFIG_TIMEOUT);202 if (!ret) {203 dev_err(dev, "timeout waiting for RECONFIG_REQUEST\n");204 ret = -ETIMEDOUT;205 goto init_done;206 }207 208 ret = 0;209 if (!test_and_clear_bit(SVC_STATUS_OK, &priv->status)) {210 ret = -ETIMEDOUT;211 goto init_done;212 }213 214 /* Allocate buffers from the service layer's pool. */215 for (i = 0; i < NUM_SVC_BUFS; i++) {216 kbuf = stratix10_svc_allocate_memory(priv->chan, SVC_BUF_SIZE);217 if (IS_ERR(kbuf)) {218 s10_free_buffers(mgr);219 ret = PTR_ERR(kbuf);220 goto init_done;221 }222 223 priv->svc_bufs[i].buf = kbuf;224 priv->svc_bufs[i].lock = 0;225 }226 227init_done:228 stratix10_svc_done(priv->chan);229 return ret;230}231 232/*233 * s10_send_buf - send a buffer to the service layer queue234 * mgr: fpga manager struct235 * buf: fpga image buffer236 * count: size of buf in bytes237 * Returns # of bytes transferred or -ENOBUFS if the all the buffers are in use238 * or if the service queue is full. Never returns 0.239 */240static int s10_send_buf(struct fpga_manager *mgr, const char *buf, size_t count)241{242 struct s10_priv *priv = mgr->priv;243 struct device *dev = priv->client.dev;244 void *svc_buf;245 size_t xfer_sz;246 int ret;247 uint i;248 249 /* get/lock a buffer that that's not being used */250 for (i = 0; i < NUM_SVC_BUFS; i++)251 if (!test_and_set_bit_lock(SVC_BUF_LOCK,252 &priv->svc_bufs[i].lock))253 break;254 255 if (i == NUM_SVC_BUFS)256 return -ENOBUFS;257 258 xfer_sz = count < SVC_BUF_SIZE ? count : SVC_BUF_SIZE;259 260 svc_buf = priv->svc_bufs[i].buf;261 memcpy(svc_buf, buf, xfer_sz);262 ret = s10_svc_send_msg(priv, COMMAND_RECONFIG_DATA_SUBMIT,263 svc_buf, xfer_sz);264 if (ret < 0) {265 dev_err(dev,266 "Error while sending data to service layer (%d)", ret);267 clear_bit_unlock(SVC_BUF_LOCK, &priv->svc_bufs[i].lock);268 return ret;269 }270 271 return xfer_sz;272}273 274/*275 * Send an FPGA image to privileged layers to write to the FPGA. When done276 * sending, free all service layer buffers we allocated in write_init.277 */278static int s10_ops_write(struct fpga_manager *mgr, const char *buf,279 size_t count)280{281 struct s10_priv *priv = mgr->priv;282 struct device *dev = priv->client.dev;283 long wait_status;284 int sent = 0;285 int ret = 0;286 287 /*288 * Loop waiting for buffers to be returned. When a buffer is returned,289 * reuse it to send more data or free if if all data has been sent.290 */291 while (count > 0 || s10_free_buffer_count(mgr) != NUM_SVC_BUFS) {292 reinit_completion(&priv->status_return_completion);293 294 if (count > 0) {295 sent = s10_send_buf(mgr, buf, count);296 if (sent < 0)297 continue;298 299 count -= sent;300 buf += sent;301 } else {302 if (s10_free_buffers(mgr))303 return 0;304 305 ret = s10_svc_send_msg(306 priv, COMMAND_RECONFIG_DATA_CLAIM,307 NULL, 0);308 if (ret < 0)309 break;310 }311 312 /*313 * If callback hasn't already happened, wait for buffers to be314 * returned from service layer315 */316 wait_status = 1; /* not timed out */317 if (!priv->status)318 wait_status = wait_for_completion_timeout(319 &priv->status_return_completion,320 S10_BUFFER_TIMEOUT);321 322 if (test_and_clear_bit(SVC_STATUS_BUFFER_DONE, &priv->status) ||323 test_and_clear_bit(SVC_STATUS_BUFFER_SUBMITTED,324 &priv->status)) {325 ret = 0;326 continue;327 }328 329 if (test_and_clear_bit(SVC_STATUS_ERROR, &priv->status)) {330 dev_err(dev, "ERROR - giving up - SVC_STATUS_ERROR\n");331 ret = -EFAULT;332 break;333 }334 335 if (!wait_status) {336 dev_err(dev, "timeout waiting for svc layer buffers\n");337 ret = -ETIMEDOUT;338 break;339 }340 }341 342 if (!s10_free_buffers(mgr))343 dev_err(dev, "%s not all buffers were freed\n", __func__);344 345 return ret;346}347 348static int s10_ops_write_complete(struct fpga_manager *mgr,349 struct fpga_image_info *info)350{351 struct s10_priv *priv = mgr->priv;352 struct device *dev = priv->client.dev;353 unsigned long timeout;354 int ret;355 356 timeout = usecs_to_jiffies(info->config_complete_timeout_us);357 358 do {359 reinit_completion(&priv->status_return_completion);360 361 ret = s10_svc_send_msg(priv, COMMAND_RECONFIG_STATUS, NULL, 0);362 if (ret < 0)363 break;364 365 ret = wait_for_completion_timeout(366 &priv->status_return_completion, timeout);367 if (!ret) {368 dev_err(dev,369 "timeout waiting for RECONFIG_COMPLETED\n");370 ret = -ETIMEDOUT;371 break;372 }373 /* Not error or timeout, so ret is # of jiffies until timeout */374 timeout = ret;375 ret = 0;376 377 if (test_and_clear_bit(SVC_STATUS_COMPLETED, &priv->status))378 break;379 380 if (test_and_clear_bit(SVC_STATUS_ERROR, &priv->status)) {381 dev_err(dev, "ERROR - giving up - SVC_STATUS_ERROR\n");382 ret = -EFAULT;383 break;384 }385 } while (1);386 387 stratix10_svc_done(priv->chan);388 389 return ret;390}391 392static const struct fpga_manager_ops s10_ops = {393 .write_init = s10_ops_write_init,394 .write = s10_ops_write,395 .write_complete = s10_ops_write_complete,396};397 398static int s10_probe(struct platform_device *pdev)399{400 struct device *dev = &pdev->dev;401 struct s10_priv *priv;402 struct fpga_manager *mgr;403 int ret;404 405 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);406 if (!priv)407 return -ENOMEM;408 409 priv->client.dev = dev;410 priv->client.receive_cb = s10_receive_callback;411 priv->client.priv = priv;412 413 priv->chan = stratix10_svc_request_channel_byname(&priv->client,414 SVC_CLIENT_FPGA);415 if (IS_ERR(priv->chan)) {416 dev_err(dev, "couldn't get service channel (%s)\n",417 SVC_CLIENT_FPGA);418 return PTR_ERR(priv->chan);419 }420 421 init_completion(&priv->status_return_completion);422 423 mgr = fpga_mgr_register(dev, "Stratix10 SOC FPGA Manager",424 &s10_ops, priv);425 if (IS_ERR(mgr)) {426 dev_err(dev, "unable to register FPGA manager\n");427 ret = PTR_ERR(mgr);428 goto probe_err;429 }430 431 platform_set_drvdata(pdev, mgr);432 return 0;433 434probe_err:435 stratix10_svc_free_channel(priv->chan);436 return ret;437}438 439static void s10_remove(struct platform_device *pdev)440{441 struct fpga_manager *mgr = platform_get_drvdata(pdev);442 struct s10_priv *priv = mgr->priv;443 444 fpga_mgr_unregister(mgr);445 stratix10_svc_free_channel(priv->chan);446}447 448static const struct of_device_id s10_of_match[] = {449 {.compatible = "intel,stratix10-soc-fpga-mgr"},450 {.compatible = "intel,agilex-soc-fpga-mgr"},451 {},452};453 454MODULE_DEVICE_TABLE(of, s10_of_match);455 456static struct platform_driver s10_driver = {457 .probe = s10_probe,458 .remove_new = s10_remove,459 .driver = {460 .name = "Stratix10 SoC FPGA manager",461 .of_match_table = of_match_ptr(s10_of_match),462 },463};464 465static int __init s10_init(void)466{467 struct device_node *fw_np;468 struct device_node *np;469 int ret;470 471 fw_np = of_find_node_by_name(NULL, "svc");472 if (!fw_np)473 return -ENODEV;474 475 of_node_get(fw_np);476 np = of_find_matching_node(fw_np, s10_of_match);477 if (!np) {478 of_node_put(fw_np);479 return -ENODEV;480 }481 482 of_node_put(np);483 ret = of_platform_populate(fw_np, s10_of_match, NULL, NULL);484 of_node_put(fw_np);485 if (ret)486 return ret;487 488 return platform_driver_register(&s10_driver);489}490 491static void __exit s10_exit(void)492{493 return platform_driver_unregister(&s10_driver);494}495 496module_init(s10_init);497module_exit(s10_exit);498 499MODULE_AUTHOR("Alan Tull <atull@kernel.org>");500MODULE_DESCRIPTION("Intel Stratix 10 SOC FPGA Manager");501MODULE_LICENSE("GPL v2");502