xref: /openbmc/linux/drivers/fpga/zynq-fpga.c (revision e9fdc41a)
18e8e69d6SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
237784706SMoritz Fischer /*
337784706SMoritz Fischer  * Copyright (c) 2011-2015 Xilinx Inc.
437784706SMoritz Fischer  * Copyright (c) 2015, National Instruments Corp.
537784706SMoritz Fischer  *
637784706SMoritz Fischer  * FPGA Manager Driver for Xilinx Zynq, heavily based on xdevcfg driver
737784706SMoritz Fischer  * in their vendor tree.
837784706SMoritz Fischer  */
937784706SMoritz Fischer 
1037784706SMoritz Fischer #include <linux/clk.h>
1137784706SMoritz Fischer #include <linux/completion.h>
1237784706SMoritz Fischer #include <linux/delay.h>
1337784706SMoritz Fischer #include <linux/dma-mapping.h>
1437784706SMoritz Fischer #include <linux/fpga/fpga-mgr.h>
1537784706SMoritz Fischer #include <linux/interrupt.h>
1637784706SMoritz Fischer #include <linux/io.h>
1737784706SMoritz Fischer #include <linux/iopoll.h>
1837784706SMoritz Fischer #include <linux/module.h>
1937784706SMoritz Fischer #include <linux/mfd/syscon.h>
2037784706SMoritz Fischer #include <linux/of_address.h>
2137784706SMoritz Fischer #include <linux/of_irq.h>
2237784706SMoritz Fischer #include <linux/pm.h>
2337784706SMoritz Fischer #include <linux/regmap.h>
2437784706SMoritz Fischer #include <linux/string.h>
25425902f5SJason Gunthorpe #include <linux/scatterlist.h>
2637784706SMoritz Fischer 
2737784706SMoritz Fischer /* Offsets into SLCR regmap */
2837784706SMoritz Fischer 
2937784706SMoritz Fischer /* FPGA Software Reset Control */
3037784706SMoritz Fischer #define SLCR_FPGA_RST_CTRL_OFFSET	0x240
3137784706SMoritz Fischer /* Level Shifters Enable */
3237784706SMoritz Fischer #define SLCR_LVL_SHFTR_EN_OFFSET	0x900
3337784706SMoritz Fischer 
3437784706SMoritz Fischer /* Constant Definitions */
3537784706SMoritz Fischer 
3637784706SMoritz Fischer /* Control Register */
3737784706SMoritz Fischer #define CTRL_OFFSET			0x00
3837784706SMoritz Fischer /* Lock Register */
3937784706SMoritz Fischer #define LOCK_OFFSET			0x04
4037784706SMoritz Fischer /* Interrupt Status Register */
4137784706SMoritz Fischer #define INT_STS_OFFSET			0x0c
4237784706SMoritz Fischer /* Interrupt Mask Register */
4337784706SMoritz Fischer #define INT_MASK_OFFSET			0x10
4437784706SMoritz Fischer /* Status Register */
4537784706SMoritz Fischer #define STATUS_OFFSET			0x14
4637784706SMoritz Fischer /* DMA Source Address Register */
4737784706SMoritz Fischer #define DMA_SRC_ADDR_OFFSET		0x18
4837784706SMoritz Fischer /* DMA Destination Address Reg */
4937784706SMoritz Fischer #define DMA_DST_ADDR_OFFSET		0x1c
5037784706SMoritz Fischer /* DMA Source Transfer Length */
5137784706SMoritz Fischer #define DMA_SRC_LEN_OFFSET		0x20
5237784706SMoritz Fischer /* DMA Destination Transfer */
5337784706SMoritz Fischer #define DMA_DEST_LEN_OFFSET		0x24
5437784706SMoritz Fischer /* Unlock Register */
5537784706SMoritz Fischer #define UNLOCK_OFFSET			0x34
5637784706SMoritz Fischer /* Misc. Control Register */
5737784706SMoritz Fischer #define MCTRL_OFFSET			0x80
5837784706SMoritz Fischer 
5937784706SMoritz Fischer /* Control Register Bit definitions */
6037784706SMoritz Fischer 
6137784706SMoritz Fischer /* Signal to reset FPGA */
6237784706SMoritz Fischer #define CTRL_PCFG_PROG_B_MASK		BIT(30)
6337784706SMoritz Fischer /* Enable PCAP for PR */
6437784706SMoritz Fischer #define CTRL_PCAP_PR_MASK		BIT(27)
6537784706SMoritz Fischer /* Enable PCAP */
6637784706SMoritz Fischer #define CTRL_PCAP_MODE_MASK		BIT(26)
677f33bbcaSMoritz Fischer /* Lower rate to allow decrypt on the fly */
687f33bbcaSMoritz Fischer #define CTRL_PCAP_RATE_EN_MASK		BIT(25)
697f33bbcaSMoritz Fischer /* System booted in secure mode */
707f33bbcaSMoritz Fischer #define CTRL_SEC_EN_MASK		BIT(7)
7137784706SMoritz Fischer 
7237784706SMoritz Fischer /* Miscellaneous Control Register bit definitions */
7337784706SMoritz Fischer /* Internal PCAP loopback */
7437784706SMoritz Fischer #define MCTRL_PCAP_LPBK_MASK		BIT(4)
7537784706SMoritz Fischer 
7637784706SMoritz Fischer /* Status register bit definitions */
7737784706SMoritz Fischer 
7837784706SMoritz Fischer /* FPGA init status */
7937784706SMoritz Fischer #define STATUS_DMA_Q_F			BIT(31)
80425902f5SJason Gunthorpe #define STATUS_DMA_Q_E			BIT(30)
8137784706SMoritz Fischer #define STATUS_PCFG_INIT_MASK		BIT(4)
8237784706SMoritz Fischer 
8337784706SMoritz Fischer /* Interrupt Status/Mask Register Bit definitions */
8437784706SMoritz Fischer /* DMA command done */
8537784706SMoritz Fischer #define IXR_DMA_DONE_MASK		BIT(13)
8637784706SMoritz Fischer /* DMA and PCAP cmd done */
8737784706SMoritz Fischer #define IXR_D_P_DONE_MASK		BIT(12)
8837784706SMoritz Fischer  /* FPGA programmed */
8937784706SMoritz Fischer #define IXR_PCFG_DONE_MASK		BIT(2)
906b45e0f2SJason Gunthorpe #define IXR_ERROR_FLAGS_MASK		0x00F0C860
9137784706SMoritz Fischer #define IXR_ALL_MASK			0xF8F7F87F
9237784706SMoritz Fischer 
9337784706SMoritz Fischer /* Miscellaneous constant values */
9437784706SMoritz Fischer 
9537784706SMoritz Fischer /* Invalid DMA addr */
9637784706SMoritz Fischer #define DMA_INVALID_ADDRESS		GENMASK(31, 0)
9737784706SMoritz Fischer /* Used to unlock the dev */
9837784706SMoritz Fischer #define UNLOCK_MASK			0x757bdf0d
9937784706SMoritz Fischer /* Timeout for polling reset bits */
10037784706SMoritz Fischer #define INIT_POLL_TIMEOUT		2500000
10137784706SMoritz Fischer /* Delay for polling reset bits */
10237784706SMoritz Fischer #define INIT_POLL_DELAY			20
103425902f5SJason Gunthorpe /* Signal this is the last DMA transfer, wait for the AXI and PCAP before
104425902f5SJason Gunthorpe  * interrupting
105425902f5SJason Gunthorpe  */
106425902f5SJason Gunthorpe #define DMA_SRC_LAST_TRANSFER		1
107425902f5SJason Gunthorpe /* Timeout for DMA completion */
108425902f5SJason Gunthorpe #define DMA_TIMEOUT_MS			5000
10937784706SMoritz Fischer 
11037784706SMoritz Fischer /* Masks for controlling stuff in SLCR */
11137784706SMoritz Fischer /* Disable all Level shifters */
11237784706SMoritz Fischer #define LVL_SHFTR_DISABLE_ALL_MASK	0x0
11337784706SMoritz Fischer /* Enable Level shifters from PS to PL */
11437784706SMoritz Fischer #define LVL_SHFTR_ENABLE_PS_TO_PL	0xa
11537784706SMoritz Fischer /* Enable Level shifters from PL to PS */
11637784706SMoritz Fischer #define LVL_SHFTR_ENABLE_PL_TO_PS	0xf
11737784706SMoritz Fischer /* Enable global resets */
11837784706SMoritz Fischer #define FPGA_RST_ALL_MASK		0xf
11937784706SMoritz Fischer /* Disable global resets */
12037784706SMoritz Fischer #define FPGA_RST_NONE_MASK		0x0
12137784706SMoritz Fischer 
12237784706SMoritz Fischer struct zynq_fpga_priv {
12337784706SMoritz Fischer 	int irq;
12437784706SMoritz Fischer 	struct clk *clk;
12537784706SMoritz Fischer 
12637784706SMoritz Fischer 	void __iomem *io_base;
12737784706SMoritz Fischer 	struct regmap *slcr;
12837784706SMoritz Fischer 
129425902f5SJason Gunthorpe 	spinlock_t dma_lock;
130425902f5SJason Gunthorpe 	unsigned int dma_elm;
131425902f5SJason Gunthorpe 	unsigned int dma_nelms;
132425902f5SJason Gunthorpe 	struct scatterlist *cur_sg;
133425902f5SJason Gunthorpe 
13437784706SMoritz Fischer 	struct completion dma_done;
13537784706SMoritz Fischer };
13637784706SMoritz Fischer 
zynq_fpga_write(struct zynq_fpga_priv * priv,u32 offset,u32 val)13737784706SMoritz Fischer static inline void zynq_fpga_write(struct zynq_fpga_priv *priv, u32 offset,
13837784706SMoritz Fischer 				   u32 val)
13937784706SMoritz Fischer {
14037784706SMoritz Fischer 	writel(val, priv->io_base + offset);
14137784706SMoritz Fischer }
14237784706SMoritz Fischer 
zynq_fpga_read(const struct zynq_fpga_priv * priv,u32 offset)14337784706SMoritz Fischer static inline u32 zynq_fpga_read(const struct zynq_fpga_priv *priv,
14437784706SMoritz Fischer 				 u32 offset)
14537784706SMoritz Fischer {
14637784706SMoritz Fischer 	return readl(priv->io_base + offset);
14737784706SMoritz Fischer }
14837784706SMoritz Fischer 
14937784706SMoritz Fischer #define zynq_fpga_poll_timeout(priv, addr, val, cond, sleep_us, timeout_us) \
15037784706SMoritz Fischer 	readl_poll_timeout(priv->io_base + addr, val, cond, sleep_us, \
15137784706SMoritz Fischer 			   timeout_us)
15237784706SMoritz Fischer 
1536b45e0f2SJason Gunthorpe /* Cause the specified irq mask bits to generate IRQs */
zynq_fpga_set_irq(struct zynq_fpga_priv * priv,u32 enable)1546b45e0f2SJason Gunthorpe static inline void zynq_fpga_set_irq(struct zynq_fpga_priv *priv, u32 enable)
15537784706SMoritz Fischer {
1566b45e0f2SJason Gunthorpe 	zynq_fpga_write(priv, INT_MASK_OFFSET, ~enable);
15737784706SMoritz Fischer }
15837784706SMoritz Fischer 
159425902f5SJason Gunthorpe /* Must be called with dma_lock held */
zynq_step_dma(struct zynq_fpga_priv * priv)160425902f5SJason Gunthorpe static void zynq_step_dma(struct zynq_fpga_priv *priv)
161425902f5SJason Gunthorpe {
162425902f5SJason Gunthorpe 	u32 addr;
163425902f5SJason Gunthorpe 	u32 len;
164425902f5SJason Gunthorpe 	bool first;
165425902f5SJason Gunthorpe 
166425902f5SJason Gunthorpe 	first = priv->dma_elm == 0;
167425902f5SJason Gunthorpe 	while (priv->cur_sg) {
168425902f5SJason Gunthorpe 		/* Feed the DMA queue until it is full. */
169425902f5SJason Gunthorpe 		if (zynq_fpga_read(priv, STATUS_OFFSET) & STATUS_DMA_Q_F)
170425902f5SJason Gunthorpe 			break;
171425902f5SJason Gunthorpe 
172425902f5SJason Gunthorpe 		addr = sg_dma_address(priv->cur_sg);
173425902f5SJason Gunthorpe 		len = sg_dma_len(priv->cur_sg);
174425902f5SJason Gunthorpe 		if (priv->dma_elm + 1 == priv->dma_nelms) {
175425902f5SJason Gunthorpe 			/* The last transfer waits for the PCAP to finish too,
176425902f5SJason Gunthorpe 			 * notice this also changes the irq_mask to ignore
177425902f5SJason Gunthorpe 			 * IXR_DMA_DONE_MASK which ensures we do not trigger
178425902f5SJason Gunthorpe 			 * the completion too early.
179425902f5SJason Gunthorpe 			 */
180425902f5SJason Gunthorpe 			addr |= DMA_SRC_LAST_TRANSFER;
181425902f5SJason Gunthorpe 			priv->cur_sg = NULL;
182425902f5SJason Gunthorpe 		} else {
183425902f5SJason Gunthorpe 			priv->cur_sg = sg_next(priv->cur_sg);
184425902f5SJason Gunthorpe 			priv->dma_elm++;
185425902f5SJason Gunthorpe 		}
186425902f5SJason Gunthorpe 
187425902f5SJason Gunthorpe 		zynq_fpga_write(priv, DMA_SRC_ADDR_OFFSET, addr);
188425902f5SJason Gunthorpe 		zynq_fpga_write(priv, DMA_DST_ADDR_OFFSET, DMA_INVALID_ADDRESS);
189425902f5SJason Gunthorpe 		zynq_fpga_write(priv, DMA_SRC_LEN_OFFSET, len / 4);
190425902f5SJason Gunthorpe 		zynq_fpga_write(priv, DMA_DEST_LEN_OFFSET, 0);
191425902f5SJason Gunthorpe 	}
192425902f5SJason Gunthorpe 
193425902f5SJason Gunthorpe 	/* Once the first transfer is queued we can turn on the ISR, future
194425902f5SJason Gunthorpe 	 * calls to zynq_step_dma will happen from the ISR context. The
195580e3137STom Rix 	 * dma_lock spinlock guarantees this handover is done coherently, the
196425902f5SJason Gunthorpe 	 * ISR enable is put at the end to avoid another CPU spinning in the
197425902f5SJason Gunthorpe 	 * ISR on this lock.
198425902f5SJason Gunthorpe 	 */
199425902f5SJason Gunthorpe 	if (first && priv->cur_sg) {
200425902f5SJason Gunthorpe 		zynq_fpga_set_irq(priv,
201425902f5SJason Gunthorpe 				  IXR_DMA_DONE_MASK | IXR_ERROR_FLAGS_MASK);
202425902f5SJason Gunthorpe 	} else if (!priv->cur_sg) {
203425902f5SJason Gunthorpe 		/* The last transfer changes to DMA & PCAP mode since we do
204425902f5SJason Gunthorpe 		 * not want to continue until everything has been flushed into
205425902f5SJason Gunthorpe 		 * the PCAP.
206425902f5SJason Gunthorpe 		 */
207425902f5SJason Gunthorpe 		zynq_fpga_set_irq(priv,
208425902f5SJason Gunthorpe 				  IXR_D_P_DONE_MASK | IXR_ERROR_FLAGS_MASK);
209425902f5SJason Gunthorpe 	}
210425902f5SJason Gunthorpe }
211425902f5SJason Gunthorpe 
zynq_fpga_isr(int irq,void * data)21237784706SMoritz Fischer static irqreturn_t zynq_fpga_isr(int irq, void *data)
21337784706SMoritz Fischer {
21437784706SMoritz Fischer 	struct zynq_fpga_priv *priv = data;
215425902f5SJason Gunthorpe 	u32 intr_status;
21637784706SMoritz Fischer 
217425902f5SJason Gunthorpe 	/* If anything other than DMA completion is reported stop and hand
218425902f5SJason Gunthorpe 	 * control back to zynq_fpga_ops_write, something went wrong,
219425902f5SJason Gunthorpe 	 * otherwise progress the DMA.
220425902f5SJason Gunthorpe 	 */
221425902f5SJason Gunthorpe 	spin_lock(&priv->dma_lock);
222425902f5SJason Gunthorpe 	intr_status = zynq_fpga_read(priv, INT_STS_OFFSET);
223425902f5SJason Gunthorpe 	if (!(intr_status & IXR_ERROR_FLAGS_MASK) &&
224425902f5SJason Gunthorpe 	    (intr_status & IXR_DMA_DONE_MASK) && priv->cur_sg) {
225425902f5SJason Gunthorpe 		zynq_fpga_write(priv, INT_STS_OFFSET, IXR_DMA_DONE_MASK);
226425902f5SJason Gunthorpe 		zynq_step_dma(priv);
227425902f5SJason Gunthorpe 		spin_unlock(&priv->dma_lock);
228425902f5SJason Gunthorpe 		return IRQ_HANDLED;
229425902f5SJason Gunthorpe 	}
230425902f5SJason Gunthorpe 	spin_unlock(&priv->dma_lock);
231425902f5SJason Gunthorpe 
2326b45e0f2SJason Gunthorpe 	zynq_fpga_set_irq(priv, 0);
23337784706SMoritz Fischer 	complete(&priv->dma_done);
23437784706SMoritz Fischer 
23537784706SMoritz Fischer 	return IRQ_HANDLED;
23637784706SMoritz Fischer }
23737784706SMoritz Fischer 
238b496df86SJason Gunthorpe /* Sanity check the proposed bitstream. It must start with the sync word in
239b496df86SJason Gunthorpe  * the correct byte order, and be dword aligned. The input is a Xilinx .bin
240b496df86SJason Gunthorpe  * file with every 32 bit quantity swapped.
241b496df86SJason Gunthorpe  */
zynq_fpga_has_sync(const u8 * buf,size_t count)242b496df86SJason Gunthorpe static bool zynq_fpga_has_sync(const u8 *buf, size_t count)
243b496df86SJason Gunthorpe {
244b496df86SJason Gunthorpe 	for (; count >= 4; buf += 4, count -= 4)
245b496df86SJason Gunthorpe 		if (buf[0] == 0x66 && buf[1] == 0x55 && buf[2] == 0x99 &&
246b496df86SJason Gunthorpe 		    buf[3] == 0xaa)
247b496df86SJason Gunthorpe 			return true;
248b496df86SJason Gunthorpe 	return false;
249b496df86SJason Gunthorpe }
250b496df86SJason Gunthorpe 
zynq_fpga_ops_write_init(struct fpga_manager * mgr,struct fpga_image_info * info,const char * buf,size_t count)2511df2865fSAlan Tull static int zynq_fpga_ops_write_init(struct fpga_manager *mgr,
2521df2865fSAlan Tull 				    struct fpga_image_info *info,
25337784706SMoritz Fischer 				    const char *buf, size_t count)
25437784706SMoritz Fischer {
25537784706SMoritz Fischer 	struct zynq_fpga_priv *priv;
25637784706SMoritz Fischer 	u32 ctrl, status;
25737784706SMoritz Fischer 	int err;
25837784706SMoritz Fischer 
25937784706SMoritz Fischer 	priv = mgr->priv;
26037784706SMoritz Fischer 
26137784706SMoritz Fischer 	err = clk_enable(priv->clk);
26237784706SMoritz Fischer 	if (err)
26337784706SMoritz Fischer 		return err;
26437784706SMoritz Fischer 
2657f33bbcaSMoritz Fischer 	/* check if bitstream is encrypted & and system's still secure */
2667f33bbcaSMoritz Fischer 	if (info->flags & FPGA_MGR_ENCRYPTED_BITSTREAM) {
2677f33bbcaSMoritz Fischer 		ctrl = zynq_fpga_read(priv, CTRL_OFFSET);
2687f33bbcaSMoritz Fischer 		if (!(ctrl & CTRL_SEC_EN_MASK)) {
2697f33bbcaSMoritz Fischer 			dev_err(&mgr->dev,
270580e3137STom Rix 				"System not secure, can't use encrypted bitstreams\n");
2717f33bbcaSMoritz Fischer 			err = -EINVAL;
2727f33bbcaSMoritz Fischer 			goto out_err;
2737f33bbcaSMoritz Fischer 		}
2747f33bbcaSMoritz Fischer 	}
2757f33bbcaSMoritz Fischer 
27637784706SMoritz Fischer 	/* don't globally reset PL if we're doing partial reconfig */
2771df2865fSAlan Tull 	if (!(info->flags & FPGA_MGR_PARTIAL_RECONFIG)) {
278b496df86SJason Gunthorpe 		if (!zynq_fpga_has_sync(buf, count)) {
279b496df86SJason Gunthorpe 			dev_err(&mgr->dev,
280b496df86SJason Gunthorpe 				"Invalid bitstream, could not find a sync word. Bitstream must be a byte swapped .bin file\n");
281b496df86SJason Gunthorpe 			err = -EINVAL;
282b496df86SJason Gunthorpe 			goto out_err;
283b496df86SJason Gunthorpe 		}
284b496df86SJason Gunthorpe 
28537784706SMoritz Fischer 		/* assert AXI interface resets */
28637784706SMoritz Fischer 		regmap_write(priv->slcr, SLCR_FPGA_RST_CTRL_OFFSET,
28737784706SMoritz Fischer 			     FPGA_RST_ALL_MASK);
28837784706SMoritz Fischer 
28937784706SMoritz Fischer 		/* disable all level shifters */
29037784706SMoritz Fischer 		regmap_write(priv->slcr, SLCR_LVL_SHFTR_EN_OFFSET,
29137784706SMoritz Fischer 			     LVL_SHFTR_DISABLE_ALL_MASK);
29237784706SMoritz Fischer 		/* enable level shifters from PS to PL */
29337784706SMoritz Fischer 		regmap_write(priv->slcr, SLCR_LVL_SHFTR_EN_OFFSET,
29437784706SMoritz Fischer 			     LVL_SHFTR_ENABLE_PS_TO_PL);
29537784706SMoritz Fischer 
29637784706SMoritz Fischer 		/* create a rising edge on PCFG_INIT. PCFG_INIT follows
29737784706SMoritz Fischer 		 * PCFG_PROG_B, so we need to poll it after setting PCFG_PROG_B
29837784706SMoritz Fischer 		 * to make sure the rising edge actually happens.
29937784706SMoritz Fischer 		 * Note: PCFG_PROG_B is low active, sequence as described in
30037784706SMoritz Fischer 		 * UG585 v1.10 page 211
30137784706SMoritz Fischer 		 */
30237784706SMoritz Fischer 		ctrl = zynq_fpga_read(priv, CTRL_OFFSET);
30337784706SMoritz Fischer 		ctrl |= CTRL_PCFG_PROG_B_MASK;
30437784706SMoritz Fischer 
30537784706SMoritz Fischer 		zynq_fpga_write(priv, CTRL_OFFSET, ctrl);
30637784706SMoritz Fischer 
30737784706SMoritz Fischer 		err = zynq_fpga_poll_timeout(priv, STATUS_OFFSET, status,
30837784706SMoritz Fischer 					     status & STATUS_PCFG_INIT_MASK,
30937784706SMoritz Fischer 					     INIT_POLL_DELAY,
31037784706SMoritz Fischer 					     INIT_POLL_TIMEOUT);
31137784706SMoritz Fischer 		if (err) {
31280baf649SJason Gunthorpe 			dev_err(&mgr->dev, "Timeout waiting for PCFG_INIT\n");
31337784706SMoritz Fischer 			goto out_err;
31437784706SMoritz Fischer 		}
31537784706SMoritz Fischer 
31637784706SMoritz Fischer 		ctrl = zynq_fpga_read(priv, CTRL_OFFSET);
31737784706SMoritz Fischer 		ctrl &= ~CTRL_PCFG_PROG_B_MASK;
31837784706SMoritz Fischer 
31937784706SMoritz Fischer 		zynq_fpga_write(priv, CTRL_OFFSET, ctrl);
32037784706SMoritz Fischer 
32137784706SMoritz Fischer 		err = zynq_fpga_poll_timeout(priv, STATUS_OFFSET, status,
32237784706SMoritz Fischer 					     !(status & STATUS_PCFG_INIT_MASK),
32337784706SMoritz Fischer 					     INIT_POLL_DELAY,
32437784706SMoritz Fischer 					     INIT_POLL_TIMEOUT);
32537784706SMoritz Fischer 		if (err) {
32680baf649SJason Gunthorpe 			dev_err(&mgr->dev, "Timeout waiting for !PCFG_INIT\n");
32737784706SMoritz Fischer 			goto out_err;
32837784706SMoritz Fischer 		}
32937784706SMoritz Fischer 
33037784706SMoritz Fischer 		ctrl = zynq_fpga_read(priv, CTRL_OFFSET);
33137784706SMoritz Fischer 		ctrl |= CTRL_PCFG_PROG_B_MASK;
33237784706SMoritz Fischer 
33337784706SMoritz Fischer 		zynq_fpga_write(priv, CTRL_OFFSET, ctrl);
33437784706SMoritz Fischer 
33537784706SMoritz Fischer 		err = zynq_fpga_poll_timeout(priv, STATUS_OFFSET, status,
33637784706SMoritz Fischer 					     status & STATUS_PCFG_INIT_MASK,
33737784706SMoritz Fischer 					     INIT_POLL_DELAY,
33837784706SMoritz Fischer 					     INIT_POLL_TIMEOUT);
33937784706SMoritz Fischer 		if (err) {
34080baf649SJason Gunthorpe 			dev_err(&mgr->dev, "Timeout waiting for PCFG_INIT\n");
34137784706SMoritz Fischer 			goto out_err;
34237784706SMoritz Fischer 		}
34337784706SMoritz Fischer 	}
34437784706SMoritz Fischer 
34537784706SMoritz Fischer 	/* set configuration register with following options:
34637784706SMoritz Fischer 	 * - enable PCAP interface
347580e3137STom Rix 	 * - set throughput for maximum speed (if bistream not encrypted)
34837784706SMoritz Fischer 	 * - set CPU in user mode
34937784706SMoritz Fischer 	 */
35037784706SMoritz Fischer 	ctrl = zynq_fpga_read(priv, CTRL_OFFSET);
3517f33bbcaSMoritz Fischer 	if (info->flags & FPGA_MGR_ENCRYPTED_BITSTREAM)
35237784706SMoritz Fischer 		zynq_fpga_write(priv, CTRL_OFFSET,
3537f33bbcaSMoritz Fischer 				(CTRL_PCAP_PR_MASK | CTRL_PCAP_MODE_MASK
3547f33bbcaSMoritz Fischer 				 | CTRL_PCAP_RATE_EN_MASK | ctrl));
3557f33bbcaSMoritz Fischer 	else
3567f33bbcaSMoritz Fischer 		zynq_fpga_write(priv, CTRL_OFFSET,
3577f33bbcaSMoritz Fischer 				(CTRL_PCAP_PR_MASK | CTRL_PCAP_MODE_MASK
3587f33bbcaSMoritz Fischer 				 | ctrl));
3597f33bbcaSMoritz Fischer 
36037784706SMoritz Fischer 
361425902f5SJason Gunthorpe 	/* We expect that the command queue is empty right now. */
36237784706SMoritz Fischer 	status = zynq_fpga_read(priv, STATUS_OFFSET);
363425902f5SJason Gunthorpe 	if ((status & STATUS_DMA_Q_F) ||
364425902f5SJason Gunthorpe 	    (status & STATUS_DMA_Q_E) != STATUS_DMA_Q_E) {
365425902f5SJason Gunthorpe 		dev_err(&mgr->dev, "DMA command queue not right\n");
36637784706SMoritz Fischer 		err = -EBUSY;
36737784706SMoritz Fischer 		goto out_err;
36837784706SMoritz Fischer 	}
36937784706SMoritz Fischer 
37037784706SMoritz Fischer 	/* ensure internal PCAP loopback is disabled */
37137784706SMoritz Fischer 	ctrl = zynq_fpga_read(priv, MCTRL_OFFSET);
37237784706SMoritz Fischer 	zynq_fpga_write(priv, MCTRL_OFFSET, (~MCTRL_PCAP_LPBK_MASK & ctrl));
37337784706SMoritz Fischer 
37437784706SMoritz Fischer 	clk_disable(priv->clk);
37537784706SMoritz Fischer 
37637784706SMoritz Fischer 	return 0;
37737784706SMoritz Fischer 
37837784706SMoritz Fischer out_err:
37937784706SMoritz Fischer 	clk_disable(priv->clk);
38037784706SMoritz Fischer 
38137784706SMoritz Fischer 	return err;
38237784706SMoritz Fischer }
38337784706SMoritz Fischer 
zynq_fpga_ops_write(struct fpga_manager * mgr,struct sg_table * sgt)384425902f5SJason Gunthorpe static int zynq_fpga_ops_write(struct fpga_manager *mgr, struct sg_table *sgt)
38537784706SMoritz Fischer {
38637784706SMoritz Fischer 	struct zynq_fpga_priv *priv;
3876b45e0f2SJason Gunthorpe 	const char *why;
38837784706SMoritz Fischer 	int err;
38937784706SMoritz Fischer 	u32 intr_status;
390425902f5SJason Gunthorpe 	unsigned long timeout;
391425902f5SJason Gunthorpe 	unsigned long flags;
392425902f5SJason Gunthorpe 	struct scatterlist *sg;
393425902f5SJason Gunthorpe 	int i;
39437784706SMoritz Fischer 
39537784706SMoritz Fischer 	priv = mgr->priv;
39637784706SMoritz Fischer 
397425902f5SJason Gunthorpe 	/* The hardware can only DMA multiples of 4 bytes, and it requires the
398425902f5SJason Gunthorpe 	 * starting addresses to be aligned to 64 bits (UG585 pg 212).
399425902f5SJason Gunthorpe 	 */
400425902f5SJason Gunthorpe 	for_each_sg(sgt->sgl, sg, sgt->nents, i) {
401425902f5SJason Gunthorpe 		if ((sg->offset % 8) || (sg->length % 4)) {
402425902f5SJason Gunthorpe 			dev_err(&mgr->dev,
403425902f5SJason Gunthorpe 			    "Invalid bitstream, chunks must be aligned\n");
404425902f5SJason Gunthorpe 			return -EINVAL;
405425902f5SJason Gunthorpe 		}
406425902f5SJason Gunthorpe 	}
40737784706SMoritz Fischer 
408425902f5SJason Gunthorpe 	priv->dma_nelms =
409425902f5SJason Gunthorpe 	    dma_map_sg(mgr->dev.parent, sgt->sgl, sgt->nents, DMA_TO_DEVICE);
410425902f5SJason Gunthorpe 	if (priv->dma_nelms == 0) {
411425902f5SJason Gunthorpe 		dev_err(&mgr->dev, "Unable to DMA map (TO_DEVICE)\n");
412425902f5SJason Gunthorpe 		return -ENOMEM;
413425902f5SJason Gunthorpe 	}
41437784706SMoritz Fischer 
41537784706SMoritz Fischer 	/* enable clock */
41637784706SMoritz Fischer 	err = clk_enable(priv->clk);
41737784706SMoritz Fischer 	if (err)
41837784706SMoritz Fischer 		goto out_free;
41937784706SMoritz Fischer 
42037784706SMoritz Fischer 	zynq_fpga_write(priv, INT_STS_OFFSET, IXR_ALL_MASK);
42137784706SMoritz Fischer 	reinit_completion(&priv->dma_done);
42237784706SMoritz Fischer 
423425902f5SJason Gunthorpe 	/* zynq_step_dma will turn on interrupts */
424425902f5SJason Gunthorpe 	spin_lock_irqsave(&priv->dma_lock, flags);
425425902f5SJason Gunthorpe 	priv->dma_elm = 0;
426425902f5SJason Gunthorpe 	priv->cur_sg = sgt->sgl;
427425902f5SJason Gunthorpe 	zynq_step_dma(priv);
428425902f5SJason Gunthorpe 	spin_unlock_irqrestore(&priv->dma_lock, flags);
42937784706SMoritz Fischer 
430425902f5SJason Gunthorpe 	timeout = wait_for_completion_timeout(&priv->dma_done,
431425902f5SJason Gunthorpe 					      msecs_to_jiffies(DMA_TIMEOUT_MS));
43237784706SMoritz Fischer 
433425902f5SJason Gunthorpe 	spin_lock_irqsave(&priv->dma_lock, flags);
434425902f5SJason Gunthorpe 	zynq_fpga_set_irq(priv, 0);
435425902f5SJason Gunthorpe 	priv->cur_sg = NULL;
436425902f5SJason Gunthorpe 	spin_unlock_irqrestore(&priv->dma_lock, flags);
43737784706SMoritz Fischer 
43837784706SMoritz Fischer 	intr_status = zynq_fpga_read(priv, INT_STS_OFFSET);
439425902f5SJason Gunthorpe 	zynq_fpga_write(priv, INT_STS_OFFSET, IXR_ALL_MASK);
440425902f5SJason Gunthorpe 
441425902f5SJason Gunthorpe 	/* There doesn't seem to be a way to force cancel any DMA, so if
442425902f5SJason Gunthorpe 	 * something went wrong we are relying on the hardware to have halted
443425902f5SJason Gunthorpe 	 * the DMA before we get here, if there was we could use
444425902f5SJason Gunthorpe 	 * wait_for_completion_interruptible too.
445425902f5SJason Gunthorpe 	 */
44637784706SMoritz Fischer 
4476b45e0f2SJason Gunthorpe 	if (intr_status & IXR_ERROR_FLAGS_MASK) {
4486b45e0f2SJason Gunthorpe 		why = "DMA reported error";
4496b45e0f2SJason Gunthorpe 		err = -EIO;
4506b45e0f2SJason Gunthorpe 		goto out_report;
45137784706SMoritz Fischer 	}
45237784706SMoritz Fischer 
453425902f5SJason Gunthorpe 	if (priv->cur_sg ||
454425902f5SJason Gunthorpe 	    !((intr_status & IXR_D_P_DONE_MASK) == IXR_D_P_DONE_MASK)) {
455425902f5SJason Gunthorpe 		if (timeout == 0)
456425902f5SJason Gunthorpe 			why = "DMA timed out";
457425902f5SJason Gunthorpe 		else
4586b45e0f2SJason Gunthorpe 			why = "DMA did not complete";
4596b45e0f2SJason Gunthorpe 		err = -EIO;
4606b45e0f2SJason Gunthorpe 		goto out_report;
4616b45e0f2SJason Gunthorpe 	}
4626b45e0f2SJason Gunthorpe 
4636b45e0f2SJason Gunthorpe 	err = 0;
4646b45e0f2SJason Gunthorpe 	goto out_clk;
4656b45e0f2SJason Gunthorpe 
4666b45e0f2SJason Gunthorpe out_report:
4676b45e0f2SJason Gunthorpe 	dev_err(&mgr->dev,
4686b45e0f2SJason Gunthorpe 		"%s: INT_STS:0x%x CTRL:0x%x LOCK:0x%x INT_MASK:0x%x STATUS:0x%x MCTRL:0x%x\n",
4696b45e0f2SJason Gunthorpe 		why,
4706b45e0f2SJason Gunthorpe 		intr_status,
4716b45e0f2SJason Gunthorpe 		zynq_fpga_read(priv, CTRL_OFFSET),
4726b45e0f2SJason Gunthorpe 		zynq_fpga_read(priv, LOCK_OFFSET),
4736b45e0f2SJason Gunthorpe 		zynq_fpga_read(priv, INT_MASK_OFFSET),
4746b45e0f2SJason Gunthorpe 		zynq_fpga_read(priv, STATUS_OFFSET),
4756b45e0f2SJason Gunthorpe 		zynq_fpga_read(priv, MCTRL_OFFSET));
4766b45e0f2SJason Gunthorpe 
4776b45e0f2SJason Gunthorpe out_clk:
47837784706SMoritz Fischer 	clk_disable(priv->clk);
47937784706SMoritz Fischer 
48037784706SMoritz Fischer out_free:
481425902f5SJason Gunthorpe 	dma_unmap_sg(mgr->dev.parent, sgt->sgl, sgt->nents, DMA_TO_DEVICE);
48237784706SMoritz Fischer 	return err;
48337784706SMoritz Fischer }
48437784706SMoritz Fischer 
zynq_fpga_ops_write_complete(struct fpga_manager * mgr,struct fpga_image_info * info)4851df2865fSAlan Tull static int zynq_fpga_ops_write_complete(struct fpga_manager *mgr,
4861df2865fSAlan Tull 					struct fpga_image_info *info)
48737784706SMoritz Fischer {
48837784706SMoritz Fischer 	struct zynq_fpga_priv *priv = mgr->priv;
48937784706SMoritz Fischer 	int err;
49037784706SMoritz Fischer 	u32 intr_status;
49137784706SMoritz Fischer 
49237784706SMoritz Fischer 	err = clk_enable(priv->clk);
49337784706SMoritz Fischer 	if (err)
49437784706SMoritz Fischer 		return err;
49537784706SMoritz Fischer 
49637784706SMoritz Fischer 	err = zynq_fpga_poll_timeout(priv, INT_STS_OFFSET, intr_status,
49737784706SMoritz Fischer 				     intr_status & IXR_PCFG_DONE_MASK,
49837784706SMoritz Fischer 				     INIT_POLL_DELAY,
49937784706SMoritz Fischer 				     INIT_POLL_TIMEOUT);
50037784706SMoritz Fischer 
50147147d56SAlfonso Rodriguez 	/* Release 'PR' control back to the ICAP */
50247147d56SAlfonso Rodriguez 	zynq_fpga_write(priv, CTRL_OFFSET,
50347147d56SAlfonso Rodriguez 			zynq_fpga_read(priv, CTRL_OFFSET) & ~CTRL_PCAP_PR_MASK);
50447147d56SAlfonso Rodriguez 
50537784706SMoritz Fischer 	clk_disable(priv->clk);
50637784706SMoritz Fischer 
50737784706SMoritz Fischer 	if (err)
50837784706SMoritz Fischer 		return err;
50937784706SMoritz Fischer 
51037784706SMoritz Fischer 	/* for the partial reconfig case we didn't touch the level shifters */
5111df2865fSAlan Tull 	if (!(info->flags & FPGA_MGR_PARTIAL_RECONFIG)) {
51237784706SMoritz Fischer 		/* enable level shifters from PL to PS */
51337784706SMoritz Fischer 		regmap_write(priv->slcr, SLCR_LVL_SHFTR_EN_OFFSET,
51437784706SMoritz Fischer 			     LVL_SHFTR_ENABLE_PL_TO_PS);
51537784706SMoritz Fischer 
51637784706SMoritz Fischer 		/* deassert AXI interface resets */
51737784706SMoritz Fischer 		regmap_write(priv->slcr, SLCR_FPGA_RST_CTRL_OFFSET,
51837784706SMoritz Fischer 			     FPGA_RST_NONE_MASK);
51937784706SMoritz Fischer 	}
52037784706SMoritz Fischer 
52137784706SMoritz Fischer 	return 0;
52237784706SMoritz Fischer }
52337784706SMoritz Fischer 
zynq_fpga_ops_state(struct fpga_manager * mgr)52437784706SMoritz Fischer static enum fpga_mgr_states zynq_fpga_ops_state(struct fpga_manager *mgr)
52537784706SMoritz Fischer {
52637784706SMoritz Fischer 	int err;
52737784706SMoritz Fischer 	u32 intr_status;
52837784706SMoritz Fischer 	struct zynq_fpga_priv *priv;
52937784706SMoritz Fischer 
53037784706SMoritz Fischer 	priv = mgr->priv;
53137784706SMoritz Fischer 
53237784706SMoritz Fischer 	err = clk_enable(priv->clk);
53337784706SMoritz Fischer 	if (err)
53437784706SMoritz Fischer 		return FPGA_MGR_STATE_UNKNOWN;
53537784706SMoritz Fischer 
53637784706SMoritz Fischer 	intr_status = zynq_fpga_read(priv, INT_STS_OFFSET);
53737784706SMoritz Fischer 	clk_disable(priv->clk);
53837784706SMoritz Fischer 
53937784706SMoritz Fischer 	if (intr_status & IXR_PCFG_DONE_MASK)
54037784706SMoritz Fischer 		return FPGA_MGR_STATE_OPERATING;
54137784706SMoritz Fischer 
54237784706SMoritz Fischer 	return FPGA_MGR_STATE_UNKNOWN;
54337784706SMoritz Fischer }
54437784706SMoritz Fischer 
54537784706SMoritz Fischer static const struct fpga_manager_ops zynq_fpga_ops = {
546b496df86SJason Gunthorpe 	.initial_header_size = 128,
54737784706SMoritz Fischer 	.state = zynq_fpga_ops_state,
54837784706SMoritz Fischer 	.write_init = zynq_fpga_ops_write_init,
549425902f5SJason Gunthorpe 	.write_sg = zynq_fpga_ops_write,
55037784706SMoritz Fischer 	.write_complete = zynq_fpga_ops_write_complete,
55137784706SMoritz Fischer };
55237784706SMoritz Fischer 
zynq_fpga_probe(struct platform_device * pdev)55337784706SMoritz Fischer static int zynq_fpga_probe(struct platform_device *pdev)
55437784706SMoritz Fischer {
55537784706SMoritz Fischer 	struct device *dev = &pdev->dev;
55637784706SMoritz Fischer 	struct zynq_fpga_priv *priv;
5577085e2a9SAlan Tull 	struct fpga_manager *mgr;
55837784706SMoritz Fischer 	int err;
55937784706SMoritz Fischer 
56037784706SMoritz Fischer 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
56137784706SMoritz Fischer 	if (!priv)
56237784706SMoritz Fischer 		return -ENOMEM;
563425902f5SJason Gunthorpe 	spin_lock_init(&priv->dma_lock);
56437784706SMoritz Fischer 
565*e9fdc41aSYangtao Li 	priv->io_base = devm_platform_ioremap_resource(pdev, 0);
56637784706SMoritz Fischer 	if (IS_ERR(priv->io_base))
56737784706SMoritz Fischer 		return PTR_ERR(priv->io_base);
56837784706SMoritz Fischer 
56937784706SMoritz Fischer 	priv->slcr = syscon_regmap_lookup_by_phandle(dev->of_node,
57037784706SMoritz Fischer 		"syscon");
57137784706SMoritz Fischer 	if (IS_ERR(priv->slcr)) {
5721930c286SJason Gunthorpe 		dev_err(dev, "unable to get zynq-slcr regmap\n");
57337784706SMoritz Fischer 		return PTR_ERR(priv->slcr);
57437784706SMoritz Fischer 	}
57537784706SMoritz Fischer 
57637784706SMoritz Fischer 	init_completion(&priv->dma_done);
57737784706SMoritz Fischer 
57837784706SMoritz Fischer 	priv->irq = platform_get_irq(pdev, 0);
579d20c0da8SStephen Boyd 	if (priv->irq < 0)
58037784706SMoritz Fischer 		return priv->irq;
58137784706SMoritz Fischer 
58237784706SMoritz Fischer 	priv->clk = devm_clk_get(dev, "ref_clk");
5837872d423SYang Yingliang 	if (IS_ERR(priv->clk))
5847872d423SYang Yingliang 		return dev_err_probe(dev, PTR_ERR(priv->clk),
5857872d423SYang Yingliang 				     "input clock not found\n");
58637784706SMoritz Fischer 
58737784706SMoritz Fischer 	err = clk_prepare_enable(priv->clk);
58837784706SMoritz Fischer 	if (err) {
5891930c286SJason Gunthorpe 		dev_err(dev, "unable to enable clock\n");
59037784706SMoritz Fischer 		return err;
59137784706SMoritz Fischer 	}
59237784706SMoritz Fischer 
59337784706SMoritz Fischer 	/* unlock the device */
59437784706SMoritz Fischer 	zynq_fpga_write(priv, UNLOCK_OFFSET, UNLOCK_MASK);
59537784706SMoritz Fischer 
5966b45e0f2SJason Gunthorpe 	zynq_fpga_set_irq(priv, 0);
597340c0c53SJason Gunthorpe 	zynq_fpga_write(priv, INT_STS_OFFSET, IXR_ALL_MASK);
598340c0c53SJason Gunthorpe 	err = devm_request_irq(dev, priv->irq, zynq_fpga_isr, 0, dev_name(dev),
599340c0c53SJason Gunthorpe 			       priv);
600340c0c53SJason Gunthorpe 	if (err) {
601340c0c53SJason Gunthorpe 		dev_err(dev, "unable to request IRQ\n");
602340c0c53SJason Gunthorpe 		clk_disable_unprepare(priv->clk);
603340c0c53SJason Gunthorpe 		return err;
604340c0c53SJason Gunthorpe 	}
605340c0c53SJason Gunthorpe 
60637784706SMoritz Fischer 	clk_disable(priv->clk);
60737784706SMoritz Fischer 
6084ba0b2c2SRuss Weight 	mgr = fpga_mgr_register(dev, "Xilinx Zynq FPGA Manager",
60937784706SMoritz Fischer 				&zynq_fpga_ops, priv);
6104ba0b2c2SRuss Weight 	if (IS_ERR(mgr)) {
6111930c286SJason Gunthorpe 		dev_err(dev, "unable to register FPGA manager\n");
6126376931bSMoritz Fischer 		clk_unprepare(priv->clk);
6134ba0b2c2SRuss Weight 		return PTR_ERR(mgr);
61437784706SMoritz Fischer 	}
61537784706SMoritz Fischer 
6164ba0b2c2SRuss Weight 	platform_set_drvdata(pdev, mgr);
6174ba0b2c2SRuss Weight 
61837784706SMoritz Fischer 	return 0;
61937784706SMoritz Fischer }
62037784706SMoritz Fischer 
zynq_fpga_remove(struct platform_device * pdev)62137784706SMoritz Fischer static int zynq_fpga_remove(struct platform_device *pdev)
62237784706SMoritz Fischer {
62337784706SMoritz Fischer 	struct zynq_fpga_priv *priv;
62428f98a12SMoritz Fischer 	struct fpga_manager *mgr;
62528f98a12SMoritz Fischer 
62628f98a12SMoritz Fischer 	mgr = platform_get_drvdata(pdev);
62728f98a12SMoritz Fischer 	priv = mgr->priv;
62837784706SMoritz Fischer 
6297085e2a9SAlan Tull 	fpga_mgr_unregister(mgr);
63037784706SMoritz Fischer 
6316376931bSMoritz Fischer 	clk_unprepare(priv->clk);
63237784706SMoritz Fischer 
63337784706SMoritz Fischer 	return 0;
63437784706SMoritz Fischer }
63537784706SMoritz Fischer 
63637784706SMoritz Fischer #ifdef CONFIG_OF
63737784706SMoritz Fischer static const struct of_device_id zynq_fpga_of_match[] = {
63837784706SMoritz Fischer 	{ .compatible = "xlnx,zynq-devcfg-1.0", },
63937784706SMoritz Fischer 	{},
64037784706SMoritz Fischer };
64137784706SMoritz Fischer 
64237784706SMoritz Fischer MODULE_DEVICE_TABLE(of, zynq_fpga_of_match);
64337784706SMoritz Fischer #endif
64437784706SMoritz Fischer 
64537784706SMoritz Fischer static struct platform_driver zynq_fpga_driver = {
64637784706SMoritz Fischer 	.probe = zynq_fpga_probe,
64737784706SMoritz Fischer 	.remove = zynq_fpga_remove,
64837784706SMoritz Fischer 	.driver = {
64937784706SMoritz Fischer 		.name = "zynq_fpga_manager",
65037784706SMoritz Fischer 		.of_match_table = of_match_ptr(zynq_fpga_of_match),
65137784706SMoritz Fischer 	},
65237784706SMoritz Fischer };
65337784706SMoritz Fischer 
65437784706SMoritz Fischer module_platform_driver(zynq_fpga_driver);
65537784706SMoritz Fischer 
65637784706SMoritz Fischer MODULE_AUTHOR("Moritz Fischer <moritz.fischer@ettus.com>");
65737784706SMoritz Fischer MODULE_AUTHOR("Michal Simek <michal.simek@xilinx.com>");
65837784706SMoritz Fischer MODULE_DESCRIPTION("Xilinx Zynq FPGA Manager");
65937784706SMoritz Fischer MODULE_LICENSE("GPL v2");
660