LiteX: driver for ICAPBitstream fpga manager
[linux/fpc-iii.git] / drivers / fpga / litex-fpga.c
blob1b3cbc54323107d3eb45914aefa7d927d7f4d7af
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (C) 2019 Antmicro <www.antmicro.com>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2
7 * as published by the Free Software Foundation.
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.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include <linux/module.h>
20 #include <linux/platform_device.h>
21 #include <linux/fpga/fpga-mgr.h>
22 #include <linux/of.h>
23 #include <linux/bits.h>
24 #include <linux/types.h>
25 #include <linux/kconfig.h>
26 #include <linux/litex.h>
27 #include <asm/byteorder.h>
29 #define OFFSET_REG_SINK_DATA 0x0
30 #define OFFSET_REG_SINK_READY 0x10
32 #define REG_SINK_DATA_SIZE 0x4
33 #define REG_SINK_READY_SIZE 0x1
35 #define INITIAL_HEADER_SIZE -1 /* Set to maximum value */
36 #define ALLOWED_FPGA_MGR_FLAGS (FPGA_MGR_PARTIAL_RECONFIG | \
37 FPGA_MGR_COMPRESSED_BITSTREAM)
38 #define BITSTREAM_INSTR_SIZE sizeof(uint32_t)
40 /* Macros for accessing ICAP registers */
42 #define WRITE_SINK_DATA(mem, val) litex_set_reg(mem + OFFSET_REG_SINK_DATA, \
43 REG_SINK_DATA_SIZE, val)
44 #define READ_SINK_READY(mem) litex_get_reg(mem + OFFSET_REG_SINK_READY, \
45 REG_SINK_READY_SIZE)
47 struct litex_fpga {
48 void __iomem *membase;
51 /* Helper functions */
53 static inline bool bit_has_sync(uint8_t *buf, size_t count)
55 int i;
57 for (i = 0; i < count - BITSTREAM_INSTR_SIZE; i += BITSTREAM_INSTR_SIZE)
58 /* Sync word is 0xAA995566 */
59 if (buf[i] == 0xAA &&
60 buf[i + 1] == 0x99 &&
61 buf[i + 2] == 0x55 &&
62 buf[i + 3] == 0x66)
63 return true;
64 return false;
67 static inline bool bit_is_aligned(uint8_t *buf, size_t count)
69 return !(count % BITSTREAM_INSTR_SIZE);
72 /* API functions */
74 static enum fpga_mgr_states litex_fpga_state(struct fpga_manager *mgr)
76 return FPGA_MGR_STATE_UNKNOWN;
79 static int litex_fpga_write_init(struct fpga_manager *mgr,
80 struct fpga_image_info *info,
81 const char *buf, size_t count)
83 /* Check if driver supports given operations */
84 if (info->flags & ~ALLOWED_FPGA_MGR_FLAGS) {
85 dev_err(&mgr->dev, "Unsupported bitstream flags occurred\n");
86 return -EINVAL;
89 return 0;
92 static int litex_fpga_write(struct fpga_manager *mgr,
93 const char *buf, size_t count)
95 const struct litex_fpga *fpga_s = (const struct litex_fpga *) mgr->priv;
96 uint32_t *buf32;
97 int i, count32;
99 /* Bitstream should consist of 32bit words*/
100 if (!bit_is_aligned((uint8_t *) buf, count)) {
101 dev_err(&mgr->dev, "Invalid bitstream alignment\n");
102 return -EINVAL;
105 /* Correct bitstream contains sync word */
106 if (!bit_has_sync((uint8_t *) buf, count)) {
107 dev_err(&mgr->dev, "Bitstream has no sync word\n");
108 return -EINVAL;
111 buf32 = (uint32_t *) buf;
112 count32 = count / BITSTREAM_INSTR_SIZE;
113 for (i = 0; i < count32; ++i) {
114 while (!READ_SINK_READY(fpga_s->membase))
116 WRITE_SINK_DATA(fpga_s->membase, be32_to_cpu(buf32[i]));
119 return 0;
122 static int litex_fpga_write_complete(struct fpga_manager *mgr,
123 struct fpga_image_info *info)
125 return 0;
128 static const struct fpga_manager_ops litex_fpga_manager_ops = {
129 .initial_header_size = INITIAL_HEADER_SIZE,
130 .state = litex_fpga_state,
131 .write_init = litex_fpga_write_init,
132 .write = litex_fpga_write,
133 .write_complete = litex_fpga_write_complete,
136 /* Driver functions */
138 static int litex_fpga_remove(struct platform_device *pdev)
140 struct fpga_manager *mgr;
142 mgr = platform_get_drvdata(pdev);
143 fpga_mgr_unregister(mgr);
145 return 0;
148 static int litex_fpga_probe(struct platform_device *pdev)
150 struct device_node *node = pdev->dev.of_node;
151 struct litex_fpga *fpga_s;
152 struct fpga_manager *mgr;
153 struct resource *res;
155 if (!node)
156 return -ENODEV;
158 fpga_s = devm_kzalloc(&pdev->dev, sizeof(*fpga_s), GFP_KERNEL);
159 if (!fpga_s)
160 return -ENOMEM;
162 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
163 if (!res)
164 return -EBUSY;
166 fpga_s->membase = devm_of_iomap(&pdev->dev, node, 0, &res->end);
167 if (IS_ERR_OR_NULL(fpga_s->membase))
168 return -EIO;
170 mgr = devm_fpga_mgr_create(&pdev->dev,
171 "LiteX ICAPBitstream FPGA Manager",
172 &litex_fpga_manager_ops, fpga_s);
173 if (!mgr)
174 return -ENOMEM;
176 platform_set_drvdata(pdev, mgr);
177 return fpga_mgr_register(mgr);
180 static const struct of_device_id litex_of_match[] = {
181 {.compatible = "litex,fpga-icap"},
185 MODULE_DEVICE_TABLE(of, litex_of_match);
187 static struct platform_driver litex_fpga_driver = {
188 .driver = {
189 .name = "litex-icap-fpga-mgr",
190 .of_match_table = of_match_ptr(litex_of_match)
192 .probe = litex_fpga_probe,
193 .remove = litex_fpga_remove
196 module_platform_driver(litex_fpga_driver);
198 MODULE_DESCRIPTION("LiteX ICAPBitstream FPGA Manager driver");
199 MODULE_AUTHOR("Antmicro <www.antmicro.com>");
200 MODULE_LICENSE("GPL v2");