From patchwork Fri Jul 12 03:32:13 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Jeffery X-Patchwork-Id: 11041375 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 09CEE1395 for ; Fri, 12 Jul 2019 03:32:47 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EB68C28B8B for ; Fri, 12 Jul 2019 03:32:46 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id DDB4728B9F; Fri, 12 Jul 2019 03:32:46 +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=-5.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.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 7AB5F28B8B for ; Fri, 12 Jul 2019 03:32:46 +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: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=xZuLm3qEOoPkWGqAInhrbx15DejwF/7t7rQdJeaD+p0=; b=uB+fXzs5B4gHOW muxPTKX9GupmS/e+CCfEI9QSj0dUQt2Xf+CP6JX+6cgqfdVxE+iX58MHNCTOq9Y68utY/pNAX82Ep X+Ke7mPJP2M302T2LhGaipLx9BFBY4rx2CsLvBMxIlHISno9f9GITqCez9J8HjDPPMKarbFvSeyPw MmLymXNbv+PY+MvQUutDjJo/uJzNUgUBUWR9eWCata870W8AMgk2J4vHgHdG/YD9qNMDZoeNhwg1I LMy0FXPJv19wCQLurmmPVN8i6nbAcf6V8WGEaVaUtaO833ji1q71N35RdB6ap76aXGr6O96hp62ow RopOfbVaJH9cdr0IIhBA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92 #3 (Red Hat Linux)) id 1hlmIf-0000v3-TS; Fri, 12 Jul 2019 03:32:46 +0000 Received: from new4-smtp.messagingengine.com ([66.111.4.230]) by bombadil.infradead.org with esmtps (Exim 4.92 #3 (Red Hat Linux)) id 1hlmIM-0000ha-5a for linux-arm-kernel@lists.infradead.org; Fri, 12 Jul 2019 03:32:27 +0000 Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailnew.nyi.internal (Postfix) with ESMTP id C10AC1B61; Thu, 11 Jul 2019 23:32:23 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute4.internal (MEProxy); Thu, 11 Jul 2019 23:32:23 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=aj.id.au; h=from :to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; s=fm3; bh=8OTTrn15u+3N9 pDWV3Ka61zLndSduUjJwrYMM8MILms=; b=Q90CrvOUoebID2ta1bqq8kxPeT2hw 6PnXZ07fFtMufFlH0lypw7I3ASf2lleRSUO3xt3T70x41NHGsUmJ1VV3NvVAHZqD JRltB0BssjVGZzYBMcW5y9iOsa5lHdgiZafE+HbjNSesbt0Xul3vZBUaw1KIzmi/ WITjOZYrr9ecmtw0fIpI5VUIyeWBO8LXAtM5O+omlHXMacpf3QaL9ok1VVfiT18h LcFF5ogdYMD06XRSt0RDe4HjJDzyyVnOIeQ5BEm3FKEB2AX3pBB0ilWWbu7X+1zW OLz9JZoWTQVw8aSwlrr4oVs4q369QI9ToYOXAE/Sure+Y9H+wFPDYGb/w== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :in-reply-to:message-id:mime-version:references:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm3; bh=8OTTrn15u+3N9pDWV3Ka61zLndSduUjJwrYMM8MILms=; b=o+oDEYuM nBf8QPrJpDwucokTXM+LYxLYvzioci4sZ+UKx0JesDJnsB4VpU8BjZE5jITJfprQ AVqYUOcBodZIqX5VIAoQxuhdygEDhw64Uv7pTmwUM8tn6xFZEy49jg1X+UT3q4t0 Wd3wwkFnG0ZAx4TCyCnhAUE0PTN9PFnisYlJ4hSOU6bB8KedCwrFpoyU2XhwvBwC JCDPPWvvLiWYEknOcMx5DoYuBrYkaNBD3JMxge9fe0CFIWEsZnOm86U1xoWeeGOI mvzBYXV+g1AWq70DQ2ZGtjPndEZktE10mBey/GTmETvJcTduWUtvvr2ASuiJm39V vdGKzDduW1EDIg== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeduvddrgeelgdejfecutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecunecujfgurhephffvufffkffojghfggfgsedtkeertd ertddtnecuhfhrohhmpeetnhgurhgvficulfgvfhhfvghrhicuoegrnhgurhgvfiesrghj rdhiugdrrghuqeenucffohhmrghinhepuggvvhhitggvthhrvggvrdhorhhgnecukfhppe dvtddvrdekuddrudekrdeftdenucfrrghrrghmpehmrghilhhfrhhomheprghnughrvgif segrjhdrihgurdgruhenucevlhhushhtvghrufhiiigvpedt X-ME-Proxy: Received: from mistburn.au.ibm.com (bh02i525f01.au.ibm.com [202.81.18.30]) by mail.messagingengine.com (Postfix) with ESMTPA id AC94B80060; Thu, 11 Jul 2019 23:32:19 -0400 (EDT) From: Andrew Jeffery To: linux-mmc@vger.kernel.org Subject: [PATCH v2 1/2] dt-bindings: mmc: Document Aspeed SD controller Date: Fri, 12 Jul 2019 13:02:13 +0930 Message-Id: <20190712033214.24713-2-andrew@aj.id.au> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190712033214.24713-1-andrew@aj.id.au> References: <20190712033214.24713-1-andrew@aj.id.au> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190711_203226_386363_15994721 X-CRM114-Status: UNSURE ( 9.96 ) X-CRM114-Notice: Please train this message. X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: mark.rutland@arm.com, devicetree@vger.kernel.org, ulf.hansson@linaro.org, linux-aspeed@lists.ozlabs.org, Andrew Jeffery , ryanchen.aspeed@gmail.com, adrian.hunter@intel.com, linux-kernel@vger.kernel.org, robh+dt@kernel.org, joel@jms.id.au, linux-arm-kernel@lists.infradead.org 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 The ASPEED SD/SDIO/eMMC controller exposes two slots implementing the SDIO Host Specification v2.00, with 1 or 4 bit data buses, or an 8 bit data bus if only a single slot is enabled. Signed-off-by: Andrew Jeffery Reviewed-by: Rob Herring --- In v2: * Rename to aspeed,sdhci.yaml * Rename sd-controller compatible * Add `maxItems: 1` for reg properties * Move sdhci subnode description to patternProperties * Drop sdhci compatible requirement * #address-cells and #size-cells are required * Prevent additional properties * Implement explicit ranges in example * Remove slot property .../devicetree/bindings/mmc/aspeed,sdhci.yaml | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 Documentation/devicetree/bindings/mmc/aspeed,sdhci.yaml diff --git a/Documentation/devicetree/bindings/mmc/aspeed,sdhci.yaml b/Documentation/devicetree/bindings/mmc/aspeed,sdhci.yaml new file mode 100644 index 000000000000..67a691c3348c --- /dev/null +++ b/Documentation/devicetree/bindings/mmc/aspeed,sdhci.yaml @@ -0,0 +1,90 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mmc/aspeed,sdhci.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ASPEED SD/SDIO/eMMC Controller + +maintainers: + - Andrew Jeffery + - Ryan Chen + +description: |+ + The ASPEED SD/SDIO/eMMC controller exposes two slots implementing the SDIO + Host Specification v2.00, with 1 or 4 bit data buses, or an 8 bit data bus if + only a single slot is enabled. + + The two slots are supported by a common configuration area. As the SDHCIs for + the slots are dependent on the common configuration area, they are described + as child nodes. + +properties: + compatible: + enum: [ aspeed,ast2400-sd-controller, aspeed,ast2500-sd-controller ] + reg: + maxItems: 1 + description: Common configuration registers + ranges: true + clocks: + maxItems: 1 + description: The SD/SDIO controller clock gate + +patternProperties: + "^sdhci@[0-9a-f]+$": + type: object + properties: + compatible: + enum: [ aspeed,ast2400-sdhci, aspeed,ast2500-sdhci ] + reg: + maxItems: 1 + description: The SDHCI registers + clocks: + maxItems: 1 + description: The SD bus clock + interrupts: + maxItems: 1 + description: The SD interrupt shared between both slots + required: + - compatible + - reg + - clocks + - interrupts + +additionalProperties: false + +required: + - compatible + - reg + - "#address-cells" + - "#size-cells" + - ranges + - clocks + +examples: + - | + #include + sdc@1e740000 { + compatible = "aspeed,ast2500-sd-controller"; + reg = <0x1e740000 0x100>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x1e740000 0x10000>; + clocks = <&syscon ASPEED_CLK_GATE_SDCLK>; + + sdhci0: sdhci@100 { + compatible = "aspeed,ast2500-sdhci"; + reg = <0x100 0x100>; + interrupts = <26>; + sdhci,auto-cmd12; + clocks = <&syscon ASPEED_CLK_SDIO>; + }; + + sdhci1: sdhci@200 { + compatible = "aspeed,ast2500-sdhci"; + reg = <0x200 0x100>; + interrupts = <26>; + sdhci,auto-cmd12; + clocks = <&syscon ASPEED_CLK_SDIO>; + }; + }; From patchwork Fri Jul 12 03:32:14 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Jeffery X-Patchwork-Id: 11041377 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E51DF14DB for ; Fri, 12 Jul 2019 03:33:05 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D140628B8B for ; Fri, 12 Jul 2019 03:33:05 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C3EC328B9F; Fri, 12 Jul 2019 03:33:05 +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=-5.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.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 A0A3628B8B for ; Fri, 12 Jul 2019 03:33:04 +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: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=YBmGx1bR4uXTl4x5Z/AkbLqeRDDvqCXv3d7iX0bqxgc=; b=jcq67OspiXJyW+ oNoOa7fPQpPf5hJcyvCMRwAp00ZraSPaNd/Fzmgd5T9Ig1Vo9GSSaYRt/872yURBJe769qbtQ59+Y K9NkNok4kwe65L+29kAR4Aab2GgjTidL+6hH04OcKHVaRjoNuMKB3+oWMdN99MbEn+z+bXP/EvZ0i OXEleFELiHdSXlXneLSe4L0J52OPk0G9k7TJli4IUngh79kSSoWro0Lmuyih/41Kn315vaLhCmHMw WnQWmGzfqDJcy0/V+H4cXVRY5D3QjJWuXvDeRZz80hNm7lhhT+qTuVpswhvGql0ZALi1r/u4ISWSG giT+zS9NKeMOgjnPE0LQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92 #3 (Red Hat Linux)) id 1hlmIy-00019e-7K; Fri, 12 Jul 2019 03:33:04 +0000 Received: from new4-smtp.messagingengine.com ([66.111.4.230]) by bombadil.infradead.org with esmtps (Exim 4.92 #3 (Red Hat Linux)) id 1hlmIO-0000iz-R0 for linux-arm-kernel@lists.infradead.org; Fri, 12 Jul 2019 03:32:31 +0000 Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailnew.nyi.internal (Postfix) with ESMTP id 3E0BC251A; Thu, 11 Jul 2019 23:32:28 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute4.internal (MEProxy); Thu, 11 Jul 2019 23:32:28 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=aj.id.au; h=from :to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; s=fm3; bh=fkSuP+7fVHlE/ E6moUmSwJxuks6N6jMHu6Z3svSfOro=; b=TMrQRiPYcQZh9ddMx0CvOQL2Q54zH 1iJNxbhsC0VFdUla1MZYBYcbILrURSPkaC52rP0IkCsuDMviuCpxCXSlkU43zwvB tMU2Zsy9q5sGx19/A0bUrBSpwyIF94KopWD8fP1RaNhv7tkL4N+0rsHBD3rIcvPu PTwKrkB/ObV7FVhVxDn7Hc2OLLCRpiHu9Nj/hBWfPCq8H+3Otd5AIerZDLBCxcae ALw1nNHXGbfC6V3nQUKxPVwoUAUx4FjFKI3/YzDoFyhLWWUkOojFTSZ2xOXlKJmx o+wNtwfKyyFP2mf/5db0lnMiGIH+CnPSCk8KYJ4b0AO5DliWP7cMzH5jA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :in-reply-to:message-id:mime-version:references:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm3; bh=fkSuP+7fVHlE/E6moUmSwJxuks6N6jMHu6Z3svSfOro=; b=wOYFd+hZ +JLOKPE36lxUuqni8q9y7JlCVgB7X1nhFZF0VxYXMfTsqGreVtDiJkNYMtwEPfs1 r5i8s5L0lM0UfOesOJLJmCU8pei4Q9Zi4/kULRCDL4mqyFZFxyBuFUvER7yNL5N0 dV9HMXJlJM71vl+lvYFi8acVjSaJ2K7mt4G55sZKnMoBdEArk8+Enry79Z5GXkVJ bnESR47DtL+SuV/pb6dQRVTKh5YK1p2Vet9AnnDy1ICxIAWo4BPudp9H0fsRqmk7 ira7RsGehkbHVUwWQgB0bE794H6Qv8+RIrgusjYcRrl+NzmTTKKHX32iCaZualbR BbYbdOf+1vHHQw== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeduvddrgeelgdejfecutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecunecujfgurhephffvufffkffojghfggfgsedtkeertd ertddtnecuhfhrohhmpeetnhgurhgvficulfgvfhhfvghrhicuoegrnhgurhgvfiesrghj rdhiugdrrghuqeenucfkphepvddtvddrkedurddukedrfedtnecurfgrrhgrmhepmhgrih hlfhhrohhmpegrnhgurhgvfiesrghjrdhiugdrrghunecuvehluhhsthgvrhfuihiivgep td X-ME-Proxy: Received: from mistburn.au.ibm.com (bh02i525f01.au.ibm.com [202.81.18.30]) by mail.messagingengine.com (Postfix) with ESMTPA id DC4168005A; Thu, 11 Jul 2019 23:32:23 -0400 (EDT) From: Andrew Jeffery To: linux-mmc@vger.kernel.org Subject: [PATCH v2 2/2] mmc: Add support for the ASPEED SD controller Date: Fri, 12 Jul 2019 13:02:14 +0930 Message-Id: <20190712033214.24713-3-andrew@aj.id.au> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190712033214.24713-1-andrew@aj.id.au> References: <20190712033214.24713-1-andrew@aj.id.au> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190711_203229_051296_481BBF76 X-CRM114-Status: GOOD ( 21.04 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: mark.rutland@arm.com, devicetree@vger.kernel.org, ulf.hansson@linaro.org, linux-aspeed@lists.ozlabs.org, Andrew Jeffery , ryanchen.aspeed@gmail.com, adrian.hunter@intel.com, linux-kernel@vger.kernel.org, robh+dt@kernel.org, joel@jms.id.au, linux-arm-kernel@lists.infradead.org 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 Add a minimal driver for ASPEED's SD controller, which exposes two SDHCIs. The ASPEED design implements a common register set for the SDHCIs, and moves some of the standard configuration elements out to this common area (e.g. 8-bit mode, and card detect configuration which is not currently supported). The SD controller has a dedicated hardware interrupt that is shared between the slots. The common register set exposes information on which slot triggered the interrupt; early revisions of the patch introduced an irqchip for the register, but reality is it doesn't behave as an irqchip, and the result fits awkwardly into the irqchip APIs. Instead I've taken the simple approach of using the IRQ as a shared IRQ with some minor performance impact for the second slot. Ryan was the original author of the patch - I've taken his work and massaged it to drop the irqchip support and rework the devicetree integration. The driver has been smoke tested under qemu against a minimal SD controller model and lightly tested on an ast2500-evb. Signed-off-by: Ryan Chen Signed-off-by: Andrew Jeffery --- In v2: * Drop unnecesasry MODULE_DEVICE_TABLE() * Rename sd-controller compatible * Add IBM copyright * Drop unnecesary data assignment in of match table entries * Derive the slot from the SDHCI offset drivers/mmc/host/Kconfig | 12 ++ drivers/mmc/host/Makefile | 1 + drivers/mmc/host/sdhci-of-aspeed.c | 326 +++++++++++++++++++++++++++++ 3 files changed, 339 insertions(+) create mode 100644 drivers/mmc/host/sdhci-of-aspeed.c diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 931770f17087..2bb5e1264b3d 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -154,6 +154,18 @@ config MMC_SDHCI_OF_ARASAN If unsure, say N. +config MMC_SDHCI_OF_ASPEED + tristate "SDHCI OF support for the ASPEED SDHCI controller" + depends on MMC_SDHCI_PLTFM + depends on OF + help + This selects the ASPEED Secure Digital Host Controller Interface. + + If you have a controller with this interface, say Y or M here. You + also need to enable an appropriate bus interface. + + If unsure, say N. + config MMC_SDHCI_OF_AT91 tristate "SDHCI OF support for the Atmel SDMMC controller" depends on MMC_SDHCI_PLTFM diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index 73578718f119..390ee162fe71 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -84,6 +84,7 @@ obj-$(CONFIG_MMC_SDHCI_ESDHC_IMX) += sdhci-esdhc-imx.o obj-$(CONFIG_MMC_SDHCI_DOVE) += sdhci-dove.o obj-$(CONFIG_MMC_SDHCI_TEGRA) += sdhci-tegra.o obj-$(CONFIG_MMC_SDHCI_OF_ARASAN) += sdhci-of-arasan.o +obj-$(CONFIG_MMC_SDHCI_OF_ASPEED) += sdhci-of-aspeed.o obj-$(CONFIG_MMC_SDHCI_OF_AT91) += sdhci-of-at91.o obj-$(CONFIG_MMC_SDHCI_OF_ESDHC) += sdhci-of-esdhc.o obj-$(CONFIG_MMC_SDHCI_OF_HLWD) += sdhci-of-hlwd.o diff --git a/drivers/mmc/host/sdhci-of-aspeed.c b/drivers/mmc/host/sdhci-of-aspeed.c new file mode 100644 index 000000000000..9528e43c257d --- /dev/null +++ b/drivers/mmc/host/sdhci-of-aspeed.c @@ -0,0 +1,326 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* Copyright (C) 2019 ASPEED Technology Inc. */ +/* Copyright (C) 2019 IBM Corp. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "sdhci-pltfm.h" + +#define ASPEED_SDC_INFO 0x00 +#define ASPEED_SDC_S1MMC8 BIT(25) +#define ASPEED_SDC_S0MMC8 BIT(24) + +struct aspeed_sdc { + struct clk *clk; + struct resource *res; + + spinlock_t lock; + void __iomem *regs; +}; + +struct aspeed_sdhci { + struct aspeed_sdc *parent; + u32 width_mask; +}; + +static void aspeed_sdc_bus_width(struct aspeed_sdc *sdc, + struct aspeed_sdhci *sdhci, bool bus8) +{ + u32 info; + + /* Set/clear 8 bit mode */ + spin_lock(&sdc->lock); + info = readl(sdc->regs + ASPEED_SDC_INFO); + if (bus8) + info |= sdhci->width_mask; + else + info &= ~sdhci->width_mask; + writel(info, sdc->regs + ASPEED_SDC_INFO); + spin_unlock(&sdc->lock); +} + +static void aspeed_sdhci_set_clock(struct sdhci_host *host, unsigned int clock) +{ + unsigned long timeout; + int div; + u16 clk; + + if (clock == host->clock) + return; + + sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL); + + if (clock == 0) + goto out; + + for (div = 1; div < 256; div *= 2) { + if ((host->max_clk / div) <= clock) + break; + } + div >>= 1; + + clk = div << SDHCI_DIVIDER_SHIFT; + clk |= SDHCI_CLOCK_INT_EN; + sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); + + /* Wait max 20 ms */ + timeout = 20; + while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL)) + & SDHCI_CLOCK_INT_STABLE)) { + if (timeout == 0) { + pr_err("%s: Internal clock never stabilised.\n", + mmc_hostname(host->mmc)); + return; + } + timeout--; + mdelay(1); + } + + clk |= SDHCI_CLOCK_CARD_EN; + sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); + +out: + host->clock = clock; +} + +static void aspeed_sdhci_set_bus_width(struct sdhci_host *host, int width) +{ + struct sdhci_pltfm_host *pltfm_priv; + struct aspeed_sdhci *aspeed_sdhci; + struct aspeed_sdc *aspeed_sdc; + u8 ctrl; + + pltfm_priv = sdhci_priv(host); + aspeed_sdhci = sdhci_pltfm_priv(pltfm_priv); + aspeed_sdc = aspeed_sdhci->parent; + + /* Set/clear 8-bit mode */ + aspeed_sdc_bus_width(aspeed_sdc, aspeed_sdhci, + width == MMC_BUS_WIDTH_8); + + /* Set/clear 1 or 4 bit mode */ + ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); + if (width == MMC_BUS_WIDTH_4) + ctrl |= SDHCI_CTRL_4BITBUS; + else + ctrl &= ~SDHCI_CTRL_4BITBUS; + sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); +} + +static const struct sdhci_ops aspeed_sdhci_ops = { + .set_clock = aspeed_sdhci_set_clock, + .get_max_clock = sdhci_pltfm_clk_get_max_clock, + .set_bus_width = aspeed_sdhci_set_bus_width, + .get_timeout_clock = sdhci_pltfm_clk_get_max_clock, + .reset = sdhci_reset, + .set_uhs_signaling = sdhci_set_uhs_signaling, +}; + +static const struct sdhci_pltfm_data aspeed_sdc_pdata = { + .ops = &aspeed_sdhci_ops, + .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN, + .quirks2 = SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN, +}; + +static inline int aspeed_sdhci_calculate_slot(struct aspeed_sdhci *dev, + struct resource *res) +{ + resource_size_t delta; + + if (!res || resource_type(res) != IORESOURCE_MEM) + return -EINVAL; + + if (res->start < dev->parent->res->start) + return -EINVAL; + + delta = res->start - dev->parent->res->start; + if (delta & (0x100 - 1)) + return -EINVAL; + + return (delta / 0x100) - 1; +} + +static int aspeed_sdhci_probe(struct platform_device *pdev) +{ + struct sdhci_pltfm_host *pltfm_host; + struct aspeed_sdhci *dev; + struct sdhci_host *host; + struct resource *res; + int slot; + int ret; + + host = sdhci_pltfm_init(pdev, &aspeed_sdc_pdata, sizeof(*dev)); + if (IS_ERR(host)) + return PTR_ERR(host); + + pltfm_host = sdhci_priv(host); + dev = sdhci_pltfm_priv(pltfm_host); + dev->parent = dev_get_drvdata(pdev->dev.parent); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + slot = aspeed_sdhci_calculate_slot(dev, res); + if (slot < 0) + return slot; + dev_info(&pdev->dev, "Configuring for slot %d\n", slot); + dev->width_mask = !slot ? ASPEED_SDC_S0MMC8 : ASPEED_SDC_S1MMC8; + + sdhci_get_of_property(pdev); + + pltfm_host->clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(pltfm_host->clk)) + return PTR_ERR(pltfm_host->clk); + + ret = clk_prepare_enable(pltfm_host->clk); + if (ret) { + dev_err(&pdev->dev, "Unable to enable SDIO clock\n"); + goto err_pltfm_free; + } + + ret = mmc_of_parse(host->mmc); + if (ret) + goto err_sdhci_add; + + ret = sdhci_add_host(host); + if (ret) + goto err_sdhci_add; + + return 0; + +err_sdhci_add: + clk_disable_unprepare(pltfm_host->clk); +err_pltfm_free: + sdhci_pltfm_free(pdev); + return ret; +} + +static int aspeed_sdhci_remove(struct platform_device *pdev) +{ + struct sdhci_pltfm_host *pltfm_host; + struct sdhci_host *host; + int dead; + + host = platform_get_drvdata(pdev); + pltfm_host = sdhci_priv(host); + + dead = readl(host->ioaddr + SDHCI_INT_STATUS) == 0xffffffff; + + sdhci_remove_host(host, dead); + + clk_disable_unprepare(pltfm_host->clk); + + sdhci_pltfm_free(pdev); + + return 0; +} + +static const struct of_device_id aspeed_sdhci_of_match[] = { + { .compatible = "aspeed,ast2400-sdhci", }, + { .compatible = "aspeed,ast2500-sdhci", }, + { } +}; + +static struct platform_driver aspeed_sdhci_driver = { + .driver = { + .name = "sdhci-aspeed", + .of_match_table = aspeed_sdhci_of_match, + }, + .probe = aspeed_sdhci_probe, + .remove = aspeed_sdhci_remove, +}; + +module_platform_driver(aspeed_sdhci_driver); + +static int aspeed_sdc_probe(struct platform_device *pdev) + +{ + struct device_node *parent, *child; + struct aspeed_sdc *sdc; + int ret; + + sdc = devm_kzalloc(&pdev->dev, sizeof(*sdc), GFP_KERNEL); + if (!sdc) + return -ENOMEM; + + spin_lock_init(&sdc->lock); + + sdc->clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(sdc->clk)) + return PTR_ERR(sdc->clk); + + ret = clk_prepare_enable(sdc->clk); + if (ret) { + dev_err(&pdev->dev, "Unable to enable SDCLK\n"); + return ret; + } + + sdc->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + sdc->regs = devm_ioremap_resource(&pdev->dev, sdc->res); + if (IS_ERR(sdc->regs)) { + ret = PTR_ERR(sdc->regs); + goto err_clk; + } + + dev_set_drvdata(&pdev->dev, sdc); + + parent = pdev->dev.of_node; + for_each_available_child_of_node(parent, child) { + struct platform_device *cpdev; + + cpdev = of_platform_device_create(child, NULL, &pdev->dev); + if (IS_ERR(cpdev)) { + of_node_put(child); + ret = PTR_ERR(pdev); + goto err_clk; + } + } + + return 0; + +err_clk: + clk_disable_unprepare(sdc->clk); + return ret; +} + +static int aspeed_sdc_remove(struct platform_device *pdev) +{ + struct aspeed_sdc *sdc = dev_get_drvdata(&pdev->dev); + + clk_disable_unprepare(sdc->clk); + + return 0; +} + +static const struct of_device_id aspeed_sdc_of_match[] = { + { .compatible = "aspeed,ast2400-sd-controller", }, + { .compatible = "aspeed,ast2500-sd-controller", }, + { } +}; + +MODULE_DEVICE_TABLE(of, aspeed_sdc_of_match); + +static struct platform_driver aspeed_sdc_driver = { + .driver = { + .name = "sd-controller-aspeed", + .pm = &sdhci_pltfm_pmops, + .of_match_table = aspeed_sdc_of_match, + }, + .probe = aspeed_sdc_probe, + .remove = aspeed_sdc_remove, +}; + +module_platform_driver(aspeed_sdc_driver); + +MODULE_DESCRIPTION("Driver for the ASPEED SD/SDIO/SDHCI Controllers"); +MODULE_AUTHOR("Ryan Chen "); +MODULE_AUTHOR("Andrew Jeffery "); +MODULE_LICENSE("GPL v2");