aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/fpga/altera-cvp.c
diff options
context:
space:
mode:
authorThor Thayer <thor.thayer@linux.intel.com>2019-08-19 16:48:06 -0400
committerMoritz Fischer <mdf@kernel.org>2019-08-24 14:38:24 -0400
commiteb12511f0d47b4da58cc9fc1e93362081fa3331b (patch)
tree007a6804555c211ca76f0250e7113a465f92f971 /drivers/fpga/altera-cvp.c
parent2949dc443116a66fd1a92d9ef107be16cdd197cd (diff)
fpga: altera-cvp: Discover Vendor Specific offset
Newer Intel FPGAs have different Vendor Specific offsets than legacy parts. Use PCI discovery to find the CvP registers. Since the register positions remain the same, change the hard coded address to a more flexible way of indexing registers from the offset. Adding new PCI read and write abstraction functions to handle the offset (altera_read_config_dword() and altera_write_config_dword()). Signed-off-by: Thor Thayer <thor.thayer@linux.intel.com> Signed-off-by: Moritz Fischer <mdf@kernel.org>
Diffstat (limited to 'drivers/fpga/altera-cvp.c')
-rw-r--r--drivers/fpga/altera-cvp.c95
1 files changed, 58 insertions, 37 deletions
diff --git a/drivers/fpga/altera-cvp.c b/drivers/fpga/altera-cvp.c
index 53b963071c7b..9df2073331cb 100644
--- a/drivers/fpga/altera-cvp.c
+++ b/drivers/fpga/altera-cvp.c
@@ -22,10 +22,10 @@
22#define TIMEOUT_US 2000 /* CVP STATUS timeout for USERMODE polling */ 22#define TIMEOUT_US 2000 /* CVP STATUS timeout for USERMODE polling */
23 23
24/* Vendor Specific Extended Capability Registers */ 24/* Vendor Specific Extended Capability Registers */
25#define VSE_PCIE_EXT_CAP_ID 0x200 25#define VSE_PCIE_EXT_CAP_ID 0x0
26#define VSE_PCIE_EXT_CAP_ID_VAL 0x000b /* 16bit */ 26#define VSE_PCIE_EXT_CAP_ID_VAL 0x000b /* 16bit */
27 27
28#define VSE_CVP_STATUS 0x21c /* 32bit */ 28#define VSE_CVP_STATUS 0x1c /* 32bit */
29#define VSE_CVP_STATUS_CFG_RDY BIT(18) /* CVP_CONFIG_READY */ 29#define VSE_CVP_STATUS_CFG_RDY BIT(18) /* CVP_CONFIG_READY */
30#define VSE_CVP_STATUS_CFG_ERR BIT(19) /* CVP_CONFIG_ERROR */ 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 */ 31#define VSE_CVP_STATUS_CVP_EN BIT(20) /* ctrl block is enabling CVP */
@@ -33,18 +33,18 @@
33#define VSE_CVP_STATUS_CFG_DONE BIT(23) /* CVP_CONFIG_DONE */ 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 */ 34#define VSE_CVP_STATUS_PLD_CLK_IN_USE BIT(24) /* PLD_CLK_IN_USE */
35 35
36#define VSE_CVP_MODE_CTRL 0x220 /* 32bit */ 36#define VSE_CVP_MODE_CTRL 0x20 /* 32bit */
37#define VSE_CVP_MODE_CTRL_CVP_MODE BIT(0) /* CVP (1) or normal mode (0) */ 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) */ 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 */ 39#define VSE_CVP_MODE_CTRL_NUMCLKS_OFF 8 /* NUMCLKS bits offset */
40#define VSE_CVP_MODE_CTRL_NUMCLKS_MASK GENMASK(15, 8) 40#define VSE_CVP_MODE_CTRL_NUMCLKS_MASK GENMASK(15, 8)
41 41
42#define VSE_CVP_DATA 0x228 /* 32bit */ 42#define VSE_CVP_DATA 0x28 /* 32bit */
43#define VSE_CVP_PROG_CTRL 0x22c /* 32bit */ 43#define VSE_CVP_PROG_CTRL 0x2c /* 32bit */
44#define VSE_CVP_PROG_CTRL_CONFIG BIT(0) 44#define VSE_CVP_PROG_CTRL_CONFIG BIT(0)
45#define VSE_CVP_PROG_CTRL_START_XFER BIT(1) 45#define VSE_CVP_PROG_CTRL_START_XFER BIT(1)
46 46
47#define VSE_UNCOR_ERR_STATUS 0x234 /* 32bit */ 47#define VSE_UNCOR_ERR_STATUS 0x34 /* 32bit */
48#define VSE_UNCOR_ERR_CVP_CFG_ERR BIT(5) /* CVP_CONFIG_ERROR_LATCHED */ 48#define VSE_UNCOR_ERR_CVP_CFG_ERR BIT(5) /* CVP_CONFIG_ERROR_LATCHED */
49 49
50#define DRV_NAME "altera-cvp" 50#define DRV_NAME "altera-cvp"
@@ -61,14 +61,29 @@ struct altera_cvp_conf {
61 u32 data); 61 u32 data);
62 char mgr_name[64]; 62 char mgr_name[64];
63 u8 numclks; 63 u8 numclks;
64 u32 vsec_offset;
64}; 65};
65 66
67static int altera_read_config_dword(struct altera_cvp_conf *conf,
68 int where, u32 *val)
69{
70 return pci_read_config_dword(conf->pci_dev, conf->vsec_offset + where,
71 val);
72}
73
74static int altera_write_config_dword(struct altera_cvp_conf *conf,
75 int where, u32 val)
76{
77 return pci_write_config_dword(conf->pci_dev, conf->vsec_offset + where,
78 val);
79}
80
66static enum fpga_mgr_states altera_cvp_state(struct fpga_manager *mgr) 81static enum fpga_mgr_states altera_cvp_state(struct fpga_manager *mgr)
67{ 82{
68 struct altera_cvp_conf *conf = mgr->priv; 83 struct altera_cvp_conf *conf = mgr->priv;
69 u32 status; 84 u32 status;
70 85
71 pci_read_config_dword(conf->pci_dev, VSE_CVP_STATUS, &status); 86 altera_read_config_dword(conf, VSE_CVP_STATUS, &status);
72 87
73 if (status & VSE_CVP_STATUS_CFG_DONE) 88 if (status & VSE_CVP_STATUS_CFG_DONE)
74 return FPGA_MGR_STATE_OPERATING; 89 return FPGA_MGR_STATE_OPERATING;
@@ -86,7 +101,8 @@ static void altera_cvp_write_data_iomem(struct altera_cvp_conf *conf, u32 val)
86 101
87static void altera_cvp_write_data_config(struct altera_cvp_conf *conf, u32 val) 102static void altera_cvp_write_data_config(struct altera_cvp_conf *conf, u32 val)
88{ 103{
89 pci_write_config_dword(conf->pci_dev, VSE_CVP_DATA, val); 104 pci_write_config_dword(conf->pci_dev, conf->vsec_offset + VSE_CVP_DATA,
105 val);
90} 106}
91 107
92/* switches between CvP clock and internal clock */ 108/* switches between CvP clock and internal clock */
@@ -96,10 +112,10 @@ static void altera_cvp_dummy_write(struct altera_cvp_conf *conf)
96 u32 val; 112 u32 val;
97 113
98 /* set 1 CVP clock cycle for every CVP Data Register Write */ 114 /* set 1 CVP clock cycle for every CVP Data Register Write */
99 pci_read_config_dword(conf->pci_dev, VSE_CVP_MODE_CTRL, &val); 115 altera_read_config_dword(conf, VSE_CVP_MODE_CTRL, &val);
100 val &= ~VSE_CVP_MODE_CTRL_NUMCLKS_MASK; 116 val &= ~VSE_CVP_MODE_CTRL_NUMCLKS_MASK;
101 val |= 1 << VSE_CVP_MODE_CTRL_NUMCLKS_OFF; 117 val |= 1 << VSE_CVP_MODE_CTRL_NUMCLKS_OFF;
102 pci_write_config_dword(conf->pci_dev, VSE_CVP_MODE_CTRL, val); 118 altera_write_config_dword(conf, VSE_CVP_MODE_CTRL, val);
103 119
104 for (i = 0; i < CVP_DUMMY_WR; i++) 120 for (i = 0; i < CVP_DUMMY_WR; i++)
105 conf->write_data(conf, 0); /* dummy data, could be any value */ 121 conf->write_data(conf, 0); /* dummy data, could be any value */
@@ -116,7 +132,7 @@ static int altera_cvp_wait_status(struct altera_cvp_conf *conf, u32 status_mask,
116 retries++; 132 retries++;
117 133
118 do { 134 do {
119 pci_read_config_dword(conf->pci_dev, VSE_CVP_STATUS, &val); 135 altera_read_config_dword(conf, VSE_CVP_STATUS, &val);
120 if ((val & status_mask) == status_val) 136 if ((val & status_mask) == status_val)
121 return 0; 137 return 0;
122 138
@@ -131,18 +147,17 @@ static int altera_cvp_teardown(struct fpga_manager *mgr,
131 struct fpga_image_info *info) 147 struct fpga_image_info *info)
132{ 148{
133 struct altera_cvp_conf *conf = mgr->priv; 149 struct altera_cvp_conf *conf = mgr->priv;
134 struct pci_dev *pdev = conf->pci_dev;
135 int ret; 150 int ret;
136 u32 val; 151 u32 val;
137 152
138 /* STEP 12 - reset START_XFER bit */ 153 /* STEP 12 - reset START_XFER bit */
139 pci_read_config_dword(pdev, VSE_CVP_PROG_CTRL, &val); 154 altera_read_config_dword(conf, VSE_CVP_PROG_CTRL, &val);
140 val &= ~VSE_CVP_PROG_CTRL_START_XFER; 155 val &= ~VSE_CVP_PROG_CTRL_START_XFER;
141 pci_write_config_dword(pdev, VSE_CVP_PROG_CTRL, val); 156 altera_write_config_dword(conf, VSE_CVP_PROG_CTRL, val);
142 157
143 /* STEP 13 - reset CVP_CONFIG bit */ 158 /* STEP 13 - reset CVP_CONFIG bit */
144 val &= ~VSE_CVP_PROG_CTRL_CONFIG; 159 val &= ~VSE_CVP_PROG_CTRL_CONFIG;
145 pci_write_config_dword(pdev, VSE_CVP_PROG_CTRL, val); 160 altera_write_config_dword(conf, VSE_CVP_PROG_CTRL, val);
146 161
147 /* 162 /*
148 * STEP 14 163 * STEP 14
@@ -164,7 +179,6 @@ static int altera_cvp_write_init(struct fpga_manager *mgr,
164 const char *buf, size_t count) 179 const char *buf, size_t count)
165{ 180{
166 struct altera_cvp_conf *conf = mgr->priv; 181 struct altera_cvp_conf *conf = mgr->priv;
167 struct pci_dev *pdev = conf->pci_dev;
168 u32 iflags, val; 182 u32 iflags, val;
169 int ret; 183 int ret;
170 184
@@ -184,7 +198,7 @@ static int altera_cvp_write_init(struct fpga_manager *mgr,
184 conf->numclks = 1; /* for uncompressed and unencrypted images */ 198 conf->numclks = 1; /* for uncompressed and unencrypted images */
185 199
186 /* STEP 1 - read CVP status and check CVP_EN flag */ 200 /* STEP 1 - read CVP status and check CVP_EN flag */
187 pci_read_config_dword(pdev, VSE_CVP_STATUS, &val); 201 altera_read_config_dword(conf, VSE_CVP_STATUS, &val);
188 if (!(val & VSE_CVP_STATUS_CVP_EN)) { 202 if (!(val & VSE_CVP_STATUS_CVP_EN)) {
189 dev_err(&mgr->dev, "CVP mode off: 0x%04x\n", val); 203 dev_err(&mgr->dev, "CVP mode off: 0x%04x\n", val);
190 return -ENODEV; 204 return -ENODEV;
@@ -202,14 +216,14 @@ static int altera_cvp_write_init(struct fpga_manager *mgr,
202 * - set HIP_CLK_SEL and CVP_MODE (must be set in the order mentioned) 216 * - set HIP_CLK_SEL and CVP_MODE (must be set in the order mentioned)
203 */ 217 */
204 /* switch from fabric to PMA clock */ 218 /* switch from fabric to PMA clock */
205 pci_read_config_dword(pdev, VSE_CVP_MODE_CTRL, &val); 219 altera_read_config_dword(conf, VSE_CVP_MODE_CTRL, &val);
206 val |= VSE_CVP_MODE_CTRL_HIP_CLK_SEL; 220 val |= VSE_CVP_MODE_CTRL_HIP_CLK_SEL;
207 pci_write_config_dword(pdev, VSE_CVP_MODE_CTRL, val); 221 altera_write_config_dword(conf, VSE_CVP_MODE_CTRL, val);
208 222
209 /* set CVP mode */ 223 /* set CVP mode */
210 pci_read_config_dword(pdev, VSE_CVP_MODE_CTRL, &val); 224 altera_read_config_dword(conf, VSE_CVP_MODE_CTRL, &val);
211 val |= VSE_CVP_MODE_CTRL_CVP_MODE; 225 val |= VSE_CVP_MODE_CTRL_CVP_MODE;
212 pci_write_config_dword(pdev, VSE_CVP_MODE_CTRL, val); 226 altera_write_config_dword(conf, VSE_CVP_MODE_CTRL, val);
213 227
214 /* 228 /*
215 * STEP 3 229 * STEP 3
@@ -218,10 +232,10 @@ static int altera_cvp_write_init(struct fpga_manager *mgr,
218 altera_cvp_dummy_write(conf); 232 altera_cvp_dummy_write(conf);
219 233
220 /* STEP 4 - set CVP_CONFIG bit */ 234 /* STEP 4 - set CVP_CONFIG bit */
221 pci_read_config_dword(pdev, VSE_CVP_PROG_CTRL, &val); 235 altera_read_config_dword(conf, VSE_CVP_PROG_CTRL, &val);
222 /* request control block to begin transfer using CVP */ 236 /* request control block to begin transfer using CVP */
223 val |= VSE_CVP_PROG_CTRL_CONFIG; 237 val |= VSE_CVP_PROG_CTRL_CONFIG;
224 pci_write_config_dword(pdev, VSE_CVP_PROG_CTRL, val); 238 altera_write_config_dword(conf, VSE_CVP_PROG_CTRL, val);
225 239
226 /* STEP 5 - poll CVP_CONFIG READY for 1 with 10us timeout */ 240 /* STEP 5 - poll CVP_CONFIG READY for 1 with 10us timeout */
227 ret = altera_cvp_wait_status(conf, VSE_CVP_STATUS_CFG_RDY, 241 ret = altera_cvp_wait_status(conf, VSE_CVP_STATUS_CFG_RDY,
@@ -238,15 +252,15 @@ static int altera_cvp_write_init(struct fpga_manager *mgr,
238 altera_cvp_dummy_write(conf); 252 altera_cvp_dummy_write(conf);
239 253
240 /* STEP 7 - set START_XFER */ 254 /* STEP 7 - set START_XFER */
241 pci_read_config_dword(pdev, VSE_CVP_PROG_CTRL, &val); 255 altera_read_config_dword(conf, VSE_CVP_PROG_CTRL, &val);
242 val |= VSE_CVP_PROG_CTRL_START_XFER; 256 val |= VSE_CVP_PROG_CTRL_START_XFER;
243 pci_write_config_dword(pdev, VSE_CVP_PROG_CTRL, val); 257 altera_write_config_dword(conf, VSE_CVP_PROG_CTRL, val);
244 258
245 /* STEP 8 - start transfer (set CVP_NUMCLKS for bitstream) */ 259 /* STEP 8 - start transfer (set CVP_NUMCLKS for bitstream) */
246 pci_read_config_dword(pdev, VSE_CVP_MODE_CTRL, &val); 260 altera_read_config_dword(conf, VSE_CVP_MODE_CTRL, &val);
247 val &= ~VSE_CVP_MODE_CTRL_NUMCLKS_MASK; 261 val &= ~VSE_CVP_MODE_CTRL_NUMCLKS_MASK;
248 val |= conf->numclks << VSE_CVP_MODE_CTRL_NUMCLKS_OFF; 262 val |= conf->numclks << VSE_CVP_MODE_CTRL_NUMCLKS_OFF;
249 pci_write_config_dword(pdev, VSE_CVP_MODE_CTRL, val); 263 altera_write_config_dword(conf, VSE_CVP_MODE_CTRL, val);
250 264
251 return 0; 265 return 0;
252} 266}
@@ -257,7 +271,7 @@ static inline int altera_cvp_chk_error(struct fpga_manager *mgr, size_t bytes)
257 u32 val; 271 u32 val;
258 272
259 /* STEP 10 (optional) - check CVP_CONFIG_ERROR flag */ 273 /* STEP 10 (optional) - check CVP_CONFIG_ERROR flag */
260 pci_read_config_dword(conf->pci_dev, VSE_CVP_STATUS, &val); 274 altera_read_config_dword(conf, VSE_CVP_STATUS, &val);
261 if (val & VSE_CVP_STATUS_CFG_ERR) { 275 if (val & VSE_CVP_STATUS_CFG_ERR) {
262 dev_err(&mgr->dev, "CVP_CONFIG_ERROR after %zu bytes!\n", 276 dev_err(&mgr->dev, "CVP_CONFIG_ERROR after %zu bytes!\n",
263 bytes); 277 bytes);
@@ -316,27 +330,25 @@ static int altera_cvp_write_complete(struct fpga_manager *mgr,
316 struct fpga_image_info *info) 330 struct fpga_image_info *info)
317{ 331{
318 struct altera_cvp_conf *conf = mgr->priv; 332 struct altera_cvp_conf *conf = mgr->priv;
319 struct pci_dev *pdev = conf->pci_dev; 333 u32 mask, val;
320 int ret; 334 int ret;
321 u32 mask;
322 u32 val;
323 335
324 ret = altera_cvp_teardown(mgr, info); 336 ret = altera_cvp_teardown(mgr, info);
325 if (ret) 337 if (ret)
326 return ret; 338 return ret;
327 339
328 /* STEP 16 - check CVP_CONFIG_ERROR_LATCHED bit */ 340 /* STEP 16 - check CVP_CONFIG_ERROR_LATCHED bit */
329 pci_read_config_dword(pdev, VSE_UNCOR_ERR_STATUS, &val); 341 altera_read_config_dword(conf, VSE_UNCOR_ERR_STATUS, &val);
330 if (val & VSE_UNCOR_ERR_CVP_CFG_ERR) { 342 if (val & VSE_UNCOR_ERR_CVP_CFG_ERR) {
331 dev_err(&mgr->dev, "detected CVP_CONFIG_ERROR_LATCHED!\n"); 343 dev_err(&mgr->dev, "detected CVP_CONFIG_ERROR_LATCHED!\n");
332 return -EPROTO; 344 return -EPROTO;
333 } 345 }
334 346
335 /* STEP 17 - reset CVP_MODE and HIP_CLK_SEL bit */ 347 /* STEP 17 - reset CVP_MODE and HIP_CLK_SEL bit */
336 pci_read_config_dword(pdev, VSE_CVP_MODE_CTRL, &val); 348 altera_read_config_dword(conf, VSE_CVP_MODE_CTRL, &val);
337 val &= ~VSE_CVP_MODE_CTRL_HIP_CLK_SEL; 349 val &= ~VSE_CVP_MODE_CTRL_HIP_CLK_SEL;
338 val &= ~VSE_CVP_MODE_CTRL_CVP_MODE; 350 val &= ~VSE_CVP_MODE_CTRL_CVP_MODE;
339 pci_write_config_dword(pdev, VSE_CVP_MODE_CTRL, val); 351 altera_write_config_dword(conf, VSE_CVP_MODE_CTRL, val);
340 352
341 /* STEP 18 - poll PLD_CLK_IN_USE and USER_MODE bits */ 353 /* STEP 18 - poll PLD_CLK_IN_USE and USER_MODE bits */
342 mask = VSE_CVP_STATUS_PLD_CLK_IN_USE | VSE_CVP_STATUS_USERMODE; 354 mask = VSE_CVP_STATUS_PLD_CLK_IN_USE | VSE_CVP_STATUS_USERMODE;
@@ -395,22 +407,29 @@ static int altera_cvp_probe(struct pci_dev *pdev,
395{ 407{
396 struct altera_cvp_conf *conf; 408 struct altera_cvp_conf *conf;
397 struct fpga_manager *mgr; 409 struct fpga_manager *mgr;
410 int ret, offset;
398 u16 cmd, val; 411 u16 cmd, val;
399 u32 regval; 412 u32 regval;
400 int ret; 413
414 /* Discover the Vendor Specific Offset for this device */
415 offset = pci_find_next_ext_capability(pdev, 0, PCI_EXT_CAP_ID_VNDR);
416 if (!offset) {
417 dev_err(&pdev->dev, "No Vendor Specific Offset.\n");
418 return -ENODEV;
419 }
401 420
402 /* 421 /*
403 * First check if this is the expected FPGA device. PCI config 422 * First check if this is the expected FPGA device. PCI config
404 * space access works without enabling the PCI device, memory 423 * space access works without enabling the PCI device, memory
405 * space access is enabled further down. 424 * space access is enabled further down.
406 */ 425 */
407 pci_read_config_word(pdev, VSE_PCIE_EXT_CAP_ID, &val); 426 pci_read_config_word(pdev, offset + VSE_PCIE_EXT_CAP_ID, &val);
408 if (val != VSE_PCIE_EXT_CAP_ID_VAL) { 427 if (val != VSE_PCIE_EXT_CAP_ID_VAL) {
409 dev_err(&pdev->dev, "Wrong EXT_CAP_ID value 0x%x\n", val); 428 dev_err(&pdev->dev, "Wrong EXT_CAP_ID value 0x%x\n", val);
410 return -ENODEV; 429 return -ENODEV;
411 } 430 }
412 431
413 pci_read_config_dword(pdev, VSE_CVP_STATUS, &regval); 432 pci_read_config_dword(pdev, offset + VSE_CVP_STATUS, &regval);
414 if (!(regval & VSE_CVP_STATUS_CVP_EN)) { 433 if (!(regval & VSE_CVP_STATUS_CVP_EN)) {
415 dev_err(&pdev->dev, 434 dev_err(&pdev->dev,
416 "CVP is disabled for this device: CVP_STATUS Reg 0x%x\n", 435 "CVP is disabled for this device: CVP_STATUS Reg 0x%x\n",
@@ -422,6 +441,8 @@ static int altera_cvp_probe(struct pci_dev *pdev,
422 if (!conf) 441 if (!conf)
423 return -ENOMEM; 442 return -ENOMEM;
424 443
444 conf->vsec_offset = offset;
445
425 /* 446 /*
426 * Enable memory BAR access. We cannot use pci_enable_device() here 447 * Enable memory BAR access. We cannot use pci_enable_device() here
427 * because it will make the driver unusable with FPGA devices that 448 * because it will make the driver unusable with FPGA devices that