1 // SPDX-License-Identifier: GPL-2.0
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>
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, \
48 void __iomem
*membase
;
51 /* Helper functions */
53 static inline bool bit_has_sync(uint8_t *buf
, size_t count
)
57 for (i
= 0; i
< count
- BITSTREAM_INSTR_SIZE
; i
+= BITSTREAM_INSTR_SIZE
)
58 /* Sync word is 0xAA995566 */
67 static inline bool bit_is_aligned(uint8_t *buf
, size_t count
)
69 return !(count
% BITSTREAM_INSTR_SIZE
);
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");
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
;
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");
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");
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
]));
122 static int litex_fpga_write_complete(struct fpga_manager
*mgr
,
123 struct fpga_image_info
*info
)
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
);
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
;
158 fpga_s
= devm_kzalloc(&pdev
->dev
, sizeof(*fpga_s
), GFP_KERNEL
);
162 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
166 fpga_s
->membase
= devm_of_iomap(&pdev
->dev
, node
, 0, &res
->end
);
167 if (IS_ERR_OR_NULL(fpga_s
->membase
))
170 mgr
= devm_fpga_mgr_create(&pdev
->dev
,
171 "LiteX ICAPBitstream FPGA Manager",
172 &litex_fpga_manager_ops
, fpga_s
);
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
= {
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");