From patchwork Wed Jan 24 06:16:24 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Icenowy Zheng X-Patchwork-Id: 10181835 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id A8871601D5 for ; Wed, 24 Jan 2018 06:18:00 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9656328837 for ; Wed, 24 Jan 2018 06:18:00 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8AC2928848; Wed, 24 Jan 2018 06:18:00 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id E830528837 for ; Wed, 24 Jan 2018 06:17:59 +0000 (UTC) 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:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id: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:In-Reply-To: References:List-Owner; bh=NTcncefbViqEHQ9wEoClP33LQI2Vqp9mVAMePgko+y4=; b=Rr2 yAYnF15F+h5AnKO87c8nHET2xvii1CBpg2bFcj3KkzxWjG7YHeEai5uuFhUeJpVQJmemYXAx5k8dS KtrC4VoJ/8w2N4wZP8cZeYCFRCgFIC2ddeKBPOuI9ReWFzyQYTYrcD4kXVB7sRpJFkGJ5Xny9Tyod onwddiZrP6FiU7AvR4iFYc3KHVGZpm/yg2YjrINdcumVf3mx9SV+3snx7QlGePQUUDsKYvpnBUsz0 G9aMWGmCtRC+Q4nTGG8qE1depN41c7dYGDvZA+hVL5cJ5zoURPkHnyLK1B3ULIEN5y6TjNK1tFjbL Ju/VYP/6L3dgxWepAr7uuCsJD9F7joQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.89 #1 (Red Hat Linux)) id 1eeENi-0006Jt-CH; Wed, 24 Jan 2018 06:17:58 +0000 Received: from glow.birch.relay.mailchannels.net ([23.83.209.71]) by bombadil.infradead.org with esmtps (Exim 4.89 #1 (Red Hat Linux)) id 1eeENP-000653-KL for linux-arm-kernel@lists.infradead.org; Wed, 24 Jan 2018 06:17:41 +0000 X-Sender-Id: lmn-tzduiowcrqmw|x-authsender|icenowy@aosc.io Received: from relay.mailchannels.net (localhost [127.0.0.1]) by relay.mailchannels.net (Postfix) with ESMTP id 85F8A560F79; Wed, 24 Jan 2018 06:17:25 +0000 (UTC) Received: from hermes.aosc.io (unknown [100.96.25.39]) (Authenticated sender: lmn-TZDUIOWCRQMW) by relay.mailchannels.net (Postfix) with ESMTPA id 8C246560D35; Wed, 24 Jan 2018 06:17:24 +0000 (UTC) X-Sender-Id: lmn-tzduiowcrqmw|x-authsender|icenowy@aosc.io Received: from hermes.aosc.io (hermes.aosc.io [172.18.36.131]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384) by 0.0.0.0:2500 (trex/5.13.1); Wed, 24 Jan 2018 06:17:25 +0000 X-MC-Relay: Neutral X-MailChannels-SenderId: lmn-tzduiowcrqmw|x-authsender|icenowy@aosc.io X-MailChannels-Auth-Id: lmn-TZDUIOWCRQMW X-Wipe-Attack: 034acaf701cf23fe_1516774645248_2216656146 X-MC-Loop-Signature: 1516774645248:3069961023 X-MC-Ingress-Time: 1516774645247 Received: from localhost (localhost [127.0.0.1]) (Authenticated sender: icenowy@aosc.io) by hermes.aosc.io (Postfix) with ESMTPSA id D733A562F7; Wed, 24 Jan 2018 06:17:17 +0000 (UTC) From: Icenowy Zheng To: Srinivas Kandagatla , Maxime Ripard , Chen-Yu Tsai Subject: [PATCH] nvmem: sunxi-sid: fix H3 SID controller support Date: Wed, 24 Jan 2018 14:16:24 +0800 Message-Id: <20180124061624.61951-1-icenowy@aosc.io> X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-sunxi@googlegroups.com, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Icenowy Zheng MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP It seems that doing some operation will make the value pre-read on H3 SID controller wrong again, so all operation should be performed by register. Change the SID reading to use register only. Signed-off-by: Icenowy Zheng --- drivers/nvmem/sunxi_sid.c | 71 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 50 insertions(+), 21 deletions(-) diff --git a/drivers/nvmem/sunxi_sid.c b/drivers/nvmem/sunxi_sid.c index 99bd54d85fcb..d4086d143ac1 100644 --- a/drivers/nvmem/sunxi_sid.c +++ b/drivers/nvmem/sunxi_sid.c @@ -85,13 +85,14 @@ static int sunxi_sid_read(void *context, unsigned int offset, } static int sun8i_sid_register_readout(const struct sunxi_sid *sid, - const unsigned int word) + const unsigned int offset, + u32 *out) { u32 reg_val; int ret; /* Set word, lock access, and set read command */ - reg_val = (word & SUN8I_SID_OFFSET_MASK) + reg_val = (offset & SUN8I_SID_OFFSET_MASK) << SUN8I_SID_OFFSET_SHIFT; reg_val |= SUN8I_SID_OP_LOCK | SUN8I_SID_READ; writel(reg_val, sid->base + SUN8I_SID_PRCTL); @@ -101,7 +102,49 @@ static int sun8i_sid_register_readout(const struct sunxi_sid *sid, if (ret) return ret; + if (out) + *out = readl(sid->base + SUN8I_SID_RDKEY); + writel(0, sid->base + SUN8I_SID_PRCTL); + + return 0; +} + +/* + * On Allwinner H3, the value on the 0x200 offset of the SID controller seems to be + * not reliable at all. + * Read by the registers instead. + */ +static int sun8i_sid_read_byte_by_reg(const struct sunxi_sid *sid, + const unsigned int offset, + u8 *out) +{ + u32 word; + int ret; + + ret = sun8i_sid_register_readout(sid, offset & ~0x03, &word); + + if (ret) + return ret; + + *out = (word >> ((offset & 0x3) * 8)) & 0xff; + + return 0; +} + +static int sun8i_sid_read_by_reg(void *context, unsigned int offset, + void *val, size_t bytes) +{ + struct sunxi_sid *sid = context; + u8 *buf = val; + int ret; + + while (bytes--) { + ret = sun8i_sid_read_byte_by_reg(sid, offset++, buf++); + if (ret) + return ret; + } + return 0; } @@ -131,26 +174,12 @@ static int sunxi_sid_probe(struct platform_device *pdev) size = cfg->size; - if (cfg->need_register_readout) { - /* - * H3's SID controller have a bug that the value at 0x200 - * offset is not the correct value when the hardware is reseted. - * However, after doing a register-based read operation, the - * value become right. - * Do a full read operation here, but ignore its value - * (as it's more fast to read by direct MMIO value than - * with registers) - */ - for (i = 0; i < (size >> 2); i++) { - ret = sun8i_sid_register_readout(sid, i); - if (ret) - return ret; - } - } - econfig.size = size; econfig.dev = dev; - econfig.reg_read = sunxi_sid_read; + if (cfg->need_register_readout) + econfig.reg_read = sun8i_sid_read_by_reg; + else + econfig.reg_read = sunxi_sid_read; econfig.priv = sid; nvmem = nvmem_register(&econfig); if (IS_ERR(nvmem)) @@ -163,7 +192,7 @@ static int sunxi_sid_probe(struct platform_device *pdev) } for (i = 0; i < size; i++) - randomness[i] = sunxi_sid_read_byte(sid, i); + econfig.reg_read(sid, i, &randomness[i], 1); add_device_randomness(randomness, size); kfree(randomness);