]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
phy: usb: add support for bcm74110
authorJustin Chen <justin.chen@broadcom.com>
Wed, 2 Apr 2025 18:51:59 +0000 (11:51 -0700)
committerVinod Koul <vkoul@kernel.org>
Fri, 11 Apr 2025 07:21:13 +0000 (12:51 +0530)
bcm74110 adds a freerun utmi/ref clock that saves further power during
suspend states. A tune is also necessary to pass USB compliance test.

Signed-off-by: Justin Chen <justin.chen@broadcom.com>
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
Link: https://lore.kernel.org/r/20250402185159.2976920-3-justin.chen@broadcom.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
drivers/phy/broadcom/phy-brcm-usb-init-synopsys.c
drivers/phy/broadcom/phy-brcm-usb-init.h
drivers/phy/broadcom/phy-brcm-usb.c

index dc452610934add4825e044d1141b9fbe1b79a97a..8a5ed50f2da07490cbe59c546c02d3855098c02f 100644 (file)
@@ -43,6 +43,8 @@
 #define   USB_CTRL_SETUP_tca_drv_sel_MASK              BIT(24)
 #define   USB_CTRL_SETUP_STRAP_IPP_SEL_MASK            BIT(25)
 #define USB_CTRL_USB_PM                        0x04
+#define   USB_CTRL_USB_PM_REF_S2_CLK_SWITCH_EN_MASK    BIT(1)
+#define   USB_CTRL_USB_PM_UTMI_S2_CLK_SWITCH_EN_MASK   BIT(2)
 #define   USB_CTRL_USB_PM_XHC_S2_CLK_SWITCH_EN_MASK    BIT(3)
 #define   USB_CTRL_USB_PM_XHC_PME_EN_MASK              BIT(4)
 #define   USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK         BIT(22)
 #define   USB_CTRL_CTLR_CSHCR_ctl_pme_en_MASK          BIT(18)
 #define USB_CTRL_P0_U2PHY_CFG1         0x68
 #define   USB_CTRL_P0_U2PHY_CFG1_COMMONONN_MASK                BIT(10)
+#define USB_CTRL_P0_U2PHY_CFG2         0x6c
+#define   USB_CTRL_P0_U2PHY_CFG2_TXVREFTUNE0_MASK      GENMASK(20, 17)
+#define   USB_CTRL_P0_U2PHY_CFG2_TXVREFTUNE0_SHIFT     17
+#define   USB_CTRL_P0_U2PHY_CFG2_TXRESTUNE0_MASK       GENMASK(24, 23)
+#define   USB_CTRL_P0_U2PHY_CFG2_TXRESTUNE0_SHIFT      23
+#define   USB_CTRL_P0_U2PHY_CFG2_TXPREEMPAMPTUNE0_MASK GENMASK(26, 25)
+#define   USB_CTRL_P0_U2PHY_CFG2_TXPREEMPAMPTUNE0_SHIFT        25
 
 /* Register definitions for the USB_PHY block in 7211b0 */
 #define USB_PHY_PLL_CTL                        0x00
@@ -369,6 +378,42 @@ static void usb_uninit_common_7216(struct brcm_usb_init_params *params)
        }
 }
 
+static void usb_init_common_74110(struct brcm_usb_init_params *params)
+{
+       void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
+       u32 reg;
+
+       reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_PM));
+       reg &= ~(USB_CTRL_MASK(USB_PM, REF_S2_CLK_SWITCH_EN) |
+               USB_CTRL_MASK(USB_PM, UTMI_S2_CLK_SWITCH_EN));
+       brcm_usb_writel(reg, USB_CTRL_REG(ctrl, USB_PM));
+
+       usb_init_common_7216(params);
+
+       reg = brcm_usb_readl(USB_CTRL_REG(ctrl, P0_U2PHY_CFG2));
+       reg &= ~(USB_CTRL_P0_U2PHY_CFG2_TXVREFTUNE0_MASK |
+                USB_CTRL_P0_U2PHY_CFG2_TXRESTUNE0_MASK |
+                USB_CTRL_P0_U2PHY_CFG2_TXPREEMPAMPTUNE0_MASK);
+       reg |= (0x6 << USB_CTRL_P0_U2PHY_CFG2_TXVREFTUNE0_SHIFT) |
+               (0x3 << USB_CTRL_P0_U2PHY_CFG2_TXRESTUNE0_SHIFT) |
+               (0x2 << USB_CTRL_P0_U2PHY_CFG2_TXPREEMPAMPTUNE0_SHIFT);
+       brcm_usb_writel(reg, USB_CTRL_REG(ctrl, P0_U2PHY_CFG2));
+}
+
+static void usb_uninit_common_74110(struct brcm_usb_init_params *params)
+{
+       void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
+       u32 reg;
+
+       if (params->wake_enabled) {
+               reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_PM));
+               reg |= (USB_CTRL_MASK(USB_PM, REF_S2_CLK_SWITCH_EN) |
+                      USB_CTRL_MASK(USB_PM, UTMI_S2_CLK_SWITCH_EN));
+               brcm_usb_writel(reg, USB_CTRL_REG(ctrl, USB_PM));
+       }
+       usb_uninit_common_7216(params);
+}
+
 static void usb_uninit_common_7211b0(struct brcm_usb_init_params *params)
 {
        void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
@@ -426,6 +471,16 @@ static void usb_set_dual_select(struct brcm_usb_init_params *params)
        brcm_usb_writel(reg, USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
 }
 
+static const struct brcm_usb_init_ops bcm74110_ops = {
+       .init_ipp = usb_init_ipp,
+       .init_common = usb_init_common_74110,
+       .init_xhci = usb_init_xhci,
+       .uninit_common = usb_uninit_common_74110,
+       .uninit_xhci = usb_uninit_xhci,
+       .get_dual_select = usb_get_dual_select,
+       .set_dual_select = usb_set_dual_select,
+};
+
 static const struct brcm_usb_init_ops bcm7216_ops = {
        .init_ipp = usb_init_ipp,
        .init_common = usb_init_common_7216,
@@ -446,6 +501,12 @@ static const struct brcm_usb_init_ops bcm7211b0_ops = {
        .set_dual_select = usb_set_dual_select,
 };
 
+void brcm_usb_dvr_init_74110(struct brcm_usb_init_params *params)
+{
+       params->family_name = "74110";
+       params->ops = &bcm74110_ops;
+}
+
 void brcm_usb_dvr_init_7216(struct brcm_usb_init_params *params)
 {
 
index c1a88f5cd4cd8e4e47bf27a276e80e51970f0abf..4c7be78d0b14cb01a74935397591a458c27ad14f 100644 (file)
@@ -72,6 +72,7 @@ struct  brcm_usb_init_params {
        bool wake_enabled;
 };
 
+void brcm_usb_dvr_init_74110(struct brcm_usb_init_params *params);
 void brcm_usb_dvr_init_4908(struct brcm_usb_init_params *params);
 void brcm_usb_dvr_init_7445(struct brcm_usb_init_params *params);
 void brcm_usb_dvr_init_7216(struct brcm_usb_init_params *params);
index 6362ca5b7fb6b5a05d938a4885bc725c8c5824ec..0666864c2f7763b94a7475c28ff633125f011c0b 100644 (file)
@@ -283,6 +283,16 @@ static const struct attribute_group brcm_usb_phy_group = {
        .attrs = brcm_usb_phy_attrs,
 };
 
+static const struct match_chip_info chip_info_74110 = {
+       .init_func = &brcm_usb_dvr_init_74110,
+       .required_regs = {
+               BRCM_REGS_CTRL,
+               BRCM_REGS_XHCI_EC,
+               BRCM_REGS_XHCI_GBL,
+               -1,
+       },
+};
+
 static const struct match_chip_info chip_info_4908 = {
        .init_func = &brcm_usb_dvr_init_4908,
        .required_regs = {
@@ -325,6 +335,10 @@ static const struct match_chip_info chip_info_7445 = {
 };
 
 static const struct of_device_id brcm_usb_dt_ids[] = {
+       {
+               .compatible = "brcm,bcm74110-usb-phy",
+               .data = &chip_info_74110,
+       },
        {
                .compatible = "brcm,bcm4908-usb-phy",
                .data = &chip_info_4908,