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_write32(mem + OFFSET_REG_SINK_DATA, val)
43 #define READ_SINK_READY(mem) litex_read8(mem + OFFSET_REG_SINK_READY)
46 void __iomem
*membase
;
49 /* Helper functions */
51 static inline bool bit_has_sync(uint8_t *buf
, size_t count
)
55 for (i
= 0; i
< count
- BITSTREAM_INSTR_SIZE
; i
+= BITSTREAM_INSTR_SIZE
)
56 /* Sync word is 0xAA995566 */
65 static inline bool bit_is_aligned(uint8_t *buf
, size_t count
)
67 return !(count
% BITSTREAM_INSTR_SIZE
);
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");
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
;
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");
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");
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
]));
120 static int litex_fpga_write_complete(struct fpga_manager
*mgr
,
121 struct fpga_image_info
*info
)
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
);
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
;
156 fpga_s
= devm_kzalloc(&pdev
->dev
, sizeof(*fpga_s
), GFP_KERNEL
);
160 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
164 fpga_s
->membase
= devm_of_iomap(&pdev
->dev
, node
, 0, &res
->end
);
165 if (IS_ERR_OR_NULL(fpga_s
->membase
))
168 mgr
= devm_fpga_mgr_create(&pdev
->dev
,
169 "LiteX ICAPBitstream FPGA Manager",
170 &litex_fpga_manager_ops
, fpga_s
);
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
= {
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");