aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/fpga/zynq-fpga.c
diff options
context:
space:
mode:
authorMoritz Fischer <moritz.fischer@ettus.com>2015-10-16 18:42:30 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-10-18 00:57:16 -0400
commit37784706bf9e3b723898125b47d6f1e76a8db418 (patch)
tree9fb87696d855a46c7c7472e3d55f5d9fa1136c03 /drivers/fpga/zynq-fpga.c
parent20598490a337abf44a8fb2d229ace6cf8087f2d4 (diff)
fpga manager: Adding FPGA Manager support for Xilinx Zynq 7000
This commit adds FPGA Manager support for the Xilinx Zynq chip. The code borrows some from the xdevcfg driver in Xilinx' vendor tree. Signed-off-by: Moritz Fischer <moritz.fischer@ettus.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/fpga/zynq-fpga.c')
-rw-r--r--drivers/fpga/zynq-fpga.c533
1 files changed, 533 insertions, 0 deletions
diff --git a/drivers/fpga/zynq-fpga.c b/drivers/fpga/zynq-fpga.c
new file mode 100644
index 000000000000..103303c88937
--- /dev/null
+++ b/drivers/fpga/zynq-fpga.c
@@ -0,0 +1,533 @@
1/*
2 * Copyright (c) 2011-2015 Xilinx Inc.
3 * Copyright (c) 2015, National Instruments Corp.
4 *
5 * FPGA Manager Driver for Xilinx Zynq, heavily based on xdevcfg driver
6 * in their vendor tree.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2 of the License.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
18#include <linux/clk.h>
19#include <linux/completion.h>
20#include <linux/delay.h>
21#include <linux/dma-mapping.h>
22#include <linux/fpga/fpga-mgr.h>
23#include <linux/interrupt.h>
24#include <linux/io.h>
25#include <linux/iopoll.h>
26#include <linux/module.h>
27#include <linux/mfd/syscon.h>
28#include <linux/of_address.h>
29#include <linux/of_irq.h>
30#include <linux/pm.h>
31#include <linux/regmap.h>
32#include <linux/string.h>
33
34/* Offsets into SLCR regmap */
35
36/* FPGA Software Reset Control */
37#define SLCR_FPGA_RST_CTRL_OFFSET 0x240
38/* Level Shifters Enable */
39#define SLCR_LVL_SHFTR_EN_OFFSET 0x900
40
41/* Constant Definitions */
42
43/* Control Register */
44#define CTRL_OFFSET 0x00
45/* Lock Register */
46#define LOCK_OFFSET 0x04
47/* Interrupt Status Register */
48#define INT_STS_OFFSET 0x0c
49/* Interrupt Mask Register */
50#define INT_MASK_OFFSET 0x10
51/* Status Register */
52#define STATUS_OFFSET 0x14
53/* DMA Source Address Register */
54#define DMA_SRC_ADDR_OFFSET 0x18
55/* DMA Destination Address Reg */
56#define DMA_DST_ADDR_OFFSET 0x1c
57/* DMA Source Transfer Length */
58#define DMA_SRC_LEN_OFFSET 0x20
59/* DMA Destination Transfer */
60#define DMA_DEST_LEN_OFFSET 0x24
61/* Unlock Register */
62#define UNLOCK_OFFSET 0x34
63/* Misc. Control Register */
64#define MCTRL_OFFSET 0x80
65
66/* Control Register Bit definitions */
67
68/* Signal to reset FPGA */
69#define CTRL_PCFG_PROG_B_MASK BIT(30)
70/* Enable PCAP for PR */
71#define CTRL_PCAP_PR_MASK BIT(27)
72/* Enable PCAP */
73#define CTRL_PCAP_MODE_MASK BIT(26)
74
75/* Miscellaneous Control Register bit definitions */
76/* Internal PCAP loopback */
77#define MCTRL_PCAP_LPBK_MASK BIT(4)
78
79/* Status register bit definitions */
80
81/* FPGA init status */
82#define STATUS_DMA_Q_F BIT(31)
83#define STATUS_PCFG_INIT_MASK BIT(4)
84
85/* Interrupt Status/Mask Register Bit definitions */
86/* DMA command done */
87#define IXR_DMA_DONE_MASK BIT(13)
88/* DMA and PCAP cmd done */
89#define IXR_D_P_DONE_MASK BIT(12)
90 /* FPGA programmed */
91#define IXR_PCFG_DONE_MASK BIT(2)
92#define IXR_ERROR_FLAGS_MASK 0x00F0F860
93#define IXR_ALL_MASK 0xF8F7F87F
94
95/* Miscellaneous constant values */
96
97/* Invalid DMA addr */
98#define DMA_INVALID_ADDRESS GENMASK(31, 0)
99/* Used to unlock the dev */
100#define UNLOCK_MASK 0x757bdf0d
101/* Timeout for DMA to complete */
102#define DMA_DONE_TIMEOUT msecs_to_jiffies(1000)
103/* Timeout for polling reset bits */
104#define INIT_POLL_TIMEOUT 2500000
105/* Delay for polling reset bits */
106#define INIT_POLL_DELAY 20
107
108/* Masks for controlling stuff in SLCR */
109/* Disable all Level shifters */
110#define LVL_SHFTR_DISABLE_ALL_MASK 0x0
111/* Enable Level shifters from PS to PL */
112#define LVL_SHFTR_ENABLE_PS_TO_PL 0xa
113/* Enable Level shifters from PL to PS */
114#define LVL_SHFTR_ENABLE_PL_TO_PS 0xf
115/* Enable global resets */
116#define FPGA_RST_ALL_MASK 0xf
117/* Disable global resets */
118#define FPGA_RST_NONE_MASK 0x0
119
120struct zynq_fpga_priv {
121 struct device *dev;
122 int irq;
123 struct clk *clk;
124
125 void __iomem *io_base;
126 struct regmap *slcr;
127
128 struct completion dma_done;
129};
130
131static inline void zynq_fpga_write(struct zynq_fpga_priv *priv, u32 offset,
132 u32 val)
133{
134 writel(val, priv->io_base + offset);
135}
136
137static inline u32 zynq_fpga_read(const struct zynq_fpga_priv *priv,
138 u32 offset)
139{
140 return readl(priv->io_base + offset);
141}
142
143#define zynq_fpga_poll_timeout(priv, addr, val, cond, sleep_us, timeout_us) \
144 readl_poll_timeout(priv->io_base + addr, val, cond, sleep_us, \
145 timeout_us)
146
147static void zynq_fpga_mask_irqs(struct zynq_fpga_priv *priv)
148{
149 u32 intr_mask;
150
151 intr_mask = zynq_fpga_read(priv, INT_MASK_OFFSET);
152 zynq_fpga_write(priv, INT_MASK_OFFSET,
153 intr_mask | IXR_DMA_DONE_MASK | IXR_ERROR_FLAGS_MASK);
154}
155
156static void zynq_fpga_unmask_irqs(struct zynq_fpga_priv *priv)
157{
158 u32 intr_mask;
159
160 intr_mask = zynq_fpga_read(priv, INT_MASK_OFFSET);
161 zynq_fpga_write(priv, INT_MASK_OFFSET,
162 intr_mask
163 & ~(IXR_D_P_DONE_MASK | IXR_ERROR_FLAGS_MASK));
164}
165
166static irqreturn_t zynq_fpga_isr(int irq, void *data)
167{
168 struct zynq_fpga_priv *priv = data;
169
170 /* disable DMA and error IRQs */
171 zynq_fpga_mask_irqs(priv);
172
173 complete(&priv->dma_done);
174
175 return IRQ_HANDLED;
176}
177
178static int zynq_fpga_ops_write_init(struct fpga_manager *mgr, u32 flags,
179 const char *buf, size_t count)
180{
181 struct zynq_fpga_priv *priv;
182 u32 ctrl, status;
183 int err;
184
185 priv = mgr->priv;
186
187 err = clk_enable(priv->clk);
188 if (err)
189 return err;
190
191 /* don't globally reset PL if we're doing partial reconfig */
192 if (!(flags & FPGA_MGR_PARTIAL_RECONFIG)) {
193 /* assert AXI interface resets */
194 regmap_write(priv->slcr, SLCR_FPGA_RST_CTRL_OFFSET,
195 FPGA_RST_ALL_MASK);
196
197 /* disable all level shifters */
198 regmap_write(priv->slcr, SLCR_LVL_SHFTR_EN_OFFSET,
199 LVL_SHFTR_DISABLE_ALL_MASK);
200 /* enable level shifters from PS to PL */
201 regmap_write(priv->slcr, SLCR_LVL_SHFTR_EN_OFFSET,
202 LVL_SHFTR_ENABLE_PS_TO_PL);
203
204 /* create a rising edge on PCFG_INIT. PCFG_INIT follows
205 * PCFG_PROG_B, so we need to poll it after setting PCFG_PROG_B
206 * to make sure the rising edge actually happens.
207 * Note: PCFG_PROG_B is low active, sequence as described in
208 * UG585 v1.10 page 211
209 */
210 ctrl = zynq_fpga_read(priv, CTRL_OFFSET);
211 ctrl |= CTRL_PCFG_PROG_B_MASK;
212
213 zynq_fpga_write(priv, CTRL_OFFSET, ctrl);
214
215 err = zynq_fpga_poll_timeout(priv, STATUS_OFFSET, status,
216 status & STATUS_PCFG_INIT_MASK,
217 INIT_POLL_DELAY,
218 INIT_POLL_TIMEOUT);
219 if (err) {
220 dev_err(priv->dev, "Timeout waiting for PCFG_INIT");
221 goto out_err;
222 }
223
224 ctrl = zynq_fpga_read(priv, CTRL_OFFSET);
225 ctrl &= ~CTRL_PCFG_PROG_B_MASK;
226
227 zynq_fpga_write(priv, CTRL_OFFSET, ctrl);
228
229 err = zynq_fpga_poll_timeout(priv, STATUS_OFFSET, status,
230 !(status & STATUS_PCFG_INIT_MASK),
231 INIT_POLL_DELAY,
232 INIT_POLL_TIMEOUT);
233 if (err) {
234 dev_err(priv->dev, "Timeout waiting for !PCFG_INIT");
235 goto out_err;
236 }
237
238 ctrl = zynq_fpga_read(priv, CTRL_OFFSET);
239 ctrl |= CTRL_PCFG_PROG_B_MASK;
240
241 zynq_fpga_write(priv, CTRL_OFFSET, ctrl);
242
243 err = zynq_fpga_poll_timeout(priv, STATUS_OFFSET, status,
244 status & STATUS_PCFG_INIT_MASK,
245 INIT_POLL_DELAY,
246 INIT_POLL_TIMEOUT);
247 if (err) {
248 dev_err(priv->dev, "Timeout waiting for PCFG_INIT");
249 goto out_err;
250 }
251 }
252
253 /* set configuration register with following options:
254 * - enable PCAP interface
255 * - set throughput for maximum speed
256 * - set CPU in user mode
257 */
258 ctrl = zynq_fpga_read(priv, CTRL_OFFSET);
259 zynq_fpga_write(priv, CTRL_OFFSET,
260 (CTRL_PCAP_PR_MASK | CTRL_PCAP_MODE_MASK | ctrl));
261
262 /* check that we have room in the command queue */
263 status = zynq_fpga_read(priv, STATUS_OFFSET);
264 if (status & STATUS_DMA_Q_F) {
265 dev_err(priv->dev, "DMA command queue full");
266 err = -EBUSY;
267 goto out_err;
268 }
269
270 /* ensure internal PCAP loopback is disabled */
271 ctrl = zynq_fpga_read(priv, MCTRL_OFFSET);
272 zynq_fpga_write(priv, MCTRL_OFFSET, (~MCTRL_PCAP_LPBK_MASK & ctrl));
273
274 clk_disable(priv->clk);
275
276 return 0;
277
278out_err:
279 clk_disable(priv->clk);
280
281 return err;
282}
283
284static int zynq_fpga_ops_write(struct fpga_manager *mgr,
285 const char *buf, size_t count)
286{
287 struct zynq_fpga_priv *priv;
288 int err;
289 char *kbuf;
290 size_t i, in_count;
291 dma_addr_t dma_addr;
292 u32 transfer_length = 0;
293 u32 intr_status;
294
295 in_count = count;
296 priv = mgr->priv;
297
298 kbuf = dma_alloc_coherent(priv->dev, count, &dma_addr, GFP_KERNEL);
299 if (!kbuf)
300 return -ENOMEM;
301
302 memcpy(kbuf, buf, count);
303
304 /* look for the sync word */
305 for (i = 0; i < count - 4; i++) {
306 if (memcmp(kbuf + i, "\xAA\x99\x55\x66", 4) == 0) {
307 dev_dbg(priv->dev, "Found swapped sync word\n");
308 break;
309 }
310 }
311
312 /* remove the header, align the data on word boundary */
313 if (i != count - 4) {
314 count -= i;
315 memmove(kbuf, kbuf + i, count);
316 }
317
318 /* fixup endianness of the data */
319 for (i = 0; i < count; i += 4) {
320 u32 *p = (u32 *)&kbuf[i];
321 *p = swab32(*p);
322 }
323
324 /* enable clock */
325 err = clk_enable(priv->clk);
326 if (err)
327 goto out_free;
328
329 zynq_fpga_write(priv, INT_STS_OFFSET, IXR_ALL_MASK);
330
331 reinit_completion(&priv->dma_done);
332
333 /* enable DMA and error IRQs */
334 zynq_fpga_unmask_irqs(priv);
335
336 /* the +1 in the src addr is used to hold off on DMA_DONE IRQ
337 * until both AXI and PCAP are done ...
338 */
339 zynq_fpga_write(priv, DMA_SRC_ADDR_OFFSET, (u32)(dma_addr) + 1);
340 zynq_fpga_write(priv, DMA_DST_ADDR_OFFSET, (u32)DMA_INVALID_ADDRESS);
341
342 /* convert #bytes to #words */
343 transfer_length = (count + 3) / 4;
344
345 zynq_fpga_write(priv, DMA_SRC_LEN_OFFSET, transfer_length);
346 zynq_fpga_write(priv, DMA_DEST_LEN_OFFSET, 0);
347
348 wait_for_completion(&priv->dma_done);
349
350 intr_status = zynq_fpga_read(priv, INT_STS_OFFSET);
351 zynq_fpga_write(priv, INT_STS_OFFSET, intr_status);
352
353 if (!((intr_status & IXR_D_P_DONE_MASK) == IXR_D_P_DONE_MASK)) {
354 dev_err(priv->dev, "Error configuring FPGA");
355 err = -EFAULT;
356 }
357
358 clk_disable(priv->clk);
359
360out_free:
361 dma_free_coherent(priv->dev, in_count, kbuf, dma_addr);
362
363 return err;
364}
365
366static int zynq_fpga_ops_write_complete(struct fpga_manager *mgr, u32 flags)
367{
368 struct zynq_fpga_priv *priv = mgr->priv;
369 int err;
370 u32 intr_status;
371
372 err = clk_enable(priv->clk);
373 if (err)
374 return err;
375
376 err = zynq_fpga_poll_timeout(priv, INT_STS_OFFSET, intr_status,
377 intr_status & IXR_PCFG_DONE_MASK,
378 INIT_POLL_DELAY,
379 INIT_POLL_TIMEOUT);
380
381 clk_disable(priv->clk);
382
383 if (err)
384 return err;
385
386 /* for the partial reconfig case we didn't touch the level shifters */
387 if (!(flags & FPGA_MGR_PARTIAL_RECONFIG)) {
388 /* enable level shifters from PL to PS */
389 regmap_write(priv->slcr, SLCR_LVL_SHFTR_EN_OFFSET,
390 LVL_SHFTR_ENABLE_PL_TO_PS);
391
392 /* deassert AXI interface resets */
393 regmap_write(priv->slcr, SLCR_FPGA_RST_CTRL_OFFSET,
394 FPGA_RST_NONE_MASK);
395 }
396
397 return 0;
398}
399
400static enum fpga_mgr_states zynq_fpga_ops_state(struct fpga_manager *mgr)
401{
402 int err;
403 u32 intr_status;
404 struct zynq_fpga_priv *priv;
405
406 priv = mgr->priv;
407
408 err = clk_enable(priv->clk);
409 if (err)
410 return FPGA_MGR_STATE_UNKNOWN;
411
412 intr_status = zynq_fpga_read(priv, INT_STS_OFFSET);
413 clk_disable(priv->clk);
414
415 if (intr_status & IXR_PCFG_DONE_MASK)
416 return FPGA_MGR_STATE_OPERATING;
417
418 return FPGA_MGR_STATE_UNKNOWN;
419}
420
421static const struct fpga_manager_ops zynq_fpga_ops = {
422 .state = zynq_fpga_ops_state,
423 .write_init = zynq_fpga_ops_write_init,
424 .write = zynq_fpga_ops_write,
425 .write_complete = zynq_fpga_ops_write_complete,
426};
427
428static int zynq_fpga_probe(struct platform_device *pdev)
429{
430 struct device *dev = &pdev->dev;
431 struct zynq_fpga_priv *priv;
432 struct resource *res;
433 int err;
434
435 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
436 if (!priv)
437 return -ENOMEM;
438
439 platform_set_drvdata(pdev, priv);
440 priv->dev = dev;
441
442 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
443 priv->io_base = devm_ioremap_resource(dev, res);
444 if (IS_ERR(priv->io_base))
445 return PTR_ERR(priv->io_base);
446
447 priv->slcr = syscon_regmap_lookup_by_phandle(dev->of_node,
448 "syscon");
449 if (IS_ERR(priv->slcr)) {
450 dev_err(dev, "unable to get zynq-slcr regmap");
451 return PTR_ERR(priv->slcr);
452 }
453
454 init_completion(&priv->dma_done);
455
456 priv->irq = platform_get_irq(pdev, 0);
457 if (priv->irq < 0) {
458 dev_err(dev, "No IRQ available");
459 return priv->irq;
460 }
461
462 err = devm_request_irq(dev, priv->irq, zynq_fpga_isr, 0,
463 dev_name(dev), priv);
464 if (err) {
465 dev_err(dev, "unable to request IRQ");
466 return err;
467 }
468
469 priv->clk = devm_clk_get(dev, "ref_clk");
470 if (IS_ERR(priv->clk)) {
471 dev_err(dev, "input clock not found");
472 return PTR_ERR(priv->clk);
473 }
474
475 err = clk_prepare_enable(priv->clk);
476 if (err) {
477 dev_err(dev, "unable to enable clock");
478 return err;
479 }
480
481 /* unlock the device */
482 zynq_fpga_write(priv, UNLOCK_OFFSET, UNLOCK_MASK);
483
484 clk_disable(priv->clk);
485
486 err = fpga_mgr_register(dev, "Xilinx Zynq FPGA Manager",
487 &zynq_fpga_ops, priv);
488 if (err) {
489 dev_err(dev, "unable to register FPGA manager");
490 clk_disable_unprepare(priv->clk);
491 return err;
492 }
493
494 return 0;
495}
496
497static int zynq_fpga_remove(struct platform_device *pdev)
498{
499 struct zynq_fpga_priv *priv;
500
501 fpga_mgr_unregister(&pdev->dev);
502
503 priv = platform_get_drvdata(pdev);
504
505 clk_disable_unprepare(priv->clk);
506
507 return 0;
508}
509
510#ifdef CONFIG_OF
511static const struct of_device_id zynq_fpga_of_match[] = {
512 { .compatible = "xlnx,zynq-devcfg-1.0", },
513 {},
514};
515
516MODULE_DEVICE_TABLE(of, zynq_fpga_of_match);
517#endif
518
519static struct platform_driver zynq_fpga_driver = {
520 .probe = zynq_fpga_probe,
521 .remove = zynq_fpga_remove,
522 .driver = {
523 .name = "zynq_fpga_manager",
524 .of_match_table = of_match_ptr(zynq_fpga_of_match),
525 },
526};
527
528module_platform_driver(zynq_fpga_driver);
529
530MODULE_AUTHOR("Moritz Fischer <moritz.fischer@ettus.com>");
531MODULE_AUTHOR("Michal Simek <michal.simek@xilinx.com>");
532MODULE_DESCRIPTION("Xilinx Zynq FPGA Manager");
533MODULE_LICENSE("GPL v2");