root/drivers/fpga/dfl-fme-mgr.c

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

DEFINITIONS

This source file includes following definitions.
  1. pr_error_to_mgr_status
  2. fme_mgr_pr_error_handle
  3. fme_mgr_write_init
  4. fme_mgr_write
  5. fme_mgr_write_complete
  6. fme_mgr_state
  7. fme_mgr_status
  8. fme_mgr_get_compat_id
  9. fme_mgr_probe
  10. fme_mgr_remove

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * FPGA Manager Driver for FPGA Management Engine (FME)
   4  *
   5  * Copyright (C) 2017-2018 Intel Corporation, Inc.
   6  *
   7  * Authors:
   8  *   Kang Luwei <luwei.kang@intel.com>
   9  *   Xiao Guangrong <guangrong.xiao@linux.intel.com>
  10  *   Wu Hao <hao.wu@intel.com>
  11  *   Joseph Grecco <joe.grecco@intel.com>
  12  *   Enno Luebbers <enno.luebbers@intel.com>
  13  *   Tim Whisonant <tim.whisonant@intel.com>
  14  *   Ananda Ravuri <ananda.ravuri@intel.com>
  15  *   Christopher Rauer <christopher.rauer@intel.com>
  16  *   Henry Mitchel <henry.mitchel@intel.com>
  17  */
  18 
  19 #include <linux/bitfield.h>
  20 #include <linux/module.h>
  21 #include <linux/iopoll.h>
  22 #include <linux/io-64-nonatomic-lo-hi.h>
  23 #include <linux/fpga/fpga-mgr.h>
  24 
  25 #include "dfl-fme-pr.h"
  26 
  27 /* FME Partial Reconfiguration Sub Feature Register Set */
  28 #define FME_PR_DFH              0x0
  29 #define FME_PR_CTRL             0x8
  30 #define FME_PR_STS              0x10
  31 #define FME_PR_DATA             0x18
  32 #define FME_PR_ERR              0x20
  33 #define FME_PR_INTFC_ID_L       0xA8
  34 #define FME_PR_INTFC_ID_H       0xB0
  35 
  36 /* FME PR Control Register Bitfield */
  37 #define FME_PR_CTRL_PR_RST      BIT_ULL(0)  /* Reset PR engine */
  38 #define FME_PR_CTRL_PR_RSTACK   BIT_ULL(4)  /* Ack for PR engine reset */
  39 #define FME_PR_CTRL_PR_RGN_ID   GENMASK_ULL(9, 7)       /* PR Region ID */
  40 #define FME_PR_CTRL_PR_START    BIT_ULL(12) /* Start to request PR service */
  41 #define FME_PR_CTRL_PR_COMPLETE BIT_ULL(13) /* PR data push completion */
  42 
  43 /* FME PR Status Register Bitfield */
  44 /* Number of available entries in HW queue inside the PR engine. */
  45 #define FME_PR_STS_PR_CREDIT    GENMASK_ULL(8, 0)
  46 #define FME_PR_STS_PR_STS       BIT_ULL(16) /* PR operation status */
  47 #define FME_PR_STS_PR_STS_IDLE  0
  48 #define FME_PR_STS_PR_CTRLR_STS GENMASK_ULL(22, 20)     /* Controller status */
  49 #define FME_PR_STS_PR_HOST_STS  GENMASK_ULL(27, 24)     /* PR host status */
  50 
  51 /* FME PR Data Register Bitfield */
  52 /* PR data from the raw-binary file. */
  53 #define FME_PR_DATA_PR_DATA_RAW GENMASK_ULL(32, 0)
  54 
  55 /* FME PR Error Register */
  56 /* PR Operation errors detected. */
  57 #define FME_PR_ERR_OPERATION_ERR        BIT_ULL(0)
  58 /* CRC error detected. */
  59 #define FME_PR_ERR_CRC_ERR              BIT_ULL(1)
  60 /* Incompatible PR bitstream detected. */
  61 #define FME_PR_ERR_INCOMPATIBLE_BS      BIT_ULL(2)
  62 /* PR data push protocol violated. */
  63 #define FME_PR_ERR_PROTOCOL_ERR         BIT_ULL(3)
  64 /* PR data fifo overflow error detected */
  65 #define FME_PR_ERR_FIFO_OVERFLOW        BIT_ULL(4)
  66 
  67 #define PR_WAIT_TIMEOUT   8000000
  68 #define PR_HOST_STATUS_IDLE     0
  69 
  70 struct fme_mgr_priv {
  71         void __iomem *ioaddr;
  72         u64 pr_error;
  73 };
  74 
  75 static u64 pr_error_to_mgr_status(u64 err)
  76 {
  77         u64 status = 0;
  78 
  79         if (err & FME_PR_ERR_OPERATION_ERR)
  80                 status |= FPGA_MGR_STATUS_OPERATION_ERR;
  81         if (err & FME_PR_ERR_CRC_ERR)
  82                 status |= FPGA_MGR_STATUS_CRC_ERR;
  83         if (err & FME_PR_ERR_INCOMPATIBLE_BS)
  84                 status |= FPGA_MGR_STATUS_INCOMPATIBLE_IMAGE_ERR;
  85         if (err & FME_PR_ERR_PROTOCOL_ERR)
  86                 status |= FPGA_MGR_STATUS_IP_PROTOCOL_ERR;
  87         if (err & FME_PR_ERR_FIFO_OVERFLOW)
  88                 status |= FPGA_MGR_STATUS_FIFO_OVERFLOW_ERR;
  89 
  90         return status;
  91 }
  92 
  93 static u64 fme_mgr_pr_error_handle(void __iomem *fme_pr)
  94 {
  95         u64 pr_status, pr_error;
  96 
  97         pr_status = readq(fme_pr + FME_PR_STS);
  98         if (!(pr_status & FME_PR_STS_PR_STS))
  99                 return 0;
 100 
 101         pr_error = readq(fme_pr + FME_PR_ERR);
 102         writeq(pr_error, fme_pr + FME_PR_ERR);
 103 
 104         return pr_error;
 105 }
 106 
 107 static int fme_mgr_write_init(struct fpga_manager *mgr,
 108                               struct fpga_image_info *info,
 109                               const char *buf, size_t count)
 110 {
 111         struct device *dev = &mgr->dev;
 112         struct fme_mgr_priv *priv = mgr->priv;
 113         void __iomem *fme_pr = priv->ioaddr;
 114         u64 pr_ctrl, pr_status;
 115 
 116         if (!(info->flags & FPGA_MGR_PARTIAL_RECONFIG)) {
 117                 dev_err(dev, "only supports partial reconfiguration.\n");
 118                 return -EINVAL;
 119         }
 120 
 121         dev_dbg(dev, "resetting PR before initiated PR\n");
 122 
 123         pr_ctrl = readq(fme_pr + FME_PR_CTRL);
 124         pr_ctrl |= FME_PR_CTRL_PR_RST;
 125         writeq(pr_ctrl, fme_pr + FME_PR_CTRL);
 126 
 127         if (readq_poll_timeout(fme_pr + FME_PR_CTRL, pr_ctrl,
 128                                pr_ctrl & FME_PR_CTRL_PR_RSTACK, 1,
 129                                PR_WAIT_TIMEOUT)) {
 130                 dev_err(dev, "PR Reset ACK timeout\n");
 131                 return -ETIMEDOUT;
 132         }
 133 
 134         pr_ctrl = readq(fme_pr + FME_PR_CTRL);
 135         pr_ctrl &= ~FME_PR_CTRL_PR_RST;
 136         writeq(pr_ctrl, fme_pr + FME_PR_CTRL);
 137 
 138         dev_dbg(dev,
 139                 "waiting for PR resource in HW to be initialized and ready\n");
 140 
 141         if (readq_poll_timeout(fme_pr + FME_PR_STS, pr_status,
 142                                (pr_status & FME_PR_STS_PR_STS) ==
 143                                FME_PR_STS_PR_STS_IDLE, 1, PR_WAIT_TIMEOUT)) {
 144                 dev_err(dev, "PR Status timeout\n");
 145                 priv->pr_error = fme_mgr_pr_error_handle(fme_pr);
 146                 return -ETIMEDOUT;
 147         }
 148 
 149         dev_dbg(dev, "check and clear previous PR error\n");
 150         priv->pr_error = fme_mgr_pr_error_handle(fme_pr);
 151         if (priv->pr_error)
 152                 dev_dbg(dev, "previous PR error detected %llx\n",
 153                         (unsigned long long)priv->pr_error);
 154 
 155         dev_dbg(dev, "set PR port ID\n");
 156 
 157         pr_ctrl = readq(fme_pr + FME_PR_CTRL);
 158         pr_ctrl &= ~FME_PR_CTRL_PR_RGN_ID;
 159         pr_ctrl |= FIELD_PREP(FME_PR_CTRL_PR_RGN_ID, info->region_id);
 160         writeq(pr_ctrl, fme_pr + FME_PR_CTRL);
 161 
 162         return 0;
 163 }
 164 
 165 static int fme_mgr_write(struct fpga_manager *mgr,
 166                          const char *buf, size_t count)
 167 {
 168         struct device *dev = &mgr->dev;
 169         struct fme_mgr_priv *priv = mgr->priv;
 170         void __iomem *fme_pr = priv->ioaddr;
 171         u64 pr_ctrl, pr_status, pr_data;
 172         int delay = 0, pr_credit, i = 0;
 173 
 174         dev_dbg(dev, "start request\n");
 175 
 176         pr_ctrl = readq(fme_pr + FME_PR_CTRL);
 177         pr_ctrl |= FME_PR_CTRL_PR_START;
 178         writeq(pr_ctrl, fme_pr + FME_PR_CTRL);
 179 
 180         dev_dbg(dev, "pushing data from bitstream to HW\n");
 181 
 182         /*
 183          * driver can push data to PR hardware using PR_DATA register once HW
 184          * has enough pr_credit (> 1), pr_credit reduces one for every 32bit
 185          * pr data write to PR_DATA register. If pr_credit <= 1, driver needs
 186          * to wait for enough pr_credit from hardware by polling.
 187          */
 188         pr_status = readq(fme_pr + FME_PR_STS);
 189         pr_credit = FIELD_GET(FME_PR_STS_PR_CREDIT, pr_status);
 190 
 191         while (count > 0) {
 192                 while (pr_credit <= 1) {
 193                         if (delay++ > PR_WAIT_TIMEOUT) {
 194                                 dev_err(dev, "PR_CREDIT timeout\n");
 195                                 return -ETIMEDOUT;
 196                         }
 197                         udelay(1);
 198 
 199                         pr_status = readq(fme_pr + FME_PR_STS);
 200                         pr_credit = FIELD_GET(FME_PR_STS_PR_CREDIT, pr_status);
 201                 }
 202 
 203                 if (count < 4) {
 204                         dev_err(dev, "Invalid PR bitstream size\n");
 205                         return -EINVAL;
 206                 }
 207 
 208                 pr_data = 0;
 209                 pr_data |= FIELD_PREP(FME_PR_DATA_PR_DATA_RAW,
 210                                       *(((u32 *)buf) + i));
 211                 writeq(pr_data, fme_pr + FME_PR_DATA);
 212                 count -= 4;
 213                 pr_credit--;
 214                 i++;
 215         }
 216 
 217         return 0;
 218 }
 219 
 220 static int fme_mgr_write_complete(struct fpga_manager *mgr,
 221                                   struct fpga_image_info *info)
 222 {
 223         struct device *dev = &mgr->dev;
 224         struct fme_mgr_priv *priv = mgr->priv;
 225         void __iomem *fme_pr = priv->ioaddr;
 226         u64 pr_ctrl;
 227 
 228         pr_ctrl = readq(fme_pr + FME_PR_CTRL);
 229         pr_ctrl |= FME_PR_CTRL_PR_COMPLETE;
 230         writeq(pr_ctrl, fme_pr + FME_PR_CTRL);
 231 
 232         dev_dbg(dev, "green bitstream push complete\n");
 233         dev_dbg(dev, "waiting for HW to release PR resource\n");
 234 
 235         if (readq_poll_timeout(fme_pr + FME_PR_CTRL, pr_ctrl,
 236                                !(pr_ctrl & FME_PR_CTRL_PR_START), 1,
 237                                PR_WAIT_TIMEOUT)) {
 238                 dev_err(dev, "PR Completion ACK timeout.\n");
 239                 return -ETIMEDOUT;
 240         }
 241 
 242         dev_dbg(dev, "PR operation complete, checking status\n");
 243         priv->pr_error = fme_mgr_pr_error_handle(fme_pr);
 244         if (priv->pr_error) {
 245                 dev_dbg(dev, "PR error detected %llx\n",
 246                         (unsigned long long)priv->pr_error);
 247                 return -EIO;
 248         }
 249 
 250         dev_dbg(dev, "PR done successfully\n");
 251 
 252         return 0;
 253 }
 254 
 255 static enum fpga_mgr_states fme_mgr_state(struct fpga_manager *mgr)
 256 {
 257         return FPGA_MGR_STATE_UNKNOWN;
 258 }
 259 
 260 static u64 fme_mgr_status(struct fpga_manager *mgr)
 261 {
 262         struct fme_mgr_priv *priv = mgr->priv;
 263 
 264         return pr_error_to_mgr_status(priv->pr_error);
 265 }
 266 
 267 static const struct fpga_manager_ops fme_mgr_ops = {
 268         .write_init = fme_mgr_write_init,
 269         .write = fme_mgr_write,
 270         .write_complete = fme_mgr_write_complete,
 271         .state = fme_mgr_state,
 272         .status = fme_mgr_status,
 273 };
 274 
 275 static void fme_mgr_get_compat_id(void __iomem *fme_pr,
 276                                   struct fpga_compat_id *id)
 277 {
 278         id->id_l = readq(fme_pr + FME_PR_INTFC_ID_L);
 279         id->id_h = readq(fme_pr + FME_PR_INTFC_ID_H);
 280 }
 281 
 282 static int fme_mgr_probe(struct platform_device *pdev)
 283 {
 284         struct dfl_fme_mgr_pdata *pdata = dev_get_platdata(&pdev->dev);
 285         struct fpga_compat_id *compat_id;
 286         struct device *dev = &pdev->dev;
 287         struct fme_mgr_priv *priv;
 288         struct fpga_manager *mgr;
 289         struct resource *res;
 290 
 291         priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 292         if (!priv)
 293                 return -ENOMEM;
 294 
 295         if (pdata->ioaddr)
 296                 priv->ioaddr = pdata->ioaddr;
 297 
 298         if (!priv->ioaddr) {
 299                 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 300                 priv->ioaddr = devm_ioremap_resource(dev, res);
 301                 if (IS_ERR(priv->ioaddr))
 302                         return PTR_ERR(priv->ioaddr);
 303         }
 304 
 305         compat_id = devm_kzalloc(dev, sizeof(*compat_id), GFP_KERNEL);
 306         if (!compat_id)
 307                 return -ENOMEM;
 308 
 309         fme_mgr_get_compat_id(priv->ioaddr, compat_id);
 310 
 311         mgr = devm_fpga_mgr_create(dev, "DFL FME FPGA Manager",
 312                                    &fme_mgr_ops, priv);
 313         if (!mgr)
 314                 return -ENOMEM;
 315 
 316         mgr->compat_id = compat_id;
 317         platform_set_drvdata(pdev, mgr);
 318 
 319         return fpga_mgr_register(mgr);
 320 }
 321 
 322 static int fme_mgr_remove(struct platform_device *pdev)
 323 {
 324         struct fpga_manager *mgr = platform_get_drvdata(pdev);
 325 
 326         fpga_mgr_unregister(mgr);
 327 
 328         return 0;
 329 }
 330 
 331 static struct platform_driver fme_mgr_driver = {
 332         .driver = {
 333                 .name    = DFL_FPGA_FME_MGR,
 334         },
 335         .probe   = fme_mgr_probe,
 336         .remove  = fme_mgr_remove,
 337 };
 338 
 339 module_platform_driver(fme_mgr_driver);
 340 
 341 MODULE_DESCRIPTION("FPGA Manager for DFL FPGA Management Engine");
 342 MODULE_AUTHOR("Intel Corporation");
 343 MODULE_LICENSE("GPL v2");
 344 MODULE_ALIAS("platform:dfl-fme-mgr");

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