1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2019-2021 Xilinx, Inc. 4 */ 5 6 #include <linux/dma-mapping.h> 7 #include <linux/fpga/fpga-mgr.h> 8 #include <linux/io.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> 14 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) 18 { 19 return 0; 20 } 21 22 static int versal_fpga_ops_write(struct fpga_manager *mgr, 23 const char *buf, size_t size) 24 { 25 dma_addr_t dma_addr = 0; 26 char *kbuf; 27 int ret; 28 29 kbuf = dma_alloc_coherent(mgr->dev.parent, size, &dma_addr, GFP_KERNEL); 30 if (!kbuf) 31 return -ENOMEM; 32 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); 36 37 return ret; 38 } 39 40 static int versal_fpga_ops_write_complete(struct fpga_manager *mgr, 41 struct fpga_image_info *info) 42 { 43 return 0; 44 } 45 46 static enum fpga_mgr_states versal_fpga_ops_state(struct fpga_manager *mgr) 47 { 48 return FPGA_MGR_STATE_UNKNOWN; 49 } 50 51 static const struct fpga_manager_ops versal_fpga_ops = { 52 .state = versal_fpga_ops_state, 53 .write_init = versal_fpga_ops_write_init, 54 .write = versal_fpga_ops_write, 55 .write_complete = versal_fpga_ops_write_complete, 56 }; 57 58 static int versal_fpga_probe(struct platform_device *pdev) 59 { 60 struct device *dev = &pdev->dev; 61 struct fpga_manager *mgr; 62 int ret; 63 64 ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); 65 if (ret < 0) { 66 dev_err(dev, "no usable DMA configuration\n"); 67 return ret; 68 } 69 70 mgr = devm_fpga_mgr_create(dev, "Xilinx Versal FPGA Manager", 71 &versal_fpga_ops, NULL); 72 if (!mgr) 73 return -ENOMEM; 74 75 return devm_fpga_mgr_register(dev, mgr); 76 } 77 78 static const struct of_device_id versal_fpga_of_match[] = { 79 { .compatible = "xlnx,versal-fpga", }, 80 {}, 81 }; 82 MODULE_DEVICE_TABLE(of, versal_fpga_of_match); 83 84 static struct platform_driver versal_fpga_driver = { 85 .probe = versal_fpga_probe, 86 .driver = { 87 .name = "versal_fpga_manager", 88 .of_match_table = of_match_ptr(versal_fpga_of_match), 89 }, 90 }; 91 module_platform_driver(versal_fpga_driver); 92 93 MODULE_AUTHOR("Nava kishore Manne <nava.manne@xilinx.com>"); 94 MODULE_AUTHOR("Appana Durga Kedareswara rao <appanad.durga.rao@xilinx.com>"); 95 MODULE_DESCRIPTION("Xilinx Versal FPGA Manager"); 96 MODULE_LICENSE("GPL"); 97