WIP FPC-III support
[linux/fpc-iii.git] / drivers / fpga / litex-fpga.c
blobc3a4f38a6610e7765a1ade74b62ddc2a9ee18998
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_write32(mem + OFFSET_REG_SINK_DATA, val)
43 #define READ_SINK_READY(mem) litex_read8(mem + OFFSET_REG_SINK_READY)
45 struct litex_fpga {
46 void __iomem *membase;
49 /* Helper functions */
51 static inline bool bit_has_sync(uint8_t *buf, size_t count)
53 int i;
55 for (i = 0; i < count - BITSTREAM_INSTR_SIZE; i += BITSTREAM_INSTR_SIZE)
56 /* Sync word is 0xAA995566 */
57 if (buf[i] == 0xAA &&
58 buf[i + 1] == 0x99 &&
59 buf[i + 2] == 0x55 &&
60 buf[i + 3] == 0x66)
61 return true;
62 return false;
65 static inline bool bit_is_aligned(uint8_t *buf, size_t count)
67 return !(count % BITSTREAM_INSTR_SIZE);
70 /* API functions */
72 static enum fpga_mgr_states litex_fpga_state(struct fpga_manager *mgr)
74 return FPGA_MGR_STATE_UNKNOWN;
77 static int litex_fpga_write_init(struct fpga_manager *mgr,
78 struct fpga_image_info *info,
79 const char *buf, size_t count)
81 /* Check if driver supports given operations */
82 if (info->flags & ~ALLOWED_FPGA_MGR_FLAGS) {
83 dev_err(&mgr->dev, "Unsupported bitstream flags occurred\n");
84 return -EINVAL;
87 return 0;
90 static int litex_fpga_write(struct fpga_manager *mgr,
91 const char *buf, size_t count)
93 const struct litex_fpga *fpga_s = (const struct litex_fpga *) mgr->priv;
94 uint32_t *buf32;
95 int i, count32;
97 /* Bitstream should consist of 32bit words*/
98 if (!bit_is_aligned((uint8_t *) buf, count)) {
99 dev_err(&mgr->dev, "Invalid bitstream alignment\n");
100 return -EINVAL;
103 /* Correct bitstream contains sync word */
104 if (!bit_has_sync((uint8_t *) buf, count)) {
105 dev_err(&mgr->dev, "Bitstream has no sync word\n");
106 return -EINVAL;
109 buf32 = (uint32_t *) buf;
110 count32 = count / BITSTREAM_INSTR_SIZE;
111 for (i = 0; i < count32; ++i) {
112 while (!READ_SINK_READY(fpga_s->membase))
114 WRITE_SINK_DATA(fpga_s->membase, be32_to_cpu(buf32[i]));
117 return 0;
120 static int litex_fpga_write_complete(struct fpga_manager *mgr,
121 struct fpga_image_info *info)
123 return 0;
126 static const struct fpga_manager_ops litex_fpga_manager_ops = {
127 .initial_header_size = INITIAL_HEADER_SIZE,
128 .state = litex_fpga_state,
129 .write_init = litex_fpga_write_init,
130 .write = litex_fpga_write,
131 .write_complete = litex_fpga_write_complete,
134 /* Driver functions */
136 static int litex_fpga_remove(struct platform_device *pdev)
138 struct fpga_manager *mgr;
140 mgr = platform_get_drvdata(pdev);
141 fpga_mgr_unregister(mgr);
143 return 0;
146 static int litex_fpga_probe(struct platform_device *pdev)
148 struct device_node *node = pdev->dev.of_node;
149 struct litex_fpga *fpga_s;
150 struct fpga_manager *mgr;
151 struct resource *res;
153 if (!node)
154 return -ENODEV;
156 fpga_s = devm_kzalloc(&pdev->dev, sizeof(*fpga_s), GFP_KERNEL);
157 if (!fpga_s)
158 return -ENOMEM;
160 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
161 if (!res)
162 return -EBUSY;
164 fpga_s->membase = devm_of_iomap(&pdev->dev, node, 0, &res->end);
165 if (IS_ERR_OR_NULL(fpga_s->membase))
166 return -EIO;
168 mgr = devm_fpga_mgr_create(&pdev->dev,
169 "LiteX ICAPBitstream FPGA Manager",
170 &litex_fpga_manager_ops, fpga_s);
171 if (!mgr)
172 return -ENOMEM;
174 platform_set_drvdata(pdev, mgr);
175 return fpga_mgr_register(mgr);
178 static const struct of_device_id litex_of_match[] = {
179 {.compatible = "litex,fpga-icap"},
183 MODULE_DEVICE_TABLE(of, litex_of_match);
185 static struct platform_driver litex_fpga_driver = {
186 .driver = {
187 .name = "litex-icap-fpga-mgr",
188 .of_match_table = of_match_ptr(litex_of_match)
190 .probe = litex_fpga_probe,
191 .remove = litex_fpga_remove
194 module_platform_driver(litex_fpga_driver);
196 MODULE_DESCRIPTION("LiteX ICAPBitstream FPGA Manager driver");
197 MODULE_AUTHOR("Antmicro <www.antmicro.com>");
198 MODULE_LICENSE("GPL v2");