From patchwork Mon May 28 12:35:35 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vipul Kumar X-Patchwork-Id: 921529 X-Patchwork-Delegate: jagannadh.teki@gmail.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.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=xilinx.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=xilinx.onmicrosoft.com header.i=@xilinx.onmicrosoft.com header.b="lroN2Ovq"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 40vcBR4mlCz9s0q for ; Mon, 28 May 2018 22:49:35 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 55C12C21E2C; Mon, 28 May 2018 12:36:54 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=-0.0 required=5.0 tests=BAD_ENC_HEADER, RCVD_IN_DNSWL_BLOCKED, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_PASS, T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id EEC28C21E07; Mon, 28 May 2018 12:33:10 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id E402FC21DFA; Mon, 28 May 2018 12:31:30 +0000 (UTC) Received: from NAM01-BY2-obe.outbound.protection.outlook.com (mail-by2nam01on0086.outbound.protection.outlook.com [104.47.34.86]) by lists.denx.de (Postfix) with ESMTPS id 3BA37C21DFF for ; Mon, 28 May 2018 12:31:23 +0000 (UTC) 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:X-MS-Exchange-SenderADCheck; bh=KifJashJIRSDQfHfnJeaW9pItQ0TXMNudsfoBOBHYr4=; b=lroN2Ovqprmc5RbhyYngZbm+HdhKgLlx6fY3lY7gX4468G3s1TFQWJeADtO2T1DZ5w+MzCXaAcVV9wOi3oZmgdNHLAQxXQypuhR8jCkrj/5vebkMc/F2u0QQj/yeOi8g4az/L9aUlGyr4JXsjBIa8/lSmD+KK+uOdzb10Oanx9E= Received: from BYAPR02CA0015.namprd02.prod.outlook.com (2603:10b6:a02:ee::28) by BLUPR02MB1217.namprd02.prod.outlook.com (2a01:111:e400:52bf::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.797.11; Mon, 28 May 2018 12:31:20 +0000 Received: from BL2NAM02FT062.eop-nam02.prod.protection.outlook.com (2a01:111:f400:7e46::200) by BYAPR02CA0015.outlook.office365.com (2603:10b6:a02:ee::28) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.797.11 via Frontend Transport; Mon, 28 May 2018 12:31:19 +0000 Authentication-Results: spf=pass (sender IP is 149.199.60.100) smtp.mailfrom=xilinx.com; lists.denx.de; dkim=none (message not signed) header.d=none;lists.denx.de; dmarc=bestguesspass action=none header.from=xilinx.com; Received-SPF: Pass (protection.outlook.com: domain of xilinx.com designates 149.199.60.100 as permitted sender) receiver=protection.outlook.com; client-ip=149.199.60.100; helo=xsj-pvapsmtpgw02; Received: from xsj-pvapsmtpgw02 (149.199.60.100) by BL2NAM02FT062.mail.protection.outlook.com (10.152.77.57) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.20.820.8 via Frontend Transport; Mon, 28 May 2018 12:31:19 +0000 Received: from unknown-38-66.xilinx.com ([149.199.38.66]:47427 helo=xsj-pvapsmtp01) by xsj-pvapsmtpgw02 with esmtp (Exim 4.63) (envelope-from ) id 1fNHJ0-0001Cr-Lt for u-boot@lists.denx.de; Mon, 28 May 2018 05:31:18 -0700 Received: from [127.0.0.1] (helo=localhost) by xsj-pvapsmtp01 with smtp (Exim 4.63) (envelope-from ) id 1fNHIv-0006LK-IP for u-boot@lists.denx.de; Mon, 28 May 2018 05:31:13 -0700 Received: from xsj-pvapsmtp01 (maildrop.xilinx.com [149.199.38.66]) by xsj-smtp-dlp1.xlnx.xilinx.com (8.13.8/8.13.1) with ESMTP id w4SCV90g005784; Mon, 28 May 2018 05:31:10 -0700 Received: from [172.23.18.183] (helo=xhdvipulk40.xilinx.com) by xsj-pvapsmtp01 with esmtp (Exim 4.63) (envelope-from ) id 1fNHIr-0006Jo-Bu; Mon, 28 May 2018 05:31:09 -0700 From: Vipul Kumar To: Date: Mon, 28 May 2018 18:05:35 +0530 Message-ID: <1527510935-7328-1-git-send-email-vipul.kumar@xilinx.com> X-Mailer: git-send-email 2.7.4 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.100; IPV:NLI; CTRY:US; EFV:NLI; SFV:NSPM; SFS:(10009020)(396003)(346002)(376002)(39380400002)(39860400002)(2980300002)(438002)(199004)(189003)(8746002)(77096007)(9786002)(2616005)(126002)(107886003)(476003)(2351001)(486006)(44832011)(26005)(305945005)(8936002)(356003)(186003)(47776003)(59450400001)(81156014)(51416003)(8676002)(81166006)(478600001)(50226002)(7696005)(36756003)(106002)(63266004)(5890100001)(50466002)(54906003)(5660300001)(48376002)(106466001)(6916009)(6666003)(336012)(575784001)(36386004)(426003)(4326008)(316002)(2906002)(107986001)(5001870100001); DIR:OUT; SFP:1101; SCL:1; SRVR:BLUPR02MB1217; H:xsj-pvapsmtpgw02; FPR:; SPF:Pass; LANG:en; PTR:xapps1.xilinx.com,unknown-60-100.xilinx.com; A:1; MX:1; X-Microsoft-Exchange-Diagnostics: 1; BL2NAM02FT062; 1:dSkNN0hpo96L2nLF6kYyGGT2BU2PtRgyeqjMFx431FCC9377dot0gA0adO9OLsohOzcNpt8RGeyspiLY6KScvN93gnOxj0Uh2amCvaeQBGma6ADYxK8e0IbLQ8H2Cn+A MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020095)(4652020)(5600026)(4608076)(4534165)(4627221)(201703031133081)(201702281549075)(2017052603328)(7153060); SRVR:BLUPR02MB1217; X-Microsoft-Exchange-Diagnostics: 1; BLUPR02MB1217; 3:O99Abvrq2vDGSrE2IxHaP/i6r2I2JSg9mlctKt2wlxSjCcPLQg0nUTd3LuGG/TN+RAmPKhbSFMKptSsOhkfHZhnaQou1DaXe4snM/wNJW68OmA6TTaRa7nECfa1IaYeWpq++LwYjrL+FE72Uc62faBUs39ccObwTbTTm5g1nMUY9qViohnQKN1SLzdT9AjpHIFQWlTjISeqCZuWdynpdorTnO9OT6uMLpqkgF8C2B8TMouV0fRvvMh4LpQvIDTLaqyeSqcb0rmKS8+9ssQ79zjC6YUVKwripZKUk4Z5/dc7Y9d/93gxl/NOA3Z+0mFL9qJDTCoyXUMVqXYblwZ3f92w87eXgmlgvxPltDbnowVc=; 25:Je/qHDYA1zS64+urKkUWT4ogKsi9udSo5WWi0zWCR7/7c7o5NRm7ITJ/dMtTv3PiSou+c3Xv9u3AmQYVOCI41NkLOTHkRfDctcVe31/smTjzB+6i++/5060T/zHEZxfEu584bNiqQMvzuNpG1jwtxZNbyO2oOZrtsi2TOorwxfy/NWO4cHQ4usmec/QbBzSXLMq5Nv+QxYc8t5mpuKab2HRk0m5L3BJsTZloZDYT5e2IKSLRZLW001Q0ZKC84TCwZE1ihp1bYKcK7dQSvCZQuwSRc7f/HGZSgeeuunqkuMZoSjWjiyIpfL80Nuttpm5YJDWJl73UuGTbcNVkTNBHkw== X-MS-TrafficTypeDiagnostic: BLUPR02MB1217: X-Microsoft-Exchange-Diagnostics: 1; BLUPR02MB1217; 31:PyyTUfpO5t1hWnD0VbNRQ25PWddqpdzCN3jJKOiZOK4hibPXrdfslQOADbcw/NTU6wCRscJcuV3Jyz4EW8+xxhgcurMj5Z1GO2jTdgtiL3Ubb5/QZLNb4ZlbSXbSizNqC2FvQ/1If1neBqie80j9UaV4OPDgd0/r7ZUrf3uEvtjoksoB/B0Xs9yIB8UK5glPPKK+4LiJaWI+nzIuNVxCUxPQRVhqbyIRKZkwRZPVR+A=; 20:ABS8kIpysdnukEGjeI2tuh67BcesJvwoI2Nc3Gv8bWorBNaWJNpd68qitfiSIK3CMAKqJpnQfE9WdC6XD4NU+aiKcruXCbR+d+qRjqujUZ5Y5uCTDTQnZyVVjGTQ6fSQo4PtLpABxbLI2zHfW/LofbCaulXE35Jv3chxnw7eD/aXkAgsp8c9HTzWiQN18To+a4Ha9Dwx0YWYXDQPavat86FQHjqHMmY2yGbPmzg0RRef5Xd7QvDy6CjZwJb/FjSJ2wM+qObmyIDsN59Ab4VW+Zl2CzNvUqbF38MoWfoQzmWZWbHSkQUMGhEdlwKlye0zblSMv9OGTtuDQwKcoZHIudehgS0qkSvjqNn9wok7hd/Trf/tutW2RHDzuhtlLjgI4y409P1J6RNO38R8IcqFw2JJVTqNwAXmKba1KT+D7JOYxrNqQDiitJkmgjYg6xkpzV9qkT8r09aRG1zaTIVgvA5kma3mJCI2giHgfUlRh59cytnIKiy0zoV40LQxWTCy X-Auto-Response-Suppress: DR, RN, NRN, OOF, AutoReply X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(131327999870524)(192813158149592); X-MS-Exchange-SenderADCheck: 1 X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(8211001083)(6040522)(2401047)(8121501046)(5005006)(3002001)(10201501046)(3231254)(944501410)(52105095)(93006095)(93004095)(6055026)(149027)(150027)(6041310)(20161123558120)(20161123560045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123562045)(20161123564045)(6072148)(201708071742011)(7699016); SRVR:BLUPR02MB1217; BCL:0; PCL:0; RULEID:; SRVR:BLUPR02MB1217; X-Microsoft-Exchange-Diagnostics: 1; BLUPR02MB1217; 4:uu2qtGYsY7ajbbJdaIBULAlBQi0kbg/zQ/K1Y5nYDG+iKl+TC/mZLbfmMrj9CohyWQuvL8TyJvIdb8kw26G1bkGSts7+rTzCyHZgMJL3uwmhi3xMnD4le3XrvX6/WscFvC6H5vB3jZ+EmCaj63ZUj8MQWfcWGLZK/hWWzLDwe8c1PXR58NdeZ+sQtnktsMXQ91yslLBdegRnv0Iv8jPNZWJsO6NhEwqMoVqj9EHOhPC8qmK48MNn9r3nEMwOxB9nDhSJ8jTjGNidcxXV5RX3EfVTe1BhdomuiKRUYEcAePrtxlLYaJLvkcB2+27AbQ8kQfYo99EkNOoOpaKITVR3681D/Bo3NK/PlAk6hBa8Mhg= X-Forefront-PRVS: 06860EDC7B X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; BLUPR02MB1217; 23:upHP0RLzT7V5qbse13oy1T6DdOIAflsBxA+xAWJ66?= 1fSC7Uoh793bChRdejUfeGm9WATFh/eto4oGcAWDvvYFdsNCkc55OOtreEVnXpuSq0pcenvAveBtyoqVKemsfTGmullQVRKfg0nlxjQP2E716G304KlF7pV9cyFOVMy5AOZPGdK6KH9PTYFrdQpReeKwJpjjAHRH8zY/5meIZzyIJX3GLaYZtTF7z9AWdZvPnAtOt5MBZSgagWJ/14NQD5CWMCh0MrtdFEJcijyu+RtFxt5ud0bPdfmQmrHgH+SO+STpLubhJ4tLb3fl+vNsjaiyoual2cfEHLZp5+Uucx+J6D0HxKKQGrGCyZUGDYySIM20wKIamW9wxlnhode9QVvAONMueb0tzG1XZjehG//j696Jlvwui29H/kaRL4eDAB3uFAu44boj/upAgxqnFMmSCoZG52PHW6PV+EY+8+ZE3qajrRfnrFKfoMMWEBkgWhgNo0uDX2rhjfC7Vql2VjFjWlxnH+6mLon5au881zvkbm9/BAxDDShibXnwTLjsNbS1BaOVDcf7V70tqW0R93blzhvjJcpjHyty4jNvCXC7xDRNwemmfImf+yZt7mjd/SGQcUFnKG+dgfFqINJLti3eQmf6N8AdPAk/J6xdt2Xoka8teTGELfnttcL9pVe4LyNr17DTdncZFCTBMX5WDvPBvS2Djo3uAknwjzb0VRQ7bpKTzfYde4kylacusQXP1/rSodgL4O4wxd7VQ0D+QLnY0VyQCsY3uFtgei4qRTp6at1G0gRqskzvrwrx1qVoCzffHcQNLwZpyUgL/AfeO4dKJMiG/9YOYtMuxjmB+3liUn8WM+3rL/e8RjBqYtVwW+7DVUCYgdh1DQyz2bxvDuylLJTz6jvOwVscBv3mm/FIpTMhbRshgzzRKT5i3YVkeDY7MNe/NDEbZSNGsnZ0ccv0Bo6ajaKNKmNlt63PxZDHYSL0RpKyo8jDKZcwrcJ2BHMHl3xpSiVZzi80NfU6Es/8ubCrLsSo9qye5YpxQdqRphIXWVe+QtvnRqIdnNZm+NMZM/XeOycovtMTFVpA9+7aUSzkeYIgGkN/mfsrciA2dMWSlHvwCFN3WW27YHSRkbvjCGKtAtwXgmBcf5hihvL2bhO4vPDhy2njn9Mnu9uwnMVh6IqsPbyMzuendZbK/C+x4PzoMkHZ3+bpTW/8gTa X-Microsoft-Antispam-Message-Info: ja3PMIcVuh5kYhjMLo2W3hXhT2HEwUqFDpa/O2bonHw+F4WX5N94yIfEHFApP0IJTc0JIaBo1mo6xnUmEAhMQJkioR+azQOlnpw0XbGO9d96jtUlosljRMVHlx1F8lHKnx9YW90VO+behsOKNMp63KZJkNxIlqncuuOIR0slszBuNwUyfsAOzdXe0xW1K7eP X-Microsoft-Exchange-Diagnostics: 1; BLUPR02MB1217; 6:Arabx7nbGxhsF8lIy2cYQ8Bju1sDvBBmmdr5DN2D1Vr3L+M99RrCcQTVPJ227RIT9hybTWPRPrfcKaP4Wr3bgS0SAZAtD36fvZai3aGngUqW45bWT7Zyycp82i+4xiaOsR87LWhhvPqBGLS87+s+mZczfCRu5x//rZgbv1gfAGmJuaw0XlTdy8er84hUwaeFIpQ93J0m1GhP6+cRoPHLrte3JJH2Wlnj997NplDbyizu5iG9lsQmY7YrlX6VUA8TmQISYn26+a3yBVmtRvM1lrvGogkv6JsN+9wXjGYueiOLtAndPnl5u4bH82QNLafxxjig/kg6Q1Dj+OhOA7RrGzF25p2vKa7CgU6KeuWEh37+vH3i9eYFNWkBnsWzzc7eybZY0CTUmtsmXnqcOlXrbHFPUohQ4sKNqgsNzN7x6YGfsgT/fyKQTGgSIIrhDid2R5zH7FMBeSAvykOeNN1GIQ==; 5:T/AD2KKEiv1AWVccxyG1T6n59I+hz23GJ9/dgNOwCOs5RCQVDbdR0WXKDFFmyrwqZV5wSJ/x6tUdGS0qI3TmM0W+l4u4bVf3d+aDNx9+4whZl7Aqm9kq3pMOa+deIWmKO6vSTOoj/T9cGTsUDas8pk9HVPg3wXQQ1heCiV6NCuo=; 24:l7UPlydaEbkA2Uw4uZWOmX7hwtLtej2w0TVJuV3ZcAk3lmPsDrSmyymUEzVRdRy6ax9QxyI/7vTO6zCvoUI+PWdqh6NvIw8h37HmR2kRcb8= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; BLUPR02MB1217; 7:cpUUfPBWveleWTBR08KgyBcHUZ2rfrIVpzF6gNSccZwwv+/gRfdFG+GeqOGtbk3bYBOOj+DoyPVV5tHnZGYYCUUTwpDBD0rJVl0jd/hOlpSvd83TwJtXAZf1YyPPUOgkg83cDC2kTzri0sx3JtKu8JWReP04sRNHWUvZLVCQgqVD0Nk3mw1IreP+EiZASsKBBk4KqvFjCIrbldxaeOgIfG6zwCbES6H4NfgSirSlw7ygNEuJB1q7/DiYm703PT4b X-MS-Office365-Filtering-Correlation-Id: 59aa03a4-4fc2-4500-f506-08d5c496ea34 X-OriginatorOrg: xilinx.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 28 May 2018 12:31:19.3302 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 59aa03a4-4fc2-4500-f506-08d5c496ea34 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.100]; Helo=[xsj-pvapsmtpgw02] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BLUPR02MB1217 Cc: michal.simek@xilinx.com, Vipul Kumar Subject: [U-Boot] [UBOOT PATCH] spi: xilinx_spi: Modify xilinx spi driver X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" This patch added support to get reg base address from DTS file and added rxfifo() and txfifo() functions to add the modularity. Also, this patch is for the startup block issue in the spi controller. SPI clock is passing through STARTUP block to FLASH. STARTUP block don't provide clock as soon as QSPI provides command. So, first command fails. This patch added support to read JEDEC id in xilinx_spi_xfer () before performing the spi operations. Signed-off-by: Vipul Kumar --- drivers/spi/xilinx_spi.c | 161 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 121 insertions(+), 40 deletions(-) -- 2.7.4 This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately. diff --git a/drivers/spi/xilinx_spi.c b/drivers/spi/xilinx_spi.c index 8f0f32f..12097ce 100644 --- a/drivers/spi/xilinx_spi.c +++ b/drivers/spi/xilinx_spi.c @@ -77,10 +77,6 @@ #define CONFIG_XILINX_SPI_IDLE_VAL GENMASK(7, 0) #endif -#ifndef CONFIG_SYS_XILINX_SPI_LIST -#define CONFIG_SYS_XILINX_SPI_LIST { CONFIG_SYS_SPI_BASE } -#endif - /* xilinx spi register set */ struct xilinx_spi_regs { u32 __space0__[7]; @@ -105,16 +101,14 @@ struct xilinx_spi_priv { struct xilinx_spi_regs *regs; unsigned int freq; unsigned int mode; + unsigned int fifo_depth; }; -static unsigned long xilinx_spi_base_list[] = CONFIG_SYS_XILINX_SPI_LIST; static int xilinx_spi_probe(struct udevice *bus) { struct xilinx_spi_priv *priv = dev_get_priv(bus); struct xilinx_spi_regs *regs = priv->regs; - priv->regs = (struct xilinx_spi_regs *)xilinx_spi_base_list[bus->seq]; - writel(SPISSR_RESET_VALUE, ®s->srr); return 0; @@ -134,8 +128,12 @@ static void spi_cs_deactivate(struct udevice *dev) struct udevice *bus = dev_get_parent(dev); struct xilinx_spi_priv *priv = dev_get_priv(bus); struct xilinx_spi_regs *regs = priv->regs; + u32 reg; + reg = readl(®s->spicr) | SPICR_RXFIFO_RESEST | SPICR_TXFIFO_RESEST; + writel(reg, ®s->spicr); writel(SPISSR_OFF, ®s->spissr); + } static int xilinx_spi_claim_bus(struct udevice *dev) @@ -162,6 +160,80 @@ static int xilinx_spi_release_bus(struct udevice *dev) return 0; } +static u32 xilinx_spi_fill_txfifo(struct udevice *bus, const u8 *txp, + u32 txbytes) +{ + struct xilinx_spi_priv *priv = dev_get_priv(bus); + struct xilinx_spi_regs *regs = priv->regs; + unsigned char d; + u32 i = 0; + + while (txbytes && !(readl(®s->spisr) & SPISR_TX_FULL) && + i < priv->fifo_depth) { + d = txp ? *txp++ : CONFIG_XILINX_SPI_IDLE_VAL; + debug("spi_xfer: tx:%x ", d); + /* write out and wait for processing (receive data) */ + writel(d & SPIDTR_8BIT_MASK, ®s->spidtr); + txbytes--; + i++; + } + return i; +} + +static u32 xilinx_spi_read_rxfifo(struct udevice *bus, u8 *rxp, u32 rxbytes) +{ + struct xilinx_spi_priv *priv = dev_get_priv(bus); + struct xilinx_spi_regs *regs = priv->regs; + unsigned char d; + unsigned int i = 0; + + while (rxbytes && !(readl(®s->spisr) & SPISR_RX_EMPTY)) { + d = readl(®s->spidrr) & SPIDRR_8BIT_MASK; + if (rxp) + *rxp++ = d; + debug("spi_xfer: rx:%x\n", d); + rxbytes--; + i++; + } + debug("Rx_done\n"); + + return i; +} + +static void xilinx_startup_block(struct udevice *dev, unsigned int bytes, + const void *dout, void *din) +{ + struct udevice *bus = dev_get_parent(dev); + struct xilinx_spi_priv *priv = dev_get_priv(bus); + struct xilinx_spi_regs *regs = priv->regs; + struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev); + const unsigned char *txp = dout; + unsigned char *rxp = din; + static int startup; + u32 reg, count; + u32 txbytes = bytes; + u32 rxbytes = bytes; + + /* + * This loop runs two times. First time to send the command. + * Second time to transfer data. After transferring data, + * it sets txp to the initial value for the normal operation. + */ + for ( ; startup < 2; startup++) { + count = xilinx_spi_fill_txfifo(bus, txp, txbytes); + reg = readl(®s->spicr) & ~SPICR_MASTER_INHIBIT; + writel(reg, ®s->spicr); + count = xilinx_spi_read_rxfifo(bus, rxp, rxbytes); + txp = din; + + if (startup) { + spi_cs_deactivate(dev); + spi_cs_activate(dev, slave_plat->cs); + txp = dout; + } + } +} + static int xilinx_spi_xfer(struct udevice *dev, unsigned int bitlen, const void *dout, void *din, unsigned long flags) { @@ -173,8 +245,9 @@ static int xilinx_spi_xfer(struct udevice *dev, unsigned int bitlen, unsigned int bytes = bitlen / XILSPI_MAX_XFER_BITS; const unsigned char *txp = dout; unsigned char *rxp = din; - unsigned rxecount = 17; /* max. 16 elements in FIFO, leftover 1 */ - unsigned global_timeout; + u32 txbytes = bytes; + u32 rxbytes = bytes; + u32 reg, count, timeout; debug("spi_xfer: bus:%i cs:%i bitlen:%i bytes:%i flags:%lx\n", bus->seq, slave_plat->cs, bitlen, bytes, flags); @@ -189,48 +262,41 @@ static int xilinx_spi_xfer(struct udevice *dev, unsigned int bitlen, goto done; } - /* empty read buffer */ - while (rxecount && !(readl(®s->spisr) & SPISR_RX_EMPTY)) { - readl(®s->spidrr); - rxecount--; - } - - if (!rxecount) { - printf("XILSPI error: Rx buffer not empty\n"); - return -1; - } - if (flags & SPI_XFER_BEGIN) spi_cs_activate(dev, slave_plat->cs); - /* at least 1usec or greater, leftover 1 */ - global_timeout = priv->freq > XILSPI_MAX_XFER_BITS * 1000000 ? 2 : - (XILSPI_MAX_XFER_BITS * 1000000 / priv->freq) + 1; - - while (bytes--) { - unsigned timeout = global_timeout; - /* get Tx element from data out buffer and count up */ - unsigned char d = txp ? *txp++ : CONFIG_XILINX_SPI_IDLE_VAL; - debug("spi_xfer: tx:%x ", d); - - /* write out and wait for processing (receive data) */ - writel(d & SPIDTR_8BIT_MASK, ®s->spidtr); - while (timeout && readl(®s->spisr) - & SPISR_RX_EMPTY) { - timeout--; + /* + * This is the work around for the startup block issue in + * the spi controller. SPI clock is passing through STARTUP + * block to FLASH. STARTUP block don't provide clock as soon + * as QSPI provides command. So first command fails. + */ + xilinx_startup_block(dev, bytes, dout, din); + + while (txbytes && rxbytes) { + count = xilinx_spi_fill_txfifo(bus, txp, txbytes); + reg = readl(®s->spicr) & ~SPICR_MASTER_INHIBIT; + writel(reg, ®s->spicr); + txbytes -= count; + if (txp) + txp += count; + + timeout = 10000000; + do { udelay(1); - } + } while (!(readl(®s->spisr) & SPISR_TX_EMPTY) && timeout--); if (!timeout) { printf("XILSPI error: Xfer timeout\n"); return -1; } - /* read Rx element and push into data in buffer */ - d = readl(®s->spidrr) & SPIDRR_8BIT_MASK; + debug("txbytes:0x%x,txp:0x%p\n", txbytes, txp); + count = xilinx_spi_read_rxfifo(bus, rxp, rxbytes); + rxbytes -= count; if (rxp) - *rxp++ = d; - debug("spi_xfer: rx:%x\n", d); + rxp += count; + debug("rxbytes:0x%x rxp:0x%p\n", rxbytes, rxp); } done: @@ -285,6 +351,20 @@ static const struct dm_spi_ops xilinx_spi_ops = { .set_mode = xilinx_spi_set_mode, }; +static int xilinx_spi_ofdata_to_platdata(struct udevice *bus) +{ + struct xilinx_spi_priv *priv = dev_get_priv(bus); + + priv->regs = (struct xilinx_spi_regs *)devfdt_get_addr(bus); + + debug("%s: regs=%p\n", __func__, priv->regs); + + priv->fifo_depth = fdtdec_get_int(gd->fdt_blob, dev_of_offset(bus), + "fifo-size", 0); + + return 0; +} + static const struct udevice_id xilinx_spi_ids[] = { { .compatible = "xlnx,xps-spi-2.00.a" }, { .compatible = "xlnx,xps-spi-2.00.b" }, @@ -296,6 +376,7 @@ U_BOOT_DRIVER(xilinx_spi) = { .id = UCLASS_SPI, .of_match = xilinx_spi_ids, .ops = &xilinx_spi_ops, + .ofdata_to_platdata = xilinx_spi_ofdata_to_platdata, .priv_auto_alloc_size = sizeof(struct xilinx_spi_priv), .probe = xilinx_spi_probe, };