xref: /linux/drivers/fpga/zynq-fpga.c (revision 1930c2865108d5510d9013aaced3c12be5f413f6)
137784706SMoritz Fischer /*
237784706SMoritz Fischer  * Copyright (c) 2011-2015 Xilinx Inc.
337784706SMoritz Fischer  * Copyright (c) 2015, National Instruments Corp.
437784706SMoritz Fischer  *
537784706SMoritz Fischer  * FPGA Manager Driver for Xilinx Zynq, heavily based on xdevcfg driver
637784706SMoritz Fischer  * in their vendor tree.
737784706SMoritz Fischer  *
837784706SMoritz Fischer  * This program is free software; you can redistribute it and/or modify
937784706SMoritz Fischer  * it under the terms of the GNU General Public License as published by
1037784706SMoritz Fischer  * the Free Software Foundation; version 2 of the License.
1137784706SMoritz Fischer  *
1237784706SMoritz Fischer  * This program is distributed in the hope that it will be useful,
1337784706SMoritz Fischer  * but WITHOUT ANY WARRANTY; without even the implied warranty of
1437784706SMoritz Fischer  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1537784706SMoritz Fischer  * GNU General Public License for more details.
1637784706SMoritz Fischer  */
1737784706SMoritz Fischer 
1837784706SMoritz Fischer #include <linux/clk.h>
1937784706SMoritz Fischer #include <linux/completion.h>
2037784706SMoritz Fischer #include <linux/delay.h>
2137784706SMoritz Fischer #include <linux/dma-mapping.h>
2237784706SMoritz Fischer #include <linux/fpga/fpga-mgr.h>
2337784706SMoritz Fischer #include <linux/interrupt.h>
2437784706SMoritz Fischer #include <linux/io.h>
2537784706SMoritz Fischer #include <linux/iopoll.h>
2637784706SMoritz Fischer #include <linux/module.h>
2737784706SMoritz Fischer #include <linux/mfd/syscon.h>
2837784706SMoritz Fischer #include <linux/of_address.h>
2937784706SMoritz Fischer #include <linux/of_irq.h>
3037784706SMoritz Fischer #include <linux/pm.h>
3137784706SMoritz Fischer #include <linux/regmap.h>
3237784706SMoritz Fischer #include <linux/string.h>
3337784706SMoritz Fischer 
3437784706SMoritz Fischer /* Offsets into SLCR regmap */
3537784706SMoritz Fischer 
3637784706SMoritz Fischer /* FPGA Software Reset Control */
3737784706SMoritz Fischer #define SLCR_FPGA_RST_CTRL_OFFSET	0x240
3837784706SMoritz Fischer /* Level Shifters Enable */
3937784706SMoritz Fischer #define SLCR_LVL_SHFTR_EN_OFFSET	0x900
4037784706SMoritz Fischer 
4137784706SMoritz Fischer /* Constant Definitions */
4237784706SMoritz Fischer 
4337784706SMoritz Fischer /* Control Register */
4437784706SMoritz Fischer #define CTRL_OFFSET			0x00
4537784706SMoritz Fischer /* Lock Register */
4637784706SMoritz Fischer #define LOCK_OFFSET			0x04
4737784706SMoritz Fischer /* Interrupt Status Register */
4837784706SMoritz Fischer #define INT_STS_OFFSET			0x0c
4937784706SMoritz Fischer /* Interrupt Mask Register */
5037784706SMoritz Fischer #define INT_MASK_OFFSET			0x10
5137784706SMoritz Fischer /* Status Register */
5237784706SMoritz Fischer #define STATUS_OFFSET			0x14
5337784706SMoritz Fischer /* DMA Source Address Register */
5437784706SMoritz Fischer #define DMA_SRC_ADDR_OFFSET		0x18
5537784706SMoritz Fischer /* DMA Destination Address Reg */
5637784706SMoritz Fischer #define DMA_DST_ADDR_OFFSET		0x1c
5737784706SMoritz Fischer /* DMA Source Transfer Length */
5837784706SMoritz Fischer #define DMA_SRC_LEN_OFFSET		0x20
5937784706SMoritz Fischer /* DMA Destination Transfer */
6037784706SMoritz Fischer #define DMA_DEST_LEN_OFFSET		0x24
6137784706SMoritz Fischer /* Unlock Register */
6237784706SMoritz Fischer #define UNLOCK_OFFSET			0x34
6337784706SMoritz Fischer /* Misc. Control Register */
6437784706SMoritz Fischer #define MCTRL_OFFSET			0x80
6537784706SMoritz Fischer 
6637784706SMoritz Fischer /* Control Register Bit definitions */
6737784706SMoritz Fischer 
6837784706SMoritz Fischer /* Signal to reset FPGA */
6937784706SMoritz Fischer #define CTRL_PCFG_PROG_B_MASK		BIT(30)
7037784706SMoritz Fischer /* Enable PCAP for PR */
7137784706SMoritz Fischer #define CTRL_PCAP_PR_MASK		BIT(27)
7237784706SMoritz Fischer /* Enable PCAP */
7337784706SMoritz Fischer #define CTRL_PCAP_MODE_MASK		BIT(26)
7437784706SMoritz Fischer 
7537784706SMoritz Fischer /* Miscellaneous Control Register bit definitions */
7637784706SMoritz Fischer /* Internal PCAP loopback */
7737784706SMoritz Fischer #define MCTRL_PCAP_LPBK_MASK		BIT(4)
7837784706SMoritz Fischer 
7937784706SMoritz Fischer /* Status register bit definitions */
8037784706SMoritz Fischer 
8137784706SMoritz Fischer /* FPGA init status */
8237784706SMoritz Fischer #define STATUS_DMA_Q_F			BIT(31)
8337784706SMoritz Fischer #define STATUS_PCFG_INIT_MASK		BIT(4)
8437784706SMoritz Fischer 
8537784706SMoritz Fischer /* Interrupt Status/Mask Register Bit definitions */
8637784706SMoritz Fischer /* DMA command done */
8737784706SMoritz Fischer #define IXR_DMA_DONE_MASK		BIT(13)
8837784706SMoritz Fischer /* DMA and PCAP cmd done */
8937784706SMoritz Fischer #define IXR_D_P_DONE_MASK		BIT(12)
9037784706SMoritz Fischer  /* FPGA programmed */
9137784706SMoritz Fischer #define IXR_PCFG_DONE_MASK		BIT(2)
9237784706SMoritz Fischer #define IXR_ERROR_FLAGS_MASK		0x00F0F860
9337784706SMoritz Fischer #define IXR_ALL_MASK			0xF8F7F87F
9437784706SMoritz Fischer 
9537784706SMoritz Fischer /* Miscellaneous constant values */
9637784706SMoritz Fischer 
9737784706SMoritz Fischer /* Invalid DMA addr */
9837784706SMoritz Fischer #define DMA_INVALID_ADDRESS		GENMASK(31, 0)
9937784706SMoritz Fischer /* Used to unlock the dev */
10037784706SMoritz Fischer #define UNLOCK_MASK			0x757bdf0d
10137784706SMoritz Fischer /* Timeout for DMA to complete */
10237784706SMoritz Fischer #define DMA_DONE_TIMEOUT		msecs_to_jiffies(1000)
10337784706SMoritz Fischer /* Timeout for polling reset bits */
10437784706SMoritz Fischer #define INIT_POLL_TIMEOUT		2500000
10537784706SMoritz Fischer /* Delay for polling reset bits */
10637784706SMoritz Fischer #define INIT_POLL_DELAY			20
10737784706SMoritz Fischer 
10837784706SMoritz Fischer /* Masks for controlling stuff in SLCR */
10937784706SMoritz Fischer /* Disable all Level shifters */
11037784706SMoritz Fischer #define LVL_SHFTR_DISABLE_ALL_MASK	0x0
11137784706SMoritz Fischer /* Enable Level shifters from PS to PL */
11237784706SMoritz Fischer #define LVL_SHFTR_ENABLE_PS_TO_PL	0xa
11337784706SMoritz Fischer /* Enable Level shifters from PL to PS */
11437784706SMoritz Fischer #define LVL_SHFTR_ENABLE_PL_TO_PS	0xf
11537784706SMoritz Fischer /* Enable global resets */
11637784706SMoritz Fischer #define FPGA_RST_ALL_MASK		0xf
11737784706SMoritz Fischer /* Disable global resets */
11837784706SMoritz Fischer #define FPGA_RST_NONE_MASK		0x0
11937784706SMoritz Fischer 
12037784706SMoritz Fischer struct zynq_fpga_priv {
12137784706SMoritz Fischer 	struct device *dev;
12237784706SMoritz Fischer 	int irq;
12337784706SMoritz Fischer 	struct clk *clk;
12437784706SMoritz Fischer 
12537784706SMoritz Fischer 	void __iomem *io_base;
12637784706SMoritz Fischer 	struct regmap *slcr;
12737784706SMoritz Fischer 
12837784706SMoritz Fischer 	struct completion dma_done;
12937784706SMoritz Fischer };
13037784706SMoritz Fischer 
13137784706SMoritz Fischer static inline void zynq_fpga_write(struct zynq_fpga_priv *priv, u32 offset,
13237784706SMoritz Fischer 				   u32 val)
13337784706SMoritz Fischer {
13437784706SMoritz Fischer 	writel(val, priv->io_base + offset);
13537784706SMoritz Fischer }
13637784706SMoritz Fischer 
13737784706SMoritz Fischer static inline u32 zynq_fpga_read(const struct zynq_fpga_priv *priv,
13837784706SMoritz Fischer 				 u32 offset)
13937784706SMoritz Fischer {
14037784706SMoritz Fischer 	return readl(priv->io_base + offset);
14137784706SMoritz Fischer }
14237784706SMoritz Fischer 
14337784706SMoritz Fischer #define zynq_fpga_poll_timeout(priv, addr, val, cond, sleep_us, timeout_us) \
14437784706SMoritz Fischer 	readl_poll_timeout(priv->io_base + addr, val, cond, sleep_us, \
14537784706SMoritz Fischer 			   timeout_us)
14637784706SMoritz Fischer 
14737784706SMoritz Fischer static void zynq_fpga_mask_irqs(struct zynq_fpga_priv *priv)
14837784706SMoritz Fischer {
14937784706SMoritz Fischer 	u32 intr_mask;
15037784706SMoritz Fischer 
15137784706SMoritz Fischer 	intr_mask = zynq_fpga_read(priv, INT_MASK_OFFSET);
15237784706SMoritz Fischer 	zynq_fpga_write(priv, INT_MASK_OFFSET,
15337784706SMoritz Fischer 			intr_mask | IXR_DMA_DONE_MASK | IXR_ERROR_FLAGS_MASK);
15437784706SMoritz Fischer }
15537784706SMoritz Fischer 
15637784706SMoritz Fischer static void zynq_fpga_unmask_irqs(struct zynq_fpga_priv *priv)
15737784706SMoritz Fischer {
15837784706SMoritz Fischer 	u32 intr_mask;
15937784706SMoritz Fischer 
16037784706SMoritz Fischer 	intr_mask = zynq_fpga_read(priv, INT_MASK_OFFSET);
16137784706SMoritz Fischer 	zynq_fpga_write(priv, INT_MASK_OFFSET,
16237784706SMoritz Fischer 			intr_mask
16337784706SMoritz Fischer 			& ~(IXR_D_P_DONE_MASK | IXR_ERROR_FLAGS_MASK));
16437784706SMoritz Fischer }
16537784706SMoritz Fischer 
16637784706SMoritz Fischer static irqreturn_t zynq_fpga_isr(int irq, void *data)
16737784706SMoritz Fischer {
16837784706SMoritz Fischer 	struct zynq_fpga_priv *priv = data;
16937784706SMoritz Fischer 
17037784706SMoritz Fischer 	/* disable DMA and error IRQs */
17137784706SMoritz Fischer 	zynq_fpga_mask_irqs(priv);
17237784706SMoritz Fischer 
17337784706SMoritz Fischer 	complete(&priv->dma_done);
17437784706SMoritz Fischer 
17537784706SMoritz Fischer 	return IRQ_HANDLED;
17637784706SMoritz Fischer }
17737784706SMoritz Fischer 
1781df2865fSAlan Tull static int zynq_fpga_ops_write_init(struct fpga_manager *mgr,
1791df2865fSAlan Tull 				    struct fpga_image_info *info,
18037784706SMoritz Fischer 				    const char *buf, size_t count)
18137784706SMoritz Fischer {
18237784706SMoritz Fischer 	struct zynq_fpga_priv *priv;
18337784706SMoritz Fischer 	u32 ctrl, status;
18437784706SMoritz Fischer 	int err;
18537784706SMoritz Fischer 
18637784706SMoritz Fischer 	priv = mgr->priv;
18737784706SMoritz Fischer 
18837784706SMoritz Fischer 	err = clk_enable(priv->clk);
18937784706SMoritz Fischer 	if (err)
19037784706SMoritz Fischer 		return err;
19137784706SMoritz Fischer 
19237784706SMoritz Fischer 	/* don't globally reset PL if we're doing partial reconfig */
1931df2865fSAlan Tull 	if (!(info->flags & FPGA_MGR_PARTIAL_RECONFIG)) {
19437784706SMoritz Fischer 		/* assert AXI interface resets */
19537784706SMoritz Fischer 		regmap_write(priv->slcr, SLCR_FPGA_RST_CTRL_OFFSET,
19637784706SMoritz Fischer 			     FPGA_RST_ALL_MASK);
19737784706SMoritz Fischer 
19837784706SMoritz Fischer 		/* disable all level shifters */
19937784706SMoritz Fischer 		regmap_write(priv->slcr, SLCR_LVL_SHFTR_EN_OFFSET,
20037784706SMoritz Fischer 			     LVL_SHFTR_DISABLE_ALL_MASK);
20137784706SMoritz Fischer 		/* enable level shifters from PS to PL */
20237784706SMoritz Fischer 		regmap_write(priv->slcr, SLCR_LVL_SHFTR_EN_OFFSET,
20337784706SMoritz Fischer 			     LVL_SHFTR_ENABLE_PS_TO_PL);
20437784706SMoritz Fischer 
20537784706SMoritz Fischer 		/* create a rising edge on PCFG_INIT. PCFG_INIT follows
20637784706SMoritz Fischer 		 * PCFG_PROG_B, so we need to poll it after setting PCFG_PROG_B
20737784706SMoritz Fischer 		 * to make sure the rising edge actually happens.
20837784706SMoritz Fischer 		 * Note: PCFG_PROG_B is low active, sequence as described in
20937784706SMoritz Fischer 		 * UG585 v1.10 page 211
21037784706SMoritz Fischer 		 */
21137784706SMoritz Fischer 		ctrl = zynq_fpga_read(priv, CTRL_OFFSET);
21237784706SMoritz Fischer 		ctrl |= CTRL_PCFG_PROG_B_MASK;
21337784706SMoritz Fischer 
21437784706SMoritz Fischer 		zynq_fpga_write(priv, CTRL_OFFSET, ctrl);
21537784706SMoritz Fischer 
21637784706SMoritz Fischer 		err = zynq_fpga_poll_timeout(priv, STATUS_OFFSET, status,
21737784706SMoritz Fischer 					     status & STATUS_PCFG_INIT_MASK,
21837784706SMoritz Fischer 					     INIT_POLL_DELAY,
21937784706SMoritz Fischer 					     INIT_POLL_TIMEOUT);
22037784706SMoritz Fischer 		if (err) {
221*1930c286SJason Gunthorpe 			dev_err(priv->dev, "Timeout waiting for PCFG_INIT\n");
22237784706SMoritz Fischer 			goto out_err;
22337784706SMoritz Fischer 		}
22437784706SMoritz Fischer 
22537784706SMoritz Fischer 		ctrl = zynq_fpga_read(priv, CTRL_OFFSET);
22637784706SMoritz Fischer 		ctrl &= ~CTRL_PCFG_PROG_B_MASK;
22737784706SMoritz Fischer 
22837784706SMoritz Fischer 		zynq_fpga_write(priv, CTRL_OFFSET, ctrl);
22937784706SMoritz Fischer 
23037784706SMoritz Fischer 		err = zynq_fpga_poll_timeout(priv, STATUS_OFFSET, status,
23137784706SMoritz Fischer 					     !(status & STATUS_PCFG_INIT_MASK),
23237784706SMoritz Fischer 					     INIT_POLL_DELAY,
23337784706SMoritz Fischer 					     INIT_POLL_TIMEOUT);
23437784706SMoritz Fischer 		if (err) {
235*1930c286SJason Gunthorpe 			dev_err(priv->dev, "Timeout waiting for !PCFG_INIT\n");
23637784706SMoritz Fischer 			goto out_err;
23737784706SMoritz Fischer 		}
23837784706SMoritz Fischer 
23937784706SMoritz Fischer 		ctrl = zynq_fpga_read(priv, CTRL_OFFSET);
24037784706SMoritz Fischer 		ctrl |= CTRL_PCFG_PROG_B_MASK;
24137784706SMoritz Fischer 
24237784706SMoritz Fischer 		zynq_fpga_write(priv, CTRL_OFFSET, ctrl);
24337784706SMoritz Fischer 
24437784706SMoritz Fischer 		err = zynq_fpga_poll_timeout(priv, STATUS_OFFSET, status,
24537784706SMoritz Fischer 					     status & STATUS_PCFG_INIT_MASK,
24637784706SMoritz Fischer 					     INIT_POLL_DELAY,
24737784706SMoritz Fischer 					     INIT_POLL_TIMEOUT);
24837784706SMoritz Fischer 		if (err) {
249*1930c286SJason Gunthorpe 			dev_err(priv->dev, "Timeout waiting for PCFG_INIT\n");
25037784706SMoritz Fischer 			goto out_err;
25137784706SMoritz Fischer 		}
25237784706SMoritz Fischer 	}
25337784706SMoritz Fischer 
25437784706SMoritz Fischer 	/* set configuration register with following options:
25537784706SMoritz Fischer 	 * - enable PCAP interface
25637784706SMoritz Fischer 	 * - set throughput for maximum speed
25737784706SMoritz Fischer 	 * - set CPU in user mode
25837784706SMoritz Fischer 	 */
25937784706SMoritz Fischer 	ctrl = zynq_fpga_read(priv, CTRL_OFFSET);
26037784706SMoritz Fischer 	zynq_fpga_write(priv, CTRL_OFFSET,
26137784706SMoritz Fischer 			(CTRL_PCAP_PR_MASK | CTRL_PCAP_MODE_MASK | ctrl));
26237784706SMoritz Fischer 
26337784706SMoritz Fischer 	/* check that we have room in the command queue */
26437784706SMoritz Fischer 	status = zynq_fpga_read(priv, STATUS_OFFSET);
26537784706SMoritz Fischer 	if (status & STATUS_DMA_Q_F) {
266*1930c286SJason Gunthorpe 		dev_err(priv->dev, "DMA command queue full\n");
26737784706SMoritz Fischer 		err = -EBUSY;
26837784706SMoritz Fischer 		goto out_err;
26937784706SMoritz Fischer 	}
27037784706SMoritz Fischer 
27137784706SMoritz Fischer 	/* ensure internal PCAP loopback is disabled */
27237784706SMoritz Fischer 	ctrl = zynq_fpga_read(priv, MCTRL_OFFSET);
27337784706SMoritz Fischer 	zynq_fpga_write(priv, MCTRL_OFFSET, (~MCTRL_PCAP_LPBK_MASK & ctrl));
27437784706SMoritz Fischer 
27537784706SMoritz Fischer 	clk_disable(priv->clk);
27637784706SMoritz Fischer 
27737784706SMoritz Fischer 	return 0;
27837784706SMoritz Fischer 
27937784706SMoritz Fischer out_err:
28037784706SMoritz Fischer 	clk_disable(priv->clk);
28137784706SMoritz Fischer 
28237784706SMoritz Fischer 	return err;
28337784706SMoritz Fischer }
28437784706SMoritz Fischer 
28537784706SMoritz Fischer static int zynq_fpga_ops_write(struct fpga_manager *mgr,
28637784706SMoritz Fischer 			       const char *buf, size_t count)
28737784706SMoritz Fischer {
28837784706SMoritz Fischer 	struct zynq_fpga_priv *priv;
28937784706SMoritz Fischer 	int err;
29037784706SMoritz Fischer 	char *kbuf;
2914d10eaffSMoritz Fischer 	size_t in_count;
29237784706SMoritz Fischer 	dma_addr_t dma_addr;
2934d10eaffSMoritz Fischer 	u32 transfer_length;
29437784706SMoritz Fischer 	u32 intr_status;
29537784706SMoritz Fischer 
29637784706SMoritz Fischer 	in_count = count;
29737784706SMoritz Fischer 	priv = mgr->priv;
29837784706SMoritz Fischer 
29937784706SMoritz Fischer 	kbuf = dma_alloc_coherent(priv->dev, count, &dma_addr, GFP_KERNEL);
30037784706SMoritz Fischer 	if (!kbuf)
30137784706SMoritz Fischer 		return -ENOMEM;
30237784706SMoritz Fischer 
30337784706SMoritz Fischer 	memcpy(kbuf, buf, count);
30437784706SMoritz Fischer 
30537784706SMoritz Fischer 	/* enable clock */
30637784706SMoritz Fischer 	err = clk_enable(priv->clk);
30737784706SMoritz Fischer 	if (err)
30837784706SMoritz Fischer 		goto out_free;
30937784706SMoritz Fischer 
31037784706SMoritz Fischer 	zynq_fpga_write(priv, INT_STS_OFFSET, IXR_ALL_MASK);
31137784706SMoritz Fischer 
31237784706SMoritz Fischer 	reinit_completion(&priv->dma_done);
31337784706SMoritz Fischer 
31437784706SMoritz Fischer 	/* enable DMA and error IRQs */
31537784706SMoritz Fischer 	zynq_fpga_unmask_irqs(priv);
31637784706SMoritz Fischer 
31737784706SMoritz Fischer 	/* the +1 in the src addr is used to hold off on DMA_DONE IRQ
31837784706SMoritz Fischer 	 * until both AXI and PCAP are done ...
31937784706SMoritz Fischer 	 */
32037784706SMoritz Fischer 	zynq_fpga_write(priv, DMA_SRC_ADDR_OFFSET, (u32)(dma_addr) + 1);
32137784706SMoritz Fischer 	zynq_fpga_write(priv, DMA_DST_ADDR_OFFSET, (u32)DMA_INVALID_ADDRESS);
32237784706SMoritz Fischer 
32337784706SMoritz Fischer 	/* convert #bytes to #words */
32437784706SMoritz Fischer 	transfer_length = (count + 3) / 4;
32537784706SMoritz Fischer 
32637784706SMoritz Fischer 	zynq_fpga_write(priv, DMA_SRC_LEN_OFFSET, transfer_length);
32737784706SMoritz Fischer 	zynq_fpga_write(priv, DMA_DEST_LEN_OFFSET, 0);
32837784706SMoritz Fischer 
32937784706SMoritz Fischer 	wait_for_completion(&priv->dma_done);
33037784706SMoritz Fischer 
33137784706SMoritz Fischer 	intr_status = zynq_fpga_read(priv, INT_STS_OFFSET);
33237784706SMoritz Fischer 	zynq_fpga_write(priv, INT_STS_OFFSET, intr_status);
33337784706SMoritz Fischer 
33437784706SMoritz Fischer 	if (!((intr_status & IXR_D_P_DONE_MASK) == IXR_D_P_DONE_MASK)) {
335*1930c286SJason Gunthorpe 		dev_err(priv->dev, "Error configuring FPGA\n");
33637784706SMoritz Fischer 		err = -EFAULT;
33737784706SMoritz Fischer 	}
33837784706SMoritz Fischer 
33937784706SMoritz Fischer 	clk_disable(priv->clk);
34037784706SMoritz Fischer 
34137784706SMoritz Fischer out_free:
34237784706SMoritz Fischer 	dma_free_coherent(priv->dev, in_count, kbuf, dma_addr);
34337784706SMoritz Fischer 
34437784706SMoritz Fischer 	return err;
34537784706SMoritz Fischer }
34637784706SMoritz Fischer 
3471df2865fSAlan Tull static int zynq_fpga_ops_write_complete(struct fpga_manager *mgr,
3481df2865fSAlan Tull 					struct fpga_image_info *info)
34937784706SMoritz Fischer {
35037784706SMoritz Fischer 	struct zynq_fpga_priv *priv = mgr->priv;
35137784706SMoritz Fischer 	int err;
35237784706SMoritz Fischer 	u32 intr_status;
35337784706SMoritz Fischer 
35437784706SMoritz Fischer 	err = clk_enable(priv->clk);
35537784706SMoritz Fischer 	if (err)
35637784706SMoritz Fischer 		return err;
35737784706SMoritz Fischer 
35837784706SMoritz Fischer 	err = zynq_fpga_poll_timeout(priv, INT_STS_OFFSET, intr_status,
35937784706SMoritz Fischer 				     intr_status & IXR_PCFG_DONE_MASK,
36037784706SMoritz Fischer 				     INIT_POLL_DELAY,
36137784706SMoritz Fischer 				     INIT_POLL_TIMEOUT);
36237784706SMoritz Fischer 
36337784706SMoritz Fischer 	clk_disable(priv->clk);
36437784706SMoritz Fischer 
36537784706SMoritz Fischer 	if (err)
36637784706SMoritz Fischer 		return err;
36737784706SMoritz Fischer 
36837784706SMoritz Fischer 	/* for the partial reconfig case we didn't touch the level shifters */
3691df2865fSAlan Tull 	if (!(info->flags & FPGA_MGR_PARTIAL_RECONFIG)) {
37037784706SMoritz Fischer 		/* enable level shifters from PL to PS */
37137784706SMoritz Fischer 		regmap_write(priv->slcr, SLCR_LVL_SHFTR_EN_OFFSET,
37237784706SMoritz Fischer 			     LVL_SHFTR_ENABLE_PL_TO_PS);
37337784706SMoritz Fischer 
37437784706SMoritz Fischer 		/* deassert AXI interface resets */
37537784706SMoritz Fischer 		regmap_write(priv->slcr, SLCR_FPGA_RST_CTRL_OFFSET,
37637784706SMoritz Fischer 			     FPGA_RST_NONE_MASK);
37737784706SMoritz Fischer 	}
37837784706SMoritz Fischer 
37937784706SMoritz Fischer 	return 0;
38037784706SMoritz Fischer }
38137784706SMoritz Fischer 
38237784706SMoritz Fischer static enum fpga_mgr_states zynq_fpga_ops_state(struct fpga_manager *mgr)
38337784706SMoritz Fischer {
38437784706SMoritz Fischer 	int err;
38537784706SMoritz Fischer 	u32 intr_status;
38637784706SMoritz Fischer 	struct zynq_fpga_priv *priv;
38737784706SMoritz Fischer 
38837784706SMoritz Fischer 	priv = mgr->priv;
38937784706SMoritz Fischer 
39037784706SMoritz Fischer 	err = clk_enable(priv->clk);
39137784706SMoritz Fischer 	if (err)
39237784706SMoritz Fischer 		return FPGA_MGR_STATE_UNKNOWN;
39337784706SMoritz Fischer 
39437784706SMoritz Fischer 	intr_status = zynq_fpga_read(priv, INT_STS_OFFSET);
39537784706SMoritz Fischer 	clk_disable(priv->clk);
39637784706SMoritz Fischer 
39737784706SMoritz Fischer 	if (intr_status & IXR_PCFG_DONE_MASK)
39837784706SMoritz Fischer 		return FPGA_MGR_STATE_OPERATING;
39937784706SMoritz Fischer 
40037784706SMoritz Fischer 	return FPGA_MGR_STATE_UNKNOWN;
40137784706SMoritz Fischer }
40237784706SMoritz Fischer 
40337784706SMoritz Fischer static const struct fpga_manager_ops zynq_fpga_ops = {
40437784706SMoritz Fischer 	.state = zynq_fpga_ops_state,
40537784706SMoritz Fischer 	.write_init = zynq_fpga_ops_write_init,
40637784706SMoritz Fischer 	.write = zynq_fpga_ops_write,
40737784706SMoritz Fischer 	.write_complete = zynq_fpga_ops_write_complete,
40837784706SMoritz Fischer };
40937784706SMoritz Fischer 
41037784706SMoritz Fischer static int zynq_fpga_probe(struct platform_device *pdev)
41137784706SMoritz Fischer {
41237784706SMoritz Fischer 	struct device *dev = &pdev->dev;
41337784706SMoritz Fischer 	struct zynq_fpga_priv *priv;
41437784706SMoritz Fischer 	struct resource *res;
41537784706SMoritz Fischer 	int err;
41637784706SMoritz Fischer 
41737784706SMoritz Fischer 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
41837784706SMoritz Fischer 	if (!priv)
41937784706SMoritz Fischer 		return -ENOMEM;
42037784706SMoritz Fischer 
42137784706SMoritz Fischer 	priv->dev = dev;
42237784706SMoritz Fischer 
42337784706SMoritz Fischer 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
42437784706SMoritz Fischer 	priv->io_base = devm_ioremap_resource(dev, res);
42537784706SMoritz Fischer 	if (IS_ERR(priv->io_base))
42637784706SMoritz Fischer 		return PTR_ERR(priv->io_base);
42737784706SMoritz Fischer 
42837784706SMoritz Fischer 	priv->slcr = syscon_regmap_lookup_by_phandle(dev->of_node,
42937784706SMoritz Fischer 		"syscon");
43037784706SMoritz Fischer 	if (IS_ERR(priv->slcr)) {
431*1930c286SJason Gunthorpe 		dev_err(dev, "unable to get zynq-slcr regmap\n");
43237784706SMoritz Fischer 		return PTR_ERR(priv->slcr);
43337784706SMoritz Fischer 	}
43437784706SMoritz Fischer 
43537784706SMoritz Fischer 	init_completion(&priv->dma_done);
43637784706SMoritz Fischer 
43737784706SMoritz Fischer 	priv->irq = platform_get_irq(pdev, 0);
43837784706SMoritz Fischer 	if (priv->irq < 0) {
439*1930c286SJason Gunthorpe 		dev_err(dev, "No IRQ available\n");
44037784706SMoritz Fischer 		return priv->irq;
44137784706SMoritz Fischer 	}
44237784706SMoritz Fischer 
44337784706SMoritz Fischer 	err = devm_request_irq(dev, priv->irq, zynq_fpga_isr, 0,
44437784706SMoritz Fischer 			       dev_name(dev), priv);
44537784706SMoritz Fischer 	if (err) {
446*1930c286SJason Gunthorpe 		dev_err(dev, "unable to request IRQ\n");
44737784706SMoritz Fischer 		return err;
44837784706SMoritz Fischer 	}
44937784706SMoritz Fischer 
45037784706SMoritz Fischer 	priv->clk = devm_clk_get(dev, "ref_clk");
45137784706SMoritz Fischer 	if (IS_ERR(priv->clk)) {
452*1930c286SJason Gunthorpe 		dev_err(dev, "input clock not found\n");
45337784706SMoritz Fischer 		return PTR_ERR(priv->clk);
45437784706SMoritz Fischer 	}
45537784706SMoritz Fischer 
45637784706SMoritz Fischer 	err = clk_prepare_enable(priv->clk);
45737784706SMoritz Fischer 	if (err) {
458*1930c286SJason Gunthorpe 		dev_err(dev, "unable to enable clock\n");
45937784706SMoritz Fischer 		return err;
46037784706SMoritz Fischer 	}
46137784706SMoritz Fischer 
46237784706SMoritz Fischer 	/* unlock the device */
46337784706SMoritz Fischer 	zynq_fpga_write(priv, UNLOCK_OFFSET, UNLOCK_MASK);
46437784706SMoritz Fischer 
46537784706SMoritz Fischer 	clk_disable(priv->clk);
46637784706SMoritz Fischer 
46737784706SMoritz Fischer 	err = fpga_mgr_register(dev, "Xilinx Zynq FPGA Manager",
46837784706SMoritz Fischer 				&zynq_fpga_ops, priv);
46937784706SMoritz Fischer 	if (err) {
470*1930c286SJason Gunthorpe 		dev_err(dev, "unable to register FPGA manager\n");
4716376931bSMoritz Fischer 		clk_unprepare(priv->clk);
47237784706SMoritz Fischer 		return err;
47337784706SMoritz Fischer 	}
47437784706SMoritz Fischer 
47537784706SMoritz Fischer 	return 0;
47637784706SMoritz Fischer }
47737784706SMoritz Fischer 
47837784706SMoritz Fischer static int zynq_fpga_remove(struct platform_device *pdev)
47937784706SMoritz Fischer {
48037784706SMoritz Fischer 	struct zynq_fpga_priv *priv;
48128f98a12SMoritz Fischer 	struct fpga_manager *mgr;
48228f98a12SMoritz Fischer 
48328f98a12SMoritz Fischer 	mgr = platform_get_drvdata(pdev);
48428f98a12SMoritz Fischer 	priv = mgr->priv;
48537784706SMoritz Fischer 
48637784706SMoritz Fischer 	fpga_mgr_unregister(&pdev->dev);
48737784706SMoritz Fischer 
4886376931bSMoritz Fischer 	clk_unprepare(priv->clk);
48937784706SMoritz Fischer 
49037784706SMoritz Fischer 	return 0;
49137784706SMoritz Fischer }
49237784706SMoritz Fischer 
49337784706SMoritz Fischer #ifdef CONFIG_OF
49437784706SMoritz Fischer static const struct of_device_id zynq_fpga_of_match[] = {
49537784706SMoritz Fischer 	{ .compatible = "xlnx,zynq-devcfg-1.0", },
49637784706SMoritz Fischer 	{},
49737784706SMoritz Fischer };
49837784706SMoritz Fischer 
49937784706SMoritz Fischer MODULE_DEVICE_TABLE(of, zynq_fpga_of_match);
50037784706SMoritz Fischer #endif
50137784706SMoritz Fischer 
50237784706SMoritz Fischer static struct platform_driver zynq_fpga_driver = {
50337784706SMoritz Fischer 	.probe = zynq_fpga_probe,
50437784706SMoritz Fischer 	.remove = zynq_fpga_remove,
50537784706SMoritz Fischer 	.driver = {
50637784706SMoritz Fischer 		.name = "zynq_fpga_manager",
50737784706SMoritz Fischer 		.of_match_table = of_match_ptr(zynq_fpga_of_match),
50837784706SMoritz Fischer 	},
50937784706SMoritz Fischer };
51037784706SMoritz Fischer 
51137784706SMoritz Fischer module_platform_driver(zynq_fpga_driver);
51237784706SMoritz Fischer 
51337784706SMoritz Fischer MODULE_AUTHOR("Moritz Fischer <moritz.fischer@ettus.com>");
51437784706SMoritz Fischer MODULE_AUTHOR("Michal Simek <michal.simek@xilinx.com>");
51537784706SMoritz Fischer MODULE_DESCRIPTION("Xilinx Zynq FPGA Manager");
51637784706SMoritz Fischer MODULE_LICENSE("GPL v2");
517