Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965165AbcJQQnX (ORCPT ); Mon, 17 Oct 2016 12:43:23 -0400 Received: from mail-dm3nam03on0088.outbound.protection.outlook.com ([104.47.41.88]:13136 "EHLO NAM03-DM3-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S965124AbcJQQnM (ORCPT ); Mon, 17 Oct 2016 12:43:12 -0400 Authentication-Results: spf=fail (sender IP is 66.35.236.236) smtp.mailfrom=opensource.altera.com; vger.kernel.org; dkim=pass (signature was verified) header.d=altera.onmicrosoft.com;vger.kernel.org; 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 , Michal Simek , Jonathan Corbet , "Cyril Chemparathy" , Matthew Gerlach , Dinh Nguyen , , , , , , Alan Tull Subject: [PATCH v20 10/10] fpga-manager: Add Socfpga Arria10 support Date: Mon, 17 Oct 2016 11:09:41 -0500 Message-ID: <20161017160941.4205-11-atull@opensource.altera.com> X-Mailer: git-send-email 2.10.1 In-Reply-To: <20161017160941.4205-1-atull@opensource.altera.com> References: <20161017160941.4205-1-atull@opensource.altera.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [64.129.157.38] X-ClientProxiedBy: BLUPR16CA0005.namprd16.prod.outlook.com (10.164.14.15) To BN3PR03MB1512.namprd03.prod.outlook.com (10.163.35.150) X-MS-Office365-Filtering-Correlation-Id: 450a42fe-ba22-4aef-1dcb-08d3f6a81295 X-Microsoft-Exchange-Diagnostics-untrusted: 1;BN3PR03MB1512;2:vZiXWt0XZ96hiajZa5ISS6hzUgQute95swsbH/S9KWhDaDqCTHkCcmR1NlNUOMR6lCiycLJj+13HwUECM3Mq4TGiawlV50ktDbJ1OpOjOB/FcRFu+mI5LfPCXfSFfwe1mx406VvL1ruybZWuorCIu+mX4pPNdGQTQrIhYRgXqYb/WXZz1FU3ANom2DF5UQEqfX2DWcg7peu9UdwYCcaOTA==;3:J1oV9zv25oLYJe7sgJdJIIazUGC1fROxrG+Rrx7vN6MguruYh/CmBE9QUc8ZQfAQfby0MN54Onz24HkA7X5xis7r/E0dHRkp2AHnI7qS4c7EJrGTuUgrdgMZ72Xy1jAYXgDb7Pvh68ohZaMIDXf6XQ== X-Microsoft-Antispam-Untrusted: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:BN3PR03MB1512; X-Microsoft-Exchange-Diagnostics-untrusted: 1;BN3PR03MB1512;25:WTVRw4/q4/IcFmpwF/UuUEkYJfR1Mvshmc+e7MYEKedu0n/QxRPYWv4PZHgEzM3x1wskU9KecobtFXghr8YkJQ6maueWK5wfQ9C6lDAVzOIdF6WxYa5ZkBfOhcdvAXci+pEpaP3M0/aQQKuPMNudE9KUpkn+zKKBcV7G9DMRnNquToBpohwEGt5LcmYtEqy9vYKOtbKjQXpkeXd1CJfw1PGPV09TnCyEXMhpwFR0efevR2KLmgwBHsMhhbubMLW2WCo4o0HQYFvynS1vy0IIxX7YWUEiYsxrSOTD5eIIygqwBpAWK/zL2ioGxhdgN4MhvS2478HlL0XY9qJyKQb1fNMykoBLiSZFtqiWvUv2P1lUAWXN9SZGJFTjOD7aih3Jki5H16i68/tjCEUox3CILCsfqEr0WDzqiQ7QDGhuGwGV4NVeM0JfzwBQVnSKnXYwAiMYG5fQLaoSBolGVQAbnIT5TrMaRAbYsJpOk7UQBmlArT4lVjr9zpk7Dmscqvqd4Yq4oQNAcAZCffoGX514KnHVp6jtGzufPQL2WtDSWauEkZRcimWL9dMpn04NopAegGJtjvMz/rbgMBJoRdV/WXZbAY6u5Xl69Vk2gmZkt9etkxGXJUfRBnYAZU/bQs78hOd22CSehxJFGaYtvAsCw7pYaeYtka6ToJDp+STwnLnSouRF//Kkdlz0meqntoAf34EbQeSUqQyTSAIObk8Q8vpnSv/Np2uR711aaRPhIlHvEnhVhWF7d1JOt88K12G2j5/T3fCXj74BxgDjX0h3+BhOHo75W8TV4dHPfKW2AoevUlgcjp+5KTn9TbLkkiiy8sbMf3qfoxEzGmmeic3LTYYeq+fIVCSCY29wH4erLiY= X-Microsoft-Exchange-Diagnostics-untrusted: 1;BN3PR03MB1512;31:vVCfzhFWThWkjL9wq/Z/Mm61UgLcSwQRINIb5DSJdDjTKUYC6mpgoky3xlTX4DG70kebI6BJSqzD9wk0koqo0mqbInf28LPs/k/Duve4nIcR38mX1NI6b+ZjO7suOGgsL2qdPQHWLmuWL3qP4DhOaL4UaIWdVB+2F7sE8nq8D7KLaCVUHuMGGXFZsGJeloZB9RbK8XHkrrKVQZe6lQZMmf7rQU27TXPlzBjmR5pNjps02WKisF3YC1XKPJieoIkGd0xX0KgZzKFikG2JBkj5cFeMEsdwdYBdHKXWt0NdnAY=;20:bFFrmnFk27+0y1ds722j71ngiRP/dwXnZQoriV/h89K1g0zwdWdV5mw8PVM9YGneiod712qAoLNzXoIHPwSElWmkcQCL0P/jYjpYneXkM3OFNCBEW6PV8yL1xn56YhC6/1+wPXcSEHwh/FSrai1CBbq50fprLs1jgBxrPODLJUE= 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:BN3PR03MB1512;BCL:0;PCL:0;RULEID:;SRVR:BN3PR03MB1512;BCL:0;PCL:0;RULEID:(6040176)(601004)(2401047)(5005006)(8121501046)(13023025)(13018025)(13024025)(13017025)(13015025)(3002001)(10201501046)(6055026);SRVR:BL2PR03MB257;BCL:0;PCL:0;RULEID:;SRVR:BL2PR03MB257; X-Microsoft-Exchange-Diagnostics-untrusted: 1;BN3PR03MB1512;4:t0nh9A6Kw3SXauaGvJXQueydpT4gIvjXblxZb9XVe53NfB3ivayecJxVKPPx90CuQZF5hl0qjSC6hk6lV+5KCBFk9O3WoDG+Xsot04VaTGhoXs8ufhzqeHf3ooY3srrrJ62QmnlcX9Zn9sJWEky8WHRZMQM1p7SLYQ4Ryqm79kNEaZlCobyPNnOT4QSbVaKr2FbhoCmc1EBMwxfWCK7lMlaERpQUMFfIthKdyavULeQavVCXuD/fzoL/aPUWdG5hwssMCA43L1kgxQZObmd4xaSPW0iZirLO0/WtRW5YZvrWRby4a+tq5URNNh62T2MqFArnrGWzcmh1v2cLiN+VMqw/kfnYNAabf+70JkCqhcDoKPcbiLNJ27QmroMDt7klD8E3JXZpboB94839GWiVFSykK1tkBcn+fTdLlXhN0oCpg0fC0Iy+pc0uTzslN6b/Rz55RS7vOxot+nnmc4UlHOBFp5Nq15MiMrPOTsMtcKZXqRq0RLfZ0avZc37616aikR2/2zJ1XtTAYSjj34LlXL2D7q9jBQ8iJuu8tkKMgsk= X-Forefront-PRVS: 0098BA6C6C X-Forefront-Antispam-Report-Untrusted: SFV:NSPM;SFS:(10009020)(4630300001)(6009001)(7916002)(199003)(189002)(4326007)(8666005)(5660300001)(53416004)(8676002)(48376002)(50466002)(86362001)(575784001)(110136003)(42186005)(50226002)(50986999)(76176999)(4001430100002)(101416001)(33646002)(6666003)(2950100002)(42882006)(5003940100001)(229853001)(15975445007)(106356001)(77096005)(68736007)(66066001)(97736004)(7846002)(107886002)(7416002)(189998001)(7736002)(47776003)(92566002)(105586002)(586003)(6116002)(19580405001)(19580395003)(2906002)(81166006)(305945005)(1076002)(69596002)(3846002)(81156014)(7059030)(2004002);DIR:OUT;SFP:1101;SCL:1;SRVR:BN3PR03MB1512;H:linuxheads99.altera.com;FPR:;SPF:None;PTR:InfoNoRecords;A:0;MX:1;LANG:en; X-Microsoft-Exchange-Diagnostics-untrusted: =?us-ascii?Q?1;BN3PR03MB1512;23:nvDclcU4piie3cHV7b2uGcYLNAUjXRMTfLGMiWCzI?= =?us-ascii?Q?OxfPrH/8XU9aDM/dOhw5Hm2c716IOfXRnpG0ASrT/Qq8NW54HrAGcs1btIvu?= =?us-ascii?Q?20rDCo3KZhMBBe/YeOJnw8sTvtlMlIGatlPq77IYWTdb68seSvc88yCJuwkB?= =?us-ascii?Q?1Cs/zBZYXYLCMI1+x00mJFKLZfmrPFtBtlxb5wn+Q1rvEe+VUEPuDENQIblq?= =?us-ascii?Q?nu2ddDBRsrjei/NiK6xIsna7keVtBWrsK+isfUdg0Il3WK9M5CcdauMZq7YD?= =?us-ascii?Q?4voIeajJEcFP0Nry1qsFor52dJsqqh+CY4VEm9TfxAud9MqBNmxlLRONY9wY?= =?us-ascii?Q?uibFp/N3WlMvfPAnkDm5MkloQBVsoP2OyyWuDnjEvRLo03vDhxH+rGyn/sHs?= =?us-ascii?Q?foTtu9KJO8zyFSinYyTZzMys2VWnTTCWDMo4Rfcw6TH6yqMSYI6CJHWJb88w?= =?us-ascii?Q?QjNODb41AMy9CjGAXTck69goaHe4HHIQGEpNgdv4dD6H9h2QpdpoOr7ub2iF?= =?us-ascii?Q?MtxPf0seYnGkOLbbnG6GkMmJYKq6A/mHkCRArpRJ0VEffhOQvrbomy7EmwFZ?= =?us-ascii?Q?kv0axLil/N5BluR7r79YoDWHmOVO7JeKHB3+qzIaKz/4b2m1aLWfq5Udvzcb?= =?us-ascii?Q?tfLYKwBvbmGkjFb210AM9wdVA0Z4dRVck4EXDOKaw4+W/1v9tkKPq3c700O9?= =?us-ascii?Q?ElVvApn2uFdWVLdDg9+1Pm4lDZGof4TxaIn9YemJiEnwLYRo0R0jQ0HB21cV?= =?us-ascii?Q?RgTPRoTglBB5wCrI+rSn62k3pQV3TlwhY34JuMyp9WzDcHO1m4DDIuZnGfx9?= =?us-ascii?Q?q3ATWskPNqhjLEfKABNqPbl0H83rfItDQIFw6Od3KPu+YAvzVMLzd0SHQDc/?= =?us-ascii?Q?JCpolg4nWEwPQltxp0ygda3bkfEIeiG7WzQr5d1FJWjmUPGdoXwQtbmi0X6b?= =?us-ascii?Q?tv7B+p2u4GxRE31AtXxEsjeoqzq690XJBlINRgBWHmv6O7N0wbhDoRHyd6kd?= =?us-ascii?Q?VC2orlslRtkEnTTnrBGcEy7UfYPBcWNDGiHdCm6MyQGe6P0kCpmLsm9Yav9P?= =?us-ascii?Q?ktQB5LaDBsR+KpdWDbnmeeJa5RFlGnySijnkz6recweEA+siXbN+8vzHzcbA?= =?us-ascii?Q?ktxCTjGcYLRt5SHa1BTDgmyv3gJCojFknhYI0t8D3OZeP/rocJ8pTxzZpBic?= =?us-ascii?Q?KWQ6uGo+VnnV0GE9o/aWvBoAEcjSiHQR7jOVcypC9Zu2BgSmQ3UevUib91Bv?= =?us-ascii?Q?YwcoLgFhcZo1bx03TnnuZ52uCA4sVVIq3C7BaqYTvokuQscAdWM5a8g5ntYS?= =?us-ascii?B?QT09?= X-Microsoft-Exchange-Diagnostics-untrusted: 1;BN3PR03MB1512;6:sKZJjWrWBAjaTkhftN76u38w80RiRh8ZqM8+MOMtwcAOZw2d/3BxTlK5c331DOFOWV696Rg9TsvLWELiRqgOomZ7s0qEM1km0NovZKEBhFrdlklnfxMYt2EekpE5lwl2unL0OAc4MLbUspGsdP7xR/O4jdhYTv762CS0XBX8uh6Tyt+tbVfCFmk09mXnBCaZWyTiPaM/CYii5o57OmMnj9MlWUA4SsBN3WZHeiXWiXwkOtGHPwavy06ouks8rlhQ36NbD8LaJ9NPxzbuOTs4zmMiwD8yXW8SAhc1Y8JR3799M+4d1MLVggUZPnNt8l1HTKEaUcp+6gGCvPov49vCWoEVAtOciAnbcfwgU8AaKjA=;5:4mMDsMlNV1qFU0UDipVLGh2aZN0csYKNX03aLtbdVjN0kd7NQdM+A+ad3XBfPscPmfzU3BdyJmrtzrPa4mERoIY1i2XEmS1AM2KrRDzEWUmJpkulJKS5HjFczNbKpGnhFY42asyyk5WJU/n0F4hrkw==;24:2XC/G9ZznwVMMKaBOYJ6fcXnzsEOOeyKXi0hNdjje1WtUvDk+7pIn9KGhTISx/7Rk62A0WY5vm7hnuBdo6sLNzOQfIEDmhsQvIYyPTXJU68= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics-untrusted: 1;BN3PR03MB1512;7:z7c3YmQ/oI0LmFSz1kNDbA/UD1stYVnjKhpQqoGqfDFHEptQDF4kkCIuLHgAFDIRzbHmRZioKa3a0/fECIKiQywu0SKmFlBxOwaPqFayu88UpQD8TuGOENXiOOyNgM0E/W1PO2XQgI6otiewAzSaWOEtYLQ938XY4sdNWOf8cfRtG9KFN715vb0LZaJzum2jpqSH5gyYFDAbDJHgmn3+WC6H28lNogqRays5vqaYRNxmco5AysqcUQOjlx7zz5T+LIfkFUmm7K/E9ToLT6VXdmdk0ZcLu5xvR6/NunsPqBUPNpFbZg9fP867kyUEU77Tdjoc5Wf54n+C1TQGi5BrywIP/z1g4zr4+I2Mpw6glwA= X-MS-Exchange-Transport-CrossTenantHeadersStamped: BN3PR03MB1512 X-EOPAttributedMessage: 0 X-MS-Office365-Filtering-HT: Tenant X-Forefront-Antispam-Report: CIP:66.35.236.236;IPV:NLI;CTRY:US;EFV:NLI;SFV:NSPM;SFS:(10009020)(6009001)(7916002)(2980300002)(1109001)(1110001)(339900001)(199003)(189002)(4326007)(356003)(7736002)(7846002)(305945005)(19580395003)(19580405001)(7416002)(53416004)(6666003)(956001)(2950100002)(42882006)(81166006)(81156014)(8676002)(8666005)(68736007)(3846002)(3720700001)(87936001)(6070500001)(107886002)(97736004)(8936002)(2906002)(189998001)(86362001)(1076002)(575784001)(85426001)(6116002)(4001430100002)(92566002)(336002)(110136003)(33646002)(47776003)(5003940100001)(586003)(15975445007)(50226002)(77096005)(5660300001)(66066001)(626004)(50986999)(50466002)(229853001)(105606002)(106466001)(76176999)(11100500001)(48376002)(7099028)(7059030)(2004002);DIR:OUT;SFP:1101;SCL:1;SRVR:BL2PR03MB257;H:sj-itexedge04.altera.priv.altera.com;FPR:;SPF:Fail;PTR:InfoDomainNonexistent;A:0;MX:1;LANG:en; X-Microsoft-Exchange-Diagnostics: 1;BN1AFFO11FD027;1:8MzqDZdeeuWzzktSwk+wdnks0eWWDimz5xNZ0DP9OiRe8hhq25sbg6dHDY9KPQuZ2QaIkvguSffhxhXvRcwLW4m2MOcreK5ntciFldYYksbk/CqR+KUjPM0zbhNPDYUMitBSf+O+qMDX9Ag39jRYzzQ308o4VOD65WywrAW1XdFlx7dpc6g/p9rc4LJqtU1oxk5qjuq6L3A06GTyHV7DT2NmUAtcYTAZQ20GOZJEbn4BLlnYUR1YQ1mbZGQjPhrX5ZcfRZhsCj9lG3NtlTuCPfKrTRjMhyU2Se+Yt1ym1McieqYi3T19ypGdBHbb2aMNfY4/aLCD+2FQJeBc3BQA2IqX0QFl1Cb/m4jkRYYizeDSrCAjlWZs3uLyFWFAaUEdEfsCc89NwQWc6SAjIrbxDkGg08TZnxNib5v3v5/NyQDRTEptZrjGeeolP0+nRDmMXychprvx4sY7ncCSUxg6f8fmHgxgbRqk6uRK5X/2udG3d/4kIOK8ToWiuGsplvlbT8h1VNJkjUKWmheVZsPiC00+As0t4xFCLrV8Uo/ZHiAGafSO2Iq6t2mU23vrYP90oqNvYQuTB8yxBvk0Q+7hgGmbj7limSGrZszYZOmvOIPpxiGt/PspDZkvxXPOm8kf X-MS-Exchange-Transport-CrossTenantHeadersStripped: BN1AFFO11FD027.protection.gbl X-Microsoft-Exchange-Diagnostics: 1;BL2PR03MB257;2:Eseh+/IX85zdgUPUnxAqfc7c2z6JSYVswB4V3MzLAe9rRyflZbME2u4E4uY/DcfJYvrh/3EpDs9WssucT4gsQy/H07Q8yw0YWUy0mu7IE22/8MSnfMSl/j2bFn1QzS8mMCTJj4TCMGJT6nuHnYN0p7V+aXPuU3U8OulT+iTIx+yiGLjjrNLzBITIXWce+96Qo6KC0aTxmLHepbMgW0zkUw==;3:a4BHlaxFYlBufuvUOjrNYrCMMdwS5NnqA7Dv5YHr+zCZCJPwwNp1SG77aBaY4i+a3Iadz3nn9DGiVn2l2L5XX/sdA+9+yoogX3Nl3CRsBF9MrVGL94p+7ggPZnbQCsRcfHisrNCl8c2BXK4wT5Ewy6QsPbCJpGfCM5f8G+Mx0ePdV/FKey99FKqz8gVgJTyilQErk2NucKY0iaQDeCtTdtIi/UNinP3wTEQSWrXVPBzaHm+Gqnvoc6Ho4doTfUJlOcF6zIyaLeaVRi5XtHCBZw==;25:s/QxVTzkXbL/FKPH3iR7mkI79LVqUthTCreTs5yhgLYu+wjfT9GjxGxbnXGdy8LBPK/+u18J8YjxZoSWsXPfPyXXqNLeEk4r0Y8NT/wQV6fivzvSbR1S1EiPUGT/pGMoZGeNYLvsKheez6Z7nN8Gy9oEe7xKq7q8vX0ztqRs7mvAkGeljC4TsNgoCSlJ86tmFZkc6TYj++fecbMex+43JMH908gzQWAybGnsAJonaBurnrkTkVG67lCKpdnksUTwSafnb04wvRKJjU2J+DDg3bQ7wFqwSvVOrUFgTVnWEkTo8s1g49N3CWiZCzAq1KZQG0I3EOMO/t/SE+N28rLx6VWljgACcSP3gLL9tf9NhiNTLfQqespiIHLSvC2K6Zc6ZdJA8J4+CBDtUmwezF1xMeZDn2XH3iNLKFIITfehWaAsURNTLrqsSgx9uCh8mwnCalrJXa5aZdmg0TvYeGCLzQ== X-DkimResult-Test: Passed X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(3001016);SRVR:BL2PR03MB257; X-Microsoft-Exchange-Diagnostics: 1;BL2PR03MB257;31:tTPPv6U6kKig2ndNmgYpysI3a0pCPMoRVSMEftsSisWFxTXeAmMYBEBgGXkTr/hTrDmRfYbCgnp+JJ9mifkaUB8UjkjQ5a7mFf60bnXurZjKoqEGw0+/eS25BIGZ55H0GmSfZ13VegPYUCOu7tuAgm5T54WJuXkX2fWD/S1OBqfMD9jOTC0Q0jiM5slcS/ri6czCL8J6RZ8nENZGZlynrid8qqleoJsDMqLS31bStez1m4ttb57Qz3O8xlHJ3JEnvtoJnl4CHsOu7WOB1VRCGnb0k8qn95vQdgxHD/WkBo4=;20:o3QSJqUIxrUg0/fhSY9noM+yA0czcXmTD2b6bOW2lBgpKU6YdmMM2w2ckMCDY9zOrUXy6bdZlGbmS3zvxLZjk17ijnUesevqprR2mul5eICvL7m7OJbs2g7hIhOd8GCjoKgTh99Lxgmv35QyhTDYL6yUcz3D5rkRRqyer42qUgY= X-Microsoft-Exchange-Diagnostics: 1;BL2PR03MB257;4:TCDgy8IeRqD3mNFsQLqwfgYEN+1OlcTNt3RmRZ6Ewj00F3gbw4XCkvfpGAaTwYXR4Y8JUoUbmELoaxxvWA5WOXuQHtKknvkKh7QvIAOwuMmhRi3N6ThAbX74n2zPVCv4cJVCDKDhDaJBQYxwyc7L9s4NkBjTN5prFS1BVB2T7BkUBHIq/3P78sti4BlqAo8myfFHEPCZ1m33T0gAXEsrPjR7vlorw/bwad1CV3AgKWHJcg4XtnoqVD2QfbJ+u2jzAskYydpYTlX7sgKhRiCVCaAQZj+w6is5Cv7wFRS4DADxkpxg+pJLbU5qVR/yCtD6E2Y2r7uWCvtjWKEGSsZPjxwLaytmc2Zi6nk1gy1Wbwaa9k0DkG7jIKpELcMVUxsZTXTtcSYcB/9k784rerR1z6dHvbjh1vxdEjEuakofT0/Gz0TgfYG98F8LETH9WKMfJM3zn2r4ZP3bXNYDbYfi+cHYRsZrZSCca7o18fX2KR5BAS53oNms5rJFLfrz1h0hvbt6cl+gcihU7SUDPoM1vU/NX+Q2WfgcvYFcS5j9KPvfl0BV7ViL5fhVSWAOZWYGS5xbsDELDxvdkMAK3Pnx3agEXC2TA9MS9FfcoIkwt+jgrzV7PyXmAorw9PmDIhiW X-Forefront-PRVS: 0098BA6C6C X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;BL2PR03MB257;23:uAC3H1b4mqTP6mrRUbI/tVdv2IKCFPxuFdbHPhOR+M?= =?us-ascii?Q?d4sxluPFjuNdjgoRy8z1p2ZMvvTZ5G3WnN6IQ0wTYMJjBfQn8j114vvxm8rf?= =?us-ascii?Q?YDvgu1Dhpvukf8j87Ad7khgjkL8LGPfs2UTiXUrBYLbmFfJWsu0cmlWO1VoX?= =?us-ascii?Q?+5cxVNTQKPsUgUy5DiGGUGlIJXfAsrm0NsqrBhbo3QUuXBKpyeKW7EPUgb2G?= =?us-ascii?Q?hwN+J8crRWTxIKrsW3orrrUkSs5gQRFDZiCkXx2hZnco+zinknD9whAVKsis?= =?us-ascii?Q?tb3KXA/nHw1FBtC5ZO6v6LHvXjgW7EiVB/l23ZQDiIEZLQi8lYMfHSfAIpq1?= =?us-ascii?Q?tS+bfoW+w4ytXI3w9iB8IXyObK+5SS4xrHPTa+nCmmqGJj1/stZb7RuaKKao?= =?us-ascii?Q?MyL3DFqnd60gP6Lal7Bgb7xi/tohNC3ROInHRYv85f7FmHZjMmzfZXkuDGlk?= =?us-ascii?Q?sJBFT9K3mB4/5DYpMpMaBqcuhtXHu9zZn7JZ8drM+11C9qSyry8thBp2EvZh?= =?us-ascii?Q?VANQGgi21czVoLcC4arUN/t1OwPtWSk4WXPzC6wm5MBV0pWj8yFf8LGVD1ai?= =?us-ascii?Q?rbfz66Z83xlVf8cyM+AWwkDDDkDhPzgf4Gk9MzDScCQLz7SeLupkZi64W2Sz?= =?us-ascii?Q?gzDUnDxVUWZLbkjHGNAFI5ZyUHYff05Dp9dUAu6C2ivo6meNGGE8jynUpCOb?= =?us-ascii?Q?38doATWIrnUm/ttYf3F88rHx0mLF9xQG6dFvaYUcXcK0t+lq7rdEfeeu0QIz?= =?us-ascii?Q?ulMorEguvjme6jKGjr/uJtadjYvNTsDUFjEngkjmkT8GUTLAcm7x6eqdO0lP?= =?us-ascii?Q?2AvTmrwR8Nv1MWpttdqyzWvphbm+lIkkC8JWgQLdmNM3aY7kqM3DRYgsKWkd?= =?us-ascii?Q?3iUF2x5h36otauK5tVdv67yfcKv8RA5IhPzVHky5x/TCtHuLHoBYcqPRKanl?= =?us-ascii?Q?3YRoV1alwa3pah3ts5SmdSqnyvANzKXYC2f596mFQyww+z3dz2vV8FCizwK5?= =?us-ascii?Q?sxDMnppT4uYlZm1xw9JjkOhez7+J5lBNXRSBadnReC/+8sd7kmm0EE5AT1AQ?= =?us-ascii?Q?QBSL1wJm915JGO4Ujk/rblPqctW44qre9H8CTodiG1f5+jqxiTtlNm+zzeOy?= =?us-ascii?Q?JudI1Z9RvbLjTt8SP04jUXChXBJVvz7wAchOLFlUNdRDVGkBk1LSQGNuJdUN?= =?us-ascii?Q?scKJDow8RRg1GkwhlE/TfU5lsUIgYO0iGADlY2dfG+5lhPeuS5RXRntV0SO8?= =?us-ascii?Q?roWKTcYTz6Jl2HTn5QDif6PNUTrvMgAXpCu38Nnz5/F/0xZKA/VMbTMr6ajN?= =?us-ascii?Q?diECGFJ7v0O4oTLyniN49OKDkzhuSo8LMdX8R1W+CXrR08brGKfY3D5Kgo3c?= =?us-ascii?Q?uw4RS1ROQ+JFm4N3VdFWt3HbsVeukM7tmGaPX53rs7Vf3RcpLp/0sG2FpF5I?= =?us-ascii?Q?arf4624hfZcDMT4yybYgwws5KmQswpm+Q2SSaptGQujwPTpa0W1pQLVyN3fh?= =?us-ascii?Q?fTZFgA9uI02e7OxwMGSm4TkBZO8yoM5q0=3D?= X-Microsoft-Exchange-Diagnostics: 1;BL2PR03MB257;6:+YAF60ZDFJkj2wrePPfr/cu1EiyQP8UAtAZqd+20ZwbJRhfgtN9UxL3rxcgzgQX1fWE9iSqg0YocBuEsIMw1zZND7wGDMsDBaXxq48FoQmujd3qNXDTnZ9OthYkl+XUg/XTkW5TLZkNNm7KZuolwsR4Urrbk79BMIw/UTFOgioi7j9++VZIKjB9i41yokidgj71RghuMb+UMBAx11mOwH3nDSnxyWJrNlI811kzKLXt4+UA+8z7tlEdIcSLGWp90htCCdGDPE1gzdKE+1l+WOdq4UnknilboBjkpegeM+mqu/Bfw2bVC4VOoLywNEts6KVjLEuOEUCOduL3YS0jhpMQ+eDT6pmnIn/Zn4D+zhYs=;5:35ZDPhOjlTMdaIXrguLhakHOmmsnganpMPic7Z6grdLEJPrfv14xr876Ujhl1ERAZlyZ2RrxoKto+CvCtGOtr+qgt93/QGcZ8Ny6eLAlTYm3hLgwD7P8yu+ynu/n1gFhkvmbtOzl8dD13cn4ZGPAxg==;24:+kT/f03f0d3QNwye+Sj2mRHZIj7ZRwYC5bJnxKn0uuXbIzpWRnGYyio2ZfSRpPumpMQXotHaK7Y01EGzq+ctqUJa5as27g8pwCMAa6DVFHc= X-Microsoft-Exchange-Diagnostics: 1;BL2PR03MB257;7:nAbfjn+gIai4DqLE8hRBo5wUjdNnVEr5A5qEdLiHLIPUx3D9NTP+pIHLMlWYqkF3F/ujXgbAW/EwvDYd32D8+5rUyGr/cCo8rpQFfsGNROIGW130GhSldh+OwZXql+hteceoVNXFk5+pVaBw/fRNxYMWO01kUYsU542+iqvhRJA0Po7t65LzLkazZ+zru060WDU+RKS20JUt9fHh+MIFt/GmSF5LJgFS0u1xV33OayuRrPG/YMHWUZULi2Er60TYxNwP+apdoTnP4r0VOjjg5dgduuCgqb3l1vV9uVFtA5/hKXrT4IS7dVcm15s1Q+xC31QUA0N43evVBrwfFgZxsA== X-OriginatorOrg: opensource.altera.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 17 Oct 2016 16:10:11.1236 (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.236];Helo=[sj-itexedge04.altera.priv.altera.com] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BL2PR03MB257 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 18230 Lines: 612 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 v20: use regmap_read_poll_timeout Add some macros/comments remove some debug prints --- 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