Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * FPGA Manager Driver for Altera Arria/Cyclone/Stratix CvP
0004  *
0005  * Copyright (C) 2017 DENX Software Engineering
0006  *
0007  * Anatolij Gustschin <agust@denx.de>
0008  *
0009  * Manage Altera FPGA firmware using PCIe CvP.
0010  * Firmware must be in binary "rbf" format.
0011  */
0012 
0013 #include <linux/delay.h>
0014 #include <linux/device.h>
0015 #include <linux/fpga/fpga-mgr.h>
0016 #include <linux/module.h>
0017 #include <linux/pci.h>
0018 #include <linux/sizes.h>
0019 
0020 #define CVP_BAR     0   /* BAR used for data transfer in memory mode */
0021 #define CVP_DUMMY_WR    244 /* dummy writes to clear CvP state machine */
0022 #define TIMEOUT_US  2000    /* CVP STATUS timeout for USERMODE polling */
0023 
0024 /* Vendor Specific Extended Capability Registers */
0025 #define VSE_PCIE_EXT_CAP_ID     0x0
0026 #define VSE_PCIE_EXT_CAP_ID_VAL     0x000b  /* 16bit */
0027 
0028 #define VSE_CVP_STATUS          0x1c    /* 32bit */
0029 #define VSE_CVP_STATUS_CFG_RDY      BIT(18) /* CVP_CONFIG_READY */
0030 #define VSE_CVP_STATUS_CFG_ERR      BIT(19) /* CVP_CONFIG_ERROR */
0031 #define VSE_CVP_STATUS_CVP_EN       BIT(20) /* ctrl block is enabling CVP */
0032 #define VSE_CVP_STATUS_USERMODE     BIT(21) /* USERMODE */
0033 #define VSE_CVP_STATUS_CFG_DONE     BIT(23) /* CVP_CONFIG_DONE */
0034 #define VSE_CVP_STATUS_PLD_CLK_IN_USE   BIT(24) /* PLD_CLK_IN_USE */
0035 
0036 #define VSE_CVP_MODE_CTRL       0x20    /* 32bit */
0037 #define VSE_CVP_MODE_CTRL_CVP_MODE  BIT(0)  /* CVP (1) or normal mode (0) */
0038 #define VSE_CVP_MODE_CTRL_HIP_CLK_SEL   BIT(1) /* PMA (1) or fabric clock (0) */
0039 #define VSE_CVP_MODE_CTRL_NUMCLKS_OFF   8   /* NUMCLKS bits offset */
0040 #define VSE_CVP_MODE_CTRL_NUMCLKS_MASK  GENMASK(15, 8)
0041 
0042 #define VSE_CVP_DATA            0x28    /* 32bit */
0043 #define VSE_CVP_PROG_CTRL       0x2c    /* 32bit */
0044 #define VSE_CVP_PROG_CTRL_CONFIG    BIT(0)
0045 #define VSE_CVP_PROG_CTRL_START_XFER    BIT(1)
0046 #define VSE_CVP_PROG_CTRL_MASK      GENMASK(1, 0)
0047 
0048 #define VSE_UNCOR_ERR_STATUS        0x34    /* 32bit */
0049 #define VSE_UNCOR_ERR_CVP_CFG_ERR   BIT(5)  /* CVP_CONFIG_ERROR_LATCHED */
0050 
0051 #define V1_VSEC_OFFSET          0x200   /* Vendor Specific Offset V1 */
0052 /* V2 Defines */
0053 #define VSE_CVP_TX_CREDITS      0x49    /* 8bit */
0054 
0055 #define V2_CREDIT_TIMEOUT_US        20000
0056 #define V2_CHECK_CREDIT_US      10
0057 #define V2_POLL_TIMEOUT_US      1000000
0058 #define V2_USER_TIMEOUT_US      500000
0059 
0060 #define V1_POLL_TIMEOUT_US      10
0061 
0062 #define DRV_NAME        "altera-cvp"
0063 #define ALTERA_CVP_MGR_NAME "Altera CvP FPGA Manager"
0064 
0065 /* Write block sizes */
0066 #define ALTERA_CVP_V1_SIZE  4
0067 #define ALTERA_CVP_V2_SIZE  4096
0068 
0069 /* Optional CvP config error status check for debugging */
0070 static bool altera_cvp_chkcfg;
0071 
0072 struct cvp_priv;
0073 
0074 struct altera_cvp_conf {
0075     struct fpga_manager *mgr;
0076     struct pci_dev      *pci_dev;
0077     void __iomem        *map;
0078     void            (*write_data)(struct altera_cvp_conf *conf,
0079                           u32 data);
0080     char            mgr_name[64];
0081     u8          numclks;
0082     u32         sent_packets;
0083     u32         vsec_offset;
0084     const struct cvp_priv   *priv;
0085 };
0086 
0087 struct cvp_priv {
0088     void    (*switch_clk)(struct altera_cvp_conf *conf);
0089     int (*clear_state)(struct altera_cvp_conf *conf);
0090     int (*wait_credit)(struct fpga_manager *mgr, u32 blocks);
0091     size_t  block_size;
0092     int poll_time_us;
0093     int user_time_us;
0094 };
0095 
0096 static int altera_read_config_byte(struct altera_cvp_conf *conf,
0097                    int where, u8 *val)
0098 {
0099     return pci_read_config_byte(conf->pci_dev, conf->vsec_offset + where,
0100                     val);
0101 }
0102 
0103 static int altera_read_config_dword(struct altera_cvp_conf *conf,
0104                     int where, u32 *val)
0105 {
0106     return pci_read_config_dword(conf->pci_dev, conf->vsec_offset + where,
0107                      val);
0108 }
0109 
0110 static int altera_write_config_dword(struct altera_cvp_conf *conf,
0111                      int where, u32 val)
0112 {
0113     return pci_write_config_dword(conf->pci_dev, conf->vsec_offset + where,
0114                       val);
0115 }
0116 
0117 static enum fpga_mgr_states altera_cvp_state(struct fpga_manager *mgr)
0118 {
0119     struct altera_cvp_conf *conf = mgr->priv;
0120     u32 status;
0121 
0122     altera_read_config_dword(conf, VSE_CVP_STATUS, &status);
0123 
0124     if (status & VSE_CVP_STATUS_CFG_DONE)
0125         return FPGA_MGR_STATE_OPERATING;
0126 
0127     if (status & VSE_CVP_STATUS_CVP_EN)
0128         return FPGA_MGR_STATE_POWER_UP;
0129 
0130     return FPGA_MGR_STATE_UNKNOWN;
0131 }
0132 
0133 static void altera_cvp_write_data_iomem(struct altera_cvp_conf *conf, u32 val)
0134 {
0135     writel(val, conf->map);
0136 }
0137 
0138 static void altera_cvp_write_data_config(struct altera_cvp_conf *conf, u32 val)
0139 {
0140     pci_write_config_dword(conf->pci_dev, conf->vsec_offset + VSE_CVP_DATA,
0141                    val);
0142 }
0143 
0144 /* switches between CvP clock and internal clock */
0145 static void altera_cvp_dummy_write(struct altera_cvp_conf *conf)
0146 {
0147     unsigned int i;
0148     u32 val;
0149 
0150     /* set 1 CVP clock cycle for every CVP Data Register Write */
0151     altera_read_config_dword(conf, VSE_CVP_MODE_CTRL, &val);
0152     val &= ~VSE_CVP_MODE_CTRL_NUMCLKS_MASK;
0153     val |= 1 << VSE_CVP_MODE_CTRL_NUMCLKS_OFF;
0154     altera_write_config_dword(conf, VSE_CVP_MODE_CTRL, val);
0155 
0156     for (i = 0; i < CVP_DUMMY_WR; i++)
0157         conf->write_data(conf, 0); /* dummy data, could be any value */
0158 }
0159 
0160 static int altera_cvp_wait_status(struct altera_cvp_conf *conf, u32 status_mask,
0161                   u32 status_val, int timeout_us)
0162 {
0163     unsigned int retries;
0164     u32 val;
0165 
0166     retries = timeout_us / 10;
0167     if (timeout_us % 10)
0168         retries++;
0169 
0170     do {
0171         altera_read_config_dword(conf, VSE_CVP_STATUS, &val);
0172         if ((val & status_mask) == status_val)
0173             return 0;
0174 
0175         /* use small usleep value to re-check and break early */
0176         usleep_range(10, 11);
0177     } while (--retries);
0178 
0179     return -ETIMEDOUT;
0180 }
0181 
0182 static int altera_cvp_chk_error(struct fpga_manager *mgr, size_t bytes)
0183 {
0184     struct altera_cvp_conf *conf = mgr->priv;
0185     u32 val;
0186     int ret;
0187 
0188     /* STEP 10 (optional) - check CVP_CONFIG_ERROR flag */
0189     ret = altera_read_config_dword(conf, VSE_CVP_STATUS, &val);
0190     if (ret || (val & VSE_CVP_STATUS_CFG_ERR)) {
0191         dev_err(&mgr->dev, "CVP_CONFIG_ERROR after %zu bytes!\n",
0192             bytes);
0193         return -EPROTO;
0194     }
0195     return 0;
0196 }
0197 
0198 /*
0199  * CvP Version2 Functions
0200  * Recent Intel FPGAs use a credit mechanism to throttle incoming
0201  * bitstreams and a different method of clearing the state.
0202  */
0203 
0204 static int altera_cvp_v2_clear_state(struct altera_cvp_conf *conf)
0205 {
0206     u32 val;
0207     int ret;
0208 
0209     /* Clear the START_XFER and CVP_CONFIG bits */
0210     ret = altera_read_config_dword(conf, VSE_CVP_PROG_CTRL, &val);
0211     if (ret) {
0212         dev_err(&conf->pci_dev->dev,
0213             "Error reading CVP Program Control Register\n");
0214         return ret;
0215     }
0216 
0217     val &= ~VSE_CVP_PROG_CTRL_MASK;
0218     ret = altera_write_config_dword(conf, VSE_CVP_PROG_CTRL, val);
0219     if (ret) {
0220         dev_err(&conf->pci_dev->dev,
0221             "Error writing CVP Program Control Register\n");
0222         return ret;
0223     }
0224 
0225     return altera_cvp_wait_status(conf, VSE_CVP_STATUS_CFG_RDY, 0,
0226                       conf->priv->poll_time_us);
0227 }
0228 
0229 static int altera_cvp_v2_wait_for_credit(struct fpga_manager *mgr,
0230                      u32 blocks)
0231 {
0232     u32 timeout = V2_CREDIT_TIMEOUT_US / V2_CHECK_CREDIT_US;
0233     struct altera_cvp_conf *conf = mgr->priv;
0234     int ret;
0235     u8 val;
0236 
0237     do {
0238         ret = altera_read_config_byte(conf, VSE_CVP_TX_CREDITS, &val);
0239         if (ret) {
0240             dev_err(&conf->pci_dev->dev,
0241                 "Error reading CVP Credit Register\n");
0242             return ret;
0243         }
0244 
0245         /* Return if there is space in FIFO */
0246         if (val - (u8)conf->sent_packets)
0247             return 0;
0248 
0249         ret = altera_cvp_chk_error(mgr, blocks * ALTERA_CVP_V2_SIZE);
0250         if (ret) {
0251             dev_err(&conf->pci_dev->dev,
0252                 "CE Bit error credit reg[0x%x]:sent[0x%x]\n",
0253                 val, conf->sent_packets);
0254             return -EAGAIN;
0255         }
0256 
0257         /* Limit the check credit byte traffic */
0258         usleep_range(V2_CHECK_CREDIT_US, V2_CHECK_CREDIT_US + 1);
0259     } while (timeout--);
0260 
0261     dev_err(&conf->pci_dev->dev, "Timeout waiting for credit\n");
0262     return -ETIMEDOUT;
0263 }
0264 
0265 static int altera_cvp_send_block(struct altera_cvp_conf *conf,
0266                  const u32 *data, size_t len)
0267 {
0268     u32 mask, words = len / sizeof(u32);
0269     int i, remainder;
0270 
0271     for (i = 0; i < words; i++)
0272         conf->write_data(conf, *data++);
0273 
0274     /* write up to 3 trailing bytes, if any */
0275     remainder = len % sizeof(u32);
0276     if (remainder) {
0277         mask = BIT(remainder * 8) - 1;
0278         if (mask)
0279             conf->write_data(conf, *data & mask);
0280     }
0281 
0282     return 0;
0283 }
0284 
0285 static int altera_cvp_teardown(struct fpga_manager *mgr,
0286                    struct fpga_image_info *info)
0287 {
0288     struct altera_cvp_conf *conf = mgr->priv;
0289     int ret;
0290     u32 val;
0291 
0292     /* STEP 12 - reset START_XFER bit */
0293     altera_read_config_dword(conf, VSE_CVP_PROG_CTRL, &val);
0294     val &= ~VSE_CVP_PROG_CTRL_START_XFER;
0295     altera_write_config_dword(conf, VSE_CVP_PROG_CTRL, val);
0296 
0297     /* STEP 13 - reset CVP_CONFIG bit */
0298     val &= ~VSE_CVP_PROG_CTRL_CONFIG;
0299     altera_write_config_dword(conf, VSE_CVP_PROG_CTRL, val);
0300 
0301     /*
0302      * STEP 14
0303      * - set CVP_NUMCLKS to 1 and then issue CVP_DUMMY_WR dummy
0304      *   writes to the HIP
0305      */
0306     if (conf->priv->switch_clk)
0307         conf->priv->switch_clk(conf);
0308 
0309     /* STEP 15 - poll CVP_CONFIG_READY bit for 0 with 10us timeout */
0310     ret = altera_cvp_wait_status(conf, VSE_CVP_STATUS_CFG_RDY, 0,
0311                      conf->priv->poll_time_us);
0312     if (ret)
0313         dev_err(&mgr->dev, "CFG_RDY == 0 timeout\n");
0314 
0315     return ret;
0316 }
0317 
0318 static int altera_cvp_write_init(struct fpga_manager *mgr,
0319                  struct fpga_image_info *info,
0320                  const char *buf, size_t count)
0321 {
0322     struct altera_cvp_conf *conf = mgr->priv;
0323     u32 iflags, val;
0324     int ret;
0325 
0326     iflags = info ? info->flags : 0;
0327 
0328     if (iflags & FPGA_MGR_PARTIAL_RECONFIG) {
0329         dev_err(&mgr->dev, "Partial reconfiguration not supported.\n");
0330         return -EINVAL;
0331     }
0332 
0333     /* Determine allowed clock to data ratio */
0334     if (iflags & FPGA_MGR_COMPRESSED_BITSTREAM)
0335         conf->numclks = 8; /* ratio for all compressed images */
0336     else if (iflags & FPGA_MGR_ENCRYPTED_BITSTREAM)
0337         conf->numclks = 4; /* for uncompressed and encrypted images */
0338     else
0339         conf->numclks = 1; /* for uncompressed and unencrypted images */
0340 
0341     /* STEP 1 - read CVP status and check CVP_EN flag */
0342     altera_read_config_dword(conf, VSE_CVP_STATUS, &val);
0343     if (!(val & VSE_CVP_STATUS_CVP_EN)) {
0344         dev_err(&mgr->dev, "CVP mode off: 0x%04x\n", val);
0345         return -ENODEV;
0346     }
0347 
0348     if (val & VSE_CVP_STATUS_CFG_RDY) {
0349         dev_warn(&mgr->dev, "CvP already started, tear down first\n");
0350         ret = altera_cvp_teardown(mgr, info);
0351         if (ret)
0352             return ret;
0353     }
0354 
0355     /*
0356      * STEP 2
0357      * - set HIP_CLK_SEL and CVP_MODE (must be set in the order mentioned)
0358      */
0359     /* switch from fabric to PMA clock */
0360     altera_read_config_dword(conf, VSE_CVP_MODE_CTRL, &val);
0361     val |= VSE_CVP_MODE_CTRL_HIP_CLK_SEL;
0362     altera_write_config_dword(conf, VSE_CVP_MODE_CTRL, val);
0363 
0364     /* set CVP mode */
0365     altera_read_config_dword(conf, VSE_CVP_MODE_CTRL, &val);
0366     val |= VSE_CVP_MODE_CTRL_CVP_MODE;
0367     altera_write_config_dword(conf, VSE_CVP_MODE_CTRL, val);
0368 
0369     /*
0370      * STEP 3
0371      * - set CVP_NUMCLKS to 1 and issue CVP_DUMMY_WR dummy writes to the HIP
0372      */
0373     if (conf->priv->switch_clk)
0374         conf->priv->switch_clk(conf);
0375 
0376     if (conf->priv->clear_state) {
0377         ret = conf->priv->clear_state(conf);
0378         if (ret) {
0379             dev_err(&mgr->dev, "Problem clearing out state\n");
0380             return ret;
0381         }
0382     }
0383 
0384     conf->sent_packets = 0;
0385 
0386     /* STEP 4 - set CVP_CONFIG bit */
0387     altera_read_config_dword(conf, VSE_CVP_PROG_CTRL, &val);
0388     /* request control block to begin transfer using CVP */
0389     val |= VSE_CVP_PROG_CTRL_CONFIG;
0390     altera_write_config_dword(conf, VSE_CVP_PROG_CTRL, val);
0391 
0392     /* STEP 5 - poll CVP_CONFIG READY for 1 with timeout */
0393     ret = altera_cvp_wait_status(conf, VSE_CVP_STATUS_CFG_RDY,
0394                      VSE_CVP_STATUS_CFG_RDY,
0395                      conf->priv->poll_time_us);
0396     if (ret) {
0397         dev_warn(&mgr->dev, "CFG_RDY == 1 timeout\n");
0398         return ret;
0399     }
0400 
0401     /*
0402      * STEP 6
0403      * - set CVP_NUMCLKS to 1 and issue CVP_DUMMY_WR dummy writes to the HIP
0404      */
0405     if (conf->priv->switch_clk)
0406         conf->priv->switch_clk(conf);
0407 
0408     if (altera_cvp_chkcfg) {
0409         ret = altera_cvp_chk_error(mgr, 0);
0410         if (ret) {
0411             dev_warn(&mgr->dev, "CFG_RDY == 1 timeout\n");
0412             return ret;
0413         }
0414     }
0415 
0416     /* STEP 7 - set START_XFER */
0417     altera_read_config_dword(conf, VSE_CVP_PROG_CTRL, &val);
0418     val |= VSE_CVP_PROG_CTRL_START_XFER;
0419     altera_write_config_dword(conf, VSE_CVP_PROG_CTRL, val);
0420 
0421     /* STEP 8 - start transfer (set CVP_NUMCLKS for bitstream) */
0422     if (conf->priv->switch_clk) {
0423         altera_read_config_dword(conf, VSE_CVP_MODE_CTRL, &val);
0424         val &= ~VSE_CVP_MODE_CTRL_NUMCLKS_MASK;
0425         val |= conf->numclks << VSE_CVP_MODE_CTRL_NUMCLKS_OFF;
0426         altera_write_config_dword(conf, VSE_CVP_MODE_CTRL, val);
0427     }
0428     return 0;
0429 }
0430 
0431 static int altera_cvp_write(struct fpga_manager *mgr, const char *buf,
0432                 size_t count)
0433 {
0434     struct altera_cvp_conf *conf = mgr->priv;
0435     size_t done, remaining, len;
0436     const u32 *data;
0437     int status = 0;
0438 
0439     /* STEP 9 - write 32-bit data from RBF file to CVP data register */
0440     data = (u32 *)buf;
0441     remaining = count;
0442     done = 0;
0443 
0444     while (remaining) {
0445         /* Use credit throttling if available */
0446         if (conf->priv->wait_credit) {
0447             status = conf->priv->wait_credit(mgr, done);
0448             if (status) {
0449                 dev_err(&conf->pci_dev->dev,
0450                     "Wait Credit ERR: 0x%x\n", status);
0451                 return status;
0452             }
0453         }
0454 
0455         len = min(conf->priv->block_size, remaining);
0456         altera_cvp_send_block(conf, data, len);
0457         data += len / sizeof(u32);
0458         done += len;
0459         remaining -= len;
0460         conf->sent_packets++;
0461 
0462         /*
0463          * STEP 10 (optional) and STEP 11
0464          * - check error flag
0465          * - loop until data transfer completed
0466          * Config images can be huge (more than 40 MiB), so
0467          * only check after a new 4k data block has been written.
0468          * This reduces the number of checks and speeds up the
0469          * configuration process.
0470          */
0471         if (altera_cvp_chkcfg && !(done % SZ_4K)) {
0472             status = altera_cvp_chk_error(mgr, done);
0473             if (status < 0)
0474                 return status;
0475         }
0476     }
0477 
0478     if (altera_cvp_chkcfg)
0479         status = altera_cvp_chk_error(mgr, count);
0480 
0481     return status;
0482 }
0483 
0484 static int altera_cvp_write_complete(struct fpga_manager *mgr,
0485                      struct fpga_image_info *info)
0486 {
0487     struct altera_cvp_conf *conf = mgr->priv;
0488     u32 mask, val;
0489     int ret;
0490 
0491     ret = altera_cvp_teardown(mgr, info);
0492     if (ret)
0493         return ret;
0494 
0495     /* STEP 16 - check CVP_CONFIG_ERROR_LATCHED bit */
0496     altera_read_config_dword(conf, VSE_UNCOR_ERR_STATUS, &val);
0497     if (val & VSE_UNCOR_ERR_CVP_CFG_ERR) {
0498         dev_err(&mgr->dev, "detected CVP_CONFIG_ERROR_LATCHED!\n");
0499         return -EPROTO;
0500     }
0501 
0502     /* STEP 17 - reset CVP_MODE and HIP_CLK_SEL bit */
0503     altera_read_config_dword(conf, VSE_CVP_MODE_CTRL, &val);
0504     val &= ~VSE_CVP_MODE_CTRL_HIP_CLK_SEL;
0505     val &= ~VSE_CVP_MODE_CTRL_CVP_MODE;
0506     altera_write_config_dword(conf, VSE_CVP_MODE_CTRL, val);
0507 
0508     /* STEP 18 - poll PLD_CLK_IN_USE and USER_MODE bits */
0509     mask = VSE_CVP_STATUS_PLD_CLK_IN_USE | VSE_CVP_STATUS_USERMODE;
0510     ret = altera_cvp_wait_status(conf, mask, mask,
0511                      conf->priv->user_time_us);
0512     if (ret)
0513         dev_err(&mgr->dev, "PLD_CLK_IN_USE|USERMODE timeout\n");
0514 
0515     return ret;
0516 }
0517 
0518 static const struct fpga_manager_ops altera_cvp_ops = {
0519     .state      = altera_cvp_state,
0520     .write_init = altera_cvp_write_init,
0521     .write      = altera_cvp_write,
0522     .write_complete = altera_cvp_write_complete,
0523 };
0524 
0525 static const struct cvp_priv cvp_priv_v1 = {
0526     .switch_clk = altera_cvp_dummy_write,
0527     .block_size = ALTERA_CVP_V1_SIZE,
0528     .poll_time_us   = V1_POLL_TIMEOUT_US,
0529     .user_time_us   = TIMEOUT_US,
0530 };
0531 
0532 static const struct cvp_priv cvp_priv_v2 = {
0533     .clear_state    = altera_cvp_v2_clear_state,
0534     .wait_credit    = altera_cvp_v2_wait_for_credit,
0535     .block_size = ALTERA_CVP_V2_SIZE,
0536     .poll_time_us   = V2_POLL_TIMEOUT_US,
0537     .user_time_us   = V2_USER_TIMEOUT_US,
0538 };
0539 
0540 static ssize_t chkcfg_show(struct device_driver *dev, char *buf)
0541 {
0542     return snprintf(buf, 3, "%d\n", altera_cvp_chkcfg);
0543 }
0544 
0545 static ssize_t chkcfg_store(struct device_driver *drv, const char *buf,
0546                 size_t count)
0547 {
0548     int ret;
0549 
0550     ret = kstrtobool(buf, &altera_cvp_chkcfg);
0551     if (ret)
0552         return ret;
0553 
0554     return count;
0555 }
0556 
0557 static DRIVER_ATTR_RW(chkcfg);
0558 
0559 static int altera_cvp_probe(struct pci_dev *pdev,
0560                 const struct pci_device_id *dev_id);
0561 static void altera_cvp_remove(struct pci_dev *pdev);
0562 
0563 static struct pci_device_id altera_cvp_id_tbl[] = {
0564     { PCI_VDEVICE(ALTERA, PCI_ANY_ID) },
0565     { }
0566 };
0567 MODULE_DEVICE_TABLE(pci, altera_cvp_id_tbl);
0568 
0569 static struct pci_driver altera_cvp_driver = {
0570     .name   = DRV_NAME,
0571     .id_table = altera_cvp_id_tbl,
0572     .probe  = altera_cvp_probe,
0573     .remove = altera_cvp_remove,
0574 };
0575 
0576 static int altera_cvp_probe(struct pci_dev *pdev,
0577                 const struct pci_device_id *dev_id)
0578 {
0579     struct altera_cvp_conf *conf;
0580     struct fpga_manager *mgr;
0581     int ret, offset;
0582     u16 cmd, val;
0583     u32 regval;
0584 
0585     /* Discover the Vendor Specific Offset for this device */
0586     offset = pci_find_next_ext_capability(pdev, 0, PCI_EXT_CAP_ID_VNDR);
0587     if (!offset) {
0588         dev_err(&pdev->dev, "No Vendor Specific Offset.\n");
0589         return -ENODEV;
0590     }
0591 
0592     /*
0593      * First check if this is the expected FPGA device. PCI config
0594      * space access works without enabling the PCI device, memory
0595      * space access is enabled further down.
0596      */
0597     pci_read_config_word(pdev, offset + VSE_PCIE_EXT_CAP_ID, &val);
0598     if (val != VSE_PCIE_EXT_CAP_ID_VAL) {
0599         dev_err(&pdev->dev, "Wrong EXT_CAP_ID value 0x%x\n", val);
0600         return -ENODEV;
0601     }
0602 
0603     pci_read_config_dword(pdev, offset + VSE_CVP_STATUS, &regval);
0604     if (!(regval & VSE_CVP_STATUS_CVP_EN)) {
0605         dev_err(&pdev->dev,
0606             "CVP is disabled for this device: CVP_STATUS Reg 0x%x\n",
0607             regval);
0608         return -ENODEV;
0609     }
0610 
0611     conf = devm_kzalloc(&pdev->dev, sizeof(*conf), GFP_KERNEL);
0612     if (!conf)
0613         return -ENOMEM;
0614 
0615     conf->vsec_offset = offset;
0616 
0617     /*
0618      * Enable memory BAR access. We cannot use pci_enable_device() here
0619      * because it will make the driver unusable with FPGA devices that
0620      * have additional big IOMEM resources (e.g. 4GiB BARs) on 32-bit
0621      * platform. Such BARs will not have an assigned address range and
0622      * pci_enable_device() will fail, complaining about not claimed BAR,
0623      * even if the concerned BAR is not needed for FPGA configuration
0624      * at all. Thus, enable the device via PCI config space command.
0625      */
0626     pci_read_config_word(pdev, PCI_COMMAND, &cmd);
0627     if (!(cmd & PCI_COMMAND_MEMORY)) {
0628         cmd |= PCI_COMMAND_MEMORY;
0629         pci_write_config_word(pdev, PCI_COMMAND, cmd);
0630     }
0631 
0632     ret = pci_request_region(pdev, CVP_BAR, "CVP");
0633     if (ret) {
0634         dev_err(&pdev->dev, "Requesting CVP BAR region failed\n");
0635         goto err_disable;
0636     }
0637 
0638     conf->pci_dev = pdev;
0639     conf->write_data = altera_cvp_write_data_iomem;
0640 
0641     if (conf->vsec_offset == V1_VSEC_OFFSET)
0642         conf->priv = &cvp_priv_v1;
0643     else
0644         conf->priv = &cvp_priv_v2;
0645 
0646     conf->map = pci_iomap(pdev, CVP_BAR, 0);
0647     if (!conf->map) {
0648         dev_warn(&pdev->dev, "Mapping CVP BAR failed\n");
0649         conf->write_data = altera_cvp_write_data_config;
0650     }
0651 
0652     snprintf(conf->mgr_name, sizeof(conf->mgr_name), "%s @%s",
0653          ALTERA_CVP_MGR_NAME, pci_name(pdev));
0654 
0655     mgr = fpga_mgr_register(&pdev->dev, conf->mgr_name,
0656                 &altera_cvp_ops, conf);
0657     if (IS_ERR(mgr)) {
0658         ret = PTR_ERR(mgr);
0659         goto err_unmap;
0660     }
0661 
0662     pci_set_drvdata(pdev, mgr);
0663 
0664     return 0;
0665 
0666 err_unmap:
0667     if (conf->map)
0668         pci_iounmap(pdev, conf->map);
0669     pci_release_region(pdev, CVP_BAR);
0670 err_disable:
0671     cmd &= ~PCI_COMMAND_MEMORY;
0672     pci_write_config_word(pdev, PCI_COMMAND, cmd);
0673     return ret;
0674 }
0675 
0676 static void altera_cvp_remove(struct pci_dev *pdev)
0677 {
0678     struct fpga_manager *mgr = pci_get_drvdata(pdev);
0679     struct altera_cvp_conf *conf = mgr->priv;
0680     u16 cmd;
0681 
0682     fpga_mgr_unregister(mgr);
0683     if (conf->map)
0684         pci_iounmap(pdev, conf->map);
0685     pci_release_region(pdev, CVP_BAR);
0686     pci_read_config_word(pdev, PCI_COMMAND, &cmd);
0687     cmd &= ~PCI_COMMAND_MEMORY;
0688     pci_write_config_word(pdev, PCI_COMMAND, cmd);
0689 }
0690 
0691 static int __init altera_cvp_init(void)
0692 {
0693     int ret;
0694 
0695     ret = pci_register_driver(&altera_cvp_driver);
0696     if (ret)
0697         return ret;
0698 
0699     ret = driver_create_file(&altera_cvp_driver.driver,
0700                  &driver_attr_chkcfg);
0701     if (ret)
0702         pr_warn("Can't create sysfs chkcfg file\n");
0703 
0704     return 0;
0705 }
0706 
0707 static void __exit altera_cvp_exit(void)
0708 {
0709     driver_remove_file(&altera_cvp_driver.driver, &driver_attr_chkcfg);
0710     pci_unregister_driver(&altera_cvp_driver);
0711 }
0712 
0713 module_init(altera_cvp_init);
0714 module_exit(altera_cvp_exit);
0715 
0716 MODULE_LICENSE("GPL v2");
0717 MODULE_AUTHOR("Anatolij Gustschin <agust@denx.de>");
0718 MODULE_DESCRIPTION("Module to load Altera FPGA over CvP");