2 * Copyright (C) 2016 Xilinx, Inc.
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.
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.
15 #include <asm/cacheflush.h>
16 #include <linux/dma-mapping.h>
17 #include <linux/fpga/fpga-mgr.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/soc/xilinx/zynqmp/firmware.h>
25 /* Constant Definitions */
26 #define IXR_FPGA_DONE_MASK 0X00000008U
27 #define IXR_FPGA_AUTHENTICATIN 0x00000004U
28 #define IXR_FPGA_ENCRYPTION_EN 0x00000008U
30 struct zynqmp_fpga_priv {
35 static int zynqmp_fpga_ops_write_init(struct fpga_manager *mgr,
36 struct fpga_image_info *info,
37 const char *buf, size_t size)
39 struct zynqmp_fpga_priv *priv;
42 priv->flags = info->flags;
47 static int zynqmp_fpga_ops_write(struct fpga_manager *mgr,
48 const char *buf, size_t size)
50 struct zynqmp_fpga_priv *priv;
52 size_t dma_size = size;
59 if (mgr->flags & IXR_FPGA_AUTHENTICATIN)
60 dma_size = dma_size + SIGNATURE_LEN + PUBLIC_KEY_LEN;
61 if (mgr->flags & IXR_FPGA_ENCRYPTION_EN)
62 dma_size = dma_size + ENCRYPTED_KEY_LEN + ENCRYPTED_IV_LEN;
64 kbuf = dma_alloc_coherent(priv->dev, dma_size, &dma_addr, GFP_KERNEL);
68 memcpy(kbuf, buf, size);
70 if (mgr->flags & IXR_FPGA_AUTHENTICATIN) {
71 memcpy(kbuf + size, mgr->signature, SIGNATURE_LEN);
72 memcpy(kbuf + size + SIGNATURE_LEN, mgr->pubkey,
75 if (mgr->flags & IXR_FPGA_ENCRYPTION_EN) {
76 memcpy(kbuf + size, mgr->key, ENCRYPTED_KEY_LEN);
77 memcpy(kbuf + size + ENCRYPTED_KEY_LEN, mgr->iv,
81 __flush_cache_user_range((unsigned long)kbuf,
82 (unsigned long)kbuf + dma_size);
85 * Translate size from bytes to number of 32bit words that
86 * the DMA should write to the PCAP interface
89 transfer_length = (size >> 2) + 1;
91 transfer_length = size >> 2;
93 ret = zynqmp_pm_fpga_load(dma_addr, transfer_length, mgr->flags);
95 dma_free_coherent(priv->dev, dma_size, kbuf, dma_addr);
100 static int zynqmp_fpga_ops_write_complete(struct fpga_manager *mgr,
101 struct fpga_image_info *info)
106 static enum fpga_mgr_states zynqmp_fpga_ops_state(struct fpga_manager *mgr)
110 zynqmp_pm_fpga_get_status(&status);
111 if (status & IXR_FPGA_DONE_MASK)
112 return FPGA_MGR_STATE_OPERATING;
114 return FPGA_MGR_STATE_UNKNOWN;
117 static const struct fpga_manager_ops zynqmp_fpga_ops = {
118 .state = zynqmp_fpga_ops_state,
119 .write_init = zynqmp_fpga_ops_write_init,
120 .write = zynqmp_fpga_ops_write,
121 .write_complete = zynqmp_fpga_ops_write_complete,
124 static int zynqmp_fpga_probe(struct platform_device *pdev)
126 struct device *dev = &pdev->dev;
127 struct zynqmp_fpga_priv *priv;
130 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
135 ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(44));
137 dev_err(dev, "no usable DMA configuration");
139 err = fpga_mgr_register(dev, "Xilinx ZynqMP FPGA Manager",
140 &zynqmp_fpga_ops, priv);
142 dev_err(dev, "unable to register FPGA manager");
149 static int zynqmp_fpga_remove(struct platform_device *pdev)
152 fpga_mgr_unregister(&pdev->dev);
157 static const struct of_device_id zynqmp_fpga_of_match[] = {
158 { .compatible = "xlnx,zynqmp-pcap-fpga", },
162 MODULE_DEVICE_TABLE(of, zynqmp_fpga_of_match);
164 static struct platform_driver zynqmp_fpga_driver = {
165 .probe = zynqmp_fpga_probe,
166 .remove = zynqmp_fpga_remove,
168 .name = "zynqmp_fpga_manager",
169 .of_match_table = of_match_ptr(zynqmp_fpga_of_match),
173 module_platform_driver(zynqmp_fpga_driver);
175 MODULE_AUTHOR("Nava kishore Manne <navam@xilinx.com>");
176 MODULE_DESCRIPTION("Xilinx ZynqMp FPGA Manager");
177 MODULE_LICENSE("GPL");