Hi Mortiz, Thanks for proving the comments. Please find my response inline. > -----Original Message----- > From: Moritz Fischer [mailto:mdf@xxxxxxxxxx] > Sent: Thursday, April 23, 2020 8:59 AM > To: Nava kishore Manne <navam@xxxxxxxxxx> > Cc: mdf@xxxxxxxxxx; Michal Simek <michals@xxxxxxxxxx>; linux- > fpga@xxxxxxxxxxxxxxx; linux-arm-kernel@xxxxxxxxxxxxxxxxxxx; linux- > kernel@xxxxxxxxxxxxxxx; chinnikishore369@xxxxxxxxx > Subject: Re: [PATCH 2/2] fpga: zynq: Add AFI config driver > > Hi Nava, > > On Wed, Apr 15, 2020 at 03:54:50PM +0530, Nava kishore Manne wrote: > > This patch Adds AFI config driver. This is useful for the PS to PL > > configuration for the fpga manager On zynq platform. > > > > Signed-off-by: Nava kishore Manne <nava.manne@xxxxxxxxxx> > > --- > > drivers/fpga/Kconfig | 8 +++++ > > drivers/fpga/Makefile | 1 + > > drivers/fpga/zynq-afi.c | 81 > > +++++++++++++++++++++++++++++++++++++++++++++++++ > > 3 files changed, 90 insertions(+) > > create mode 100644 drivers/fpga/zynq-afi.c > > > > diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig index > > 474f304e..60982a0 100644 > > --- a/drivers/fpga/Kconfig > > +++ b/drivers/fpga/Kconfig > > @@ -214,4 +214,12 @@ config FPGA_MGR_ZYNQMP_FPGA > > to configure the programmable logic(PL) through PS > > on ZynqMP SoC. > > > > +config FPGA_MGR_ZYNQ_AFI_FPGA > > + bool "Xilinx AFI FPGA" > > + depends on FPGA_MGR_ZYNQ_FPGA > Curious. How does this dependency play in here? > > + help > > + Zynq AFI driver support for writing to the AFI registers > > + for configuring the PS_PL interface. For some of the bitstream > > + or designs to work the PS to PL interfaces need to be configured > > + like the data bus-width etc. > > endif # FPGA > > diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile index > > 312b937..d115e29 100644 > > --- a/drivers/fpga/Makefile > > +++ b/drivers/fpga/Makefile > > @@ -26,6 +26,7 @@ obj-$(CONFIG_FPGA_BRIDGE) += fpga- > bridge.o > > obj-$(CONFIG_SOCFPGA_FPGA_BRIDGE) += altera-hps2fpga.o altera- > fpga2sdram.o > > obj-$(CONFIG_ALTERA_FREEZE_BRIDGE) += altera-freeze-bridge.o > > obj-$(CONFIG_XILINX_PR_DECOUPLER) += xilinx-pr-decoupler.o > > +obj-$(CONFIG_FPGA_MGR_ZYNQ_AFI_FPGA) += zynq-afi.o > > > > # High Level Interfaces > > obj-$(CONFIG_FPGA_REGION) += fpga-region.o > > diff --git a/drivers/fpga/zynq-afi.c b/drivers/fpga/zynq-afi.c new > > file mode 100644 index 0000000..7ce0d08 > > --- /dev/null > > +++ b/drivers/fpga/zynq-afi.c > > @@ -0,0 +1,81 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +/* > > + * Xilinx FPGA AFI driver. > > + * Copyright (c) 2018 Xilinx Inc. > > + */ > > + > > +#include <linux/err.h> > > +#include <linux/io.h> > > +#include <linux/module.h> > > +#include <linux/of.h> > > +#include <linux/platform_device.h> > > + > > +/* Registers and special values for doing register-based operations */ > > +#define AFI_RDCHAN_CTRL_OFFSET 0x00 > > +#define AFI_WRCHAN_CTRL_OFFSET 0x14 > > + > > +#define AFI_BUSWIDTH_MASK 0x01 > > + > > +/** > > + * struct afi_fpga - AFI register description > > + * @membase: pointer to register struct > > + * @afi_width: AFI bus width to be written > > + */ > > +struct zynq_afi_fpga { > > + void __iomem *membase; > > + u32 afi_width; > > +}; > > + > > +static int zynq_afi_fpga_probe(struct platform_device *pdev) { > > + struct zynq_afi_fpga *afi_fpga; > > + struct resource *res; > > + u32 reg_val; > > + u32 val; > > + > > + afi_fpga = devm_kzalloc(&pdev->dev, sizeof(*afi_fpga), GFP_KERNEL); > > + if (!afi_fpga) > > + return -ENOMEM; > > + > > + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); > > + afi_fpga->membase = devm_ioremap_resource(&pdev->dev, res); > > + if (IS_ERR(afi_fpga->membase)) > > + return PTR_ERR(afi_fpga->membase); > > + > > + val = device_property_read_u32(&pdev->dev, "xlnx,afi-width", > > + &afi_fpga->afi_width); > > + if (val) { > > + dev_err(&pdev->dev, "Fail to get the afi bus width\n"); > > + return -EINVAL; > > + } > > + > > + reg_val = readl(afi_fpga->membase + AFI_RDCHAN_CTRL_OFFSET); > > + reg_val &= ~AFI_BUSWIDTH_MASK; > > + writel(reg_val | afi_fpga->afi_width, > > + afi_fpga->membase + AFI_RDCHAN_CTRL_OFFSET); > > + reg_val = readl(afi_fpga->membase + AFI_WRCHAN_CTRL_OFFSET); > > + reg_val &= ~AFI_BUSWIDTH_MASK; > > + writel(reg_val | afi_fpga->afi_width, > > + afi_fpga->membase + AFI_WRCHAN_CTRL_OFFSET); > > + > > + return 0; > > +} > > + > > +static const struct of_device_id zynq_afi_fpga_ids[] = { > > + { .compatible = "xlnx,zynq-afi-fpga" }, > > + { }, > > +}; > > +MODULE_DEVICE_TABLE(of, zynq_afi_fpga_ids); > > + > > +static struct platform_driver zynq_afi_fpga_driver = { > > + .driver = { > > + .name = "zynq-afi-fpga", > > + .of_match_table = zynq_afi_fpga_ids, > > + }, > > + .probe = zynq_afi_fpga_probe, > > +}; > > +module_platform_driver(zynq_afi_fpga_driver); > > + > > +MODULE_DESCRIPTION("ZYNQ FPGA AFI module"); > MODULE_AUTHOR("Nava > > +kishore Manne <nava.manne@xxxxxxxxxx>"); MODULE_LICENSE("GPL v2"); > > -- > > 2.7.4 > > > > It looks like all the driver does is writing two registers? How does > that fit into FPGA Manager as a framework. Should this maybe be eithe > for Zynq architecture or a Misc driver instead? > To establish the proper communication channel between PS and PL, The AXI Interface Bus Width should be configured properly. For a design to design this AXI Interface Bus Width settings are vary. So for Zynq just loading the Bitstream into the PL is not sufficient to establish a proper communication channel between PS and PL we have to do AXI Interface Bus Width settings as per the design after loading the Bit file into the PL. I feel this is more relevant to the FPGA settings so I have placed this driver here. Please suggest the best place to put this driver. > Is the idea here to create the device via an overlay? Yes, this driver loading/removal is triggered by the overlay after loading the bit file into the PL. Regards, Navakishore.