Linux 6.10-rc4
[linux-2.6-block.git] / drivers / fpga / altera-cvp.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * FPGA Manager Driver for Altera Arria/Cyclone/Stratix CvP
4  *
5  * Copyright (C) 2017 DENX Software Engineering
6  *
7  * Anatolij Gustschin <agust@denx.de>
8  *
9  * Manage Altera FPGA firmware using PCIe CvP.
10  * Firmware must be in binary "rbf" format.
11  */
12
13 #include <linux/delay.h>
14 #include <linux/device.h>
15 #include <linux/fpga/fpga-mgr.h>
16 #include <linux/module.h>
17 #include <linux/pci.h>
18 #include <linux/sizes.h>
19
20 #define CVP_BAR         0       /* BAR used for data transfer in memory mode */
21 #define CVP_DUMMY_WR    244     /* dummy writes to clear CvP state machine */
22 #define TIMEOUT_US      2000    /* CVP STATUS timeout for USERMODE polling */
23
24 /* Vendor Specific Extended Capability Registers */
25 #define VSE_PCIE_EXT_CAP_ID             0x0
26 #define VSE_PCIE_EXT_CAP_ID_VAL         0x000b  /* 16bit */
27
28 #define VSE_CVP_STATUS                  0x1c    /* 32bit */
29 #define VSE_CVP_STATUS_CFG_RDY          BIT(18) /* CVP_CONFIG_READY */
30 #define VSE_CVP_STATUS_CFG_ERR          BIT(19) /* CVP_CONFIG_ERROR */
31 #define VSE_CVP_STATUS_CVP_EN           BIT(20) /* ctrl block is enabling CVP */
32 #define VSE_CVP_STATUS_USERMODE         BIT(21) /* USERMODE */
33 #define VSE_CVP_STATUS_CFG_DONE         BIT(23) /* CVP_CONFIG_DONE */
34 #define VSE_CVP_STATUS_PLD_CLK_IN_USE   BIT(24) /* PLD_CLK_IN_USE */
35
36 #define VSE_CVP_MODE_CTRL               0x20    /* 32bit */
37 #define VSE_CVP_MODE_CTRL_CVP_MODE      BIT(0)  /* CVP (1) or normal mode (0) */
38 #define VSE_CVP_MODE_CTRL_HIP_CLK_SEL   BIT(1) /* PMA (1) or fabric clock (0) */
39 #define VSE_CVP_MODE_CTRL_NUMCLKS_OFF   8       /* NUMCLKS bits offset */
40 #define VSE_CVP_MODE_CTRL_NUMCLKS_MASK  GENMASK(15, 8)
41
42 #define VSE_CVP_DATA                    0x28    /* 32bit */
43 #define VSE_CVP_PROG_CTRL               0x2c    /* 32bit */
44 #define VSE_CVP_PROG_CTRL_CONFIG        BIT(0)
45 #define VSE_CVP_PROG_CTRL_START_XFER    BIT(1)
46 #define VSE_CVP_PROG_CTRL_MASK          GENMASK(1, 0)
47
48 #define VSE_UNCOR_ERR_STATUS            0x34    /* 32bit */
49 #define VSE_UNCOR_ERR_CVP_CFG_ERR       BIT(5)  /* CVP_CONFIG_ERROR_LATCHED */
50
51 #define V1_VSEC_OFFSET                  0x200   /* Vendor Specific Offset V1 */
52 /* V2 Defines */
53 #define VSE_CVP_TX_CREDITS              0x49    /* 8bit */
54
55 #define V2_CREDIT_TIMEOUT_US            20000
56 #define V2_CHECK_CREDIT_US              10
57 #define V2_POLL_TIMEOUT_US              1000000
58 #define V2_USER_TIMEOUT_US              500000
59
60 #define V1_POLL_TIMEOUT_US              10
61
62 #define DRV_NAME                "altera-cvp"
63 #define ALTERA_CVP_MGR_NAME     "Altera CvP FPGA Manager"
64
65 /* Write block sizes */
66 #define ALTERA_CVP_V1_SIZE      4
67 #define ALTERA_CVP_V2_SIZE      4096
68
69 /* Optional CvP config error status check for debugging */
70 static bool altera_cvp_chkcfg;
71
72 struct cvp_priv;
73
74 struct altera_cvp_conf {
75         struct pci_dev          *pci_dev;
76         void __iomem            *map;
77         void                    (*write_data)(struct altera_cvp_conf *conf,
78                                               u32 data);
79         char                    mgr_name[64];
80         u8                      numclks;
81         u32                     sent_packets;
82         u32                     vsec_offset;
83         const struct cvp_priv   *priv;
84 };
85
86 struct cvp_priv {
87         void    (*switch_clk)(struct altera_cvp_conf *conf);
88         int     (*clear_state)(struct altera_cvp_conf *conf);
89         int     (*wait_credit)(struct fpga_manager *mgr, u32 blocks);
90         size_t  block_size;
91         int     poll_time_us;
92         int     user_time_us;
93 };
94
95 static int altera_read_config_byte(struct altera_cvp_conf *conf,
96                                    int where, u8 *val)
97 {
98         return pci_read_config_byte(conf->pci_dev, conf->vsec_offset + where,
99                                     val);
100 }
101
102 static int altera_read_config_dword(struct altera_cvp_conf *conf,
103                                     int where, u32 *val)
104 {
105         return pci_read_config_dword(conf->pci_dev, conf->vsec_offset + where,
106                                      val);
107 }
108
109 static int altera_write_config_dword(struct altera_cvp_conf *conf,
110                                      int where, u32 val)
111 {
112         return pci_write_config_dword(conf->pci_dev, conf->vsec_offset + where,
113                                       val);
114 }
115
116 static enum fpga_mgr_states altera_cvp_state(struct fpga_manager *mgr)
117 {
118         struct altera_cvp_conf *conf = mgr->priv;
119         u32 status;
120
121         altera_read_config_dword(conf, VSE_CVP_STATUS, &status);
122
123         if (status & VSE_CVP_STATUS_CFG_DONE)
124                 return FPGA_MGR_STATE_OPERATING;
125
126         if (status & VSE_CVP_STATUS_CVP_EN)
127                 return FPGA_MGR_STATE_POWER_UP;
128
129         return FPGA_MGR_STATE_UNKNOWN;
130 }
131
132 static void altera_cvp_write_data_iomem(struct altera_cvp_conf *conf, u32 val)
133 {
134         writel(val, conf->map);
135 }
136
137 static void altera_cvp_write_data_config(struct altera_cvp_conf *conf, u32 val)
138 {
139         pci_write_config_dword(conf->pci_dev, conf->vsec_offset + VSE_CVP_DATA,
140                                val);
141 }
142
143 /* switches between CvP clock and internal clock */
144 static void altera_cvp_dummy_write(struct altera_cvp_conf *conf)
145 {
146         unsigned int i;
147         u32 val;
148
149         /* set 1 CVP clock cycle for every CVP Data Register Write */
150         altera_read_config_dword(conf, VSE_CVP_MODE_CTRL, &val);
151         val &= ~VSE_CVP_MODE_CTRL_NUMCLKS_MASK;
152         val |= 1 << VSE_CVP_MODE_CTRL_NUMCLKS_OFF;
153         altera_write_config_dword(conf, VSE_CVP_MODE_CTRL, val);
154
155         for (i = 0; i < CVP_DUMMY_WR; i++)
156                 conf->write_data(conf, 0); /* dummy data, could be any value */
157 }
158
159 static int altera_cvp_wait_status(struct altera_cvp_conf *conf, u32 status_mask,
160                                   u32 status_val, int timeout_us)
161 {
162         unsigned int retries;
163         u32 val;
164
165         retries = timeout_us / 10;
166         if (timeout_us % 10)
167                 retries++;
168
169         do {
170                 altera_read_config_dword(conf, VSE_CVP_STATUS, &val);
171                 if ((val & status_mask) == status_val)
172                         return 0;
173
174                 /* use small usleep value to re-check and break early */
175                 usleep_range(10, 11);
176         } while (--retries);
177
178         return -ETIMEDOUT;
179 }
180
181 static int altera_cvp_chk_error(struct fpga_manager *mgr, size_t bytes)
182 {
183         struct altera_cvp_conf *conf = mgr->priv;
184         u32 val;
185         int ret;
186
187         /* STEP 10 (optional) - check CVP_CONFIG_ERROR flag */
188         ret = altera_read_config_dword(conf, VSE_CVP_STATUS, &val);
189         if (ret || (val & VSE_CVP_STATUS_CFG_ERR)) {
190                 dev_err(&mgr->dev, "CVP_CONFIG_ERROR after %zu bytes!\n",
191                         bytes);
192                 return -EPROTO;
193         }
194         return 0;
195 }
196
197 /*
198  * CvP Version2 Functions
199  * Recent Intel FPGAs use a credit mechanism to throttle incoming
200  * bitstreams and a different method of clearing the state.
201  */
202
203 static int altera_cvp_v2_clear_state(struct altera_cvp_conf *conf)
204 {
205         u32 val;
206         int ret;
207
208         /* Clear the START_XFER and CVP_CONFIG bits */
209         ret = altera_read_config_dword(conf, VSE_CVP_PROG_CTRL, &val);
210         if (ret) {
211                 dev_err(&conf->pci_dev->dev,
212                         "Error reading CVP Program Control Register\n");
213                 return ret;
214         }
215
216         val &= ~VSE_CVP_PROG_CTRL_MASK;
217         ret = altera_write_config_dword(conf, VSE_CVP_PROG_CTRL, val);
218         if (ret) {
219                 dev_err(&conf->pci_dev->dev,
220                         "Error writing CVP Program Control Register\n");
221                 return ret;
222         }
223
224         return altera_cvp_wait_status(conf, VSE_CVP_STATUS_CFG_RDY, 0,
225                                       conf->priv->poll_time_us);
226 }
227
228 static int altera_cvp_v2_wait_for_credit(struct fpga_manager *mgr,
229                                          u32 blocks)
230 {
231         u32 timeout = V2_CREDIT_TIMEOUT_US / V2_CHECK_CREDIT_US;
232         struct altera_cvp_conf *conf = mgr->priv;
233         int ret;
234         u8 val;
235
236         do {
237                 ret = altera_read_config_byte(conf, VSE_CVP_TX_CREDITS, &val);
238                 if (ret) {
239                         dev_err(&conf->pci_dev->dev,
240                                 "Error reading CVP Credit Register\n");
241                         return ret;
242                 }
243
244                 /* Return if there is space in FIFO */
245                 if (val - (u8)conf->sent_packets)
246                         return 0;
247
248                 ret = altera_cvp_chk_error(mgr, blocks * ALTERA_CVP_V2_SIZE);
249                 if (ret) {
250                         dev_err(&conf->pci_dev->dev,
251                                 "CE Bit error credit reg[0x%x]:sent[0x%x]\n",
252                                 val, conf->sent_packets);
253                         return -EAGAIN;
254                 }
255
256                 /* Limit the check credit byte traffic */
257                 usleep_range(V2_CHECK_CREDIT_US, V2_CHECK_CREDIT_US + 1);
258         } while (timeout--);
259
260         dev_err(&conf->pci_dev->dev, "Timeout waiting for credit\n");
261         return -ETIMEDOUT;
262 }
263
264 static int altera_cvp_send_block(struct altera_cvp_conf *conf,
265                                  const u32 *data, size_t len)
266 {
267         u32 mask, words = len / sizeof(u32);
268         int i, remainder;
269
270         for (i = 0; i < words; i++)
271                 conf->write_data(conf, *data++);
272
273         /* write up to 3 trailing bytes, if any */
274         remainder = len % sizeof(u32);
275         if (remainder) {
276                 mask = BIT(remainder * 8) - 1;
277                 if (mask)
278                         conf->write_data(conf, *data & mask);
279         }
280
281         return 0;
282 }
283
284 static int altera_cvp_teardown(struct fpga_manager *mgr,
285                                struct fpga_image_info *info)
286 {
287         struct altera_cvp_conf *conf = mgr->priv;
288         int ret;
289         u32 val;
290
291         /* STEP 12 - reset START_XFER bit */
292         altera_read_config_dword(conf, VSE_CVP_PROG_CTRL, &val);
293         val &= ~VSE_CVP_PROG_CTRL_START_XFER;
294         altera_write_config_dword(conf, VSE_CVP_PROG_CTRL, val);
295
296         /* STEP 13 - reset CVP_CONFIG bit */
297         val &= ~VSE_CVP_PROG_CTRL_CONFIG;
298         altera_write_config_dword(conf, VSE_CVP_PROG_CTRL, val);
299
300         /*
301          * STEP 14
302          * - set CVP_NUMCLKS to 1 and then issue CVP_DUMMY_WR dummy
303          *   writes to the HIP
304          */
305         if (conf->priv->switch_clk)
306                 conf->priv->switch_clk(conf);
307
308         /* STEP 15 - poll CVP_CONFIG_READY bit for 0 with 10us timeout */
309         ret = altera_cvp_wait_status(conf, VSE_CVP_STATUS_CFG_RDY, 0,
310                                      conf->priv->poll_time_us);
311         if (ret)
312                 dev_err(&mgr->dev, "CFG_RDY == 0 timeout\n");
313
314         return ret;
315 }
316
317 static int altera_cvp_write_init(struct fpga_manager *mgr,
318                                  struct fpga_image_info *info,
319                                  const char *buf, size_t count)
320 {
321         struct altera_cvp_conf *conf = mgr->priv;
322         u32 iflags, val;
323         int ret;
324
325         iflags = info ? info->flags : 0;
326
327         if (iflags & FPGA_MGR_PARTIAL_RECONFIG) {
328                 dev_err(&mgr->dev, "Partial reconfiguration not supported.\n");
329                 return -EINVAL;
330         }
331
332         /* Determine allowed clock to data ratio */
333         if (iflags & FPGA_MGR_COMPRESSED_BITSTREAM)
334                 conf->numclks = 8; /* ratio for all compressed images */
335         else if (iflags & FPGA_MGR_ENCRYPTED_BITSTREAM)
336                 conf->numclks = 4; /* for uncompressed and encrypted images */
337         else
338                 conf->numclks = 1; /* for uncompressed and unencrypted images */
339
340         /* STEP 1 - read CVP status and check CVP_EN flag */
341         altera_read_config_dword(conf, VSE_CVP_STATUS, &val);
342         if (!(val & VSE_CVP_STATUS_CVP_EN)) {
343                 dev_err(&mgr->dev, "CVP mode off: 0x%04x\n", val);
344                 return -ENODEV;
345         }
346
347         if (val & VSE_CVP_STATUS_CFG_RDY) {
348                 dev_warn(&mgr->dev, "CvP already started, tear down first\n");
349                 ret = altera_cvp_teardown(mgr, info);
350                 if (ret)
351                         return ret;
352         }
353
354         /*
355          * STEP 2
356          * - set HIP_CLK_SEL and CVP_MODE (must be set in the order mentioned)
357          */
358         /* switch from fabric to PMA clock */
359         altera_read_config_dword(conf, VSE_CVP_MODE_CTRL, &val);
360         val |= VSE_CVP_MODE_CTRL_HIP_CLK_SEL;
361         altera_write_config_dword(conf, VSE_CVP_MODE_CTRL, val);
362
363         /* set CVP mode */
364         altera_read_config_dword(conf, VSE_CVP_MODE_CTRL, &val);
365         val |= VSE_CVP_MODE_CTRL_CVP_MODE;
366         altera_write_config_dword(conf, VSE_CVP_MODE_CTRL, val);
367
368         /*
369          * STEP 3
370          * - set CVP_NUMCLKS to 1 and issue CVP_DUMMY_WR dummy writes to the HIP
371          */
372         if (conf->priv->switch_clk)
373                 conf->priv->switch_clk(conf);
374
375         if (conf->priv->clear_state) {
376                 ret = conf->priv->clear_state(conf);
377                 if (ret) {
378                         dev_err(&mgr->dev, "Problem clearing out state\n");
379                         return ret;
380                 }
381         }
382
383         conf->sent_packets = 0;
384
385         /* STEP 4 - set CVP_CONFIG bit */
386         altera_read_config_dword(conf, VSE_CVP_PROG_CTRL, &val);
387         /* request control block to begin transfer using CVP */
388         val |= VSE_CVP_PROG_CTRL_CONFIG;
389         altera_write_config_dword(conf, VSE_CVP_PROG_CTRL, val);
390
391         /* STEP 5 - poll CVP_CONFIG READY for 1 with timeout */
392         ret = altera_cvp_wait_status(conf, VSE_CVP_STATUS_CFG_RDY,
393                                      VSE_CVP_STATUS_CFG_RDY,
394                                      conf->priv->poll_time_us);
395         if (ret) {
396                 dev_warn(&mgr->dev, "CFG_RDY == 1 timeout\n");
397                 return ret;
398         }
399
400         /*
401          * STEP 6
402          * - set CVP_NUMCLKS to 1 and issue CVP_DUMMY_WR dummy writes to the HIP
403          */
404         if (conf->priv->switch_clk)
405                 conf->priv->switch_clk(conf);
406
407         if (altera_cvp_chkcfg) {
408                 ret = altera_cvp_chk_error(mgr, 0);
409                 if (ret) {
410                         dev_warn(&mgr->dev, "CFG_RDY == 1 timeout\n");
411                         return ret;
412                 }
413         }
414
415         /* STEP 7 - set START_XFER */
416         altera_read_config_dword(conf, VSE_CVP_PROG_CTRL, &val);
417         val |= VSE_CVP_PROG_CTRL_START_XFER;
418         altera_write_config_dword(conf, VSE_CVP_PROG_CTRL, val);
419
420         /* STEP 8 - start transfer (set CVP_NUMCLKS for bitstream) */
421         if (conf->priv->switch_clk) {
422                 altera_read_config_dword(conf, VSE_CVP_MODE_CTRL, &val);
423                 val &= ~VSE_CVP_MODE_CTRL_NUMCLKS_MASK;
424                 val |= conf->numclks << VSE_CVP_MODE_CTRL_NUMCLKS_OFF;
425                 altera_write_config_dword(conf, VSE_CVP_MODE_CTRL, val);
426         }
427         return 0;
428 }
429
430 static int altera_cvp_write(struct fpga_manager *mgr, const char *buf,
431                             size_t count)
432 {
433         struct altera_cvp_conf *conf = mgr->priv;
434         size_t done, remaining, len;
435         const u32 *data;
436         int status = 0;
437
438         /* STEP 9 - write 32-bit data from RBF file to CVP data register */
439         data = (u32 *)buf;
440         remaining = count;
441         done = 0;
442
443         while (remaining) {
444                 /* Use credit throttling if available */
445                 if (conf->priv->wait_credit) {
446                         status = conf->priv->wait_credit(mgr, done);
447                         if (status) {
448                                 dev_err(&conf->pci_dev->dev,
449                                         "Wait Credit ERR: 0x%x\n", status);
450                                 return status;
451                         }
452                 }
453
454                 len = min(conf->priv->block_size, remaining);
455                 altera_cvp_send_block(conf, data, len);
456                 data += len / sizeof(u32);
457                 done += len;
458                 remaining -= len;
459                 conf->sent_packets++;
460
461                 /*
462                  * STEP 10 (optional) and STEP 11
463                  * - check error flag
464                  * - loop until data transfer completed
465                  * Config images can be huge (more than 40 MiB), so
466                  * only check after a new 4k data block has been written.
467                  * This reduces the number of checks and speeds up the
468                  * configuration process.
469                  */
470                 if (altera_cvp_chkcfg && !(done % SZ_4K)) {
471                         status = altera_cvp_chk_error(mgr, done);
472                         if (status < 0)
473                                 return status;
474                 }
475         }
476
477         if (altera_cvp_chkcfg)
478                 status = altera_cvp_chk_error(mgr, count);
479
480         return status;
481 }
482
483 static int altera_cvp_write_complete(struct fpga_manager *mgr,
484                                      struct fpga_image_info *info)
485 {
486         struct altera_cvp_conf *conf = mgr->priv;
487         u32 mask, val;
488         int ret;
489
490         ret = altera_cvp_teardown(mgr, info);
491         if (ret)
492                 return ret;
493
494         /* STEP 16 - check CVP_CONFIG_ERROR_LATCHED bit */
495         altera_read_config_dword(conf, VSE_UNCOR_ERR_STATUS, &val);
496         if (val & VSE_UNCOR_ERR_CVP_CFG_ERR) {
497                 dev_err(&mgr->dev, "detected CVP_CONFIG_ERROR_LATCHED!\n");
498                 return -EPROTO;
499         }
500
501         /* STEP 17 - reset CVP_MODE and HIP_CLK_SEL bit */
502         altera_read_config_dword(conf, VSE_CVP_MODE_CTRL, &val);
503         val &= ~VSE_CVP_MODE_CTRL_HIP_CLK_SEL;
504         val &= ~VSE_CVP_MODE_CTRL_CVP_MODE;
505         altera_write_config_dword(conf, VSE_CVP_MODE_CTRL, val);
506
507         /* STEP 18 - poll PLD_CLK_IN_USE and USER_MODE bits */
508         mask = VSE_CVP_STATUS_PLD_CLK_IN_USE | VSE_CVP_STATUS_USERMODE;
509         ret = altera_cvp_wait_status(conf, mask, mask,
510                                      conf->priv->user_time_us);
511         if (ret)
512                 dev_err(&mgr->dev, "PLD_CLK_IN_USE|USERMODE timeout\n");
513
514         return ret;
515 }
516
517 static const struct fpga_manager_ops altera_cvp_ops = {
518         .state          = altera_cvp_state,
519         .write_init     = altera_cvp_write_init,
520         .write          = altera_cvp_write,
521         .write_complete = altera_cvp_write_complete,
522 };
523
524 static const struct cvp_priv cvp_priv_v1 = {
525         .switch_clk     = altera_cvp_dummy_write,
526         .block_size     = ALTERA_CVP_V1_SIZE,
527         .poll_time_us   = V1_POLL_TIMEOUT_US,
528         .user_time_us   = TIMEOUT_US,
529 };
530
531 static const struct cvp_priv cvp_priv_v2 = {
532         .clear_state    = altera_cvp_v2_clear_state,
533         .wait_credit    = altera_cvp_v2_wait_for_credit,
534         .block_size     = ALTERA_CVP_V2_SIZE,
535         .poll_time_us   = V2_POLL_TIMEOUT_US,
536         .user_time_us   = V2_USER_TIMEOUT_US,
537 };
538
539 static ssize_t chkcfg_show(struct device_driver *dev, char *buf)
540 {
541         return snprintf(buf, 3, "%d\n", altera_cvp_chkcfg);
542 }
543
544 static ssize_t chkcfg_store(struct device_driver *drv, const char *buf,
545                             size_t count)
546 {
547         int ret;
548
549         ret = kstrtobool(buf, &altera_cvp_chkcfg);
550         if (ret)
551                 return ret;
552
553         return count;
554 }
555
556 static DRIVER_ATTR_RW(chkcfg);
557
558 static int altera_cvp_probe(struct pci_dev *pdev,
559                             const struct pci_device_id *dev_id);
560 static void altera_cvp_remove(struct pci_dev *pdev);
561
562 static struct pci_device_id altera_cvp_id_tbl[] = {
563         { PCI_VDEVICE(ALTERA, PCI_ANY_ID) },
564         { }
565 };
566 MODULE_DEVICE_TABLE(pci, altera_cvp_id_tbl);
567
568 static struct pci_driver altera_cvp_driver = {
569         .name   = DRV_NAME,
570         .id_table = altera_cvp_id_tbl,
571         .probe  = altera_cvp_probe,
572         .remove = altera_cvp_remove,
573 };
574
575 static int altera_cvp_probe(struct pci_dev *pdev,
576                             const struct pci_device_id *dev_id)
577 {
578         struct altera_cvp_conf *conf;
579         struct fpga_manager *mgr;
580         int ret, offset;
581         u16 cmd, val;
582         u32 regval;
583
584         /* Discover the Vendor Specific Offset for this device */
585         offset = pci_find_next_ext_capability(pdev, 0, PCI_EXT_CAP_ID_VNDR);
586         if (!offset) {
587                 dev_err(&pdev->dev, "No Vendor Specific Offset.\n");
588                 return -ENODEV;
589         }
590
591         /*
592          * First check if this is the expected FPGA device. PCI config
593          * space access works without enabling the PCI device, memory
594          * space access is enabled further down.
595          */
596         pci_read_config_word(pdev, offset + VSE_PCIE_EXT_CAP_ID, &val);
597         if (val != VSE_PCIE_EXT_CAP_ID_VAL) {
598                 dev_err(&pdev->dev, "Wrong EXT_CAP_ID value 0x%x\n", val);
599                 return -ENODEV;
600         }
601
602         pci_read_config_dword(pdev, offset + VSE_CVP_STATUS, &regval);
603         if (!(regval & VSE_CVP_STATUS_CVP_EN)) {
604                 dev_err(&pdev->dev,
605                         "CVP is disabled for this device: CVP_STATUS Reg 0x%x\n",
606                         regval);
607                 return -ENODEV;
608         }
609
610         conf = devm_kzalloc(&pdev->dev, sizeof(*conf), GFP_KERNEL);
611         if (!conf)
612                 return -ENOMEM;
613
614         conf->vsec_offset = offset;
615
616         /*
617          * Enable memory BAR access. We cannot use pci_enable_device() here
618          * because it will make the driver unusable with FPGA devices that
619          * have additional big IOMEM resources (e.g. 4GiB BARs) on 32-bit
620          * platform. Such BARs will not have an assigned address range and
621          * pci_enable_device() will fail, complaining about not claimed BAR,
622          * even if the concerned BAR is not needed for FPGA configuration
623          * at all. Thus, enable the device via PCI config space command.
624          */
625         pci_read_config_word(pdev, PCI_COMMAND, &cmd);
626         if (!(cmd & PCI_COMMAND_MEMORY)) {
627                 cmd |= PCI_COMMAND_MEMORY;
628                 pci_write_config_word(pdev, PCI_COMMAND, cmd);
629         }
630
631         ret = pci_request_region(pdev, CVP_BAR, "CVP");
632         if (ret) {
633                 dev_err(&pdev->dev, "Requesting CVP BAR region failed\n");
634                 goto err_disable;
635         }
636
637         conf->pci_dev = pdev;
638         conf->write_data = altera_cvp_write_data_iomem;
639
640         if (conf->vsec_offset == V1_VSEC_OFFSET)
641                 conf->priv = &cvp_priv_v1;
642         else
643                 conf->priv = &cvp_priv_v2;
644
645         conf->map = pci_iomap(pdev, CVP_BAR, 0);
646         if (!conf->map) {
647                 dev_warn(&pdev->dev, "Mapping CVP BAR failed\n");
648                 conf->write_data = altera_cvp_write_data_config;
649         }
650
651         snprintf(conf->mgr_name, sizeof(conf->mgr_name), "%s @%s",
652                  ALTERA_CVP_MGR_NAME, pci_name(pdev));
653
654         mgr = fpga_mgr_register(&pdev->dev, conf->mgr_name,
655                                 &altera_cvp_ops, conf);
656         if (IS_ERR(mgr)) {
657                 ret = PTR_ERR(mgr);
658                 goto err_unmap;
659         }
660
661         pci_set_drvdata(pdev, mgr);
662
663         return 0;
664
665 err_unmap:
666         if (conf->map)
667                 pci_iounmap(pdev, conf->map);
668         pci_release_region(pdev, CVP_BAR);
669 err_disable:
670         cmd &= ~PCI_COMMAND_MEMORY;
671         pci_write_config_word(pdev, PCI_COMMAND, cmd);
672         return ret;
673 }
674
675 static void altera_cvp_remove(struct pci_dev *pdev)
676 {
677         struct fpga_manager *mgr = pci_get_drvdata(pdev);
678         struct altera_cvp_conf *conf = mgr->priv;
679         u16 cmd;
680
681         fpga_mgr_unregister(mgr);
682         if (conf->map)
683                 pci_iounmap(pdev, conf->map);
684         pci_release_region(pdev, CVP_BAR);
685         pci_read_config_word(pdev, PCI_COMMAND, &cmd);
686         cmd &= ~PCI_COMMAND_MEMORY;
687         pci_write_config_word(pdev, PCI_COMMAND, cmd);
688 }
689
690 static int __init altera_cvp_init(void)
691 {
692         int ret;
693
694         ret = pci_register_driver(&altera_cvp_driver);
695         if (ret)
696                 return ret;
697
698         ret = driver_create_file(&altera_cvp_driver.driver,
699                                  &driver_attr_chkcfg);
700         if (ret)
701                 pr_warn("Can't create sysfs chkcfg file\n");
702
703         return 0;
704 }
705
706 static void __exit altera_cvp_exit(void)
707 {
708         driver_remove_file(&altera_cvp_driver.driver, &driver_attr_chkcfg);
709         pci_unregister_driver(&altera_cvp_driver);
710 }
711
712 module_init(altera_cvp_init);
713 module_exit(altera_cvp_exit);
714
715 MODULE_LICENSE("GPL v2");
716 MODULE_AUTHOR("Anatolij Gustschin <agust@denx.de>");
717 MODULE_DESCRIPTION("Module to load Altera FPGA over CvP");