]> rtime.felk.cvut.cz Git - zynq/linux.git/blob - drivers/fpga/zynqmp-fpga.c
fpga: Fix bitstream typo error
[zynq/linux.git] / drivers / fpga / zynqmp-fpga.c
1 /*
2  * Copyright (C) 2016 Xilinx, Inc.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  */
14
15 #include <linux/clk.h>
16 #include <linux/dma-mapping.h>
17 #include <linux/fpga/fpga-mgr.h>
18 #include <linux/io.h>
19 #include <linux/kernel.h>
20 #include <linux/module.h>
21 #include <linux/of_address.h>
22 #include <linux/string.h>
23 #include <linux/firmware/xilinx/zynqmp/firmware.h>
24
25 /* Constant Definitions */
26 #define IXR_FPGA_DONE_MASK      0X00000008U
27 #define IXR_FPGA_ENCRYPTION_EN  0x00000008U
28
29 #define READ_DMA_SIZE           0x200
30 #define DUMMY_FRAMES_SIZE       0x64
31 #define PCAP_READ_CLKFREQ       25000000
32
33 static bool readback_type;
34 module_param(readback_type, bool, 0644);
35 MODULE_PARM_DESC(readback_type,
36                  "readback_type 0-configuration register read "
37                  "1- configuration data read (default: 0)");
38
39 /**
40  * struct zynqmp_configreg - Configuration register offsets
41  * @reg:        Name of the configuration register.
42  * @offset:     Register offset.
43  */
44 struct zynqmp_configreg {
45         char *reg;
46         u32 offset;
47 };
48
49 static struct zynqmp_configreg cfgreg[] = {
50         {.reg = "CRC",          .offset = 0},
51         {.reg = "FAR",          .offset = 1},
52         {.reg = "FDRI",         .offset = 2},
53         {.reg = "FDRO",         .offset = 3},
54         {.reg = "CMD",          .offset = 4},
55         {.reg = "CTRL0",        .offset = 5},
56         {.reg = "MASK",         .offset = 6},
57         {.reg = "STAT",         .offset = 7},
58         {.reg = "LOUT",         .offset = 8},
59         {.reg = "COR0",         .offset = 9},
60         {.reg = "MFWR",         .offset = 10},
61         {.reg = "CBC",          .offset = 11},
62         {.reg = "IDCODE",       .offset = 12},
63         {.reg = "AXSS",         .offset = 13},
64         {.reg = "COR1",         .offset = 14},
65         {.reg = "WBSTR",        .offset = 16},
66         {.reg = "TIMER",        .offset = 17},
67         {.reg = "BOOTSTS",      .offset = 22},
68         {.reg = "CTRL1",        .offset = 24},
69         {}
70 };
71
72 /**
73  * struct zynqmp_fpga_priv - Private data structure
74  * @dev:        Device data structure
75  * @lock:       Mutex lock for device
76  * @clk:        Clock resource for pcap controller
77  * @flags:      flags which is used to identify the bitfile type
78  * @size:       Size of the Bitstream used for readback
79  */
80 struct zynqmp_fpga_priv {
81         struct device *dev;
82         struct mutex lock;
83         struct clk *clk;
84         u32 flags;
85         u32 size;
86 };
87
88 static int zynqmp_fpga_ops_write_init(struct fpga_manager *mgr,
89                                       struct fpga_image_info *info,
90                                       const char *buf, size_t size)
91 {
92         struct zynqmp_fpga_priv *priv;
93
94         priv = mgr->priv;
95         priv->flags = info->flags;
96
97         return 0;
98 }
99
100 static int zynqmp_fpga_ops_write(struct fpga_manager *mgr,
101                                         const char *buf, size_t size)
102 {
103         struct zynqmp_fpga_priv *priv;
104         char *kbuf;
105         size_t dma_size;
106         dma_addr_t dma_addr;
107         int ret;
108         const struct zynqmp_eemi_ops *eemi_ops = zynqmp_pm_get_eemi_ops();
109
110         if (!eemi_ops || !eemi_ops->fpga_load)
111                 return -ENXIO;
112
113         priv = mgr->priv;
114         priv->size = size;
115
116         if (!mutex_trylock(&priv->lock))
117                 return -EBUSY;
118
119         ret = clk_enable(priv->clk);
120         if (ret)
121                 goto err_unlock;
122
123         if (mgr->flags & IXR_FPGA_ENCRYPTION_EN)
124                 dma_size = size + ENCRYPTED_KEY_LEN;
125         else
126                 dma_size = size;
127
128         kbuf = dma_alloc_coherent(priv->dev, dma_size, &dma_addr, GFP_KERNEL);
129         if (!kbuf) {
130                 ret = -ENOMEM;
131                 goto disable_clk;
132         }
133
134         memcpy(kbuf, buf, size);
135
136         if (mgr->flags & IXR_FPGA_ENCRYPTION_EN)
137                 memcpy(kbuf + size, mgr->key, ENCRYPTED_KEY_LEN);
138
139         wmb(); /* ensure all writes are done before initiate FW call */
140
141         if (mgr->flags & IXR_FPGA_ENCRYPTION_EN)
142                 ret = eemi_ops->fpga_load(dma_addr, dma_addr + size,
143                                                         mgr->flags);
144         else
145                 ret = eemi_ops->fpga_load(dma_addr, size,
146                                                 mgr->flags);
147
148         dma_free_coherent(priv->dev, dma_size, kbuf, dma_addr);
149 disable_clk:
150         clk_disable(priv->clk);
151 err_unlock:
152         mutex_unlock(&priv->lock);
153         return ret;
154 }
155
156 static int zynqmp_fpga_ops_write_complete(struct fpga_manager *mgr,
157                                           struct fpga_image_info *info)
158 {
159         return 0;
160 }
161
162 static enum fpga_mgr_states zynqmp_fpga_ops_state(struct fpga_manager *mgr)
163 {
164         u32 status;
165         const struct zynqmp_eemi_ops *eemi_ops = zynqmp_pm_get_eemi_ops();
166
167         if (!eemi_ops || !eemi_ops->fpga_get_status)
168                 return FPGA_MGR_STATE_UNKNOWN;
169
170         eemi_ops->fpga_get_status(&status);
171         if (status & IXR_FPGA_DONE_MASK)
172                 return FPGA_MGR_STATE_OPERATING;
173
174         return FPGA_MGR_STATE_UNKNOWN;
175 }
176
177 static int zynqmp_fpga_read_cfgreg(struct fpga_manager *mgr,
178                                    struct seq_file *s)
179 {
180         const struct zynqmp_eemi_ops *eemi_ops = zynqmp_pm_get_eemi_ops();
181         struct zynqmp_fpga_priv *priv = mgr->priv;
182         int ret, val;
183         unsigned int *buf;
184         dma_addr_t dma_addr;
185         struct zynqmp_configreg *p = cfgreg;
186
187         ret = clk_enable(priv->clk);
188         if (ret)
189                 return ret;
190
191         buf = dma_zalloc_coherent(mgr->dev.parent, READ_DMA_SIZE,
192                                   &dma_addr, GFP_KERNEL);
193         if (!buf) {
194                 ret = -ENOMEM;
195                 goto disable_clk;
196         }
197
198         seq_puts(s, "zynqMP FPGA Configuration register contents are\n");
199
200         while (p->reg) {
201                 ret = eemi_ops->fpga_read(p->offset, dma_addr, readback_type,
202                                           &val);
203                 if (ret)
204                         goto free_dmabuf;
205                 seq_printf(s, "%s --> \t %x \t\r\n", p->reg, val);
206                 p++;
207         }
208
209 free_dmabuf:
210         dma_free_coherent(mgr->dev.parent, READ_DMA_SIZE, buf,
211                           dma_addr);
212 disable_clk:
213         clk_disable(priv->clk);
214
215         return ret;
216 }
217
218 static int zynqmp_fpga_read_cfgdata(struct fpga_manager *mgr,
219                                     struct seq_file *s)
220 {
221         const struct zynqmp_eemi_ops *eemi_ops = zynqmp_pm_get_eemi_ops();
222         struct zynqmp_fpga_priv *priv;
223         int ret, data_offset;
224         unsigned int *buf;
225         dma_addr_t dma_addr;
226         size_t size;
227         int clk_rate;
228
229         priv = mgr->priv;
230         size = priv->size + READ_DMA_SIZE + DUMMY_FRAMES_SIZE;
231
232         /*
233          * There is no h/w flow control for pcap read
234          * to prevent the FIFO from over flowing, reduce
235          * the PCAP operating frequency.
236          */
237         clk_rate = clk_get_rate(priv->clk);
238         clk_unprepare(priv->clk);
239         ret = clk_set_rate(priv->clk, PCAP_READ_CLKFREQ);
240         if (ret) {
241                 dev_err(&mgr->dev, "Unable to reduce the PCAP freq %d\n", ret);
242                 goto prepare_clk;
243         }
244         ret = clk_prepare_enable(priv->clk);
245         if (ret) {
246                 dev_err(&mgr->dev, "Cannot enable clock.\n");
247                 goto restore_pcap_clk;
248         }
249
250         buf = dma_zalloc_coherent(mgr->dev.parent, size, &dma_addr,
251                                   GFP_KERNEL);
252         if (!buf) {
253                 ret = -ENOMEM;
254                 goto disable_clk;
255         }
256
257         seq_puts(s, "zynqMP FPGA Configuration data contents are\n");
258         ret = eemi_ops->fpga_read((priv->size + DUMMY_FRAMES_SIZE) / 4,
259                                   dma_addr, readback_type, &data_offset);
260         if (ret)
261                 goto free_dmabuf;
262
263         seq_write(s, &buf[data_offset], priv->size);
264
265 free_dmabuf:
266         dma_free_coherent(mgr->dev.parent, size, buf, dma_addr);
267 disable_clk:
268         clk_disable_unprepare(priv->clk);
269 restore_pcap_clk:
270         clk_set_rate(priv->clk, clk_rate);
271 prepare_clk:
272         clk_prepare(priv->clk);
273
274         return ret;
275 }
276
277 static int zynqmp_fpga_ops_read(struct fpga_manager *mgr, struct seq_file *s)
278 {
279         const struct zynqmp_eemi_ops *eemi_ops = zynqmp_pm_get_eemi_ops();
280         struct zynqmp_fpga_priv *priv = mgr->priv;
281         int ret;
282
283         if (!eemi_ops || !eemi_ops->fpga_read)
284                 return -ENXIO;
285
286         if (!mutex_trylock(&priv->lock))
287                 return -EBUSY;
288
289         if (readback_type)
290                 ret = zynqmp_fpga_read_cfgdata(mgr, s);
291         else
292                 ret = zynqmp_fpga_read_cfgreg(mgr, s);
293
294         mutex_unlock(&priv->lock);
295         return ret;
296 }
297
298 static const struct fpga_manager_ops zynqmp_fpga_ops = {
299         .state = zynqmp_fpga_ops_state,
300         .write_init = zynqmp_fpga_ops_write_init,
301         .write = zynqmp_fpga_ops_write,
302         .write_complete = zynqmp_fpga_ops_write_complete,
303         .read = zynqmp_fpga_ops_read,
304 };
305
306 static int zynqmp_fpga_probe(struct platform_device *pdev)
307 {
308         struct device *dev = &pdev->dev;
309         struct zynqmp_fpga_priv *priv;
310         int err, ret;
311
312         priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
313         if (!priv)
314                 return -ENOMEM;
315
316         priv->dev = dev;
317         mutex_init(&priv->lock);
318         ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(44));
319         if (ret < 0)
320                 dev_err(dev, "no usable DMA configuration");
321
322         priv->clk = devm_clk_get(dev, "ref_clk");
323         if (IS_ERR(priv->clk)) {
324                 ret = PTR_ERR(priv->clk);
325                 dev_err(dev, "failed to to get pcp ref_clk (%d)\n", ret);
326                 return ret;
327         }
328
329         ret = clk_prepare(priv->clk);
330         if (ret) {
331                 dev_err(dev, "Cannot enable clock.\n");
332                 return ret;
333         }
334
335         err = fpga_mgr_register(dev, "Xilinx ZynqMP FPGA Manager",
336                                 &zynqmp_fpga_ops, priv);
337         if (err) {
338                 dev_err(dev, "unable to register FPGA manager");
339                 clk_unprepare(priv->clk);
340                 return err;
341         }
342
343         return 0;
344 }
345
346 static int zynqmp_fpga_remove(struct platform_device *pdev)
347 {
348         struct zynqmp_fpga_priv *priv;
349         struct fpga_manager *mgr;
350
351         mgr = platform_get_drvdata(pdev);
352         priv = mgr->priv;
353
354         fpga_mgr_unregister(&pdev->dev);
355         clk_unprepare(priv->clk);
356
357         return 0;
358 }
359
360 static const struct of_device_id zynqmp_fpga_of_match[] = {
361         { .compatible = "xlnx,zynqmp-pcap-fpga", },
362         {},
363 };
364
365 MODULE_DEVICE_TABLE(of, zynqmp_fpga_of_match);
366
367 static struct platform_driver zynqmp_fpga_driver = {
368         .probe = zynqmp_fpga_probe,
369         .remove = zynqmp_fpga_remove,
370         .driver = {
371                 .name = "zynqmp_fpga_manager",
372                 .of_match_table = of_match_ptr(zynqmp_fpga_of_match),
373         },
374 };
375
376 module_platform_driver(zynqmp_fpga_driver);
377
378 MODULE_AUTHOR("Nava kishore Manne <navam@xilinx.com>");
379 MODULE_DESCRIPTION("Xilinx ZynqMp FPGA Manager");
380 MODULE_LICENSE("GPL");