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