1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2019-2021 Xilinx, Inc.
6 #include <linux/dma-mapping.h>
7 #include <linux/fpga/fpga-mgr.h>
9 #include <linux/kernel.h>
10 #include <linux/module.h>
11 #include <linux/of_address.h>
12 #include <linux/string.h>
13 #include <linux/firmware/xlnx-zynqmp.h>
15 static int versal_fpga_ops_write_init(struct fpga_manager
*mgr
,
16 struct fpga_image_info
*info
,
17 const char *buf
, size_t size
)
22 static int versal_fpga_ops_write(struct fpga_manager
*mgr
,
23 const char *buf
, size_t size
)
25 dma_addr_t dma_addr
= 0;
29 kbuf
= dma_alloc_coherent(mgr
->dev
.parent
, size
, &dma_addr
, GFP_KERNEL
);
33 memcpy(kbuf
, buf
, size
);
34 ret
= zynqmp_pm_load_pdi(PDI_SRC_DDR
, dma_addr
);
35 dma_free_coherent(mgr
->dev
.parent
, size
, kbuf
, dma_addr
);
40 static const struct fpga_manager_ops versal_fpga_ops
= {
41 .write_init
= versal_fpga_ops_write_init
,
42 .write
= versal_fpga_ops_write
,
45 static int versal_fpga_probe(struct platform_device
*pdev
)
47 struct device
*dev
= &pdev
->dev
;
48 struct fpga_manager
*mgr
;
51 ret
= dma_set_mask_and_coherent(&pdev
->dev
, DMA_BIT_MASK(44));
53 dev_err(dev
, "no usable DMA configuration\n");
57 mgr
= devm_fpga_mgr_register(dev
, "Xilinx Versal FPGA Manager",
58 &versal_fpga_ops
, NULL
);
59 return PTR_ERR_OR_ZERO(mgr
);
62 static const struct of_device_id versal_fpga_of_match
[] = {
63 { .compatible
= "xlnx,versal-fpga", },
66 MODULE_DEVICE_TABLE(of
, versal_fpga_of_match
);
68 static struct platform_driver versal_fpga_driver
= {
69 .probe
= versal_fpga_probe
,
71 .name
= "versal_fpga_manager",
72 .of_match_table
= of_match_ptr(versal_fpga_of_match
),
75 module_platform_driver(versal_fpga_driver
);
77 MODULE_AUTHOR("Nava kishore Manne <nava.manne@xilinx.com>");
78 MODULE_AUTHOR("Appana Durga Kedareswara rao <appanad.durga.rao@xilinx.com>");
79 MODULE_DESCRIPTION("Xilinx Versal FPGA Manager");
80 MODULE_LICENSE("GPL");