From patchwork Mon Jun 17 16:44:42 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Andr=C3=A9_Draszik?= X-Patchwork-Id: 13701048 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 7F4E3C27C79 for ; Mon, 17 Jun 2024 16:45:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:In-Reply-To:References:Message-Id :MIME-Version:Subject:Date:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=W5aCt1SXVZPly3uC1pDECVlUJwkrnigPjnWeBNJsFpM=; b=KiZUMlIOviFMLG yUO3mVqj1noq+y2qvRbEpGjwjunAtyXQFa0V7AP6SopxQkxBv9UTYIlh0yeF+9WlL5OOh1TjE2Tos CZbmBqmqvENgNr4aFHg9W5s15JNYoYMMRcYNao6PvCLsiI+dzXT2phUA9a6aKOOZ1LFORW9MxfXu/ RqcMOAX2bWhx9foWT16X2tIB4crbWwDCCg+nig1K0PelvqGn35GaTqGOkouBMPGRGOu53f1pX+E9U r9UVxmEyRpJHorzj0cq7NS9ks0gyS7p1iws+QU7Y2ZO1Z/BGZEyiK1H5zG4T+z8cw7NEWMDl0+rRQ /K9q818GRg/Ws0tmHVqA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1sJFTt-0000000Bn8s-3i6Y; Mon, 17 Jun 2024 16:45:21 +0000 Received: from mail-ej1-x629.google.com ([2a00:1450:4864:20::629]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1sJFTl-0000000Bn0W-1x4j for linux-phy@lists.infradead.org; Mon, 17 Jun 2024 16:45:17 +0000 Received: by mail-ej1-x629.google.com with SMTP id a640c23a62f3a-a6f09eaf420so531080566b.3 for ; Mon, 17 Jun 2024 09:45:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1718642711; x=1719247511; darn=lists.infradead.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=wYub/RSqb8Rt0WMbKUbwYUc1IlmByIMY38T9EwCcE9I=; b=r+4IhVX5QrwIlNoe+uLYcggIGGqJqT/B9tFRxqJJgLOQAmJWUNkeSfqq6DdkIf5ayZ OHLV431jNDhlsWkkUqxhTbRpVhEsRF5+PNKVGAxp/6XSMVCvSG7N4F23o0ynt2uoJcHA muqGA+wg1gDriAZRKn2ucIhKkcEbqof95VGWRQwEQH3MS/GbxJ7QsRqDI+Q1KWsah+MR XwtgQGq3Y0kB2EOPgY01+gL4+AI7Au65q2s61lg95JSCeRi8qrUpETCWggeH3bsiFXmZ NRQdQ8W4MAIgOm1ZPNKrdl1vfQQP7d664E4CWHGgGh1/mPFIfgUw6C2bHCRP+XWurWpF Hbow== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718642711; x=1719247511; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=wYub/RSqb8Rt0WMbKUbwYUc1IlmByIMY38T9EwCcE9I=; b=v7T0UFHYRIW4rqCI/zqPakeIouPQSl2Bi89uMSR434JItQgupXEfm6Zueole/eHBjj rozq7VPi4Rqrhxyfw4VzxJbDUgX5IA9GJib8ubFiAFkhdNy5Xa5F5ZdW8SkMTRHs5p1c 0/ulcHwsh41CD6GblMVdPqBeK3etWIKQ1l+Zn7yed2TwNYhv2kwu/WTYGQTAynXwlFon YOyOGmB3LltTLMnr3DetlGLyedASYewCAFIdNjtwKIqYc1OCw6jUqqJpCH3P4wmWESZC XUaeomnTVnPFmRyEEX6cCOalRPMeLjrvQaaw2mFNKpIe6YRJvJVrjpNQ3K6zQoIypNX5 EP2A== X-Forwarded-Encrypted: i=1; AJvYcCV88no0abyS6qPKz04Eb7mGkBzT3FYhJLiJsqESCZHTTz5kQ/hcEABm7hSlYKqb00O5DMenQQpcpS/+ZSmqQtpY5cy0Vmv2fzTJJwL2HA== X-Gm-Message-State: AOJu0YwOpvU4jQsAyyzsIhQcVC1hv299zjt3xGM5WiwWO+/lGsM7jgOt qrV8kx+Z+tCWOCJrHipOGVBLjyOp9WxmLj87M4883OLNHjP2CqBAusx1aDFzex4= X-Google-Smtp-Source: AGHT+IHv0ukUOJDUc8BdVmzy7hmS+1oi69QOBMofoFgHRV33yO4xcJwLLTOoJRJaGOBhau06DyTjJg== X-Received: by 2002:a17:907:6d25:b0:a6e:a97c:fc9a with SMTP id a640c23a62f3a-a6f60cef313mr888080866b.8.1718642711038; Mon, 17 Jun 2024 09:45:11 -0700 (PDT) Received: from puffmais.c.googlers.com (8.239.204.35.bc.googleusercontent.com. [35.204.239.8]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-a6f56f4170bsm527139966b.157.2024.06.17.09.45.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Jun 2024 09:45:10 -0700 (PDT) From: =?utf-8?q?Andr=C3=A9_Draszik?= Date: Mon, 17 Jun 2024 17:44:42 +0100 Subject: [PATCH v3 1/6] dt-bindings: phy: samsung,usb3-drd-phy: add gs101 compatible MIME-Version: 1.0 Message-Id: <20240617-usb-phy-gs101-v3-1-b66de9ae7424@linaro.org> References: <20240617-usb-phy-gs101-v3-0-b66de9ae7424@linaro.org> In-Reply-To: <20240617-usb-phy-gs101-v3-0-b66de9ae7424@linaro.org> To: Vinod Koul , Kishon Vijay Abraham I , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Peter Griffin , Marek Szyprowski , Sylwester Nawrocki , Alim Akhtar , Sam Protsenko Cc: Krzysztof Kozlowski , Tudor Ambarus , Will McVicker , Roy Luo , kernel-team@android.com, linux-phy@lists.infradead.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-samsung-soc@vger.kernel.org, =?utf-8?q?Andr=C3=A9_Draszik?= X-Mailer: b4 0.13.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240617_094514_005235_2D9A3411 X-CRM114-Status: UNSURE ( 9.55 ) X-CRM114-Notice: Please train this message. X-BeenThere: linux-phy@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux Phy Mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-phy" Errors-To: linux-phy-bounces+linux-phy=archiver.kernel.org@lists.infradead.org Add a dedicated google,gs101-usb31drd-phy compatible for Google Tensor gs101 SoC. It needs additional clocks enabled for register access, and additional memory regions (PCS & PMA) are required for successful configuration. It also requires various power supplies (regulators) for the internal circuitry to work. The required voltages are: * pll-supply: 0.85V * dvdd-usb20-supply: 0.85V (+10%, -7%) * vddh-usb20-supply: 1.8V (+10%, -7%) * vdd33-usb20-supply: 3.3V (+10%, -7%) * vdda-usbdp-supply: 0.85V * vddh-usbdp-supply: 1.8V Signed-off-by: André Draszik Reviewed-by: Krzysztof Kozlowski Reviewed-by: Peter Griffin --- v3: * drop descriptions of reg items (Krzysztof) Rather than coming up with another description for the reg items, I opted to fully drop the descriptions from the reg items as reg-names describes these already using the standard, well-known abbreviations. * add required power supplies v2: avoid having nested else/if, and instead change the existing 'else' to explicitly state the platforms using 'if' --- .../bindings/phy/samsung,usb3-drd-phy.yaml | 77 +++++++++++++++++++++- 1 file changed, 75 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml index 452e584d9812..16321cdd4919 100644 --- a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml +++ b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml @@ -25,6 +25,7 @@ description: | properties: compatible: enum: + - google,gs101-usb31drd-phy - samsung,exynos5250-usbdrd-phy - samsung,exynos5420-usbdrd-phy - samsung,exynos5433-usbdrd-phy @@ -57,7 +58,15 @@ properties: the OF graph bindings specified. reg: - maxItems: 1 + minItems: 1 + maxItems: 3 + + reg-names: + minItems: 1 + items: + - const: phy + - const: pcs + - const: pma samsung,pmu-syscon: $ref: /schemas/types.yaml#/definitions/phandle @@ -72,6 +81,19 @@ properties: description: VBUS Boost 5V power source. + pll-supply: + description: Power supply for the USB PLL. + dvdd-usb20-supply: + description: DVDD power supply for the USB 2.0 phy. + vddh-usb20-supply: + description: VDDh power supply for the USB 2.0 phy. + vdd33-usb20-supply: + description: 3.3V power supply for the USB 2.0 phy. + vdda-usbdp-supply: + description: VDDa power supply for the USB DP phy. + vddh-usbdp-supply: + description: VDDh power supply for the USB DP phy. + required: - compatible - clocks @@ -81,6 +103,40 @@ required: - samsung,pmu-syscon allOf: + - if: + properties: + compatible: + contains: + const: google,gs101-usb31drd-phy + then: + properties: + clocks: + items: + - description: Gate of main PHY clock + - description: Gate of PHY reference clock + - description: Gate of control interface AXI clock + - description: Gate of control interface APB clock + - description: Gate of SCL APB clock + clock-names: + items: + - const: phy + - const: ref + - const: ctrl_aclk + - const: ctrl_pclk + - const: scl_pclk + reg: + minItems: 3 + reg-names: + minItems: 3 + required: + - reg-names + - pll-supply + - dvdd-usb20-supply + - vddh-usb20-supply + - vdd33-usb20-supply + - vdda-usbdp-supply + - vddh-usbdp-supply + - if: properties: compatible: @@ -100,7 +156,20 @@ allOf: - const: phy_utmi - const: phy_pipe - const: itp - else: + reg: + maxItems: 1 + reg-names: + maxItems: 1 + + - if: + properties: + compatible: + contains: + enum: + - samsung,exynos5250-usbdrd-phy + - samsung,exynos5420-usbdrd-phy + - samsung,exynos850-usbdrd-phy + then: properties: clocks: minItems: 2 @@ -109,6 +178,10 @@ allOf: items: - const: phy - const: ref + reg: + maxItems: 1 + reg-names: + maxItems: 1 additionalProperties: false From patchwork Mon Jun 17 16:44:43 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Andr=C3=A9_Draszik?= X-Patchwork-Id: 13701047 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id ACB98C2BA18 for ; Mon, 17 Jun 2024 16:45:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:In-Reply-To:References:Message-Id :MIME-Version:Subject:Date:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=9XsSex1ytT9ciqjtaEGAG+/p+r1QJgpXaB11KKP/BTc=; b=lyt5i1fem2dwny Lpnwijeu0BcQKB/3RkntUTZb5BSo36rg4ZnYFiZJprTw+MLOn3CNzbXeK9Ti1zNKRJFA1TSDWQVCk ZZ83Ha3p8azdQNkrsCBEQuHLx63FNIPlz6UFgOpMj5snSIr/kcPVUpFT+do5wvboe5VsHIkzlUw+r KWJ1JuzxzObmnyH+xCy7LBzcuyREoXFZ0f1MOp+z2StiNMHIO0Xx7l6kMbTAHFjDMhlkZiDhYhMFv QyExheZYxBL5ckypteoDCP07MX9jZQWrOe2zhNgzGMuaKG1Nc5J1kPrpJ949Gx++4RcEcrTNavdxn UlXP4XcXmeFBClAdgr1A==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1sJFTt-0000000Bn89-0d7W; Mon, 17 Jun 2024 16:45:21 +0000 Received: from mail-ej1-x629.google.com ([2a00:1450:4864:20::629]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1sJFTl-0000000Bn0m-2APl for linux-phy@lists.infradead.org; Mon, 17 Jun 2024 16:45:17 +0000 Received: by mail-ej1-x629.google.com with SMTP id a640c23a62f3a-a6f936d2ba1so28556266b.0 for ; Mon, 17 Jun 2024 09:45:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1718642712; x=1719247512; darn=lists.infradead.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=ThsTojdQQ8zSHFhNOOxiXRSOPUFKMTWzQLxLd3s8TBU=; b=vp5CHSJVxg2nbyr/yBtPeLXjE86OlOmq5IARQZuSesl7GFmE1lub5ZZxI1blDCCeRG 95N124hid+1kIv7Z79L3JTVOtBi0kmDEfV0ANEUKK3kOBWbzp7CDBVkglXQYrCfzDaf5 haDLa3oZqLrlEwUIyUK2JpDiPkw1rg9bFZeBN4qWjyH5XAnIAn8KQBPvhgtjFDm3ypgW uL1xuVrSW91w6vZIGCMHeYGXOI/aZPJg9VrQo6CRg/bt2IuPVzDgeRCbKmVZVhBnl8hM WUq7SdBZee0pIBorfoOpAT8bPuymzei90Sb629bhAEfVhHwaHz6cZtLlzQXbNAI/WdRt 2V+w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718642712; x=1719247512; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ThsTojdQQ8zSHFhNOOxiXRSOPUFKMTWzQLxLd3s8TBU=; b=hRFYe5JDShWT8150TU4dSJC05FcPI/R2pin1741uCG143Dv/CP3Ueyqh8+tNv0h62t 0+clcAPS2WwG2nko/ls6pQH9r3rg8IlfEBHjylsAyOZuvsyMvNbBWHVqit3abHcjCW9h YDNJV0o7etoi7N32KJox3tyK/ATYCyAXWRfweRMa+vm3gWwhdb94OuzwdeAxPde7wHbK hb6IVx8aRfx3prsccLn/+1fBzXjwKulJEbn74fdUk0PNZIGRpSFDjvetqQK/ZK79YUZ2 E86WazZp9JI4yCxXf+TuWw9MJqoC9JG18dH2+34hpRdccQ3XIN7dlt5dkBnmT44Usr4H oGcg== X-Forwarded-Encrypted: i=1; AJvYcCX1ImGmL9l7VW+MO55C4oahRnsCCfJDx/I+53lRBIwut8+VPLu1dNZwvHKg4Fv+zqD24VRZnP8cYXJaNsLDbNHmpvXI81AbdP9tgGSQlQ== X-Gm-Message-State: AOJu0YyrxY7YGOsG3W9pjcpfbXFKTpQkPidhl+Zpby7uJmeWFiPf2D+M 8C5z75pfYAh/xutbaq5gvACTAe5L3JT0raF5BkYHwUp/hQuqfqYad2Y+rrDtLmk= X-Google-Smtp-Source: AGHT+IFcJWeLyEHV3yWQ18wnmpR54ia9kKxwzabyy2RmlFFm5mvL5H8jtPPWb261kiLvundn45hNyg== X-Received: by 2002:a17:907:c249:b0:a6f:603a:d9e9 with SMTP id a640c23a62f3a-a6f94e29a83mr13525366b.10.1718642711493; Mon, 17 Jun 2024 09:45:11 -0700 (PDT) Received: from puffmais.c.googlers.com (8.239.204.35.bc.googleusercontent.com. [35.204.239.8]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-a6f56f4170bsm527139966b.157.2024.06.17.09.45.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Jun 2024 09:45:11 -0700 (PDT) From: =?utf-8?q?Andr=C3=A9_Draszik?= Date: Mon, 17 Jun 2024 17:44:43 +0100 Subject: [PATCH v3 2/6] phy: exynos5-usbdrd: support isolating HS and SS ports independently MIME-Version: 1.0 Message-Id: <20240617-usb-phy-gs101-v3-2-b66de9ae7424@linaro.org> References: <20240617-usb-phy-gs101-v3-0-b66de9ae7424@linaro.org> In-Reply-To: <20240617-usb-phy-gs101-v3-0-b66de9ae7424@linaro.org> To: Vinod Koul , Kishon Vijay Abraham I , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Peter Griffin , Marek Szyprowski , Sylwester Nawrocki , Alim Akhtar , Sam Protsenko Cc: Krzysztof Kozlowski , Tudor Ambarus , Will McVicker , Roy Luo , kernel-team@android.com, linux-phy@lists.infradead.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-samsung-soc@vger.kernel.org, =?utf-8?q?Andr=C3=A9_Draszik?= X-Mailer: b4 0.13.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240617_094514_003712_304BDAF5 X-CRM114-Status: GOOD ( 12.43 ) X-BeenThere: linux-phy@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux Phy Mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-phy" Errors-To: linux-phy-bounces+linux-phy=archiver.kernel.org@lists.infradead.org Some versions of this IP have been integrated using separate PMU power control registers for the HS and SS parts. One example is the Google Tensor gs101 SoC. Such SoCs can now set pmu_offset_usbdrd0_phy_ss in their exynos5_usbdrd_phy_drvdata for the SS phy to the appropriate value. The existing 'usbdrdphy' alias can not be used in this case because that is meant for determining the correct PMU offset if multiple distinct PHYs exist in the system (as opposed to one PHY with multiple isolators). Signed-off-by: André Draszik Tested-by: Will McVicker Reviewed-by: Peter Griffin Tested-by: Peter Griffin --- v3: use drv_data instead of phy_drd->drv_data for shorter lines --- drivers/phy/samsung/phy-exynos5-usbdrd.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c index 15be966b50ae..b7e2526f4c06 100644 --- a/drivers/phy/samsung/phy-exynos5-usbdrd.c +++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c @@ -186,6 +186,7 @@ struct exynos5_usbdrd_phy_drvdata { const struct exynos5_usbdrd_phy_config *phy_cfg; const struct phy_ops *phy_ops; u32 pmu_offset_usbdrd0_phy; + u32 pmu_offset_usbdrd0_phy_ss; u32 pmu_offset_usbdrd1_phy; bool has_common_clk_gate; }; @@ -1065,16 +1066,6 @@ static int exynos5_usbdrd_phy_probe(struct platform_device *pdev) if (channel < 0) dev_dbg(dev, "Not a multi-controller usbdrd phy\n"); - switch (channel) { - case 1: - pmu_offset = phy_drd->drv_data->pmu_offset_usbdrd1_phy; - break; - case 0: - default: - pmu_offset = phy_drd->drv_data->pmu_offset_usbdrd0_phy; - break; - } - /* Get Vbus regulators */ phy_drd->vbus = devm_regulator_get(dev, "vbus"); if (IS_ERR(phy_drd->vbus)) { @@ -1109,6 +1100,18 @@ static int exynos5_usbdrd_phy_probe(struct platform_device *pdev) phy_drd->phys[i].phy = phy; phy_drd->phys[i].index = i; phy_drd->phys[i].reg_pmu = reg_pmu; + switch (channel) { + case 1: + pmu_offset = drv_data->pmu_offset_usbdrd1_phy; + break; + case 0: + default: + pmu_offset = drv_data->pmu_offset_usbdrd0_phy; + if (i == EXYNOS5_DRDPHY_PIPE3 && drv_data + ->pmu_offset_usbdrd0_phy_ss) + pmu_offset = drv_data->pmu_offset_usbdrd0_phy_ss; + break; + } phy_drd->phys[i].pmu_offset = pmu_offset; phy_drd->phys[i].phy_cfg = &drv_data->phy_cfg[i]; phy_set_drvdata(phy, &phy_drd->phys[i]); From patchwork Mon Jun 17 16:44:44 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Andr=C3=A9_Draszik?= X-Patchwork-Id: 13701051 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 2370AC2BA18 for ; Mon, 17 Jun 2024 16:45:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:In-Reply-To:References:Message-Id :MIME-Version:Subject:Date:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=EJJuJeRlAphZ25cvdZV451E3oSiaif+OdHAL1v50a9g=; b=gWtHQfVXrfaUij 0AzqDOUH9krPlyCIPsDuL4mZhJ4ydiadTbl+naMiKNLapKGMoJFCynastQ0PIxiKpldfv5BwP0xI2 KnjP3LbUCvCUIbX7ROBqG0/cq8ujtcR3YwK2CUbo9wtsud9hWu2+46QuCr6XO8qVj/VcA+auNiFDh vzLJOrGLZnyAfjyDGjC1OVLAWslHehVQKSJzI13qkdgFBizwNhy3EKmQnaDQmhRRzyiZlEV5ER/Yl F4e9bKvuliCoYgb3sqZy6tI07KOtzG76sk2AJiXtZ5hXlzPS8VkQaUqe4Qmjs1vCKOBCaFyxJJ6hz hwacJGzRWv2MtKoSLyIw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1sJFUR-0000000BnR5-39Wn; Mon, 17 Jun 2024 16:45:55 +0000 Received: from mail-ed1-x534.google.com ([2a00:1450:4864:20::534]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1sJFTn-0000000Bn16-0IBn for linux-phy@lists.infradead.org; Mon, 17 Jun 2024 16:45:22 +0000 Received: by mail-ed1-x534.google.com with SMTP id 4fb4d7f45d1cf-57ca578ce8dso5266795a12.2 for ; Mon, 17 Jun 2024 09:45:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1718642713; x=1719247513; darn=lists.infradead.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=ZfbBcvTWg9v7Bbg+JkZfv+jRFiGBg9MQxpTsL00jJxg=; b=u5kYIOG1gQz8yF5gxcrfVmcpTCyf1iiYODzRpmcag+dEMcPGMc7uirXkdV2ziNGLoP /mz4dWbGTHci6FHzBuJuz2YiHsT6qA8WV/XUgHCo6PsddgKSwzDDxGdaPQEEJKhy7lor xgrINYUyTdb9+QXfhorKG3EusYhts99500dHIDHlWJyW2/t/ZRxT3HNcZFboo3WLqD/w S8Npb57WguPBmvojGqa921zHuflPAunM9CwGxFJFL3Twe7d2Vpig6zYOgUEfn6Z5ByrM PyMcoQwJIFogiS8lRbDTF465n1vU5BKSMERp2Dot/W0hSPFulkc6KxOk8ckIgMRJerna y2pA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718642713; x=1719247513; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ZfbBcvTWg9v7Bbg+JkZfv+jRFiGBg9MQxpTsL00jJxg=; b=Y9RWhwaGmrhFeTXjQLoPNWCrnhgAAZewJxUKjDiKVL2xo4kmgtWQq3A7/0ckgXI4Zu l+gcRWVsg0bQnTVKf6PAr4thSGyRUhZyLEzVJadatZXw4TfZKjFcxIFo+q+6a3/QI57C kbDcySFBC/AAB6XLo4PFvLDsUZryTVKQNiRWKo1oRhkh1dQX6tSvBPpyp3pFAg2fcGWk xxOsmGOTARNwEIjIRNyjI2P7MofwfMevU0VGm1XGPVav4YkKNYlRvs0bWp/LjZJYp1+2 JjnFsG0II9eajPzvWeFq4xdIuMu8xcimz8/LW8YnpXpKTa2R/kn5BvJOXfov5BtvJUyA C3IQ== X-Forwarded-Encrypted: i=1; AJvYcCVbhTCv36otDMCcCZcVKcI8trMNxIIkggVpT2ii2j2a/OQguSHJeqVel3XN74nZl3bJluBBWOA9vCHl8qvSCjlb5+aFotsV6k+cUJaFRg== X-Gm-Message-State: AOJu0YxFja6KLdrz64FtS4i/56XsitRGATLsq0cD4lMnd2WGGoQ7PgHA uz7C8eb/p+FbfMA7MA1BQbuR9UyZiA+4NRWKQT8ZtzWKhN/49APrcoDCXu4peJM= X-Google-Smtp-Source: AGHT+IFwqHuL/AFdrKJ5yS1y9SrBtKhrGrSio/O9IDSp5AUqAYl4zRsXzu5G8/8K7KBD2vk6PlyL9A== X-Received: by 2002:a17:906:d18f:b0:a6f:7c8:4fd6 with SMTP id a640c23a62f3a-a6f60bcbaadmr750030066b.0.1718642712613; Mon, 17 Jun 2024 09:45:12 -0700 (PDT) Received: from puffmais.c.googlers.com (8.239.204.35.bc.googleusercontent.com. [35.204.239.8]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-a6f56f4170bsm527139966b.157.2024.06.17.09.45.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Jun 2024 09:45:12 -0700 (PDT) From: =?utf-8?q?Andr=C3=A9_Draszik?= Date: Mon, 17 Jun 2024 17:44:44 +0100 Subject: [PATCH v3 3/6] phy: exynos5-usbdrd: convert core clocks to clk_bulk MIME-Version: 1.0 Message-Id: <20240617-usb-phy-gs101-v3-3-b66de9ae7424@linaro.org> References: <20240617-usb-phy-gs101-v3-0-b66de9ae7424@linaro.org> In-Reply-To: <20240617-usb-phy-gs101-v3-0-b66de9ae7424@linaro.org> To: Vinod Koul , Kishon Vijay Abraham I , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Peter Griffin , Marek Szyprowski , Sylwester Nawrocki , Alim Akhtar , Sam Protsenko Cc: Krzysztof Kozlowski , Tudor Ambarus , Will McVicker , Roy Luo , kernel-team@android.com, linux-phy@lists.infradead.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-samsung-soc@vger.kernel.org, =?utf-8?q?Andr=C3=A9_Draszik?= X-Mailer: b4 0.13.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240617_094515_418877_D1246C58 X-CRM114-Status: GOOD ( 23.04 ) X-BeenThere: linux-phy@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux Phy Mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-phy" Errors-To: linux-phy-bounces+linux-phy=archiver.kernel.org@lists.infradead.org Using the clk_bulk APIs, the clock handling for the core clocks becomes much simpler. No need to check any flags whether or not certain clocks exist or not. Further, we can drop the various handles to the individual clocks in the driver data and instead simply treat them all as one thing. So far, this driver assumes that all platforms have a clock "ref". It also assumes that the clocks "phy_pipe", "phy_utmi", and "itp" exist if the platform data "has_common_clk_gate" is set to true. It then goes and individually tries to acquire and enable and disable all the individual clocks one by one. Rather than relying on these implicit clocks and open-coding the clock handling, we can just explicitly spell out the clock names in the different device data and use that information to populate clk_bulk_data, allowing us to use the clk_bulk APIs for managing the clocks. As a side-effect, this change highlighted the fact that exynos5_usbdrd_phy_power_on() forgot to check the result of the clock enable calls. Using the clk_bulk APIs, the compiler now warns when return values are not checked - therefore add the necessary check instead of silently ignoring failures and continuing as if all is OK when it isn't. For consistency, also change a related dev_err() to dev_err_probe() in exynos5_usbdrd_phy_clk_handle() to get consistent error message formatting. Finally, exynos5_usbdrd_phy_clk_handle() prints an error message in all cases as necessary (except for -ENOMEM). There is no need to print another message in its caller (the probe() function), and printing errors during OOM conditions is usually discouraged. Drop the duplicated message in exynos5_usbdrd_phy_probe(). Signed-off-by: André Draszik Tested-by: Will McVicker Reviewed-by: Peter Griffin Tested-by: Peter Griffin --- drivers/phy/samsung/phy-exynos5-usbdrd.c | 129 +++++++++++++++---------------- 1 file changed, 61 insertions(+), 68 deletions(-) diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c index b7e2526f4c06..35b307dad2ee 100644 --- a/drivers/phy/samsung/phy-exynos5-usbdrd.c +++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c @@ -185,10 +185,11 @@ struct exynos5_usbdrd_phy_config { struct exynos5_usbdrd_phy_drvdata { const struct exynos5_usbdrd_phy_config *phy_cfg; const struct phy_ops *phy_ops; + const char * const *core_clk_names; + int n_core_clks; u32 pmu_offset_usbdrd0_phy; u32 pmu_offset_usbdrd0_phy_ss; u32 pmu_offset_usbdrd1_phy; - bool has_common_clk_gate; }; /** @@ -196,16 +197,12 @@ struct exynos5_usbdrd_phy_drvdata { * @dev: pointer to device instance of this platform device * @reg_phy: usb phy controller register memory base * @clk: phy clock for register access - * @pipeclk: clock for pipe3 phy - * @utmiclk: clock for utmi+ phy - * @itpclk: clock for ITP generation + * @core_clks: core clocks for phy (ref, pipe3, utmi+, ITP, etc. as required) * @drv_data: pointer to SoC level driver data structure * @phys: array for 'EXYNOS5_DRDPHYS_NUM' number of PHY * instances each with its 'phy' and 'phy_cfg'. * @extrefclk: frequency select settings when using 'separate * reference clocks' for SS and HS operations - * @ref_clk: reference clock to PHY block from which PHY's - * operational clocks are derived * @vbus: VBUS regulator for phy * @vbus_boost: Boost regulator for VBUS present on few Exynos boards */ @@ -213,9 +210,7 @@ struct exynos5_usbdrd_phy { struct device *dev; void __iomem *reg_phy; struct clk *clk; - struct clk *pipeclk; - struct clk *utmiclk; - struct clk *itpclk; + struct clk_bulk_data *core_clks; const struct exynos5_usbdrd_phy_drvdata *drv_data; struct phy_usb_instance { struct phy *phy; @@ -225,7 +220,6 @@ struct exynos5_usbdrd_phy { const struct exynos5_usbdrd_phy_config *phy_cfg; } phys[EXYNOS5_DRDPHYS_NUM]; u32 extrefclk; - struct clk *ref_clk; struct regulator *vbus; struct regulator *vbus_boost; }; @@ -505,12 +499,10 @@ static int exynos5_usbdrd_phy_power_on(struct phy *phy) dev_dbg(phy_drd->dev, "Request to power_on usbdrd_phy phy\n"); - clk_prepare_enable(phy_drd->ref_clk); - if (!phy_drd->drv_data->has_common_clk_gate) { - clk_prepare_enable(phy_drd->pipeclk); - clk_prepare_enable(phy_drd->utmiclk); - clk_prepare_enable(phy_drd->itpclk); - } + ret = clk_bulk_prepare_enable(phy_drd->drv_data->n_core_clks, + phy_drd->core_clks); + if (ret) + return ret; /* Enable VBUS supply */ if (phy_drd->vbus_boost) { @@ -540,12 +532,8 @@ static int exynos5_usbdrd_phy_power_on(struct phy *phy) regulator_disable(phy_drd->vbus_boost); fail_vbus: - clk_disable_unprepare(phy_drd->ref_clk); - if (!phy_drd->drv_data->has_common_clk_gate) { - clk_disable_unprepare(phy_drd->itpclk); - clk_disable_unprepare(phy_drd->utmiclk); - clk_disable_unprepare(phy_drd->pipeclk); - } + clk_bulk_disable_unprepare(phy_drd->drv_data->n_core_clks, + phy_drd->core_clks); return ret; } @@ -566,12 +554,8 @@ static int exynos5_usbdrd_phy_power_off(struct phy *phy) if (phy_drd->vbus_boost) regulator_disable(phy_drd->vbus_boost); - clk_disable_unprepare(phy_drd->ref_clk); - if (!phy_drd->drv_data->has_common_clk_gate) { - clk_disable_unprepare(phy_drd->itpclk); - clk_disable_unprepare(phy_drd->pipeclk); - clk_disable_unprepare(phy_drd->utmiclk); - } + clk_bulk_disable_unprepare(phy_drd->drv_data->n_core_clks, + phy_drd->core_clks); return 0; } @@ -885,8 +869,9 @@ static const struct phy_ops exynos850_usbdrd_phy_ops = { static int exynos5_usbdrd_phy_clk_handle(struct exynos5_usbdrd_phy *phy_drd) { - unsigned long ref_rate; int ret; + struct clk *ref_clk; + unsigned long ref_rate; phy_drd->clk = devm_clk_get(phy_drd->dev, "phy"); if (IS_ERR(phy_drd->clk)) { @@ -894,42 +879,39 @@ static int exynos5_usbdrd_phy_clk_handle(struct exynos5_usbdrd_phy *phy_drd) return PTR_ERR(phy_drd->clk); } - phy_drd->ref_clk = devm_clk_get(phy_drd->dev, "ref"); - if (IS_ERR(phy_drd->ref_clk)) { - dev_err(phy_drd->dev, "Failed to get phy reference clock\n"); - return PTR_ERR(phy_drd->ref_clk); - } - ref_rate = clk_get_rate(phy_drd->ref_clk); - - ret = exynos5_rate_to_clk(ref_rate, &phy_drd->extrefclk); - if (ret) { - dev_err(phy_drd->dev, "Clock rate (%ld) not supported\n", - ref_rate); - return ret; - } + phy_drd->core_clks = devm_kcalloc(phy_drd->dev, + phy_drd->drv_data->n_core_clks, + sizeof(*phy_drd->core_clks), + GFP_KERNEL); + if (!phy_drd->core_clks) + return -ENOMEM; - if (!phy_drd->drv_data->has_common_clk_gate) { - phy_drd->pipeclk = devm_clk_get(phy_drd->dev, "phy_pipe"); - if (IS_ERR(phy_drd->pipeclk)) { - dev_info(phy_drd->dev, - "PIPE3 phy operational clock not specified\n"); - phy_drd->pipeclk = NULL; - } + for (int i = 0; i < phy_drd->drv_data->n_core_clks; ++i) + phy_drd->core_clks[i].id = phy_drd->drv_data->core_clk_names[i]; - phy_drd->utmiclk = devm_clk_get(phy_drd->dev, "phy_utmi"); - if (IS_ERR(phy_drd->utmiclk)) { - dev_info(phy_drd->dev, - "UTMI phy operational clock not specified\n"); - phy_drd->utmiclk = NULL; - } + ret = devm_clk_bulk_get(phy_drd->dev, phy_drd->drv_data->n_core_clks, + phy_drd->core_clks); + if (ret) + return dev_err_probe(phy_drd->dev, ret, + "failed to get phy core clock(s)\n"); - phy_drd->itpclk = devm_clk_get(phy_drd->dev, "itp"); - if (IS_ERR(phy_drd->itpclk)) { - dev_info(phy_drd->dev, - "ITP clock from main OSC not specified\n"); - phy_drd->itpclk = NULL; + ref_clk = NULL; + for (int i = 0; i < phy_drd->drv_data->n_core_clks; ++i) { + if (!strcmp(phy_drd->core_clks[i].id, "ref")) { + ref_clk = phy_drd->core_clks[i].clk; + break; } } + if (!ref_clk) + return dev_err_probe(phy_drd->dev, -ENODEV, + "failed to find phy reference clock\n"); + + ref_rate = clk_get_rate(ref_clk); + ret = exynos5_rate_to_clk(ref_rate, &phy_drd->extrefclk); + if (ret) + return dev_err_probe(phy_drd->dev, ret, + "clock rate (%ld) not supported\n", + ref_rate); return 0; } @@ -957,19 +939,29 @@ static const struct exynos5_usbdrd_phy_config phy_cfg_exynos850[] = { }, }; +static const char * const exynos5_core_clk_names[] = { + "ref", +}; + +static const char * const exynos5433_core_clk_names[] = { + "ref", "phy_pipe", "phy_utmi", "itp", +}; + static const struct exynos5_usbdrd_phy_drvdata exynos5420_usbdrd_phy = { .phy_cfg = phy_cfg_exynos5, .phy_ops = &exynos5_usbdrd_phy_ops, .pmu_offset_usbdrd0_phy = EXYNOS5_USBDRD_PHY_CONTROL, .pmu_offset_usbdrd1_phy = EXYNOS5420_USBDRD1_PHY_CONTROL, - .has_common_clk_gate = true, + .core_clk_names = exynos5_core_clk_names, + .n_core_clks = ARRAY_SIZE(exynos5_core_clk_names), }; static const struct exynos5_usbdrd_phy_drvdata exynos5250_usbdrd_phy = { .phy_cfg = phy_cfg_exynos5, .phy_ops = &exynos5_usbdrd_phy_ops, .pmu_offset_usbdrd0_phy = EXYNOS5_USBDRD_PHY_CONTROL, - .has_common_clk_gate = true, + .core_clk_names = exynos5_core_clk_names, + .n_core_clks = ARRAY_SIZE(exynos5_core_clk_names), }; static const struct exynos5_usbdrd_phy_drvdata exynos5433_usbdrd_phy = { @@ -977,21 +969,24 @@ static const struct exynos5_usbdrd_phy_drvdata exynos5433_usbdrd_phy = { .phy_ops = &exynos5_usbdrd_phy_ops, .pmu_offset_usbdrd0_phy = EXYNOS5_USBDRD_PHY_CONTROL, .pmu_offset_usbdrd1_phy = EXYNOS5433_USBHOST30_PHY_CONTROL, - .has_common_clk_gate = false, + .core_clk_names = exynos5433_core_clk_names, + .n_core_clks = ARRAY_SIZE(exynos5433_core_clk_names), }; static const struct exynos5_usbdrd_phy_drvdata exynos7_usbdrd_phy = { .phy_cfg = phy_cfg_exynos5, .phy_ops = &exynos5_usbdrd_phy_ops, .pmu_offset_usbdrd0_phy = EXYNOS5_USBDRD_PHY_CONTROL, - .has_common_clk_gate = false, + .core_clk_names = exynos5433_core_clk_names, + .n_core_clks = ARRAY_SIZE(exynos5433_core_clk_names), }; static const struct exynos5_usbdrd_phy_drvdata exynos850_usbdrd_phy = { .phy_cfg = phy_cfg_exynos850, .phy_ops = &exynos850_usbdrd_phy_ops, .pmu_offset_usbdrd0_phy = EXYNOS5_USBDRD_PHY_CONTROL, - .has_common_clk_gate = true, + .core_clk_names = exynos5_core_clk_names, + .n_core_clks = ARRAY_SIZE(exynos5_core_clk_names), }; static const struct of_device_id exynos5_usbdrd_phy_of_match[] = { @@ -1045,10 +1040,8 @@ static int exynos5_usbdrd_phy_probe(struct platform_device *pdev) phy_drd->drv_data = drv_data; ret = exynos5_usbdrd_phy_clk_handle(phy_drd); - if (ret) { - dev_err(dev, "Failed to initialize clocks\n"); + if (ret) return ret; - } reg_pmu = syscon_regmap_lookup_by_phandle(dev->of_node, "samsung,pmu-syscon"); From patchwork Mon Jun 17 16:44:45 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Andr=C3=A9_Draszik?= X-Patchwork-Id: 13701050 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 25B33C27C79 for ; Mon, 17 Jun 2024 16:45:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:In-Reply-To:References:Message-Id :MIME-Version:Subject:Date:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=+P8hwIj1GSf7U9VmUSFRl7RzLLgQBUfOUXmW5FJRzqY=; b=GzuIGY3ay+hSJJ AcWtKg3GaSzap4RMXZx4SMtWXxN8v1J4DfTYFaD0iVlqrr1cF/WOjfiT1WqiX+dILwcvh9da18JjK s4lWDzFn1RAK/RWhONeVK16Rur26inKGIuDmb5UJKiDGwXX3G4EGqRcPsmwbttImUp2G0W+WGIFgK RZoNETBnieaEj/IQqX1GQe31EIt+w5KPIcLT4PywZnDdHspRtH6HxyMbIoQTZAgFmp59bm0zy0We0 xIk8pnAcM8W8ekt7D+tF7zIPe3Ik7kkQRWwYcNT8lTsnS7WRB9sXasdmhsQdKB9dQEyBUBF1xNmhC Pw5jilsNBeZ+RFiZmxHg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1sJFU6-0000000BnFF-2wM7; Mon, 17 Jun 2024 16:45:34 +0000 Received: from mail-ej1-x62e.google.com ([2a00:1450:4864:20::62e]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1sJFTm-0000000Bn1G-23aA for linux-phy@lists.infradead.org; Mon, 17 Jun 2024 16:45:20 +0000 Received: by mail-ej1-x62e.google.com with SMTP id a640c23a62f3a-a6e43dad8ecso792398366b.1 for ; Mon, 17 Jun 2024 09:45:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1718642713; x=1719247513; darn=lists.infradead.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=775Rc3YSZJA9GkF9P0glZgOGiZ3l+SlVgXxf6vD2zUg=; b=jSIjn0MQSjMG+Ip3gqd1eoClv/NABwlYH7d/FdJot485v3gLYKbGP2n2r4DimOv84B 78ES08VuSyA05BR9Hg0SieP37EPHTNNlujQx64vqJ7q17skGDPJK+dnR/DPjEELEwlZA w0J8pE5vBptdj151J+oK+pS+jF0oQjh0fQjMkyYmi5DAs0ztp8ndGRuRWuma//vdM6MN vxbfiNi15gg8kJpSuY31XPs8ikUK0QmMKjXW/3Q/07UOpxWyCJEk3L2fVPcxjQKI4TTs ZwjjzcUSSUM96jmk2jJZldy9rezaRAplQJqcGNd2M6dp45lw0bDKug6KRo27HSHiO6YM auPw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718642713; x=1719247513; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=775Rc3YSZJA9GkF9P0glZgOGiZ3l+SlVgXxf6vD2zUg=; b=o+mIaN6qG08+ChFlh5TTQSlUGIF+TExrnrsBtVNxAiTaadZqSO/XsMtBvYK5jBi304 xURjE9m92i7w7p11paYvJvWHqAtQYAkFoiIduCZTDof3di94//YA5cnldT9peouboQUv rWdQT0y249jEJiyrRG8FGJBlPsvLPXxiVR3I7SWRlhGHp3alNHFhXDkBBJGKK6pg1Xra 2SgJhO9PGF3E0s/kYL0XRcW9OSzJWVBTEMyRhGVM5+87iASTRMbWkAm7VEWSWhd67Lh1 LOyERsp4WbWo2GHbvEEeYbSQ3aK177cqZHOiuZqwZd37hIEp8/ORhWEnA+QCu3ioq+tc zlnA== X-Forwarded-Encrypted: i=1; AJvYcCXi/7xQH2DEA8KBFVJlUgSi7d9xt1yG4/+LIFZEAGodpmdV0Cerv3p/GS2yLq4Sx2d4W83jJo0dE7cDd72v/MP/sFvH5njGTdxah+XUqw== X-Gm-Message-State: AOJu0Yy8f0a1tFTMcZ+kkdikl6T3yUUUBiuFnPPbMttNqZ2baBiH+G5C HLrHwbljLx6V5XyyQd8btz35iAr35tqHd+jCE9QThfKMNcTot2jXU9CPpzJdt5E= X-Google-Smtp-Source: AGHT+IGxghexs1XqxhT5potawbeFSAX16ipohQs+SrpdF0FJ0NKfLsTElkU4lhVhPvf7HZsnVf1r1Q== X-Received: by 2002:a17:906:ba89:b0:a6f:6960:5e15 with SMTP id a640c23a62f3a-a6f94c13e0emr12835266b.7.1718642713131; Mon, 17 Jun 2024 09:45:13 -0700 (PDT) Received: from puffmais.c.googlers.com (8.239.204.35.bc.googleusercontent.com. [35.204.239.8]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-a6f56f4170bsm527139966b.157.2024.06.17.09.45.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Jun 2024 09:45:12 -0700 (PDT) From: =?utf-8?q?Andr=C3=A9_Draszik?= Date: Mon, 17 Jun 2024 17:44:45 +0100 Subject: [PATCH v3 4/6] phy: exynos5-usbdrd: convert (phy) register access clock to clk_bulk MIME-Version: 1.0 Message-Id: <20240617-usb-phy-gs101-v3-4-b66de9ae7424@linaro.org> References: <20240617-usb-phy-gs101-v3-0-b66de9ae7424@linaro.org> In-Reply-To: <20240617-usb-phy-gs101-v3-0-b66de9ae7424@linaro.org> To: Vinod Koul , Kishon Vijay Abraham I , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Peter Griffin , Marek Szyprowski , Sylwester Nawrocki , Alim Akhtar , Sam Protsenko Cc: Krzysztof Kozlowski , Tudor Ambarus , Will McVicker , Roy Luo , kernel-team@android.com, linux-phy@lists.infradead.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-samsung-soc@vger.kernel.org, =?utf-8?q?Andr=C3=A9_Draszik?= X-Mailer: b4 0.13.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240617_094514_686702_A0480C22 X-CRM114-Status: GOOD ( 15.91 ) X-BeenThere: linux-phy@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux Phy Mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-phy" Errors-To: linux-phy-bounces+linux-phy=archiver.kernel.org@lists.infradead.org In preparation for support for additional platforms, convert the phy register access clock to using the clk_bulk interfaces. Newer SoCs like Google Tensor gs101 require additional clocks for access to additional (different) register areas (PHY, PMA, PCS), and converting to clk_bulk simplifies addition of those extra clocks. Signed-off-by: André Draszik Tested-by: Will McVicker Reviewed-by: Peter Griffin Tested-by: Peter Griffin --- v3: * make the register access clock name(s) platform specific and avoid use of devm_clk_bulk_get_optional() as we want to be sure to have retrieved all required clocks * fix a whitespace issue * slightly rephrase commit message --- drivers/phy/samsung/phy-exynos5-usbdrd.c | 54 +++++++++++++++++++++++--------- 1 file changed, 39 insertions(+), 15 deletions(-) diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c index 35b307dad2ee..80a3891fd605 100644 --- a/drivers/phy/samsung/phy-exynos5-usbdrd.c +++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c @@ -185,6 +185,8 @@ struct exynos5_usbdrd_phy_config { struct exynos5_usbdrd_phy_drvdata { const struct exynos5_usbdrd_phy_config *phy_cfg; const struct phy_ops *phy_ops; + const char * const *clk_names; + int n_clks; const char * const *core_clk_names; int n_core_clks; u32 pmu_offset_usbdrd0_phy; @@ -196,7 +198,7 @@ struct exynos5_usbdrd_phy_drvdata { * struct exynos5_usbdrd_phy - driver data for USB 3.0 PHY * @dev: pointer to device instance of this platform device * @reg_phy: usb phy controller register memory base - * @clk: phy clock for register access + * @clks: clocks for register access * @core_clks: core clocks for phy (ref, pipe3, utmi+, ITP, etc. as required) * @drv_data: pointer to SoC level driver data structure * @phys: array for 'EXYNOS5_DRDPHYS_NUM' number of PHY @@ -209,7 +211,7 @@ struct exynos5_usbdrd_phy_drvdata { struct exynos5_usbdrd_phy { struct device *dev; void __iomem *reg_phy; - struct clk *clk; + struct clk_bulk_data *clks; struct clk_bulk_data *core_clks; const struct exynos5_usbdrd_phy_drvdata *drv_data; struct phy_usb_instance { @@ -402,7 +404,7 @@ static int exynos5_usbdrd_phy_init(struct phy *phy) struct phy_usb_instance *inst = phy_get_drvdata(phy); struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst); - ret = clk_prepare_enable(phy_drd->clk); + ret = clk_bulk_prepare_enable(phy_drd->drv_data->n_clks, phy_drd->clks); if (ret) return ret; @@ -452,7 +454,7 @@ static int exynos5_usbdrd_phy_init(struct phy *phy) reg &= ~PHYCLKRST_PORTRESET; writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYCLKRST); - clk_disable_unprepare(phy_drd->clk); + clk_bulk_disable_unprepare(phy_drd->drv_data->n_clks, phy_drd->clks); return 0; } @@ -464,7 +466,7 @@ static int exynos5_usbdrd_phy_exit(struct phy *phy) struct phy_usb_instance *inst = phy_get_drvdata(phy); struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst); - ret = clk_prepare_enable(phy_drd->clk); + ret = clk_bulk_prepare_enable(phy_drd->drv_data->n_clks, phy_drd->clks); if (ret) return ret; @@ -486,7 +488,7 @@ static int exynos5_usbdrd_phy_exit(struct phy *phy) PHYTEST_POWERDOWN_HSP; writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYTEST); - clk_disable_unprepare(phy_drd->clk); + clk_bulk_disable_unprepare(phy_drd->drv_data->n_clks, phy_drd->clks); return 0; } @@ -811,14 +813,14 @@ static int exynos850_usbdrd_phy_init(struct phy *phy) struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst); int ret; - ret = clk_prepare_enable(phy_drd->clk); + ret = clk_bulk_prepare_enable(phy_drd->drv_data->n_clks, phy_drd->clks); if (ret) return ret; /* UTMI or PIPE3 specific init */ inst->phy_cfg->phy_init(phy_drd); - clk_disable_unprepare(phy_drd->clk); + clk_bulk_disable_unprepare(phy_drd->drv_data->n_clks, phy_drd->clks); return 0; } @@ -831,7 +833,7 @@ static int exynos850_usbdrd_phy_exit(struct phy *phy) u32 reg; int ret; - ret = clk_prepare_enable(phy_drd->clk); + ret = clk_bulk_prepare_enable(phy_drd->drv_data->n_clks, phy_drd->clks); if (ret) return ret; @@ -854,7 +856,7 @@ static int exynos850_usbdrd_phy_exit(struct phy *phy) reg &= ~CLKRST_LINK_SW_RST; writel(reg, regs_base + EXYNOS850_DRD_CLKRST); - clk_disable_unprepare(phy_drd->clk); + clk_bulk_disable_unprepare(phy_drd->drv_data->n_clks, phy_drd->clks); return 0; } @@ -873,11 +875,19 @@ static int exynos5_usbdrd_phy_clk_handle(struct exynos5_usbdrd_phy *phy_drd) struct clk *ref_clk; unsigned long ref_rate; - phy_drd->clk = devm_clk_get(phy_drd->dev, "phy"); - if (IS_ERR(phy_drd->clk)) { - dev_err(phy_drd->dev, "Failed to get phy clock\n"); - return PTR_ERR(phy_drd->clk); - } + phy_drd->clks = devm_kcalloc(phy_drd->dev, phy_drd->drv_data->n_clks, + sizeof(*phy_drd->clks), GFP_KERNEL); + if (!phy_drd->clks) + return -ENOMEM; + + for (int i = 0; i < phy_drd->drv_data->n_clks; ++i) + phy_drd->clks[i].id = phy_drd->drv_data->clk_names[i]; + + ret = devm_clk_bulk_get(phy_drd->dev, phy_drd->drv_data->n_clks, + phy_drd->clks); + if (ret) + return dev_err_probe(phy_drd->dev, ret, + "failed to get phy clock(s)\n"); phy_drd->core_clks = devm_kcalloc(phy_drd->dev, phy_drd->drv_data->n_core_clks, @@ -939,6 +949,10 @@ static const struct exynos5_usbdrd_phy_config phy_cfg_exynos850[] = { }, }; +static const char * const exynos5_clk_names[] = { + "phy", +}; + static const char * const exynos5_core_clk_names[] = { "ref", }; @@ -952,6 +966,8 @@ static const struct exynos5_usbdrd_phy_drvdata exynos5420_usbdrd_phy = { .phy_ops = &exynos5_usbdrd_phy_ops, .pmu_offset_usbdrd0_phy = EXYNOS5_USBDRD_PHY_CONTROL, .pmu_offset_usbdrd1_phy = EXYNOS5420_USBDRD1_PHY_CONTROL, + .clk_names = exynos5_clk_names, + .n_clks = ARRAY_SIZE(exynos5_clk_names), .core_clk_names = exynos5_core_clk_names, .n_core_clks = ARRAY_SIZE(exynos5_core_clk_names), }; @@ -960,6 +976,8 @@ static const struct exynos5_usbdrd_phy_drvdata exynos5250_usbdrd_phy = { .phy_cfg = phy_cfg_exynos5, .phy_ops = &exynos5_usbdrd_phy_ops, .pmu_offset_usbdrd0_phy = EXYNOS5_USBDRD_PHY_CONTROL, + .clk_names = exynos5_clk_names, + .n_clks = ARRAY_SIZE(exynos5_clk_names), .core_clk_names = exynos5_core_clk_names, .n_core_clks = ARRAY_SIZE(exynos5_core_clk_names), }; @@ -969,6 +987,8 @@ static const struct exynos5_usbdrd_phy_drvdata exynos5433_usbdrd_phy = { .phy_ops = &exynos5_usbdrd_phy_ops, .pmu_offset_usbdrd0_phy = EXYNOS5_USBDRD_PHY_CONTROL, .pmu_offset_usbdrd1_phy = EXYNOS5433_USBHOST30_PHY_CONTROL, + .clk_names = exynos5_clk_names, + .n_clks = ARRAY_SIZE(exynos5_clk_names), .core_clk_names = exynos5433_core_clk_names, .n_core_clks = ARRAY_SIZE(exynos5433_core_clk_names), }; @@ -977,6 +997,8 @@ static const struct exynos5_usbdrd_phy_drvdata exynos7_usbdrd_phy = { .phy_cfg = phy_cfg_exynos5, .phy_ops = &exynos5_usbdrd_phy_ops, .pmu_offset_usbdrd0_phy = EXYNOS5_USBDRD_PHY_CONTROL, + .clk_names = exynos5_clk_names, + .n_clks = ARRAY_SIZE(exynos5_clk_names), .core_clk_names = exynos5433_core_clk_names, .n_core_clks = ARRAY_SIZE(exynos5433_core_clk_names), }; @@ -985,6 +1007,8 @@ static const struct exynos5_usbdrd_phy_drvdata exynos850_usbdrd_phy = { .phy_cfg = phy_cfg_exynos850, .phy_ops = &exynos850_usbdrd_phy_ops, .pmu_offset_usbdrd0_phy = EXYNOS5_USBDRD_PHY_CONTROL, + .clk_names = exynos5_clk_names, + .n_clks = ARRAY_SIZE(exynos5_clk_names), .core_clk_names = exynos5_core_clk_names, .n_core_clks = ARRAY_SIZE(exynos5_core_clk_names), }; From patchwork Mon Jun 17 16:44:46 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Andr=C3=A9_Draszik?= X-Patchwork-Id: 13701052 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 074E5C27C79 for ; Mon, 17 Jun 2024 16:46:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:In-Reply-To:References:Message-Id :MIME-Version:Subject:Date:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=JxoFOGTNbA4brsC1+kpTEA3lQDawjgBOayqCk4XZkQw=; b=CwGA2WvF0VOc21 WB50FbrCWaIBrfGeTmBDn4TFaTAEcKynNw6/tSYMZB4kneAdRxEMGKltK0IP2lGtqNwuloU8FQS+R HgtuEW3SdcOjEn9EfItHBYe3HQfzPin0I2pdvTpAFddmrLeTEpHZq3tFuCmpdiSMkVanC0TiKXIr/ WCqp16uIznHZLMbW48tXanLd/uGuZsZkzfSB+jq18winrfZN5/4hmxaCo7MyVGvs2WEvqi0aGeeWv 3JoCrpVkpADmEhB4egf8ZQ0YeVsll3knf1xRlNzma8gKYczalgGxMBTm/heebcpx0IJWs53yrL1XZ gVybFjnfFOrnY6yu5NnA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1sJFUV-0000000BnTY-0wdL; Mon, 17 Jun 2024 16:45:59 +0000 Received: from mail-ej1-x631.google.com ([2a00:1450:4864:20::631]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1sJFTn-0000000Bn2W-3BQs for linux-phy@lists.infradead.org; Mon, 17 Jun 2024 16:45:22 +0000 Received: by mail-ej1-x631.google.com with SMTP id a640c23a62f3a-a6f0e153eddso587572866b.0 for ; Mon, 17 Jun 2024 09:45:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1718642713; x=1719247513; darn=lists.infradead.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=1iqem2TTUm0Io6iE50JUxcLVu6vIdSJQI7akG3Vt878=; b=dE+hB4Ms7aDFGuYgjc38AXqOd2aFsTzcA+C//ZWYLwex+WCaSWVmAHKBmPYJ7LOsNe qjLWrM2sXIyS9yROQXkP7PnBtNEYZUdB+masZSv48+0d+85toZ6E1pLbxJje1pbkSDTn b+3VCxOM28chlYf9ZWfkZL3puR2iofwGpSBwgCC/KL1iGA7Bw2d29iyg4f2dcJtDuPhQ 5ZjZG0iN2kwIcv2XO0jRHe5K1ExqlZT3N9zc3m/1nm6aPnFMT8xqNLNNiT0CIGwvfcOj R8zCPnc3TIU9C/Qf+Cxf3jyvkxz1MQYBoAtrOG2ckoDA2S+U0iXmpeZropoBpNM1uYzj HKWw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718642713; x=1719247513; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=1iqem2TTUm0Io6iE50JUxcLVu6vIdSJQI7akG3Vt878=; b=N6wQzqCsZcPskSrWW7vu3jVkCHYvkE4tT7wD0QN7MMV/KZioCyJozIM/mvMYwZ2Yuh BEvLTjkBS3ajX4h6xCMSv8vMoq9bYkhuCOHRjvycvpFdEjXG4CEs1aewQNOV1s4Bs4Fu LQj/53z1mX/retRThUh6sNqiRdSJmiQCuQ796ETMvmSqxhw14n+fXg18BndaDkoaqgfH i+uNX+Z19Tciue3qoDuEKFI7/54A+DZ7gnsj8UoSkj892kZ28p/rSqAVbWvMmlwo+N+0 p5oNG/eQddlr8CS2m8xQLwVZdzb6ygyCQQJh8vVUUiCoMIgBxrXCniQ5iqDibeuC7MwE KH1A== X-Forwarded-Encrypted: i=1; AJvYcCUG8+IaUNX4C1krf11onh99CWhf3uXxuJLsgpB2nZ5D0Z5UJuV1S403RBFLvt3mJ9W9NvOatW8cotsjk60hV5WlulojhCBTYdGlzLK0Lw== X-Gm-Message-State: AOJu0YyfiEiENFJXQXpz84qq7inaWdpwJYaQOso87uY97I7bWR44AITf Rqe/t6aMp8wh5CQ0wYycECUK6HKu/lXl4YUpWDIUS4v/CcnWMx/Heqk+8LDmAh8= X-Google-Smtp-Source: AGHT+IExQsl5L51QJEkILCWw/4EWi/X1ko1LnAIwMsBrVJigwlCKJAPhnITO1WSus9mGPJk5KWgHbQ== X-Received: by 2002:a17:906:e251:b0:a6f:17a9:947a with SMTP id a640c23a62f3a-a6f60de6059mr682118766b.71.1718642713618; Mon, 17 Jun 2024 09:45:13 -0700 (PDT) Received: from puffmais.c.googlers.com (8.239.204.35.bc.googleusercontent.com. [35.204.239.8]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-a6f56f4170bsm527139966b.157.2024.06.17.09.45.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Jun 2024 09:45:13 -0700 (PDT) From: =?utf-8?q?Andr=C3=A9_Draszik?= Date: Mon, 17 Jun 2024 17:44:46 +0100 Subject: [PATCH v3 5/6] phy: exynos5-usbdrd: convert Vbus supplies to regulator_bulk MIME-Version: 1.0 Message-Id: <20240617-usb-phy-gs101-v3-5-b66de9ae7424@linaro.org> References: <20240617-usb-phy-gs101-v3-0-b66de9ae7424@linaro.org> In-Reply-To: <20240617-usb-phy-gs101-v3-0-b66de9ae7424@linaro.org> To: Vinod Koul , Kishon Vijay Abraham I , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Peter Griffin , Marek Szyprowski , Sylwester Nawrocki , Alim Akhtar , Sam Protsenko Cc: Krzysztof Kozlowski , Tudor Ambarus , Will McVicker , Roy Luo , kernel-team@android.com, linux-phy@lists.infradead.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-samsung-soc@vger.kernel.org, =?utf-8?q?Andr=C3=A9_Draszik?= X-Mailer: b4 0.13.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240617_094515_955471_D1004607 X-CRM114-Status: GOOD ( 18.00 ) X-BeenThere: linux-phy@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux Phy Mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-phy" Errors-To: linux-phy-bounces+linux-phy=archiver.kernel.org@lists.infradead.org Using the regulator_bulk APIs, the handling of power supplies becomes much simpler. There is no need anymore to check if regulators have been acquired or not, the bulk APIs will do all the work for us. We can also drop the various handles to the individual power supplies in the driver runtime data and instead simply treat them all as one thing. Error cleanup also becomes much simpler. Converting to the regulator_bulk APIs also makes it easier to add support for those SoCs that have additional power supplies for the PHY. Google Tensor gs101 is one example of such a SoC. Otherwise we'd have to add all additional supplies individually via individual calls to regulator_get() and enable/disable handle them all individually, including complicated error handling. That doesn't scale and clutters the code. Just update the code to use the regulator_bulk APIs. Signed-off-by: André Draszik Tested-by: Will McVicker Reviewed-by: Peter Griffin Tested-by: Peter Griffin --- drivers/phy/samsung/phy-exynos5-usbdrd.c | 86 +++++++++++++++----------------- 1 file changed, 39 insertions(+), 47 deletions(-) diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c index 80a3891fd605..2d2ce06765c4 100644 --- a/drivers/phy/samsung/phy-exynos5-usbdrd.c +++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c @@ -189,6 +189,8 @@ struct exynos5_usbdrd_phy_drvdata { int n_clks; const char * const *core_clk_names; int n_core_clks; + const char * const *regulator_names; + int n_regulators; u32 pmu_offset_usbdrd0_phy; u32 pmu_offset_usbdrd0_phy_ss; u32 pmu_offset_usbdrd1_phy; @@ -205,8 +207,7 @@ struct exynos5_usbdrd_phy_drvdata { * instances each with its 'phy' and 'phy_cfg'. * @extrefclk: frequency select settings when using 'separate * reference clocks' for SS and HS operations - * @vbus: VBUS regulator for phy - * @vbus_boost: Boost regulator for VBUS present on few Exynos boards + * @regulators: regulators for phy */ struct exynos5_usbdrd_phy { struct device *dev; @@ -222,8 +223,7 @@ struct exynos5_usbdrd_phy { const struct exynos5_usbdrd_phy_config *phy_cfg; } phys[EXYNOS5_DRDPHYS_NUM]; u32 extrefclk; - struct regulator *vbus; - struct regulator *vbus_boost; + struct regulator_bulk_data *regulators; }; static inline @@ -507,21 +507,11 @@ static int exynos5_usbdrd_phy_power_on(struct phy *phy) return ret; /* Enable VBUS supply */ - if (phy_drd->vbus_boost) { - ret = regulator_enable(phy_drd->vbus_boost); - if (ret) { - dev_err(phy_drd->dev, - "Failed to enable VBUS boost supply\n"); - goto fail_vbus; - } - } - - if (phy_drd->vbus) { - ret = regulator_enable(phy_drd->vbus); - if (ret) { - dev_err(phy_drd->dev, "Failed to enable VBUS supply\n"); - goto fail_vbus_boost; - } + ret = regulator_bulk_enable(phy_drd->drv_data->n_regulators, + phy_drd->regulators); + if (ret) { + dev_err(phy_drd->dev, "Failed to enable PHY regulator(s)\n"); + goto fail_vbus; } /* Power-on PHY */ @@ -529,10 +519,6 @@ static int exynos5_usbdrd_phy_power_on(struct phy *phy) return 0; -fail_vbus_boost: - if (phy_drd->vbus_boost) - regulator_disable(phy_drd->vbus_boost); - fail_vbus: clk_bulk_disable_unprepare(phy_drd->drv_data->n_core_clks, phy_drd->core_clks); @@ -551,10 +537,8 @@ static int exynos5_usbdrd_phy_power_off(struct phy *phy) inst->phy_cfg->phy_isol(inst, true); /* Disable VBUS supply */ - if (phy_drd->vbus) - regulator_disable(phy_drd->vbus); - if (phy_drd->vbus_boost) - regulator_disable(phy_drd->vbus_boost); + regulator_bulk_disable(phy_drd->drv_data->n_regulators, + phy_drd->regulators); clk_bulk_disable_unprepare(phy_drd->drv_data->n_core_clks, phy_drd->core_clks); @@ -961,6 +945,10 @@ static const char * const exynos5433_core_clk_names[] = { "ref", "phy_pipe", "phy_utmi", "itp", }; +static const char * const exynos5_regulator_names[] = { + "vbus", "vbus-boost", +}; + static const struct exynos5_usbdrd_phy_drvdata exynos5420_usbdrd_phy = { .phy_cfg = phy_cfg_exynos5, .phy_ops = &exynos5_usbdrd_phy_ops, @@ -970,6 +958,8 @@ static const struct exynos5_usbdrd_phy_drvdata exynos5420_usbdrd_phy = { .n_clks = ARRAY_SIZE(exynos5_clk_names), .core_clk_names = exynos5_core_clk_names, .n_core_clks = ARRAY_SIZE(exynos5_core_clk_names), + .regulator_names = exynos5_regulator_names, + .n_regulators = ARRAY_SIZE(exynos5_regulator_names), }; static const struct exynos5_usbdrd_phy_drvdata exynos5250_usbdrd_phy = { @@ -980,6 +970,8 @@ static const struct exynos5_usbdrd_phy_drvdata exynos5250_usbdrd_phy = { .n_clks = ARRAY_SIZE(exynos5_clk_names), .core_clk_names = exynos5_core_clk_names, .n_core_clks = ARRAY_SIZE(exynos5_core_clk_names), + .regulator_names = exynos5_regulator_names, + .n_regulators = ARRAY_SIZE(exynos5_regulator_names), }; static const struct exynos5_usbdrd_phy_drvdata exynos5433_usbdrd_phy = { @@ -991,6 +983,8 @@ static const struct exynos5_usbdrd_phy_drvdata exynos5433_usbdrd_phy = { .n_clks = ARRAY_SIZE(exynos5_clk_names), .core_clk_names = exynos5433_core_clk_names, .n_core_clks = ARRAY_SIZE(exynos5433_core_clk_names), + .regulator_names = exynos5_regulator_names, + .n_regulators = ARRAY_SIZE(exynos5_regulator_names), }; static const struct exynos5_usbdrd_phy_drvdata exynos7_usbdrd_phy = { @@ -1001,6 +995,8 @@ static const struct exynos5_usbdrd_phy_drvdata exynos7_usbdrd_phy = { .n_clks = ARRAY_SIZE(exynos5_clk_names), .core_clk_names = exynos5433_core_clk_names, .n_core_clks = ARRAY_SIZE(exynos5433_core_clk_names), + .regulator_names = exynos5_regulator_names, + .n_regulators = ARRAY_SIZE(exynos5_regulator_names), }; static const struct exynos5_usbdrd_phy_drvdata exynos850_usbdrd_phy = { @@ -1011,6 +1007,8 @@ static const struct exynos5_usbdrd_phy_drvdata exynos850_usbdrd_phy = { .n_clks = ARRAY_SIZE(exynos5_clk_names), .core_clk_names = exynos5_core_clk_names, .n_core_clks = ARRAY_SIZE(exynos5_core_clk_names), + .regulator_names = exynos5_regulator_names, + .n_regulators = ARRAY_SIZE(exynos5_regulator_names), }; static const struct of_device_id exynos5_usbdrd_phy_of_match[] = { @@ -1083,26 +1081,20 @@ static int exynos5_usbdrd_phy_probe(struct platform_device *pdev) if (channel < 0) dev_dbg(dev, "Not a multi-controller usbdrd phy\n"); - /* Get Vbus regulators */ - phy_drd->vbus = devm_regulator_get(dev, "vbus"); - if (IS_ERR(phy_drd->vbus)) { - ret = PTR_ERR(phy_drd->vbus); - if (ret == -EPROBE_DEFER) - return ret; - - dev_warn(dev, "Failed to get VBUS supply regulator\n"); - phy_drd->vbus = NULL; - } - - phy_drd->vbus_boost = devm_regulator_get(dev, "vbus-boost"); - if (IS_ERR(phy_drd->vbus_boost)) { - ret = PTR_ERR(phy_drd->vbus_boost); - if (ret == -EPROBE_DEFER) - return ret; - - dev_warn(dev, "Failed to get VBUS boost supply regulator\n"); - phy_drd->vbus_boost = NULL; - } + /* Get regulators */ + phy_drd->regulators = devm_kcalloc(dev, + drv_data->n_regulators, + sizeof(*phy_drd->regulators), + GFP_KERNEL); + if (!phy_drd->regulators) + return ENOMEM; + regulator_bulk_set_supply_names(phy_drd->regulators, + drv_data->regulator_names, + drv_data->n_regulators); + ret = devm_regulator_bulk_get(dev, drv_data->n_regulators, + phy_drd->regulators); + if (ret) + return dev_err_probe(dev, ret, "failed to get regulators\n"); dev_vdbg(dev, "Creating usbdrd_phy phy\n"); From patchwork Mon Jun 17 16:44:47 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Andr=C3=A9_Draszik?= X-Patchwork-Id: 13701053 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 4F890C2BA18 for ; Mon, 17 Jun 2024 16:46:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:In-Reply-To:References:Message-Id :MIME-Version:Subject:Date:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=AFrI614Lh1EftkQI4fIJe+pFH4ggjw51zAiUJUqnF/g=; b=d/q0Sg4dNssApl fxxbhzAGXRCWnaf5ddzieEzvdQigeLOtVw+28L3/0UZ6QLIfKR3nKgVx72/3kMLARy9r7RFLwKFxw Fh1XKCVgvPYXUqpEQ9/TRyTutFPYrp+2DTrS3kUnwrWzycHWAJuCQ0GR1NwsJbuWDi0VftLkhNkMf efINNzw2Pq0LFzCQ+v311H6G/8ZVy81TSxCLnotPI4iDJ4IzctmmZemu9je8XZDHDTh6wBcDoMoTu dbsvLUR4j+N1W3Y08m+/KMeLH3yf9nrLZnUTi18qNnlbWnKZA8qY5g4ILI263Qj4ol3PYF1rHMAFJ Bvxs7ZurdN6ekceVctgQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1sJFUb-0000000BnXM-2M5K; Mon, 17 Jun 2024 16:46:05 +0000 Received: from mail-ed1-x530.google.com ([2a00:1450:4864:20::530]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1sJFTo-0000000Bn3x-3Y3D for linux-phy@lists.infradead.org; Mon, 17 Jun 2024 16:45:28 +0000 Received: by mail-ed1-x530.google.com with SMTP id 4fb4d7f45d1cf-57c75464e77so5535173a12.0 for ; Mon, 17 Jun 2024 09:45:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1718642714; x=1719247514; darn=lists.infradead.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=DZhdhb4rmqBa4poOONSAD2uld3E8ituenuLQCyMLX/0=; b=opLK3ZIUtj3/VM5Xqm7vUK4jZiS8ViJxMQ/iAkO0o+W/KxO0wRhc4L+RPHNtAhhcwD vop9fmQkjyuECceZFzYRywf7/7jlTGVd3u2Uo2zDzL1+v/viOXjd5aDeXO2FM0jqy/YA /lnZfxRuWWaZWm60ISNSa+Egqf9f+xtwuQtbPltwi+sZmluUuS41D2uI0M7hwEm88iXk eQ7gbjxjGZwQUUvHM/TcwQm+jw+Ixt3L4XBf45nT9qSj7uPyDbmuyKw4o/4K7vZx9arg 24dDyQuPvTWagfRj+3xNukg3YTfqqB8uFTtUqGUUQ1zCWtxqMLBcLGF5K2Xsy/c7F2V+ rA9Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718642714; x=1719247514; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=DZhdhb4rmqBa4poOONSAD2uld3E8ituenuLQCyMLX/0=; b=wWc2dbAvCBClo9h6573U5pzGJy0FaD0bt0N79991q1/vL3DlZhnwEJy0r3Htzwdvib msH0brZBg4kQ9HSiaMEYC5rDzoWwilxemgQfdBbp/sscllcrQK9gJkgbdcNuV1kRAkgk B3ud1Epg4JPbg65hkVTjk26za026e/4/Lk6PEXwg/hOHy6Eds++6FiUyfvFVHz4spmvC 2kprnZCKgNH2GXFaaA7ybl+0xZQI3lvgUNdykU21WJH8zf1E82p+/1EVkVhIl/Mi8TaO lQxmv8svK8EPWCsJQm2ZUA2rV+osDCrxxiEWly70IHg0Jg95wGQTsmAACMPnQi5mzsZo P4oQ== X-Forwarded-Encrypted: i=1; AJvYcCWBvxTOnVYl7FohWEJu+B8UCiEHvTWJoggMdIjHxjY+mD158GLFoq0cvgUyFHhvcoE/Xau1Yf8PLFfW7dmNAMW3wFKOduF5bUk0twFvqw== X-Gm-Message-State: AOJu0Yzi9wK20plFyRT3lrGb2zv5rtntTnOxNek6UCi94/TXXPFwB6wx Q7J/spUPNj75yc/nreKs9IhvgTD/tMuhKN64o/MAEstFA1U2HSyV3Y0kdvYrnNk= X-Google-Smtp-Source: AGHT+IFyiujBmbbm3gbxHfCJFIPGVX4E+fY3vvSXp5MF/RGOoRY2gXPP8Uy5YLzj4fVGzDlhpWxpHg== X-Received: by 2002:a17:906:a013:b0:a6f:4954:30f8 with SMTP id a640c23a62f3a-a6f60dc8940mr738825266b.51.1718642714486; Mon, 17 Jun 2024 09:45:14 -0700 (PDT) Received: from puffmais.c.googlers.com (8.239.204.35.bc.googleusercontent.com. [35.204.239.8]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-a6f56f4170bsm527139966b.157.2024.06.17.09.45.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Jun 2024 09:45:14 -0700 (PDT) From: =?utf-8?q?Andr=C3=A9_Draszik?= Date: Mon, 17 Jun 2024 17:44:47 +0100 Subject: [PATCH v3 6/6] phy: exynos5-usbdrd: support Exynos USBDRD 3.1 combo phy (HS & SS) MIME-Version: 1.0 Message-Id: <20240617-usb-phy-gs101-v3-6-b66de9ae7424@linaro.org> References: <20240617-usb-phy-gs101-v3-0-b66de9ae7424@linaro.org> In-Reply-To: <20240617-usb-phy-gs101-v3-0-b66de9ae7424@linaro.org> To: Vinod Koul , Kishon Vijay Abraham I , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Peter Griffin , Marek Szyprowski , Sylwester Nawrocki , Alim Akhtar , Sam Protsenko Cc: Krzysztof Kozlowski , Tudor Ambarus , Will McVicker , Roy Luo , kernel-team@android.com, linux-phy@lists.infradead.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-samsung-soc@vger.kernel.org, =?utf-8?q?Andr=C3=A9_Draszik?= X-Mailer: b4 0.13.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240617_094517_007644_E0FACC0D X-CRM114-Status: GOOD ( 22.59 ) X-BeenThere: linux-phy@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux Phy Mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-phy" Errors-To: linux-phy-bounces+linux-phy=archiver.kernel.org@lists.infradead.org Add support for the Exynos USB 3.1 DRD combo phy, as found in Exynos 9 SoCs like Google GS101. It supports USB SS, HS and DisplayPort. In terms of UTMI+, this is very similar to the existing Exynos850 support in this driver. The difference is that this combo phy supports both UTMI+ (HS) and PIPE3 (SS). It also supports DP alt mode. The number of ports for UTMI+ and PIPE3 can be determined using the LINKPORT register (which also exists on Exynos E850). For SuperSpeed (SS) a new SS phy is in use and its PIPE3 interface is new compared to Exynos E850, and also very different from the existing support for older Exynos SoCs in this driver. The SS phy needs a bit more configuration work and register tuning for signal quality to work reliably, presumably due to the higher frequency, e.g. to account for different board layouts. Additionally, power needs to be enabled before writing to the SS phy registers. This commit adds the necessary changes for USB HS and SS to work. DisplayPort is out of scope in this commit. Notes: * For the register tuning, exynos5_usbdrd_apply_phy_tunes() has been added with the appropriate data structures to support tuning at various stages during initialisation. Since these are hardware specific, the platform data is supposed to be populated accordingly. The implementation is loosely modelled after the Samsung UFS PHY driver. There is one tuning state for UTMI+, PTS_UTMI_POSTINIT, to execute after init and generally intended for HS signal tuning, as done in this commit. PTS_PIPE3_PREINIT PTS_PIPE3_INIT PTS_PIPE3_POSTINIT PTS_PIPE3_POSTLOCK are tuning states for PIPE3. In the downstream driver, preinit differs by Exynos SoC, and postinit and postlock are different per board. The latter haven't been implemented for gs101 here, because downstream doesn't use them on gs101 either. * Signal lock acquisition for SS depends on the orientation of the USB-C plug. Since there currently is no infrastructure to chain connector events to both the USB DWC3 driver and this phy driver, a work-around has been added in exynos5_usbdrd_usbdp_g2_v4_pma_check_cdr_lock() to check both registers if it failed in one of the orientations. * Equally, we can only establish SS speed in one of the connector orientations due to programming differences when selecting the lane mux in exynos5_usbdrd_usbdp_g2_v4_pma_lane_mux_sel(), which really needs to be dynamic, based on the orientation of the connector. * As is, we can establish a HS link using any cable, and an SS link in one orientation of the plug, falling back to HS if the orientation is reversed to the expectation. Signed-off-by: André Draszik Tested-by: Will McVicker Reviewed-by: Peter Griffin Tested-by: Peter Griffin --- v3: * implement handling of regulators * enable power rails and bypass PMU isolatation during struct phy_ops::init() before writing registers and not in ::power_on(), which is too late. Without power register access doesn't work obviously, and the bootloader enables enables PMU isolation in certain cases. * set unused callback pointers to NULL in gs101_tunes[] (I had stripped out too much during original preparation of v1 for submission :-( * add missing postlock tunes from downstream * move PTS_UTMI_POSTINIT utmi phy tuning to before completion of POR sequence, as per datasheet * group gs101 related symbols closer to each other --- drivers/phy/samsung/phy-exynos5-usbdrd.c | 668 +++++++++++++++++++++++++++- include/linux/soc/samsung/exynos-regs-pmu.h | 4 + 2 files changed, 667 insertions(+), 5 deletions(-) diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c index 2d2ce06765c4..df52b78a120b 100644 --- a/drivers/phy/samsung/phy-exynos5-usbdrd.c +++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c @@ -134,11 +134,27 @@ /* Exynos850: USB DRD PHY registers */ #define EXYNOS850_DRD_LINKCTRL 0x04 +#define LINKCTRL_FORCE_RXELECIDLE BIT(18) +#define LINKCTRL_FORCE_PHYSTATUS BIT(17) +#define LINKCTRL_FORCE_PIPE_EN BIT(16) #define LINKCTRL_FORCE_QACT BIT(8) #define LINKCTRL_BUS_FILTER_BYPASS(_x) ((_x) << 4) +#define EXYNOS850_DRD_LINKPORT 0x08 +#define LINKPORT_HOST_NUM_U3 GENMASK(19, 16) +#define LINKPORT_HOST_NUM_U2 GENMASK(15, 12) + #define EXYNOS850_DRD_CLKRST 0x20 +/* + * On versions without SS ports (like E850), bit 3 is for the 2.0 phy (HS), + * while on versions with (like gs101), bits 2 and 3 are for the 3.0 phy (SS) + * and bits 12 & 13 for the 2.0 phy. + */ +#define CLKRST_PHY20_SW_POR BIT(13) +#define CLKRST_PHY20_SW_POR_SEL BIT(12) +#define CLKRST_LINK_PCLK_SEL BIT(7) #define CLKRST_PHY_SW_RST BIT(3) +#define CLKRST_PHY_RESET_SEL BIT(2) #define CLKRST_PORT_RST BIT(1) #define CLKRST_LINK_SW_RST BIT(0) @@ -160,12 +176,173 @@ #define HSP_EN_UTMISUSPEND BIT(9) #define HSP_COMMONONN BIT(8) +#define EXYNOS850_DRD_HSPPARACON 0x58 +#define HSPPARACON_TXVREF GENMASK(31, 28) +#define HSPPARACON_TXRISE GENMASK(25, 24) +#define HSPPARACON_TXRES GENMASK(22, 21) +#define HSPPARACON_TXPREEMPPULSE BIT(20) +#define HSPPARACON_TXPREEMPAMP GENMASK(19, 18) +#define HSPPARACON_TXHSXV GENMASK(17, 16) +#define HSPPARACON_TXFSLS GENMASK(15, 12) +#define HSPPARACON_SQRX GENMASK(10, 8) +#define HSPPARACON_OTG GENMASK(6, 4) +#define HSPPARACON_COMPDIS GENMASK(2, 0) + #define EXYNOS850_DRD_HSP_TEST 0x5c #define HSP_TEST_SIDDQ BIT(24) +/* Exynos9 - GS101 */ +#define EXYNOS850_DRD_SECPMACTL 0x48 +#define SECPMACTL_PMA_ROPLL_REF_CLK_SEL GENMASK(13, 12) +#define SECPMACTL_PMA_LCPLL_REF_CLK_SEL GENMASK(11, 10) +#define SECPMACTL_PMA_REF_FREQ_SEL GENMASK(9, 8) +#define SECPMACTL_PMA_LOW_PWR BIT(4) +#define SECPMACTL_PMA_TRSV_SW_RST BIT(3) +#define SECPMACTL_PMA_CMN_SW_RST BIT(2) +#define SECPMACTL_PMA_INIT_SW_RST BIT(1) +#define SECPMACTL_PMA_APB_SW_RST BIT(0) + +/* PMA registers */ +#define EXYNOS9_PMA_USBDP_CMN_REG0008 0x0020 +#define CMN_REG0008_OVRD_AUX_EN BIT(3) +#define CMN_REG0008_AUX_EN BIT(2) + +#define EXYNOS9_PMA_USBDP_CMN_REG00B8 0x02e0 +#define CMN_REG00B8_LANE_MUX_SEL_DP GENMASK(3, 0) + +#define EXYNOS9_PMA_USBDP_CMN_REG01C0 0x0700 +#define CMN_REG01C0_ANA_LCPLL_LOCK_DONE BIT(7) +#define CMN_REG01C0_ANA_LCPLL_AFC_DONE BIT(6) + +/* these have similar register layout, for lanes 0 and 2 */ +#define EXYNOS9_PMA_USBDP_TRSV_REG03C3 0x0f0c +#define EXYNOS9_PMA_USBDP_TRSV_REG07C3 0x1f0c +#define TRSV_REG03C3_LN0_MON_RX_CDR_AFC_DONE BIT(3) +#define TRSV_REG03C3_LN0_MON_RX_CDR_CAL_DONE BIT(2) +#define TRSV_REG03C3_LN0_MON_RX_CDR_FLD_PLL_MODE_DONE BIT(1) +#define TRSV_REG03C3_LN0_MON_RX_CDR_LOCK_DONE BIT(0) + +/* TRSV_REG0413 and TRSV_REG0813 have similar register layout */ +#define EXYNOS9_PMA_USBDP_TRSV_REG0413 0x104c +#define TRSV_REG0413_OVRD_LN1_TX_RXD_COMP_EN BIT(7) +#define TRSV_REG0413_OVRD_LN1_TX_RXD_EN BIT(5) + +#define EXYNOS9_PMA_USBDP_TRSV_REG0813 0x204c +#define TRSV_REG0813_OVRD_LN3_TX_RXD_COMP_EN BIT(7) +#define TRSV_REG0813_OVRD_LN3_TX_RXD_EN BIT(5) + +/* PCS registers */ +#define EXYNOS9_PCS_NS_VEC_PS1_N1 0x010c +#define EXYNOS9_PCS_NS_VEC_PS2_N0 0x0110 +#define EXYNOS9_PCS_NS_VEC_PS3_N0 0x0118 +#define NS_VEC_NS_REQ GENMASK(31, 24) +#define NS_VEC_ENABLE_TIMER BIT(22) +#define NS_VEC_SEL_TIMEOUT GENMASK(21, 20) +#define NS_VEC_INV_MASK GENMASK(19, 16) +#define NS_VEC_COND_MASK GENMASK(11, 8) +#define NS_VEC_EXP_COND GENMASK(3, 0) + +#define EXYNOS9_PCS_OUT_VEC_2 0x014c +#define EXYNOS9_PCS_OUT_VEC_3 0x0150 +#define PCS_OUT_VEC_B9_DYNAMIC BIT(19) +#define PCS_OUT_VEC_B9_SEL_OUT BIT(18) +#define PCS_OUT_VEC_B8_DYNAMIC BIT(17) +#define PCS_OUT_VEC_B8_SEL_OUT BIT(16) +#define PCS_OUT_VEC_B7_DYNAMIC BIT(15) +#define PCS_OUT_VEC_B7_SEL_OUT BIT(14) +#define PCS_OUT_VEC_B6_DYNAMIC BIT(13) +#define PCS_OUT_VEC_B6_SEL_OUT BIT(12) +#define PCS_OUT_VEC_B5_DYNAMIC BIT(11) +#define PCS_OUT_VEC_B5_SEL_OUT BIT(10) +#define PCS_OUT_VEC_B4_DYNAMIC BIT(9) +#define PCS_OUT_VEC_B4_SEL_OUT BIT(8) +#define PCS_OUT_VEC_B3_DYNAMIC BIT(7) +#define PCS_OUT_VEC_B3_SEL_OUT BIT(6) +#define PCS_OUT_VEC_B2_DYNAMIC BIT(5) +#define PCS_OUT_VEC_B2_SEL_OUT BIT(4) +#define PCS_OUT_VEC_B1_DYNAMIC BIT(3) +#define PCS_OUT_VEC_B1_SEL_OUT BIT(2) +#define PCS_OUT_VEC_B0_DYNAMIC BIT(1) +#define PCS_OUT_VEC_B0_SEL_OUT BIT(0) + +#define EXYNOS9_PCS_TIMEOUT_0 0x0170 + +#define EXYNOS9_PCS_TIMEOUT_3 0x017c + +#define EXYNOS9_PCS_EBUF_PARAM 0x0304 +#define EBUF_PARAM_SKP_REMOVE_TH_EMPTY_MODE GENMASK(29, 24) + +#define EXYNOS9_PCS_BACK_END_MODE_VEC 0x030c +#define BACK_END_MODE_VEC_FORCE_EBUF_EMPTY_MODE BIT(1) +#define BACK_END_MODE_VEC_DISABLE_DATA_MASK BIT(0) + +#define EXYNOS9_PCS_RX_CONTROL 0x03f0 +#define RX_CONTROL_EN_BLOCK_ALIGNER_TYPE_B BIT(22) + +#define EXYNOS9_PCS_RX_CONTROL_DEBUG 0x03f4 +#define RX_CONTROL_DEBUG_EN_TS_CHECK BIT(5) +#define RX_CONTROL_DEBUG_NUM_COM_FOUND GENMASK(3, 0) + +#define EXYNOS9_PCS_LOCAL_COEF 0x040c +#define LOCAL_COEF_PMA_CENTER_COEF GENMASK(21, 16) +#define LOCAL_COEF_LF GENMASK(13, 8) +#define LOCAL_COEF_FS GENMASK(5, 0) + +#define EXYNOS9_PCS_HS_TX_COEF_MAP_0 0x0410 +#define HS_TX_COEF_MAP_0_SSTX_DEEMP GENMASK(17, 12) +#define HS_TX_COEF_MAP_0_SSTX_LEVEL GENMASK(11, 6) +#define HS_TX_COEF_MAP_0_SSTX_PRE_SHOOT GENMASK(5, 0) + + #define KHZ 1000 #define MHZ (KHZ * KHZ) +#define PHY_TUNING_ENTRY_PHY(o, m, v) { \ + .off = (o), \ + .mask = (m), \ + .val = (v), \ + .region = PTR_PHY \ + } + +#define PHY_TUNING_ENTRY_PCS(o, m, v) { \ + .off = (o), \ + .mask = (m), \ + .val = (v), \ + .region = PTR_PCS \ + } + +#define PHY_TUNING_ENTRY_PMA(o, m, v) { \ + .off = (o), \ + .mask = (m), \ + .val = (v), \ + .region = PTR_PMA, \ + } + +#define PHY_TUNING_ENTRY_LAST { .region = PTR_INVALID } + +#define for_each_phy_tune(tune) \ + for (; (tune)->region != PTR_INVALID; ++(tune)) + +struct exynos5_usbdrd_phy_tuning { + u32 off; + u32 mask; + u32 val; + char region; +#define PTR_INVALID 0 +#define PTR_PHY 1 +#define PTR_PCS 2 +#define PTR_PMA 3 +}; + +enum exynos5_usbdrd_phy_tuning_state { + PTS_UTMI_POSTINIT, + PTS_PIPE3_PREINIT, + PTS_PIPE3_INIT, + PTS_PIPE3_POSTINIT, + PTS_PIPE3_POSTLOCK, + PTS_MAX, +}; + enum exynos5_usbdrd_phy_id { EXYNOS5_DRDPHY_UTMI, EXYNOS5_DRDPHY_PIPE3, @@ -184,6 +361,7 @@ struct exynos5_usbdrd_phy_config { struct exynos5_usbdrd_phy_drvdata { const struct exynos5_usbdrd_phy_config *phy_cfg; + const struct exynos5_usbdrd_phy_tuning **phy_tunes; const struct phy_ops *phy_ops; const char * const *clk_names; int n_clks; @@ -200,6 +378,8 @@ struct exynos5_usbdrd_phy_drvdata { * struct exynos5_usbdrd_phy - driver data for USB 3.0 PHY * @dev: pointer to device instance of this platform device * @reg_phy: usb phy controller register memory base + * @reg_pcs: usb phy physical coding sublayer register memory base + * @reg_pma: usb phy physical media attachment register memory base * @clks: clocks for register access * @core_clks: core clocks for phy (ref, pipe3, utmi+, ITP, etc. as required) * @drv_data: pointer to SoC level driver data structure @@ -212,6 +392,8 @@ struct exynos5_usbdrd_phy_drvdata { struct exynos5_usbdrd_phy { struct device *dev; void __iomem *reg_phy; + void __iomem *reg_pcs; + void __iomem *reg_pma; struct clk_bulk_data *clks; struct clk_bulk_data *core_clks; const struct exynos5_usbdrd_phy_drvdata *drv_data; @@ -358,6 +540,45 @@ exynos5_usbdrd_utmi_set_refclk(struct phy_usb_instance *inst) return reg; } +static void +exynos5_usbdrd_apply_phy_tunes(struct exynos5_usbdrd_phy *phy_drd, + enum exynos5_usbdrd_phy_tuning_state state) +{ + const struct exynos5_usbdrd_phy_tuning *tune; + + tune = phy_drd->drv_data->phy_tunes[state]; + if (!tune) + return; + + for_each_phy_tune(tune) { + void __iomem *reg_base; + u32 reg = 0; + + switch (tune->region) { + case PTR_PHY: + reg_base = phy_drd->reg_phy; + break; + case PTR_PCS: + reg_base = phy_drd->reg_pcs; + break; + case PTR_PMA: + reg_base = phy_drd->reg_pma; + break; + default: + dev_warn_once(phy_drd->dev, + "unknown phy region %d\n", tune->region); + continue; + } + + if (~tune->mask) { + reg = readl(reg_base + tune->off); + reg &= ~tune->mask; + } + reg |= tune->val; + writel(reg, reg_base + tune->off); + } +} + static void exynos5_usbdrd_pipe3_init(struct exynos5_usbdrd_phy *phy_drd) { u32 reg; @@ -373,6 +594,129 @@ static void exynos5_usbdrd_pipe3_init(struct exynos5_usbdrd_phy *phy_drd) writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYTEST); } +static void +exynos5_usbdrd_usbdp_g2_v4_ctrl_pma_ready(struct exynos5_usbdrd_phy *phy_drd) +{ + void __iomem *regs_base = phy_drd->reg_phy; + u32 reg; + + /* link pipe_clock selection to pclk of PMA */ + reg = readl(regs_base + EXYNOS850_DRD_CLKRST); + reg |= CLKRST_LINK_PCLK_SEL; + writel(reg, regs_base + EXYNOS850_DRD_CLKRST); + + reg = readl(regs_base + EXYNOS850_DRD_SECPMACTL); + reg &= ~SECPMACTL_PMA_REF_FREQ_SEL; + reg |= FIELD_PREP_CONST(SECPMACTL_PMA_REF_FREQ_SEL, 1); + /* SFR reset */ + reg |= (SECPMACTL_PMA_LOW_PWR | SECPMACTL_PMA_APB_SW_RST); + reg &= ~(SECPMACTL_PMA_ROPLL_REF_CLK_SEL | + SECPMACTL_PMA_LCPLL_REF_CLK_SEL); + /* PMA power off */ + reg |= (SECPMACTL_PMA_TRSV_SW_RST | SECPMACTL_PMA_CMN_SW_RST | + SECPMACTL_PMA_INIT_SW_RST); + writel(reg, regs_base + EXYNOS850_DRD_SECPMACTL); + + udelay(1); + + reg = readl(regs_base + EXYNOS850_DRD_SECPMACTL); + reg &= ~SECPMACTL_PMA_LOW_PWR; + writel(reg, regs_base + EXYNOS850_DRD_SECPMACTL); + + udelay(1); + + /* release override */ + reg = readl(regs_base + EXYNOS850_DRD_LINKCTRL); + reg &= ~LINKCTRL_FORCE_PIPE_EN; + writel(reg, regs_base + EXYNOS850_DRD_LINKCTRL); + + udelay(1); + + /* APB enable */ + reg = readl(regs_base + EXYNOS850_DRD_SECPMACTL); + reg &= ~SECPMACTL_PMA_APB_SW_RST; + writel(reg, regs_base + EXYNOS850_DRD_SECPMACTL); +} + +static void +exynos5_usbdrd_usbdp_g2_v4_pma_lane_mux_sel(struct exynos5_usbdrd_phy *phy_drd) +{ + void __iomem *regs_base = phy_drd->reg_pma; + u32 reg; + + /* lane configuration: USB on all lanes */ + reg = readl(regs_base + EXYNOS9_PMA_USBDP_CMN_REG00B8); + reg &= ~CMN_REG00B8_LANE_MUX_SEL_DP; + writel(reg, regs_base + EXYNOS9_PMA_USBDP_CMN_REG00B8); + + /* + * FIXME: below code supports one connector orientation only. It needs + * updating once we can receive connector events. + */ + /* override of TX receiver detector and comparator: lane 1 */ + reg = readl(regs_base + EXYNOS9_PMA_USBDP_TRSV_REG0413); + reg &= ~TRSV_REG0413_OVRD_LN1_TX_RXD_COMP_EN; + reg &= ~TRSV_REG0413_OVRD_LN1_TX_RXD_EN; + writel(reg, regs_base + EXYNOS9_PMA_USBDP_TRSV_REG0413); + + /* lane 3 */ + reg = readl(regs_base + EXYNOS9_PMA_USBDP_TRSV_REG0813); + reg |= TRSV_REG0813_OVRD_LN3_TX_RXD_COMP_EN; + reg |= TRSV_REG0813_OVRD_LN3_TX_RXD_EN; + writel(reg, regs_base + EXYNOS9_PMA_USBDP_TRSV_REG0813); +} + +static int +exynos5_usbdrd_usbdp_g2_v4_pma_check_pll_lock(struct exynos5_usbdrd_phy *phy_drd) +{ + static const unsigned int timeout_us = 40000; + static const unsigned int sleep_us = 40; + static const u32 locked = (CMN_REG01C0_ANA_LCPLL_LOCK_DONE | + CMN_REG01C0_ANA_LCPLL_AFC_DONE); + u32 reg; + int err; + + err = readl_poll_timeout( + phy_drd->reg_pma + EXYNOS9_PMA_USBDP_CMN_REG01C0, + reg, (reg & locked) == locked, sleep_us, timeout_us); + if (err) + dev_err(phy_drd->dev, + "timed out waiting for PLL lock: %#.8x\n", reg); + + return err; +} + +static void +exynos5_usbdrd_usbdp_g2_v4_pma_check_cdr_lock(struct exynos5_usbdrd_phy *phy_drd) +{ + static const unsigned int timeout_us = 40000; + static const unsigned int sleep_us = 40; + static const u32 locked = + (TRSV_REG03C3_LN0_MON_RX_CDR_AFC_DONE + | TRSV_REG03C3_LN0_MON_RX_CDR_CAL_DONE + | TRSV_REG03C3_LN0_MON_RX_CDR_FLD_PLL_MODE_DONE + | TRSV_REG03C3_LN0_MON_RX_CDR_LOCK_DONE); + u32 reg; + int err; + + err = readl_poll_timeout( + phy_drd->reg_pma + EXYNOS9_PMA_USBDP_TRSV_REG03C3, + reg, (reg & locked) == locked, sleep_us, timeout_us); + if (!err) + return; + + dev_err(phy_drd->dev, + "timed out waiting for CDR lock (l0): %#.8x, retrying\n", reg); + + /* based on cable orientation, this might be on the other phy port */ + err = readl_poll_timeout( + phy_drd->reg_pma + EXYNOS9_PMA_USBDP_TRSV_REG07C3, + reg, (reg & locked) == locked, sleep_us, timeout_us); + if (err) + dev_err(phy_drd->dev, + "timed out waiting for CDR lock (l2): %#.8x\n", reg); +} + static void exynos5_usbdrd_utmi_init(struct exynos5_usbdrd_phy *phy_drd) { u32 reg; @@ -705,10 +1049,29 @@ static const struct phy_ops exynos5_usbdrd_phy_ops = { .owner = THIS_MODULE, }; +static void +exynos5_usbdrd_usb_v3p1_pipe_override(struct exynos5_usbdrd_phy *phy_drd) +{ + void __iomem *regs_base = phy_drd->reg_phy; + u32 reg; + + /* force pipe3 signal for link */ + reg = readl(regs_base + EXYNOS850_DRD_LINKCTRL); + reg &= ~LINKCTRL_FORCE_PHYSTATUS; + reg |= LINKCTRL_FORCE_PIPE_EN | LINKCTRL_FORCE_RXELECIDLE; + writel(reg, regs_base + EXYNOS850_DRD_LINKCTRL); + + /* PMA disable */ + reg = readl(regs_base + EXYNOS850_DRD_SECPMACTL); + reg |= SECPMACTL_PMA_LOW_PWR; + writel(reg, regs_base + EXYNOS850_DRD_SECPMACTL); +} + static void exynos850_usbdrd_utmi_init(struct exynos5_usbdrd_phy *phy_drd) { void __iomem *regs_base = phy_drd->reg_phy; u32 reg; + u32 ss_ports; /* * Disable HWACG (hardware auto clock gating control). This will force @@ -719,8 +1082,16 @@ static void exynos850_usbdrd_utmi_init(struct exynos5_usbdrd_phy *phy_drd) reg |= LINKCTRL_FORCE_QACT; writel(reg, regs_base + EXYNOS850_DRD_LINKCTRL); + reg = readl(regs_base + EXYNOS850_DRD_LINKPORT); + ss_ports = FIELD_GET(LINKPORT_HOST_NUM_U3, reg); + /* Start PHY Reset (POR=high) */ reg = readl(regs_base + EXYNOS850_DRD_CLKRST); + if (ss_ports) { + reg |= CLKRST_PHY20_SW_POR; + reg |= CLKRST_PHY20_SW_POR_SEL; + reg |= CLKRST_PHY_RESET_SEL; + } reg |= CLKRST_PHY_SW_RST; writel(reg, regs_base + EXYNOS850_DRD_CLKRST); @@ -773,6 +1144,10 @@ static void exynos850_usbdrd_utmi_init(struct exynos5_usbdrd_phy *phy_drd) } writel(reg, regs_base + EXYNOS850_DRD_SSPPLLCTL); + if (phy_drd->drv_data->phy_tunes) + exynos5_usbdrd_apply_phy_tunes(phy_drd, + PTS_UTMI_POSTINIT); + /* Power up PHY analog blocks */ reg = readl(regs_base + EXYNOS850_DRD_HSP_TEST); reg &= ~HSP_TEST_SIDDQ; @@ -781,6 +1156,10 @@ static void exynos850_usbdrd_utmi_init(struct exynos5_usbdrd_phy *phy_drd) /* Finish PHY reset (POR=low) */ fsleep(10); /* required before doing POR=low */ reg = readl(regs_base + EXYNOS850_DRD_CLKRST); + if (ss_ports) { + reg |= CLKRST_PHY20_SW_POR_SEL; + reg &= ~CLKRST_PHY20_SW_POR; + } reg &= ~(CLKRST_PHY_SW_RST | CLKRST_PORT_RST); writel(reg, regs_base + EXYNOS850_DRD_CLKRST); fsleep(75); /* required after POR=low for guaranteed PHY clock */ @@ -789,6 +1168,9 @@ static void exynos850_usbdrd_utmi_init(struct exynos5_usbdrd_phy *phy_drd) reg = readl(regs_base + EXYNOS850_DRD_HSP); reg &= ~HSP_FSV_OUT_EN; writel(reg, regs_base + EXYNOS850_DRD_HSP); + + if (ss_ports) + exynos5_usbdrd_usb_v3p1_pipe_override(phy_drd); } static int exynos850_usbdrd_phy_init(struct phy *phy) @@ -853,6 +1235,85 @@ static const struct phy_ops exynos850_usbdrd_phy_ops = { .owner = THIS_MODULE, }; +static void exynos5_usbdrd_gs101_pipe3_init(struct exynos5_usbdrd_phy *phy_drd) +{ + void __iomem *regs_pma = phy_drd->reg_pma; + void __iomem *regs_phy = phy_drd->reg_phy; + u32 reg; + + exynos5_usbdrd_usbdp_g2_v4_ctrl_pma_ready(phy_drd); + + /* force aux off */ + reg = readl(regs_pma + EXYNOS9_PMA_USBDP_CMN_REG0008); + reg &= ~CMN_REG0008_AUX_EN; + reg |= CMN_REG0008_OVRD_AUX_EN; + writel(reg, regs_pma + EXYNOS9_PMA_USBDP_CMN_REG0008); + + exynos5_usbdrd_apply_phy_tunes(phy_drd, PTS_PIPE3_PREINIT); + exynos5_usbdrd_apply_phy_tunes(phy_drd, PTS_PIPE3_INIT); + exynos5_usbdrd_apply_phy_tunes(phy_drd, PTS_PIPE3_POSTINIT); + + exynos5_usbdrd_usbdp_g2_v4_pma_lane_mux_sel(phy_drd); + + /* reset release from port */ + reg = readl(regs_phy + EXYNOS850_DRD_SECPMACTL); + reg &= ~(SECPMACTL_PMA_TRSV_SW_RST | SECPMACTL_PMA_CMN_SW_RST | + SECPMACTL_PMA_INIT_SW_RST); + writel(reg, regs_phy + EXYNOS850_DRD_SECPMACTL); + + if (!exynos5_usbdrd_usbdp_g2_v4_pma_check_pll_lock(phy_drd)) + exynos5_usbdrd_usbdp_g2_v4_pma_check_cdr_lock(phy_drd); +} + +static int exynos5_usbdrd_gs101_phy_init(struct phy *phy) +{ + struct phy_usb_instance *inst = phy_get_drvdata(phy); + struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst); + int ret; + + if (inst->phy_cfg->id == EXYNOS5_DRDPHY_UTMI) { + /* Power-on PHY ... */ + ret = regulator_bulk_enable(phy_drd->drv_data->n_regulators, + phy_drd->regulators); + if (ret) { + dev_err(phy_drd->dev, + "Failed to enable PHY regulator(s)\n"); + return ret; + } + } + /* + * ... and ungate power via PMU. Without this here, we get an SError + * trying to access PMA registers + */ + exynos5_usbdrd_phy_isol(inst, false); + + return exynos850_usbdrd_phy_init(phy); +} + +static int exynos5_usbdrd_gs101_phy_exit(struct phy *phy) +{ + struct phy_usb_instance *inst = phy_get_drvdata(phy); + struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst); + int ret; + + if (inst->phy_cfg->id != EXYNOS5_DRDPHY_UTMI) + return 0; + + ret = exynos850_usbdrd_phy_exit(phy); + if (ret) + return ret; + + exynos5_usbdrd_phy_isol(inst, true); + return regulator_bulk_disable(phy_drd->drv_data->n_regulators, + phy_drd->regulators); +} + +static const struct phy_ops gs101_usbdrd_phy_ops = { + .init = exynos5_usbdrd_gs101_phy_init, + .exit = exynos5_usbdrd_gs101_phy_exit, + .owner = THIS_MODULE, +}; + static int exynos5_usbdrd_phy_clk_handle(struct exynos5_usbdrd_phy *phy_drd) { int ret; @@ -1011,8 +1472,186 @@ static const struct exynos5_usbdrd_phy_drvdata exynos850_usbdrd_phy = { .n_regulators = ARRAY_SIZE(exynos5_regulator_names), }; +static const struct exynos5_usbdrd_phy_config phy_cfg_gs101[] = { + { + .id = EXYNOS5_DRDPHY_UTMI, + .phy_isol = exynos5_usbdrd_phy_isol, + .phy_init = exynos850_usbdrd_utmi_init, + }, + { + .id = EXYNOS5_DRDPHY_PIPE3, + .phy_isol = exynos5_usbdrd_phy_isol, + .phy_init = exynos5_usbdrd_gs101_pipe3_init, + }, +}; + +static const struct exynos5_usbdrd_phy_tuning gs101_tunes_utmi_postinit[] = { + PHY_TUNING_ENTRY_PHY(EXYNOS850_DRD_HSPPARACON, + (HSPPARACON_TXVREF | HSPPARACON_TXRES | + HSPPARACON_TXPREEMPAMP | HSPPARACON_SQRX | + HSPPARACON_COMPDIS), + (FIELD_PREP_CONST(HSPPARACON_TXVREF, 6) | + FIELD_PREP_CONST(HSPPARACON_TXRES, 1) | + FIELD_PREP_CONST(HSPPARACON_TXPREEMPAMP, 3) | + FIELD_PREP_CONST(HSPPARACON_SQRX, 5) | + FIELD_PREP_CONST(HSPPARACON_COMPDIS, 7))), + PHY_TUNING_ENTRY_LAST +}; + +static const struct exynos5_usbdrd_phy_tuning gs101_tunes_pipe3_preinit[] = { + /* preinit */ + /* CDR data mode exit GEN1 ON / GEN2 OFF */ + PHY_TUNING_ENTRY_PMA(0x0c8c, -1, 0xff), + PHY_TUNING_ENTRY_PMA(0x1c8c, -1, 0xff), + PHY_TUNING_ENTRY_PMA(0x0c9c, -1, 0x7d), + PHY_TUNING_ENTRY_PMA(0x1c9c, -1, 0x7d), + /* improve EDS distribution */ + PHY_TUNING_ENTRY_PMA(0x0e7c, -1, 0x06), + PHY_TUNING_ENTRY_PMA(0x09e0, -1, 0x00), + PHY_TUNING_ENTRY_PMA(0x09e4, -1, 0x36), + PHY_TUNING_ENTRY_PMA(0x1e7c, -1, 0x06), + PHY_TUNING_ENTRY_PMA(0x1e90, -1, 0x00), + PHY_TUNING_ENTRY_PMA(0x1e94, -1, 0x36), + /* improve LVCC */ + PHY_TUNING_ENTRY_PMA(0x08f0, -1, 0x30), + PHY_TUNING_ENTRY_PMA(0x18f0, -1, 0x30), + /* LFPS RX VIH shmoo hole */ + PHY_TUNING_ENTRY_PMA(0x0a08, -1, 0x0c), + PHY_TUNING_ENTRY_PMA(0x1a08, -1, 0x0c), + /* remove unrelated option for v4 phy */ + PHY_TUNING_ENTRY_PMA(0x0a0c, -1, 0x05), + PHY_TUNING_ENTRY_PMA(0x1a0c, -1, 0x05), + /* improve Gen2 LVCC */ + PHY_TUNING_ENTRY_PMA(0x00f8, -1, 0x1c), + PHY_TUNING_ENTRY_PMA(0x00fc, -1, 0x54), + /* Change Vth of RCV_DET because of TD 7.40 Polling Retry Test */ + PHY_TUNING_ENTRY_PMA(0x104c, -1, 0x07), + PHY_TUNING_ENTRY_PMA(0x204c, -1, 0x07), + /* reduce Ux Exit time, assuming 26MHz clock */ + /* Gen1 */ + PHY_TUNING_ENTRY_PMA(0x0ca8, -1, 0x00), + PHY_TUNING_ENTRY_PMA(0x0cac, -1, 0x04), + PHY_TUNING_ENTRY_PMA(0x1ca8, -1, 0x00), + PHY_TUNING_ENTRY_PMA(0x1cac, -1, 0x04), + /* Gen2 */ + PHY_TUNING_ENTRY_PMA(0x0cb8, -1, 0x00), + PHY_TUNING_ENTRY_PMA(0x0cbc, -1, 0x04), + PHY_TUNING_ENTRY_PMA(0x1cb8, -1, 0x00), + PHY_TUNING_ENTRY_PMA(0x1cbc, -1, 0x04), + /* RX impedance setting */ + PHY_TUNING_ENTRY_PMA(0x0bb0, 0x03, 0x01), + PHY_TUNING_ENTRY_PMA(0x0bb4, 0xf0, 0xa0), + PHY_TUNING_ENTRY_PMA(0x1bb0, 0x03, 0x01), + PHY_TUNING_ENTRY_PMA(0x1bb4, 0xf0, 0xa0), + + PHY_TUNING_ENTRY_LAST +}; + +static const struct exynos5_usbdrd_phy_tuning gs101_tunes_pipe3_init[] = { + /* init */ + /* abnormal common pattern mask */ + PHY_TUNING_ENTRY_PCS(EXYNOS9_PCS_BACK_END_MODE_VEC, + BACK_END_MODE_VEC_DISABLE_DATA_MASK, 0), + /* de-serializer enabled when U2 */ + PHY_TUNING_ENTRY_PCS(EXYNOS9_PCS_OUT_VEC_2, PCS_OUT_VEC_B4_DYNAMIC, + PCS_OUT_VEC_B4_SEL_OUT), + /* TX Keeper Disable, Squelch on when U3 */ + PHY_TUNING_ENTRY_PCS(EXYNOS9_PCS_OUT_VEC_3, PCS_OUT_VEC_B7_DYNAMIC, + PCS_OUT_VEC_B7_SEL_OUT | PCS_OUT_VEC_B2_SEL_OUT), + PHY_TUNING_ENTRY_PCS(EXYNOS9_PCS_NS_VEC_PS1_N1, -1, + (FIELD_PREP_CONST(NS_VEC_NS_REQ, 5) | + NS_VEC_ENABLE_TIMER | + FIELD_PREP_CONST(NS_VEC_SEL_TIMEOUT, 3))), + PHY_TUNING_ENTRY_PCS(EXYNOS9_PCS_NS_VEC_PS2_N0, -1, + (FIELD_PREP_CONST(NS_VEC_NS_REQ, 1) | + NS_VEC_ENABLE_TIMER | + FIELD_PREP_CONST(NS_VEC_SEL_TIMEOUT, 3) | + FIELD_PREP_CONST(NS_VEC_COND_MASK, 2) | + FIELD_PREP_CONST(NS_VEC_EXP_COND, 2))), + PHY_TUNING_ENTRY_PCS(EXYNOS9_PCS_NS_VEC_PS3_N0, -1, + (FIELD_PREP_CONST(NS_VEC_NS_REQ, 1) | + NS_VEC_ENABLE_TIMER | + FIELD_PREP_CONST(NS_VEC_SEL_TIMEOUT, 3) | + FIELD_PREP_CONST(NS_VEC_COND_MASK, 7) | + FIELD_PREP_CONST(NS_VEC_EXP_COND, 7))), + PHY_TUNING_ENTRY_PCS(EXYNOS9_PCS_TIMEOUT_0, -1, 112), + /* Block Aligner Type B */ + PHY_TUNING_ENTRY_PCS(EXYNOS9_PCS_RX_CONTROL, 0, + RX_CONTROL_EN_BLOCK_ALIGNER_TYPE_B), + /* Block align at TS1/TS2 for Gen2 stability (Gen2 only) */ + PHY_TUNING_ENTRY_PCS(EXYNOS9_PCS_RX_CONTROL_DEBUG, + RX_CONTROL_DEBUG_NUM_COM_FOUND, + (RX_CONTROL_DEBUG_EN_TS_CHECK | + /* + * increase pcs ts1 adding packet-cnt 1 --> 4 + * lnx_rx_valid_rstn_delay_rise_sp/ssp : + * 19.6us(0x200) -> 15.3us(0x4) + */ + FIELD_PREP_CONST(RX_CONTROL_DEBUG_NUM_COM_FOUND, 4))), + /* Gen1 Tx DRIVER pre-shoot, de-emphasis, level ctrl */ + PHY_TUNING_ENTRY_PCS(EXYNOS9_PCS_HS_TX_COEF_MAP_0, + (HS_TX_COEF_MAP_0_SSTX_DEEMP | HS_TX_COEF_MAP_0_SSTX_LEVEL | + HS_TX_COEF_MAP_0_SSTX_PRE_SHOOT), + (FIELD_PREP_CONST(HS_TX_COEF_MAP_0_SSTX_DEEMP, 8) | + FIELD_PREP_CONST(HS_TX_COEF_MAP_0_SSTX_LEVEL, 0xb) | + FIELD_PREP_CONST(HS_TX_COEF_MAP_0_SSTX_PRE_SHOOT, 0))), + /* Gen2 Tx DRIVER level ctrl */ + PHY_TUNING_ENTRY_PCS(EXYNOS9_PCS_LOCAL_COEF, + LOCAL_COEF_PMA_CENTER_COEF, + FIELD_PREP_CONST(LOCAL_COEF_PMA_CENTER_COEF, 0xb)), + /* Gen2 U1 exit LFPS duration : 900ns ~ 1.2us */ + PHY_TUNING_ENTRY_PCS(EXYNOS9_PCS_TIMEOUT_3, -1, 4096), + /* set skp_remove_th 0x2 -> 0x7 for avoiding retry problem. */ + PHY_TUNING_ENTRY_PCS(EXYNOS9_PCS_EBUF_PARAM, + EBUF_PARAM_SKP_REMOVE_TH_EMPTY_MODE, + FIELD_PREP_CONST(EBUF_PARAM_SKP_REMOVE_TH_EMPTY_MODE, 0x7)), + + PHY_TUNING_ENTRY_LAST +}; + +static const struct exynos5_usbdrd_phy_tuning gs101_tunes_pipe3_postlock[] = { + /* Squelch off when U3 */ + PHY_TUNING_ENTRY_PCS(EXYNOS9_PCS_OUT_VEC_3, PCS_OUT_VEC_B2_SEL_OUT, 0), + + PHY_TUNING_ENTRY_LAST +}; + +static const struct exynos5_usbdrd_phy_tuning *gs101_tunes[PTS_MAX] = { + [PTS_UTMI_POSTINIT] = gs101_tunes_utmi_postinit, + [PTS_PIPE3_PREINIT] = gs101_tunes_pipe3_preinit, + [PTS_PIPE3_INIT] = gs101_tunes_pipe3_init, + [PTS_PIPE3_POSTLOCK] = gs101_tunes_pipe3_postlock, +}; + +static const char * const gs101_clk_names[] = { + "phy", "ctrl_aclk", "ctrl_pclk", "scl_pclk", +}; + +static const char * const gs101_regulator_names[] = { + "pll", + "dvdd-usb20", "vddh-usb20", "vdd33-usb20", + "vdda-usbdp", "vddh-usbdp", +}; + +static const struct exynos5_usbdrd_phy_drvdata gs101_usbd31rd_phy = { + .phy_cfg = phy_cfg_gs101, + .phy_tunes = gs101_tunes, + .phy_ops = &gs101_usbdrd_phy_ops, + .pmu_offset_usbdrd0_phy = GS101_PHY_CTRL_USB20, + .pmu_offset_usbdrd0_phy_ss = GS101_PHY_CTRL_USBDP, + .clk_names = gs101_clk_names, + .n_clks = ARRAY_SIZE(gs101_clk_names), + .core_clk_names = exynos5_core_clk_names, + .n_core_clks = ARRAY_SIZE(exynos5_core_clk_names), + .regulator_names = gs101_regulator_names, + .n_regulators = ARRAY_SIZE(gs101_regulator_names), +}; + static const struct of_device_id exynos5_usbdrd_phy_of_match[] = { { + .compatible = "google,gs101-usb31drd-phy", + .data = &gs101_usbd31rd_phy + }, { .compatible = "samsung,exynos5250-usbdrd-phy", .data = &exynos5250_usbdrd_phy }, { @@ -1051,16 +1690,35 @@ static int exynos5_usbdrd_phy_probe(struct platform_device *pdev) dev_set_drvdata(dev, phy_drd); phy_drd->dev = dev; - phy_drd->reg_phy = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(phy_drd->reg_phy)) - return PTR_ERR(phy_drd->reg_phy); - drv_data = of_device_get_match_data(dev); if (!drv_data) return -EINVAL; - phy_drd->drv_data = drv_data; + if (of_property_present(dev->of_node, "reg-names")) { + void __iomem *reg; + + reg = devm_platform_ioremap_resource_byname(pdev, "phy"); + if (IS_ERR(reg)) + return PTR_ERR(reg); + phy_drd->reg_phy = reg; + + reg = devm_platform_ioremap_resource_byname(pdev, "pcs"); + if (IS_ERR(reg)) + return PTR_ERR(reg); + phy_drd->reg_pcs = reg; + + reg = devm_platform_ioremap_resource_byname(pdev, "pma"); + if (IS_ERR(reg)) + return PTR_ERR(reg); + phy_drd->reg_pma = reg; + } else { + /* DTB with just a single region */ + phy_drd->reg_phy = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(phy_drd->reg_phy)) + return PTR_ERR(phy_drd->reg_phy); + } + ret = exynos5_usbdrd_phy_clk_handle(phy_drd); if (ret) return ret; diff --git a/include/linux/soc/samsung/exynos-regs-pmu.h b/include/linux/soc/samsung/exynos-regs-pmu.h index aa840ed043e1..6765160eaab2 100644 --- a/include/linux/soc/samsung/exynos-regs-pmu.h +++ b/include/linux/soc/samsung/exynos-regs-pmu.h @@ -657,4 +657,8 @@ #define EXYNOS5433_PAD_RETENTION_UFS_OPTION (0x3268) #define EXYNOS5433_PAD_RETENTION_FSYSGENIO_OPTION (0x32A8) +/* For GS101 */ +#define GS101_PHY_CTRL_USB20 0x3eb0 +#define GS101_PHY_CTRL_USBDP 0x3eb4 + #endif /* __LINUX_SOC_EXYNOS_REGS_PMU_H */