From nobody Tue Apr 7 19:50:38 2026 Received: from mx0a-002e3701.pphosted.com (mx0a-002e3701.pphosted.com [148.163.147.86]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0046D3E275D; Wed, 11 Mar 2026 18:11:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.147.86 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773252696; cv=none; b=rmV6J8L8NtvaDyHtMLsc0mEJ6w9Kr5e16NOIR9lYWUymCacHUxofe7ryHMfrR9vkeUAqWInLC5PipUZrW8sBnQk4qnYQB0Ros9wIK07DZVNepwk9akAd6VGDImrss+CRkXWbc94HMuZc74kZiPCjTCq7D93AHjdV+uk5uBzgV5I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773252696; c=relaxed/simple; bh=ZFCWkDjShmTxzAzuf3WMqjgbe0E+1RhwHyjyZvmng5U=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=bdZAgxA/EiQzcB+b4xBnx+jbVtJ+HDkngHAhh4K2t5n+waGCPWEajhLJthgT3C+kDUZr1piRGzwiAJBlpKH+WVtKDZRZzmBtcW0xOPvgIYu8Hn91TurXkYuuJUYAKXNWqAi1O8/7q148/M0Xv7cvfb98BhNvY8voCIuaZ9gccBw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=hpe.com; spf=pass smtp.mailfrom=hpe.com; dkim=pass (2048-bit key) header.d=hpe.com header.i=@hpe.com header.b=ethFetFX; arc=none smtp.client-ip=148.163.147.86 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=hpe.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=hpe.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=hpe.com header.i=@hpe.com header.b="ethFetFX" Received: from pps.filterd (m0148663.ppops.net [127.0.0.1]) by mx0a-002e3701.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 62BGWG5Q3181922; Wed, 11 Mar 2026 18:11:24 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=hpe.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pps0720; bh=trtzqw01eHYaX fdnc8eseJw+VgcB7uZ9iXgGEnqQSWY=; b=ethFetFXh2y4ek9vZalB52yvDwhxx ptIn6m86+lC5f5dO+VEaqw1zoKJhDuvgS5R9Y+ydCom10+IetPlltB+80bHZ+CCY TmY7LsbX3KadsDTPhwvfXvXoIokGnGkDhfxi6RRcYgxLWQ54dhfmNzEnyfjhHTR4 68gCXIExN+Rk4CX3MFRzzk3BsC3K4L4rD5cCx4aHWpmA7jdVPpDPPGfqdW4fXomR oHUt5oIVBB78ukIULLzVzbKEzlGb3XdCJ6euz6iCtIEF6XzfM33fDZa6gfzO5akj pPRT0u2TuNaJHnQrgN9U5Xg9lQ3QhF+sUZiX5bAWYWJU7V0Q14g4Gsi+A== Received: from p1lg14879.it.hpe.com (p1lg14879.it.hpe.com [16.230.97.200]) by mx0a-002e3701.pphosted.com (PPS) with ESMTPS id 4cu8ercx6m-1 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Wed, 11 Mar 2026 18:11:24 +0000 (GMT) Received: from p1lg14886.dc01.its.hpecorp.net (unknown [10.119.18.237]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by p1lg14879.it.hpe.com (Postfix) with ESMTPS id 184A1D28A; Wed, 11 Mar 2026 18:11:24 +0000 (UTC) Received: from hpe.com (unknown [16.231.227.36]) by p1lg14886.dc01.its.hpecorp.net (Postfix) with ESMTP id A3A4A8118FF; Wed, 11 Mar 2026 18:11:23 +0000 (UTC) From: nick.hawkins@hpe.com To: ulf.hansson@linaro.org, adrian.hunter@intel.com, jszhang@kernel.org Cc: robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, shawn.lin@rock-chips.com, linux-mmc@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Nick Hawkins Subject: [PATCH v3 1/2] dt-bindings: mmc: snps,dwcmshc-sdhci: add HPE GSC dwcmshc compatible Date: Wed, 11 Mar 2026 13:11:11 -0500 Message-Id: <20260311181112.1700667-2-nick.hawkins@hpe.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260311181112.1700667-1-nick.hawkins@hpe.com> References: <20260311181112.1700667-1-nick.hawkins@hpe.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Proofpoint-ORIG-GUID: LaCIwzSuRPniJTNpCRQtcU7Ul6GWf_Ub X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwMzExMDE1MyBTYWx0ZWRfX1HAceFIx1oN7 c4qtI6dhzm/JOIX8Jh9UUMLE7tP2p+fvPvDQEt29X2qOLdhbwtZFEfjYu1SscPo3Cm8Caarx4CH jfDlf+nVBeUbnd+xnObDJklZQ1mxdp9Wbotnb8pagOFG/WaM/l0ozth4MMjgp011zHdimFwrWsF EM/iwicVN7+lfm7j+a3TqmbkinrTpUXO6wJn5UaYymruu6KAkT9dCWX2NiF/Vd9OzpJS7lL4uFE EvzuttBfoFhEd8zLWelUd5/tT1pt0wQ50Lhg7VY81/FU70bwGi2TgV+4b6ceM81u2wjPH4bAEgO psQfbxs3NCAHFm55kW22ACrnwzelT0vRrGjju3FG/m6Q/roFMgJTuj0C3VgBuWsv8pHuIfqTahu arPocTWyOqLPU3V3ac2AIoMPgGbBwJ+qV55jKnMG8tu6K/Hi3Nek/iTPAYWngtJuQQD0T0xX7hm ehwnHm1toS5xtMjGSLQ== X-Authority-Analysis: v=2.4 cv=bdlmkePB c=1 sm=1 tr=0 ts=69b1b04c cx=c_pps a=5jkVtQsCUlC8zk5UhkBgHg==:117 a=5jkVtQsCUlC8zk5UhkBgHg==:17 a=Yq5XynenixoA:10 a=VkNPw1HP01LnGYTKEx00:22 a=gQcMVamqm3wCPoSYhaRC:22 a=6_mrDcixewTG61oOsKN3:22 a=MvuuwTCpAAAA:8 a=Un5EUvwKq7LZpnUfPCQA:9 X-Proofpoint-GUID: LaCIwzSuRPniJTNpCRQtcU7Ul6GWf_Ub X-HPE-SCL: -1 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.51,FMLib:17.12.100.49 definitions=2026-03-11_02,2026-03-09_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 phishscore=0 lowpriorityscore=0 bulkscore=0 adultscore=0 impostorscore=0 malwarescore=0 suspectscore=0 clxscore=1011 priorityscore=1501 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2602130000 definitions=main-2603110153 Content-Type: text/plain; charset="utf-8" From: Nick Hawkins Add the 'hpe,gsc-dwcmshc' compatible string for the HPE GSC (ARM64 Cortex-A53) BMC SoC eMMC controller. The HPE GSC requires access to the MSHCCS register in the SoC system register block to configure SCG sync disable (bit 18) for HS200 RX delay-line phase selection. The existing 'hpe,gxp-sysreg' syscon phandle is required for this compatible to access MSHCCS via regmap. The HPE GSC eMMC interface only exposes a single 'core' clock (no bus clock), so clocks/clock-names are constrained to a single item. Add an example node with the hpe,gxp-sysreg syscon reference. Signed-off-by: Nick Hawkins --- .../bindings/mmc/snps,dwcmshc-sdhci.yaml | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/Documentation/devicetree/bindings/mmc/snps,dwcmshc-sdhci.yaml = b/Documentation/devicetree/bindings/mmc/snps,dwcmshc-sdhci.yaml index 7e7c55dc2440..74734d46c70d 100644 --- a/Documentation/devicetree/bindings/mmc/snps,dwcmshc-sdhci.yaml +++ b/Documentation/devicetree/bindings/mmc/snps,dwcmshc-sdhci.yaml @@ -23,6 +23,7 @@ properties: - const: sophgo,sg2044-dwcmshc - const: sophgo,sg2042-dwcmshc - enum: + - hpe,gsc-dwcmshc - rockchip,rk3568-dwcmshc - rockchip,rk3588-dwcmshc - snps,dwcmshc-sdhci @@ -77,6 +78,13 @@ properties: description: Specifies the drive impedance in Ohm. enum: [33, 40, 50, 66, 100] =20 + hpe,gxp-sysreg: + $ref: /schemas/types.yaml#/definitions/phandle + description: + Phandle to the HPE GXP SoC system register block (syscon). + The driver accesses the MSHCCS register at offset 0x110 within + this block to configure clock synchronisation for HS200 tuning. + required: - compatible - reg @@ -87,6 +95,23 @@ required: allOf: - $ref: mmc-controller.yaml# =20 + - if: + properties: + compatible: + contains: + const: hpe,gsc-dwcmshc + + then: + properties: + clocks: + items: + - description: core clock + clock-names: + items: + - const: core + required: + - hpe,gxp-sysreg + - if: properties: compatible: @@ -190,5 +215,16 @@ examples: #address-cells =3D <1>; #size-cells =3D <0>; }; + - | + mmc@c0100000 { + compatible =3D "hpe,gsc-dwcmshc"; + reg =3D <0xc0100000 0x1000>; + interrupts =3D <0 17 0x4>; + clocks =3D <&emmcclk>; + clock-names =3D "core"; + hpe,gxp-sysreg =3D <&soc_ctrl>; + bus-width =3D <8>; + non-removable; + }; =20 ... --=20 2.34.1 From nobody Tue Apr 7 19:50:38 2026 Received: from mx0b-002e3701.pphosted.com (mx0b-002e3701.pphosted.com [148.163.143.35]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CB7A03E6DE8; Wed, 11 Mar 2026 18:11:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.143.35 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773252717; cv=none; b=t4oS6Ff9phhJ2UDGupWRYrDZSjCoplcUF51eQ6/xm7taM8DfPKFrahpYiIjDYpxto1zcptLSLRVhtadKTndu2hMVBAasXkDKhvLhQMw+G+90cxa54MIGvHodVEZ+os/CxlDipqyK81UGTeF9Lc4mPbrbqMzdAk5CuP72AmHQd7I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773252717; c=relaxed/simple; bh=cOS7SxwXQcw9xyJKwAv0JFN3B4eq0pT4Y8KEhAl2SGo=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=E8hZ+trZMhexi8R68mu1khKJ03re48O5rpgzDqmdrQKFdCb0qw/FICoRyz8nhoYRRIdsjJCfvvTaAeofY2urcQh5VI2xZtyqOfPRzPzrI1LdNx/YUopsjSPRjp7FKOKLhNPxNZ2GlPDRRFyRN3q/KsBAsopqbuKTbnoSrLheO+8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=hpe.com; spf=pass smtp.mailfrom=hpe.com; dkim=pass (2048-bit key) header.d=hpe.com header.i=@hpe.com header.b=AbPZABrv; arc=none smtp.client-ip=148.163.143.35 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=hpe.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=hpe.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=hpe.com header.i=@hpe.com header.b="AbPZABrv" Received: from pps.filterd (m0134425.ppops.net [127.0.0.1]) by mx0b-002e3701.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 62BFwGqp1273755; Wed, 11 Mar 2026 18:11:29 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=hpe.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pps0720; bh=IWj0Vb/hZDmv4 /LVwZgLq5W9J9T6HnGYcqIHjUrb/EQ=; b=AbPZABrv//s3yhSLW+AL6OdvSsl4D gal6FD7YWYnUMOJF4OUA0+UxE9q25gwvbTgrhjp9YXPDG4HtSd4rGtAxo+XoRI5W 33wzrDlQbDtzzZhyu68kzbnOHT7Vb+kXczrbdlyPDPiVF29oyUcmASpwAqYSxNs7 0wTXnLACjGhx0na0oQ3MI/HHAjlKkGY21ERGUW2pI19cCO0O2BaqPlgcvYiK1Dg1 QESRp7mZRBywdOAfwXrCHHFY6GaObSjyMocDwnRnuVQ2q9na11hJhLJg3DOpcfWA Nu94AhzCrpWIjHn9Uu6YqMMk8Ix+xTSKU1ThFEUXYFZQFxViybwARZX5A== Received: from p1lg14878.it.hpe.com (p1lg14878.it.hpe.com [16.230.97.204]) by mx0b-002e3701.pphosted.com (PPS) with ESMTPS id 4cubgm1sje-1 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Wed, 11 Mar 2026 18:11:29 +0000 (GMT) Received: from p1lg14886.dc01.its.hpecorp.net (unknown [10.119.18.237]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by p1lg14878.it.hpe.com (Postfix) with ESMTPS id 35D7AD16B; Wed, 11 Mar 2026 18:11:26 +0000 (UTC) Received: from hpe.com (unknown [16.231.227.36]) by p1lg14886.dc01.its.hpecorp.net (Postfix) with ESMTP id F1421811A47; Wed, 11 Mar 2026 18:11:25 +0000 (UTC) From: nick.hawkins@hpe.com To: ulf.hansson@linaro.org, adrian.hunter@intel.com, jszhang@kernel.org Cc: robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, shawn.lin@rock-chips.com, linux-mmc@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Nick Hawkins Subject: [PATCH v3 2/2] mmc: sdhci-of-dwcmshc: Add HPE GSC eMMC support Date: Wed, 11 Mar 2026 13:11:12 -0500 Message-Id: <20260311181112.1700667-3-nick.hawkins@hpe.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260311181112.1700667-1-nick.hawkins@hpe.com> References: <20260311181112.1700667-1-nick.hawkins@hpe.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwMzExMDE1MyBTYWx0ZWRfX9vYzRYOgfGSV +170lEU2lj/k88hWY28Q6Pk8LNWAIwzF2eP53K17X/YoZ1HZiE0RydbIsKmgK3Vv8s346HZ4FO7 JbwTE3ugqC9dxz2NUOvi+SsuT5qDX8NX6lpDUE9vcguDYttPfycb3P7T1+/0LM6YDAH52gxGsSd JVvjC+jamfVIJSKIPiIFtyCscr6tlPTHgckGU1a6bx/+de5DKtgErWbN8zdZh/BI69sguq6vjD/ WT7eeEMlQGVLi4bUj738aZyKeMaxtix/BXXZeOOfGqzNTFIXaSwAKbKbWMGHlKz/1J0ngKhxSht AGZSSNoXpJPoyCZWDyfeThVKyTTI1gfuhEr9Y8N9NIj/A+7t2B0ndUqEs6faopaNA9LsC0jrpv+ wnMJfCKRVd2o5GDm8NFQYD308+1SSvi2Tu7fjl1SnEq95RfWU4Qe32vfoWD0eZ6ai0L9omCRyUY 0IQez+Z22SfLHZRmIfQ== X-Authority-Analysis: v=2.4 cv=ebUwvrEH c=1 sm=1 tr=0 ts=69b1b051 cx=c_pps a=UObrlqRbTUrrdMEdGJ+KZA==:117 a=UObrlqRbTUrrdMEdGJ+KZA==:17 a=Yq5XynenixoA:10 a=VkNPw1HP01LnGYTKEx00:22 a=gQcMVamqm3wCPoSYhaRC:22 a=ZSrvDirOKP4VPF05hnFf:22 a=MvuuwTCpAAAA:8 a=gIu2JzmVZeEO0Gw7ChAA:9 X-Proofpoint-ORIG-GUID: R4EtAFWwkZifJSCPnaiHvxbYuOClDfLs X-Proofpoint-GUID: R4EtAFWwkZifJSCPnaiHvxbYuOClDfLs X-HPE-SCL: -1 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.51,FMLib:17.12.100.49 definitions=2026-03-11_02,2026-03-09_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 phishscore=0 bulkscore=0 adultscore=0 spamscore=0 lowpriorityscore=0 clxscore=1011 suspectscore=0 impostorscore=0 malwarescore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2602130000 definitions=main-2603110153 Content-Type: text/plain; charset="utf-8" From: Nick Hawkins Add support for the eMMC controller integrated in the HPE GSC (ARM64 Cortex-A53) BMC SoC under the new 'hpe,gsc-dwcmshc' compatible string. The HPE GSC eMMC controller is based on the DesignWare Cores MSHC IP but requires several platform-specific adjustments: Clock mux (dwcmshc_hpe_set_clock): The GSC SoC wires SDHCI_CLOCK_CONTROL.freq_sel directly to a clock mux rather than a divider. Forcing freq_sel =3D 1 when the requested clock is 200 MHz (HS200) selects the correct high-speed clock source. Using the generic sdhci_set_clock() would otherwise leave the mux on the wrong source after tuning. Auto-tuning / vendor config (dwcmshc_hpe_vendor_specific): Disables the command-conflict check (DWCMSHC_HOST_CTRL3 BIT(0)) and programs the ATCTRL register using existing AT_CTRL_* macros: AT_CTRL_AT_EN auto-tuning circuit enable AT_CTRL_SWIN_TH_EN sampling window threshold enable AT_CTRL_TUNE_CLK_STOP_EN tune-clock-stop enable PRE_CHANGE_DLY =3D 3 pre-change delay POST_CHANGE_DLY =3D 3 post-change delay SWIN_TH_VAL =3D 2 sampling window threshold This combination is required for reliable HS200 signal integrity on the GSC PCB trace topology. Reset (dwcmshc_hpe_reset): Calls sdhci_reset(), re-applies the vendor config above, and then sets DWCMSHC_CARD_IS_EMMC unconditionally. The GSC controller clears this bit on every reset; leaving it clear causes card-detect mis-identification on an eMMC-only slot. UHS signaling (dwcmshc_hpe_set_uhs_signaling): Wraps dwcmshc_set_uhs_signaling() and unconditionally sets CARD_IS_EMMC for all timing modes, not just HS400. Init (dwcmshc_hpe_gsc_init): Obtains the SoC register block via the 'hpe,gxp-sysreg' syscon phandle and sets SCGSyncDis (BIT(18)) in MSHCCS (offset 0x110) to allow the HS200 RX delay lines to settle while the card clock is stopped during auto-tuning. Enables SDHCI v4 mode. Quirks: SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN: base clock not advertised in capabilities; must be obtained from the DTS 'clocks' property. SDHCI_QUIRK2_PRESET_VALUE_BROKEN: preset-value registers are not populated in the GSC ROM. All HPE-specific code is isolated to the new hpe_gsc_init / hpe_ops / hpe_gsc_pdata symbols. No existing platform (Rockchip, T-Head, sg2042, etc.) is affected. Signed-off-by: Nick Hawkins --- drivers/mmc/host/sdhci-of-dwcmshc.c | 149 ++++++++++++++++++++++++++++ 1 file changed, 149 insertions(+) diff --git a/drivers/mmc/host/sdhci-of-dwcmshc.c b/drivers/mmc/host/sdhci-o= f-dwcmshc.c index 2b75a36c096b..46662071cc61 100644 --- a/drivers/mmc/host/sdhci-of-dwcmshc.c +++ b/drivers/mmc/host/sdhci-of-dwcmshc.c @@ -1245,6 +1245,132 @@ static int sg2042_init(struct device *dev, struct s= dhci_host *host, ARRAY_SIZE(clk_ids), clk_ids); } =20 +/* HPE GSC-specific vendor configuration: disable command conflict check + * and program Auto-Tuning Control register. + */ +static void dwcmshc_hpe_vendor_specific(struct sdhci_host *host) +{ + struct sdhci_pltfm_host *pltfm_host =3D sdhci_priv(host); + struct dwcmshc_priv *dwc_priv =3D sdhci_pltfm_priv(pltfm_host); + u32 atctrl; + u8 extra; + + extra =3D sdhci_readb(host, dwc_priv->vendor_specific_area1 + DWCMSHC_HOS= T_CTRL3); + extra &=3D ~BIT(0); + sdhci_writeb(host, extra, dwc_priv->vendor_specific_area1 + DWCMSHC_HOST_= CTRL3); + + atctrl =3D AT_CTRL_AT_EN | AT_CTRL_SWIN_TH_EN | AT_CTRL_TUNE_CLK_STOP_EN | + FIELD_PREP(AT_CTRL_PRE_CHANGE_DLY_MASK, 3) | + FIELD_PREP(AT_CTRL_POST_CHANGE_DLY_MASK, AT_CTRL_POST_CHANGE_DLY) | + FIELD_PREP(AT_CTRL_SWIN_TH_VAL_MASK, 2); + sdhci_writel(host, atctrl, dwc_priv->vendor_specific_area1 + DWCMSHC_EMMC= _ATCTRL); +} + +static void dwcmshc_hpe_reset(struct sdhci_host *host, u8 mask) +{ + struct sdhci_pltfm_host *pltfm_host =3D sdhci_priv(host); + struct dwcmshc_priv *dwc_priv =3D sdhci_pltfm_priv(pltfm_host); + u16 ctrl; + + dwcmshc_reset(host, mask); + + dwcmshc_hpe_vendor_specific(host); + + /* HPE GSC eMMC always needs CARD_IS_EMMC set after reset */ + ctrl =3D sdhci_readw(host, dwc_priv->vendor_specific_area1 + DWCMSHC_EMMC= _CONTROL); + ctrl |=3D DWCMSHC_CARD_IS_EMMC; + sdhci_writew(host, ctrl, dwc_priv->vendor_specific_area1 + DWCMSHC_EMMC_C= ONTROL); +} + +static void dwcmshc_hpe_set_uhs_signaling(struct sdhci_host *host, + unsigned int timing) +{ + struct sdhci_pltfm_host *pltfm_host =3D sdhci_priv(host); + struct dwcmshc_priv *priv =3D sdhci_pltfm_priv(pltfm_host); + u16 ctrl; + + dwcmshc_set_uhs_signaling(host, timing); + + /* HPE GSC: always set CARD_IS_EMMC for all timing modes */ + ctrl =3D sdhci_readw(host, priv->vendor_specific_area1 + DWCMSHC_EMMC_CON= TROL); + ctrl |=3D DWCMSHC_CARD_IS_EMMC; + sdhci_writew(host, ctrl, priv->vendor_specific_area1 + DWCMSHC_EMMC_CONTR= OL); +} + +/* + * HPE GSC eMMC controller clock setup. + * + * The GSC SoC wires the freq_sel field of SDHCI_CLOCK_CONTROL directly to= a + * clock mux rather than a divider. Force freq_sel =3D 1 when running at + * 200 MHz (HS200) so the mux selects the correct clock source. + */ +static void dwcmshc_hpe_set_clock(struct sdhci_host *host, unsigned int cl= ock) +{ + u16 clk; + + host->mmc->actual_clock =3D 0; + + sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL); + + if (clock =3D=3D 0) + return; + + clk =3D sdhci_calc_clk(host, clock, &host->mmc->actual_clock); + + if (host->mmc->actual_clock =3D=3D 200000000) + clk |=3D (1 << SDHCI_DIVIDER_SHIFT); + + sdhci_enable_clk(host, clk); +} + +/* + * HPE GSC eMMC controller init. + * + * The GSC SoC requires configuring MSHCCS. Bit 18 (SCGSyncDis) disables = clock + * synchronisation for phase-select values going to the HS200 RX delay lin= es, + * allowing the card clock to be stopped while the delay selection settles= and + * the phase shift is applied. This must be used together with the ATCTRL + * settings programmed in dwcmshc_hpe_vendor_specific(): + * AT_CTRL_R.TUNE_CLK_STOP_EN =3D 0x1 + * AT_CTRL_R.POST_CHANGE_DLY =3D 0x3 + * AT_CTRL_R.PRE_CHANGE_DLY =3D 0x3 + * + * The DTS node provides a syscon phandle ('hpe,gxp-sysreg') to access + * this register at offset 0x110 within the SoC control block. + */ +#define HPE_GSC_MSHCCS_OFFSET 0x110 +#define HPE_GSC_MSHCCS_SCGSYNCDIS BIT(18) + +static int dwcmshc_hpe_gsc_init(struct device *dev, struct sdhci_host *hos= t, + struct dwcmshc_priv *dwc_priv) +{ + struct regmap *soc_ctrl; + int ret; + + /* Disable cmd conflict check and configure auto-tuning */ + dwcmshc_hpe_vendor_specific(host); + + /* Look up the GXP sysreg syscon for MSHCCS access */ + soc_ctrl =3D syscon_regmap_lookup_by_phandle(dev->of_node, "hpe,gxp-sysre= g"); + if (IS_ERR(soc_ctrl)) { + dev_err(dev, "failed to get hpe,gxp-sysreg syscon\n"); + return PTR_ERR(soc_ctrl); + } + + /* Set SCGSyncDis (bit 18) to disable sync on HS200 RX delay lines */ + ret =3D regmap_update_bits(soc_ctrl, HPE_GSC_MSHCCS_OFFSET, + HPE_GSC_MSHCCS_SCGSYNCDIS, + HPE_GSC_MSHCCS_SCGSYNCDIS); + if (ret) { + dev_err(dev, "failed to set SCGSyncDis in MSHCCS\n"); + return ret; + } + + sdhci_enable_v4_mode(host); + + return 0; +} + static void sdhci_eic7700_set_clock(struct sdhci_host *host, unsigned int = clock) { struct sdhci_pltfm_host *pltfm_host =3D sdhci_priv(host); @@ -1834,6 +1960,25 @@ static const struct dwcmshc_pltfm_data sdhci_dwcmshc= _eic7700_pdata =3D { .init =3D eic7700_init, }; =20 +static const struct sdhci_ops sdhci_dwcmshc_hpe_ops =3D { + .set_clock =3D dwcmshc_hpe_set_clock, + .set_bus_width =3D sdhci_set_bus_width, + .set_uhs_signaling =3D dwcmshc_hpe_set_uhs_signaling, + .get_max_clock =3D dwcmshc_get_max_clock, + .reset =3D dwcmshc_hpe_reset, + .adma_write_desc =3D dwcmshc_adma_write_desc, + .irq =3D dwcmshc_cqe_irq_handler, +}; + +static const struct dwcmshc_pltfm_data sdhci_dwcmshc_hpe_gsc_pdata =3D { + .pdata =3D { + .ops =3D &sdhci_dwcmshc_hpe_ops, + .quirks =3D SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN, + .quirks2 =3D SDHCI_QUIRK2_PRESET_VALUE_BROKEN, + }, + .init =3D dwcmshc_hpe_gsc_init, +}; + static const struct cqhci_host_ops dwcmshc_cqhci_ops =3D { .enable =3D dwcmshc_sdhci_cqe_enable, .disable =3D sdhci_cqe_disable, @@ -1942,6 +2087,10 @@ static const struct of_device_id sdhci_dwcmshc_dt_id= s[] =3D { .compatible =3D "eswin,eic7700-dwcmshc", .data =3D &sdhci_dwcmshc_eic7700_pdata, }, + { + .compatible =3D "hpe,gsc-dwcmshc", + .data =3D &sdhci_dwcmshc_hpe_gsc_pdata, + }, {}, }; MODULE_DEVICE_TABLE(of, sdhci_dwcmshc_dt_ids); --=20 2.34.1