root/drivers/fpga/stratix10-soc.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. s10_svc_send_msg
  2. s10_free_buffers
  3. s10_free_buffer_count
  4. s10_unlock_bufs
  5. s10_receive_callback
  6. s10_ops_write_init
  7. s10_send_buf
  8. s10_ops_write
  9. s10_ops_write_complete
  10. s10_ops_state
  11. s10_probe
  12. s10_remove
  13. s10_init
  14. s10_exit

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

/* [<][>][^][v][top][bottom][index][help] */