Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965968AbcJYPMA (ORCPT ); Tue, 25 Oct 2016 11:12:00 -0400 Received: from mail-by2nam01on0055.outbound.protection.outlook.com ([104.47.34.55]:59264 "EHLO NAM01-BY2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S965785AbcJYPLv (ORCPT ); Tue, 25 Oct 2016 11:11:51 -0400 Authentication-Results: spf=fail (sender IP is 66.35.236.227) smtp.mailfrom=opensource.altera.com; ettus.com; dkim=pass (signature was verified) header.d=altera.onmicrosoft.com;ettus.com; dmarc=none action=none header.from=opensource.altera.com; Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=atull@opensource.altera.com; From: Alan Tull To: Rob Herring CC: Frank Rowand , Mark Rutland , Greg Kroah-Hartman , Moritz Fischer , Joel Holdsworth , Ian Campbell , "Jon Masters" , Julia Cartwright , Michal Simek , Jonathan Corbet , "Cyril Chemparathy" , Matthew Gerlach , Dinh Nguyen , , , , , , Alan Tull Subject: [PATCH v21 9/9] fpga-manager: Add Socfpga Arria10 support Date: Tue, 25 Oct 2016 09:55:40 -0500 Message-ID: <20161025145540.3722-10-atull@opensource.altera.com> X-Mailer: git-send-email 2.10.1 In-Reply-To: <20161025145540.3722-1-atull@opensource.altera.com> References: <20161025145540.3722-1-atull@opensource.altera.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [64.129.157.38] X-ClientProxiedBy: BY2PR11CA0017.namprd11.prod.outlook.com (10.163.150.27) To CY1PR03MB1518.namprd03.prod.outlook.com (10.163.17.24) X-MS-Office365-Filtering-Correlation-Id: cf2ea63e-91f4-40bd-785e-08d3fce71a72 X-Microsoft-Exchange-Diagnostics-untrusted: 1;CY1PR03MB1518;2:5CaXrfBafperAt2UhzKy+NFSxuCAbFG9BhSsQNm1LMW6FoqZljvXANCD2EKS2qmcBe9sr9J2xjIWCHd2a0Xk0Nw5N/Q1zpdX+Y8AVPsd2ohDkrW1odJVAQwyHvmidg+wLTQk8ZUTrzCSBehWQFvZLPD/d2lIztKZPqCAyDuXsWCLcXRZQkK+5ah4M9waPZ7aP+C4YamwgrO/oMPgl7T2eA==;3:VZ/0GYlwwfk8EP3zY4p1MzeoKeR2zNWMXCU+Zrbeb7f1EniY6i1Yftb55Crrj3Arqum9HYvRvSR/vhYtiN7v68lB/3Q/ofhzfRYK2dP0qRMvKBg4hY7oGvyQ8xgvP3Va2wkGt6cVZTlJobyhgukPhQ== X-Microsoft-Antispam-Untrusted: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:CY1PR03MB1518; X-Microsoft-Exchange-Diagnostics-untrusted: 1;CY1PR03MB1518;25:KdS1avXT8+ykh3NfhD1SS348gTZoc1OFJLhqP8PRmOppSn/yeHaqwZA/rCIcaZRiqvNfcFnB2jhlXNOzGnpKt8KyGbPVGmbKMTHl6B4oUZrVms4ibinNpnPNCoe2N8S83L/uvJTg7q0mFJP5xLCrbX6GpR0wf+UP1bLzmmmTEo8GATr3ccKKHUp1u5gN/gku3X82wilJ9VKvPfK+m7Z4IvQaAcvVjjscU5INuj5qrhJ7TxjlNeOANus/Iao2WNpp43mscHAKRqatUBv62YCeag5pNvZtReI4gmgLxwXLFndE8GKPf4XxZP+ObgePqJLbBcnHPbTCr86xpMnn8CsHleXnzsco9k6qho95wJKLOhM5FAKhI5J+/Y8Ibm05dM8nbvyOLwbmZGN12GWOQEMs98c00CkFr/2FsjiHg6LW2WRjOY7RzrSIuuvMXYTlq0QH2hKu7wriUuTY+u6WOMV96gCVkQ1B4EEBiIwJX4Jo2GO2shvrtXKmmqwY6huOA6eW7YIYrW9NfnXv148zKwi27NsNBDxjik1U4287ZeurRPsorhLAyD+yTHdWtT4PAKKyYUpTvzr6O3qwtKZ0pWm/iYOU0broKCQjEGg5u9ntic5QeS9Phn7Hp9eRuMffs5fryow7iRhbhQxlxnDNpaFEWriWd5OToPJeGGZ7oDGmiUD10bXzuft61oFCgP06Qm2UnwepujgtkDkeA8/VaT9FDw2Zpg7564pQ+Zeor1k0sFeTOezAqgwZlQOLXwpe4Er94VE5pnKV38qlkfoXWcF6r6NMQnpBf8BBFtWUGSOBhFUYRFZ0pip8Jqont/9cUUn+tPcv61LGit5rVmkk/++kafvvD3e5hpPOp/BNvNokQgQ= X-Microsoft-Exchange-Diagnostics-untrusted: 1;CY1PR03MB1518;31:r9ebEUI7PlAd1V9KhcOWgBSpeWfSznVadRduVAzvecANlfEQAlaXMHy+dYB59ABNDVxDMeENguqrvOHLAJcAVSMF9C//d07rXVtClnk5aE2EIGc/Lsh2yP3IW+iaohrqUvkGlqPrMRpPnnsxc4KtwWPQUOyKiJ9h92E6V3gu9cSjIRZkSRgxJaMt+Y2kmlm78WGiVS4MoxGjHfMjCfRlzbP+0LhtH2oLWGpCfzsUU2yU6hOHOw+RxtPXy51Y251hIPCTQ0OxYCGhIUwOUDCPqMNo+u7IOvS3vCKmVxo7xqw=;20:Jo3JibtURwI86POpy5ut6WL15XCexHcPSsZlnpCXbulMVAH4+AT2lVf/CIZA6Pek3LV+h3JQhG5skjvTcljWbUcN9z4+HYo+89BY8XxzrtdHtZ+ZXf43ZYsAoEbf5Qu9IZrfBI0nw5r/rn9eEhp/L7Nz7J4hs1vmrKs0IyfMNTQ= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(250305191791016)(22074186197030)(80048183373757);UriScan:(250305191791016)(22074186197030)(80048183373757); X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(6040176)(601004)(2401047)(5005006)(8121501046)(3002001)(10201501046)(6055026);SRVR:CY1PR03MB1518;BCL:0;PCL:0;RULEID:;SRVR:CY1PR03MB1518;BCL:0;PCL:0;RULEID:(6040176)(601004)(2401047)(13023025)(13024025)(13015025)(13018025)(13017025)(8121501046)(5005006)(3002001)(10201501046)(6055026)(6072056);SRVR:BLUPR03MB280;BCL:0;PCL:0;RULEID:;SRVR:BLUPR03MB280; X-Microsoft-Exchange-Diagnostics-untrusted: 1;CY1PR03MB1518;4:C7nEQC03f7DO3MlMr91MfvJlgg/gBtgJeDUcppmG9ZZSeJVWR2QyIBoQDQkMbeB+OZcue5Nmczfi22LECQdt/q1HIeTCoGuSwFY7IEUaIBISIfNl1c+2qQMmL+lApsB7HB6yV3DooErmjH65xW1TsJ7UNCpTFbhu9TFpBawLnYwqGut5L2NoZO4AGJ5WBrPEewqvSVNzhYjJYLpVRwP5DOB9pUPrHJPcRZESDScDa6DX1DooEMzuUPq4MdAuR4udqBRw7s6Et3bVVHadOUeP3tfTIf2ltXXH37QdzSI8ERGRkWyXsn/CWHz08tVfYe3CquLQ5q3rR9SA9egsI9M3i16Pn516CwN1SdBVgJSdHgmFHvVE6lX5NLtHtUY4hAOhXWUhedmBoNTldAfrHSkqpnxJTmEd05y1ePbt6hhBwxHkwZFIRUYTQaguYJJNL7OlOzM2HuVEEOOuLF6C84JUaTbNOcfwn9oe+pLW+mKl4KUGhPm8d3KvGmGXXqCpZWLbWeg+HQf5757m76h7daHl13NJDeV+MRuGd987TpUvO4o= X-Forefront-PRVS: 01068D0A20 X-Forefront-Antispam-Report-Untrusted: SFV:NSPM;SFS:(10009020)(4630300001)(6009001)(7916002)(189002)(199003)(189998001)(4001430100002)(42186005)(7846002)(81166006)(8676002)(229853001)(106356001)(50226002)(69596002)(5660300001)(2950100002)(7416002)(1076002)(586003)(6666003)(107886002)(7736002)(68736007)(97736004)(42882006)(3846002)(81156014)(6116002)(305945005)(53416004)(2906002)(86362001)(77096005)(66066001)(33646002)(19580395003)(19580405001)(50466002)(15975445007)(575784001)(76176999)(110136003)(47776003)(5003940100001)(48376002)(50986999)(92566002)(4326007)(105586002)(101416001)(8666005)(7059030)(2004002);DIR:OUT;SFP:1101;SCL:1;SRVR:CY1PR03MB1518;H:linuxheads99.altera.com;FPR:;SPF:None;PTR:InfoNoRecords;MX:1;A:0;LANG:en; X-Microsoft-Exchange-Diagnostics-untrusted: =?us-ascii?Q?1;CY1PR03MB1518;23:4UJcu1fjJatdHZF0vq9DN7gfY+zywNuTCOroAlRhi?= =?us-ascii?Q?miIiKLTH8pZ3ukkgAm9PfXQogF39jz8wmC/BcyrYodX0TXpDfm2Bpr+XC/H4?= =?us-ascii?Q?qf7vrLn/UKH0jjUBkjjo/vw8S1owKZSRfTFlOqZY6N5EknlJOI35IkljvWR/?= =?us-ascii?Q?nD4/SeaABXjWB5bym+CAYpCrO5JuNamyH0keCVGVDakRsO3Mhx0WeZLiM1ZT?= =?us-ascii?Q?UpvBy696ZVfnzh+beo0/V7EwjK2uYTnC0q5sJZhNTdqDw+oRsRa+T5nyh/nz?= =?us-ascii?Q?zmh+il64pq7toCAquVzOhH+PAFs/RfOBer7lGMhOdiW+FHIRhAaTnIUhEnXP?= =?us-ascii?Q?prkw4B0yhs1zMuoHRRHoxccrmamvjosD/zQ8aY+0HvnVu9CWZBPxbGJQG5k6?= =?us-ascii?Q?FYAL33ykLbit/gGpR9pj/h/vlUqBOAz2YAMcK97AwLEAAJYtgjUJkonuDd5e?= =?us-ascii?Q?ZsymJpb1eHi73h5AX1oAZj1QcZiPrKEswj8OBts6ctLnU7v2AV8EieyEN8zw?= =?us-ascii?Q?u3O+Ns24bh1PyHIej5k5U2XoOnfwiv9Z2w4P746iT/hukDr270/IE5lRw+Cj?= =?us-ascii?Q?ciRWbiXjb0AA90TZo0qdsBTiJm9uMzqS+Iyv5wTnoywNyGImFIjVukFPns/M?= =?us-ascii?Q?CdTmp3RW0T+oqOLEuAPiDdDAN0kr30ey2RkRm8pCb5UJ8OKiAD1QU8OpCZw6?= =?us-ascii?Q?7FD5hk8plAop3cbVoGpXpiIuci+Z0hmQD84MhjxDeJsX8vD2iDEijMVIjaZR?= =?us-ascii?Q?OKRU/8g1oUXC9bAPuE9jMVwUifkcp6gE1Er6K418mbCzMWhjWUV7p3XXGLHG?= =?us-ascii?Q?7jT3FSJZoqq7Mz54nyVuJShYvxi1c7eGKJcMEYTpBiFczu+JS02nKp7TW73H?= =?us-ascii?Q?j7yQR/XvzO/ybbzlDdmfW8TEswXaNdTFASdoCw2/Nf1Al0WFNXUPXdTSIxgt?= =?us-ascii?Q?ayvgp2pyPh3pQ4n5ioe55cnodNxBI/tt3zf5gnCK6jNn9jBs5yzx4Y6HhnPD?= =?us-ascii?Q?yCqvORNJfuU6gk5Yu42pUfc3ecbftDjPL2MPqYJTXuOi7FtRHNIN4iSJIc4R?= =?us-ascii?Q?4JoF1HE1cr+aZ/iWJ9stWwWkhyzvmO+CctY/eupFA7nXppZFyPvRXr7Wz0a9?= =?us-ascii?Q?35/eWkATl10l5znXJ3M3SAXbdoirrAgPBEjq324XqR9gBeyRiLnta0HZTmL7?= =?us-ascii?Q?18gAcvf2uT0OQ+Vdft8ZPMX3Zdj21ng7AthnG9Q1W40P8aTuKMoheHOzYnsg?= =?us-ascii?Q?i/fdPrufd1KM6oCOB5E1oyvPzL23aZZo13CwEWCVVw5LL7Yll5RXr9sSQ3Uu?= =?us-ascii?B?Zz09?= X-Microsoft-Exchange-Diagnostics-untrusted: 1;CY1PR03MB1518;6:4vqeO/jr2p7sJRp/+3AquV8bj0h6Zb/an2d8HEW152CjoeWz5GTsNk/tFCC0EJ0mdCU+U5JREE5mUCXCOFLRUFSFGtIAvt9mDAv7tJz7gCl/ZtH2HD5U7amI+1Re0rYWKWCbJhJEz+FLwmCoDMHayRpWwNyl58QBQOb0NTo3/euTLSvdXnqwPCnpel/qu7bTnKCDwKd9bPI9oZ6rXJovlfhvk9gPyZq3nUhbDxYigQSZsBwQxJhi2ysIpjLhK58s8jhEm/uqxukNZRJuDbg06hIAdglq+SjfAa0BiGEe+JkXgUv63iM3x6OZ+rDEQ5Ymg03L7jPUeuEfD4ffulbksLa1L0fB0qQm5eb87RlsDSQ=;5:mTirQYP3xGwOTMHHH7DjNEdwnZZ0CJi90JK7MLsVl3k6V+RFvx/CppPEeJpY+IyYs3jN3FHE9s9D4jeY/WCNSlkwYDh9nBsKqdyQ64NRk6iR/hhOrNmsfbUDrgN1FpJkEcyqqdI2z+2sh3zQqEInrDP33lRn/ZpyaExtoKbH0wY=;24:m1yX6gP+KR70mTa0enQ9UL1AM7Zz9lqIMu1ybVum5sTNYyhuE3B1l29Wu5JtMkYxXMVWFxe7dZkOwbIpmXmamPUXsRsWWz+i9p6+i4CaWEM= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics-untrusted: 1;CY1PR03MB1518;7:vjT8DjXX3WqxDtN5G9OiI2UZXNS1iepsCjRUdq7HA81LuV0mDtN1eqyv6477FONY/Ox4AusOsvv6MpBb1XYX3k0u+DirS4nvxeYH9c/oBqePtZDRskfCEtlhoK9K68kOo8KDiCxPEk6ooRUpn5ytu4fo05Oomy4k1YvDBGqFojjo/Hq8rIrKI2N12G3M59uTEJoVkZNt32WW49NhKnBodhlwb2pFzaMiXGGeh4X2zRS6DGeFjwACAR7wzXR/zgGnCrrfIGS5rNejB8yc40+TT7lKOPsVx7ghu7hlpx4WGL6sdFprlpBLtKr9V/sUxhvjPn3vPuInhPc98X1OPU/0dum0y/vpx7+OAmE5Mwnx8S4= X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY1PR03MB1518 X-EOPAttributedMessage: 0 X-MS-Exchange-Transport-CrossTenantHeadersStripped: BL2FFO11FD037.protection.gbl X-MS-Office365-Filtering-HT: Tenant X-Forefront-Antispam-Report: CIP:66.35.236.227;IPV:NLI;CTRY:US;EFV:NLI;SFV:NSPM;SFS:(10009020)(6009001)(7916002)(2980300002)(1110001)(1109001)(339900001)(199003)(189002)(2950100002)(956001)(336002)(50466002)(8676002)(86362001)(42882006)(575784001)(81156014)(3720700001)(106466001)(53416004)(97736004)(105606002)(68736007)(1076002)(110136003)(50986999)(6070500001)(50226002)(5660300001)(76176999)(189998001)(229853001)(19580405001)(92566002)(107886002)(6666003)(4001430100002)(305945005)(7736002)(356003)(11100500001)(66066001)(8936002)(5003940100001)(15975445007)(2906002)(47776003)(7416002)(8666005)(77096005)(85426001)(87936001)(626004)(7846002)(586003)(81166006)(4326007)(33646002)(6116002)(3846002)(48376002)(19580395003)(7099028)(7059030)(2004002);DIR:OUT;SFP:1101;SCL:1;SRVR:BLUPR03MB280;H:sj-itexedge03.altera.priv.altera.com;FPR:;SPF:Fail;PTR:InfoDomainNonexistent;A:0;MX:1;LANG:en; X-Microsoft-Exchange-Diagnostics: 1;BL2FFO11FD037;1:O+V5FpejzeNFE2gnWirkO/bMyHehP4XdYB+4/bErFWtm1aE8IcE4PMLy2GTOz+OwRtp+AgNIvCG6pCRCB53/qXumH2E79qp1poWb5GwZeXea4gU0NbWddorb5Nao8d19GlrSnjIuzmXGbATZylegvH2tnZQXt0/o113rc+oyZYNFabDLAU5WcuhEFPlejg889P8zvkdq/49QClIBT3WGLaWnWMhYg3x4KexceBqXp8wkNnjMYiPug9WGBMix2rTbO8mdBmn8TyRynUTIXXycWIaYzvedPL//FRTz6kRaMucylSKNrKlKeF8xXxWHnEIrw3zJasnjZI7iWuhENlicmXUWdmd2R65yQulKFKNm3EzElVt7cMtWeNsMR1dVJFp0eeFFJPL+wsgaj4VGoTwU7YN9G+e6zwoOllrF+Jnt8IQ77sN24if9rJ0HWItK2gQSBX/XA8zV1smCKif25J1Q9Zd7+C9LO8X+mGPEoGiDT3XdZ13q+tO1M6GonOsfn3AdDIOFxspYWhrfUjxszveNUzXG9TZVnSKsF+ai9AV27g61ISB2BkTJAPvxVn08sfRgveFUku5i70xVJQ2IvsZkE2OxzQh+vqgXeKhXR1Y2+QyT3lzPOzrLfoXaPIrOVZpI X-Microsoft-Exchange-Diagnostics: 1;BLUPR03MB280;2:j4cBZhhKVj21KAZpvC3Ro01/mGx0W+ro0uddc48MNAC3A5Th83bvCjy0wnge3wS3UuaYVDTWCW/mxZddocGTe5a5sx9ejMc2AbTsBoFxHJED3yXKYvXFUPV0kf8RjiwKqLkuWXuUweop2nyevG9v5lTsT6NW7paKDidHDfWDRPDBTY83oTnewX8KAkv9mRiCQHdy+kBhW755E/ddQ5oPfQ==;3:7KDWq+8yiLStglToiTzTmGp/Ci8o4ktqooxYlqwVlVaCK5AMizaPoFdDJAYox1Hy8WjD512ts1quUU7FhBQjvZXeRBsUPhNAwFmZ/9HHKaUQOvw9/y3045/LxxIPfNC5duhir5gzYK77jcXL1tw78vFGAqRq7XDwMkfGP0y0Of396csldl/W4a9mKJPCckeP8FbKwPLc24Nst/oi40M9u5HoDj6uh4SdUCl1KU2rpAPXg1jl0pZfGaDkwGrxWDlK5MvCG2vw6LYsgRk+xfoSXA== X-DkimResult-Test: Passed X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(3001016);SRVR:BLUPR03MB280; X-Microsoft-Exchange-Diagnostics: 1;BLUPR03MB280;25:c7mrU0izSrTFf+yR/GVOjjmXSNAjNRwswKgcf9IUK5tFEs4/nYwMMBve/BH3hi6tzAmAdjAT/1UXArmq4BWWlD6hJbrvxE21s8v9z7fRC7mY48W8JhFk8BN0sREVO6vVzQwffJGKjWvLO6UkzCBedpzjjfEIqrffGHkgbyl3ruGS2NB6gu5mdgogzYGo4WG5c8Ctsv40Fhu7MV1rzpXLTFXmzGg/3UgFuDewp1tgZ6E7XK1QxL2LJkc/16tr9EgLxGaZL4Me2t9btMj8dUpNlxBfIMKeO5RG1ZL8QEPNSi6JxF/wQRUfEn9a0snxl6qNVhumg38eziQAXNyNlgNNRFbEgV2v+vcfiOo+1TlHsxrg+0wjpJuMIObNNpgRBC405W+3jToz9ZDzna54WYjrTbebf3X6ttNZoKRrZKgnC+Zlb7vOl0Q5N3hxMdQgWAOF89/ai3Rs/Kld3pvyMnCVNJKc/E70K9OQbZQqrhmFdTbLq9+loMP3ECEW2I/kOrIhnaUq49d8h6sNaNJbIOtlJEBy6P0PZrzjM7+UkU5ZFuLnUSSA5vdlo03k1pmFA0TkgG2T/KWw5eGLGBzygSJKiq4G8SJjvvEe71Qbjhb9AuZJbLAj7hwObGPXLafdnDAKTJiQ/3ou+1/VOIlXOyfyx5jt1F9SHoo6t+wdfPPd6FgzeGdCirOdARb20iJFM1fEVO9GLe5NZxe5Amwzsgdp+WlS9M9nCujZXgGIaQZUazzn3lAaftVdDqo6uLGmcIhok+13cnHAHs/yZ36oPYvyOhmQ+TPnRskock9ZKkMI9MpME8M5FpHuTMa8VrsG4dneWWF5o7mKET4uQWK+8abneav/HkO1aTcTc5VQ0ncn9X4CbUzp+pdn44KKgYaMxGdk X-Microsoft-Exchange-Diagnostics: 1;BLUPR03MB280;31:rs/AoIKwAy2c4ETEooB7/8rlzC1wAwYErobMpZ1k0HEouc/CnJC2e0d7hbcoJ7MNRiVBA1rI+YdGrPklUAhUx9iVnH1wpYGJMvVsBMTLQ3bASyDC21+h8SY/U/SxUkUXM/8/lD6kA2hoTDVn0xDbix5Hb/PnVKVD6dCNwc0X7a2Ohm57sMlyT44HGewEpLNHqUl4DR8kM3JTHW7i3Y+0EL3+0ksuvylMXjlnHu5dee2IscgUIom2vF9VpanaXQvTNjM1DmkPtg8V5s9egwvwYw==;20:kZhH52NWuKc4eHxFpFeigk9rvzHn0tnyIyx1FMIHpMh4v6xva1THvcmA4BdXB4+O4UIp4U8xOR6tESu/rcjS/l4jJzdZktHB8/9Gsp90QtlvvzTD0ttnOr08vYkUWptQc/+ib1h0qCKQKlMOsRfgSOcABLroyUndk8Dq54exyRs= X-Microsoft-Exchange-Diagnostics: 1;BLUPR03MB280;4:s+4QLLW2zPyeo0m5GHxTXE7xJEbjE9MPmsE74uQT4mba62GqXQBwtNkEUiu/iyPU43CYjjn1xb+oYqRmQmspsAdyTrOQzxkil+pfZi/wrMMybxTS5Fe/s6xHfU2TUbSCBi5r4Fsxvt3un6UtUKIg0s3cZEz4lVlMGkmdomKph0TcWVKIupE4t6OfTEnNvFNy+e61HpYadS1udNGr4x0zZdcJtDx8LSZOoQf6HREXvfbanY4tOnSVd6oeIH6YY23+JsXHSGtnv/RmzfYlNzTN3F1Lcfh25H8zPATRU9+33YRUI97a/Xet/FwEL4L3pmZzJwuGc+olYuA4j11BvL2MbKiU7f+QQz22kO1HbZJcRbtIft8E/Pzb6Xq3oUutY4DyCjyF17HcEDTIaP7CgTuvvhJAaE9LG67otdT5EEOC9/dkq0WHUorOl0vwyu3f/6OJSx8MWHt/iZbswjVoOO50gqTtbElc4/ux0wpKF2DstwXatvnkE9UKJoy1ILWeqmVyG5IaE2q3vbQpL09YfudxtQ8Ofe8SW0ETxiWxWT242+GbLBYPLoz9kw8ABfz3EmDrD5ctrXVUAgo+F4fF7zdw+cZw4r2gQmuQOynAfH1dtz+dYtrUCISxIxqWR3Kwk2sAEiSuZo8cOxGqQznbdnm7rw== X-Forefront-PRVS: 01068D0A20 X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;BLUPR03MB280;23:9XJguXfR1RIB2a202CnszzlcTB4btwkPwXan3l2POH?= =?us-ascii?Q?qhcLX9xWp2AlD08aCS19/p974UKa6mrMTAgRWcZWWcDpjjkfcxot2RtDMEtN?= =?us-ascii?Q?fqa9q9sYXFzpWCQMcZAsJJJ+s52OuyrX5svZGnwMbQRS2KHPzjQKJjATa1ND?= =?us-ascii?Q?xannY44Kf7WDZyxSIrLqjCsorR8we9lE12GJe4ZhK9LO5q6wbFZRqDc70bH6?= =?us-ascii?Q?9g/5uGDoY+BonWHW+9JMCWOWe8kaI3sdQ1RPN6OH/5LMUclkn3V/EgZDM36E?= =?us-ascii?Q?rpHdnoOC0lnC/EMJgcFH8R2vfqreZVquSPoEPTl8bsWCvNVbG1nqmoIvWbSy?= =?us-ascii?Q?Pjs2n7wwGpS3rY6ZR/IaiRxVl3/qpac8nLPpt3NehWNMoD8Ml63/IGb5o7mF?= =?us-ascii?Q?q1k0bva7yYP1eTmq6zZsIl9ZLcugOB9D9v067L+6tqdtuiwVx1x2vRLe7nFJ?= =?us-ascii?Q?zf93EAkymgoYyUs/52AxvIyt2T5LOJ68+8mQcoKqrDdxipQmYbM+6DAs9NHd?= =?us-ascii?Q?S1yctZzNHjDapyEMW4jXwQUc83XnTYOvJNIMwZrNN5ie/F+IbvwzPbfgdHb/?= =?us-ascii?Q?MbBRNCXGWaeI/uLErfHhkqr5esfCExsGuuAFjETIteg0u4xPQpflPkUXjKie?= =?us-ascii?Q?7tgb1zp70OTPAgChpBGeXc2ueSxkBelQ/8F0s1nNYvUl3uXsxKhq5Llvv5tX?= =?us-ascii?Q?1t4/GHjfo7Eet5DgnTDlylo28syfHT0f2jD3s9bvOlsxGyoW5vbb/46OUlX0?= =?us-ascii?Q?2abPd0KK0TTvulOUSuwkq8/cBiTBbFPl8/sitK9/sdhn/zdafo9s2kp6CQht?= =?us-ascii?Q?AGB+OiKh5B3Z4WewtekGdmFR4wpG0PPDwcqLdEATaKu/wtTAbZpenCCnBGKY?= =?us-ascii?Q?rbqnLCz98I/3eih3Rnha/LpjBVruVA77e7CMYkc+tgnsATAX8GrZGNeAKM2x?= =?us-ascii?Q?gnLsAV7wX9NGF7hWoL9gffjCj9URdHmb6S5ovkPFgG3yqi3r1SSp8h3iUKT/?= =?us-ascii?Q?C+fk+T1olaG4uK3x5opiJgdsVbeQaZKw56eIaF9L5e/eA7JWcufUP8q2UWr9?= =?us-ascii?Q?yup+GMf+rCjbRtqjT+3sjL/E/sDfiZzEAp6NMoICmPG44MX7zOicnGzQL6hf?= =?us-ascii?Q?TBqpb2rKFyTRp07Zmxs/XoMpd+zTb3yTr5oRgIBkwSV/foIfuloQ0yqxNLCJ?= =?us-ascii?Q?fA7Ka/3tl7SbO1+RuD5aBqfp3h6OF++ZOrRAnY45UbreC37Pq+/u4++5J6c4?= =?us-ascii?Q?HibJvYuX+DslwgbweOvKRO5iORfwxr8CVXaWS0DBi+izfYbLvWNW+Vi0RCIU?= =?us-ascii?Q?9fxrUtKy5dSI6uxTPg5bzooLKSKJ71QJzwGzUwbSmrHCvo/jBTJfEWGxzKlP?= =?us-ascii?Q?z4XVIkX4ebU8LW71euROwcIVyvl5TeQyvNlEYbHYNzHLKzcwDjU70rCEACYE?= =?us-ascii?Q?HBNknUjlK4l0gsVkjPpVnqJIDias0K6igOZ3lgnTTmR/4rWClpLb0ye4GR2D?= =?us-ascii?Q?qYDVKreh17LwE2ddlDcN0+k33jYKFgiqM=3D?= X-Microsoft-Exchange-Diagnostics: 1;BLUPR03MB280;6:fWj6EZKsSZbqCNDgoNms41SvoVULCzqTiA54PuE3CK2wVTVNg1wxQMg3+7tabH4IsP0bTec1RORVxVgoQ63PCVHZigNoeeDYUlUWw69SQ/tSk6K7l2D+47LMfNpE+0hx6ize+2SlgBQAZjHKmXjv46dsHCEPGuTYmEF48hQhD4mpJ9v1yU633WzfmBbADtnpKRO9V1N9k6s2Vvf1L93l8QOJ5nPKnO6PCY/cCPz0rmqYPJIYoyD5N9iS2BcF/kyU9Aivr8zlE3rfv9K832xpLM0E++OESKsb5SBfKtFMQv1AeKaG2rfSXVE4Woy2viqL17YCi7M04ZDhVI0XFrJWuGCaLfNbsZ8r6kEUmV+1MZI=;5:UlakDrfieWsAOqTG2LA/5UQsiUCyNRD8UrR5yBouxloXghop4/JYAOnMexUaaATxu2gmmfOZFSfBF8kJ4aTkjkShF6eA5maDuhSRULGFo+yZ73i+u6n482R54udOFA+SbzdiNGNTcqVVl0mKfc6uYI+JHYVDiCWTSZldgzCEJkk=;24:cM9/R8rrcyA9mNTsJNRsRnLaBcs+mlRvlBq8I3BtfWOJgxtobiIhwmQcWKg09YJoNmlWcww1VmbMtuZTON/6sz0kQuXwDnCNzrXKbYzsC5k= X-Microsoft-Exchange-Diagnostics: 1;BLUPR03MB280;7:BCg1fgZsXeSYEUv0imYdm3ZrV55BzPLx8ISXGLlaOkqnpgZ6W3eO9UzjLSSU0vhhq2sxGn3cyOynbqcVZO1nqmTSS/N9rm/twFQ8KxWgG2nBJbhKkHc5UOCEllPpPXlgRwS4QCEj+3OItlwR26dgXKMgUyQSctYhjPvgfklFrhJ2H5CPhR7JtWcV/eMo1x5rNLfGARTCg+RGWqZUAj/hZ7HVEqOcON3GxbhhqvOaDq5WdKaRm18OwYN248tioet+LFoxSZ8KQFGS4LhyB7/5oaJd9lIsRWFhFAFhuxHDDpOHgsx92I6OQeJyywGUwamws5HNHAXNik1WAmsDvM4LUg== X-OriginatorOrg: opensource.altera.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 25 Oct 2016 14:56:29.6046 (UTC) X-MS-Exchange-CrossTenant-Id: fbd72e03-d4a5-4110-adce-614d51f2077a X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=fbd72e03-d4a5-4110-adce-614d51f2077a;Ip=[66.35.236.227];Helo=[sj-itexedge03.altera.priv.altera.com] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BLUPR03MB280 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 18314 Lines: 614 Add low level driver to support reprogramming FPGAs for Altera SoCFPGA Arria10. Signed-off-by: Alan Tull Reviewed-by: Moritz Fischer --- v19: Added to this patchset as has been changed to use fpga image information struct a checkpatch fix of a block comment do not use clk_put because we are using devm_clk_get v20: use regmap_read_poll_timeout Add some macros/comments remove some debug prints v21: Add Moritz' reviewed-by --- drivers/fpga/Kconfig | 6 + drivers/fpga/Makefile | 1 + drivers/fpga/socfpga-a10.c | 556 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 563 insertions(+) create mode 100644 drivers/fpga/socfpga-a10.c diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig index 8fe6a84..889e4c3 100644 --- a/drivers/fpga/Kconfig +++ b/drivers/fpga/Kconfig @@ -26,6 +26,12 @@ config FPGA_MGR_SOCFPGA help FPGA manager driver support for Altera SOCFPGA. +config FPGA_MGR_SOCFPGA_A10 + tristate "Altera SoCFPGA Arria10" + depends on ARCH_SOCFPGA + help + FPGA manager driver support for Altera Arria10 SoCFPGA. + config FPGA_MGR_ZYNQ_FPGA tristate "Xilinx Zynq FPGA" depends on ARCH_ZYNQ || COMPILE_TEST diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile index a6f874d..8df07bc 100644 --- a/drivers/fpga/Makefile +++ b/drivers/fpga/Makefile @@ -7,6 +7,7 @@ obj-$(CONFIG_FPGA) += fpga-mgr.o # FPGA Manager Drivers obj-$(CONFIG_FPGA_MGR_SOCFPGA) += socfpga.o +obj-$(CONFIG_FPGA_MGR_SOCFPGA_A10) += socfpga-a10.o obj-$(CONFIG_FPGA_MGR_ZYNQ_FPGA) += zynq-fpga.o # FPGA Bridge Drivers diff --git a/drivers/fpga/socfpga-a10.c b/drivers/fpga/socfpga-a10.c new file mode 100644 index 0000000..ccd9fb2 --- /dev/null +++ b/drivers/fpga/socfpga-a10.c @@ -0,0 +1,556 @@ +/* + * FPGA Manager Driver for Altera Arria10 SoCFPGA + * + * Copyright (C) 2015-2016 Altera Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define A10_FPGAMGR_DCLKCNT_OFST 0x08 +#define A10_FPGAMGR_DCLKSTAT_OFST 0x0c +#define A10_FPGAMGR_IMGCFG_CTL_00_OFST 0x70 +#define A10_FPGAMGR_IMGCFG_CTL_01_OFST 0x74 +#define A10_FPGAMGR_IMGCFG_CTL_02_OFST 0x78 +#define A10_FPGAMGR_IMGCFG_STAT_OFST 0x80 + +#define A10_FPGAMGR_DCLKSTAT_DCLKDONE BIT(0) + +#define A10_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_NCONFIG BIT(0) +#define A10_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_NSTATUS BIT(1) +#define A10_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_CONDONE BIT(2) +#define A10_FPGAMGR_IMGCFG_CTL_00_S2F_NCONFIG BIT(8) +#define A10_FPGAMGR_IMGCFG_CTL_00_S2F_NSTATUS_OE BIT(16) +#define A10_FPGAMGR_IMGCFG_CTL_00_S2F_CONDONE_OE BIT(24) + +#define A10_FPGAMGR_IMGCFG_CTL_01_S2F_NENABLE_CONFIG BIT(0) +#define A10_FPGAMGR_IMGCFG_CTL_01_S2F_PR_REQUEST BIT(16) +#define A10_FPGAMGR_IMGCFG_CTL_01_S2F_NCE BIT(24) + +#define A10_FPGAMGR_IMGCFG_CTL_02_EN_CFG_CTRL BIT(0) +#define A10_FPGAMGR_IMGCFG_CTL_02_CDRATIO_MASK (BIT(16) | BIT(17)) +#define A10_FPGAMGR_IMGCFG_CTL_02_CDRATIO_SHIFT 16 +#define A10_FPGAMGR_IMGCFG_CTL_02_CFGWIDTH BIT(24) +#define A10_FPGAMGR_IMGCFG_CTL_02_CFGWIDTH_SHIFT 24 + +#define A10_FPGAMGR_IMGCFG_STAT_F2S_CRC_ERROR BIT(0) +#define A10_FPGAMGR_IMGCFG_STAT_F2S_EARLY_USERMODE BIT(1) +#define A10_FPGAMGR_IMGCFG_STAT_F2S_USERMODE BIT(2) +#define A10_FPGAMGR_IMGCFG_STAT_F2S_NSTATUS_PIN BIT(4) +#define A10_FPGAMGR_IMGCFG_STAT_F2S_CONDONE_PIN BIT(6) +#define A10_FPGAMGR_IMGCFG_STAT_F2S_PR_READY BIT(9) +#define A10_FPGAMGR_IMGCFG_STAT_F2S_PR_DONE BIT(10) +#define A10_FPGAMGR_IMGCFG_STAT_F2S_PR_ERROR BIT(11) +#define A10_FPGAMGR_IMGCFG_STAT_F2S_NCONFIG_PIN BIT(12) +#define A10_FPGAMGR_IMGCFG_STAT_F2S_MSEL_MASK (BIT(16) | BIT(17) | BIT(18)) +#define A10_FPGAMGR_IMGCFG_STAT_F2S_MSEL_SHIFT 16 + +/* FPGA CD Ratio Value */ +#define CDRATIO_x1 0x0 +#define CDRATIO_x2 0x1 +#define CDRATIO_x4 0x2 +#define CDRATIO_x8 0x3 + +/* Configuration width 16/32 bit */ +#define CFGWDTH_32 1 +#define CFGWDTH_16 0 + +/* + * struct a10_fpga_priv - private data for fpga manager + * @regmap: regmap for register access + * @fpga_data_addr: iomap for single address data register to FPGA + * @clk: clock + */ +struct a10_fpga_priv { + struct regmap *regmap; + void __iomem *fpga_data_addr; + struct clk *clk; +}; + +static bool socfpga_a10_fpga_writeable_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case A10_FPGAMGR_DCLKCNT_OFST: + case A10_FPGAMGR_DCLKSTAT_OFST: + case A10_FPGAMGR_IMGCFG_CTL_00_OFST: + case A10_FPGAMGR_IMGCFG_CTL_01_OFST: + case A10_FPGAMGR_IMGCFG_CTL_02_OFST: + return true; + } + return false; +} + +static bool socfpga_a10_fpga_readable_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case A10_FPGAMGR_DCLKCNT_OFST: + case A10_FPGAMGR_DCLKSTAT_OFST: + case A10_FPGAMGR_IMGCFG_CTL_00_OFST: + case A10_FPGAMGR_IMGCFG_CTL_01_OFST: + case A10_FPGAMGR_IMGCFG_CTL_02_OFST: + case A10_FPGAMGR_IMGCFG_STAT_OFST: + return true; + } + return false; +} + +static const struct regmap_config socfpga_a10_fpga_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .writeable_reg = socfpga_a10_fpga_writeable_reg, + .readable_reg = socfpga_a10_fpga_readable_reg, + .max_register = A10_FPGAMGR_IMGCFG_STAT_OFST, + .cache_type = REGCACHE_NONE, +}; + +/* + * from the register map description of cdratio in imgcfg_ctrl_02: + * Normal Configuration : 32bit Passive Parallel + * Partial Reconfiguration : 16bit Passive Parallel + */ +static void socfpga_a10_fpga_set_cfg_width(struct a10_fpga_priv *priv, + int width) +{ + width <<= A10_FPGAMGR_IMGCFG_CTL_02_CFGWIDTH_SHIFT; + + regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_02_OFST, + A10_FPGAMGR_IMGCFG_CTL_02_CFGWIDTH, width); +} + +static void socfpga_a10_fpga_generate_dclks(struct a10_fpga_priv *priv, + u32 count) +{ + u32 val; + + /* Clear any existing DONE status. */ + regmap_write(priv->regmap, A10_FPGAMGR_DCLKSTAT_OFST, + A10_FPGAMGR_DCLKSTAT_DCLKDONE); + + /* Issue the DCLK regmap. */ + regmap_write(priv->regmap, A10_FPGAMGR_DCLKCNT_OFST, count); + + /* wait till the dclkcnt done */ + regmap_read_poll_timeout(priv->regmap, A10_FPGAMGR_DCLKSTAT_OFST, val, + val, 1, 100); + + /* Clear DONE status. */ + regmap_write(priv->regmap, A10_FPGAMGR_DCLKSTAT_OFST, + A10_FPGAMGR_DCLKSTAT_DCLKDONE); +} + +#define RBF_ENCRYPTION_MODE_OFFSET 69 +#define RBF_DECOMPRESS_OFFSET 229 + +static int socfpga_a10_fpga_encrypted(u32 *buf32, size_t buf32_size) +{ + if (buf32_size < RBF_ENCRYPTION_MODE_OFFSET + 1) + return -EINVAL; + + /* Is the bitstream encrypted? */ + return ((buf32[RBF_ENCRYPTION_MODE_OFFSET] >> 2) & 3) != 0; +} + +static int socfpga_a10_fpga_compressed(u32 *buf32, size_t buf32_size) +{ + if (buf32_size < RBF_DECOMPRESS_OFFSET + 1) + return -EINVAL; + + /* Is the bitstream compressed? */ + return !((buf32[RBF_DECOMPRESS_OFFSET] >> 1) & 1); +} + +static unsigned int socfpga_a10_fpga_get_cd_ratio(unsigned int cfg_width, + bool encrypt, bool compress) +{ + unsigned int cd_ratio; + + /* + * cd ratio is dependent on cfg width and whether the bitstream + * is encrypted and/or compressed. + * + * | width | encr. | compr. | cd ratio | + * | 16 | 0 | 0 | 1 | + * | 16 | 0 | 1 | 4 | + * | 16 | 1 | 0 | 2 | + * | 16 | 1 | 1 | 4 | + * | 32 | 0 | 0 | 1 | + * | 32 | 0 | 1 | 8 | + * | 32 | 1 | 0 | 4 | + * | 32 | 1 | 1 | 8 | + */ + if (!compress && !encrypt) + return CDRATIO_x1; + + if (compress) + cd_ratio = CDRATIO_x4; + else + cd_ratio = CDRATIO_x2; + + /* If 32 bit, double the cd ratio by incrementing the field */ + if (cfg_width == CFGWDTH_32) + cd_ratio += 1; + + return cd_ratio; +} + +static int socfpga_a10_fpga_set_cdratio(struct fpga_manager *mgr, + unsigned int cfg_width, + const char *buf, size_t count) +{ + struct a10_fpga_priv *priv = mgr->priv; + unsigned int cd_ratio; + int encrypt, compress; + + encrypt = socfpga_a10_fpga_encrypted((u32 *)buf, count / 4); + if (encrypt < 0) + return -EINVAL; + + compress = socfpga_a10_fpga_compressed((u32 *)buf, count / 4); + if (compress < 0) + return -EINVAL; + + cd_ratio = socfpga_a10_fpga_get_cd_ratio(cfg_width, encrypt, compress); + + regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_02_OFST, + A10_FPGAMGR_IMGCFG_CTL_02_CDRATIO_MASK, + cd_ratio << A10_FPGAMGR_IMGCFG_CTL_02_CDRATIO_SHIFT); + + return 0; +} + +static u32 socfpga_a10_fpga_read_stat(struct a10_fpga_priv *priv) +{ + u32 val; + + regmap_read(priv->regmap, A10_FPGAMGR_IMGCFG_STAT_OFST, &val); + + return val; +} + +static int socfpga_a10_fpga_wait_for_pr_ready(struct a10_fpga_priv *priv) +{ + u32 reg, i; + + for (i = 0; i < 10 ; i++) { + reg = socfpga_a10_fpga_read_stat(priv); + + if (reg & A10_FPGAMGR_IMGCFG_STAT_F2S_PR_ERROR) + return -EINVAL; + + if (reg & A10_FPGAMGR_IMGCFG_STAT_F2S_PR_READY) + return 0; + } + + return -ETIMEDOUT; +} + +static int socfpga_a10_fpga_wait_for_pr_done(struct a10_fpga_priv *priv) +{ + u32 reg, i; + + for (i = 0; i < 10 ; i++) { + reg = socfpga_a10_fpga_read_stat(priv); + + if (reg & A10_FPGAMGR_IMGCFG_STAT_F2S_PR_ERROR) + return -EINVAL; + + if (reg & A10_FPGAMGR_IMGCFG_STAT_F2S_PR_DONE) + return 0; + } + + return -ETIMEDOUT; +} + +/* Start the FPGA programming by initialize the FPGA Manager */ +static int socfpga_a10_fpga_write_init(struct fpga_manager *mgr, + struct fpga_image_info *info, + const char *buf, size_t count) +{ + struct a10_fpga_priv *priv = mgr->priv; + unsigned int cfg_width; + u32 msel, stat, mask; + int ret; + + if (info->flags & FPGA_MGR_PARTIAL_RECONFIG) + cfg_width = CFGWDTH_16; + else + return -EINVAL; + + /* Check for passive parallel (msel == 000 or 001) */ + msel = socfpga_a10_fpga_read_stat(priv); + msel &= A10_FPGAMGR_IMGCFG_STAT_F2S_MSEL_MASK; + msel >>= A10_FPGAMGR_IMGCFG_STAT_F2S_MSEL_SHIFT; + if ((msel != 0) && (msel != 1)) { + dev_dbg(&mgr->dev, "Fail: invalid msel=%d\n", msel); + return -EINVAL; + } + + /* Make sure no external devices are interfering */ + stat = socfpga_a10_fpga_read_stat(priv); + mask = A10_FPGAMGR_IMGCFG_STAT_F2S_NCONFIG_PIN | + A10_FPGAMGR_IMGCFG_STAT_F2S_NSTATUS_PIN; + if ((stat & mask) != mask) + return -EINVAL; + + /* Set cfg width */ + socfpga_a10_fpga_set_cfg_width(priv, cfg_width); + + /* Determine cd ratio from bitstream header and set cd ratio */ + ret = socfpga_a10_fpga_set_cdratio(mgr, cfg_width, buf, count); + if (ret) + return ret; + + /* + * Clear s2f_nce to enable chip select. Leave pr_request + * unasserted and override disabled. + */ + regmap_write(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_01_OFST, + A10_FPGAMGR_IMGCFG_CTL_01_S2F_NENABLE_CONFIG); + + /* Set cfg_ctrl to enable s2f dclk and data */ + regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_02_OFST, + A10_FPGAMGR_IMGCFG_CTL_02_EN_CFG_CTRL, + A10_FPGAMGR_IMGCFG_CTL_02_EN_CFG_CTRL); + + /* + * Disable overrides not needed for pr. + * s2f_config==1 leaves reset deasseted. + */ + regmap_write(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_00_OFST, + A10_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_NCONFIG | + A10_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_NSTATUS | + A10_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_CONDONE | + A10_FPGAMGR_IMGCFG_CTL_00_S2F_NCONFIG); + + /* Enable override for data, dclk, nce, and pr_request to CSS */ + regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_01_OFST, + A10_FPGAMGR_IMGCFG_CTL_01_S2F_NENABLE_CONFIG, 0); + + /* Send some clocks to clear out any errors */ + socfpga_a10_fpga_generate_dclks(priv, 256); + + /* Assert pr_request */ + regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_01_OFST, + A10_FPGAMGR_IMGCFG_CTL_01_S2F_PR_REQUEST, + A10_FPGAMGR_IMGCFG_CTL_01_S2F_PR_REQUEST); + + /* Provide 2048 DCLKs before starting the config data streaming. */ + socfpga_a10_fpga_generate_dclks(priv, 0x7ff); + + /* Wait for pr_ready */ + return socfpga_a10_fpga_wait_for_pr_ready(priv); +} + +/* + * write data to the FPGA data register + */ +static int socfpga_a10_fpga_write(struct fpga_manager *mgr, const char *buf, + size_t count) +{ + struct a10_fpga_priv *priv = mgr->priv; + u32 *buffer_32 = (u32 *)buf; + size_t i = 0; + + if (count <= 0) + return -EINVAL; + + /* Write out the complete 32-bit chunks */ + while (count >= sizeof(u32)) { + writel(buffer_32[i++], priv->fpga_data_addr); + count -= sizeof(u32); + } + + /* Write out remaining non 32-bit chunks */ + switch (count) { + case 3: + writel(buffer_32[i++] & 0x00ffffff, priv->fpga_data_addr); + break; + case 2: + writel(buffer_32[i++] & 0x0000ffff, priv->fpga_data_addr); + break; + case 1: + writel(buffer_32[i++] & 0x000000ff, priv->fpga_data_addr); + break; + case 0: + break; + default: + /* This will never happen */ + return -EFAULT; + } + + return 0; +} + +static int socfpga_a10_fpga_write_complete(struct fpga_manager *mgr, + struct fpga_image_info *info) +{ + struct a10_fpga_priv *priv = mgr->priv; + u32 reg; + int ret; + + /* Wait for pr_done */ + ret = socfpga_a10_fpga_wait_for_pr_done(priv); + + /* Clear pr_request */ + regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_01_OFST, + A10_FPGAMGR_IMGCFG_CTL_01_S2F_PR_REQUEST, 0); + + /* Send some clocks to clear out any errors */ + socfpga_a10_fpga_generate_dclks(priv, 256); + + /* Disable s2f dclk and data */ + regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_02_OFST, + A10_FPGAMGR_IMGCFG_CTL_02_EN_CFG_CTRL, 0); + + /* Deassert chip select */ + regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_01_OFST, + A10_FPGAMGR_IMGCFG_CTL_01_S2F_NCE, + A10_FPGAMGR_IMGCFG_CTL_01_S2F_NCE); + + /* Disable data, dclk, nce, and pr_request override to CSS */ + regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_01_OFST, + A10_FPGAMGR_IMGCFG_CTL_01_S2F_NENABLE_CONFIG, + A10_FPGAMGR_IMGCFG_CTL_01_S2F_NENABLE_CONFIG); + + /* Return any errors regarding pr_done or pr_error */ + if (ret) + return ret; + + /* Final check */ + reg = socfpga_a10_fpga_read_stat(priv); + + if (((reg & A10_FPGAMGR_IMGCFG_STAT_F2S_USERMODE) == 0) || + ((reg & A10_FPGAMGR_IMGCFG_STAT_F2S_CONDONE_PIN) == 0) || + ((reg & A10_FPGAMGR_IMGCFG_STAT_F2S_NSTATUS_PIN) == 0)) { + dev_dbg(&mgr->dev, + "Timeout in final check. Status=%08xf\n", reg); + return -ETIMEDOUT; + } + + return 0; +} + +static enum fpga_mgr_states socfpga_a10_fpga_state(struct fpga_manager *mgr) +{ + struct a10_fpga_priv *priv = mgr->priv; + u32 reg = socfpga_a10_fpga_read_stat(priv); + + if (reg & A10_FPGAMGR_IMGCFG_STAT_F2S_USERMODE) + return FPGA_MGR_STATE_OPERATING; + + if (reg & A10_FPGAMGR_IMGCFG_STAT_F2S_PR_READY) + return FPGA_MGR_STATE_WRITE; + + if (reg & A10_FPGAMGR_IMGCFG_STAT_F2S_CRC_ERROR) + return FPGA_MGR_STATE_WRITE_COMPLETE_ERR; + + if ((reg & A10_FPGAMGR_IMGCFG_STAT_F2S_NSTATUS_PIN) == 0) + return FPGA_MGR_STATE_RESET; + + return FPGA_MGR_STATE_UNKNOWN; +} + +static const struct fpga_manager_ops socfpga_a10_fpga_mgr_ops = { + .state = socfpga_a10_fpga_state, + .write_init = socfpga_a10_fpga_write_init, + .write = socfpga_a10_fpga_write, + .write_complete = socfpga_a10_fpga_write_complete, +}; + +static int socfpga_a10_fpga_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct a10_fpga_priv *priv; + void __iomem *reg_base; + struct resource *res; + int ret; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + /* First mmio base is for register access */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + reg_base = devm_ioremap_resource(dev, res); + if (IS_ERR(reg_base)) + return PTR_ERR(reg_base); + + /* Second mmio base is for writing FPGA image data */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + priv->fpga_data_addr = devm_ioremap_resource(dev, res); + if (IS_ERR(priv->fpga_data_addr)) + return PTR_ERR(priv->fpga_data_addr); + + /* regmap for register access */ + priv->regmap = devm_regmap_init_mmio(dev, reg_base, + &socfpga_a10_fpga_regmap_config); + if (IS_ERR(priv->regmap)) + return -ENODEV; + + priv->clk = devm_clk_get(dev, NULL); + if (IS_ERR(priv->clk)) { + dev_err(dev, "no clock specified\n"); + return PTR_ERR(priv->clk); + } + + ret = clk_prepare_enable(priv->clk); + if (ret) { + dev_err(dev, "could not enable clock\n"); + return -EBUSY; + } + + return fpga_mgr_register(dev, "SoCFPGA Arria10 FPGA Manager", + &socfpga_a10_fpga_mgr_ops, priv); +} + +static int socfpga_a10_fpga_remove(struct platform_device *pdev) +{ + struct fpga_manager *mgr = platform_get_drvdata(pdev); + struct a10_fpga_priv *priv = mgr->priv; + + fpga_mgr_unregister(&pdev->dev); + clk_disable_unprepare(priv->clk); + + return 0; +} + +static const struct of_device_id socfpga_a10_fpga_of_match[] = { + { .compatible = "altr,socfpga-a10-fpga-mgr", }, + {}, +}; + +MODULE_DEVICE_TABLE(of, socfpga_a10_fpga_of_match); + +static struct platform_driver socfpga_a10_fpga_driver = { + .probe = socfpga_a10_fpga_probe, + .remove = socfpga_a10_fpga_remove, + .driver = { + .name = "socfpga_a10_fpga_manager", + .of_match_table = socfpga_a10_fpga_of_match, + }, +}; + +module_platform_driver(socfpga_a10_fpga_driver); + +MODULE_AUTHOR("Alan Tull "); +MODULE_DESCRIPTION("SoCFPGA Arria10 FPGA Manager"); +MODULE_LICENSE("GPL v2"); -- 2.10.1