summaryrefslogtreecommitdiff
path: root/port/dwc2/usb_dwc2_param.h
blob: 74e436c225f075b8c543707a55194f5d1f3bc77e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
/*
 * Copyright (c) 2025, sakumisu
 *
 * SPDX-License-Identifier: Apache-2.0
 */
#ifndef __USB_DWC2_PARAM_H__
#define __USB_DWC2_PARAM_H__

/* Maximum number of Endpoints/HostChannels */
#define MAX_EPS_CHANNELS 16

#define HSOTG_REG(x) (x)

#define dwc2_readl(addr) \
    (*(volatile uint32_t *)(addr))

#define GUID_OFFSET HSOTG_REG(0x003C)

#define GSNPSID_OFFSET  HSOTG_REG(0x0040)
#define GSNPSID_ID_MASK (0xFFFF0000UL)

#define GHWCFG1_OFFSET HSOTG_REG(0x0044)

#define GHWCFG2_OFFSET                        HSOTG_REG(0x0048)
#define GHWCFG2_OTG_ENABLE_IC_USB             (0x01UL << 31U)
#define GHWCFG2_DEV_TOKEN_Q_DEPTH_MASK        (0x1FUL << 26U)
#define GHWCFG2_DEV_TOKEN_Q_DEPTH_SHIFT       (26U)
#define GHWCFG2_HOST_PERIO_TX_Q_DEPTH_MASK    (0x03UL << 24U)
#define GHWCFG2_HOST_PERIO_TX_Q_DEPTH_SHIFT   (24U)
#define GHWCFG2_NONPERIO_TX_Q_DEPTH_MASK      (0x03UL << 22U)
#define GHWCFG2_NONPERIO_TX_Q_DEPTH_SHIFT     (22U)
#define GHWCFG2_MULTI_PROC_INT                (0x01UL << 20U)
#define GHWCFG2_DYNAMIC_FIFO                  (0x01UL << 19U)
#define GHWCFG2_PERIO_EP_SUPPORTED            (0x01UL << 18U)
#define GHWCFG2_NUM_HOST_CHAN_MASK            (0x0FUL << 14U)
#define GHWCFG2_NUM_HOST_CHAN_SHIFT           (14U)
#define GHWCFG2_NUM_DEV_EP_MASK               (0x0FUL << 10U)
#define GHWCFG2_NUM_DEV_EP_SHIFT              (10U)
#define GHWCFG2_FS_PHY_TYPE_MASK              (0x03UL << 8U)
#define GHWCFG2_FS_PHY_TYPE_SHIFT             (8U)
#define GHWCFG2_FS_PHY_TYPE_NOT_SUPPORTED     (0x00UL)
#define GHWCFG2_FS_PHY_TYPE_DEDICATED         (0x01UL)
#define GHWCFG2_FS_PHY_TYPE_SHARED_UTMI       (0x02UL)
#define GHWCFG2_FS_PHY_TYPE_SHARED_ULPI       (0x03UL)
#define GHWCFG2_HS_PHY_TYPE_MASK              (0x03UL << 6U)
#define GHWCFG2_HS_PHY_TYPE_SHIFT             (6U)
#define GHWCFG2_HS_PHY_TYPE_NOT_SUPPORTED     (0x00UL)
#define GHWCFG2_HS_PHY_TYPE_UTMI              (0x01UL)
#define GHWCFG2_HS_PHY_TYPE_ULPI              (0x02UL)
#define GHWCFG2_HS_PHY_TYPE_UTMI_ULPI         (0x03UL)
#define GHWCFG2_POINT2POINT                   (0x01UL << 5U)
#define GHWCFG2_ARCHITECTURE_MASK             (0x03UL << 3U)
#define GHWCFG2_ARCHITECTURE_SHIFT            (3U)
#define GHWCFG2_SLAVE_ONLY_ARCH               (0x00UL)
#define GHWCFG2_EXT_DMA_ARCH                  (0x01UL)
#define GHWCFG2_INT_DMA_ARCH                  (0x02UL)
#define GHWCFG2_OP_MODE_MASK                  (0x07UL << 0U)
#define GHWCFG2_OP_MODE_SHIFT                 (0U)
#define GHWCFG2_OP_MODE_HNP_SRP_CAPABLE       (0x00UL)
#define GHWCFG2_OP_MODE_SRP_ONLY_CAPABLE      (0x01UL)
#define GHWCFG2_OP_MODE_NO_HNP_SRP_CAPABLE    (0x02UL)
#define GHWCFG2_OP_MODE_SRP_CAPABLE_DEVICE    (0x03UL)
#define GHWCFG2_OP_MODE_NO_SRP_CAPABLE_DEVICE (0x04UL)
#define GHWCFG2_OP_MODE_SRP_CAPABLE_HOST      (0x05UL)
#define GHWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST   (0x06UL)
#define GHWCFG2_OP_MODE_UNDEFINED             (0x07UL)

#define GHWCFG3_OFFSET                       HSOTG_REG(0x004C)
#define GHWCFG3_DFIFO_DEPTH_MASK             (0xFFFFUL << 16U)
#define GHWCFG3_DFIFO_DEPTH_SHIFT            (16U)
#define GHWCFG3_OTG_LPM_EN                   (0x0001UL << 15U)
#define GHWCFG3_BC_SUPPORT                   (0x0001UL << 14U)
#define GHWCFG3_OTG_ENABLE_HSIC              (0x0001UL << 13U)
#define GHWCFG3_ADP_SUPP                     (0x0001UL << 12U)
#define GHWCFG3_SYNCH_RESET_TYPE             (0x0001UL << 11U)
#define GHWCFG3_OPTIONAL_FEATURES            (0x0001UL << 10U)
#define GHWCFG3_VENDOR_CTRL_IF               (0x0001UL << 9U)
#define GHWCFG3_I2C                          (0x0001UL << 8U)
#define GHWCFG3_OTG_FUNC                     (0x0001UL << 7U)
#define GHWCFG3_PACKET_SIZE_CNTR_WIDTH_MASK  (0x0007UL << 4U)
#define GHWCFG3_PACKET_SIZE_CNTR_WIDTH_SHIFT (4U)
#define GHWCFG3_XFER_SIZE_CNTR_WIDTH_MASK    (0x000FUL << 0U)
#define GHWCFG3_XFER_SIZE_CNTR_WIDTH_SHIFT   (0U)

#define GHWCFG4_OFFSET                      HSOTG_REG(0x0050)
#define GHWCFG4_DESC_DMA_DYN                (0x1UL << 31U)
#define GHWCFG4_DESC_DMA                    (0x1UL << 30U)
#define GHWCFG4_NUM_IN_EPS_MASK             (0xFUL << 26U)
#define GHWCFG4_NUM_IN_EPS_SHIFT            (26U)
#define GHWCFG4_DED_FIFO_EN                 (0x1UL << 25U)
#define GHWCFG4_DED_FIFO_SHIFT              (25U)
#define GHWCFG4_SESSION_END_FILT_EN         (0x1UL << 24U)
#define GHWCFG4_B_VALID_FILT_EN             (0x1UL << 23U)
#define GHWCFG4_A_VALID_FILT_EN             (0x1UL << 22U)
#define GHWCFG4_VBUS_VALID_FILT_EN          (0x1UL << 21U)
#define GHWCFG4_IDDIG_FILT_EN               (0x1UL << 20U)
#define GHWCFG4_NUM_DEV_MODE_CTRL_EP_MASK   (0xFUL << 16U)
#define GHWCFG4_NUM_DEV_MODE_CTRL_EP_SHIFT  (16U)
#define GHWCFG4_UTMI_PHY_DATA_WIDTH_MASK    (0x3UL << 14U)
#define GHWCFG4_UTMI_PHY_DATA_WIDTH_SHIFT   (14U)
#define GHWCFG4_UTMI_PHY_DATA_WIDTH_8       (0x0UL)
#define GHWCFG4_UTMI_PHY_DATA_WIDTH_16      (0x1UL)
#define GHWCFG4_UTMI_PHY_DATA_WIDTH_8_OR_16 (0x2UL)
#define GHWCFG4_ACG_SUPPORTED               (0x1UL << 12U)
#define GHWCFG4_IPG_ISOC_SUPPORTED          (0x1UL << 11U)
#define GHWCFG4_SERVICE_INTERVAL_SUPPORTED  (0x1UL << 10U)
#define GHWCFG4_XHIBER                      (0x1UL << 7U)
#define GHWCFG4_HIBER                       (0x1UL << 6U)
#define GHWCFG4_MIN_AHB_FREQ                (0x1UL << 5U)
#define GHWCFG4_POWER_OPTIMIZ               (0x1UL << 4U)
#define GHWCFG4_NUM_DEV_PERIO_IN_EP_MASK    (0xFUL << 0U)
#define GHWCFG4_NUM_DEV_PERIO_IN_EP_SHIFT   (0U)

/**
 * struct dwc2_hw_params - Autodetected parameters.
 *
 * These parameters are the various parameters read from hardware
 * registers during initialization. They typically contain the best
 * supported or maximum value that can be configured in the
 * corresponding dwc2_core_params value.
 *
 * The values that are not in dwc2_core_params are documented below.
 *
 * @snpsid:             Value from SNPSID register
 * @dev_ep_dirs:        Direction of device endpoints (GHWCFG1)
 *
 * @op_mode:             Mode of Operation
 *                       0 - HNP- and SRP-Capable OTG (Host & Device)
 *                       1 - SRP-Capable OTG (Host & Device)
 *                       2 - Non-HNP and Non-SRP Capable OTG (Host & Device)
 *                       3 - SRP-Capable Device
 *                       4 - Non-OTG Device
 *                       5 - SRP-Capable Host
 *                       6 - Non-OTG Host
 * @arch:                Architecture
 *                       0 - Slave only
 *                       1 - External DMA
 *                       2 - Internal DMA
 * @enable_dynamic_fifo: 0 - Use coreConsultant-specified FIFO size parameters
 *                       1 - Allow dynamic FIFO sizing (default, if available)
 * @host_channels:      The number of host channel registers to use
 *                       1 to 16
 * @hs_phy_type:         High-speed PHY interface type
 *                       0 - High-speed interface not supported
 *                       1 - UTMI+
 *                       2 - ULPI
 *                       3 - UTMI+ and ULPI
 * @fs_phy_type:         Full-speed PHY interface type
 *                       0 - Full speed interface not supported
 *                       1 - Dedicated full speed interface
 *                       2 - FS pins shared with UTMI+ pins
 *                       3 - FS pins shared with ULPI pins
 * @num_dev_ep:         Number of device endpoints available
 * @nperio_tx_q_depth:
 *                      Non-Periodic Request Queue Depth
 *                       2, 4 or 8
 * @dev_token_q_depth:  Device Mode IN Token Sequence Learning Queue
 *                      Depth
 *                       0 to 30
 * @host_perio_tx_q_depth:
 *                      Host Mode Periodic Request Queue Depth
 *                       2, 4 or 8
 *
 * @max_transfer_size:  The maximum transfer size supported, in bytes
 *                       2047 to 65,535
 *                      Actual maximum value is autodetected and also
 *                      the default.
 * @max_packet_count:   The maximum number of packets in a transfer
 *                       15 to 511
 *                      Actual maximum value is autodetected and also
 *                      the default.
 * @i2c_enable:         Specifies whether to use the I2Cinterface for a full
 *                      speed PHY. This parameter is only applicable if phy_type
 *                      is FS.
 *                       0 - No (default)
 *                       1 - Yes
 * @total_fifo_size:    Total internal RAM for FIFOs (bytes)
 * @lpm_mode:		For enabling Link Power Management in the controller
 *                       0 - Disable
 *                       1 - Enable
 *
 * @en_multiple_tx_fifo: Specifies whether dedicated per-endpoint transmit FIFOs
 *                      are enabled for non-periodic IN endpoints in device
 *                      mode.
 * @num_dev_in_eps:     Number of device IN endpoints available
 * @num_dev_perio_in_ep: Number of device periodic IN endpoints
 *                       available
 * @dma_desc_enable:    When DMA mode is enabled, specifies whether to use
 *                      address DMA mode or descriptor DMA mode for accessing
 *                      the data FIFOs. The driver will automatically detect the
 *                      value for this if none is specified.
 *                       0 - Address DMA
 *                       1 - Descriptor DMA (default, if available)

 * @power_optimized:    Are power optimizations enabled?
 * @hibernation:	Is hibernation enabled?
 * @utmi_phy_data_width: UTMI+ PHY data width
 *                       0 - 8 bits
 *                       1 - 16 bits
 *                       2 - 8 or 16 bits

 * @acg_enable:		For enabling Active Clock Gating in the controller
 *                       0 - Disable
 *                       1 - Enable
 * @ipg_isoc_en:        This feature indicates that the controller supports
 *                      the worst-case scenario of Rx followed by Rx
 *                      Interpacket Gap (IPG) (32 bitTimes) as per the utmi
 *                      specification for any token following ISOC OUT token.
 *                       0 - Don't support
 *                       1 - Support
 * @service_interval_mode: For enabling service interval based scheduling in the
 *                         controller.
 *                           0 - Disable
 *                           1 - Enable
 */
struct dwc2_hw_params {
    uint32_t snpsid;
    uint32_t dev_ep_dirs;

    unsigned op_mode                  : 3;
    unsigned arch                     : 2;
    unsigned enable_dynamic_fifo      : 1;
    unsigned host_channels            : 5;
    unsigned hs_phy_type              : 2;
    unsigned fs_phy_type              : 2;
    unsigned num_dev_ep               : 4;
    unsigned nperio_tx_q_depth        : 3;
    unsigned host_perio_tx_q_depth    : 3;
    unsigned dev_token_q_depth        : 5;

    unsigned max_transfer_size        : 26;
    unsigned max_packet_count         : 11;
    unsigned i2c_enable               : 1;
    unsigned total_fifo_size          : 16;
    unsigned lpm_mode                 : 1;

    unsigned en_multiple_tx_fifo      : 1;
    unsigned num_dev_in_eps           : 4;
    unsigned num_dev_perio_in_ep      : 4;
    unsigned dma_desc_enable          : 1;
    unsigned power_optimized          : 1;
    unsigned hibernation              : 1;
    unsigned utmi_phy_data_width      : 2;
    unsigned acg_enable               : 1;
    unsigned ipg_isoc_en              : 1;
    unsigned service_interval_mode    : 1;
};

#define DWC2_PHY_TYPE_PARAM_FS		0
#define DWC2_PHY_TYPE_PARAM_UTMI	1
#define DWC2_PHY_TYPE_PARAM_ULPI	2

struct dwc2_user_params {
	uint8_t phy_type;
    uint8_t phy_utmi_width;

    bool device_dma_enable;
    bool device_dma_desc_enable;
    /* (5 * number of control endpoints + 8) + ((largest USB packet used / 4) + 1 for
    * status information) + (2 * number of OUT endpoints) + 1 for Global NAK
    */
    uint16_t device_rx_fifo_size;
    /* IN Endpoints Max packet Size / 4 */
	uint16_t device_tx_fifo_size[MAX_EPS_CHANNELS];

    bool host_dma_desc_enable;
    /*
    * (largest USB packet used / 4) + 1 for status information + 1 transfer complete +
    * 1 location each for Bulk/Control endpoint for handling NAK/NYET scenario
    */
	uint16_t host_rx_fifo_size;
    /* largest non-periodic USB packet used / 4 */
	uint16_t host_nperio_tx_fifo_size;
    /* largest periodic USB packet used / 4 */
	uint16_t host_perio_tx_fifo_size;

    uint32_t device_gccfg;
    uint32_t host_gccfg;

    bool b_session_valid_override;
    uint32_t total_fifo_size;
};

struct usb_dwc2_user_fifo_config {
     /* (5 * number of control endpoints + 8) + ((largest USB packet used / 4) + 1 for
    * status information) + (2 * number of OUT endpoints) + 1 for Global NAK
    */
    uint16_t device_rx_fifo_size;
    /* IN Endpoints Max packet Size / 4 */
    uint16_t device_tx_fifo_size[MAX_EPS_CHANNELS];
};

static inline void dwc2_get_hwparams(uint32_t reg_base, struct dwc2_hw_params *hw)
{
    unsigned int width;
    uint32_t snpsid, hwcfg1, hwcfg2, hwcfg3, hwcfg4;

    snpsid = dwc2_readl(reg_base + GSNPSID_OFFSET);

    hwcfg1 = dwc2_readl(reg_base + GHWCFG1_OFFSET);
    hwcfg2 = dwc2_readl(reg_base + GHWCFG2_OFFSET);
    hwcfg3 = dwc2_readl(reg_base + GHWCFG3_OFFSET);
    hwcfg4 = dwc2_readl(reg_base + GHWCFG4_OFFSET);

    /* snpsid */
    hw->snpsid = snpsid;

    /* hwcfg1 */
    hw->dev_ep_dirs = hwcfg1;

    /* hwcfg2 */
    hw->op_mode = (hwcfg2 & GHWCFG2_OP_MODE_MASK) >>
                  GHWCFG2_OP_MODE_SHIFT;
    hw->arch = (hwcfg2 & GHWCFG2_ARCHITECTURE_MASK) >>
               GHWCFG2_ARCHITECTURE_SHIFT;
    hw->enable_dynamic_fifo = !!(hwcfg2 & GHWCFG2_DYNAMIC_FIFO);
    hw->host_channels = 1 + ((hwcfg2 & GHWCFG2_NUM_HOST_CHAN_MASK) >>
                             GHWCFG2_NUM_HOST_CHAN_SHIFT);
    hw->hs_phy_type = (hwcfg2 & GHWCFG2_HS_PHY_TYPE_MASK) >>
                      GHWCFG2_HS_PHY_TYPE_SHIFT;
    hw->fs_phy_type = (hwcfg2 & GHWCFG2_FS_PHY_TYPE_MASK) >>
                      GHWCFG2_FS_PHY_TYPE_SHIFT;
    hw->num_dev_ep = (hwcfg2 & GHWCFG2_NUM_DEV_EP_MASK) >>
                     GHWCFG2_NUM_DEV_EP_SHIFT;
    hw->nperio_tx_q_depth =
        (hwcfg2 & GHWCFG2_NONPERIO_TX_Q_DEPTH_MASK) >>
        GHWCFG2_NONPERIO_TX_Q_DEPTH_SHIFT << 1;
    hw->host_perio_tx_q_depth =
        (hwcfg2 & GHWCFG2_HOST_PERIO_TX_Q_DEPTH_MASK) >>
        GHWCFG2_HOST_PERIO_TX_Q_DEPTH_SHIFT << 1;
    hw->dev_token_q_depth =
        (hwcfg2 & GHWCFG2_DEV_TOKEN_Q_DEPTH_MASK) >>
        GHWCFG2_DEV_TOKEN_Q_DEPTH_SHIFT;

    /* hwcfg3 */
    width = (hwcfg3 & GHWCFG3_XFER_SIZE_CNTR_WIDTH_MASK) >>
            GHWCFG3_XFER_SIZE_CNTR_WIDTH_SHIFT;
    hw->max_transfer_size = (1 << (width + 11)) - 1;
    width = (hwcfg3 & GHWCFG3_PACKET_SIZE_CNTR_WIDTH_MASK) >>
            GHWCFG3_PACKET_SIZE_CNTR_WIDTH_SHIFT;
    hw->max_packet_count = (1 << (width + 4)) - 1;
    hw->i2c_enable = !!(hwcfg3 & GHWCFG3_I2C);
    hw->total_fifo_size = (hwcfg3 & GHWCFG3_DFIFO_DEPTH_MASK) >>
                          GHWCFG3_DFIFO_DEPTH_SHIFT;
    hw->lpm_mode = !!(hwcfg3 & GHWCFG3_OTG_LPM_EN);

    /* hwcfg4 */
    hw->en_multiple_tx_fifo = !!(hwcfg4 & GHWCFG4_DED_FIFO_EN);
    hw->num_dev_perio_in_ep = (hwcfg4 & GHWCFG4_NUM_DEV_PERIO_IN_EP_MASK) >>
                              GHWCFG4_NUM_DEV_PERIO_IN_EP_SHIFT;
    hw->num_dev_in_eps = (hwcfg4 & GHWCFG4_NUM_IN_EPS_MASK) >>
                         GHWCFG4_NUM_IN_EPS_SHIFT;
    hw->dma_desc_enable = !!(hwcfg4 & GHWCFG4_DESC_DMA);
    hw->power_optimized = !!(hwcfg4 & GHWCFG4_POWER_OPTIMIZ);
    hw->hibernation = !!(hwcfg4 & GHWCFG4_HIBER);
    hw->utmi_phy_data_width = (hwcfg4 & GHWCFG4_UTMI_PHY_DATA_WIDTH_MASK) >>
                              GHWCFG4_UTMI_PHY_DATA_WIDTH_SHIFT;
    hw->acg_enable = !!(hwcfg4 & GHWCFG4_ACG_SUPPORTED);
    hw->ipg_isoc_en = !!(hwcfg4 & GHWCFG4_IPG_ISOC_SUPPORTED);
    hw->service_interval_mode = !!(hwcfg4 &
                                   GHWCFG4_SERVICE_INTERVAL_SUPPORTED);
}

void dwc2_get_user_params(uint32_t reg_base, struct dwc2_user_params *params);
void dwc2_get_user_fifo_config(uint32_t reg_base, struct usb_dwc2_user_fifo_config *config);

#endif