From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754558AbcI1Sif (ORCPT ); Wed, 28 Sep 2016 14:38:35 -0400 Received: from mail-dm3nam03on0071.outbound.protection.outlook.com ([104.47.41.71]:64807 "EHLO NAM03-DM3-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1754454AbcI1Shn (ORCPT ); Wed, 28 Sep 2016 14:37:43 -0400 X-Greylist: delayed 900 seconds by postgrey-1.27 at vger.kernel.org; Wed, 28 Sep 2016 14:37:43 EDT Authentication-Results: spf=fail (sender IP is 66.35.236.227) smtp.mailfrom=opensource.altera.com; ni.com; dkim=pass (signature was verified) header.d=altera.onmicrosoft.com;ni.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 , Ian Campbell , Jon Masters , "Walter Goossens" , Michal Simek , Cyril Chemparathy , Josh Cartwright , Matthew Gerlach , Dinh Nguyen , , , , , Alan Tull Subject: [PATCH v19 12/12] fpga-manager: Add Socfpga Arria10 support Date: Wed, 28 Sep 2016 13:22:00 -0500 Message-ID: <20160928182200.15800-13-atull@opensource.altera.com> X-Mailer: git-send-email 2.10.0 In-Reply-To: <20160928182200.15800-1-atull@opensource.altera.com> References: <20160928182200.15800-1-atull@opensource.altera.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [64.129.157.38] X-ClientProxiedBy: BY2PR1001CA0078.namprd10.prod.outlook.com (10.164.163.46) To BLUPR03MB1508.namprd03.prod.outlook.com (10.163.81.26) X-MS-Office365-Filtering-Correlation-Id: 72185a27-57d1-4fe0-5ce3-08d3e7cc6478 X-Microsoft-Exchange-Diagnostics-untrusted: 1;BLUPR03MB1508;2:BecxJXZADeXbBJcxZH+XKBR/LRtad6DZ1KDvLtAcEErRX3ZKyGmWoon4NwLLOV4dJ99+fNCuMCdxwq5GSyEDPS02CImmuW1mkcnBNScKj9DGGtLJ/6xXFmaL5DbSs9Q53cQ29KoX+nk3ecnJTRunqaHQHYzEJjRz6bUkOs90Hm0TdbH0M6f6IkX9ZeTQ5fBH;3:UXXUfcrJJ3Galf8SvaRal7fKHE1xksyENVd/3t6wAw0dlN/YTEzz3tcIgLo6Qdysh436AMpEW4ph126hEbx1A0dq3dq3n0P45xYaCmrwIBm2SiSNKaxQ8y9kp/NQfnZv X-Microsoft-Antispam-Untrusted: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:BLUPR03MB1508; X-Microsoft-Exchange-Diagnostics-untrusted: 1;BLUPR03MB1508;25:dxTOKyDzqGgQ4VjkteJy9zZ1e/9wTyHvIIDJ3WCZbiw0XepGIEz37Oqfn5yl/+0WR7cbLplgDGxchvtQOKBATrr5ESkcCVi5T+n5DZ3Pm+8bcyux+7XKqfhGUqNA6AErvizuUml6v3Iv8qRgOVwoZnjGy7s2RWqzr7bsm8JuBKqZBeD5gwMN9rX0rrX34sfTOB1A22i3pVYQc03RL/h12l26t709/GB0dwhY8kAsEVYLNbH9Ct2Q7y9vS+/MD2jLQP/deMdP9zpYnXmRz8I9TvSyeZJIjWKb9Y5CHP5sITj64SsqM92deMqyn7azdsG5H4/FchLTiH0GaYqldHm61yk1P1vxhs48ZQGeooEqpm6CeCXajzbTZqXedYvG1MdvXlLDOzyRqMujGWqyUlWVysgCDtEDYHrTJsF1koimA4b70a7EBwNKVRzvcXp5XMnwOyk+igI+SpeZMzrn9u6ivzMez7PJ9ZTltMGCZ+XeejrUi5D6tyS4jLPBrg9f4w597QM70bmI2EnUmZ59gzA7QQ2wQ5Z3FnHMTjQyvZFfGBp+fmc8TuuqGfZldICdoagF0h8JlksymMHV7lqBacfEPY7VJL0343RglkKMy3kyjnlkDfrq1M5GfSWT+d1nvvP6uRwYDpJtxZPPP1UrcmkyEi7kZgrTHC9BRRbUsPiDLFQarqT5HHfFrcE7r3Cl6fkc/8JmIwvkIF3o03BfTi6v4/3bIlqtX5U5xmZ2YPGTiSx2KZlCT6TZ2Oppt7IQ3VDo51fy/1bAaYvAL6oWQN4e3Dgj5+g69YRd5P56urMeDZuy31wQccupjWhPjQIJFFTn X-Microsoft-Exchange-Diagnostics-untrusted: 1;BLUPR03MB1508;31:Qiu0wt1ymGuVzlzUB3hzy0ueoklCoqlaP7mXD5hnRej8N91GGXitVi62BMin6R1gNlWsq1B4zREiTqyAxr+fLzCHGf7kw0+Xnr+08QfhHD9JSG+Rr/xl9QVay+IheyGqD82hlaYN5fH+Id2cXSQ5IBkh/bBRip7inPZa3/vZ7/ARtzwNYl7iMeJj8tKyhAPQRapQUfsKGVpWukJ6fLJBhgHZG+O+zIgS7zIRCF0ywSY=;20:Vsl0dBXdfq3NGfLFiq4yRWRF+OOC5DHPUnZPhU8JPMRg3tIoFauzmZNKEUbICVPfPc/AKZJqnbm2a5490JyFsACAoMQP3adXANn7gCSbpqV1Fqp+0Rp3cQnh3le1DYL55/dzOvs6W4KMpguD8TniYa1sJ9VcHfv3V2QSLmUHkys=;4:BplKAsZJ790b/fs614nD5OeRfOccgCqKq03fK+RyOC4UD8cjUC7PzOa4v1qWbsZinSxFjQH8EBvEg+LuWbU+URzJBT4NoZKWEm7e/sxagco7XnKhlXi9V6Tb20cNEroagyNQI+nefM9hOG3XT5tYj8I+Mt2nf1sRzCCP727+LHZZJ9rpvwWKn59PNpJWIVYPwYo6kPOFRdCfnqRaq9q0bqUqzzldJ0MJdqivmxepAGmDimDsL0CLh2HVlFa52yCKDcqm2kOittH3LZAc+rUDHwehXu0C2zrgCnS8BOIdSlgbG+9YCvYxU5e1PArGQHy4S6eGb9h2EvV4gUUVEiazoIdvNkF9WMXr8kNS5hKHk3EUuTkmU4rJfmefHANDFd8bRYESrniy8vwos2nTHS+XhOuw+nMlB3xoC4K3JJ3NupTf29Fxi9wHVDU2wMWx4bulpYh/mlWhi4iKdg41g6/E33XI41tt3lpBXhBC1M89MOT0N3Rzvkviliqch84Aazgwv8OKlXfuYle0MWv5GwbwsQ== 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)(8121501046)(5005006)(3002001)(10201501046)(6055026);SRVR:BLUPR03MB1508;BCL:0;PCL:0;RULEID:;SRVR:BLUPR03MB1508;BCL:0;PCL:0;RULEID:(6040176)(601004)(2401047)(5005006)(8121501046)(13018025)(13024025)(13023025)(13015025)(13017025)(10201501046)(3002001)(6055026);SRVR:CH1PR03MB1915;BCL:0;PCL:0;RULEID:;SRVR:CH1PR03MB1915; X-Forefront-PRVS: 0079056367 X-Forefront-Antispam-Report-Untrusted: SFV:NSPM;SFS:(10009020)(4630300001)(6009001)(7916002)(199003)(189002)(53416004)(97736004)(189998001)(107886002)(19580405001)(575784001)(86362001)(33646002)(19580395003)(5660300001)(7416002)(2950100002)(42882006)(76176999)(110136003)(15975445007)(101416001)(77096005)(5003940100001)(4326007)(106356001)(92566002)(50986999)(66066001)(2906002)(42186005)(48376002)(1076002)(105586002)(50466002)(47776003)(586003)(6116002)(3846002)(50226002)(229853001)(69596002)(4001430100002)(81156014)(81166006)(7736002)(7846002)(305945005)(8676002)(8666005)(68736007)(7059030)(2004002);DIR:OUT;SFP:1101;SCL:1;SRVR:BLUPR03MB1508;H:linuxheads99.altera.com;FPR:;SPF:None;PTR:InfoNoRecords;A:0;MX:1;LANG:en; X-Microsoft-Exchange-Diagnostics-untrusted: =?us-ascii?Q?1;BLUPR03MB1508;23:1FFX0vJplfjW3qV+8mqrcz8ZZ1OgdClHvg+7ZQQ/p?= =?us-ascii?Q?CYGOf1IeyBVGdaz2NRswpQ60zdsYBGGT2jp0LYlUZLKne5CS55jIJ5oA73vB?= =?us-ascii?Q?0m3KBsFfG55HXTn5MvFI/JuYUw+X1Kwko0CCM0j3S/nuSOtq0zyK7qog/ype?= =?us-ascii?Q?dY1fo8F7a6/+S+HPm0eCiX7VgBK6lrvXd0JyZgV6YVMIjEMWgzPOEzmiCndA?= =?us-ascii?Q?LUcf27ndZs7zBA8xOCDrTVVGzc9GBpY7plVytQJN/EqEaAwjsKSC6RaT8M/r?= =?us-ascii?Q?W7z4uGTuz7c+qV5ZOQFOcj5FNNLbDsfmcE4M37CviqtKYGASKLAKCoyqi9NI?= =?us-ascii?Q?G8w8zmsNL8tlszN7TxvJnJMDMY5EsxHzZt/3Bo2xGagZ8+227aeP7bc7euX+?= =?us-ascii?Q?FWr2uWf4hmDsRrk1i1zwS+SsgZSWoUBG6wrgrsnJ3qnVQvJvfQ5NQPZ6CYPH?= =?us-ascii?Q?oqYQ7vtNfjcoAT6+C/A+0PMkSpxoM1UfTsL+/QtWtp4FTXhCyOAaL8EebNX+?= =?us-ascii?Q?NWDaVgLLwC7N7wJy/Hd78XQYzPgH1wDIn4dcKmZDrDljgRU2GdvbuzdgHdud?= =?us-ascii?Q?c1uj1wn5UWCcJFoHYFJ5qkF14r6gfSFi5tMezH/d+Qfzygh5O4JjyHmf8XPA?= =?us-ascii?Q?o+TCclt033Ul7Vms3rORDZMRzb+xinB15WMn+2hSdLTjCsVk9L36liaXzmje?= =?us-ascii?Q?YwUO4d0vF/cA6yOPkZ2ecZQChGZ2BCKVFCyzJq12RyW/JImxuylhKaUPxrOs?= =?us-ascii?Q?ZAhBUcGHEIhwxEZ9UEqgvHxsP7KVFQEbRBQ+QyRAgmvE7ydfdzPidat24Bug?= =?us-ascii?Q?dC/lfH0a3j8micgbAW9VP69T2edNFt7N+bSAuk9llC/hx/KvWjjzoVbXfh0D?= =?us-ascii?Q?/Dv4BtSKnu1QxpLfVOqphiMJSaYQk8+S4lFBQ8mmMc3dv9OriiY2WBuZL8uf?= =?us-ascii?Q?HGwF02oR4vDHsiqsUu08N926x2hwRdwVIl08xO7/yFRNZPwnjrtXbk57PuUv?= =?us-ascii?Q?2nYLSswM29z7MPM99TIUivpJ9/J6OI7NxDP4XA/Dlr2CLdAYHA0PMbR0BZQ2?= =?us-ascii?Q?Tsszv8o6bWle7kApC5WKjCP8A7tWzkkFZuZi6OZeh7J/lMwjU80p4fx98xrl?= =?us-ascii?Q?rNhLuRdlPNdUT07GWVH98jnf+KzjR6vYTLQP7nIZaoc7obkdNcm8rDGrkraZ?= =?us-ascii?Q?pZZVLy/Qnd+a8k9ri96L6AXvmYe+nRCVRZ2BdM1HGmom5Z6OP4LpSPx25n60?= =?us-ascii?Q?0bVCK9rdFhXl/xSibzH6+Qpy9AsRxuNDnFeseca?= X-Microsoft-Exchange-Diagnostics-untrusted: 1;BLUPR03MB1508;6:W8RNmNWmppC+LTz8reuLz/gyVOWfjctXTbgkS650c4PJQUW21v78dUCjoR3CPKJo0io9vnLH2/+YQC4kKAXrejcUrRqKRWxM9oCgt9RVkmUdZ1NsqZ8UPvrbfaCzgO4anLZwUysF3IpKeMMroRyVWyI2Tx+svLsCbRrEOfIBInp5dn68F6AJdbEwsbhy37x0l8ET3qpOeYpCabdhs7fJrqGwk0LOTDw/8nAeJxYhkEiIsygKuBugH/rwvfnVSZZV8/uc785y/VPsb2AwDX4NEsPmuj7kobZveGfTZRDpOmKVbnsCSRKeILkMVVQUWC+m7RkfCqoGkoJOPG04FjwVnA==;5:Rc1bzyPosNshKlFIoNwArgaHAS5+ajCd8m8KvWDp8AoqdJKWOASz2cwCmR2ejzB4BY4s6H/RLuLo95jVqDVd1kAvqldev9HEroEwnV/zIsjuho1VyDn1h3/SUi7/cs2O+BYEgMVHtugqvsdNKxMrUw==;24:g6BNJzvKdki1Jsgpsh7hQi5DAhZ0w2kWb9M5yyhj0kZZJpplayGvL7JK8YHEjDmF6uejpGa4+/m2dFOjNwTrQWQ45ZJhiskryGT8ETyl6As=;7:wgD+WNNs5QaPnS9yH6mD/itBX7TjSwDdDgdO0zTeFJQGzHCcsL0giJc+np2G/vc1Vb9WR1q7d+piK0gCuI0cAfeaFndzZgktZzrlkzqU+xg8MzRWt2ejoBnPRqzQShL4+l2/1kGuKXRrA7Eo+Lcy91pGLeqfCqcOJ4QsyC6YrJcfiprn4EaS7z65k//Pul7pKw6vlqXNJyVz0POVAXKuu5cWDyOC597bjZa1nRNvOdspvAiM7W1pgsxoLnneeBv1D55zgVTS+WSTqCTAEFQyfNK1E35O5ShOZRIFw/z7Jg3nq6RNm0aPS1PZ/0fANt45 SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-MS-Exchange-Transport-CrossTenantHeadersStamped: BLUPR03MB1508 X-EOPAttributedMessage: 0 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)(189002)(199003)(5660300001)(85426001)(87936001)(68736007)(4001430100002)(4326007)(3720700001)(50226002)(66066001)(575784001)(86362001)(81156014)(6116002)(8676002)(81166006)(47776003)(92566002)(356003)(7846002)(586003)(8666005)(2950100002)(5003940100001)(7736002)(42882006)(2906002)(8936002)(305945005)(3846002)(1076002)(107886002)(956001)(6070500001)(33646002)(110136003)(97736004)(50466002)(336002)(189998001)(7416002)(15975445007)(76176999)(50986999)(626004)(105606002)(229853001)(48376002)(53416004)(19580395003)(19580405001)(16796002)(106466001)(77096005)(7099028)(7059030)(2004002);DIR:OUT;SFP:1101;SCL:1;SRVR:CH1PR03MB1915;H:sj-itexedge03.altera.priv.altera.com;FPR:;SPF:Fail;PTR:InfoDomainNonexistent;MX:1;A:0;LANG:en; X-Microsoft-Exchange-Diagnostics: 1;BL2FFO11OLC002;1:0Jzglzf9YUr8xu/EXwTviWImWEyPjx6um2YIriYlWJPhu35mtrtkzrkFC3gSGeAlCxJfrIlWaIOcMxg9jwBIzBUia6c1bxXeLndsbCtYL8Eq3F5ddEZVbBeVS9dhBxbrp/zZyDYnyCpPgvuXuKKZs1bjS40X65q2RGiBPGDI1rB7907dJnTqP2VMB9hkTsk+tCANShMRD7bKYcrXnoo7wiAlwIVoBiBwatIEv6098EGCpCudMno8AMoV80rqBZKG9RrXtvACrRCkAjWDkwRVbxlfvdtcPBFoohbnqA0D/jprDlGENxBZKzLyep2EC2qQpUf7MCreKeMH5ESv8MGjzYr+OzWvWCfkyvIJQ1nbAXztaHnwo9dINvYOEl3uwir1A1hTygYifzYiNYiHBwFJl6uDKMzO7XMZUnVE/EhzeICkLb2W3hv1cn1+ZgLO9c8KFM73+XOWXwGjRZeBMjeiOBsIXd5JqpqO4ZJrbkfHiSaV1QLQgqhu2lE4xoVsVZKqVZswxVLJOz7Z0pkrKlnSBqWfcYlTb+2O5SxdN+S6wXFwUO7SySeOtEbYeZFiY6d82nKZVHULMdA11ppi0KARGdeDEgLxIJNf64explqRUi0= X-MS-Exchange-Transport-CrossTenantHeadersStripped: BL2FFO11OLC002.protection.gbl X-Microsoft-Exchange-Diagnostics: 1;CH1PR03MB1915;2:zH5J+Y/rhRXuIaF2XVnGhawpMsQ5ZyHbcgqA+oLJB5xp34++cfzF1K4PV4kk6V4f9ElaBJg+2RSbRvLu0BW6WirtgmY4oDgi+qjt138kEa09EmjBd4npgSzjZsALPXdpmQjSAQHCPIBwJsGyBh0TGEQuFkow2q8Ruej/13bhVF1JqvVZsw1OwEl7YZfkH5c7RnAvfmgvEroyOBGslgExaA==;3:VcTCh+L/PJYKe8bxmWHFiPWIIpy0iYbFeLtQuOTonh/YQFMu4/+LNYkWWnf5Dn7TH9W/BBTyDhBreHRG7jxQLbn+ioiIn2glFR/002DF5n8vWW5r1+C5o17OtkjjDZ12Kq4O4na66bqZQ6zI0U88uZahttAX4DRc08rfWEpMS5afVtZ5Aa73zK/4nn2Pi5nkCh8AFN+u/FT9IMqC371svgtwUF4RvN+ufdaJe0JgZIWJ5dBc0OIdrOXJ7LoNCC+4lnSNvazesnN1ZC8zrtRa5w== X-DkimResult-Test: Passed X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(3001016);SRVR:CH1PR03MB1915; X-Microsoft-Exchange-Diagnostics: 1;CH1PR03MB1915;25:7whNARh060f37Go3GA9omrkAC1JCGV9PIMwgZQR8+0+6yIl5dsYHJhooEc3xhA6TprLQndJB3AyRqGUMA/pOU/RvG617kPH1O8b/wzxXhbR7prPxRvRDK5bECBkha5PsQe0MAon1Et61KuJrWcQyef31PGRQFEDiQB0LpPpanPHhsrA2H/DDF+10EY2fo9GPYKa8dCyvV5DThBIcjIM9xD2eHuimGgdszZ3owbFopPpIBv6LtDFzcVMmIMABy6kIOsJ4S5lN0aQmahE6hlEuX/ZMC5rsJXsmltf7OrLVDzne+DLhepeOacq0Y/4EXE/yDa301kdSSgXVTelEptRJweY9F1/iwWrcrAYQQ2wqlNjTTmaociK+nvUnCHMEv8+8TS/Ov0lvxbafOhmVU9+fZTRZm0GQeJ10u5XlVSmKn59VCE8Xic9Zox8BtTkz2G+VsNN5hiB+c/By9vljjf3SD1RX0yiF+KvhI01Wcm98j1UPWWUtN+YEe1lamcCVvxe4432vA8Sy+adOUZ7c5+sHozmaxmqogKb5Ox5kioTUWGvIi2SG0t5U5Dpj3gAYeB1TmU99Lb1d/TyXdB6J18BurKqR6/YwQ1FT9e85uMbtuPfmC8Jwm4nRAijrTPTYMwYwifUbYJc3ZKMcqJNZt8uqT+EM7Hv1gs3nhD8IIo4IfO/W+wlbqts+BvHNUkU4x0BPsNqta9zFmJoDx+gvgdgcmOLY3YU9MejyeLpBWvdli4ORyE19UDuRqkENgLtxc28DTAflZPgXzVtLaGEEoHy22TmSEaJ3InA7Wrg8REeANGiBiVezsFYxHb6UuECwo2j9K697COfmYTv4mM04uT1L/Q== X-Microsoft-Exchange-Diagnostics: 1;CH1PR03MB1915;31:U50ISVxM+ss5n21jcguhVvD3DVUcZBPJ7dVJ5xABFfvPlWTZey6cbLWslH21GjS9v4VSX+EsxKBEbNEdR2iSHTzcT4khVw7epWscBvOSajQ3L+58OidUenwI4AGxgRyGxoWDNiGbXldsltiMnBXr5+6kpbF1ocxXId9N3u5AVLDEyq7q2x0IKxfiumuvqTGdFgg4BVuVGqN6zut6cdAHLyrEGaE9cWGL4ZZ45A+MZ2vN3m1FZo/hzqFLE0jnOtIi;20:xOhOSnptnscFOVf1X5lzAMa3qbRQMlBUNoOU0FSrnB+bt+QxBinNuSZBsoJwgnaSLQCqthxRztsah/VLhwoi76DB+Pvd4qk2m9sHb3f3HGs20WCeHNRcGZTjtBhJyuHt9Yaa8zp/i4ln3oHq6/DnYQY/zsknRAmHTwUuHji/lCg= X-Microsoft-Exchange-Diagnostics: 1;CH1PR03MB1915;4:ktASRNdKfLNFefT/PMhbcXVsT/cXZwKR9b90keEJ16TAuaRlN+tWsRrJvOHsVysroxv/bK/vnzih2+ZizUuiO34JxNWH3fQIOXtRfa6IMQSJtUZq5UKOzy6j4N2Ri9GYgK5w4+uzyAA1Wuwl3LVhuFL1mSbXh8R7jIl81eJ7DQBUh6ljNuCm4W7vl035mOIZXLpNUtM7VZEZNr+A3eXhKqyIVfolJMAondsrdCmODICythiFblINicylNb70wdUEmfhNK0/yNyyaliYTuahNDgcmu09rJBcWvvuZRivlXmP/bV6uuhc7o+0YKBGt+jObhTxerqZWaI61rOT+4F5PhiTqO881tPlbB+pNV5dZa418yWJuLRtKNzJ7Rw+EBSDwr0cOtI7YoDh+CLSjYOfsvSNpBMfKmLY7/YcvbGaayEzpYyx3Y3S0dmZKb8lw9z8zmJjYbjjOitu0tAgrW+c+dp9iecT1sJaoAxKa3lxfEOx4wOmAN5l/5OEch9GCd/JyENc+Kwm8BBsJGi0wOTzREadYoWXImlinjUF9L4ekEbqglV+sSsNILS5LLXoFoiP7+pjjlYbmFOEyJZrkY6pPC8t+80ThJ+YO0clbP6zVQPjBexRGYZrhTdQfR9ZiHLVK X-Forefront-PRVS: 0079056367 X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;CH1PR03MB1915;23:D2sCcE2glkAuMngZGUlkqOmEfr9AGEb7by+2o17ZY?= =?us-ascii?Q?3Pof7cWHZsl3TbFcBAyFioKl5C9Q7cte5a/Ue7mUP8QXiVwKSUF9xnelCrhB?= =?us-ascii?Q?kRpL/tcayTLTMmnLNMpahuHk5vNxcJtqUg6Ozm2+j6FT7DavjTjshG9VFMSS?= =?us-ascii?Q?pRbFbyNXnnvzx/eH3Kxa7GUdX3hy2AhxF+fAJJFF15farjRVUdstDsk+83HA?= =?us-ascii?Q?2yEBgRSCTr0bIeK6drxxlovur+IwSUtFlkO2rVKAp3sD54x1KzfX/o2KqrG9?= =?us-ascii?Q?kPMB1cHxUiMCLuS9Q2Zwz4K1bbe6j+bEHluSrjk6eR4JTpbbPbfXxWxZMQF3?= =?us-ascii?Q?U2G0JFameCUX8jkZaVGwhSoDB57CnsfLKPWn+d5Pfjazkj2NxrlYo16as763?= =?us-ascii?Q?7Lk0/tzK3xD1T8OZzh58rs17s+qkmWo54Slkn0NndYUziUcsrW1dJQuKa9h/?= =?us-ascii?Q?odde/i0zMtCNe4pTjvfxgwoOw/oHv2Rd4FDL7Riyj8XZTAKaiDjUM4PjiQ+O?= =?us-ascii?Q?br5xRqEU9ozG4TGGA2J/C/x8yhM7H61jAgb8t+7LsbnJwG769N6g4sNdtcTZ?= =?us-ascii?Q?2n/Ckso3FW2QuZ2qTI0KLbaGq/KC0xLl9L+KR3nmFuSjBEFJEn5amFV7YoKl?= =?us-ascii?Q?ym1uXfe5CouVmflv9XS+UEMwdi10cPlphCMJ1t+Tvx9kxD4ctyIaQGhgDUjA?= =?us-ascii?Q?RUdhBe3W+HCVHrZjTcXHdpL6Ls7gFWpP0F7wJhC/uo1xyI3WoMC7oKYTyfLB?= =?us-ascii?Q?CxOfvvpGkrXYC3q0/5idYALT4WfU+MDDd/cmqIg5o2u1CA2CHzqpr8AfrQ+K?= =?us-ascii?Q?SxShCP9BHV9JsZowdtVntF8BVyGOAkMsdSZyJXPKwpZ1X02EFWquTWIofA/M?= =?us-ascii?Q?cPQUuoLWHdj+g3YpaGfrHqDTYcQtauMyMddw4gHZm53pbLbhnkz4sjAplbEG?= =?us-ascii?Q?/2P5qdcUalI2k4PJ2jwl7GHUk+XKckxYj8NXa4c/6nA/GH3OuprC+P2DnRrt?= =?us-ascii?Q?1Lu6/5bRZ7gu0JWwvfjwGP/iYvdtvjkG/pRhjcUSCGq1eDUl1pZaBtavuSYo?= =?us-ascii?Q?txDVnXs/VvykcpOjMPzkIYNAqmjjj8DrYTXl4cnAgFIxu8o+W9s+pUg3q9x3?= =?us-ascii?Q?pWtNM4CYsE2i3iYE4ijvlYVc2jEFATO8kMjQi4xMD8zakSdEvpIa3EsIv9ZI?= =?us-ascii?Q?cEHvoZKyMcnses+WmV+bQ8oRchff3TF0rJO/5gjl3EPRcGGVejna8gyzUwpt?= =?us-ascii?Q?HaWcDYKl0phyMMPJhI8AgOv1CRvInx81Jm33Cztvl8Bm4yGAm/dbcE61u1xQ?= =?us-ascii?Q?4Ii02sobrFEcy0RaZb7mvOZsYR1AO2eTV00275/vUVGOCkFLoJMAd0lYjzSM?= =?us-ascii?Q?t2MWUv9YJS7vWxPNrGhDRzM3baNGILSOyeY8/5kx/8GUfrOWgxg4BRkNIHZk?= =?us-ascii?Q?t1C77xAjKtDvEC8N0bLxFlXvgfY8BT9Sa1l1U9EFuxsAWeE405k3EfXKaxXo?= =?us-ascii?Q?xJeFs77BNhcxQ=3D=3D?= X-Microsoft-Exchange-Diagnostics: 1;CH1PR03MB1915;6:4HLwCwPkSSLfWfsZ+CS6asKRk0xV9lGcimd3AUT0fjJzFktPsKdKHXGMN1M4SetOWAU1eEfUHDQxRP+I3msEd67hp+0dZiOid+J1eqTEub/ZRUWs3PciEg5bkyWRlewb5MvPlMuSGnYLRZ87s52Y9xEy1YQzMD5p9ZXEPAa8abo4uxKNLBLEtHeks0o46N6kT79w1B0pLw3CZQ2scMxa5E7+Wi6iW56sDDN9yljnZLhC0Ch5fB1qojWQbae1NUim/z8HAWzWiNBBtRSbNmyY2aMQl013sFeI3CHqOVCfH/qqs40GuTQkYt76s9N9GcI9TqFnNsG5YPWgZlFS0DBusL5di/RpYBgTBNStin518Bs=;5:6c/Uyoj3xXo/NaqczF3HOxR5d1ewR/PIWV0Ud8I8EhK5cGbjztaFMCleWEqx3AZeKXj6iPa/+SeAyKGt0Nc6e7mhqTb5XpkKc5qr0V1wq16oT0vQlGlTDW74rTPP0v1Gs5aRBHA6aZ4ghq9e4bHOxb2EdsJclXAUScbrJxyqrwk=;24:HoJ1sh7o6CVnR2S/A9FB/EM9cE8UEv06swOlTlqfcZlehmqWLjh0KNtMYeUfvKNr9Lms9NC3hdTG7fNo7BAnssNiMqzDedanht6jtz9fC0I=;7:Rz2vPFryO/C423N8J682oGeFZlxiasrU/TVFSg4CQMF8ARBsfoTwCIGl3cFrBXWfdA52ON7P21voS782BVPObMjVPU/oko8Vf7yd0Y+ee+ASxTW+TMDxLJQX543/wvyUzYb0n9i7a+lQ9zoHHJ8hkxGtXJhuI5qrt5vUE/Yahw6FB6JG6RTBGHH8gkyvI5Vr7ucdLxRFhce1zQdXicaZQKUVjtpVTpzvmuK0ZvK6G3wm2UBWayMDZ7ru83K/K96Se73nS5MDK+ygMqqGuXjHNWz3IKekjG+hCzGIC/I+IQo= X-OriginatorOrg: opensource.altera.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 28 Sep 2016 18:22:14.8370 (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: CH1PR03MB1915 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add low level driver to support reprogramming FPGAs for Altera SoCFPGA Arria10. Signed-off-by: Alan Tull --- 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 --- drivers/fpga/Kconfig | 6 + drivers/fpga/Makefile | 1 + drivers/fpga/socfpga-a10.c | 572 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 579 insertions(+) create mode 100644 drivers/fpga/socfpga-a10.c diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig index 0d1887f..bc56c4c 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 HAS_DMA 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..01ca5f0 --- /dev/null +++ b/drivers/fpga/socfpga-a10.c @@ -0,0 +1,572 @@ +/* + * 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; + unsigned int i; + + /* 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 */ + for (i = 0; i < 100; i++) { + regmap_read(priv->regmap, A10_FPGAMGR_DCLKSTAT_OFST, &val); + if (val) + break; + udelay(1); + } + + /* Clear DONE status. */ + regmap_write(priv->regmap, A10_FPGAMGR_DCLKSTAT_OFST, + A10_FPGAMGR_DCLKSTAT_DCLKDONE); +} + +static int socfpga_a10_fpga_encrypted(struct fpga_manager *mgr, + u32 *buf32, size_t buf32_size) +{ + int encrypt; + + if (buf32_size < 70) + return -EINVAL; + + encrypt = ((buf32[69] >> 2) & 3) != 0; + + dev_dbg(&mgr->dev, "header word %d = %08x encrypt=%d\n", + 69, buf32[69], encrypt); + + return encrypt; +} + +static int socfpga_a10_fpga_compressed(struct fpga_manager *mgr, + u32 *buf32, size_t buf32_size) +{ + int compress; + + if (buf32_size < 230) + return -EINVAL; + + compress = !((buf32[229] >> 1) & 1); + + dev_dbg(&mgr->dev, "header word %d = %08x compress=%d\n", + 229, buf32[229], compress); + + return compress; +} + +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(mgr, (u32 *)buf, count / 4); + if (encrypt < 0) + return -EINVAL; + + compress = socfpga_a10_fpga_compressed(mgr, (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); + + /* Do some dclks, wait for pr_ready */ + 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.9.3