From patchwork Fri Mar 23 12:22:00 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naga Sureshkumar Relli X-Patchwork-Id: 889950 X-Patchwork-Delegate: cyrille.pitchen@atmel.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=xilinx.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="s4O5wc/u"; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=xilinx.onmicrosoft.com header.i=@xilinx.onmicrosoft.com header.b="pZS5klc+"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4072lC2wj0z9s0b for ; Fri, 23 Mar 2018 23:23:51 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=p+L8omm9kVKnoDpYxrwiTah9obRHF8DCmHmy7hu36Xs=; b=s4O5wc/uln6pDN MDj7CPI57FtJtIm/s0hXcXz2xO/AUbTo+M/zsypP69cGT3Bsbhh3lk8LgyWSx41+cuKrBtIjF00c7 brYyaL6gxwPCc9TQeR17M/IP5Pmm+r/AZfYGpQEZTkVq7koRfAFWtJuER1erwj7E8AXm7aT7TZC07 WmbKWjIL+YZUpR+9NykRPRWKI5B/uFwGRw8HRtZaS4KmumN4SZf8hMi+13SWc06AL5Bd9r4hqza6y WkD1XxGsV6avd8ZQW2HKUxULNpk95HuyeQBe6/L7WWMMD48ix5u+EVJLMECuiOO//v/g8856GbRHX SjLNrWXKODc9AQUoYP/w==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1ezLjV-0006jp-GN; Fri, 23 Mar 2018 12:23:45 +0000 Received: from mail-bn3nam01on0073.outbound.protection.outlook.com ([104.47.33.73] helo=NAM01-BN3-obe.outbound.protection.outlook.com) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1ezLjD-0006VA-Vn for linux-mtd@lists.infradead.org; Fri, 23 Mar 2018 12:23:41 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=xilinx.onmicrosoft.com; s=selector1-xilinx-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=maAm25rCw+KGo8jXvtkwJoVkU9SHD98JVvyDtbsMe/I=; b=pZS5klc+28E3JlhKU1mEqK/F6WLYNZRKNNcXRohBjOFNToYYeMzTArTclYysM9khG7dLIZMWtKZbMA6a8R7UexVi4C//ZMjvshj6msUeFz+bjS9IcZLxil3BNJG/yxr/O4qGOZIOW27revJws6ocGBibZ5AhnJP4pHRYfxkrllw= Received: from MWHPR02CA0018.namprd02.prod.outlook.com (10.168.209.156) by BN6PR02MB2257.namprd02.prod.outlook.com (10.168.253.139) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.609.10; Fri, 23 Mar 2018 12:23:14 +0000 Received: from BL2NAM02FT038.eop-nam02.prod.protection.outlook.com (2a01:111:f400:7e46::201) by MWHPR02CA0018.outlook.office365.com (2603:10b6:300:4b::28) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.609.10 via Frontend Transport; Fri, 23 Mar 2018 12:23:14 +0000 Authentication-Results: spf=pass (sender IP is 149.199.60.83) smtp.mailfrom=xilinx.com; lists.infradead.org; dkim=none (message not signed) header.d=none;lists.infradead.org; dmarc=bestguesspass action=none header.from=xilinx.com; Received-SPF: Pass (protection.outlook.com: domain of xilinx.com designates 149.199.60.83 as permitted sender) receiver=protection.outlook.com; client-ip=149.199.60.83; helo=xsj-pvapsmtpgw01; Received: from xsj-pvapsmtpgw01 (149.199.60.83) by BL2NAM02FT038.mail.protection.outlook.com (10.152.77.25) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.20.631.7 via Frontend Transport; Fri, 23 Mar 2018 12:23:13 +0000 Received: from unknown-38-66.xilinx.com ([149.199.38.66] helo=xsj-pvapsmtp01) by xsj-pvapsmtpgw01 with esmtp (Exim 4.63) (envelope-from ) id 1ezLiz-0003po-0Y; Fri, 23 Mar 2018 05:23:13 -0700 Received: from [127.0.0.1] (helo=localhost) by xsj-pvapsmtp01 with smtp (Exim 4.63) (envelope-from ) id 1ezLit-0007MI-U7; Fri, 23 Mar 2018 05:23:07 -0700 Received: from xsj-pvapsmtp01 (mailhost.xilinx.com [149.199.38.66]) by xsj-smtp-dlp2.xlnx.xilinx.com (8.13.8/8.13.1) with ESMTP id w2NCN5lG024463; Fri, 23 Mar 2018 05:23:05 -0700 Received: from [172.23.37.108] (helo=xhdnagasure40.xilinx.com) by xsj-pvapsmtp01 with esmtp (Exim 4.63) (envelope-from ) id 1ezLiq-0007Js-Oc; Fri, 23 Mar 2018 05:23:05 -0700 From: Naga Sureshkumar Relli To: , , , , Subject: [RFC PATCH 3/5] mtd: spi-nor: Add Dual Parallel and Stacked support for Zynq QSPI Date: Fri, 23 Mar 2018 17:52:00 +0530 Message-ID: <1521807722-21626-4-git-send-email-nagasure@xilinx.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1521807722-21626-1-git-send-email-nagasure@xilinx.com> References: <1521807722-21626-1-git-send-email-nagasure@xilinx.com> X-RCIS-Action: ALLOW X-TM-AS-Product-Ver: IMSS-7.1.0.1224-8.2.0.1013-23620.005 X-TM-AS-User-Approved-Sender: Yes;Yes X-EOPAttributedMessage: 0 X-MS-Office365-Filtering-HT: Tenant X-Forefront-Antispam-Report: CIP:149.199.60.83; IPV:NLI; CTRY:US; EFV:NLI; SFV:NSPM; SFS:(10009020)(39380400002)(396003)(39860400002)(346002)(376002)(2980300002)(438002)(199004)(189003)(54906003)(2201001)(356003)(110136005)(5660300001)(106002)(478600001)(63266004)(47776003)(446003)(11346002)(16586007)(9786002)(8676002)(305945005)(50226002)(81156014)(8936002)(81166006)(316002)(426003)(7696005)(76176011)(51416003)(336012)(50466002)(48376002)(26005)(186003)(77096007)(2906002)(107886003)(106466001)(6666003)(36756003)(39060400002)(36386004)(59450400001)(4326008)(107986001)(217873001); DIR:OUT; SFP:1101; SCL:1; SRVR:BN6PR02MB2257; H:xsj-pvapsmtpgw01; FPR:; SPF:Pass; PTR:unknown-60-83.xilinx.com; A:1; MX:1; LANG:en; X-Microsoft-Exchange-Diagnostics: 1; BL2NAM02FT038; 1:JQyKezdSVkO+rOpWvwhZs0rRHEPDlCJkEXVfaSe2XYFD2c2EjpjmMQSybnB8DQmVa1E89D0VnP3zEbD1Yp+jORTIxReZyRmXgT2ob6iXpQ/CjnsBMgXGmniz+m0J52/k MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: a2d9b116-25bf-4ce6-d77b-08d590b8d971 X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020095)(4652020)(5600026)(4604075)(4608076)(4534165)(4627221)(201703031133081)(201702281549075)(2017052603328)(7153060); SRVR:BN6PR02MB2257; X-Microsoft-Exchange-Diagnostics: 1; BN6PR02MB2257; 3:mHt9mtvUzUiL2uX283+6Meh68mGud7dLgbzCd5H09F4TVQj1qtqToeKlCQNdAAcA5ASU0Rz2JRmtdW8e4b8B1tdJclFiECkRWjmCmyaTXDOj3r7l8L2yojbTV5FP6HuH57bQlfEVe0UqhNp3FIFbP1fWhi4c9YuujKKcGfIFPiI2u588XVthb2Ri9+TU35SXC9tqru54e7/C1kZo4cvnj/ilHZA1pC2ZAOXYBfU801eUzQPpb1rtJxuKlY0uvsPP/4hZQ2Stfd9juWahqyuWifeLvPEj1k0L33KUV4kYQD2FSjhDoeVEy+xzKH11eB+KiLV8X+2jDk4+TAxGG2hqBvuwLLZEzqKgyGPtNRve9uI=; 25:WgWOf/6qmgjzljrXCB1T7qgoQxQRHbDjy5N2nN8QhbwgKe1hEw4Pq8+BWXOQdnNCYfJrt+qdZ5xO703VgCHVgU0NGVRd9laJOLk/cybDU3if6nD/4ZKjbm8ufhgv+nCa5uFWMo3Jg6a0DYGeFtqwvGTS31CH8c6t2tY4yn/T2y+hlkVwOffVWKLUZyy5bi8jUMH4pILgDXdwP3MJPXvIVqg6NWzBMu58GnkdBkKLoScVYeURR4Q1CiZnEqdHqOZajlrz+RodiTxEkBRmzJTS2booIcxzPRMfUoFruau/lziL6haADl+AGZbWxZqaNXtxYa8S1RlIzbH7o8RroNuZ0A== X-MS-TrafficTypeDiagnostic: BN6PR02MB2257: X-Microsoft-Exchange-Diagnostics: 1; BN6PR02MB2257; 31:ODQ3QbJVN105K8N8wb1CG7vruzbVePUXqkP67Ywd3J6YX1wkFWuO2AV6uxWwgcaMF1wMi2edI9pcVj1rfy3KGaVX+RrhOGJx32J9IsnfUwTFnnjq/iv1h3y7LtKQOOgrwqF57oo+8gd6hB6F2NReFrtNo5Qdz0oR1Yo8JoxY4njGzZO25RSwzR++mZxVOPj+mxjT1u9eVv7JtCN07aX7cofrTorQhQeiiEMdHLl6sXI=; 20:p7cpYhFdhCK8jJ6rBZiNstvk8De5vB2nHV47GppzyJQZ0NNjel+V93GHvJgMsfuNrXLjQhAUdvWrLiLlt9dTQMIyfKWmzvRvirlKC1/I04ABhk0zxfoDyDuQOYrfDo4u07RsNXhCMwA319uG9xq7xiay9bfISmzbvgVVxp4WradztoEdR4oMTlLbNAvKgtWu36wUnRm7dwBOJpNHWKAqc8+TgTEdV0WQNJmjkLfvf/+UqL7J34H3NSSxVx80BU2nkJYi0oXAClj6NVmRiW19lNG1yk7o0QEbbf6hWKUcdJGOBg/1/FUg8lrHfNMovjgPKhD07O2QrsFX2ECFFZk4eNHSqSdN7cJUlJYcKdUPoSqVXCkY+DxKPhmHAy2+e9uUNSWHOuWfHqHW2oQ3pPmHch3ZtlbnjJwapnxpsgIxoc2dqQBHnQR1RzTiXRoQbKkwsZmY9cv94KHTmDQZjS09KAZpCnylYssgDeXRJW9YwVl3eHxSJ4Wgo5eStmMP4zAh X-Auto-Response-Suppress: DR, RN, NRN, OOF, AutoReply X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(192813158149592); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(8211001083)(6040522)(2401047)(5005006)(8121501046)(3231221)(944501327)(52105095)(93006095)(93004095)(10201501046)(3002001)(6055026)(6041310)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123558120)(20161123564045)(20161123560045)(20161123562045)(6072148)(201708071742011); SRVR:BN6PR02MB2257; BCL:0; PCL:0; RULEID:; SRVR:BN6PR02MB2257; X-Microsoft-Exchange-Diagnostics: 1; BN6PR02MB2257; 4:Gd0XH4EjtWMuz/L4iWSeRO4NMLuzOnk1VDFkP8tt7VmPjvvXhak6c3HvjsgeIDv36yWkDd1pvRGpvqO3QYgdhJepLHF29mNci7ekBUEMY3nwh7t1rmSHOslAdFtEI4sLr/S3PSD9DYZmkxNwzQShvXb1YnJqvm7cp3Vcwe5Vx6bpgGWwA54EhDC8IA9kfZtqiA7FzzkeSZDyzTksec3TdYIDojDT7fK+24w+NXlTjzvgG8ErjDKocZMIwL8pYlnRfSBcBJdhXBpgerTo8atVzASlCfzeOSaf0r1Jp2MGyEQXSWNe7n3s/e7tLHLF/eS4 X-Forefront-PRVS: 0620CADDF3 X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; BN6PR02MB2257; 23:8SVeaDpRXnoKWDvySTkvLk9qIEqheX0IDUHkMPqFq?= NBG+aFOUVrLjyZftMJPTm3EbhkpT62O/KUFnbyg2B9Mh7Q/I2Nbvuxpz8VKZKPCXJkhvJkD7AaE8ZqW4p3H5BtZr4CPOGST+xl6GvVFoGFUCpe8k87W4R+Bbi7vfyEzK6HGFmaaT1rPp586vIoUqKZLP+CViq4/uudwHHe7McXYxCPF/k6k9Y5g+MOGunricaPle+3KlhXP9eO9TAusxkUOUAWGxldJ4TnkWn2udljLlQ7/h8X2OOlPU4esJQWfZDfquLadB5IlGYctEyYlpjKqGUt1836SVLDsANd7yOwz+II/aGUd20D44Wkwz2mHGH7nJXLWitdHCuSOnlXTWswHGpXaQFu89tPH+TjcY0vhofZv+WnZY/IJ221Fczfkl4F3ifRF81cqD+STvQqtZuLIZ4SrEMsjjE2/KxWI17GBOLEJOz7OT0vz7Dq4rZ1Q2bSWUVRx3N4i/Sv0RbZOpvIlZOw3kMqZomepRVnAz5XXe6482lyV8xW3+JijIItn3NCuzbJyvxCBko4fZzKOqABUgjItJBm9b4OaWQt5a7xhwfJq3aL44re4bFJVzqiTRaBsN86RYm9qRQ2s3wxsjTay4RUWWQZTUL+GQX/TIZvgy4JuDGhfB0bGq34PqUPK6Jzctw0kkCl61zFlRIVshBecCdjRQYGfkPASI2LvWk/Jm1KrkNDFT6dE1kGIWpalIJUP7Iu8ytV/xkU00ygA+X/C+HCiwkE4gqpkEbTvwe8ElQgyAnYNZhXLgqVRtOmWV6QHsOO7qkM1CCtsPQu4bMqfc9f8YRRin7oh7qvYzkRS4pEuXnuYouHo3v0LvmGmivtKP4hfNC5rAikzGE4+efqvJUc50YJQEzUmWUs2O0H7xFJb5zAjwN2UGFGt8eRxstSHAIB4lqWTN2nOjbKjH1TBNY6MAaztQsZ7j/1U85q4O9qoru6W8F/Jn/fLc50Fusu+R25L/r2LodvOy4cIDFgUwn866ktcl69dxeTPldMDtXwldNfFEu7IoRoPO1xlsyqQMM0yfYnmpbn7m0+1RdzUf+S5yxxoC3p8t4bzGx+MsjfD/Ilg63RYcciKv9K93F+6rO4MBCfh99tNX2y5OWqr X-Microsoft-Antispam-Message-Info: bX6coOKyFVeApJZWFMbXHKwMPlW0l0fPHYaxb9TC5l50GFPyhcWDSQl1E6LKDTbAdYv/prx0ReuwUl3JZD4v/ozDzF+JU7zqY/4dwZDy2Oz25eS9m06LnOsrZ2R99ViFJK1XIPgYrQJAa5XzzSHRiusRc8JTbS0RXPRMfutdvjq2Bvs+0YU2x5xGifq9uZXP X-Microsoft-Exchange-Diagnostics: 1; BN6PR02MB2257; 6:TWA/VEUWKMB2ubdugyTqZoYbk8ujCd9Ouwt5Ak1AOpZYoT1C79KybSUWZsK05oyDN98pekyLSNCvO0Hv7qrGZJbq4H2O9W8zfSk0oVPsvneCvvbSt302DAdDQw2BHoegWspQ3QOb7aGcpk6oLDtFh7od4nILylw59d3B9dVjYwF3tm3J81bsqCXMc9RnKhca4HiAFSm6iGQ2iL5w1S1ihCpcOevXzsfwq9+87Dgu6bSKvfmm2BzAYDOC7BajMs0gKWrmclHjM8cbmkhBYvZNUe5R4kiQmX9kpIR0tDECjoNTn3xXQ0qt4kqsDg63j9YofnK3sCpcb11SO/JRWg/GI2pIhX4ehw5bHgoi1TSlOvRwTF1UYodVQl31mlrQyhrb+RKOpHwsghule0qFuxtTRHzpSqeRZ7cqvx7x2wEQMcKsljuG23UjLpK5a+hGsGQi9OFDhwmTy5Kj0qYjgSjT0w==; 5:yU9VmYLcIU9sQNp31pi/jbuODHXz2vc8Nz13ikl9vGY/RMbMHvL5Fe+O3ifyf/I8XA1WRSOY5O/ivtVFtC22p2CLbpC3TEBdnudPPRhCU3IAJ0MSN2Nnsm2dyYziDK8OwdN61TPtkxLWcwhKmk9lOHPmEz+6U7eYhI4LRkCx+20=; 24:WgxdsrKTGpRuSam9+aSF2sKOB3XFPzo3L4PImZ5TUn+184Uq15GHWOJvQMoYORUUHoa4YWQnOAsnioPYkJW/XuwM0hyQx1anzb8XT8xZFUM= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; BN6PR02MB2257; 7:Jzf5x4NBADQMMTjylvEIWYet1/O5TFCMGKhpWBxvP5/GrlmAlLV4HIj9ZF926E8HH/uc20MGVB1IojjfblhD3Ee7+9LVSLfOEUy4ZJtcbHEGiDVynULx22KDFCfjU3IUuSf08siDxhqbfhXb9lS/RVXQRsVQ1bhAoNrPpwGD3qDoF1rVMtaitYYwaEHsDIBfTsDn7I2Hk2i8UZehSI3mwYXR2KnAleHx0XYtNkCQEezwsKg6jG9WCcB5ixkLjtee X-OriginatorOrg: xilinx.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Mar 2018 12:23:13.6029 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: a2d9b116-25bf-4ce6-d77b-08d590b8d971 X-MS-Exchange-CrossTenant-Id: 657af505-d5df-48d0-8300-c31994686c5c X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=657af505-d5df-48d0-8300-c31994686c5c; Ip=[149.199.60.83]; Helo=[xsj-pvapsmtpgw01] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BN6PR02MB2257 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180323_052328_780953_550977FE X-CRM114-Status: GOOD ( 13.46 ) X-Spam-Score: -0.0 (/) X-Spam-Report: SpamAssassin version 3.4.1 on bombadil.infradead.org summary: Content analysis details: (-0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at http://www.dnswl.org/, no trust [104.47.33.73 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record -0.0 SPF_HELO_PASS SPF: HELO matches SPF record 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Naga Sureshkumar Relli , linux-mtd@lists.infradead.org Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org This patch adds Xilinx Zynq QSPI dual parallel and stacked support. Signed-off-by: Naga Sureshkumar Relli --- drivers/mtd/spi-nor/spi-nor.c | 241 ++++++++++++++++++++++++++++++++++++++---- include/linux/mtd/spi-nor.h | 2 + 2 files changed, 220 insertions(+), 23 deletions(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index 7698a92..03aa8c9 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -106,15 +106,24 @@ static const struct flash_info *spi_nor_match_id(const char *name); static int read_sr(struct spi_nor *nor) { int ret; - u8 val; + u8 val[2]; - ret = nor->read_reg(nor, SPINOR_OP_RDSR, &val, 1); - if (ret < 0) { - pr_err("error %d reading SR\n", (int) ret); - return ret; + if (nor->isparallel) { + ret = nor->read_reg(nor, SPINOR_OP_RDSR, &val[0], 2); + if (ret < 0) { + pr_err("error %d reading SR\n", (int) ret); + return ret; + } + val[0] |= val[1]; + } else { + ret = nor->read_reg(nor, SPINOR_OP_RDSR, &val[0], 1); + if (ret < 0) { + pr_err("error %d reading SR\n", (int) ret); + return ret; + } } - return val; + return val[0]; } /* @@ -125,15 +134,24 @@ static int read_sr(struct spi_nor *nor) static int read_fsr(struct spi_nor *nor) { int ret; - u8 val; + u8 val[2]; - ret = nor->read_reg(nor, SPINOR_OP_RDFSR, &val, 1); - if (ret < 0) { - pr_err("error %d reading FSR\n", ret); - return ret; + if (nor->isparallel) { + ret = nor->read_reg(nor, SPINOR_OP_RDFSR, &val[0], 2); + if (ret < 0) { + pr_err("error %d reading FSR\n", ret); + return ret; + } + val[0] &= val[1]; + } else { + ret = nor->read_reg(nor, SPINOR_OP_RDFSR, &val[0], 1); + if (ret < 0) { + pr_err("error %d reading FSR\n", ret); + return ret; + } } - return val; + return val[0]; } /* @@ -451,7 +469,10 @@ static int write_ear(struct spi_nor *nor, u32 addr) addr = addr % (u32) mtd->size; ear = addr >> 24; - if (ear == nor->curbank) + if ((!nor->isstacked) && (ear == nor->curbank)) + return 0; + + if (nor->isstacked && (mtd->size <= 0x2000000)) return 0; if (nor->jedec_id == CFI_MFR_AMD) @@ -480,9 +501,21 @@ static int erase_chip(struct spi_nor *nor) u32 ret; dev_dbg(nor->dev, " %lldKiB\n", (long long)(nor->mtd.size >> 10)); + if (nor->isstacked) + nor->spi->master->flags &= ~SPI_MASTER_U_PAGE; ret = nor->write_reg(nor, SPINOR_OP_CHIP_ERASE, NULL, 0); if (ret) return ret; + if (nor->isstacked) { + /* Wait until previous write command finished */ + ret = spi_nor_wait_till_ready(nor); + if (ret) + return ret; + + nor->spi->master->flags |= SPI_MASTER_U_PAGE; + + ret = nor->write_reg(nor, SPINOR_OP_CHIP_ERASE, NULL, 0); + } return ret; } @@ -619,6 +652,20 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr) write_enable(nor); offset = addr; + if (nor->isparallel == 1) + offset /= 2; + + if (nor->isstacked == 1) { + if (offset >= (mtd->size / 2)) { + offset = offset - (mtd->size / 2); + nor->spi->master->flags |= + SPI_MASTER_U_PAGE; + } else { + nor->spi->master->flags &= + ~SPI_MASTER_U_PAGE; + } + } + if (nor->addr_width == 3) { /* Update Extended Address Register */ ret = write_ear(nor, offset); @@ -949,6 +996,16 @@ static int spi_nor_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) ret = spi_nor_lock_and_prep(nor, SPI_NOR_OPS_LOCK); if (ret) return ret; + if (nor->isparallel == 1) + ofs = ofs >> nor->shift; + + if (nor->isstacked == 1) { + if (ofs >= (mtd->size / 2)) { + ofs = ofs - (mtd->size / 2); + nor->spi->master->flags |= SPI_MASTER_U_PAGE; + } else + nor->spi->master->flags &= ~SPI_MASTER_U_PAGE; + } ret = nor->flash_lock(nor, ofs, len); @@ -964,6 +1021,16 @@ static int spi_nor_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) ret = spi_nor_lock_and_prep(nor, SPI_NOR_OPS_UNLOCK); if (ret) return ret; + if (nor->isparallel == 1) + ofs = ofs >> nor->shift; + + if (nor->isstacked == 1) { + if (ofs >= (mtd->size / 2)) { + ofs = ofs - (mtd->size / 2); + nor->spi->master->flags |= SPI_MASTER_U_PAGE; + } else + nor->spi->master->flags &= ~SPI_MASTER_U_PAGE; + } ret = nor->flash_unlock(nor, ofs, len); @@ -1355,6 +1422,7 @@ static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len, struct spi_nor *nor = mtd_to_spi_nor(mtd); int ret; u32 offset = from; + u32 stack_shift = 0; u32 read_len = 0; u32 rem_bank_len = 0; u8 bank; @@ -1375,8 +1443,25 @@ static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len, (bank + 1)) - from; } offset = from; + if (nor->isparallel == 1) + offset /= 2; + + if (nor->isstacked == 1) { + stack_shift = 1; + if (offset >= (mtd->size / 2)) { + offset = offset - (mtd->size / 2); + nor->spi->master->flags |= SPI_MASTER_U_PAGE; + } else { + nor->spi->master->flags &= ~SPI_MASTER_U_PAGE; + } + } /* Die cross over issue is not handled */ + if (nor->addr_width == 4) { + rem_bank_len = (mtd->size >> stack_shift) - + (offset << nor->shift); + } + if (nor->addr_width == 3) write_ear(nor, offset); if (len < rem_bank_len) @@ -1390,9 +1475,9 @@ static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len, goto read_err; if (nor->flags & SNOR_F_S3AN_ADDR_DEFAULT) - addr = spi_nor_s3an_addr_convert(nor, addr); + addr = spi_nor_s3an_addr_convert(nor, offset); - ret = nor->read(nor, addr, len, buf); + ret = nor->read(nor, offset, len, buf); if (ret == 0) { /* We shouldn't see 0-length reads */ ret = -EIO; @@ -1504,6 +1589,7 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len, struct spi_nor *nor = mtd_to_spi_nor(mtd); size_t page_offset, page_remain, i; ssize_t ret; + u32 offset, stack_shift = 0; u8 bank = 0; u32 rem_bank_len = 0; #define OFFSET_16_MB 0x1000000 @@ -1517,7 +1603,7 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len, for (i = 0; i < len; ) { ssize_t written; loff_t addr = to + i; - + offset = (to + i); if (nor->addr_width == 3) { bank = (u32)to / (OFFSET_16_MB << nor->shift); rem_bank_len = ((OFFSET_16_MB << nor->shift) * @@ -1535,26 +1621,53 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len, * modulus (do_div()) or not. */ if (hweight32(nor->page_size) == 1) { - page_offset = addr & (nor->page_size - 1); + page_offset = offset & (nor->page_size - 1); } else { - uint64_t aux = addr; + uint64_t aux = offset; page_offset = do_div(aux, nor->page_size); } + if (nor->isparallel == 1) + offset /= 2; + + if (nor->isstacked == 1) { + stack_shift = 1; + if (offset >= (mtd->size / 2)) { + offset = offset - (mtd->size / 2); + nor->spi->master->flags |= SPI_MASTER_U_PAGE; + } else { + nor->spi->master->flags &= ~SPI_MASTER_U_PAGE; + } + } /* Die cross over issue is not handled */ + if (nor->addr_width == 4) + rem_bank_len = (mtd->size >> stack_shift) - offset; if (nor->addr_width == 3) - write_ear(nor, addr); - else { - /* the size of data remaining on the first page */ + write_ear(nor, offset); + if (nor->isstacked == 1) { + if (len <= rem_bank_len) { + page_remain = min_t(size_t, + nor->page_size - page_offset, len - i); + } else { + /* + * the size of data remaining + * on the first page + */ + page_remain = rem_bank_len; + } + } else { page_remain = min_t(size_t, - nor->page_size - page_offset, len - i); + nor->page_size - page_offset, len - i); } + ret = spi_nor_wait_till_ready(nor); + if (ret) + goto write_err; if (nor->flags & SNOR_F_S3AN_ADDR_DEFAULT) addr = spi_nor_s3an_addr_convert(nor, addr); write_enable(nor); - ret = nor->write(nor, addr, page_remain, buf + i); + ret = nor->write(nor, offset, page_remain, buf + i); if (ret < 0) goto write_err; written = ret; @@ -2897,6 +3010,7 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, struct device_node *np_spi; int ret; int i; + u32 is_dual; ret = spi_nor_check(nor); if (ret) @@ -2965,6 +3079,69 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, mtd->_read = spi_nor_read; mtd->_resume = spi_nor_resume; +#ifdef CONFIG_OF + np_spi = of_get_next_parent(np); + if ((of_property_match_string(np_spi, "compatible", + "xlnx,zynq-qspi-1.0") >= 0) || + (of_property_match_string(np_spi, "compatible", + "xlnx,zynqmp-qspi-1.0") >= 0)) { + if (of_property_read_u32(np_spi, "is-dual", + &is_dual) < 0) { + /* Default to single if prop not defined */ + nor->shift = 0; + nor->isstacked = 0; + nor->isparallel = 0; + } else { + if (is_dual == 1) { + /* dual parallel */ + nor->shift = 1; + info->sector_size <<= nor->shift; + info->page_size <<= nor->shift; + mtd->size <<= nor->shift; + nor->isparallel = 1; + nor->isstacked = 0; + } else { +#ifdef CONFIG_SPI_ZYNQ_QSPI_DUAL_STACKED + /* dual stacked */ + nor->shift = 0; + mtd->size <<= 1; + info->n_sectors <<= 1; + nor->isstacked = 1; + nor->isparallel = 0; +#else + u32 is_stacked; + + if (of_property_read_u32(np_spi, + "is-stacked", + &is_stacked) < 0) { + is_stacked = 0; + } + if (is_stacked) { + /* dual stacked */ + nor->shift = 0; + mtd->size <<= 1; + info->n_sectors <<= 1; + nor->isstacked = 1; + nor->isparallel = 0; + } else { + /* single */ + nor->shift = 0; + nor->isstacked = 0; + nor->isparallel = 0; + } +#endif + } + } + } + +#else + /* Default to single */ + nor->shift = 0; + nor->isstacked = 0; + nor->isparallel = 0; +#endif + + /* NOR protection support for STmicro/Micron chips and similar */ if (JEDEC_MFR(info) == SNOR_MFR_MICRON || info->flags & SPI_NOR_HAS_LOCK) { @@ -3063,6 +3240,24 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, if (JEDEC_MFR(info) == SNOR_MFR_SPANSION || info->flags & SPI_NOR_4B_OPCODES) spi_nor_set_4byte_opcodes(nor, info); + else { + np_spi = of_get_next_parent(np); + if (of_property_match_string(np_spi, + "compatible", + "xlnx,xps-spi-2.00.a") >= 0) { + nor->addr_width = 3; + set_4byte(nor, info, 0); + } else { + set_4byte(nor, info, 1); + if (nor->isstacked) { + nor->spi->master->flags |= + SPI_MASTER_U_PAGE; + set_4byte(nor, info, 1); + nor->spi->master->flags &= + ~SPI_MASTER_U_PAGE; + } + } + } #ifdef CONFIG_OF } #endif diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index 64232b1..bdf6433 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -303,6 +303,8 @@ struct spi_nor { enum spi_nor_protocol reg_proto; bool sst_write_second; bool shift; + bool isparallel; + bool isstacked; u8 flags; u8 cmd_buf[SPI_NOR_MAX_CMD_SIZE];