^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * MediaTek xHCI Host Controller Driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2015 MediaTek Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Author:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Chunfeng Yun <chunfeng.yun@mediatek.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/dma-mapping.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/iopoll.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/mfd/syscon.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/regulator/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "xhci.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "xhci-mtk.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) /* ip_pw_ctrl0 register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define CTRL0_IP_SW_RST BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) /* ip_pw_ctrl1 register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define CTRL1_IP_HOST_PDN BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) /* ip_pw_ctrl2 register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define CTRL2_IP_DEV_PDN BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) /* ip_pw_sts1 register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define STS1_IP_SLEEP_STS BIT(30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define STS1_U3_MAC_RST BIT(16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define STS1_XHCI_RST BIT(11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define STS1_SYS125_RST BIT(10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define STS1_REF_RST BIT(8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define STS1_SYSPLL_STABLE BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) /* ip_xhci_cap register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define CAP_U3_PORT_NUM(p) ((p) & 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define CAP_U2_PORT_NUM(p) (((p) >> 8) & 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) /* u3_ctrl_p register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define CTRL_U3_PORT_HOST_SEL BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define CTRL_U3_PORT_PDN BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define CTRL_U3_PORT_DIS BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) /* u2_ctrl_p register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define CTRL_U2_PORT_HOST_SEL BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define CTRL_U2_PORT_PDN BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define CTRL_U2_PORT_DIS BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) /* u2_phy_pll register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define CTRL_U2_FORCE_PLL_STB BIT(28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) /* usb remote wakeup registers in syscon */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) /* mt8173 etc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define PERI_WK_CTRL1 0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define WC1_IS_C(x) (((x) & 0xf) << 26) /* cycle debounce */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define WC1_IS_EN BIT(25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define WC1_IS_P BIT(6) /* polarity for ip sleep */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) /* mt2712 etc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define PERI_SSUSB_SPM_CTRL 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define SSC_IP_SLEEP_EN BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define SSC_SPM_INT_EN BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) enum ssusb_uwk_vers {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) SSUSB_UWK_V1 = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) SSUSB_UWK_V2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) static int xhci_mtk_host_enable(struct xhci_hcd_mtk *mtk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) struct mu3c_ippc_regs __iomem *ippc = mtk->ippc_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) u32 value, check_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) int u3_ports_disabled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) if (!mtk->has_ippc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) /* power on host ip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) value = readl(&ippc->ip_pw_ctr1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) value &= ~CTRL1_IP_HOST_PDN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) writel(value, &ippc->ip_pw_ctr1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) /* power on and enable u3 ports except skipped ones */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) for (i = 0; i < mtk->num_u3_ports; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) if ((0x1 << i) & mtk->u3p_dis_msk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) u3_ports_disabled++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) value = readl(&ippc->u3_ctrl_p[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) value &= ~(CTRL_U3_PORT_PDN | CTRL_U3_PORT_DIS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) value |= CTRL_U3_PORT_HOST_SEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) writel(value, &ippc->u3_ctrl_p[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) /* power on and enable all u2 ports */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) for (i = 0; i < mtk->num_u2_ports; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) value = readl(&ippc->u2_ctrl_p[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) value &= ~(CTRL_U2_PORT_PDN | CTRL_U2_PORT_DIS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) value |= CTRL_U2_PORT_HOST_SEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) writel(value, &ippc->u2_ctrl_p[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * wait for clocks to be stable, and clock domains reset to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * be inactive after power on and enable ports
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) check_val = STS1_SYSPLL_STABLE | STS1_REF_RST |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) STS1_SYS125_RST | STS1_XHCI_RST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) if (mtk->num_u3_ports > u3_ports_disabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) check_val |= STS1_U3_MAC_RST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) ret = readl_poll_timeout(&ippc->ip_pw_sts1, value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) (check_val == (value & check_val)), 100, 20000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) dev_err(mtk->dev, "clocks are not stable (0x%x)\n", value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) static int xhci_mtk_host_disable(struct xhci_hcd_mtk *mtk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) struct mu3c_ippc_regs __iomem *ippc = mtk->ippc_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) if (!mtk->has_ippc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) /* power down u3 ports except skipped ones */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) for (i = 0; i < mtk->num_u3_ports; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) if ((0x1 << i) & mtk->u3p_dis_msk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) value = readl(&ippc->u3_ctrl_p[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) value |= CTRL_U3_PORT_PDN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) writel(value, &ippc->u3_ctrl_p[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) /* power down all u2 ports */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) for (i = 0; i < mtk->num_u2_ports; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) value = readl(&ippc->u2_ctrl_p[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) value |= CTRL_U2_PORT_PDN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) writel(value, &ippc->u2_ctrl_p[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) /* power down host ip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) value = readl(&ippc->ip_pw_ctr1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) value |= CTRL1_IP_HOST_PDN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) writel(value, &ippc->ip_pw_ctr1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) /* wait for host ip to sleep */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) ret = readl_poll_timeout(&ippc->ip_pw_sts1, value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) (value & STS1_IP_SLEEP_STS), 100, 100000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) dev_err(mtk->dev, "ip sleep failed!!!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) static int xhci_mtk_ssusb_config(struct xhci_hcd_mtk *mtk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) struct mu3c_ippc_regs __iomem *ippc = mtk->ippc_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) if (!mtk->has_ippc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) /* reset whole ip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) value = readl(&ippc->ip_pw_ctr0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) value |= CTRL0_IP_SW_RST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) writel(value, &ippc->ip_pw_ctr0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) value = readl(&ippc->ip_pw_ctr0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) value &= ~CTRL0_IP_SW_RST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) writel(value, &ippc->ip_pw_ctr0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) * device ip is default power-on in fact
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) * power down device ip, otherwise ip-sleep will fail
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) value = readl(&ippc->ip_pw_ctr2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) value |= CTRL2_IP_DEV_PDN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) writel(value, &ippc->ip_pw_ctr2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) value = readl(&ippc->ip_xhci_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) mtk->num_u3_ports = CAP_U3_PORT_NUM(value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) mtk->num_u2_ports = CAP_U2_PORT_NUM(value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) dev_dbg(mtk->dev, "%s u2p:%d, u3p:%d\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) mtk->num_u2_ports, mtk->num_u3_ports);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) return xhci_mtk_host_enable(mtk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) static int xhci_mtk_clks_get(struct xhci_hcd_mtk *mtk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) struct device *dev = mtk->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) mtk->sys_clk = devm_clk_get(dev, "sys_ck");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) if (IS_ERR(mtk->sys_clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) dev_err(dev, "fail to get sys_ck\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return PTR_ERR(mtk->sys_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) mtk->xhci_clk = devm_clk_get_optional(dev, "xhci_ck");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) if (IS_ERR(mtk->xhci_clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) return PTR_ERR(mtk->xhci_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) mtk->ref_clk = devm_clk_get_optional(dev, "ref_ck");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if (IS_ERR(mtk->ref_clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) return PTR_ERR(mtk->ref_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) mtk->mcu_clk = devm_clk_get_optional(dev, "mcu_ck");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) if (IS_ERR(mtk->mcu_clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) return PTR_ERR(mtk->mcu_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) mtk->dma_clk = devm_clk_get_optional(dev, "dma_ck");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) return PTR_ERR_OR_ZERO(mtk->dma_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) static int xhci_mtk_clks_enable(struct xhci_hcd_mtk *mtk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) ret = clk_prepare_enable(mtk->ref_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) dev_err(mtk->dev, "failed to enable ref_clk\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) goto ref_clk_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) ret = clk_prepare_enable(mtk->sys_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) dev_err(mtk->dev, "failed to enable sys_clk\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) goto sys_clk_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) ret = clk_prepare_enable(mtk->xhci_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) dev_err(mtk->dev, "failed to enable xhci_clk\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) goto xhci_clk_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) ret = clk_prepare_enable(mtk->mcu_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) dev_err(mtk->dev, "failed to enable mcu_clk\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) goto mcu_clk_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) ret = clk_prepare_enable(mtk->dma_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) dev_err(mtk->dev, "failed to enable dma_clk\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) goto dma_clk_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) dma_clk_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) clk_disable_unprepare(mtk->mcu_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) mcu_clk_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) clk_disable_unprepare(mtk->xhci_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) xhci_clk_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) clk_disable_unprepare(mtk->sys_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) sys_clk_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) clk_disable_unprepare(mtk->ref_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) ref_clk_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) static void xhci_mtk_clks_disable(struct xhci_hcd_mtk *mtk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) clk_disable_unprepare(mtk->dma_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) clk_disable_unprepare(mtk->mcu_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) clk_disable_unprepare(mtk->xhci_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) clk_disable_unprepare(mtk->sys_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) clk_disable_unprepare(mtk->ref_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) /* only clocks can be turn off for ip-sleep wakeup mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) static void usb_wakeup_ip_sleep_set(struct xhci_hcd_mtk *mtk, bool enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) u32 reg, msk, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) switch (mtk->uwk_vers) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) case SSUSB_UWK_V1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) reg = mtk->uwk_reg_base + PERI_WK_CTRL1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) msk = WC1_IS_EN | WC1_IS_C(0xf) | WC1_IS_P;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) val = enable ? (WC1_IS_EN | WC1_IS_C(0x8)) : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) case SSUSB_UWK_V2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) reg = mtk->uwk_reg_base + PERI_SSUSB_SPM_CTRL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) msk = SSC_IP_SLEEP_EN | SSC_SPM_INT_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) val = enable ? msk : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) regmap_update_bits(mtk->uwk, reg, msk, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) static int usb_wakeup_of_property_parse(struct xhci_hcd_mtk *mtk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) struct device_node *dn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) struct of_phandle_args args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) /* Wakeup function is optional */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) mtk->uwk_en = of_property_read_bool(dn, "wakeup-source");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) if (!mtk->uwk_en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) ret = of_parse_phandle_with_fixed_args(dn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) "mediatek,syscon-wakeup", 2, 0, &args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) mtk->uwk_reg_base = args.args[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) mtk->uwk_vers = args.args[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) mtk->uwk = syscon_node_to_regmap(args.np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) of_node_put(args.np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) dev_info(mtk->dev, "uwk - reg:0x%x, version:%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) mtk->uwk_reg_base, mtk->uwk_vers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) return PTR_ERR_OR_ZERO(mtk->uwk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) static void usb_wakeup_set(struct xhci_hcd_mtk *mtk, bool enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (mtk->uwk_en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) usb_wakeup_ip_sleep_set(mtk, enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) static int xhci_mtk_ldos_enable(struct xhci_hcd_mtk *mtk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) ret = regulator_enable(mtk->vbus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) dev_err(mtk->dev, "failed to enable vbus\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) ret = regulator_enable(mtk->vusb33);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) dev_err(mtk->dev, "failed to enable vusb33\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) regulator_disable(mtk->vbus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) static void xhci_mtk_ldos_disable(struct xhci_hcd_mtk *mtk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) regulator_disable(mtk->vbus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) regulator_disable(mtk->vusb33);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) static void xhci_mtk_quirks(struct device *dev, struct xhci_hcd *xhci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) struct usb_hcd *hcd = xhci_to_hcd(xhci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) * As of now platform drivers don't provide MSI support so we ensure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) * here that the generic code does not try to make a pci_dev from our
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) * dev struct in order to setup MSI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) xhci->quirks |= XHCI_PLAT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) xhci->quirks |= XHCI_MTK_HOST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) * MTK host controller gives a spurious successful event after a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) * short transfer. Ignore it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) xhci->quirks |= XHCI_SPURIOUS_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) if (mtk->lpm_support)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) xhci->quirks |= XHCI_LPM_SUPPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) if (mtk->u2_lpm_disable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) xhci->quirks |= XHCI_HW_LPM_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) * MTK xHCI 0.96: PSA is 1 by default even if doesn't support stream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) * and it's 3 when support it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) if (xhci->hci_version < 0x100 && HCC_MAX_PSA(xhci->hcc_params) == 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) xhci->quirks |= XHCI_BROKEN_STREAMS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) /* called during probe() after chip reset completes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) static int xhci_mtk_setup(struct usb_hcd *hcd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) if (usb_hcd_is_primary_hcd(hcd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) ret = xhci_mtk_ssusb_config(mtk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) ret = xhci_gen_setup(hcd, xhci_mtk_quirks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) if (usb_hcd_is_primary_hcd(hcd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) ret = xhci_mtk_sch_init(mtk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) static const struct xhci_driver_overrides xhci_mtk_overrides __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) .reset = xhci_mtk_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) .add_endpoint = xhci_mtk_add_ep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) .drop_endpoint = xhci_mtk_drop_ep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) .check_bandwidth = xhci_mtk_check_bandwidth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) .reset_bandwidth = xhci_mtk_reset_bandwidth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) static struct hc_driver __read_mostly xhci_mtk_hc_driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) static int xhci_mtk_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) struct device_node *node = dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) struct xhci_hcd_mtk *mtk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) const struct hc_driver *driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) struct xhci_hcd *xhci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) struct usb_hcd *hcd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) int ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) if (usb_disabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) driver = &xhci_mtk_hc_driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) mtk = devm_kzalloc(dev, sizeof(*mtk), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) if (!mtk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) mtk->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) mtk->vbus = devm_regulator_get(dev, "vbus");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) if (IS_ERR(mtk->vbus)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) dev_err(dev, "fail to get vbus\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) return PTR_ERR(mtk->vbus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) mtk->vusb33 = devm_regulator_get(dev, "vusb33");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) if (IS_ERR(mtk->vusb33)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) dev_err(dev, "fail to get vusb33\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) return PTR_ERR(mtk->vusb33);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) ret = xhci_mtk_clks_get(mtk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) mtk->lpm_support = of_property_read_bool(node, "usb3-lpm-capable");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) mtk->u2_lpm_disable = of_property_read_bool(node, "usb2-lpm-disable");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) /* optional property, ignore the error if it does not exist */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) of_property_read_u32(node, "mediatek,u3p-dis-msk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) &mtk->u3p_dis_msk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) ret = usb_wakeup_of_property_parse(mtk, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) dev_err(dev, "failed to parse uwk property\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) pm_runtime_enable(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) pm_runtime_get_sync(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) device_enable_async_suspend(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) ret = xhci_mtk_ldos_enable(mtk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) goto disable_pm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) ret = xhci_mtk_clks_enable(mtk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) goto disable_ldos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) irq = platform_get_irq(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) if (irq < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) ret = irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) goto disable_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) hcd = usb_create_hcd(driver, dev, dev_name(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) if (!hcd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) goto disable_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) * USB 2.0 roothub is stored in the platform_device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) * Swap it with mtk HCD.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) mtk->hcd = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) platform_set_drvdata(pdev, mtk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mac");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) hcd->regs = devm_ioremap_resource(dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) if (IS_ERR(hcd->regs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) ret = PTR_ERR(hcd->regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) goto put_usb2_hcd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) hcd->rsrc_start = res->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) hcd->rsrc_len = resource_size(res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ippc");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) if (res) { /* ippc register is optional */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) mtk->ippc_regs = devm_ioremap_resource(dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) if (IS_ERR(mtk->ippc_regs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) ret = PTR_ERR(mtk->ippc_regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) goto put_usb2_hcd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) mtk->has_ippc = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) mtk->has_ippc = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) device_init_wakeup(dev, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) xhci = hcd_to_xhci(hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) xhci->main_hcd = hcd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) * imod_interval is the interrupt moderation value in nanoseconds.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) * The increment interval is 8 times as much as that defined in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) * the xHCI spec on MTK's controller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) xhci->imod_interval = 5000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) device_property_read_u32(dev, "imod-interval-ns", &xhci->imod_interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) xhci->shared_hcd = usb_create_shared_hcd(driver, dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) dev_name(dev), hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) if (!xhci->shared_hcd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) goto disable_device_wakeup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) goto put_usb3_hcd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) if (HCC_MAX_PSA(xhci->hcc_params) >= 4 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) !(xhci->quirks & XHCI_BROKEN_STREAMS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) xhci->shared_hcd->can_do_streams = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) goto dealloc_usb2_hcd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) dealloc_usb2_hcd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) usb_remove_hcd(hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) put_usb3_hcd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) xhci_mtk_sch_exit(mtk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) usb_put_hcd(xhci->shared_hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) disable_device_wakeup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) device_init_wakeup(dev, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) put_usb2_hcd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) usb_put_hcd(hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) disable_clk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) xhci_mtk_clks_disable(mtk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) disable_ldos:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) xhci_mtk_ldos_disable(mtk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) disable_pm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) pm_runtime_put_sync(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) pm_runtime_disable(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) static int xhci_mtk_remove(struct platform_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) struct xhci_hcd_mtk *mtk = platform_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) struct usb_hcd *hcd = mtk->hcd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) struct xhci_hcd *xhci = hcd_to_xhci(hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) struct usb_hcd *shared_hcd = xhci->shared_hcd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) pm_runtime_put_noidle(&dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) pm_runtime_disable(&dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) usb_remove_hcd(shared_hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) xhci->shared_hcd = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) device_init_wakeup(&dev->dev, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) usb_remove_hcd(hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) usb_put_hcd(shared_hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) usb_put_hcd(hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) xhci_mtk_sch_exit(mtk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) xhci_mtk_clks_disable(mtk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) xhci_mtk_ldos_disable(mtk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) * if ip sleep fails, and all clocks are disabled, access register will hang
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) * AHB bus, so stop polling roothubs to avoid regs access on bus suspend.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) * and no need to check whether ip sleep failed or not; this will cause SPM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) * to wake up system immediately after system suspend complete if ip sleep
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) * fails, it is what we wanted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) static int __maybe_unused xhci_mtk_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) struct xhci_hcd_mtk *mtk = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) struct usb_hcd *hcd = mtk->hcd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) struct xhci_hcd *xhci = hcd_to_xhci(hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) xhci_dbg(xhci, "%s: stop port polling\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) del_timer_sync(&hcd->rh_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) clear_bit(HCD_FLAG_POLL_RH, &xhci->shared_hcd->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) del_timer_sync(&xhci->shared_hcd->rh_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) xhci_mtk_host_disable(mtk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) xhci_mtk_clks_disable(mtk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) usb_wakeup_set(mtk, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) static int __maybe_unused xhci_mtk_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) struct xhci_hcd_mtk *mtk = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) struct usb_hcd *hcd = mtk->hcd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) struct xhci_hcd *xhci = hcd_to_xhci(hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) usb_wakeup_set(mtk, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) xhci_mtk_clks_enable(mtk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) xhci_mtk_host_enable(mtk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) xhci_dbg(xhci, "%s: restart port polling\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) set_bit(HCD_FLAG_POLL_RH, &xhci->shared_hcd->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) usb_hcd_poll_rh_status(xhci->shared_hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) set_bit(HCD_FLAG_POLL_RH, &hcd->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) usb_hcd_poll_rh_status(hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) static const struct dev_pm_ops xhci_mtk_pm_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) SET_SYSTEM_SLEEP_PM_OPS(xhci_mtk_suspend, xhci_mtk_resume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) #define DEV_PM_OPS IS_ENABLED(CONFIG_PM) ? &xhci_mtk_pm_ops : NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) #ifdef CONFIG_OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) static const struct of_device_id mtk_xhci_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) { .compatible = "mediatek,mt8173-xhci"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) { .compatible = "mediatek,mtk-xhci"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) MODULE_DEVICE_TABLE(of, mtk_xhci_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) static struct platform_driver mtk_xhci_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) .probe = xhci_mtk_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) .remove = xhci_mtk_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) .name = "xhci-mtk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) .pm = DEV_PM_OPS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) .of_match_table = of_match_ptr(mtk_xhci_of_match),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) MODULE_ALIAS("platform:xhci-mtk");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) static int __init xhci_mtk_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) xhci_init_driver(&xhci_mtk_hc_driver, &xhci_mtk_overrides);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) return platform_driver_register(&mtk_xhci_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) module_init(xhci_mtk_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) static void __exit xhci_mtk_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) platform_driver_unregister(&mtk_xhci_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) module_exit(xhci_mtk_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) MODULE_AUTHOR("Chunfeng Yun <chunfeng.yun@mediatek.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) MODULE_DESCRIPTION("MediaTek xHCI Host Controller Driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) MODULE_LICENSE("GPL v2");