1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Copyright (c) 2024-2025, Kongyang Liu <seashell11234455@gmail.com>
4 */
5
6 #include <linux/bitfield.h>
7 #include <linux/errno.h>
8 #include <linux/io.h>
9 #include <wait_bit.h>
10
11 #include "dwc2_core.h"
12
dwc2_core_reset(struct dwc2_core_regs * regs)13 int dwc2_core_reset(struct dwc2_core_regs *regs)
14 {
15 u32 snpsid;
16 int ret;
17 bool host_mode = false;
18
19 if (!(readl(®s->global_regs.gotgctl) & GOTGCTL_CONID_B) ||
20 (readl(®s->global_regs.gusbcfg) & GUSBCFG_FORCEDEVMODE))
21 host_mode = true;
22
23 /* Core Soft Reset */
24 snpsid = readl(®s->global_regs.gsnpsid);
25 writel(GRSTCTL_CSFTRST, ®s->global_regs.grstctl);
26 if (FIELD_GET(GSNPSID_VER_MASK, snpsid) < 0x420a) {
27 ret = wait_for_bit_le32(®s->global_regs.grstctl, GRSTCTL_CSFTRST,
28 false, 1000, false);
29 if (ret) {
30 log_warning("%s: Waiting for GRSTCTL_CSFTRST timeout\n", __func__);
31 return ret;
32 }
33 } else {
34 ret = wait_for_bit_le32(®s->global_regs.grstctl, GRSTCTL_CSFTRST_DONE,
35 true, 1000, false);
36 if (ret) {
37 log_warning("%s: Waiting for GRSTCTL_CSFTRST_DONE timeout\n", __func__);
38 return ret;
39 }
40 clrsetbits_le32(®s->global_regs.grstctl, GRSTCTL_CSFTRST, GRSTCTL_CSFTRST_DONE);
41 }
42
43 /* Wait for AHB master IDLE state. */
44 ret = wait_for_bit_le32(®s->global_regs.grstctl, GRSTCTL_AHBIDLE,
45 true, 1000, false);
46 if (ret) {
47 log_warning("%s: Waiting for GRSTCTL_AHBIDLE timeout\n", __func__);
48 return ret;
49 }
50
51 if (host_mode) {
52 ret = wait_for_bit_le32(®s->global_regs.gintsts, GINTSTS_CURMODE_HOST,
53 host_mode, 1000, false);
54 if (ret) {
55 log_warning("%s: Waiting for GINTSTS_CURMODE_HOST timeout\n", __func__);
56 return ret;
57 }
58 }
59
60 return 0;
61 }
62
dwc2_flush_tx_fifo(struct dwc2_core_regs * regs,const int num)63 int dwc2_flush_tx_fifo(struct dwc2_core_regs *regs, const int num)
64 {
65 int ret;
66
67 log_debug("Flush Tx FIFO %d\n", num);
68
69 /* Wait for AHB master IDLE state */
70 ret = wait_for_bit_le32(®s->global_regs.grstctl, GRSTCTL_AHBIDLE, true, 1000, false);
71 if (ret) {
72 log_warning("%s: Waiting for GRSTCTL_AHBIDLE timeout\n", __func__);
73 return ret;
74 }
75
76 writel(GRSTCTL_TXFFLSH | FIELD_PREP(GRSTCTL_TXFNUM_MASK, num), ®s->global_regs.grstctl);
77
78 ret = wait_for_bit_le32(®s->global_regs.grstctl, GRSTCTL_TXFFLSH, false, 1000, false);
79 if (ret) {
80 log_warning("%s: Waiting for GRSTCTL_TXFFLSH timeout\n", __func__);
81 return ret;
82 }
83
84 /*
85 * Wait for at least 3 PHY clocks.
86 *
87 * The PHY clock frequency can be configured to 6/30/48/60 MHz
88 * based on the speed mode. A fixed delay of 1us ensures that the
89 * wait time is sufficient even at the lowest PHY clock frequency
90 * (6 MHz), where 1us corresponds to twice the duration of 3 PHY
91 * clocks.
92 */
93 udelay(1);
94
95 return 0;
96 }
97
dwc2_flush_rx_fifo(struct dwc2_core_regs * regs)98 int dwc2_flush_rx_fifo(struct dwc2_core_regs *regs)
99 {
100 int ret;
101
102 log_debug("Flush Rx FIFO\n");
103
104 /* Wait for AHB master IDLE state */
105 ret = wait_for_bit_le32(®s->global_regs.grstctl, GRSTCTL_AHBIDLE, true, 1000, false);
106 if (ret) {
107 log_warning("%s: Waiting for GRSTCTL_AHBIDLE timeout\n", __func__);
108 return ret;
109 }
110
111 writel(GRSTCTL_RXFFLSH, ®s->global_regs.grstctl);
112
113 ret = wait_for_bit_le32(®s->global_regs.grstctl, GRSTCTL_RXFFLSH, false, 1000, false);
114 if (ret) {
115 log_warning("%s: Waiting for GRSTCTL_RXFFLSH timeout\n", __func__);
116 return ret;
117 }
118
119 /*
120 * Wait for at least 3 PHY clocks.
121 *
122 * The PHY clock frequency can be configured to 6/30/48/60 MHz
123 * based on the speed mode. A fixed delay of 1us ensures that the
124 * wait time is sufficient even at the lowest PHY clock frequency
125 * (6 MHz), where 1us corresponds to twice the duration of 3 PHY
126 * clocks.
127 */
128 udelay(1);
129
130 return 0;
131 }
132