From patchwork Wed Nov 27 10:58:17 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: 13886874 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 97258D609D2 for ; Wed, 27 Nov 2024 11:06:07 +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=4/cpVX9OLXGGz3qNovpXLfnOix+cS0YAzgAdkktJBiQ=; b=NtjpWAp3cz2smh tnPgbANpG8uhJOjLLhOE+CXxPGR6kqQY7qxjbuvcG5MBIg/7q1VqbwhkbIkg3KgzypylFWimQRwjL qv1OnEdRC6co23tpGT1BUQ7gCEYm6A5d6FfL7q9ZHn+p1cXTdW/09IH2lPb8bCTRNxuS4bnIddkXI ys8tAmj/9+AV5w8wPLku4MSuOjx1IHF63YWhCEznW3RIg1kPIp/7brJjDsHC2NrocP/uSRMU4W8xi OoR+owlOpe2R6amqSfTy7UzpCZX+Y9k4tiPg/MIcqsYZ0FcOz/f2W9snxf95Ua/F+VvjFEV0eUVOx DPYa+SjPWl70j+3zXjEw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tGFrz-0000000CwuG-1Vxv; Wed, 27 Nov 2024 11:06:07 +0000 Received: from mail-ej1-x62c.google.com ([2a00:1450:4864:20::62c]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tGFkP-0000000CvEH-16Jo for linux-phy@lists.infradead.org; Wed, 27 Nov 2024 10:58:19 +0000 Received: by mail-ej1-x62c.google.com with SMTP id a640c23a62f3a-aa55da18f89so399638166b.0 for ; Wed, 27 Nov 2024 02:58:16 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1732705096; x=1733309896; 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=AASoBGvbx8nrRldBio8kzQShrHQPCejymiRL3Jm8QQw=; b=d8zBBulNs6saf5nas+4ngM9mRv1QeOl3NB/fzk1ackVZUcQR3zBTkZaBFFJ0l3MCa3 wtSE/86KM2Cj0tvHNaxY6i+bplKcXLZqzAlXobT7ICv+9s9GUjzmHz950+XpoFE5KujQ 2OoxGa11pWZoJJIf0s2OQsHI/UcfWqKX8K7U3ie5maIk9DGs21o0L1AodgoEm638yjV+ widnb6Xg7yn0nE7k+CCkGgAXt2LnXoUbmApRi/iSirpxj0mYxCdJ4qzlspvw81pf/GMV wk7/eme2AJIXt6Yu6Ph3c6aW/srmR4Pw99W1O9sMjumD0CoUACTXFWBLQwZHrEOXof4e ABDw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732705096; x=1733309896; 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=AASoBGvbx8nrRldBio8kzQShrHQPCejymiRL3Jm8QQw=; b=U4N2XAErersodGZ3dcSeWjIUVzEbSqwrMVJulZy5r+pQU0eXKsI0Fwm8UOVE5EylFo tFdNqVH0gSRTF/OFKrj1b5dX/rT6BswvaDDG4N1SAFbjhZbA1xz2aIVZMV6rXNXuEhLq zFyMOMgELg1Z7gCTB4B4Zarv7yXeKknfprGqIsHiMxFL5DgYcE+3xGckMnh7YLP7001S 162Q0cxWcMo1F5TNCN25neXUSodXAjqrFMu/2G+KYEiGVXYLXxgmeAKFW5q/8BnuEQXT p4PUX3Qc8HxsVw8S0B3SUBfv5Kyiw8pKNDaBfQYYbDvFBGovYpx64eN16dAk39foOgzA vdQw== X-Forwarded-Encrypted: i=1; AJvYcCUpKUuYGvMkKPeo2ikvDjLQGBxjY4pJeH+DkULotm9vuR/se/GntXktiMz+Sws4mBv7hRWtg1G9n1Y=@lists.infradead.org X-Gm-Message-State: AOJu0YwmpFI19d1JPq9KlYS8U6Zei8dIQSBPiPXhsyQFP02Jmum18zfZ 0ZtUAP2bnlDeg89EzqODSDrTYiTCZvkb7wp0CXOE0amXeIb/xs9dcVcwYTGKrmw= X-Gm-Gg: ASbGncuVkkNkJPTRcEgJGGBRIUeiuUeUOCVx6MorCoNQ8ZxOmQ7uAmZHSfwlLIqffRL MIIJwTGpRAkpRoBJKlnf/ug87TiPLUSXiFrVJtmqYZ7WtOgXBcq/nDuTx6qg6mOQbZfCTUUqpai +tYaRAQpNWZKXreCjHnG1Aqog9p5g6lF6LgLqOYyxbrL+ilu0W7cw31Ldb1tBvqlqDHtSd06kE0 Nn+1Jhsjoecwlr4np8CWpVtqJpWWHzWFNsyaOKbRCrO1r74SUoDprzcG7PIh5b+WmtmixdCpscO oWiVwzhraeDWMDNl0YtgbzW4jAQ3sZrnzw== X-Google-Smtp-Source: AGHT+IF3uxkslq060bQu5IOXE2CVt35TZdsY8S2FoowTgID7ALlXsIj3b2YpVReHJiVUCHWHrA1DAQ== X-Received: by 2002:a17:907:7819:b0:aa5:b2b:f236 with SMTP id a640c23a62f3a-aa580f353f3mr179583566b.28.1732705095696; Wed, 27 Nov 2024 02:58:15 -0800 (PST) Received: from puffmais.c.googlers.com (64.227.90.34.bc.googleusercontent.com. [34.90.227.64]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-aa54a6db906sm412183566b.41.2024.11.27.02.58.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 27 Nov 2024 02:58:15 -0800 (PST) From: =?utf-8?q?Andr=C3=A9_Draszik?= Date: Wed, 27 Nov 2024 10:58:17 +0000 Subject: [PATCH 7/9] phy: exynos5-usbdrd: gs101: configure SS lanes based on orientation MIME-Version: 1.0 Message-Id: <20241127-gs101-phy-lanes-orientation-phy-v1-7-1b7fce24960b@linaro.org> References: <20241127-gs101-phy-lanes-orientation-phy-v1-0-1b7fce24960b@linaro.org> In-Reply-To: <20241127-gs101-phy-lanes-orientation-phy-v1-0-1b7fce24960b@linaro.org> To: Vinod Koul , Kishon Vijay Abraham I , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Marek Szyprowski , Sylwester Nawrocki , Alim Akhtar Cc: Peter Griffin , Tudor Ambarus , Sam Protsenko , 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-20241127_025817_307633_E93303DD X-CRM114-Status: GOOD ( 21.70 ) 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 USB SS lanes need to be configured based the connector orientation - at most two lanes will be in use for USB (and the remaining two for alternate modes like DP). For the USB link to come up in SS, the lane configuration registers have to be programmed accordingly. While we still need a way to be notified of the actual connector orientation and then reprogram the registers accordingly (at the moment the configuration happens just once during phy_init() and never again), we can prepare the code doing the configuration to take the orientation into account. Do so. Note: the mutex is needed to synchronize this with the upcoming connector orientation callback. Signed-off-by: André Draszik Reviewed-by: Peter Griffin Tested-by: Peter Griffin --- drivers/phy/samsung/phy-exynos5-usbdrd.c | 72 ++++++++++++++++++++++---------- 1 file changed, 51 insertions(+), 21 deletions(-) diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c index c1ce6fdeef31..1a34e9b4618a 100644 --- a/drivers/phy/samsung/phy-exynos5-usbdrd.c +++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c @@ -23,6 +23,7 @@ #include #include #include +#include /* Exynos USB PHY registers */ #define EXYNOS5_FSEL_9MHZ6 0x0 @@ -209,6 +210,10 @@ #define EXYNOS9_PMA_USBDP_CMN_REG00B8 0x02e0 #define CMN_REG00B8_LANE_MUX_SEL_DP GENMASK(3, 0) +#define CMN_REG00B8_LANE_MUX_SEL_DP_LANE3 BIT(3) +#define CMN_REG00B8_LANE_MUX_SEL_DP_LANE2 BIT(2) +#define CMN_REG00B8_LANE_MUX_SEL_DP_LANE1 BIT(1) +#define CMN_REG00B8_LANE_MUX_SEL_DP_LANE0 BIT(0) #define EXYNOS9_PMA_USBDP_CMN_REG01C0 0x0700 #define CMN_REG01C0_ANA_LCPLL_LOCK_DONE BIT(7) @@ -383,11 +388,13 @@ struct exynos5_usbdrd_phy_drvdata { * @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 + * @phy_mutex: mutex protecting phy_init/exit & TCPC callbacks * @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 * @regulators: regulators for phy + * @orientation: TypeC connector orientation - normal or flipped */ struct exynos5_usbdrd_phy { struct device *dev; @@ -397,6 +404,7 @@ struct exynos5_usbdrd_phy { struct clk_bulk_data *clks; struct clk_bulk_data *core_clks; const struct exynos5_usbdrd_phy_drvdata *drv_data; + struct mutex phy_mutex; struct phy_usb_instance { struct phy *phy; u32 index; @@ -406,6 +414,8 @@ struct exynos5_usbdrd_phy { } phys[EXYNOS5_DRDPHYS_NUM]; u32 extrefclk; struct regulator_bulk_data *regulators; + + enum typec_orientation orientation; }; static inline @@ -647,22 +657,38 @@ exynos5_usbdrd_usbdp_g2_v4_pma_lane_mux_sel(struct exynos5_usbdrd_phy *phy_drd) /* 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. + * USB on lanes 0 & 1 in normal mode, or 2 & 3 if reversed, DP on the + * other ones. */ + reg |= FIELD_PREP(CMN_REG00B8_LANE_MUX_SEL_DP, + ((phy_drd->orientation == TYPEC_ORIENTATION_NORMAL) + ? (CMN_REG00B8_LANE_MUX_SEL_DP_LANE3 + | CMN_REG00B8_LANE_MUX_SEL_DP_LANE2) + : (CMN_REG00B8_LANE_MUX_SEL_DP_LANE1 + | CMN_REG00B8_LANE_MUX_SEL_DP_LANE0))); + writel(reg, regs_base + EXYNOS9_PMA_USBDP_CMN_REG00B8); + /* 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; + if (phy_drd->orientation == TYPEC_ORIENTATION_NORMAL) { + reg &= ~TRSV_REG0413_OVRD_LN1_TX_RXD_COMP_EN; + reg &= ~TRSV_REG0413_OVRD_LN1_TX_RXD_EN; + } else { + 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; + if (phy_drd->orientation == TYPEC_ORIENTATION_NORMAL) { + reg |= TRSV_REG0813_OVRD_LN3_TX_RXD_COMP_EN; + reg |= TRSV_REG0813_OVRD_LN3_TX_RXD_EN; + } else { + 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); } @@ -700,21 +726,18 @@ exynos5_usbdrd_usbdp_g2_v4_pma_check_cdr_lock(struct exynos5_usbdrd_phy *phy_drd 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, + /* lane depends on cable orientation */ + (phy_drd->reg_pma + + ((phy_drd->orientation == TYPEC_ORIENTATION_NORMAL) + ? EXYNOS9_PMA_USBDP_TRSV_REG03C3 + : 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); + "timed out waiting for CDR(l%d) lock: %#.8x\n", + ((phy_drd->orientation == TYPEC_ORIENTATION_NORMAL) + ? 0 + : 2), reg); } static void exynos5_usbdrd_utmi_init(struct exynos5_usbdrd_phy *phy_drd) @@ -1184,7 +1207,8 @@ static int exynos850_usbdrd_phy_init(struct phy *phy) return ret; /* UTMI or PIPE3 specific init */ - inst->phy_cfg->phy_init(phy_drd); + scoped_guard(mutex, &phy_drd->phy_mutex) + inst->phy_cfg->phy_init(phy_drd); clk_bulk_disable_unprepare(phy_drd->drv_data->n_clks, phy_drd->clks); @@ -1203,6 +1227,8 @@ static int exynos850_usbdrd_phy_exit(struct phy *phy) if (ret) return ret; + guard(mutex)(&phy_drd->phy_mutex); + /* Set PHY clock and control HS PHY */ reg = readl(regs_base + EXYNOS850_DRD_UTMI); reg &= ~(UTMI_DP_PULLDOWN | UTMI_DM_PULLDOWN); @@ -1701,6 +1727,10 @@ static int exynos5_usbdrd_phy_probe(struct platform_device *pdev) return -EINVAL; phy_drd->drv_data = drv_data; + ret = devm_mutex_init(dev, &phy_drd->phy_mutex); + if (ret) + return ret; + if (of_property_present(dev->of_node, "reg-names")) { void __iomem *reg;