113-add-xilinx-devcfg-char-node.patch 60 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231
  1. --- a/drivers/char/Kconfig
  2. +++ b/drivers/char/Kconfig
  3. @@ -387,6 +387,13 @@ config XILINX_HWICAP
  4. If unsure, say N.
  5. +config XILINX_DEVCFG
  6. + tristate "Xilinx Device Configuration"
  7. + depends on ARCH_ZYNQ
  8. + help
  9. + This option enables support for the Xilinx device configuration driver.
  10. + If unsure, say N
  11. +
  12. config R3964
  13. tristate "Siemens R3964 line discipline"
  14. depends on TTY
  15. --- a/drivers/char/Makefile
  16. +++ b/drivers/char/Makefile
  17. @@ -29,6 +29,7 @@ obj-$(CONFIG_GEN_RTC) += genrtc.o
  18. obj-$(CONFIG_EFI_RTC) += efirtc.o
  19. obj-$(CONFIG_DS1302) += ds1302.o
  20. obj-$(CONFIG_XILINX_HWICAP) += xilinx_hwicap/
  21. +obj-$(CONFIG_XILINX_DEVCFG) += xilinx_devcfg.o
  22. ifeq ($(CONFIG_GENERIC_NVRAM),y)
  23. obj-$(CONFIG_NVRAM) += generic_nvram.o
  24. else
  25. --- /dev/null
  26. +++ b/drivers/char/xilinx_devcfg.c
  27. @@ -0,0 +1,2105 @@
  28. +/*
  29. + * Xilinx Zynq Device Config driver
  30. + *
  31. + * Copyright (c) 2011 - 2013 Xilinx Inc.
  32. + *
  33. + * This program is free software; you can redistribute it and/or
  34. + * modify it under the terms of the GNU General Public License
  35. + * as published by the Free Software Foundation; either version
  36. + * 2 of the License, or (at your option) any later version.
  37. + */
  38. +
  39. +#include <linux/cdev.h>
  40. +#include <linux/clk.h>
  41. +#include <linux/delay.h>
  42. +#include <linux/dma-mapping.h>
  43. +#include <linux/fs.h>
  44. +#include <linux/init.h>
  45. +#include <linux/interrupt.h>
  46. +#include <linux/io.h>
  47. +#include <linux/ioport.h>
  48. +#include <linux/kernel.h>
  49. +#include <linux/module.h>
  50. +#include <linux/mutex.h>
  51. +#include <linux/of.h>
  52. +#include <linux/platform_device.h>
  53. +#include <linux/slab.h>
  54. +#include <linux/string.h>
  55. +#include <linux/sysctl.h>
  56. +#include <linux/types.h>
  57. +#include <linux/uaccess.h>
  58. +
  59. +extern void zynq_slcr_init_preload_fpga(void);
  60. +extern void zynq_slcr_init_postload_fpga(void);
  61. +
  62. +#define DRIVER_NAME "xdevcfg"
  63. +#define XDEVCFG_DEVICES 1
  64. +
  65. +/* An array, which is set to true when the device is registered. */
  66. +static DEFINE_MUTEX(xdevcfg_mutex);
  67. +
  68. +/* Constant Definitions */
  69. +#define XDCFG_CTRL_OFFSET 0x00 /* Control Register */
  70. +#define XDCFG_LOCK_OFFSET 0x04 /* Lock Register */
  71. +#define XDCFG_INT_STS_OFFSET 0x0C /* Interrupt Status Register */
  72. +#define XDCFG_INT_MASK_OFFSET 0x10 /* Interrupt Mask Register */
  73. +#define XDCFG_STATUS_OFFSET 0x14 /* Status Register */
  74. +#define XDCFG_DMA_SRC_ADDR_OFFSET 0x18 /* DMA Source Address Register */
  75. +#define XDCFG_DMA_DEST_ADDR_OFFSET 0x1C /* DMA Destination Address Reg */
  76. +#define XDCFG_DMA_SRC_LEN_OFFSET 0x20 /* DMA Source Transfer Length */
  77. +#define XDCFG_DMA_DEST_LEN_OFFSET 0x24 /* DMA Destination Transfer */
  78. +#define XDCFG_UNLOCK_OFFSET 0x34 /* Unlock Register */
  79. +#define XDCFG_MCTRL_OFFSET 0x80 /* Misc. Control Register */
  80. +
  81. +/* Control Register Bit definitions */
  82. +#define XDCFG_CTRL_PCFG_PROG_B_MASK 0x40000000 /* Program signal to
  83. + * Reset FPGA */
  84. +#define XDCFG_CTRL_PCAP_PR_MASK 0x08000000 /* Enable PCAP for PR */
  85. +#define XDCFG_CTRL_PCAP_MODE_MASK 0x04000000 /* Enable PCAP */
  86. +#define XDCFG_CTRL_PCAP_RATE_EN_MASK 0x02000000 /* Enable PCAP Quad Rate */
  87. +#define XDCFG_CTRL_PCFG_AES_EN_MASK 0x00000E00 /* AES Enable Mask */
  88. +#define XDCFG_CTRL_SEU_EN_MASK 0x00000100 /* SEU Enable Mask */
  89. +#define XDCFG_CTRL_SPNIDEN_MASK 0x00000040 /* Secure Non Invasive
  90. + * Debug Enable */
  91. +#define XDCFG_CTRL_SPIDEN_MASK 0x00000020 /* Secure Invasive
  92. + * Debug Enable */
  93. +#define XDCFG_CTRL_NIDEN_MASK 0x00000010 /* Non-Invasive Debug
  94. + * Enable */
  95. +#define XDCFG_CTRL_DBGEN_MASK 0x00000008 /* Invasive Debug
  96. + * Enable */
  97. +#define XDCFG_CTRL_DAP_EN_MASK 0x00000007 /* DAP Enable Mask */
  98. +
  99. +/* Lock register bit definitions */
  100. +
  101. +#define XDCFG_LOCK_AES_EN_MASK 0x00000008 /* Lock AES_EN update */
  102. +#define XDCFG_LOCK_SEU_MASK 0x00000004 /* Lock SEU_En update */
  103. +#define XDCFG_LOCK_DBG_MASK 0x00000001 /* This bit locks
  104. + * security config
  105. + * including: DAP_En,
  106. + * DBGEN,NIDEN, SPNIEN */
  107. +
  108. +/* Miscellaneous Control Register bit definitions */
  109. +#define XDCFG_MCTRL_PCAP_LPBK_MASK 0x00000010 /* Internal PCAP loopback */
  110. +
  111. +/* Status register bit definitions */
  112. +#define XDCFG_STATUS_PCFG_INIT_MASK 0x00000010 /* FPGA init status */
  113. +
  114. +/* Interrupt Status/Mask Register Bit definitions */
  115. +#define XDCFG_IXR_DMA_DONE_MASK 0x00002000 /* DMA Command Done */
  116. +#define XDCFG_IXR_D_P_DONE_MASK 0x00001000 /* DMA and PCAP Cmd Done */
  117. +#define XDCFG_IXR_PCFG_DONE_MASK 0x00000004 /* FPGA programmed */
  118. +#define XDCFG_IXR_ERROR_FLAGS_MASK 0x00F0F860
  119. +#define XDCFG_IXR_ALL_MASK 0xF8F7F87F
  120. +/* Miscellaneous constant values */
  121. +#define XDCFG_DMA_INVALID_ADDRESS 0xFFFFFFFF /* Invalid DMA address */
  122. +
  123. +static const char * const fclk_name[] = {
  124. + "fclk0",
  125. + "fclk1",
  126. + "fclk2",
  127. + "fclk3"
  128. +};
  129. +#define NUMFCLKS ARRAY_SIZE(fclk_name)
  130. +
  131. +/**
  132. + * struct xdevcfg_drvdata - Device Configuration driver structure
  133. + *
  134. + * @dev: Pointer to the device structure
  135. + * @cdev: Instance of the cdev structure
  136. + * @devt: Pointer to the dev_t structure
  137. + * @class: Pointer to device class
  138. + * @fclk_class: Pointer to fclk device class
  139. + * @dma_done: The dma_done status bit for the DMA command completion
  140. + * @error_status: The error status captured during the DMA transfer
  141. + * @irq: Interrupt number
  142. + * @clk: Peripheral clock for devcfg
  143. + * @fclk: Array holding references to the FPGA clocks
  144. + * @fclk_exported: Flag inidcating whether an FPGA clock is exported
  145. + * @is_open: The status bit to indicate whether the device is opened
  146. + * @sem: Instance for the mutex
  147. + * @lock: Instance of spinlock
  148. + * @base_address: The virtual device base address of the device registers
  149. + * @is_partial_bitstream: Status bit to indicate partial/full bitstream
  150. + */
  151. +struct xdevcfg_drvdata {
  152. + struct device *dev;
  153. + struct cdev cdev;
  154. + dev_t devt;
  155. + struct class *class;
  156. + struct class *fclk_class;
  157. + int irq;
  158. + struct clk *clk;
  159. + struct clk *fclk[NUMFCLKS];
  160. + u8 fclk_exported[NUMFCLKS];
  161. + volatile bool dma_done;
  162. + volatile int error_status;
  163. + bool is_open;
  164. + struct mutex sem;
  165. + spinlock_t lock;
  166. + void __iomem *base_address;
  167. + int ep107;
  168. + bool is_partial_bitstream;
  169. + bool endian_swap;
  170. + char residue_buf[3];
  171. + int residue_len;
  172. +};
  173. +
  174. +/**
  175. + * struct fclk_data - FPGA clock data
  176. + * @clk: Pointer to clock
  177. + * @enable: Flag indicating enable status of the clock
  178. + * @rate_rnd: Rate to be rounded for round rate operation
  179. + */
  180. +struct fclk_data {
  181. + struct clk *clk;
  182. + int enabled;
  183. + unsigned long rate_rnd;
  184. +};
  185. +
  186. +/* Register read/write access routines */
  187. +#define xdevcfg_writereg(offset, val) __raw_writel(val, offset)
  188. +#define xdevcfg_readreg(offset) __raw_readl(offset)
  189. +
  190. +/**
  191. + * xdevcfg_reset_pl() - Reset the programmable logic.
  192. + * @base_address: The base address of the device.
  193. + *
  194. + * Must be called with PCAP clock enabled
  195. + */
  196. +static void xdevcfg_reset_pl(void __iomem *base_address)
  197. +{
  198. + /*
  199. + * Create a rising edge on PCFG_INIT. PCFG_INIT follows PCFG_PROG_B,
  200. + * so we need to * poll it after setting PCFG_PROG_B to make sure that
  201. + * the rising edge happens.
  202. + */
  203. + xdevcfg_writereg(base_address + XDCFG_CTRL_OFFSET,
  204. + (xdevcfg_readreg(base_address + XDCFG_CTRL_OFFSET) |
  205. + XDCFG_CTRL_PCFG_PROG_B_MASK));
  206. + while (!(xdevcfg_readreg(base_address + XDCFG_STATUS_OFFSET) &
  207. + XDCFG_STATUS_PCFG_INIT_MASK))
  208. + ;
  209. +
  210. + xdevcfg_writereg(base_address + XDCFG_CTRL_OFFSET,
  211. + (xdevcfg_readreg(base_address + XDCFG_CTRL_OFFSET) &
  212. + ~XDCFG_CTRL_PCFG_PROG_B_MASK));
  213. + while (xdevcfg_readreg(base_address + XDCFG_STATUS_OFFSET) &
  214. + XDCFG_STATUS_PCFG_INIT_MASK)
  215. + ;
  216. +
  217. + msleep(5);
  218. + xdevcfg_writereg(base_address + XDCFG_CTRL_OFFSET,
  219. + (xdevcfg_readreg(base_address + XDCFG_CTRL_OFFSET) |
  220. + XDCFG_CTRL_PCFG_PROG_B_MASK));
  221. + while (!(xdevcfg_readreg(base_address + XDCFG_STATUS_OFFSET) &
  222. + XDCFG_STATUS_PCFG_INIT_MASK))
  223. + ;
  224. +}
  225. +
  226. +/**
  227. + * xdevcfg_irq() - The main interrupt handler.
  228. + * @irq: The interrupt number.
  229. + * @data: Pointer to the driver data structure.
  230. + * returns: IRQ_HANDLED after the interrupt is handled.
  231. + **/
  232. +static irqreturn_t xdevcfg_irq(int irq, void *data)
  233. +{
  234. + u32 intr_status;
  235. + struct xdevcfg_drvdata *drvdata = data;
  236. +
  237. + spin_lock(&drvdata->lock);
  238. +
  239. + intr_status = xdevcfg_readreg(drvdata->base_address +
  240. + XDCFG_INT_STS_OFFSET);
  241. +
  242. + /* Clear the interrupts */
  243. + xdevcfg_writereg(drvdata->base_address + XDCFG_INT_STS_OFFSET,
  244. + intr_status);
  245. +
  246. + if ((intr_status & XDCFG_IXR_D_P_DONE_MASK) ==
  247. + XDCFG_IXR_D_P_DONE_MASK)
  248. + drvdata->dma_done = 1;
  249. +
  250. + if ((intr_status & XDCFG_IXR_ERROR_FLAGS_MASK) ==
  251. + XDCFG_IXR_ERROR_FLAGS_MASK)
  252. + drvdata->error_status = 1;
  253. +
  254. + spin_unlock(&drvdata->lock);
  255. +
  256. + return IRQ_HANDLED;
  257. +}
  258. +
  259. +/**
  260. + * xdevcfg_write() - The is the driver write function.
  261. + *
  262. + * @file: Pointer to the file structure.
  263. + * @buf: Pointer to the bitstream location.
  264. + * @count: The number of bytes to be written.
  265. + * @ppos: Pointer to the offset value
  266. + * returns: Success or error status.
  267. + **/
  268. +static ssize_t
  269. +xdevcfg_write(struct file *file, const char __user *buf, size_t count,
  270. + loff_t *ppos)
  271. +{
  272. + char *kbuf;
  273. + int status;
  274. + unsigned long timeout;
  275. + u32 intr_reg, dma_len;
  276. + dma_addr_t dma_addr;
  277. + u32 transfer_length = 0;
  278. + struct xdevcfg_drvdata *drvdata = file->private_data;
  279. + size_t user_count = count;
  280. + int i;
  281. +
  282. + status = clk_enable(drvdata->clk);
  283. + if (status)
  284. + return status;
  285. +
  286. + status = mutex_lock_interruptible(&drvdata->sem);
  287. +
  288. + if (status)
  289. + goto err_clk;
  290. +
  291. + dma_len = count + drvdata->residue_len;
  292. + kbuf = dma_alloc_coherent(drvdata->dev, dma_len, &dma_addr, GFP_KERNEL);
  293. + if (!kbuf) {
  294. + status = -ENOMEM;
  295. + goto err_unlock;
  296. + }
  297. +
  298. + /* Collect stragglers from last time (0 to 3 bytes) */
  299. + memcpy(kbuf, drvdata->residue_buf, drvdata->residue_len);
  300. +
  301. + /* Fetch user data, appending to stragglers */
  302. + if (copy_from_user(kbuf + drvdata->residue_len, buf, count)) {
  303. + status = -EFAULT;
  304. + goto error;
  305. + }
  306. +
  307. + /* Include stragglers in total bytes to be handled */
  308. + count += drvdata->residue_len;
  309. +
  310. + /* First block contains a header */
  311. + if (*ppos == 0 && count > 4) {
  312. + /* Look for sync word */
  313. + for (i = 0; i < count - 4; i++) {
  314. + if (memcmp(kbuf + i, "\x66\x55\x99\xAA", 4) == 0) {
  315. + pr_debug("Found normal sync word\n");
  316. + drvdata->endian_swap = 0;
  317. + break;
  318. + }
  319. + if (memcmp(kbuf + i, "\xAA\x99\x55\x66", 4) == 0) {
  320. + pr_debug("Found swapped sync word\n");
  321. + drvdata->endian_swap = 1;
  322. + break;
  323. + }
  324. + }
  325. + /* Remove the header, aligning the data on word boundary */
  326. + if (i != count - 4) {
  327. + count -= i;
  328. + memmove(kbuf, kbuf + i, count);
  329. + }
  330. + }
  331. +
  332. + /* Save stragglers for next time */
  333. + drvdata->residue_len = count % 4;
  334. + count -= drvdata->residue_len;
  335. + memcpy(drvdata->residue_buf, kbuf + count, drvdata->residue_len);
  336. +
  337. + /* Fixup endianess of the data */
  338. + if (drvdata->endian_swap) {
  339. + for (i = 0; i < count; i += 4) {
  340. + u32 *p = (u32 *)&kbuf[i];
  341. + *p = swab32(*p);
  342. + }
  343. + }
  344. +
  345. + /* Enable DMA and error interrupts */
  346. + xdevcfg_writereg(drvdata->base_address + XDCFG_INT_STS_OFFSET,
  347. + XDCFG_IXR_ALL_MASK);
  348. +
  349. +
  350. + xdevcfg_writereg(drvdata->base_address + XDCFG_INT_MASK_OFFSET,
  351. + (u32) (~(XDCFG_IXR_D_P_DONE_MASK |
  352. + XDCFG_IXR_ERROR_FLAGS_MASK)));
  353. +
  354. + drvdata->dma_done = 0;
  355. + drvdata->error_status = 0;
  356. +
  357. + /* Initiate DMA write command */
  358. + if (count < 0x1000)
  359. + xdevcfg_writereg(drvdata->base_address +
  360. + XDCFG_DMA_SRC_ADDR_OFFSET, (u32)(dma_addr + 1));
  361. + else
  362. + xdevcfg_writereg(drvdata->base_address +
  363. + XDCFG_DMA_SRC_ADDR_OFFSET, (u32) dma_addr);
  364. +
  365. + xdevcfg_writereg(drvdata->base_address + XDCFG_DMA_DEST_ADDR_OFFSET,
  366. + (u32)XDCFG_DMA_INVALID_ADDRESS);
  367. + /* Convert number of bytes to number of words. */
  368. + if (count % 4)
  369. + transfer_length = (count / 4 + 1);
  370. + else
  371. + transfer_length = count / 4;
  372. + xdevcfg_writereg(drvdata->base_address + XDCFG_DMA_SRC_LEN_OFFSET,
  373. + transfer_length);
  374. + xdevcfg_writereg(drvdata->base_address + XDCFG_DMA_DEST_LEN_OFFSET, 0);
  375. +
  376. + timeout = jiffies + msecs_to_jiffies(1000);
  377. +
  378. + while (!drvdata->dma_done) {
  379. + if (time_after(jiffies, timeout)) {
  380. + status = -ETIMEDOUT;
  381. + goto error;
  382. + }
  383. + }
  384. +
  385. + if (drvdata->error_status)
  386. + status = drvdata->error_status;
  387. +
  388. + /* Disable the DMA and error interrupts */
  389. + intr_reg = xdevcfg_readreg(drvdata->base_address +
  390. + XDCFG_INT_MASK_OFFSET);
  391. + xdevcfg_writereg(drvdata->base_address + XDCFG_INT_MASK_OFFSET,
  392. + intr_reg | (XDCFG_IXR_D_P_DONE_MASK |
  393. + XDCFG_IXR_ERROR_FLAGS_MASK));
  394. +
  395. + /* If we didn't write correctly, then bail out. */
  396. + if (status) {
  397. + status = -EFAULT;
  398. + goto error;
  399. + }
  400. +
  401. + *ppos += user_count;
  402. + status = user_count;
  403. +
  404. +error:
  405. + dma_free_coherent(drvdata->dev, dma_len, kbuf, dma_addr);
  406. +err_unlock:
  407. + mutex_unlock(&drvdata->sem);
  408. +err_clk:
  409. + clk_disable(drvdata->clk);
  410. + return status;
  411. +}
  412. +
  413. +
  414. +/**
  415. + * xdevcfg_read() - The is the driver read function.
  416. + * @file: Pointer to the file structure.
  417. + * @buf: Pointer to the bitstream location.
  418. + * @count: The number of bytes read.
  419. + * @ppos: Pointer to the offsetvalue
  420. + * returns: Success or error status.
  421. + */
  422. +static ssize_t
  423. +xdevcfg_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
  424. +{
  425. + u32 *kbuf;
  426. + int status;
  427. + unsigned long timeout;
  428. + dma_addr_t dma_addr;
  429. + struct xdevcfg_drvdata *drvdata = file->private_data;
  430. + u32 intr_reg;
  431. +
  432. + status = clk_enable(drvdata->clk);
  433. + if (status)
  434. + return status;
  435. +
  436. + status = mutex_lock_interruptible(&drvdata->sem);
  437. + if (status)
  438. + goto err_clk;
  439. +
  440. + /* Get new data from the ICAP, and return was requested. */
  441. + kbuf = dma_alloc_coherent(drvdata->dev, count, &dma_addr, GFP_KERNEL);
  442. + if (!kbuf) {
  443. + status = -ENOMEM;
  444. + goto err_unlock;
  445. + }
  446. +
  447. + drvdata->dma_done = 0;
  448. + drvdata->error_status = 0;
  449. +
  450. + /* Enable DMA and error interrupts */
  451. + xdevcfg_writereg(drvdata->base_address + XDCFG_INT_STS_OFFSET,
  452. + XDCFG_IXR_ALL_MASK);
  453. +
  454. + xdevcfg_writereg(drvdata->base_address + XDCFG_INT_MASK_OFFSET,
  455. + (u32) (~(XDCFG_IXR_D_P_DONE_MASK |
  456. + XDCFG_IXR_ERROR_FLAGS_MASK)));
  457. + /* Initiate DMA read command */
  458. + xdevcfg_writereg(drvdata->base_address + XDCFG_DMA_SRC_ADDR_OFFSET,
  459. + (u32)XDCFG_DMA_INVALID_ADDRESS);
  460. + xdevcfg_writereg(drvdata->base_address + XDCFG_DMA_DEST_ADDR_OFFSET,
  461. + (u32)dma_addr);
  462. + xdevcfg_writereg(drvdata->base_address + XDCFG_DMA_SRC_LEN_OFFSET, 0);
  463. + xdevcfg_writereg(drvdata->base_address + XDCFG_DMA_DEST_LEN_OFFSET,
  464. + count / 4);
  465. +
  466. + timeout = jiffies + msecs_to_jiffies(1000);
  467. +
  468. + while (!drvdata->dma_done) {
  469. + if (time_after(jiffies, timeout)) {
  470. + status = -ETIMEDOUT;
  471. + goto error;
  472. + }
  473. + }
  474. +
  475. + if (drvdata->error_status)
  476. + status = drvdata->error_status;
  477. +
  478. + /* Disable and clear DMA and error interrupts */
  479. + intr_reg = xdevcfg_readreg(drvdata->base_address +
  480. + XDCFG_INT_MASK_OFFSET);
  481. + xdevcfg_writereg(drvdata->base_address + XDCFG_INT_MASK_OFFSET,
  482. + intr_reg | (XDCFG_IXR_D_P_DONE_MASK |
  483. + XDCFG_IXR_ERROR_FLAGS_MASK));
  484. +
  485. +
  486. + /* If we didn't read correctly, then bail out. */
  487. + if (status) {
  488. + status = -EFAULT;
  489. + goto error;
  490. + }
  491. +
  492. + /* If we fail to return the data to the user, then bail out. */
  493. + if (copy_to_user(buf, kbuf, count)) {
  494. + status = -EFAULT;
  495. + goto error;
  496. + }
  497. +
  498. + status = count;
  499. +error:
  500. + dma_free_coherent(drvdata->dev, count, kbuf, dma_addr);
  501. +err_unlock:
  502. + mutex_unlock(&drvdata->sem);
  503. +err_clk:
  504. + clk_disable(drvdata->clk);
  505. +
  506. + return status;
  507. +}
  508. +
  509. +static void xdevcfg_enable_partial(struct xdevcfg_drvdata *drvdata)
  510. +{
  511. + u32 reg = xdevcfg_readreg(drvdata->base_address + XDCFG_CTRL_OFFSET);
  512. +
  513. + xdevcfg_writereg(drvdata->base_address + XDCFG_CTRL_OFFSET,
  514. + reg | XDCFG_CTRL_PCAP_PR_MASK);
  515. +}
  516. +
  517. +static void xdevcfg_disable_partial(struct xdevcfg_drvdata *drvdata)
  518. +{
  519. + u32 reg = xdevcfg_readreg(drvdata->base_address + XDCFG_CTRL_OFFSET);
  520. +
  521. + xdevcfg_writereg(drvdata->base_address + XDCFG_CTRL_OFFSET,
  522. + reg & ~XDCFG_CTRL_PCAP_PR_MASK);
  523. +}
  524. +
  525. +/**
  526. + * xdevcfg_open() - The is the driver open function.
  527. + * @inode: Pointer to the inode structure of this device.
  528. + * @file: Pointer to the file structure.
  529. + * returns: Success or error status.
  530. + */
  531. +static int xdevcfg_open(struct inode *inode, struct file *file)
  532. +{
  533. + struct xdevcfg_drvdata *drvdata;
  534. + int status;
  535. +
  536. + drvdata = container_of(inode->i_cdev, struct xdevcfg_drvdata, cdev);
  537. +
  538. + status = clk_enable(drvdata->clk);
  539. + if (status)
  540. + return status;
  541. +
  542. + status = mutex_lock_interruptible(&drvdata->sem);
  543. + if (status)
  544. + goto err_clk;
  545. +
  546. + if (drvdata->is_open) {
  547. + status = -EBUSY;
  548. + goto error;
  549. + }
  550. +
  551. + file->private_data = drvdata;
  552. + drvdata->is_open = 1;
  553. + drvdata->endian_swap = 0;
  554. + drvdata->residue_len= 0;
  555. +
  556. + /*
  557. + * If is_partial_bitstream is set, then PROG_B is not asserted
  558. + * (xdevcfg_reset_pl function) and also zynq_slcr_init_preload_fpga and
  559. + * zynq_slcr_init_postload_fpga functions are not invoked.
  560. + */
  561. + if (drvdata->is_partial_bitstream)
  562. + xdevcfg_enable_partial(drvdata);
  563. + else
  564. + zynq_slcr_init_preload_fpga();
  565. +
  566. + /*
  567. + * Only do the reset of the PL for Zynq as it causes problems on the
  568. + * EP107 and the issue is not understood, but not worth investigating
  569. + * as the emulation platform is very different than silicon and not a
  570. + * complete implementation. Also, do not reset if it is a partial
  571. + * bitstream.
  572. + */
  573. + if ((!drvdata->ep107) && (!drvdata->is_partial_bitstream))
  574. + xdevcfg_reset_pl(drvdata->base_address);
  575. +
  576. + xdevcfg_writereg(drvdata->base_address + XDCFG_INT_STS_OFFSET,
  577. + XDCFG_IXR_PCFG_DONE_MASK);
  578. +
  579. +error:
  580. + mutex_unlock(&drvdata->sem);
  581. +err_clk:
  582. + clk_disable(drvdata->clk);
  583. + return status;
  584. +}
  585. +
  586. +/**
  587. + * xdevcfg_release() - The is the driver release function.
  588. + * @inode: Pointer to the inode structure of this device.
  589. + * @file: Pointer to the file structure.
  590. + * returns: Success.
  591. + */
  592. +static int xdevcfg_release(struct inode *inode, struct file *file)
  593. +{
  594. + struct xdevcfg_drvdata *drvdata = file->private_data;
  595. +
  596. + if (drvdata->is_partial_bitstream)
  597. + xdevcfg_disable_partial(drvdata);
  598. + else
  599. + zynq_slcr_init_postload_fpga();
  600. +
  601. +
  602. + if (drvdata->residue_len)
  603. + printk("Did not transfer last %d bytes\n",
  604. + drvdata->residue_len);
  605. +
  606. + drvdata->is_open = 0;
  607. +
  608. + return 0;
  609. +}
  610. +
  611. +static const struct file_operations xdevcfg_fops = {
  612. + .owner = THIS_MODULE,
  613. + .write = xdevcfg_write,
  614. + .read = xdevcfg_read,
  615. + .open = xdevcfg_open,
  616. + .release = xdevcfg_release,
  617. +};
  618. +
  619. +/*
  620. + * The following functions are the routines provided to the user to
  621. + * set/get the status bit value in the control/lock registers.
  622. + */
  623. +
  624. +/**
  625. + * xdevcfg_set_dap_en() - This function sets the DAP bits in the
  626. + * control register with the given value.
  627. + * @dev: Pointer to the device structure.
  628. + * @attr: Pointer to the device attribute structure.
  629. + * @buf: Pointer to the buffer location for the configuration
  630. + * data.
  631. + * @size: The number of bytes used from the buffer
  632. + * returns: negative error if the string could not be converted
  633. + * or the size of the buffer.
  634. + */
  635. +static ssize_t xdevcfg_set_dap_en(struct device *dev,
  636. + struct device_attribute *attr, const char *buf, size_t size)
  637. +{
  638. + u32 ctrl_reg_status;
  639. + unsigned long flags;
  640. + unsigned long mask_bit;
  641. + int status;
  642. + struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
  643. +
  644. + status = clk_enable(drvdata->clk);
  645. + if (status)
  646. + return status;
  647. +
  648. + ctrl_reg_status = xdevcfg_readreg(drvdata->base_address +
  649. + XDCFG_CTRL_OFFSET);
  650. + spin_lock_irqsave(&drvdata->lock, flags);
  651. +
  652. + status = kstrtoul(buf, 10, &mask_bit);
  653. +
  654. + if (status)
  655. + goto err_unlock;
  656. +
  657. + if (mask_bit > 7) {
  658. + status = -EINVAL;
  659. + goto err_unlock;
  660. + }
  661. +
  662. + xdevcfg_writereg(drvdata->base_address + XDCFG_CTRL_OFFSET,
  663. + (ctrl_reg_status |
  664. + (((u32)mask_bit) & XDCFG_CTRL_DAP_EN_MASK)));
  665. +
  666. + spin_unlock_irqrestore(&drvdata->lock, flags);
  667. +
  668. + clk_disable(drvdata->clk);
  669. +
  670. + return size;
  671. +
  672. +err_unlock:
  673. + spin_unlock_irqrestore(&drvdata->lock, flags);
  674. + clk_disable(drvdata->clk);
  675. +
  676. + return status;
  677. +}
  678. +
  679. +/**
  680. + * xdevcfg_show_dap_en_status() - The function returns the DAP_EN bits status in
  681. + * the control register.
  682. + * @dev: Pointer to the device structure.
  683. + * @attr: Pointer to the device attribute structure.
  684. + * @buf: Pointer to the buffer location for the configuration
  685. + * data.
  686. + * returns: Size of the buffer.
  687. + */
  688. +static ssize_t xdevcfg_show_dap_en_status(struct device *dev,
  689. + struct device_attribute *attr, char *buf)
  690. +{
  691. + u32 dap_en_status;
  692. + int status;
  693. + struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
  694. +
  695. + status = clk_enable(drvdata->clk);
  696. + if (status)
  697. + return status;
  698. +
  699. + dap_en_status = xdevcfg_readreg(drvdata->base_address +
  700. + XDCFG_CTRL_OFFSET) & XDCFG_CTRL_DAP_EN_MASK;
  701. +
  702. + clk_disable(drvdata->clk);
  703. +
  704. + status = sprintf(buf, "%d\n", dap_en_status);
  705. +
  706. + return status;
  707. +}
  708. +
  709. +static DEVICE_ATTR(enable_dap, 0644, xdevcfg_show_dap_en_status,
  710. + xdevcfg_set_dap_en);
  711. +
  712. +/**
  713. + * xdevcfg_set_dbgen() - This function sets the DBGEN bit in the
  714. + * control register with the given value.
  715. + * @dev: Pointer to the device structure.
  716. + * @attr: Pointer to the device attribute structure.
  717. + * @buf: Pointer to the buffer location for the configuration
  718. + * data.
  719. + * @size: The number of bytes used from the buffer
  720. + * returns: -EINVAL if invalid parameter is sent or size
  721. + */
  722. +static ssize_t xdevcfg_set_dbgen(struct device *dev,
  723. + struct device_attribute *attr, const char *buf, size_t size)
  724. +{
  725. + u32 ctrl_reg_status;
  726. + unsigned long flags;
  727. + unsigned long mask_bit;
  728. + int status;
  729. + struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
  730. +
  731. + status = clk_enable(drvdata->clk);
  732. + if (status)
  733. + return status;
  734. +
  735. + ctrl_reg_status = xdevcfg_readreg(drvdata->base_address +
  736. + XDCFG_CTRL_OFFSET);
  737. +
  738. + status = kstrtoul(buf, 10, &mask_bit);
  739. +
  740. + if (status)
  741. + goto err_clk;
  742. +
  743. + if (mask_bit > 1) {
  744. + status = -EINVAL;
  745. + goto err_clk;
  746. + }
  747. +
  748. + spin_lock_irqsave(&drvdata->lock, flags);
  749. +
  750. + if (mask_bit)
  751. + xdevcfg_writereg(drvdata->base_address + XDCFG_CTRL_OFFSET,
  752. + (ctrl_reg_status | XDCFG_CTRL_DBGEN_MASK));
  753. + else
  754. + xdevcfg_writereg(drvdata->base_address + XDCFG_CTRL_OFFSET,
  755. + (ctrl_reg_status & (~XDCFG_CTRL_DBGEN_MASK)));
  756. +
  757. + spin_unlock_irqrestore(&drvdata->lock, flags);
  758. +
  759. + clk_disable(drvdata->clk);
  760. +
  761. + return size;
  762. +
  763. +err_clk:
  764. + clk_disable(drvdata->clk);
  765. +
  766. + return status;
  767. +}
  768. +
  769. +/**
  770. + * xdevcfg_show_dbgen_status() - The function returns the DBGEN bit status in
  771. + * the control register.
  772. + * @dev: Pointer to the device structure.
  773. + * @attr: Pointer to the device attribute structure.
  774. + * @buf: Pointer to the buffer location for the configuration
  775. + * data.
  776. + * returns: Size of the buffer.
  777. + */
  778. +static ssize_t xdevcfg_show_dbgen_status(struct device *dev,
  779. + struct device_attribute *attr, char *buf)
  780. +{
  781. + u32 dbgen_status;
  782. + ssize_t status;
  783. + struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
  784. +
  785. + status = clk_enable(drvdata->clk);
  786. + if (status)
  787. + return status;
  788. +
  789. + dbgen_status = xdevcfg_readreg(drvdata->base_address +
  790. + XDCFG_CTRL_OFFSET) & XDCFG_CTRL_DBGEN_MASK;
  791. +
  792. + clk_disable(drvdata->clk);
  793. +
  794. + status = sprintf(buf, "%d\n", (dbgen_status >> 3));
  795. +
  796. + return status;
  797. +}
  798. +
  799. +static DEVICE_ATTR(enable_dbg_in, 0644, xdevcfg_show_dbgen_status,
  800. + xdevcfg_set_dbgen);
  801. +
  802. +/**
  803. + * xdevcfg_set_niden() - This function sets the NIDEN bit in the
  804. + * control register with the given value.
  805. + * @dev: Pointer to the device structure.
  806. + * @attr: Pointer to the device attribute structure.
  807. + * @buf: Pointer to the buffer location for the configuration
  808. + * data.
  809. + * @size: The number of bytes used from the buffer
  810. + * returns: -EINVAL if invalid parameter is sent or size
  811. + */
  812. +static ssize_t xdevcfg_set_niden(struct device *dev,
  813. + struct device_attribute *attr, const char *buf, size_t size)
  814. +{
  815. + u32 ctrl_reg_status;
  816. + unsigned long flags;
  817. + unsigned long mask_bit;
  818. + int status;
  819. + struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
  820. +
  821. + status = clk_enable(drvdata->clk);
  822. + if (status)
  823. + return status;
  824. +
  825. + ctrl_reg_status = xdevcfg_readreg(drvdata->base_address +
  826. + XDCFG_CTRL_OFFSET);
  827. +
  828. + status = kstrtoul(buf, 10, &mask_bit);
  829. +
  830. + if (status)
  831. + goto err_clk;
  832. +
  833. + if (mask_bit > 1) {
  834. + status = -EINVAL;
  835. + goto err_clk;
  836. + }
  837. +
  838. + spin_lock_irqsave(&drvdata->lock, flags);
  839. +
  840. + if (mask_bit)
  841. + xdevcfg_writereg(drvdata->base_address + XDCFG_CTRL_OFFSET,
  842. + (ctrl_reg_status | XDCFG_CTRL_NIDEN_MASK));
  843. + else
  844. + xdevcfg_writereg(drvdata->base_address + XDCFG_CTRL_OFFSET,
  845. + (ctrl_reg_status & (~XDCFG_CTRL_NIDEN_MASK)));
  846. +
  847. + spin_unlock_irqrestore(&drvdata->lock, flags);
  848. +
  849. + clk_disable(drvdata->clk);
  850. +
  851. + return size;
  852. +
  853. +err_clk:
  854. + clk_disable(drvdata->clk);
  855. +
  856. + return status;
  857. +}
  858. +
  859. +/**
  860. + * xdevcfg_show_niden_status() - The function returns the NIDEN bit status in
  861. + * the control register.
  862. + * @dev: Pointer to the device structure.
  863. + * @attr: Pointer to the device attribute structure.
  864. + * @buf: Pointer to the buffer location for the configuration
  865. + * data.
  866. + * returns: Size of the buffer.
  867. + */
  868. +static ssize_t xdevcfg_show_niden_status(struct device *dev,
  869. + struct device_attribute *attr, char *buf)
  870. +{
  871. + u32 niden_status;
  872. + ssize_t status;
  873. + struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
  874. +
  875. + status = clk_enable(drvdata->clk);
  876. + if (status)
  877. + return status;
  878. +
  879. + niden_status = xdevcfg_readreg(drvdata->base_address +
  880. + XDCFG_CTRL_OFFSET) & XDCFG_CTRL_NIDEN_MASK;
  881. +
  882. + clk_disable(drvdata->clk);
  883. +
  884. + status = sprintf(buf, "%d\n", (niden_status >> 4));
  885. +
  886. + return status;
  887. +}
  888. +
  889. +static DEVICE_ATTR(enable_dbg_nonin, 0644, xdevcfg_show_niden_status,
  890. + xdevcfg_set_niden);
  891. +
  892. +/**
  893. + * xdevcfg_set_spiden() - This function sets the SPIDEN bit in the
  894. + * control register with the given value.
  895. + * @dev: Pointer to the device structure.
  896. + * @attr: Pointer to the device attribute structure.
  897. + * @buf: Pointer to the buffer location for the configuration
  898. + * data.
  899. + * @size: The number of bytes used from the buffer
  900. + * returns: -EINVAL if invalid parameter is sent or size
  901. + */
  902. +static ssize_t xdevcfg_set_spiden(struct device *dev,
  903. + struct device_attribute *attr, const char *buf, size_t size)
  904. +{
  905. + u32 ctrl_reg_status;
  906. + unsigned long flags;
  907. + unsigned long mask_bit;
  908. + int status;
  909. + struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
  910. +
  911. + status = clk_enable(drvdata->clk);
  912. + if (status)
  913. + return status;
  914. +
  915. + ctrl_reg_status = xdevcfg_readreg(drvdata->base_address +
  916. + XDCFG_CTRL_OFFSET);
  917. +
  918. + status = kstrtoul(buf, 10, &mask_bit);
  919. +
  920. + if (status)
  921. + goto err_clk;
  922. +
  923. + if (mask_bit > 1) {
  924. + status = -EINVAL;
  925. + goto err_clk;
  926. + }
  927. +
  928. + spin_lock_irqsave(&drvdata->lock, flags);
  929. +
  930. + if (mask_bit)
  931. + xdevcfg_writereg(drvdata->base_address + XDCFG_CTRL_OFFSET,
  932. + (ctrl_reg_status | XDCFG_CTRL_SPIDEN_MASK));
  933. + else
  934. +
  935. + xdevcfg_writereg(drvdata->base_address + XDCFG_CTRL_OFFSET,
  936. + (ctrl_reg_status & (~XDCFG_CTRL_SPIDEN_MASK)));
  937. +
  938. + spin_unlock_irqrestore(&drvdata->lock, flags);
  939. +
  940. + clk_disable(drvdata->clk);
  941. +
  942. + return size;
  943. +
  944. +err_clk:
  945. + clk_disable(drvdata->clk);
  946. +
  947. + return status;
  948. +}
  949. +
  950. +/**
  951. + * xdevcfg_show_spiden_status() - The function returns the SPIDEN bit status in
  952. + * the control register.
  953. + * @dev: Pointer to the device structure.
  954. + * @attr: Pointer to the device attribute structure.
  955. + * @buf: Pointer to the buffer location for the configuration
  956. + * data.
  957. + * returns: Size of the buffer.
  958. + */
  959. +static ssize_t xdevcfg_show_spiden_status(struct device *dev,
  960. + struct device_attribute *attr, char *buf)
  961. +{
  962. + u32 spiden_status;
  963. + ssize_t status;
  964. + struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
  965. +
  966. + status = clk_enable(drvdata->clk);
  967. + if (status)
  968. + return status;
  969. +
  970. + spiden_status = xdevcfg_readreg(drvdata->base_address +
  971. + XDCFG_CTRL_OFFSET) & XDCFG_CTRL_SPIDEN_MASK;
  972. +
  973. + clk_disable(drvdata->clk);
  974. +
  975. + status = sprintf(buf, "%d\n", (spiden_status >> 5));
  976. +
  977. + return status;
  978. +}
  979. +
  980. +static DEVICE_ATTR(enable_sec_dbg_in, 0644, xdevcfg_show_spiden_status,
  981. + xdevcfg_set_spiden);
  982. +
  983. +/**
  984. + * xdevcfg_set_spniden() - This function sets the SPNIDEN bit in the
  985. + * control register with the given value.
  986. + * @dev: Pointer to the device structure.
  987. + * @attr: Pointer to the device attribute structure.
  988. + * @buf: Pointer to the buffer location for the configuration
  989. + * data.
  990. + * @size: The number of bytes used from the buffer
  991. + * returns: -EINVAL if invalid parameter is sent or the size of buffer
  992. + */
  993. +static ssize_t xdevcfg_set_spniden(struct device *dev,
  994. + struct device_attribute *attr, const char *buf, size_t size)
  995. +{
  996. + u32 ctrl_reg_status;
  997. + unsigned long flags;
  998. + unsigned long mask_bit;
  999. + ssize_t status;
  1000. + struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
  1001. +
  1002. + status = clk_enable(drvdata->clk);
  1003. + if (status)
  1004. + return status;
  1005. +
  1006. + ctrl_reg_status = xdevcfg_readreg(drvdata->base_address +
  1007. + XDCFG_CTRL_OFFSET);
  1008. + status = kstrtoul(buf, 10, &mask_bit);
  1009. +
  1010. + if (status)
  1011. + goto err_clk;
  1012. +
  1013. + if (mask_bit > 1) {
  1014. + status = -EINVAL;
  1015. + goto err_clk;
  1016. + }
  1017. +
  1018. + spin_lock_irqsave(&drvdata->lock, flags);
  1019. +
  1020. + if (mask_bit)
  1021. + xdevcfg_writereg(drvdata->base_address + XDCFG_CTRL_OFFSET,
  1022. + (ctrl_reg_status | XDCFG_CTRL_SPNIDEN_MASK));
  1023. + else
  1024. + xdevcfg_writereg(drvdata->base_address + XDCFG_CTRL_OFFSET,
  1025. + (ctrl_reg_status & (~XDCFG_CTRL_SPNIDEN_MASK)));
  1026. +
  1027. + spin_unlock_irqrestore(&drvdata->lock, flags);
  1028. +
  1029. + clk_disable(drvdata->clk);
  1030. +
  1031. + return size;
  1032. +
  1033. +err_clk:
  1034. + clk_disable(drvdata->clk);
  1035. +
  1036. + return status;
  1037. +}
  1038. +
  1039. +/**
  1040. + * xdevcfg_show_spniden_status() - The function returns the SPNIDEN bit status
  1041. + * in the control register.
  1042. + * @dev: Pointer to the device structure.
  1043. + * @attr: Pointer to the device attribute structure.
  1044. + * @buf: Pointer to the buffer location for the configuration
  1045. + * data.
  1046. + * returns: Size of the buffer.
  1047. + */
  1048. +static ssize_t xdevcfg_show_spniden_status(struct device *dev,
  1049. + struct device_attribute *attr, char *buf)
  1050. +{
  1051. + u32 spniden_status;
  1052. + ssize_t status;
  1053. + struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
  1054. +
  1055. + status = clk_enable(drvdata->clk);
  1056. + if (status)
  1057. + return status;
  1058. +
  1059. + spniden_status = xdevcfg_readreg(drvdata->base_address +
  1060. + XDCFG_CTRL_OFFSET) & XDCFG_CTRL_SPNIDEN_MASK;
  1061. +
  1062. + clk_disable(drvdata->clk);
  1063. +
  1064. + status = sprintf(buf, "%d\n", (spniden_status >> 6));
  1065. +
  1066. + return status;
  1067. +}
  1068. +
  1069. +static DEVICE_ATTR(enable_sec_dbg_nonin, 0644, xdevcfg_show_spniden_status,
  1070. + xdevcfg_set_spniden);
  1071. +
  1072. +/**
  1073. + * xdevcfg_set_seu() - This function sets the SEU_EN bit in the
  1074. + * control register with the given value
  1075. + * @dev: Pointer to the device structure.
  1076. + * @attr: Pointer to the device attribute structure.
  1077. + * @buf: Pointer to the buffer location for the configuration
  1078. + * data.
  1079. + * @size: The number of bytes used from the buffer
  1080. + * returns: -EINVAL if invalid parameter is sent or size
  1081. + */
  1082. +static ssize_t xdevcfg_set_seu(struct device *dev,
  1083. + struct device_attribute *attr, const char *buf, size_t size)
  1084. +{
  1085. + u32 ctrl_reg_status;
  1086. + unsigned long flags;
  1087. + unsigned long mask_bit;
  1088. + ssize_t status;
  1089. + struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
  1090. +
  1091. + status = clk_enable(drvdata->clk);
  1092. + if (status)
  1093. + return status;
  1094. +
  1095. + ctrl_reg_status = xdevcfg_readreg(drvdata->base_address +
  1096. + XDCFG_CTRL_OFFSET);
  1097. +
  1098. + status = kstrtoul(buf, 10, &mask_bit);
  1099. +
  1100. + if (status)
  1101. + goto err_clk;
  1102. +
  1103. + if (mask_bit > 1) {
  1104. + status = -EINVAL;
  1105. + goto err_clk;
  1106. + }
  1107. +
  1108. + spin_lock_irqsave(&drvdata->lock, flags);
  1109. +
  1110. + if (mask_bit)
  1111. + xdevcfg_writereg(drvdata->base_address + XDCFG_CTRL_OFFSET,
  1112. + (ctrl_reg_status | XDCFG_CTRL_SEU_EN_MASK));
  1113. + else
  1114. + xdevcfg_writereg(drvdata->base_address + XDCFG_CTRL_OFFSET,
  1115. + (ctrl_reg_status & (~XDCFG_CTRL_SEU_EN_MASK)));
  1116. +
  1117. + spin_unlock_irqrestore(&drvdata->lock, flags);
  1118. +
  1119. + clk_disable(drvdata->clk);
  1120. +
  1121. + return size;
  1122. +
  1123. +err_clk:
  1124. + clk_disable(drvdata->clk);
  1125. +
  1126. + return status;
  1127. +}
  1128. +
  1129. +/**
  1130. + * xdevcfg_show_seu_status() - The function returns the SEU_EN bit status
  1131. + * in the control register.
  1132. + * @dev: Pointer to the device structure.
  1133. + * @attr: Pointer to the device attribute structure.
  1134. + * @buf: Pointer to the buffer location for the configuration
  1135. + * data.
  1136. + * returns: size of the buffer.
  1137. + */
  1138. +static ssize_t xdevcfg_show_seu_status(struct device *dev,
  1139. + struct device_attribute *attr, char *buf)
  1140. +{
  1141. + u32 seu_status;
  1142. + ssize_t status;
  1143. + struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
  1144. +
  1145. + status = clk_enable(drvdata->clk);
  1146. + if (status)
  1147. + return status;
  1148. +
  1149. + seu_status = xdevcfg_readreg(drvdata->base_address +
  1150. + XDCFG_CTRL_OFFSET) & XDCFG_CTRL_SEU_EN_MASK;
  1151. +
  1152. + clk_disable(drvdata->clk);
  1153. +
  1154. + status = sprintf(buf, "%d\n", (seu_status > 8));
  1155. +
  1156. + return status;
  1157. +}
  1158. +
  1159. +static DEVICE_ATTR(enable_seu, 0644, xdevcfg_show_seu_status, xdevcfg_set_seu);
  1160. +
  1161. +/**
  1162. + * xdevcfg_set_aes() - This function sets the AES_EN bits in the
  1163. + * control register with either all 1s or all 0s.
  1164. + * @dev: Pointer to the device structure.
  1165. + * @attr: Pointer to the device attribute structure.
  1166. + * @buf: Pointer to the buffer location for the configuration
  1167. + * data.
  1168. + * @size: The number of bytes used from the buffer
  1169. + * returns: -EINVAL if invalid parameter is sent or size
  1170. + *
  1171. + * The user must send only one bit in the buffer to notify whether he wants to
  1172. + * either set or reset these bits.
  1173. + */
  1174. +static ssize_t xdevcfg_set_aes(struct device *dev,
  1175. + struct device_attribute *attr, const char *buf, size_t size)
  1176. +{
  1177. + u32 ctrl_reg_status;
  1178. + unsigned long flags;
  1179. + unsigned long mask_bit;
  1180. + int status;
  1181. + struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
  1182. +
  1183. + status = clk_enable(drvdata->clk);
  1184. + if (status)
  1185. + return status;
  1186. +
  1187. + ctrl_reg_status = xdevcfg_readreg(drvdata->base_address +
  1188. + XDCFG_CTRL_OFFSET);
  1189. +
  1190. + status = kstrtoul(buf, 10, &mask_bit);
  1191. +
  1192. + if (status < 0)
  1193. + goto err_clk;
  1194. +
  1195. + if (mask_bit > 1) {
  1196. + status = -EINVAL;
  1197. + goto err_clk;
  1198. + }
  1199. +
  1200. +
  1201. + spin_lock_irqsave(&drvdata->lock, flags);
  1202. +
  1203. + if (mask_bit)
  1204. + xdevcfg_writereg(drvdata->base_address + XDCFG_CTRL_OFFSET,
  1205. + (ctrl_reg_status |
  1206. + XDCFG_CTRL_PCFG_AES_EN_MASK |
  1207. + XDCFG_CTRL_PCAP_RATE_EN_MASK));
  1208. + else
  1209. + xdevcfg_writereg(drvdata->base_address + XDCFG_CTRL_OFFSET,
  1210. + (ctrl_reg_status &
  1211. + ~(XDCFG_CTRL_PCFG_AES_EN_MASK |
  1212. + XDCFG_CTRL_PCAP_RATE_EN_MASK)));
  1213. +
  1214. + spin_unlock_irqrestore(&drvdata->lock, flags);
  1215. +
  1216. + clk_disable(drvdata->clk);
  1217. +
  1218. + return size;
  1219. +
  1220. +err_clk:
  1221. + clk_disable(drvdata->clk);
  1222. +
  1223. + return status;
  1224. +}
  1225. +
  1226. +/**
  1227. + * xdevcfg_show_aes_status() - The function returns the AES_EN bit status
  1228. + * in the control register.
  1229. + * @dev: Pointer to the device structure.
  1230. + * @attr: Pointer to the device attribute structure.
  1231. + * @buf: Pointer to the buffer location for the configuration
  1232. + * data.
  1233. + * returns: size of the buffer.
  1234. + */
  1235. +static ssize_t xdevcfg_show_aes_status(struct device *dev,
  1236. + struct device_attribute *attr, char *buf)
  1237. +{
  1238. + u32 aes_status;
  1239. + ssize_t status;
  1240. + struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
  1241. +
  1242. + status = clk_enable(drvdata->clk);
  1243. + if (status)
  1244. + return status;
  1245. +
  1246. + aes_status = xdevcfg_readreg(drvdata->base_address +
  1247. + XDCFG_CTRL_OFFSET) & XDCFG_CTRL_PCFG_AES_EN_MASK;
  1248. +
  1249. + clk_disable(drvdata->clk);
  1250. +
  1251. + status = sprintf(buf, "%d\n", (aes_status >> 9));
  1252. +
  1253. + return status;
  1254. +}
  1255. +
  1256. +static DEVICE_ATTR(enable_aes, 0644, xdevcfg_show_aes_status, xdevcfg_set_aes);
  1257. +
  1258. +/**
  1259. + * xdevcfg_set_aes_en_lock() - This function sets the LOCK_AES_EN bit in the
  1260. + * lock register.
  1261. + * @dev: Pointer to the device structure.
  1262. + * @attr: Pointer to the device attribute structure.
  1263. + * @buf: Pointer to the buffer location for the configuration
  1264. + * data.
  1265. + * @size: The number of bytes used from the buffer
  1266. + * returns: -EINVAL if invalid parameter is sent or size
  1267. + */
  1268. +static ssize_t xdevcfg_set_aes_en_lock(struct device *dev,
  1269. + struct device_attribute *attr, const char *buf, size_t size)
  1270. +{
  1271. + u32 aes_en_lock_status;
  1272. + unsigned long flags;
  1273. + unsigned long mask_bit;
  1274. + ssize_t status;
  1275. + struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
  1276. +
  1277. + status = clk_enable(drvdata->clk);
  1278. + if (status)
  1279. + return status;
  1280. +
  1281. + aes_en_lock_status = xdevcfg_readreg(drvdata->base_address +
  1282. + XDCFG_LOCK_OFFSET);
  1283. +
  1284. + status = kstrtoul(buf, 10, &mask_bit);
  1285. +
  1286. + if (status)
  1287. + goto err_clk;
  1288. +
  1289. + if (mask_bit > 1) {
  1290. + status = -EINVAL;
  1291. + goto err_clk;
  1292. + }
  1293. +
  1294. + spin_lock_irqsave(&drvdata->lock, flags);
  1295. +
  1296. + if (mask_bit)
  1297. + xdevcfg_writereg(drvdata->base_address + XDCFG_LOCK_OFFSET,
  1298. + (aes_en_lock_status | XDCFG_LOCK_AES_EN_MASK));
  1299. + else
  1300. + xdevcfg_writereg(drvdata->base_address + XDCFG_LOCK_OFFSET,
  1301. + (aes_en_lock_status &
  1302. + (~XDCFG_LOCK_AES_EN_MASK)));
  1303. +
  1304. + spin_unlock_irqrestore(&drvdata->lock, flags);
  1305. +
  1306. + clk_disable(drvdata->clk);
  1307. +
  1308. + return size;
  1309. +
  1310. +err_clk:
  1311. + clk_disable(drvdata->clk);
  1312. +
  1313. + return status;
  1314. +}
  1315. +
  1316. +/**
  1317. + * xdevcfg_show_aes_en_lock_status() - The function returns the LOCK_AES_EN bit
  1318. + * status in the lock register.
  1319. + * @dev: Pointer to the device structure.
  1320. + * @attr: Pointer to the device attribute structure.
  1321. + * @buf: Pointer to the buffer location for the configuration
  1322. + * data.
  1323. + * returns: size of the buffer.
  1324. + */
  1325. +static ssize_t xdevcfg_show_aes_en_lock_status(struct device *dev,
  1326. + struct device_attribute *attr, char *buf)
  1327. +{
  1328. + u32 aes_en_lock_status;
  1329. + ssize_t status;
  1330. + struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
  1331. +
  1332. + status = clk_enable(drvdata->clk);
  1333. + if (status)
  1334. + return status;
  1335. +
  1336. + aes_en_lock_status = xdevcfg_readreg(drvdata->base_address +
  1337. + XDCFG_LOCK_OFFSET) & XDCFG_LOCK_AES_EN_MASK;
  1338. +
  1339. + clk_disable(drvdata->clk);
  1340. +
  1341. + status = sprintf(buf, "%d\n", (aes_en_lock_status >> 3));
  1342. +
  1343. + return status;
  1344. +}
  1345. +
  1346. +static DEVICE_ATTR(aes_en_lock, 0644, xdevcfg_show_aes_en_lock_status,
  1347. + xdevcfg_set_aes_en_lock);
  1348. +
  1349. +/**
  1350. + * xdevcfg_set_seu_lock() - This function sets the LOCK_SEU bit in the
  1351. + * lock register.
  1352. + * @dev: Pointer to the device structure.
  1353. + * @attr: Pointer to the device attribute structure.
  1354. + * @buf: Pointer to the buffer location for the configuration
  1355. + * data.
  1356. + * @size: The number of bytes used from the buffer
  1357. + * returns: -EINVAL if invalid parameter is sent or size
  1358. + */
  1359. +static ssize_t xdevcfg_set_seu_lock(struct device *dev,
  1360. + struct device_attribute *attr, const char *buf, size_t size)
  1361. +{
  1362. + u32 seu_lock_status;
  1363. + unsigned long flags;
  1364. + unsigned long mask_bit;
  1365. + ssize_t status;
  1366. + struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
  1367. +
  1368. + status = clk_enable(drvdata->clk);
  1369. + if (status)
  1370. + return status;
  1371. +
  1372. + seu_lock_status = xdevcfg_readreg(drvdata->base_address +
  1373. + XDCFG_LOCK_OFFSET);
  1374. +
  1375. + status = kstrtoul(buf, 10, &mask_bit);
  1376. +
  1377. + if (status)
  1378. + goto err_clk;
  1379. +
  1380. + if (mask_bit > 1) {
  1381. + status = -EINVAL;
  1382. + goto err_clk;
  1383. + }
  1384. +
  1385. + spin_lock_irqsave(&drvdata->lock, flags);
  1386. +
  1387. + if (mask_bit)
  1388. + xdevcfg_writereg(drvdata->base_address + XDCFG_LOCK_OFFSET,
  1389. + (seu_lock_status | XDCFG_LOCK_SEU_MASK));
  1390. + else
  1391. + xdevcfg_writereg(drvdata->base_address + XDCFG_LOCK_OFFSET,
  1392. + (seu_lock_status & (~XDCFG_LOCK_SEU_MASK)));
  1393. +
  1394. + spin_unlock_irqrestore(&drvdata->lock, flags);
  1395. +
  1396. + clk_disable(drvdata->clk);
  1397. +
  1398. + return size;
  1399. +
  1400. +err_clk:
  1401. + clk_disable(drvdata->clk);
  1402. +
  1403. + return status;
  1404. +}
  1405. +
  1406. +/**
  1407. + * xdevcfg_show_seu_lock_status() - The function returns the LOCK_SEU bit
  1408. + * status in the lock register.
  1409. + * @dev: Pointer to the device structure.
  1410. + * @attr: Pointer to the device attribute structure.
  1411. + * @buf: Pointer to the buffer location for the configuration
  1412. + * data.
  1413. + * returns: size of the buffer.
  1414. + */
  1415. +static ssize_t xdevcfg_show_seu_lock_status(struct device *dev,
  1416. + struct device_attribute *attr, char *buf)
  1417. +{
  1418. + u32 seu_lock_status;
  1419. + ssize_t status;
  1420. + struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
  1421. +
  1422. + status = clk_enable(drvdata->clk);
  1423. + if (status)
  1424. + return status;
  1425. +
  1426. + seu_lock_status = xdevcfg_readreg(drvdata->base_address +
  1427. + XDCFG_LOCK_OFFSET) & XDCFG_LOCK_SEU_MASK;
  1428. +
  1429. + clk_disable(drvdata->clk);
  1430. +
  1431. + status = sprintf(buf, "%d\n", (seu_lock_status >> 2));
  1432. +
  1433. + return status;
  1434. +}
  1435. +
  1436. +static DEVICE_ATTR(seu_lock, 0644, xdevcfg_show_seu_lock_status,
  1437. + xdevcfg_set_seu_lock);
  1438. +
  1439. +/**
  1440. + * xdevcfg_set_dbg_lock() - This function sets the LOCK_DBG bit in the
  1441. + * lock register.
  1442. + * @dev: Pointer to the device structure.
  1443. + * @attr: Pointer to the device attribute structure.
  1444. + * @buf: Pointer to the buffer location for the configuration
  1445. + * data.
  1446. + * @size: The number of bytes used from the buffer
  1447. + * returns: -EINVAL if invalid parameter is sent or size
  1448. + */
  1449. +static ssize_t xdevcfg_set_dbg_lock(struct device *dev,
  1450. + struct device_attribute *attr, const char *buf, size_t size)
  1451. +{
  1452. + u32 lock_reg_status;
  1453. + unsigned long flags;
  1454. + unsigned long mask_bit;
  1455. + ssize_t status;
  1456. + struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
  1457. +
  1458. + status = clk_enable(drvdata->clk);
  1459. + if (status)
  1460. + return status;
  1461. +
  1462. + lock_reg_status = xdevcfg_readreg(drvdata->base_address +
  1463. + XDCFG_LOCK_OFFSET);
  1464. + status = kstrtoul(buf, 10, &mask_bit);
  1465. +
  1466. + if (status)
  1467. + goto err_clk;
  1468. +
  1469. + if (mask_bit > 1) {
  1470. + status = -EINVAL;
  1471. + goto err_clk;
  1472. + }
  1473. +
  1474. + spin_lock_irqsave(&drvdata->lock, flags);
  1475. +
  1476. + if (mask_bit)
  1477. + xdevcfg_writereg(drvdata->base_address + XDCFG_LOCK_OFFSET,
  1478. + (lock_reg_status | XDCFG_LOCK_DBG_MASK));
  1479. + else
  1480. + xdevcfg_writereg(drvdata->base_address + XDCFG_LOCK_OFFSET,
  1481. + (lock_reg_status & (~XDCFG_LOCK_DBG_MASK)));
  1482. +
  1483. + spin_unlock_irqrestore(&drvdata->lock, flags);
  1484. +
  1485. + clk_disable(drvdata->clk);
  1486. +
  1487. + return size;
  1488. +
  1489. +err_clk:
  1490. + clk_disable(drvdata->clk);
  1491. +
  1492. + return status;
  1493. +}
  1494. +
  1495. +/**
  1496. + * xdevcfg_show_dbg_lock_status() - The function returns the LOCK_DBG bit
  1497. + * status in the lock register.
  1498. + * @dev: Pointer to the device structure.
  1499. + * @attr: Pointer to the device attribute structure.
  1500. + * @buf: Pointer to the buffer location for the configuration
  1501. + * data.
  1502. + * returns: size of the buffer.
  1503. + */
  1504. +static ssize_t xdevcfg_show_dbg_lock_status(struct device *dev,
  1505. + struct device_attribute *attr, char *buf)
  1506. +{
  1507. + u32 dbg_lock_status;
  1508. + ssize_t status;
  1509. + struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
  1510. +
  1511. + status = clk_enable(drvdata->clk);
  1512. + if (status)
  1513. + return status;
  1514. +
  1515. + dbg_lock_status = xdevcfg_readreg(drvdata->base_address +
  1516. + XDCFG_LOCK_OFFSET) & XDCFG_LOCK_DBG_MASK;
  1517. +
  1518. + clk_disable(drvdata->clk);
  1519. +
  1520. + status = sprintf(buf, "%d\n", dbg_lock_status);
  1521. +
  1522. + return status;
  1523. +}
  1524. +
  1525. +static DEVICE_ATTR(dbg_lock, 0644, xdevcfg_show_dbg_lock_status,
  1526. + xdevcfg_set_dbg_lock);
  1527. +
  1528. +/**
  1529. + * xdevcfg_show_prog_done_status() - The function returns the PROG_DONE bit
  1530. + * status in the interrupt status register.
  1531. + * @dev: Pointer to the device structure.
  1532. + * @attr: Pointer to the device attribute structure.
  1533. + * @buf: Pointer to the buffer location for the configuration
  1534. + * data.
  1535. + * returns: size of the buffer.
  1536. + */
  1537. +static ssize_t xdevcfg_show_prog_done_status(struct device *dev,
  1538. + struct device_attribute *attr, char *buf)
  1539. +{
  1540. + u32 prog_done_status;
  1541. + ssize_t status;
  1542. + struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
  1543. +
  1544. + status = clk_enable(drvdata->clk);
  1545. + if (status)
  1546. + return status;
  1547. +
  1548. + prog_done_status = xdevcfg_readreg(drvdata->base_address +
  1549. + XDCFG_INT_STS_OFFSET) & XDCFG_IXR_PCFG_DONE_MASK;
  1550. +
  1551. + clk_disable(drvdata->clk);
  1552. +
  1553. + status = sprintf(buf, "%d\n", (prog_done_status >> 2));
  1554. +
  1555. + return status;
  1556. +}
  1557. +
  1558. +static DEVICE_ATTR(prog_done, 0644, xdevcfg_show_prog_done_status,
  1559. + NULL);
  1560. +
  1561. +/**
  1562. + * xdevcfg_set_is_partial_bitstream() - This function sets the
  1563. + * is_partial_bitstream variable. If is_partial_bitstream is set,
  1564. + * then PROG_B is not asserted (xdevcfg_reset_pl) and also
  1565. + * zynq_slcr_init_preload_fpga and zynq_slcr_init_postload_fpga functions
  1566. + * are not invoked.
  1567. + * @dev: Pointer to the device structure.
  1568. + * @attr: Pointer to the device attribute structure.
  1569. + * @buf: Pointer to the buffer location for the configuration
  1570. + * data.
  1571. + * @size: The number of bytes used from the buffer
  1572. + * returns: -EINVAL if invalid parameter is sent or size
  1573. + */
  1574. +static ssize_t xdevcfg_set_is_partial_bitstream(struct device *dev,
  1575. + struct device_attribute *attr, const char *buf, size_t size)
  1576. +{
  1577. + unsigned long mask_bit;
  1578. + ssize_t status;
  1579. + struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
  1580. +
  1581. + status = kstrtoul(buf, 10, &mask_bit);
  1582. +
  1583. + if (status)
  1584. + return status;
  1585. +
  1586. + if (mask_bit > 1)
  1587. + return -EINVAL;
  1588. +
  1589. + if (mask_bit)
  1590. + drvdata->is_partial_bitstream = 1;
  1591. + else
  1592. + drvdata->is_partial_bitstream = 0;
  1593. +
  1594. + return size;
  1595. +}
  1596. +
  1597. +/**
  1598. + * xdevcfg_show_is_partial_bitstream_status() - The function returns the
  1599. + * value of is_partial_bitstream variable.
  1600. + * @dev: Pointer to the device structure.
  1601. + * @attr: Pointer to the device attribute structure.
  1602. + * @buf: Pointer to the buffer location for the configuration
  1603. + * data.
  1604. + * returns: size of the buffer.
  1605. + */
  1606. +static ssize_t xdevcfg_show_is_partial_bitstream_status(struct device *dev,
  1607. + struct device_attribute *attr, char *buf)
  1608. +{
  1609. + ssize_t status;
  1610. + struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
  1611. +
  1612. + status = sprintf(buf, "%d\n", drvdata->is_partial_bitstream);
  1613. +
  1614. + return status;
  1615. +}
  1616. +
  1617. +static DEVICE_ATTR(is_partial_bitstream, 0644,
  1618. + xdevcfg_show_is_partial_bitstream_status,
  1619. + xdevcfg_set_is_partial_bitstream);
  1620. +
  1621. +static const struct attribute *xdevcfg_attrs[] = {
  1622. + &dev_attr_prog_done.attr, /* PCFG_DONE bit in Intr Status register */
  1623. + &dev_attr_dbg_lock.attr, /* Debug lock bit in Lock register */
  1624. + &dev_attr_seu_lock.attr, /* SEU lock bit in Lock register */
  1625. + &dev_attr_aes_en_lock.attr, /* AES EN lock bit in Lock register */
  1626. + &dev_attr_enable_aes.attr, /* AES EN bit in Control register */
  1627. + &dev_attr_enable_seu.attr, /* SEU EN bit in Control register */
  1628. + &dev_attr_enable_sec_dbg_nonin.attr, /*SPNIDEN bit in Control register*/
  1629. + &dev_attr_enable_sec_dbg_in.attr, /*SPIDEN bit in Control register */
  1630. + &dev_attr_enable_dbg_nonin.attr, /* NIDEN bit in Control register */
  1631. + &dev_attr_enable_dbg_in.attr, /* DBGEN bit in Control register */
  1632. + &dev_attr_enable_dap.attr, /* DAP_EN bits in Control register */
  1633. + &dev_attr_is_partial_bitstream.attr, /* Flag for partial bitstream */
  1634. + NULL,
  1635. +};
  1636. +
  1637. +
  1638. +static const struct attribute_group xdevcfg_attr_group = {
  1639. + .attrs = (struct attribute **) xdevcfg_attrs,
  1640. +};
  1641. +
  1642. +static ssize_t fclk_enable_show(struct device *dev,
  1643. + struct device_attribute *attr, char *buf)
  1644. +{
  1645. + struct fclk_data *pdata = dev_get_drvdata(dev);
  1646. +
  1647. + return scnprintf(buf, PAGE_SIZE, "%u\n", pdata->enabled);
  1648. +}
  1649. +
  1650. +static ssize_t fclk_enable_store(struct device *dev,
  1651. + struct device_attribute *attr, const char *buf, size_t count)
  1652. +{
  1653. + unsigned long enable;
  1654. + int ret;
  1655. + struct fclk_data *pdata = dev_get_drvdata(dev);
  1656. +
  1657. + ret = kstrtoul(buf, 0, &enable);
  1658. + if (ret)
  1659. + return -EINVAL;
  1660. +
  1661. + enable = !!enable;
  1662. + if (enable == pdata->enabled)
  1663. + return count;
  1664. +
  1665. + if (enable)
  1666. + ret = clk_enable(pdata->clk);
  1667. + else
  1668. + clk_disable(pdata->clk);
  1669. +
  1670. + if (ret)
  1671. + return ret;
  1672. +
  1673. + pdata->enabled = enable;
  1674. + return count;
  1675. +}
  1676. +
  1677. +static DEVICE_ATTR(enable, 0644, fclk_enable_show, fclk_enable_store);
  1678. +
  1679. +static ssize_t fclk_set_rate_show(struct device *dev,
  1680. + struct device_attribute *attr, char *buf)
  1681. +{
  1682. + struct fclk_data *pdata = dev_get_drvdata(dev);
  1683. +
  1684. + return scnprintf(buf, PAGE_SIZE, "%lu\n", clk_get_rate(pdata->clk));
  1685. +}
  1686. +
  1687. +static ssize_t fclk_set_rate_store(struct device *dev,
  1688. + struct device_attribute *attr, const char *buf, size_t count)
  1689. +{
  1690. + int ret = 0;
  1691. + unsigned long rate;
  1692. + struct fclk_data *pdata = dev_get_drvdata(dev);
  1693. +
  1694. + ret = kstrtoul(buf, 0, &rate);
  1695. + if (ret)
  1696. + return -EINVAL;
  1697. +
  1698. + rate = clk_round_rate(pdata->clk, rate);
  1699. + ret = clk_set_rate(pdata->clk, rate);
  1700. +
  1701. + return ret ? ret : count;
  1702. +}
  1703. +
  1704. +static DEVICE_ATTR(set_rate, 0644, fclk_set_rate_show, fclk_set_rate_store);
  1705. +
  1706. +static ssize_t fclk_round_rate_show(struct device *dev,
  1707. + struct device_attribute *attr, char *buf)
  1708. +{
  1709. + struct fclk_data *pdata = dev_get_drvdata(dev);
  1710. +
  1711. + return scnprintf(buf, PAGE_SIZE, "%lu => %lu\n", pdata->rate_rnd,
  1712. + clk_round_rate(pdata->clk, pdata->rate_rnd));
  1713. +}
  1714. +
  1715. +static ssize_t fclk_round_rate_store(struct device *dev,
  1716. + struct device_attribute *attr, const char *buf, size_t count)
  1717. +{
  1718. + int ret = 0;
  1719. + unsigned long rate;
  1720. + struct fclk_data *pdata = dev_get_drvdata(dev);
  1721. +
  1722. + ret = kstrtoul(buf, 0, &rate);
  1723. + if (ret)
  1724. + return -EINVAL;
  1725. +
  1726. + pdata->rate_rnd = rate;
  1727. +
  1728. + return count;
  1729. +}
  1730. +
  1731. +static DEVICE_ATTR(round_rate, 0644, fclk_round_rate_show,
  1732. + fclk_round_rate_store);
  1733. +
  1734. +static const struct attribute *fclk_ctrl_attrs[] = {
  1735. + &dev_attr_enable.attr,
  1736. + &dev_attr_set_rate.attr,
  1737. + &dev_attr_round_rate.attr,
  1738. + NULL,
  1739. +};
  1740. +
  1741. +static const struct attribute_group fclk_ctrl_attr_grp = {
  1742. + .attrs = (struct attribute **)fclk_ctrl_attrs,
  1743. +};
  1744. +
  1745. +static ssize_t xdevcfg_fclk_export_store(struct device *dev,
  1746. + struct device_attribute *attr, const char *buf, size_t size)
  1747. +{
  1748. + int i, ret;
  1749. + struct device *subdev;
  1750. + struct fclk_data *fdata;
  1751. + struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
  1752. +
  1753. + for (i = 0; i < NUMFCLKS; i++) {
  1754. + if (!strncmp(buf, fclk_name[i], strlen(fclk_name[i])))
  1755. + break;
  1756. + }
  1757. +
  1758. + if (i < NUMFCLKS && !drvdata->fclk_exported[i]) {
  1759. + drvdata->fclk_exported[i] = 1;
  1760. + subdev = device_create(drvdata->fclk_class, dev, MKDEV(0, 0),
  1761. + NULL, fclk_name[i]);
  1762. + if (IS_ERR(subdev))
  1763. + return PTR_ERR(subdev);
  1764. + ret = clk_prepare(drvdata->fclk[i]);
  1765. + if (ret)
  1766. + return ret;
  1767. + fdata = kzalloc(sizeof(*fdata), GFP_KERNEL);
  1768. + if (!fdata) {
  1769. + ret = -ENOMEM;
  1770. + goto err_unprepare;
  1771. + }
  1772. + fdata->clk = drvdata->fclk[i];
  1773. + dev_set_drvdata(subdev, fdata);
  1774. + ret = sysfs_create_group(&subdev->kobj, &fclk_ctrl_attr_grp);
  1775. + if (ret)
  1776. + goto err_free;
  1777. + } else {
  1778. + return -EINVAL;
  1779. + }
  1780. +
  1781. + return size;
  1782. +
  1783. +err_free:
  1784. + kfree(fdata);
  1785. +err_unprepare:
  1786. + clk_unprepare(drvdata->fclk[i]);
  1787. +
  1788. + return ret;
  1789. +}
  1790. +
  1791. +static ssize_t xdevcfg_fclk_export_show(struct device *dev,
  1792. + struct device_attribute *attr, char *buf)
  1793. +{
  1794. + int i;
  1795. + ssize_t count = 0;
  1796. + struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
  1797. +
  1798. + for (i = 0; i < NUMFCLKS; i++) {
  1799. + if (!drvdata->fclk_exported[i])
  1800. + count += scnprintf(buf + count, PAGE_SIZE - count,
  1801. + "%s\n", fclk_name[i]);
  1802. + }
  1803. + return count;
  1804. +}
  1805. +
  1806. +static DEVICE_ATTR(fclk_export, 0644, xdevcfg_fclk_export_show,
  1807. + xdevcfg_fclk_export_store);
  1808. +
  1809. +static int match_fclk(struct device *dev, const void *data)
  1810. +{
  1811. + struct fclk_data *fdata = dev_get_drvdata(dev);
  1812. +
  1813. + return fdata->clk == data;
  1814. +}
  1815. +
  1816. +static ssize_t xdevcfg_fclk_unexport_store(struct device *dev,
  1817. + struct device_attribute *attr, const char *buf, size_t size)
  1818. +{
  1819. + int i;
  1820. + struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
  1821. +
  1822. + for (i = 0; i < NUMFCLKS; i++) {
  1823. + if (!strncmp(buf, fclk_name[i], strlen(fclk_name[i])))
  1824. + break;
  1825. + }
  1826. +
  1827. + if (i < NUMFCLKS && drvdata->fclk_exported[i]) {
  1828. + struct fclk_data *fdata;
  1829. + struct device *subdev;
  1830. +
  1831. + drvdata->fclk_exported[i] = 0;
  1832. + subdev = class_find_device(drvdata->fclk_class, NULL,
  1833. + drvdata->fclk[i], match_fclk);
  1834. + fdata = dev_get_drvdata(subdev);
  1835. + if (fdata->enabled)
  1836. + clk_disable(fdata->clk);
  1837. + clk_unprepare(fdata->clk);
  1838. + kfree(fdata);
  1839. + device_unregister(subdev);
  1840. + put_device(subdev);
  1841. + } else {
  1842. + return -EINVAL;
  1843. + }
  1844. +
  1845. + return size;
  1846. +}
  1847. +
  1848. +static ssize_t xdevcfg_fclk_unexport_show(struct device *dev,
  1849. + struct device_attribute *attr, char *buf)
  1850. +{
  1851. + int i;
  1852. + ssize_t count = 0;
  1853. + struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
  1854. +
  1855. + for (i = 0; i < NUMFCLKS; i++) {
  1856. + if (drvdata->fclk_exported[i])
  1857. + count += scnprintf(buf + count, PAGE_SIZE - count,
  1858. + "%s\n", fclk_name[i]);
  1859. + }
  1860. + return count;
  1861. +}
  1862. +
  1863. +static DEVICE_ATTR(fclk_unexport, 0644, xdevcfg_fclk_unexport_show,
  1864. + xdevcfg_fclk_unexport_store);
  1865. +
  1866. +static const struct attribute *fclk_exp_attrs[] = {
  1867. + &dev_attr_fclk_export.attr,
  1868. + &dev_attr_fclk_unexport.attr,
  1869. + NULL,
  1870. +};
  1871. +
  1872. +static const struct attribute_group fclk_exp_attr_grp = {
  1873. + .attrs = (struct attribute **)fclk_exp_attrs,
  1874. +};
  1875. +
  1876. +static void xdevcfg_fclk_init(struct device *dev)
  1877. +{
  1878. + int i;
  1879. + struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
  1880. +
  1881. + for (i = 0; i < NUMFCLKS; i++) {
  1882. + drvdata->fclk[i] = clk_get(dev, fclk_name[i]);
  1883. + if (IS_ERR(drvdata->fclk[i])) {
  1884. + dev_warn(dev, "fclk not found\n");
  1885. + return;
  1886. + }
  1887. + }
  1888. +
  1889. + drvdata->fclk_class = class_create(THIS_MODULE, "fclk");
  1890. + if (IS_ERR(drvdata->fclk_class)) {
  1891. + dev_warn(dev, "failed to create fclk class\n");
  1892. + return;
  1893. + }
  1894. +
  1895. + if (sysfs_create_group(&dev->kobj, &fclk_exp_attr_grp))
  1896. + dev_warn(dev, "failed to create sysfs entries\n");
  1897. +}
  1898. +
  1899. +static void xdevcfg_fclk_remove(struct device *dev)
  1900. +{
  1901. + int i;
  1902. + struct xdevcfg_drvdata *drvdata = dev_get_drvdata(dev);
  1903. +
  1904. + for (i = 0; i < NUMFCLKS; i++) {
  1905. + if (drvdata->fclk_exported[i]) {
  1906. + struct fclk_data *fdata;
  1907. + struct device *subdev;
  1908. +
  1909. + drvdata->fclk_exported[i] = 0;
  1910. + subdev = class_find_device(drvdata->fclk_class, NULL,
  1911. + drvdata->fclk[i], match_fclk);
  1912. + fdata = dev_get_drvdata(subdev);
  1913. + if (fdata->enabled)
  1914. + clk_disable(fdata->clk);
  1915. + clk_unprepare(fdata->clk);
  1916. + kfree(fdata);
  1917. + device_unregister(subdev);
  1918. + put_device(subdev);
  1919. +
  1920. + }
  1921. + }
  1922. +
  1923. + class_destroy(drvdata->fclk_class);
  1924. + sysfs_remove_group(&dev->kobj, &fclk_exp_attr_grp);
  1925. +
  1926. + return;
  1927. +}
  1928. +
  1929. +/**
  1930. + * xdevcfg_drv_probe - Probe call for the device.
  1931. + *
  1932. + * @pdev: handle to the platform device structure.
  1933. + * Returns 0 on success, negative error otherwise.
  1934. + *
  1935. + * It does all the memory allocation and registration for the device.
  1936. + */
  1937. +static int xdevcfg_drv_probe(struct platform_device *pdev)
  1938. +{
  1939. + struct resource *res;
  1940. + struct xdevcfg_drvdata *drvdata;
  1941. + dev_t devt;
  1942. + int retval;
  1943. + u32 ctrlreg;
  1944. + struct device_node *np;
  1945. + const void *prop;
  1946. + int size;
  1947. + struct device *dev;
  1948. +
  1949. + drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
  1950. + if (!drvdata)
  1951. + return -ENOMEM;
  1952. +
  1953. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  1954. + drvdata->base_address = devm_ioremap_resource(&pdev->dev, res);
  1955. + if (IS_ERR(drvdata->base_address))
  1956. + return PTR_ERR(drvdata->base_address);
  1957. +
  1958. + drvdata->irq = platform_get_irq(pdev, 0);
  1959. + retval = devm_request_irq(&pdev->dev, drvdata->irq, &xdevcfg_irq,
  1960. + 0, dev_name(&pdev->dev), drvdata);
  1961. + if (retval) {
  1962. + dev_err(&pdev->dev, "No IRQ available");
  1963. + return retval;
  1964. + }
  1965. +
  1966. + platform_set_drvdata(pdev, drvdata);
  1967. + spin_lock_init(&drvdata->lock);
  1968. + mutex_init(&drvdata->sem);
  1969. + drvdata->is_open = 0;
  1970. + drvdata->is_partial_bitstream = 0;
  1971. + drvdata->dma_done = 0;
  1972. + drvdata->error_status = 0;
  1973. + dev_info(&pdev->dev, "ioremap %pa to %p\n",
  1974. + &res->start, drvdata->base_address);
  1975. +
  1976. + drvdata->clk = devm_clk_get(&pdev->dev, "ref_clk");
  1977. + if (IS_ERR(drvdata->clk)) {
  1978. + dev_err(&pdev->dev, "input clock not found\n");
  1979. + return PTR_ERR(drvdata->clk);
  1980. + }
  1981. +
  1982. + retval = clk_prepare_enable(drvdata->clk);
  1983. + if (retval) {
  1984. + dev_err(&pdev->dev, "unable to enable clock\n");
  1985. + return retval;
  1986. + }
  1987. +
  1988. + /*
  1989. + * Figure out from the device tree if this is running on the EP107
  1990. + * emulation platform as it doesn't match the silicon exactly and the
  1991. + * driver needs to work accordingly.
  1992. + */
  1993. + np = of_get_next_parent(pdev->dev.of_node);
  1994. + np = of_get_next_parent(np);
  1995. + prop = of_get_property(np, "compatible", &size);
  1996. +
  1997. + if (prop != NULL) {
  1998. + if ((strcmp((const char *)prop, "xlnx,zynq-ep107")) == 0)
  1999. + drvdata->ep107 = 1;
  2000. + else
  2001. + drvdata->ep107 = 0;
  2002. + }
  2003. +
  2004. + /* Unlock the device */
  2005. + xdevcfg_writereg(drvdata->base_address + XDCFG_UNLOCK_OFFSET,
  2006. + 0x757BDF0D);
  2007. +
  2008. + /*
  2009. + * Set the configuration register with the following options
  2010. + * - Reset FPGA
  2011. + * - Enable the PCAP interface
  2012. + * - Set the throughput rate for maximum speed
  2013. + * - Set the CPU in user mode
  2014. + */
  2015. + ctrlreg = xdevcfg_readreg(drvdata->base_address + XDCFG_CTRL_OFFSET);
  2016. + ctrlreg &= ~XDCFG_CTRL_PCAP_PR_MASK;
  2017. + ctrlreg |= XDCFG_CTRL_PCFG_PROG_B_MASK | XDCFG_CTRL_PCAP_MODE_MASK;
  2018. + xdevcfg_writereg(drvdata->base_address + XDCFG_CTRL_OFFSET, ctrlreg);
  2019. +
  2020. + /* Ensure internal PCAP loopback is disabled */
  2021. + ctrlreg = xdevcfg_readreg(drvdata->base_address + XDCFG_MCTRL_OFFSET);
  2022. + xdevcfg_writereg(drvdata->base_address + XDCFG_MCTRL_OFFSET,
  2023. + (~XDCFG_MCTRL_PCAP_LPBK_MASK &
  2024. + ctrlreg));
  2025. +
  2026. +
  2027. + retval = alloc_chrdev_region(&devt, 0, XDEVCFG_DEVICES, DRIVER_NAME);
  2028. + if (retval < 0)
  2029. + goto failed5;
  2030. +
  2031. + drvdata->devt = devt;
  2032. +
  2033. + cdev_init(&drvdata->cdev, &xdevcfg_fops);
  2034. + drvdata->cdev.owner = THIS_MODULE;
  2035. + retval = cdev_add(&drvdata->cdev, devt, 1);
  2036. + if (retval) {
  2037. + dev_err(&pdev->dev, "cdev_add() failed\n");
  2038. + goto failed6;
  2039. + }
  2040. +
  2041. + drvdata->class = class_create(THIS_MODULE, DRIVER_NAME);
  2042. + if (IS_ERR(drvdata->class)) {
  2043. + dev_err(&pdev->dev, "failed to create class\n");
  2044. + goto failed6;
  2045. + }
  2046. +
  2047. + dev = device_create(drvdata->class, &pdev->dev, devt, drvdata,
  2048. + DRIVER_NAME);
  2049. + if (IS_ERR(dev)) {
  2050. + dev_err(&pdev->dev, "unable to create device\n");
  2051. + goto failed7;
  2052. + }
  2053. +
  2054. + /* create sysfs files for the device */
  2055. + retval = sysfs_create_group(&(pdev->dev.kobj), &xdevcfg_attr_group);
  2056. + if (retval) {
  2057. + dev_err(&pdev->dev, "Failed to create sysfs attr group\n");
  2058. + cdev_del(&drvdata->cdev);
  2059. + goto failed8;
  2060. + }
  2061. +
  2062. + xdevcfg_fclk_init(&pdev->dev);
  2063. +
  2064. + clk_disable(drvdata->clk);
  2065. +
  2066. + return 0; /* Success */
  2067. +
  2068. +failed8:
  2069. + device_destroy(drvdata->class, drvdata->devt);
  2070. +failed7:
  2071. + class_destroy(drvdata->class);
  2072. +failed6:
  2073. + /* Unregister char driver */
  2074. + unregister_chrdev_region(devt, XDEVCFG_DEVICES);
  2075. +failed5:
  2076. + clk_disable_unprepare(drvdata->clk);
  2077. +
  2078. + return retval;
  2079. +}
  2080. +
  2081. +/**
  2082. + * xdevcfg_drv_remove - Remove call for the device.
  2083. + *
  2084. + * @pdev: handle to the platform device structure.
  2085. + * Returns 0 or error status.
  2086. + *
  2087. + * Unregister the device after releasing the resources.
  2088. + */
  2089. +static int xdevcfg_drv_remove(struct platform_device *pdev)
  2090. +{
  2091. + struct xdevcfg_drvdata *drvdata;
  2092. +
  2093. + drvdata = platform_get_drvdata(pdev);
  2094. +
  2095. + if (!drvdata)
  2096. + return -ENODEV;
  2097. +
  2098. + unregister_chrdev_region(drvdata->devt, XDEVCFG_DEVICES);
  2099. +
  2100. + sysfs_remove_group(&pdev->dev.kobj, &xdevcfg_attr_group);
  2101. +
  2102. + xdevcfg_fclk_remove(&pdev->dev);
  2103. + device_destroy(drvdata->class, drvdata->devt);
  2104. + class_destroy(drvdata->class);
  2105. + cdev_del(&drvdata->cdev);
  2106. + clk_unprepare(drvdata->clk);
  2107. +
  2108. + return 0; /* Success */
  2109. +}
  2110. +
  2111. +static struct of_device_id xdevcfg_of_match[] = {
  2112. + { .compatible = "xlnx,zynq-devcfg-1.0", },
  2113. + { /* end of table */}
  2114. +};
  2115. +MODULE_DEVICE_TABLE(of, xdevcfg_of_match);
  2116. +
  2117. +/* Driver Structure */
  2118. +static struct platform_driver xdevcfg_platform_driver = {
  2119. + .probe = xdevcfg_drv_probe,
  2120. + .remove = xdevcfg_drv_remove,
  2121. + .driver = {
  2122. + .owner = THIS_MODULE,
  2123. + .name = DRIVER_NAME,
  2124. + .of_match_table = xdevcfg_of_match,
  2125. + },
  2126. +};
  2127. +
  2128. +module_platform_driver(xdevcfg_platform_driver);
  2129. +
  2130. +MODULE_AUTHOR("Xilinx, Inc");
  2131. +MODULE_DESCRIPTION("Xilinx Device Config Driver");
  2132. +MODULE_LICENSE("GPL");
  2133. --- a/arch/arm/mach-zynq/common.h
  2134. +++ b/arch/arm/mach-zynq/common.h
  2135. @@ -33,6 +33,9 @@ extern int zynq_cpun_start(u32 address,
  2136. extern struct smp_operations zynq_smp_ops __initdata;
  2137. #endif
  2138. +extern void zynq_slcr_init_preload_fpga(void);
  2139. +extern void zynq_slcr_init_postload_fpga(void);
  2140. +
  2141. extern void __iomem *zynq_scu_base;
  2142. void zynq_pm_late_init(void);
  2143. --- a/arch/arm/mach-zynq/slcr.c
  2144. +++ b/arch/arm/mach-zynq/slcr.c
  2145. @@ -24,10 +24,14 @@
  2146. /* register offsets */
  2147. #define SLCR_UNLOCK_OFFSET 0x8 /* SCLR unlock register */
  2148. +
  2149. #define SLCR_PS_RST_CTRL_OFFSET 0x200 /* PS Software Reset Control */
  2150. +#define SLCR_FPGA_RST_CTRL_OFFSET 0x240 /* FPGA Software Reset Control */
  2151. #define SLCR_A9_CPU_RST_CTRL_OFFSET 0x244 /* CPU Software Reset Control */
  2152. #define SLCR_REBOOT_STATUS_OFFSET 0x258 /* PS Reboot Status */
  2153. #define SLCR_PSS_IDCODE 0x530 /* PS IDCODE */
  2154. +#define SLCR_L2C_RAM 0xA1C /* L2C_RAM in AR#54190 */
  2155. +#define SLCR_LVL_SHFTR_EN_OFFSET 0x900 /* Level Shifters Enable */
  2156. #define SLCR_UNLOCK_MAGIC 0xDF0D
  2157. #define SLCR_A9_CPU_CLKSTOP 0x10
  2158. @@ -124,6 +128,35 @@ static struct notifier_block zynq_slcr_r
  2159. };
  2160. /**
  2161. + * zynq_slcr_init_preload_fpga - Disable communication from the PL to PS.
  2162. + */
  2163. +void zynq_slcr_init_preload_fpga(void)
  2164. +{
  2165. + /* Assert FPGA top level output resets */
  2166. + zynq_slcr_write(0xF, SLCR_FPGA_RST_CTRL_OFFSET);
  2167. +
  2168. + /* Disable level shifters */
  2169. + zynq_slcr_write(0, SLCR_LVL_SHFTR_EN_OFFSET);
  2170. +
  2171. + /* Enable output level shifters */
  2172. + zynq_slcr_write(0xA, SLCR_LVL_SHFTR_EN_OFFSET);
  2173. +}
  2174. +EXPORT_SYMBOL(zynq_slcr_init_preload_fpga);
  2175. +
  2176. +/**
  2177. + * zynq_slcr_init_postload_fpga - Re-enable communication from the PL to PS.
  2178. + */
  2179. +void zynq_slcr_init_postload_fpga(void)
  2180. +{
  2181. + /* Enable level shifters */
  2182. + zynq_slcr_write(0xf, SLCR_LVL_SHFTR_EN_OFFSET);
  2183. +
  2184. + /* Deassert AXI interface resets */
  2185. + zynq_slcr_write(0, SLCR_FPGA_RST_CTRL_OFFSET);
  2186. +}
  2187. +EXPORT_SYMBOL(zynq_slcr_init_postload_fpga);
  2188. +
  2189. +/**
  2190. * zynq_slcr_cpu_start - Start cpu
  2191. * @cpu: cpu number
  2192. */
  2193. @@ -227,6 +260,9 @@ int __init zynq_early_slcr_init(void)
  2194. /* unlock the SLCR so that registers can be changed */
  2195. zynq_slcr_unlock();
  2196. + /* See AR#54190 design advisory */
  2197. + regmap_update_bits(zynq_slcr_regmap, SLCR_L2C_RAM, 0x70707, 0x20202);
  2198. +
  2199. register_restart_handler(&zynq_slcr_restart_nb);
  2200. pr_info("%s mapped to %p\n", np->name, zynq_slcr_base);
  2201. --- a/arch/arm/boot/dts/zynq-7000.dtsi
  2202. +++ b/arch/arm/boot/dts/zynq-7000.dtsi
  2203. @@ -244,7 +244,7 @@
  2204. clkc: clkc@100 {
  2205. #clock-cells = <1>;
  2206. compatible = "xlnx,ps7-clkc";
  2207. - fclk-enable = <0>;
  2208. + fclk-enable = <0xf>;
  2209. clock-output-names = "armpll", "ddrpll", "iopll", "cpu_6or4x",
  2210. "cpu_3or2x", "cpu_2x", "cpu_1x", "ddr2x", "ddr3x",
  2211. "dci", "lqspi", "smc", "pcap", "gem0", "gem1",
  2212. @@ -296,8 +296,8 @@
  2213. reg = <0xf8007000 0x100>;
  2214. interrupt-parent = <&intc>;
  2215. interrupts = <0 8 4>;
  2216. - clocks = <&clkc 12>;
  2217. - clock-names = "ref_clk";
  2218. + clocks = <&clkc 12>, <&clkc 15>, <&clkc 16>, <&clkc 17>, <&clkc 18>;
  2219. + clock-names = "ref_clk", "fclk0", "fclk1", "fclk2", "fclk3";
  2220. syscon = <&slcr>;
  2221. };