From patchwork Fri Mar 23 12:21:59 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: 889962 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="Q75zYbHv"; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=xilinx.onmicrosoft.com header.i=@xilinx.onmicrosoft.com header.b="J3wzAVre"; 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 4072v035YQz9s0b for ; Fri, 23 Mar 2018 23:30:36 +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=9d9lVVMfeT4BcRWfhMpthIL46TEYvsNHOLePOxkfOHo=; b=Q75zYbHv6dL9ND BSheYVC2DFJ01XWFIwRac7LkEvO3XoCTvrHe5o9rxLQU0HJbRnC25fLqKLM6OM7Z6HGgUomWmKDsA lMzZrfKKhqZDd96SaIq20XCPxY/FizB6O61MhIpjqi8RQiAFT8txAphiPevAs533yMGwrHawmE7NM UAtn3jDqaNIpA5CBtfhQOLJFu7vYC44+iuKbfPESrTr6aOMlTJ2B9rJyAoTdZRWidKHt8EFExJDj0 1j5Cg6cnO4a5SJ770fmsqtytxnjPZ4lme8OmVlySsdM7rgaRLCw6ZvCwZAJEqi+vaRIyOCMYUZTj2 xKvJ/YhsvF9WetfOavCg==; 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 1ezLq0-0002u2-2h; Fri, 23 Mar 2018 12:30:28 +0000 Received: from mail-bn3nam01on0044.outbound.protection.outlook.com ([104.47.33.44] helo=NAM01-BN3-obe.outbound.protection.outlook.com) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1ezLjF-0006VL-QR for linux-mtd@lists.infradead.org; Fri, 23 Mar 2018 12:23:50 +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=fnC2YmXC0YaNoWPe3+e+5J+at7difHr66Pta0FGrhFk=; b=J3wzAVreiaKmUdi2M96RMfFRTjOjDq0uLdZ0HtLk7iho/TyhJ2DRjRYaLAcSlECfVT73WCVW6c3r2pbov9FqSKmtKedeeiPKb0kWZzZTnrvQ2MJ25G0R6B6v4y9ZKkyNf+N+M4YabssNMODHlz6/rUIbj6/Hhae2a0q0MgpaO7M= Received: from BLUPR0201CA0034.namprd02.prod.outlook.com (2a01:111:e400:52e7::44) by CY1PR02MB1304.namprd02.prod.outlook.com (2a01:111:e400:50f0::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.588.14; Fri, 23 Mar 2018 12:23:15 +0000 Received: from CY1NAM02FT003.eop-nam02.prod.protection.outlook.com (2a01:111:f400:7e45::209) by BLUPR0201CA0034.outlook.office365.com (2a01:111:e400:52e7::44) 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 CY1NAM02FT003.mail.protection.outlook.com (10.152.74.151) 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 1ezLiy-0003pn-VT; Fri, 23 Mar 2018 05:23:12 -0700 Received: from [127.0.0.1] (helo=localhost) by xsj-pvapsmtp01 with smtp (Exim 4.63) (envelope-from ) id 1ezLit-0007MI-Sb; Fri, 23 Mar 2018 05:23:07 -0700 Received: from xsj-pvapsmtp01 (maildrop.xilinx.com [149.199.38.66]) by xsj-smtp-dlp2.xlnx.xilinx.com (8.13.8/8.13.1) with ESMTP id w2NCN2ag024441; Fri, 23 Mar 2018 05:23:02 -0700 Received: from [172.23.37.108] (helo=xhdnagasure40.xilinx.com) by xsj-pvapsmtp01 with esmtp (Exim 4.63) (envelope-from ) id 1ezLin-0007Js-HB; Fri, 23 Mar 2018 05:23:01 -0700 From: Naga Sureshkumar Relli To: , , , , Subject: [RFC PATCH 2/5] mtd: spi-nor: Add support for Zynq QSPI controller Date: Fri, 23 Mar 2018 17:51:59 +0530 Message-ID: <1521807722-21626-3-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)(39860400002)(346002)(376002)(39380400002)(396003)(2980300002)(438002)(199004)(189003)(36756003)(39060400002)(356003)(107886003)(4326008)(51416003)(7696005)(50226002)(9786002)(36386004)(5660300001)(2906002)(478600001)(305945005)(47776003)(110136005)(8936002)(54906003)(63266004)(186003)(16586007)(446003)(106466001)(59450400001)(336012)(81166006)(48376002)(2201001)(50466002)(81156014)(106002)(8676002)(316002)(426003)(76176011)(26005)(77096007)(11346002)(107986001)(217873001); DIR:OUT; SFP:1101; SCL:1; SRVR:CY1PR02MB1304; H:xsj-pvapsmtpgw01; FPR:; SPF:Pass; PTR:unknown-60-83.xilinx.com; A:1; MX:1; LANG:en; X-Microsoft-Exchange-Diagnostics: 1; CY1NAM02FT003; 1:645GrL06BHJYXXyzBO/9aExUlW7pCtoZd5FVTOU9Z3m8T/e3YTFG2Ix9i+1P4vGCwSZW3OWn2HugoObOn521gYav0H8Kjjb4mP7r4vINyzohkSGYMdH9CufHns1WWnpN MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: b380e20e-880b-4f55-a094-08d590b8d981 X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020095)(4652020)(5600026)(4604075)(4608076)(4534165)(4627221)(201703031133081)(201702281549075)(2017052603328)(7153060); SRVR:CY1PR02MB1304; X-Microsoft-Exchange-Diagnostics: 1; CY1PR02MB1304; 3:8kXuSt+b6NG/VsXjIccYBL4WEFlN9AirWoqIzlKmpNMLosJlyRNAY7U0XeaqPe+cjEyyxO4FuhWO/HaBmUEpkUijigyLoQDfuPB4B1ZTz3dV3bBrGhL2ZRstlqEVlFOay/RGSMRewOceSZ16RZJY6C32wiX/OKh8hPv7Bvq0P1lA8TnNBrS0v+9wSfNvtx31YE8X3D8obJ8I3v7zJtzu20KXT88L//VsQxJVDc+GQfICnwesiY6Kpn4LCrd1ERHnXgpUdxTyeISXjDpRO2I5zu/cOFVzudILCvQP3qh7lZYU5oJQ0p4k7uIkA8RzjPUnHpU9ikMFYz/MSLI2Py7Y+ei6wlZc1VKMIELbEx+So8Q=; 25:pLciX8JDK+E9UMnd9NWv5Gv35NQNYUCO0U4ycWNNH+bXfe9BHEswMeCpnsjSzbJRqlzOXAC1TtJ5fXu/SBO9ZEUuRSBSYydRsUYmaWkFEpr/4MARSzYJGOS3XxFYurcUydwkrB60M/u5otHmVn+V6RuvOQ5smldKfffKE+pkKqnXcZBMFAdScJu5gltSBja0YupBCLXAtWuNo0eosz9uTCQ52OtW6tC2dAmUiAiQFKkn3gwMqxniQ1pV3Crfz0RISyVCZKMnoG6pxbAir3kmmM1jUZoBeU8ut4Xtel7dD94dptU22eBLbw6Fs8MH7cB81ny6EveCmeEv9SKaVn9AhA== X-MS-TrafficTypeDiagnostic: CY1PR02MB1304: X-Microsoft-Exchange-Diagnostics: 1; CY1PR02MB1304; 31:rjy/0LcKlxRw+L6zwrMsUvtm1LH6DcT3UHDrmwVqRrPr2Y2mED3uGT/zne0/gCb6UZ3pE7A++07TQ7MrvEmrxCAawWAWoWiMDGJo4W5d1BH6STUoRzsTcBS4ykMpbge7Xot+N/eTqRXWRcDuQlc2jOCkEwYA4eqUX73/Icl5IJ1Y3XUFmE8k3vmlPMDsH0aAr3644fF8NxTbXySyQC6hqqQ0NmPEgfKrWoOyaMV5nfI=; 20:AiynqFDc/ZfPTZnZ07We93bsKS/HRmlZGXwYjiPGUcd4WK7HUPNM9j5WlyhBzssy8ZMSlRtqIVU7wIYL/cyDPCSy+fWaMShzjjCr3cao73BgJhhYEWeyJqSl1LnNQCr1kOmyAsUOCM2IqVa+z/ZiIYipySwHnMlrB/cLeVbu638kqrLqkcECfQ3E/YV7HDCWYSr0AWKAc7fZjKtdJUDbpKPZVhfAigM9TzyVwWKj0Fz340eNljvsLgYOx9hHuVS9t9IKXUhTwtTu5bfjKBstRN0w49HVMyGbjCEppkwoGu5zH+MO9zs5Dfbjkpk9W6yhBh77xLhQiLmelw+IV/BKl1vuL/6f0G7rxPIKMBRaZ9czwSNE0sOCwJpzverZW42iMxryNv3fBzm+ncfyA7geWFRE1IiwLPEe8mR78c5qEG0dMMMDS9c4zzdpPNYFTCChNR/H6GvVgLlsPJbYV9IbxjGmph65rC+/POgMEtyNJQNjBnUUcH3P/y7U28lcqU3S 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)(8121501046)(5005006)(10201501046)(3002001)(93006095)(93004095)(3231221)(944501327)(52105095)(6055026)(6041310)(20161123562045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123560045)(20161123558120)(20161123564045)(6072148)(201708071742011); SRVR:CY1PR02MB1304; BCL:0; PCL:0; RULEID:; SRVR:CY1PR02MB1304; X-Microsoft-Exchange-Diagnostics: 1; CY1PR02MB1304; 4:8AJybFfmdih8keIJbf53gHmrOnw4peLmfdTruAvcgv0gjJUCSCTpKym3IRynb9qeOMxPxp+fjMhJD0NJlqoIQM360QUujgB5my2nY2hd1UWf7/kuydrGaxzpdtgHPcfAv9JDWKVw+WWZG6jjz3nTrU1HYSM7NJkNMCB0UWirIM14DOtWg8rNgJ91fGC4CUgLuTxhEU8cD+kPZMOZH7+1nSsd+d/2MusuqMMI6NDnyxJ6rZJbIKqOARRc3vqpeEU5vGKiceBUSy565jYWVStdd6GSy1z7ymRyodp9N7DJfD8J7zaoqS4ruZIh+ucWmZo/ X-Forefront-PRVS: 0620CADDF3 X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; CY1PR02MB1304; 23:e12qPgB2SWyP5cnXaQMnrZeRjOlZMOJHwkOgH2NbJ?= c8ohNSsxn1RhBuR9/3UUEtrdu1oqd39HutmDHO+MB+a2pI+98OWVixTRs73nF3Qfcz4fAquoOY/MlcvYAROjf21452rtnfy84+UlJC+0d2yX+xKsHrAUuwfSPdtL/IGFsB5As7C6VoajisXjrx+CquQ7JzcG1W4ZinRPkzsQRAy+1kYbBuCcSxXotK3Kk83YymPx4BdPwpUg1S8rBLxf2shWtFgxa81qzS5hsBa1P5u/wVwtDoQ0J9niJalWI2L+YnL8No4eegLwwj74v4zFkI94yX7nikanbnqPLNU5TSY297lJ5tJziXR1EgCLNGc4hK/4Jjjljg8B05n69vx/WO3qwldmLlwvHAHKzv9WgYoNVg2aiUJpVCcxQWUuojgvPZv+nD/eCc6yyamfk+1jTLIa5MdRNIFGtz2iiZJvqlayuRtqFcBTBDVp7m+5QInqcoKAE+hQo47hyIMBM7QLxpafQM9Zfw5Na0qvB1e6GcuR43jyDFubGzO02M71Yucw4sjuCgGmR2UtWNQV41WhA4J7svTvVXa96RlQMJMbdW/R1DsgXVCe6xOYPtY0Gd6Iwxx515hwSSfX8KEDOy0DI3gsSQ8zhkRypbP/NzNCVaLXUMDPG4IfXlnwb4wi52a3XCoBX1t0qGSApAQbz09s6ZadNGhGygeCKkfYYGYrhwlGBaPLLLtYqDBPX0NCNuX6ycw+wIyvMOlm/ZrQBzBBo5bddmpujoTGVgtHhQC0TB70V58NOgy2xctr3HWvkjXLG4wrTxvdYU413DuvVsauRw35utn1IiLDsBQ+JgL+aS+7glwuat90M4QhS3gvHnOLKp1Iuimos1SIg0CNfjkHEkwHk8Cbdx+4bCe5UD+G6LpjYEpq8j9MMFnPRcZB1zmJIuTlD02RLxY06KNUPC3pz2QV0+zZjbn7fxuDHS2kcd7lNVY/2J+vXuLnA22smun1S5J53sAkIygXGlFn/40wBeMBWL8KriQQu6WGbHKxlthn1XJxdjI/+l+/h4nc5AJOyuTcAbpv66QoNmdFEN5FuXufwbq/0SMJ4K4NsQnV2dmB0R1uNycqp/CmsTR0j8WLvg= X-Microsoft-Antispam-Message-Info: RmdYeMU1Ehz5EKHT7C2SSwianw5gz35irIJv4yNhI2HMfQOhJGXRNYqqphuTsT9O9iWSl2IQDdbpFWGW7urHccFg1at2AyKahRVVGCFdFwAv3yGoI81wgVZyfdI6F3fQjBYVuwz2BDhkHULu7w6ihMMO7fSBwWDlG3HSZMWgcmwnU1wy1NCv3ILE3fMacrRs X-Microsoft-Exchange-Diagnostics: 1; CY1PR02MB1304; 6:L4urwA9sth6vT/DCjpUHlkPdN0lqKyiDU+pby9pi/XFSKpsr3ecqBwH2ZhV9B+G3096buIZNbFff5kXZxDVtn0aCOgIjjXhAqNDOd4o5b6eIoNebUklBr++ezEH+gwvfrf7h4SuWT88VoTiv2crjVCgLluXhzPoMWp/ekw86JlYs/M4DZsPFgX4DuFWymwmJQYZbeEssbirIic51yjjJExCvlf3Ruazn3fcCCbx7dSp/VVPF16FMqM923yjoW7tIX/filsGzUxt9SNtCk2MQW2Vz9d1rwU63XTuz7s36WPL6C862Y9YPUObUiT8bxPop3DUyiHatu5rc2BAyv8h1T28vhbFy99yP1ze18NIvdmY=; 5:skieOQDh26y/V/8ECYt7Ot9jfrkR8a+8Sff0emajuH9W2bLfLjcO/p3kLjpNcTvyNBhw3iHldHnSK8jXlwugY4680sLqZSZla1LC4vdw7Ye5yIsmM4VRkp7xXO1n4cstb74RIOu1kYmpe4MVhnwy1gaZnDldkbekpepHHg2cDyw=; 24:KAwFIn/tawAa63mb4gXYiWAnS6uia8r8rldlHC/DuID7Ehsf5Jof3jmuvxzVBMFq9QYjCyR5XBgpHv5zL72EJ5iv0ds4FGkJDhU9D83ndFc=; 7:l9q/3c9XhIO1bbTtn+kOYJ0QD+tzcw2ndJP+zxMbClsCTIDuFZ7JJ/R7+QIL+iCh1M9L+JrHyzKrBF+h3ErCywtyM71iCPkCEplAm/zEP3XL75eByUbPPRhqSiRctzOtgMsGs9iutFOE0ksIBJ5mDxBfpbZBjN/KXtpQwXSvGTssEtMJwDg32+YsxjJcjDwwla2iVdNPfNOG5JKHau/UdHz/DnvEnesFDwq9gygGTthu3Od+//4JNXx8B+q5/L5k SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: xilinx.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Mar 2018 12:23:13.5482 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: b380e20e-880b-4f55-a094-08d590b8d981 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: CY1PR02MB1304 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180323_052330_993461_AD8A59BB X-CRM114-Status: GOOD ( 14.97 ) 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.44 listed in list.dnswl.org] -0.0 RCVD_IN_MSPIKE_H2 RBL: Average reputation (+2) [104.47.33.44 listed in wl.mailspike.net] -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 necessary changes required to support Zynq QSPI Controller driver. Signed-off-by: Naga Sureshkumar Relli --- drivers/mtd/spi-nor/spi-nor.c | 194 ++++++++++++++++++++++++++++++++++++++---- include/linux/mtd/spi-nor.h | 13 ++- include/linux/spi/spi.h | 5 +- 3 files changed, 192 insertions(+), 20 deletions(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index d445a4d..7698a92 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -23,6 +23,7 @@ #include #include #include +#include /* Define max times to check status register before we give up. */ @@ -292,6 +293,35 @@ static inline int set_4byte(struct spi_nor *nor, const struct flash_info *info, } } +/** + * read_ear - Get the extended/bank address register value + * @nor: Pointer to the flash control structure + * + * This routine reads the Extended/bank address register value + * + * Return: Negative if error occurred. + */ +static int read_ear(struct spi_nor *nor, struct flash_info *info) +{ + int ret; + u8 val; + u8 code; + + /* This is actually Spansion */ + if (JEDEC_MFR(info) == CFI_MFR_AMD) + code = SPINOR_OP_BRRD; + /* This is actually Micron */ + else if (JEDEC_MFR(info) == CFI_MFR_ST) + code = SPINOR_OP_RDEAR; + else + return -EINVAL; + + ret = nor->read_reg(nor, code, &val, 1); + if (ret < 0) + return ret; + + return val; +} static int s3an_sr_ready(struct spi_nor *nor) { int ret; @@ -401,15 +431,60 @@ static int spi_nor_wait_till_ready(struct spi_nor *nor) } /* + * Update Extended Address/bank selection Register. + * Call with flash->lock locked. + */ +static int write_ear(struct spi_nor *nor, u32 addr) +{ + u8 code; + u8 ear; + int ret; + struct mtd_info *mtd = &nor->mtd; + + /* Wait until finished previous write command. */ + if (spi_nor_wait_till_ready(nor)) + return 1; + + if (mtd->size <= (0x1000000) << nor->shift) + return 0; + + addr = addr % (u32) mtd->size; + ear = addr >> 24; + + if (ear == nor->curbank) + return 0; + + if (nor->jedec_id == CFI_MFR_AMD) + code = SPINOR_OP_BRWR; + if (nor->jedec_id == CFI_MFR_ST) { + write_enable(nor); + code = SPINOR_OP_WREAR; + } + nor->cmd_buf[0] = ear; + + ret = nor->write_reg(nor, code, nor->cmd_buf, 1); + if (ret < 0) + return ret; + + nor->curbank = ear; + + return 0; +} +/* * Erase the whole flash memory * * Returns 0 if successful, non-zero otherwise. */ static int erase_chip(struct spi_nor *nor) { + u32 ret; dev_dbg(nor->dev, " %lldKiB\n", (long long)(nor->mtd.size >> 10)); - return nor->write_reg(nor, SPINOR_OP_CHIP_ERASE, NULL, 0); + ret = nor->write_reg(nor, SPINOR_OP_CHIP_ERASE, NULL, 0); + if (ret) + return ret; + + return ret; } static int spi_nor_lock_and_prep(struct spi_nor *nor, enum spi_nor_ops ops) @@ -490,7 +565,7 @@ static int spi_nor_erase_sector(struct spi_nor *nor, u32 addr) static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr) { struct spi_nor *nor = mtd_to_spi_nor(mtd); - u32 addr, len; + u32 addr, len, offset; uint32_t rem; int ret; @@ -540,9 +615,23 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr) /* "sector"-at-a-time erase */ } else { while (len) { + + write_enable(nor); + offset = addr; + + if (nor->addr_width == 3) { + /* Update Extended Address Register */ + ret = write_ear(nor, offset); + if (ret) + goto erase_err; + } + ret = spi_nor_wait_till_ready(nor); + if (ret) + goto erase_err; + write_enable(nor); - ret = spi_nor_erase_sector(nor, addr); + ret = spi_nor_erase_sector(nor, offset); if (ret) goto erase_err; @@ -1265,6 +1354,13 @@ 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 read_len = 0; + u32 rem_bank_len = 0; + u8 bank; + loff_t addr = 0; + +#define OFFSET_16_MB 0x1000000 dev_dbg(nor->dev, "from 0x%08x, len %zd\n", (u32)from, len); @@ -1273,7 +1369,25 @@ static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len, return ret; while (len) { - loff_t addr = from; + if (nor->addr_width == 3) { + bank = (u32)from / (OFFSET_16_MB << nor->shift); + rem_bank_len = ((OFFSET_16_MB << nor->shift) * + (bank + 1)) - from; + } + offset = from; + + /* Die cross over issue is not handled */ + if (nor->addr_width == 3) + write_ear(nor, offset); + if (len < rem_bank_len) + read_len = len; + else + read_len = rem_bank_len; + + /* Wait till previous write/erase is done. */ + ret = spi_nor_wait_till_ready(nor); + if (ret) + goto read_err; if (nor->flags & SNOR_F_S3AN_ADDR_DEFAULT) addr = spi_nor_s3an_addr_convert(nor, addr); @@ -1390,6 +1504,9 @@ 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; + u8 bank = 0; + u32 rem_bank_len = 0; +#define OFFSET_16_MB 0x1000000 dev_dbg(nor->dev, "to 0x%08x, len %zd\n", (u32)to, len); @@ -1401,6 +1518,14 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len, ssize_t written; loff_t addr = to + i; + if (nor->addr_width == 3) { + bank = (u32)to / (OFFSET_16_MB << nor->shift); + rem_bank_len = ((OFFSET_16_MB << nor->shift) * + (bank + 1)) - to; + } + + page_offset = ((to + i)) & (nor->page_size - 1); + /* * If page_size is a power of two, the offset can be quickly * calculated with an AND operation. On the other cases we @@ -1416,9 +1541,14 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len, page_offset = do_div(aux, nor->page_size); } - /* the size of data remaining on the first page */ - page_remain = min_t(size_t, + /* Die cross over issue is not handled */ + if (nor->addr_width == 3) + write_ear(nor, addr); + else { + /* the size of data remaining on the first page */ + page_remain = min_t(size_t, nor->page_size - page_offset, len - i); + } if (nor->flags & SNOR_F_S3AN_ADDR_DEFAULT) addr = spi_nor_s3an_addr_convert(nor, addr); @@ -2760,10 +2890,11 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, const struct spi_nor_hwcaps *hwcaps) { struct spi_nor_flash_parameter params; - const struct flash_info *info = NULL; + struct flash_info *info = NULL; struct device *dev = nor->dev; struct mtd_info *mtd = &nor->mtd; struct device_node *np = spi_nor_get_flash_node(nor); + struct device_node *np_spi; int ret; int i; @@ -2777,10 +2908,10 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, nor->write_proto = SNOR_PROTO_1_1_1; if (name) - info = spi_nor_match_id(name); + info = (struct flash_info *)spi_nor_match_id(name); /* Try to auto-detect if chip name wasn't specified or not found */ if (!info) - info = spi_nor_read_id(nor); + info = (struct flash_info *)spi_nor_read_id(nor); if (IS_ERR_OR_NULL(info)) return -ENOENT; @@ -2804,7 +2935,7 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, */ dev_warn(dev, "found %s, expected %s\n", jinfo->name, info->name); - info = jinfo; + info = (struct flash_info *)jinfo; } } @@ -2863,9 +2994,17 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, if (info->flags & USE_CLSR) nor->flags |= SNOR_F_USE_CLSR; - if (info->flags & SPI_NOR_NO_ERASE) - mtd->flags |= MTD_NO_ERASE; +#ifdef CONFIG_MTD_SPI_NOR_USE_4K_SECTORS + /* prefer "small sector" erase if possible */ + if (info->flags & SECT_4K || + info->flags & SECT_4K_PMC) { + mtd->erasesize = 4096 << nor->shift; + } else +#endif + if (info->flags & SPI_NOR_NO_ERASE) + mtd->flags |= MTD_NO_ERASE; + nor->jedec_id = info->id[0]; mtd->dev.parent = dev; nor->page_size = params.page_size; mtd->writebufsize = nor->page_size; @@ -2901,11 +3040,32 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, } else if (info->addr_width) { nor->addr_width = info->addr_width; } else if (mtd->size > 0x1000000) { - /* enable 4-byte addressing if the device exceeds 16MiB */ - nor->addr_width = 4; - if (JEDEC_MFR(info) == SNOR_MFR_SPANSION || - info->flags & SPI_NOR_4B_OPCODES) - spi_nor_set_4byte_opcodes(nor, info); +#ifdef CONFIG_OF + np_spi = of_get_next_parent(np); + if (of_property_match_string(np_spi, "compatible", + "xlnx,zynq-qspi-1.0") >= 0) { + int status; + + nor->addr_width = 3; + set_4byte(nor, info, 0); + status = read_ear(nor, info); + if (status < 0) + dev_warn(dev, "failed to read ear reg\n"); + else + nor->curbank = status & EAR_SEGMENT_MASK; + } else { +#endif + /* + * enable 4-byte addressing + * if the device exceeds 16MiB + */ + nor->addr_width = 4; + if (JEDEC_MFR(info) == SNOR_MFR_SPANSION || + info->flags & SPI_NOR_4B_OPCODES) + spi_nor_set_4byte_opcodes(nor, info); +#ifdef CONFIG_OF + } +#endif } else { nor->addr_width = 3; } diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index de36969..64232b1 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -62,6 +62,9 @@ #define SPINOR_OP_RDCR 0x35 /* Read configuration register */ #define SPINOR_OP_RDFSR 0x70 /* Read flag status register */ #define SPINOR_OP_CLFSR 0x50 /* Clear flag status register */ +#define SPINOR_OP_WREAR 0xc5 /* Write Extended Address Register */ +#define SPINOR_OP_RDEAR 0xc8 /* Read Extended Address Register */ + /* 4-byte address opcodes - used on Spansion and some Macronix flashes. */ #define SPINOR_OP_READ_4B 0x13 /* Read data bytes (low frequency) */ @@ -106,6 +109,7 @@ /* Used for Spansion flashes only. */ #define SPINOR_OP_BRWR 0x17 /* Bank register write */ +#define SPINOR_OP_BRRD 0x16 /* Bank register read */ #define SPINOR_OP_CLSR 0x30 /* Clear status register 1 */ /* Used for Micron flashes only. */ @@ -139,6 +143,7 @@ /* Configuration Register bits. */ #define CR_QUAD_EN_SPAN BIT(1) /* Spansion Quad I/O */ +#define EAR_SEGMENT_MASK 0x7 /* 128 Mb segment mask */ /* Status Register 2 bits. */ #define SR2_QUAD_EN_BIT7 BIT(7) @@ -281,6 +286,7 @@ struct spi_nor { struct mtd_info mtd; struct mutex lock; struct device *dev; + struct spi_device *spi; const struct flash_info *info; u32 page_size; u8 addr_width; @@ -288,11 +294,16 @@ struct spi_nor { u8 read_opcode; u8 read_dummy; u8 program_opcode; + u32 jedec_id; + u16 curbank; + u16 n_sectors; + u32 sector_size; enum spi_nor_protocol read_proto; enum spi_nor_protocol write_proto; enum spi_nor_protocol reg_proto; bool sst_write_second; - u32 flags; + bool shift; + u8 flags; u8 cmd_buf[SPI_NOR_MAX_CMD_SIZE]; int (*prepare)(struct spi_nor *nor, enum spi_nor_ops ops); diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index bc6bb32..576dea1 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -451,7 +451,8 @@ struct spi_controller { #define SPI_CONTROLLER_MUST_TX BIT(4) /* requires tx */ #define SPI_MASTER_GPIO_SS BIT(5) /* GPIO CS must select slave */ - +#define SPI_MASTER_QUAD_MODE BIT(6) /* support quad mode */ +#define SPI_MASTER_U_PAGE BIT(9) /* select upper flash */ /* flag indicating this is an SPI slave controller */ bool slave; @@ -797,7 +798,7 @@ struct spi_transfer { u8 bits_per_word; u16 delay_usecs; u32 speed_hz; - + u32 dummy; struct list_head transfer_list; };