^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) /* Copyright (c) 2018, The Linux Foundation. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Inspired by dwc3-of-simple.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/of.h>
^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/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/of_clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/extcon.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/interconnect.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/of_platform.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/phy/phy.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/usb/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/reset.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/iopoll.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "core.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) /* USB QSCRATCH Hardware registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define QSCRATCH_HS_PHY_CTRL 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define UTMI_OTG_VBUS_VALID BIT(20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define SW_SESSVLD_SEL BIT(28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define QSCRATCH_SS_PHY_CTRL 0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define LANE0_PWR_PRESENT BIT(24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define QSCRATCH_GENERAL_CFG 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define PIPE_UTMI_CLK_SEL BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define PIPE3_PHYSTATUS_SW BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define PIPE_UTMI_CLK_DIS BIT(8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define PWR_EVNT_IRQ_STAT_REG 0x58
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define PWR_EVNT_LPM_IN_L2_MASK BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define PWR_EVNT_LPM_OUT_L2_MASK BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define SDM845_QSCRATCH_BASE_OFFSET 0xf8800
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define SDM845_QSCRATCH_SIZE 0x400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define SDM845_DWC3_CORE_SIZE 0xcd00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) /* Interconnect path bandwidths in MBps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define USB_MEMORY_AVG_HS_BW MBps_to_icc(240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define USB_MEMORY_PEAK_HS_BW MBps_to_icc(700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define USB_MEMORY_AVG_SS_BW MBps_to_icc(1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define USB_MEMORY_PEAK_SS_BW MBps_to_icc(2500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define APPS_USB_AVG_BW 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define APPS_USB_PEAK_BW MBps_to_icc(40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) struct dwc3_acpi_pdata {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) u32 qscratch_base_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) u32 qscratch_base_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) u32 dwc3_core_base_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) int hs_phy_irq_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) int dp_hs_phy_irq_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) int dm_hs_phy_irq_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) int ss_phy_irq_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) bool is_urs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) struct dwc3_qcom {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) void __iomem *qscratch_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) struct platform_device *dwc3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) struct platform_device *urs_usb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) struct clk **clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) int num_clocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) struct reset_control *resets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) int hs_phy_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) int dp_hs_phy_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) int dm_hs_phy_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) int ss_phy_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) struct extcon_dev *edev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) struct extcon_dev *host_edev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) struct notifier_block vbus_nb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct notifier_block host_nb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) const struct dwc3_acpi_pdata *acpi_pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) enum usb_dr_mode mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) bool is_suspended;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) bool pm_suspended;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) struct icc_path *icc_path_ddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) struct icc_path *icc_path_apps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) static inline void dwc3_qcom_setbits(void __iomem *base, u32 offset, u32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) reg = readl(base + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) reg |= val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) writel(reg, base + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) /* ensure that above write is through */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) readl(base + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) static inline void dwc3_qcom_clrbits(void __iomem *base, u32 offset, u32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) reg = readl(base + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) reg &= ~val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) writel(reg, base + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /* ensure that above write is through */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) readl(base + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) static void dwc3_qcom_vbus_overrride_enable(struct dwc3_qcom *qcom, bool enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) if (enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) dwc3_qcom_setbits(qcom->qscratch_base, QSCRATCH_SS_PHY_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) LANE0_PWR_PRESENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) dwc3_qcom_setbits(qcom->qscratch_base, QSCRATCH_HS_PHY_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) UTMI_OTG_VBUS_VALID | SW_SESSVLD_SEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) dwc3_qcom_clrbits(qcom->qscratch_base, QSCRATCH_SS_PHY_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) LANE0_PWR_PRESENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) dwc3_qcom_clrbits(qcom->qscratch_base, QSCRATCH_HS_PHY_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) UTMI_OTG_VBUS_VALID | SW_SESSVLD_SEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^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 dwc3_qcom_vbus_notifier(struct notifier_block *nb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) unsigned long event, void *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) struct dwc3_qcom *qcom = container_of(nb, struct dwc3_qcom, vbus_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) /* enable vbus override for device mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) dwc3_qcom_vbus_overrride_enable(qcom, event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) qcom->mode = event ? USB_DR_MODE_PERIPHERAL : USB_DR_MODE_HOST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) return NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) static int dwc3_qcom_host_notifier(struct notifier_block *nb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) unsigned long event, void *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) struct dwc3_qcom *qcom = container_of(nb, struct dwc3_qcom, host_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) /* disable vbus override in host mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) dwc3_qcom_vbus_overrride_enable(qcom, !event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) qcom->mode = event ? USB_DR_MODE_HOST : USB_DR_MODE_PERIPHERAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) return NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) static int dwc3_qcom_register_extcon(struct dwc3_qcom *qcom)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) struct device *dev = qcom->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) struct extcon_dev *host_edev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) if (!of_property_read_bool(dev->of_node, "extcon"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) qcom->edev = extcon_get_edev_by_phandle(dev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) if (IS_ERR(qcom->edev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) return PTR_ERR(qcom->edev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) qcom->vbus_nb.notifier_call = dwc3_qcom_vbus_notifier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) qcom->host_edev = extcon_get_edev_by_phandle(dev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) if (IS_ERR(qcom->host_edev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) qcom->host_edev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) ret = devm_extcon_register_notifier(dev, qcom->edev, EXTCON_USB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) &qcom->vbus_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) dev_err(dev, "VBUS notifier register failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) if (qcom->host_edev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) host_edev = qcom->host_edev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) host_edev = qcom->edev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) qcom->host_nb.notifier_call = dwc3_qcom_host_notifier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) ret = devm_extcon_register_notifier(dev, host_edev, EXTCON_USB_HOST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) &qcom->host_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) dev_err(dev, "Host notifier register failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) /* Update initial VBUS override based on extcon state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) if (extcon_get_state(qcom->edev, EXTCON_USB) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) !extcon_get_state(host_edev, EXTCON_USB_HOST))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) dwc3_qcom_vbus_notifier(&qcom->vbus_nb, true, qcom->edev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) dwc3_qcom_vbus_notifier(&qcom->vbus_nb, false, qcom->edev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) static int dwc3_qcom_interconnect_enable(struct dwc3_qcom *qcom)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) ret = icc_enable(qcom->icc_path_ddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) ret = icc_enable(qcom->icc_path_apps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) icc_disable(qcom->icc_path_ddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) static int dwc3_qcom_interconnect_disable(struct dwc3_qcom *qcom)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) ret = icc_disable(qcom->icc_path_ddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) ret = icc_disable(qcom->icc_path_apps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) icc_enable(qcom->icc_path_ddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) * dwc3_qcom_interconnect_init() - Get interconnect path handles
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) * and set bandwidhth.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) * @qcom: Pointer to the concerned usb core.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) static int dwc3_qcom_interconnect_init(struct dwc3_qcom *qcom)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) struct device *dev = qcom->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) if (has_acpi_companion(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) qcom->icc_path_ddr = of_icc_get(dev, "usb-ddr");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) if (IS_ERR(qcom->icc_path_ddr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) dev_err(dev, "failed to get usb-ddr path: %ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) PTR_ERR(qcom->icc_path_ddr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) return PTR_ERR(qcom->icc_path_ddr);
^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) qcom->icc_path_apps = of_icc_get(dev, "apps-usb");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) if (IS_ERR(qcom->icc_path_apps)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) dev_err(dev, "failed to get apps-usb path: %ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) PTR_ERR(qcom->icc_path_apps));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) return PTR_ERR(qcom->icc_path_apps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) if (usb_get_maximum_speed(&qcom->dwc3->dev) >= USB_SPEED_SUPER ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) usb_get_maximum_speed(&qcom->dwc3->dev) == USB_SPEED_UNKNOWN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) ret = icc_set_bw(qcom->icc_path_ddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) USB_MEMORY_AVG_SS_BW, USB_MEMORY_PEAK_SS_BW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) ret = icc_set_bw(qcom->icc_path_ddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) USB_MEMORY_AVG_HS_BW, USB_MEMORY_PEAK_HS_BW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) dev_err(dev, "failed to set bandwidth for usb-ddr path: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) ret = icc_set_bw(qcom->icc_path_apps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) APPS_USB_AVG_BW, APPS_USB_PEAK_BW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) dev_err(dev, "failed to set bandwidth for apps-usb path: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) * dwc3_qcom_interconnect_exit() - Release interconnect path handles
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) * @qcom: Pointer to the concerned usb core.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) * This function is used to release interconnect path handle.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) static void dwc3_qcom_interconnect_exit(struct dwc3_qcom *qcom)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) icc_put(qcom->icc_path_ddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) icc_put(qcom->icc_path_apps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) static void dwc3_qcom_disable_interrupts(struct dwc3_qcom *qcom)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) if (qcom->hs_phy_irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) disable_irq_wake(qcom->hs_phy_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) disable_irq_nosync(qcom->hs_phy_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) if (qcom->dp_hs_phy_irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) disable_irq_wake(qcom->dp_hs_phy_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) disable_irq_nosync(qcom->dp_hs_phy_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) if (qcom->dm_hs_phy_irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) disable_irq_wake(qcom->dm_hs_phy_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) disable_irq_nosync(qcom->dm_hs_phy_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) if (qcom->ss_phy_irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) disable_irq_wake(qcom->ss_phy_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) disable_irq_nosync(qcom->ss_phy_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) static void dwc3_qcom_enable_interrupts(struct dwc3_qcom *qcom)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) if (qcom->hs_phy_irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) enable_irq(qcom->hs_phy_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) enable_irq_wake(qcom->hs_phy_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (qcom->dp_hs_phy_irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) enable_irq(qcom->dp_hs_phy_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) enable_irq_wake(qcom->dp_hs_phy_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) if (qcom->dm_hs_phy_irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) enable_irq(qcom->dm_hs_phy_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) enable_irq_wake(qcom->dm_hs_phy_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (qcom->ss_phy_irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) enable_irq(qcom->ss_phy_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) enable_irq_wake(qcom->ss_phy_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) static int dwc3_qcom_suspend(struct dwc3_qcom *qcom)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) if (qcom->is_suspended)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) val = readl(qcom->qscratch_base + PWR_EVNT_IRQ_STAT_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) if (!(val & PWR_EVNT_LPM_IN_L2_MASK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) dev_err(qcom->dev, "HS-PHY not in L2\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) for (i = qcom->num_clocks - 1; i >= 0; i--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) clk_disable_unprepare(qcom->clks[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) ret = dwc3_qcom_interconnect_disable(qcom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) dev_warn(qcom->dev, "failed to disable interconnect: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) if (device_may_wakeup(qcom->dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) dwc3_qcom_enable_interrupts(qcom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) qcom->is_suspended = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) return 0;
^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 int dwc3_qcom_resume(struct dwc3_qcom *qcom)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) if (!qcom->is_suspended)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) if (device_may_wakeup(qcom->dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) dwc3_qcom_disable_interrupts(qcom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) for (i = 0; i < qcom->num_clocks; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) ret = clk_prepare_enable(qcom->clks[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) while (--i >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) clk_disable_unprepare(qcom->clks[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) ret = dwc3_qcom_interconnect_enable(qcom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) dev_warn(qcom->dev, "failed to enable interconnect: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) /* Clear existing events from PHY related to L2 in/out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) dwc3_qcom_setbits(qcom->qscratch_base, PWR_EVNT_IRQ_STAT_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) PWR_EVNT_LPM_IN_L2_MASK | PWR_EVNT_LPM_OUT_L2_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) qcom->is_suspended = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) static irqreturn_t qcom_dwc3_resume_irq(int irq, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) struct dwc3_qcom *qcom = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) struct dwc3 *dwc = platform_get_drvdata(qcom->dwc3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) /* If pm_suspended then let pm_resume take care of resuming h/w */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) if (qcom->pm_suspended)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) if (dwc->xhci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) pm_runtime_resume(&dwc->xhci->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) static void dwc3_qcom_select_utmi_clk(struct dwc3_qcom *qcom)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) /* Configure dwc3 to use UTMI clock as PIPE clock not present */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) dwc3_qcom_setbits(qcom->qscratch_base, QSCRATCH_GENERAL_CFG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) PIPE_UTMI_CLK_DIS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) usleep_range(100, 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) dwc3_qcom_setbits(qcom->qscratch_base, QSCRATCH_GENERAL_CFG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) PIPE_UTMI_CLK_SEL | PIPE3_PHYSTATUS_SW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) usleep_range(100, 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) dwc3_qcom_clrbits(qcom->qscratch_base, QSCRATCH_GENERAL_CFG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) PIPE_UTMI_CLK_DIS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) static int dwc3_qcom_get_irq(struct platform_device *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) const char *name, int num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) struct dwc3_qcom *qcom = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) struct platform_device *pdev_irq = qcom->urs_usb ? qcom->urs_usb : pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) struct device_node *np = pdev->dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) if (np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) ret = platform_get_irq_byname(pdev_irq, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) ret = platform_get_irq(pdev_irq, num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) static int dwc3_qcom_setup_irq(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) struct dwc3_qcom *qcom = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) const struct dwc3_acpi_pdata *pdata = qcom->acpi_pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) irq = dwc3_qcom_get_irq(pdev, "hs_phy_irq",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) pdata ? pdata->hs_phy_irq_index : -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) if (irq > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) /* Keep wakeup interrupts disabled until suspend */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) irq_set_status_flags(irq, IRQ_NOAUTOEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) ret = devm_request_threaded_irq(qcom->dev, irq, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) qcom_dwc3_resume_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) "qcom_dwc3 HS", qcom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) dev_err(qcom->dev, "hs_phy_irq failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) qcom->hs_phy_irq = irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) irq = dwc3_qcom_get_irq(pdev, "dp_hs_phy_irq",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) pdata ? pdata->dp_hs_phy_irq_index : -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) if (irq > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) irq_set_status_flags(irq, IRQ_NOAUTOEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) ret = devm_request_threaded_irq(qcom->dev, irq, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) qcom_dwc3_resume_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) "qcom_dwc3 DP_HS", qcom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) dev_err(qcom->dev, "dp_hs_phy_irq failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) qcom->dp_hs_phy_irq = irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) irq = dwc3_qcom_get_irq(pdev, "dm_hs_phy_irq",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) pdata ? pdata->dm_hs_phy_irq_index : -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) if (irq > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) irq_set_status_flags(irq, IRQ_NOAUTOEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) ret = devm_request_threaded_irq(qcom->dev, irq, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) qcom_dwc3_resume_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) "qcom_dwc3 DM_HS", qcom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) dev_err(qcom->dev, "dm_hs_phy_irq failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) qcom->dm_hs_phy_irq = irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) irq = dwc3_qcom_get_irq(pdev, "ss_phy_irq",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) pdata ? pdata->ss_phy_irq_index : -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) if (irq > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) irq_set_status_flags(irq, IRQ_NOAUTOEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) ret = devm_request_threaded_irq(qcom->dev, irq, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) qcom_dwc3_resume_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) "qcom_dwc3 SS", qcom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) dev_err(qcom->dev, "ss_phy_irq failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) qcom->ss_phy_irq = irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) static int dwc3_qcom_clk_init(struct dwc3_qcom *qcom, int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) struct device *dev = qcom->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) struct device_node *np = dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) if (!np || !count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) if (count < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) qcom->num_clocks = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) qcom->clks = devm_kcalloc(dev, qcom->num_clocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) sizeof(struct clk *), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) if (!qcom->clks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) for (i = 0; i < qcom->num_clocks; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) clk = of_clk_get(np, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) if (IS_ERR(clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) while (--i >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) clk_put(qcom->clks[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) return PTR_ERR(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) ret = clk_prepare_enable(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) while (--i >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) clk_disable_unprepare(qcom->clks[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) clk_put(qcom->clks[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) clk_put(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) qcom->clks[i] = clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) static const struct property_entry dwc3_qcom_acpi_properties[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) PROPERTY_ENTRY_STRING("dr_mode", "host"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) static int dwc3_qcom_acpi_register_core(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) struct dwc3_qcom *qcom = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) struct resource *res, *child_res = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) struct platform_device *pdev_irq = qcom->urs_usb ? qcom->urs_usb :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) qcom->dwc3 = platform_device_alloc("dwc3", PLATFORM_DEVID_AUTO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) if (!qcom->dwc3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) qcom->dwc3->dev.parent = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) qcom->dwc3->dev.type = dev->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) qcom->dwc3->dev.dma_mask = dev->dma_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) qcom->dwc3->dev.dma_parms = dev->dma_parms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) qcom->dwc3->dev.coherent_dma_mask = dev->coherent_dma_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) child_res = kcalloc(2, sizeof(*child_res), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) if (!child_res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) if (!res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) dev_err(&pdev->dev, "failed to get memory resource\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) child_res[0].flags = res->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) child_res[0].start = res->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) child_res[0].end = child_res[0].start +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) qcom->acpi_pdata->dwc3_core_base_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) irq = platform_get_irq(pdev_irq, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) if (irq < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) ret = irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) child_res[1].flags = IORESOURCE_IRQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) child_res[1].start = child_res[1].end = irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) ret = platform_device_add_resources(qcom->dwc3, child_res, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) dev_err(&pdev->dev, "failed to add resources\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) ret = platform_device_add_properties(qcom->dwc3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) dwc3_qcom_acpi_properties);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) dev_err(&pdev->dev, "failed to add properties\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) ret = platform_device_add(qcom->dwc3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) dev_err(&pdev->dev, "failed to add device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) kfree(child_res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) static int dwc3_qcom_of_register_core(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) struct dwc3_qcom *qcom = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) struct device_node *np = pdev->dev.of_node, *dwc3_np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) dwc3_np = of_get_child_by_name(np, "dwc3");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) if (!dwc3_np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) dev_err(dev, "failed to find dwc3 core child\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) ret = of_platform_populate(np, NULL, NULL, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) dev_err(dev, "failed to register dwc3 core - %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) goto node_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) qcom->dwc3 = of_find_device_by_node(dwc3_np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) if (!qcom->dwc3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) dev_err(dev, "failed to get dwc3 platform device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) node_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) of_node_put(dwc3_np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) static struct platform_device *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) dwc3_qcom_create_urs_usb_platdev(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) struct fwnode_handle *fwh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) struct acpi_device *adev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) char name[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) /* Figure out device id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) ret = sscanf(fwnode_get_name(dev->fwnode), "URS%d", &id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) /* Find the child using name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) snprintf(name, sizeof(name), "USB%d", id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) fwh = fwnode_get_named_child_node(dev->fwnode, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) if (!fwh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) adev = to_acpi_device_node(fwh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) if (!adev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) return acpi_create_platform_device(adev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) static int dwc3_qcom_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) struct device_node *np = pdev->dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) struct dwc3_qcom *qcom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) struct resource *res, *parent_res = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) bool ignore_pipe_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) qcom = devm_kzalloc(&pdev->dev, sizeof(*qcom), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) if (!qcom)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) platform_set_drvdata(pdev, qcom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) qcom->dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) if (has_acpi_companion(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) qcom->acpi_pdata = acpi_device_get_match_data(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) if (!qcom->acpi_pdata) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) dev_err(&pdev->dev, "no supporting ACPI device data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) qcom->resets = devm_reset_control_array_get_optional_exclusive(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) if (IS_ERR(qcom->resets)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) ret = PTR_ERR(qcom->resets);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) dev_err(&pdev->dev, "failed to get resets, err=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) ret = reset_control_assert(qcom->resets);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) dev_err(&pdev->dev, "failed to assert resets, err=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) usleep_range(10, 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) ret = reset_control_deassert(qcom->resets);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) dev_err(&pdev->dev, "failed to deassert resets, err=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) goto reset_assert;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) ret = dwc3_qcom_clk_init(qcom, of_clk_get_parent_count(np));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) dev_err(dev, "failed to get clocks\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) goto reset_assert;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) if (np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) parent_res = res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) parent_res = kmemdup(res, sizeof(struct resource), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) if (!parent_res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) parent_res->start = res->start +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) qcom->acpi_pdata->qscratch_base_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) parent_res->end = parent_res->start +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) qcom->acpi_pdata->qscratch_base_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) if (qcom->acpi_pdata->is_urs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) qcom->urs_usb = dwc3_qcom_create_urs_usb_platdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) if (IS_ERR_OR_NULL(qcom->urs_usb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) dev_err(dev, "failed to create URS USB platdev\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) if (!qcom->urs_usb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) return PTR_ERR(qcom->urs_usb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) qcom->qscratch_base = devm_ioremap_resource(dev, parent_res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) if (IS_ERR(qcom->qscratch_base)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) dev_err(dev, "failed to map qscratch, err=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) ret = PTR_ERR(qcom->qscratch_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) goto clk_disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) ret = dwc3_qcom_setup_irq(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) dev_err(dev, "failed to setup IRQs, err=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) goto clk_disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) * Disable pipe_clk requirement if specified. Used when dwc3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) * operates without SSPHY and only HS/FS/LS modes are supported.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) ignore_pipe_clk = device_property_read_bool(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) "qcom,select-utmi-as-pipe-clk");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) if (ignore_pipe_clk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) dwc3_qcom_select_utmi_clk(qcom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) if (np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) ret = dwc3_qcom_of_register_core(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) ret = dwc3_qcom_acpi_register_core(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) dev_err(dev, "failed to register DWC3 Core, err=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) goto depopulate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) ret = dwc3_qcom_interconnect_init(qcom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) goto depopulate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) qcom->mode = usb_get_dr_mode(&qcom->dwc3->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) /* enable vbus override for device mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) if (qcom->mode == USB_DR_MODE_PERIPHERAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) dwc3_qcom_vbus_overrride_enable(qcom, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) /* register extcon to override sw_vbus on Vbus change later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) ret = dwc3_qcom_register_extcon(qcom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) goto interconnect_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) device_init_wakeup(&pdev->dev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) qcom->is_suspended = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) pm_runtime_set_active(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) pm_runtime_enable(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) pm_runtime_forbid(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) interconnect_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) dwc3_qcom_interconnect_exit(qcom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) depopulate:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) if (np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) of_platform_depopulate(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) platform_device_put(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) clk_disable:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) for (i = qcom->num_clocks - 1; i >= 0; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) clk_disable_unprepare(qcom->clks[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) clk_put(qcom->clks[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) reset_assert:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) reset_control_assert(qcom->resets);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) static int dwc3_qcom_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) struct dwc3_qcom *qcom = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) of_platform_depopulate(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) for (i = qcom->num_clocks - 1; i >= 0; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) clk_disable_unprepare(qcom->clks[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) clk_put(qcom->clks[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) qcom->num_clocks = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) dwc3_qcom_interconnect_exit(qcom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) reset_control_assert(qcom->resets);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) pm_runtime_allow(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) pm_runtime_disable(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) static int __maybe_unused dwc3_qcom_pm_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) struct dwc3_qcom *qcom = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) ret = dwc3_qcom_suspend(qcom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) qcom->pm_suspended = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) static int __maybe_unused dwc3_qcom_pm_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) struct dwc3_qcom *qcom = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) ret = dwc3_qcom_resume(qcom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) qcom->pm_suspended = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) static int __maybe_unused dwc3_qcom_runtime_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) struct dwc3_qcom *qcom = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) return dwc3_qcom_suspend(qcom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) static int __maybe_unused dwc3_qcom_runtime_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) struct dwc3_qcom *qcom = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) return dwc3_qcom_resume(qcom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) static const struct dev_pm_ops dwc3_qcom_dev_pm_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) SET_SYSTEM_SLEEP_PM_OPS(dwc3_qcom_pm_suspend, dwc3_qcom_pm_resume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) SET_RUNTIME_PM_OPS(dwc3_qcom_runtime_suspend, dwc3_qcom_runtime_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) static const struct of_device_id dwc3_qcom_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) { .compatible = "qcom,dwc3" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) { .compatible = "qcom,msm8996-dwc3" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) { .compatible = "qcom,msm8998-dwc3" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) { .compatible = "qcom,sdm845-dwc3" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) MODULE_DEVICE_TABLE(of, dwc3_qcom_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) #ifdef CONFIG_ACPI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) static const struct dwc3_acpi_pdata sdm845_acpi_pdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) .qscratch_base_offset = SDM845_QSCRATCH_BASE_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) .qscratch_base_size = SDM845_QSCRATCH_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) .dwc3_core_base_size = SDM845_DWC3_CORE_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) .hs_phy_irq_index = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) .dp_hs_phy_irq_index = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) .dm_hs_phy_irq_index = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) .ss_phy_irq_index = 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) static const struct dwc3_acpi_pdata sdm845_acpi_urs_pdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) .qscratch_base_offset = SDM845_QSCRATCH_BASE_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) .qscratch_base_size = SDM845_QSCRATCH_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) .dwc3_core_base_size = SDM845_DWC3_CORE_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) .hs_phy_irq_index = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) .dp_hs_phy_irq_index = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) .dm_hs_phy_irq_index = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) .ss_phy_irq_index = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) .is_urs = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) static const struct acpi_device_id dwc3_qcom_acpi_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) { "QCOM2430", (unsigned long)&sdm845_acpi_pdata },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) { "QCOM0304", (unsigned long)&sdm845_acpi_urs_pdata },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) { "QCOM0497", (unsigned long)&sdm845_acpi_urs_pdata },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) { "QCOM04A6", (unsigned long)&sdm845_acpi_pdata },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) MODULE_DEVICE_TABLE(acpi, dwc3_qcom_acpi_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) static struct platform_driver dwc3_qcom_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) .probe = dwc3_qcom_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) .remove = dwc3_qcom_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) .name = "dwc3-qcom",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) .pm = &dwc3_qcom_dev_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) .of_match_table = dwc3_qcom_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) .acpi_match_table = ACPI_PTR(dwc3_qcom_acpi_match),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) module_platform_driver(dwc3_qcom_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) MODULE_LICENSE("GPL v2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) MODULE_DESCRIPTION("DesignWare DWC3 QCOM Glue Driver");