xref: /openbmc/linux/drivers/usb/dwc2/params.c (revision 323230ef4ef17512007c22898b008e9fb87b372e)
1*323230efSJohn Youn /*
2*323230efSJohn Youn  * Copyright (C) 2004-2016 Synopsys, Inc.
3*323230efSJohn Youn  *
4*323230efSJohn Youn  * Redistribution and use in source and binary forms, with or without
5*323230efSJohn Youn  * modification, are permitted provided that the following conditions
6*323230efSJohn Youn  * are met:
7*323230efSJohn Youn  * 1. Redistributions of source code must retain the above copyright
8*323230efSJohn Youn  *    notice, this list of conditions, and the following disclaimer,
9*323230efSJohn Youn  *    without modification.
10*323230efSJohn Youn  * 2. Redistributions in binary form must reproduce the above copyright
11*323230efSJohn Youn  *    notice, this list of conditions and the following disclaimer in the
12*323230efSJohn Youn  *    documentation and/or other materials provided with the distribution.
13*323230efSJohn Youn  * 3. The names of the above-listed copyright holders may not be used
14*323230efSJohn Youn  *    to endorse or promote products derived from this software without
15*323230efSJohn Youn  *    specific prior written permission.
16*323230efSJohn Youn  *
17*323230efSJohn Youn  * ALTERNATIVELY, this software may be distributed under the terms of the
18*323230efSJohn Youn  * GNU General Public License ("GPL") as published by the Free Software
19*323230efSJohn Youn  * Foundation; either version 2 of the License, or (at your option) any
20*323230efSJohn Youn  * later version.
21*323230efSJohn Youn  *
22*323230efSJohn Youn  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
23*323230efSJohn Youn  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
24*323230efSJohn Youn  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25*323230efSJohn Youn  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
26*323230efSJohn Youn  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27*323230efSJohn Youn  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28*323230efSJohn Youn  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29*323230efSJohn Youn  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30*323230efSJohn Youn  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31*323230efSJohn Youn  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32*323230efSJohn Youn  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33*323230efSJohn Youn  */
34*323230efSJohn Youn 
35*323230efSJohn Youn #include <linux/kernel.h>
36*323230efSJohn Youn #include <linux/module.h>
37*323230efSJohn Youn #include <linux/of_device.h>
38*323230efSJohn Youn 
39*323230efSJohn Youn #include "core.h"
40*323230efSJohn Youn 
41*323230efSJohn Youn static const struct dwc2_core_params params_hi6220 = {
42*323230efSJohn Youn 	.otg_cap			= 2,	/* No HNP/SRP capable */
43*323230efSJohn Youn 	.otg_ver			= 0,	/* 1.3 */
44*323230efSJohn Youn 	.dma_enable			= 1,
45*323230efSJohn Youn 	.dma_desc_enable		= 0,
46*323230efSJohn Youn 	.dma_desc_fs_enable		= 0,
47*323230efSJohn Youn 	.speed				= 0,	/* High Speed */
48*323230efSJohn Youn 	.enable_dynamic_fifo		= 1,
49*323230efSJohn Youn 	.en_multiple_tx_fifo		= 1,
50*323230efSJohn Youn 	.host_rx_fifo_size		= 512,
51*323230efSJohn Youn 	.host_nperio_tx_fifo_size	= 512,
52*323230efSJohn Youn 	.host_perio_tx_fifo_size	= 512,
53*323230efSJohn Youn 	.max_transfer_size		= 65535,
54*323230efSJohn Youn 	.max_packet_count		= 511,
55*323230efSJohn Youn 	.host_channels			= 16,
56*323230efSJohn Youn 	.phy_type			= 1,	/* UTMI */
57*323230efSJohn Youn 	.phy_utmi_width			= 8,
58*323230efSJohn Youn 	.phy_ulpi_ddr			= 0,	/* Single */
59*323230efSJohn Youn 	.phy_ulpi_ext_vbus		= 0,
60*323230efSJohn Youn 	.i2c_enable			= 0,
61*323230efSJohn Youn 	.ulpi_fs_ls			= 0,
62*323230efSJohn Youn 	.host_support_fs_ls_low_power	= 0,
63*323230efSJohn Youn 	.host_ls_low_power_phy_clk	= 0,	/* 48 MHz */
64*323230efSJohn Youn 	.ts_dline			= 0,
65*323230efSJohn Youn 	.reload_ctl			= 0,
66*323230efSJohn Youn 	.ahbcfg				= GAHBCFG_HBSTLEN_INCR16 <<
67*323230efSJohn Youn 					  GAHBCFG_HBSTLEN_SHIFT,
68*323230efSJohn Youn 	.uframe_sched			= 0,
69*323230efSJohn Youn 	.external_id_pin_ctl		= -1,
70*323230efSJohn Youn 	.hibernation			= -1,
71*323230efSJohn Youn };
72*323230efSJohn Youn 
73*323230efSJohn Youn static const struct dwc2_core_params params_bcm2835 = {
74*323230efSJohn Youn 	.otg_cap			= 0,	/* HNP/SRP capable */
75*323230efSJohn Youn 	.otg_ver			= 0,	/* 1.3 */
76*323230efSJohn Youn 	.dma_enable			= 1,
77*323230efSJohn Youn 	.dma_desc_enable		= 0,
78*323230efSJohn Youn 	.dma_desc_fs_enable		= 0,
79*323230efSJohn Youn 	.speed				= 0,	/* High Speed */
80*323230efSJohn Youn 	.enable_dynamic_fifo		= 1,
81*323230efSJohn Youn 	.en_multiple_tx_fifo		= 1,
82*323230efSJohn Youn 	.host_rx_fifo_size		= 774,	/* 774 DWORDs */
83*323230efSJohn Youn 	.host_nperio_tx_fifo_size	= 256,	/* 256 DWORDs */
84*323230efSJohn Youn 	.host_perio_tx_fifo_size	= 512,	/* 512 DWORDs */
85*323230efSJohn Youn 	.max_transfer_size		= 65535,
86*323230efSJohn Youn 	.max_packet_count		= 511,
87*323230efSJohn Youn 	.host_channels			= 8,
88*323230efSJohn Youn 	.phy_type			= 1,	/* UTMI */
89*323230efSJohn Youn 	.phy_utmi_width			= 8,	/* 8 bits */
90*323230efSJohn Youn 	.phy_ulpi_ddr			= 0,	/* Single */
91*323230efSJohn Youn 	.phy_ulpi_ext_vbus		= 0,
92*323230efSJohn Youn 	.i2c_enable			= 0,
93*323230efSJohn Youn 	.ulpi_fs_ls			= 0,
94*323230efSJohn Youn 	.host_support_fs_ls_low_power	= 0,
95*323230efSJohn Youn 	.host_ls_low_power_phy_clk	= 0,	/* 48 MHz */
96*323230efSJohn Youn 	.ts_dline			= 0,
97*323230efSJohn Youn 	.reload_ctl			= 0,
98*323230efSJohn Youn 	.ahbcfg				= 0x10,
99*323230efSJohn Youn 	.uframe_sched			= 0,
100*323230efSJohn Youn 	.external_id_pin_ctl		= -1,
101*323230efSJohn Youn 	.hibernation			= -1,
102*323230efSJohn Youn };
103*323230efSJohn Youn 
104*323230efSJohn Youn static const struct dwc2_core_params params_rk3066 = {
105*323230efSJohn Youn 	.otg_cap			= 2,	/* non-HNP/non-SRP */
106*323230efSJohn Youn 	.otg_ver			= -1,
107*323230efSJohn Youn 	.dma_enable			= -1,
108*323230efSJohn Youn 	.dma_desc_enable		= 0,
109*323230efSJohn Youn 	.dma_desc_fs_enable		= 0,
110*323230efSJohn Youn 	.speed				= -1,
111*323230efSJohn Youn 	.enable_dynamic_fifo		= 1,
112*323230efSJohn Youn 	.en_multiple_tx_fifo		= -1,
113*323230efSJohn Youn 	.host_rx_fifo_size		= 525,	/* 525 DWORDs */
114*323230efSJohn Youn 	.host_nperio_tx_fifo_size	= 128,	/* 128 DWORDs */
115*323230efSJohn Youn 	.host_perio_tx_fifo_size	= 256,	/* 256 DWORDs */
116*323230efSJohn Youn 	.max_transfer_size		= -1,
117*323230efSJohn Youn 	.max_packet_count		= -1,
118*323230efSJohn Youn 	.host_channels			= -1,
119*323230efSJohn Youn 	.phy_type			= -1,
120*323230efSJohn Youn 	.phy_utmi_width			= -1,
121*323230efSJohn Youn 	.phy_ulpi_ddr			= -1,
122*323230efSJohn Youn 	.phy_ulpi_ext_vbus		= -1,
123*323230efSJohn Youn 	.i2c_enable			= -1,
124*323230efSJohn Youn 	.ulpi_fs_ls			= -1,
125*323230efSJohn Youn 	.host_support_fs_ls_low_power	= -1,
126*323230efSJohn Youn 	.host_ls_low_power_phy_clk	= -1,
127*323230efSJohn Youn 	.ts_dline			= -1,
128*323230efSJohn Youn 	.reload_ctl			= -1,
129*323230efSJohn Youn 	.ahbcfg				= GAHBCFG_HBSTLEN_INCR16 <<
130*323230efSJohn Youn 					  GAHBCFG_HBSTLEN_SHIFT,
131*323230efSJohn Youn 	.uframe_sched			= -1,
132*323230efSJohn Youn 	.external_id_pin_ctl		= -1,
133*323230efSJohn Youn 	.hibernation			= -1,
134*323230efSJohn Youn };
135*323230efSJohn Youn 
136*323230efSJohn Youn static const struct dwc2_core_params params_ltq = {
137*323230efSJohn Youn 	.otg_cap			= 2,	/* non-HNP/non-SRP */
138*323230efSJohn Youn 	.otg_ver			= -1,
139*323230efSJohn Youn 	.dma_enable			= -1,
140*323230efSJohn Youn 	.dma_desc_enable		= -1,
141*323230efSJohn Youn 	.dma_desc_fs_enable		= -1,
142*323230efSJohn Youn 	.speed				= -1,
143*323230efSJohn Youn 	.enable_dynamic_fifo		= -1,
144*323230efSJohn Youn 	.en_multiple_tx_fifo		= -1,
145*323230efSJohn Youn 	.host_rx_fifo_size		= 288,	/* 288 DWORDs */
146*323230efSJohn Youn 	.host_nperio_tx_fifo_size	= 128,	/* 128 DWORDs */
147*323230efSJohn Youn 	.host_perio_tx_fifo_size	= 96,	/* 96 DWORDs */
148*323230efSJohn Youn 	.max_transfer_size		= 65535,
149*323230efSJohn Youn 	.max_packet_count		= 511,
150*323230efSJohn Youn 	.host_channels			= -1,
151*323230efSJohn Youn 	.phy_type			= -1,
152*323230efSJohn Youn 	.phy_utmi_width			= -1,
153*323230efSJohn Youn 	.phy_ulpi_ddr			= -1,
154*323230efSJohn Youn 	.phy_ulpi_ext_vbus		= -1,
155*323230efSJohn Youn 	.i2c_enable			= -1,
156*323230efSJohn Youn 	.ulpi_fs_ls			= -1,
157*323230efSJohn Youn 	.host_support_fs_ls_low_power	= -1,
158*323230efSJohn Youn 	.host_ls_low_power_phy_clk	= -1,
159*323230efSJohn Youn 	.ts_dline			= -1,
160*323230efSJohn Youn 	.reload_ctl			= -1,
161*323230efSJohn Youn 	.ahbcfg				= GAHBCFG_HBSTLEN_INCR16 <<
162*323230efSJohn Youn 					  GAHBCFG_HBSTLEN_SHIFT,
163*323230efSJohn Youn 	.uframe_sched			= -1,
164*323230efSJohn Youn 	.external_id_pin_ctl		= -1,
165*323230efSJohn Youn 	.hibernation			= -1,
166*323230efSJohn Youn };
167*323230efSJohn Youn 
168*323230efSJohn Youn static const struct dwc2_core_params params_amlogic = {
169*323230efSJohn Youn 	.otg_cap			= DWC2_CAP_PARAM_NO_HNP_SRP_CAPABLE,
170*323230efSJohn Youn 	.otg_ver			= -1,
171*323230efSJohn Youn 	.dma_enable			= 1,
172*323230efSJohn Youn 	.dma_desc_enable		= 0,
173*323230efSJohn Youn 	.dma_desc_fs_enable		= 0,
174*323230efSJohn Youn 	.speed				= DWC2_SPEED_PARAM_HIGH,
175*323230efSJohn Youn 	.enable_dynamic_fifo		= 1,
176*323230efSJohn Youn 	.en_multiple_tx_fifo		= -1,
177*323230efSJohn Youn 	.host_rx_fifo_size		= 512,
178*323230efSJohn Youn 	.host_nperio_tx_fifo_size	= 500,
179*323230efSJohn Youn 	.host_perio_tx_fifo_size	= 500,
180*323230efSJohn Youn 	.max_transfer_size		= -1,
181*323230efSJohn Youn 	.max_packet_count		= -1,
182*323230efSJohn Youn 	.host_channels			= 16,
183*323230efSJohn Youn 	.phy_type			= DWC2_PHY_TYPE_PARAM_UTMI,
184*323230efSJohn Youn 	.phy_utmi_width			= -1,
185*323230efSJohn Youn 	.phy_ulpi_ddr			= -1,
186*323230efSJohn Youn 	.phy_ulpi_ext_vbus		= -1,
187*323230efSJohn Youn 	.i2c_enable			= -1,
188*323230efSJohn Youn 	.ulpi_fs_ls			= -1,
189*323230efSJohn Youn 	.host_support_fs_ls_low_power	= -1,
190*323230efSJohn Youn 	.host_ls_low_power_phy_clk	= -1,
191*323230efSJohn Youn 	.ts_dline			= -1,
192*323230efSJohn Youn 	.reload_ctl			= 1,
193*323230efSJohn Youn 	.ahbcfg				= GAHBCFG_HBSTLEN_INCR8 <<
194*323230efSJohn Youn 					  GAHBCFG_HBSTLEN_SHIFT,
195*323230efSJohn Youn 	.uframe_sched			= 0,
196*323230efSJohn Youn 	.external_id_pin_ctl		= -1,
197*323230efSJohn Youn 	.hibernation			= -1,
198*323230efSJohn Youn };
199*323230efSJohn Youn 
200*323230efSJohn Youn const struct of_device_id dwc2_of_match_table[] = {
201*323230efSJohn Youn 	{ .compatible = "brcm,bcm2835-usb", .data = &params_bcm2835 },
202*323230efSJohn Youn 	{ .compatible = "hisilicon,hi6220-usb", .data = &params_hi6220 },
203*323230efSJohn Youn 	{ .compatible = "rockchip,rk3066-usb", .data = &params_rk3066 },
204*323230efSJohn Youn 	{ .compatible = "lantiq,arx100-usb", .data = &params_ltq },
205*323230efSJohn Youn 	{ .compatible = "lantiq,xrx200-usb", .data = &params_ltq },
206*323230efSJohn Youn 	{ .compatible = "snps,dwc2", .data = NULL },
207*323230efSJohn Youn 	{ .compatible = "samsung,s3c6400-hsotg", .data = NULL},
208*323230efSJohn Youn 	{ .compatible = "amlogic,meson8b-usb", .data = &params_amlogic },
209*323230efSJohn Youn 	{ .compatible = "amlogic,meson-gxbb-usb", .data = &params_amlogic },
210*323230efSJohn Youn 	{},
211*323230efSJohn Youn };
212*323230efSJohn Youn MODULE_DEVICE_TABLE(of, dwc2_of_match_table);
213*323230efSJohn Youn 
214*323230efSJohn Youn #define DWC2_OUT_OF_BOUNDS(a, b, c)	((a) < (b) || (a) > (c))
215*323230efSJohn Youn 
216*323230efSJohn Youn /* Parameter access functions */
217*323230efSJohn Youn void dwc2_set_param_otg_cap(struct dwc2_hsotg *hsotg, int val)
218*323230efSJohn Youn {
219*323230efSJohn Youn 	int valid = 1;
220*323230efSJohn Youn 
221*323230efSJohn Youn 	switch (val) {
222*323230efSJohn Youn 	case DWC2_CAP_PARAM_HNP_SRP_CAPABLE:
223*323230efSJohn Youn 		if (hsotg->hw_params.op_mode != GHWCFG2_OP_MODE_HNP_SRP_CAPABLE)
224*323230efSJohn Youn 			valid = 0;
225*323230efSJohn Youn 		break;
226*323230efSJohn Youn 	case DWC2_CAP_PARAM_SRP_ONLY_CAPABLE:
227*323230efSJohn Youn 		switch (hsotg->hw_params.op_mode) {
228*323230efSJohn Youn 		case GHWCFG2_OP_MODE_HNP_SRP_CAPABLE:
229*323230efSJohn Youn 		case GHWCFG2_OP_MODE_SRP_ONLY_CAPABLE:
230*323230efSJohn Youn 		case GHWCFG2_OP_MODE_SRP_CAPABLE_DEVICE:
231*323230efSJohn Youn 		case GHWCFG2_OP_MODE_SRP_CAPABLE_HOST:
232*323230efSJohn Youn 			break;
233*323230efSJohn Youn 		default:
234*323230efSJohn Youn 			valid = 0;
235*323230efSJohn Youn 			break;
236*323230efSJohn Youn 		}
237*323230efSJohn Youn 		break;
238*323230efSJohn Youn 	case DWC2_CAP_PARAM_NO_HNP_SRP_CAPABLE:
239*323230efSJohn Youn 		/* always valid */
240*323230efSJohn Youn 		break;
241*323230efSJohn Youn 	default:
242*323230efSJohn Youn 		valid = 0;
243*323230efSJohn Youn 		break;
244*323230efSJohn Youn 	}
245*323230efSJohn Youn 
246*323230efSJohn Youn 	if (!valid) {
247*323230efSJohn Youn 		if (val >= 0)
248*323230efSJohn Youn 			dev_err(hsotg->dev,
249*323230efSJohn Youn 				"%d invalid for otg_cap parameter. Check HW configuration.\n",
250*323230efSJohn Youn 				val);
251*323230efSJohn Youn 		switch (hsotg->hw_params.op_mode) {
252*323230efSJohn Youn 		case GHWCFG2_OP_MODE_HNP_SRP_CAPABLE:
253*323230efSJohn Youn 			val = DWC2_CAP_PARAM_HNP_SRP_CAPABLE;
254*323230efSJohn Youn 			break;
255*323230efSJohn Youn 		case GHWCFG2_OP_MODE_SRP_ONLY_CAPABLE:
256*323230efSJohn Youn 		case GHWCFG2_OP_MODE_SRP_CAPABLE_DEVICE:
257*323230efSJohn Youn 		case GHWCFG2_OP_MODE_SRP_CAPABLE_HOST:
258*323230efSJohn Youn 			val = DWC2_CAP_PARAM_SRP_ONLY_CAPABLE;
259*323230efSJohn Youn 			break;
260*323230efSJohn Youn 		default:
261*323230efSJohn Youn 			val = DWC2_CAP_PARAM_NO_HNP_SRP_CAPABLE;
262*323230efSJohn Youn 			break;
263*323230efSJohn Youn 		}
264*323230efSJohn Youn 		dev_dbg(hsotg->dev, "Setting otg_cap to %d\n", val);
265*323230efSJohn Youn 	}
266*323230efSJohn Youn 
267*323230efSJohn Youn 	hsotg->core_params->otg_cap = val;
268*323230efSJohn Youn }
269*323230efSJohn Youn 
270*323230efSJohn Youn void dwc2_set_param_dma_enable(struct dwc2_hsotg *hsotg, int val)
271*323230efSJohn Youn {
272*323230efSJohn Youn 	int valid = 1;
273*323230efSJohn Youn 
274*323230efSJohn Youn 	if (val > 0 && hsotg->hw_params.arch == GHWCFG2_SLAVE_ONLY_ARCH)
275*323230efSJohn Youn 		valid = 0;
276*323230efSJohn Youn 	if (val < 0)
277*323230efSJohn Youn 		valid = 0;
278*323230efSJohn Youn 
279*323230efSJohn Youn 	if (!valid) {
280*323230efSJohn Youn 		if (val >= 0)
281*323230efSJohn Youn 			dev_err(hsotg->dev,
282*323230efSJohn Youn 				"%d invalid for dma_enable parameter. Check HW configuration.\n",
283*323230efSJohn Youn 				val);
284*323230efSJohn Youn 		val = hsotg->hw_params.arch != GHWCFG2_SLAVE_ONLY_ARCH;
285*323230efSJohn Youn 		dev_dbg(hsotg->dev, "Setting dma_enable to %d\n", val);
286*323230efSJohn Youn 	}
287*323230efSJohn Youn 
288*323230efSJohn Youn 	hsotg->core_params->dma_enable = val;
289*323230efSJohn Youn }
290*323230efSJohn Youn 
291*323230efSJohn Youn void dwc2_set_param_dma_desc_enable(struct dwc2_hsotg *hsotg, int val)
292*323230efSJohn Youn {
293*323230efSJohn Youn 	int valid = 1;
294*323230efSJohn Youn 
295*323230efSJohn Youn 	if (val > 0 && (hsotg->core_params->dma_enable <= 0 ||
296*323230efSJohn Youn 			!hsotg->hw_params.dma_desc_enable))
297*323230efSJohn Youn 		valid = 0;
298*323230efSJohn Youn 	if (val < 0)
299*323230efSJohn Youn 		valid = 0;
300*323230efSJohn Youn 
301*323230efSJohn Youn 	if (!valid) {
302*323230efSJohn Youn 		if (val >= 0)
303*323230efSJohn Youn 			dev_err(hsotg->dev,
304*323230efSJohn Youn 				"%d invalid for dma_desc_enable parameter. Check HW configuration.\n",
305*323230efSJohn Youn 				val);
306*323230efSJohn Youn 		val = (hsotg->core_params->dma_enable > 0 &&
307*323230efSJohn Youn 			hsotg->hw_params.dma_desc_enable);
308*323230efSJohn Youn 		dev_dbg(hsotg->dev, "Setting dma_desc_enable to %d\n", val);
309*323230efSJohn Youn 	}
310*323230efSJohn Youn 
311*323230efSJohn Youn 	hsotg->core_params->dma_desc_enable = val;
312*323230efSJohn Youn }
313*323230efSJohn Youn 
314*323230efSJohn Youn void dwc2_set_param_dma_desc_fs_enable(struct dwc2_hsotg *hsotg, int val)
315*323230efSJohn Youn {
316*323230efSJohn Youn 	int valid = 1;
317*323230efSJohn Youn 
318*323230efSJohn Youn 	if (val > 0 && (hsotg->core_params->dma_enable <= 0 ||
319*323230efSJohn Youn 			!hsotg->hw_params.dma_desc_enable))
320*323230efSJohn Youn 		valid = 0;
321*323230efSJohn Youn 	if (val < 0)
322*323230efSJohn Youn 		valid = 0;
323*323230efSJohn Youn 
324*323230efSJohn Youn 	if (!valid) {
325*323230efSJohn Youn 		if (val >= 0)
326*323230efSJohn Youn 			dev_err(hsotg->dev,
327*323230efSJohn Youn 				"%d invalid for dma_desc_fs_enable parameter. Check HW configuration.\n",
328*323230efSJohn Youn 				val);
329*323230efSJohn Youn 		val = (hsotg->core_params->dma_enable > 0 &&
330*323230efSJohn Youn 			hsotg->hw_params.dma_desc_enable);
331*323230efSJohn Youn 	}
332*323230efSJohn Youn 
333*323230efSJohn Youn 	hsotg->core_params->dma_desc_fs_enable = val;
334*323230efSJohn Youn 	dev_dbg(hsotg->dev, "Setting dma_desc_fs_enable to %d\n", val);
335*323230efSJohn Youn }
336*323230efSJohn Youn 
337*323230efSJohn Youn void dwc2_set_param_host_support_fs_ls_low_power(struct dwc2_hsotg *hsotg,
338*323230efSJohn Youn 						 int val)
339*323230efSJohn Youn {
340*323230efSJohn Youn 	if (DWC2_OUT_OF_BOUNDS(val, 0, 1)) {
341*323230efSJohn Youn 		if (val >= 0) {
342*323230efSJohn Youn 			dev_err(hsotg->dev,
343*323230efSJohn Youn 				"Wrong value for host_support_fs_low_power\n");
344*323230efSJohn Youn 			dev_err(hsotg->dev,
345*323230efSJohn Youn 				"host_support_fs_low_power must be 0 or 1\n");
346*323230efSJohn Youn 		}
347*323230efSJohn Youn 		val = 0;
348*323230efSJohn Youn 		dev_dbg(hsotg->dev,
349*323230efSJohn Youn 			"Setting host_support_fs_low_power to %d\n", val);
350*323230efSJohn Youn 	}
351*323230efSJohn Youn 
352*323230efSJohn Youn 	hsotg->core_params->host_support_fs_ls_low_power = val;
353*323230efSJohn Youn }
354*323230efSJohn Youn 
355*323230efSJohn Youn void dwc2_set_param_enable_dynamic_fifo(struct dwc2_hsotg *hsotg, int val)
356*323230efSJohn Youn {
357*323230efSJohn Youn 	int valid = 1;
358*323230efSJohn Youn 
359*323230efSJohn Youn 	if (val > 0 && !hsotg->hw_params.enable_dynamic_fifo)
360*323230efSJohn Youn 		valid = 0;
361*323230efSJohn Youn 	if (val < 0)
362*323230efSJohn Youn 		valid = 0;
363*323230efSJohn Youn 
364*323230efSJohn Youn 	if (!valid) {
365*323230efSJohn Youn 		if (val >= 0)
366*323230efSJohn Youn 			dev_err(hsotg->dev,
367*323230efSJohn Youn 				"%d invalid for enable_dynamic_fifo parameter. Check HW configuration.\n",
368*323230efSJohn Youn 				val);
369*323230efSJohn Youn 		val = hsotg->hw_params.enable_dynamic_fifo;
370*323230efSJohn Youn 		dev_dbg(hsotg->dev, "Setting enable_dynamic_fifo to %d\n", val);
371*323230efSJohn Youn 	}
372*323230efSJohn Youn 
373*323230efSJohn Youn 	hsotg->core_params->enable_dynamic_fifo = val;
374*323230efSJohn Youn }
375*323230efSJohn Youn 
376*323230efSJohn Youn void dwc2_set_param_host_rx_fifo_size(struct dwc2_hsotg *hsotg, int val)
377*323230efSJohn Youn {
378*323230efSJohn Youn 	int valid = 1;
379*323230efSJohn Youn 
380*323230efSJohn Youn 	if (val < 16 || val > hsotg->hw_params.host_rx_fifo_size)
381*323230efSJohn Youn 		valid = 0;
382*323230efSJohn Youn 
383*323230efSJohn Youn 	if (!valid) {
384*323230efSJohn Youn 		if (val >= 0)
385*323230efSJohn Youn 			dev_err(hsotg->dev,
386*323230efSJohn Youn 				"%d invalid for host_rx_fifo_size. Check HW configuration.\n",
387*323230efSJohn Youn 				val);
388*323230efSJohn Youn 		val = hsotg->hw_params.host_rx_fifo_size;
389*323230efSJohn Youn 		dev_dbg(hsotg->dev, "Setting host_rx_fifo_size to %d\n", val);
390*323230efSJohn Youn 	}
391*323230efSJohn Youn 
392*323230efSJohn Youn 	hsotg->core_params->host_rx_fifo_size = val;
393*323230efSJohn Youn }
394*323230efSJohn Youn 
395*323230efSJohn Youn void dwc2_set_param_host_nperio_tx_fifo_size(struct dwc2_hsotg *hsotg, int val)
396*323230efSJohn Youn {
397*323230efSJohn Youn 	int valid = 1;
398*323230efSJohn Youn 
399*323230efSJohn Youn 	if (val < 16 || val > hsotg->hw_params.host_nperio_tx_fifo_size)
400*323230efSJohn Youn 		valid = 0;
401*323230efSJohn Youn 
402*323230efSJohn Youn 	if (!valid) {
403*323230efSJohn Youn 		if (val >= 0)
404*323230efSJohn Youn 			dev_err(hsotg->dev,
405*323230efSJohn Youn 				"%d invalid for host_nperio_tx_fifo_size. Check HW configuration.\n",
406*323230efSJohn Youn 				val);
407*323230efSJohn Youn 		val = hsotg->hw_params.host_nperio_tx_fifo_size;
408*323230efSJohn Youn 		dev_dbg(hsotg->dev, "Setting host_nperio_tx_fifo_size to %d\n",
409*323230efSJohn Youn 			val);
410*323230efSJohn Youn 	}
411*323230efSJohn Youn 
412*323230efSJohn Youn 	hsotg->core_params->host_nperio_tx_fifo_size = val;
413*323230efSJohn Youn }
414*323230efSJohn Youn 
415*323230efSJohn Youn void dwc2_set_param_host_perio_tx_fifo_size(struct dwc2_hsotg *hsotg, int val)
416*323230efSJohn Youn {
417*323230efSJohn Youn 	int valid = 1;
418*323230efSJohn Youn 
419*323230efSJohn Youn 	if (val < 16 || val > hsotg->hw_params.host_perio_tx_fifo_size)
420*323230efSJohn Youn 		valid = 0;
421*323230efSJohn Youn 
422*323230efSJohn Youn 	if (!valid) {
423*323230efSJohn Youn 		if (val >= 0)
424*323230efSJohn Youn 			dev_err(hsotg->dev,
425*323230efSJohn Youn 				"%d invalid for host_perio_tx_fifo_size. Check HW configuration.\n",
426*323230efSJohn Youn 				val);
427*323230efSJohn Youn 		val = hsotg->hw_params.host_perio_tx_fifo_size;
428*323230efSJohn Youn 		dev_dbg(hsotg->dev, "Setting host_perio_tx_fifo_size to %d\n",
429*323230efSJohn Youn 			val);
430*323230efSJohn Youn 	}
431*323230efSJohn Youn 
432*323230efSJohn Youn 	hsotg->core_params->host_perio_tx_fifo_size = val;
433*323230efSJohn Youn }
434*323230efSJohn Youn 
435*323230efSJohn Youn void dwc2_set_param_max_transfer_size(struct dwc2_hsotg *hsotg, int val)
436*323230efSJohn Youn {
437*323230efSJohn Youn 	int valid = 1;
438*323230efSJohn Youn 
439*323230efSJohn Youn 	if (val < 2047 || val > hsotg->hw_params.max_transfer_size)
440*323230efSJohn Youn 		valid = 0;
441*323230efSJohn Youn 
442*323230efSJohn Youn 	if (!valid) {
443*323230efSJohn Youn 		if (val >= 0)
444*323230efSJohn Youn 			dev_err(hsotg->dev,
445*323230efSJohn Youn 				"%d invalid for max_transfer_size. Check HW configuration.\n",
446*323230efSJohn Youn 				val);
447*323230efSJohn Youn 		val = hsotg->hw_params.max_transfer_size;
448*323230efSJohn Youn 		dev_dbg(hsotg->dev, "Setting max_transfer_size to %d\n", val);
449*323230efSJohn Youn 	}
450*323230efSJohn Youn 
451*323230efSJohn Youn 	hsotg->core_params->max_transfer_size = val;
452*323230efSJohn Youn }
453*323230efSJohn Youn 
454*323230efSJohn Youn void dwc2_set_param_max_packet_count(struct dwc2_hsotg *hsotg, int val)
455*323230efSJohn Youn {
456*323230efSJohn Youn 	int valid = 1;
457*323230efSJohn Youn 
458*323230efSJohn Youn 	if (val < 15 || val > hsotg->hw_params.max_packet_count)
459*323230efSJohn Youn 		valid = 0;
460*323230efSJohn Youn 
461*323230efSJohn Youn 	if (!valid) {
462*323230efSJohn Youn 		if (val >= 0)
463*323230efSJohn Youn 			dev_err(hsotg->dev,
464*323230efSJohn Youn 				"%d invalid for max_packet_count. Check HW configuration.\n",
465*323230efSJohn Youn 				val);
466*323230efSJohn Youn 		val = hsotg->hw_params.max_packet_count;
467*323230efSJohn Youn 		dev_dbg(hsotg->dev, "Setting max_packet_count to %d\n", val);
468*323230efSJohn Youn 	}
469*323230efSJohn Youn 
470*323230efSJohn Youn 	hsotg->core_params->max_packet_count = val;
471*323230efSJohn Youn }
472*323230efSJohn Youn 
473*323230efSJohn Youn void dwc2_set_param_host_channels(struct dwc2_hsotg *hsotg, int val)
474*323230efSJohn Youn {
475*323230efSJohn Youn 	int valid = 1;
476*323230efSJohn Youn 
477*323230efSJohn Youn 	if (val < 1 || val > hsotg->hw_params.host_channels)
478*323230efSJohn Youn 		valid = 0;
479*323230efSJohn Youn 
480*323230efSJohn Youn 	if (!valid) {
481*323230efSJohn Youn 		if (val >= 0)
482*323230efSJohn Youn 			dev_err(hsotg->dev,
483*323230efSJohn Youn 				"%d invalid for host_channels. Check HW configuration.\n",
484*323230efSJohn Youn 				val);
485*323230efSJohn Youn 		val = hsotg->hw_params.host_channels;
486*323230efSJohn Youn 		dev_dbg(hsotg->dev, "Setting host_channels to %d\n", val);
487*323230efSJohn Youn 	}
488*323230efSJohn Youn 
489*323230efSJohn Youn 	hsotg->core_params->host_channels = val;
490*323230efSJohn Youn }
491*323230efSJohn Youn 
492*323230efSJohn Youn void dwc2_set_param_phy_type(struct dwc2_hsotg *hsotg, int val)
493*323230efSJohn Youn {
494*323230efSJohn Youn 	int valid = 0;
495*323230efSJohn Youn 	u32 hs_phy_type, fs_phy_type;
496*323230efSJohn Youn 
497*323230efSJohn Youn 	if (DWC2_OUT_OF_BOUNDS(val, DWC2_PHY_TYPE_PARAM_FS,
498*323230efSJohn Youn 			       DWC2_PHY_TYPE_PARAM_ULPI)) {
499*323230efSJohn Youn 		if (val >= 0) {
500*323230efSJohn Youn 			dev_err(hsotg->dev, "Wrong value for phy_type\n");
501*323230efSJohn Youn 			dev_err(hsotg->dev, "phy_type must be 0, 1 or 2\n");
502*323230efSJohn Youn 		}
503*323230efSJohn Youn 
504*323230efSJohn Youn 		valid = 0;
505*323230efSJohn Youn 	}
506*323230efSJohn Youn 
507*323230efSJohn Youn 	hs_phy_type = hsotg->hw_params.hs_phy_type;
508*323230efSJohn Youn 	fs_phy_type = hsotg->hw_params.fs_phy_type;
509*323230efSJohn Youn 	if (val == DWC2_PHY_TYPE_PARAM_UTMI &&
510*323230efSJohn Youn 	    (hs_phy_type == GHWCFG2_HS_PHY_TYPE_UTMI ||
511*323230efSJohn Youn 	     hs_phy_type == GHWCFG2_HS_PHY_TYPE_UTMI_ULPI))
512*323230efSJohn Youn 		valid = 1;
513*323230efSJohn Youn 	else if (val == DWC2_PHY_TYPE_PARAM_ULPI &&
514*323230efSJohn Youn 		 (hs_phy_type == GHWCFG2_HS_PHY_TYPE_ULPI ||
515*323230efSJohn Youn 		  hs_phy_type == GHWCFG2_HS_PHY_TYPE_UTMI_ULPI))
516*323230efSJohn Youn 		valid = 1;
517*323230efSJohn Youn 	else if (val == DWC2_PHY_TYPE_PARAM_FS &&
518*323230efSJohn Youn 		 fs_phy_type == GHWCFG2_FS_PHY_TYPE_DEDICATED)
519*323230efSJohn Youn 		valid = 1;
520*323230efSJohn Youn 
521*323230efSJohn Youn 	if (!valid) {
522*323230efSJohn Youn 		if (val >= 0)
523*323230efSJohn Youn 			dev_err(hsotg->dev,
524*323230efSJohn Youn 				"%d invalid for phy_type. Check HW configuration.\n",
525*323230efSJohn Youn 				val);
526*323230efSJohn Youn 		val = DWC2_PHY_TYPE_PARAM_FS;
527*323230efSJohn Youn 		if (hs_phy_type != GHWCFG2_HS_PHY_TYPE_NOT_SUPPORTED) {
528*323230efSJohn Youn 			if (hs_phy_type == GHWCFG2_HS_PHY_TYPE_UTMI ||
529*323230efSJohn Youn 			    hs_phy_type == GHWCFG2_HS_PHY_TYPE_UTMI_ULPI)
530*323230efSJohn Youn 				val = DWC2_PHY_TYPE_PARAM_UTMI;
531*323230efSJohn Youn 			else
532*323230efSJohn Youn 				val = DWC2_PHY_TYPE_PARAM_ULPI;
533*323230efSJohn Youn 		}
534*323230efSJohn Youn 		dev_dbg(hsotg->dev, "Setting phy_type to %d\n", val);
535*323230efSJohn Youn 	}
536*323230efSJohn Youn 
537*323230efSJohn Youn 	hsotg->core_params->phy_type = val;
538*323230efSJohn Youn }
539*323230efSJohn Youn 
540*323230efSJohn Youn static int dwc2_get_param_phy_type(struct dwc2_hsotg *hsotg)
541*323230efSJohn Youn {
542*323230efSJohn Youn 	return hsotg->core_params->phy_type;
543*323230efSJohn Youn }
544*323230efSJohn Youn 
545*323230efSJohn Youn void dwc2_set_param_speed(struct dwc2_hsotg *hsotg, int val)
546*323230efSJohn Youn {
547*323230efSJohn Youn 	int valid = 1;
548*323230efSJohn Youn 
549*323230efSJohn Youn 	if (DWC2_OUT_OF_BOUNDS(val, 0, 1)) {
550*323230efSJohn Youn 		if (val >= 0) {
551*323230efSJohn Youn 			dev_err(hsotg->dev, "Wrong value for speed parameter\n");
552*323230efSJohn Youn 			dev_err(hsotg->dev, "max_speed parameter must be 0 or 1\n");
553*323230efSJohn Youn 		}
554*323230efSJohn Youn 		valid = 0;
555*323230efSJohn Youn 	}
556*323230efSJohn Youn 
557*323230efSJohn Youn 	if (val == DWC2_SPEED_PARAM_HIGH &&
558*323230efSJohn Youn 	    dwc2_get_param_phy_type(hsotg) == DWC2_PHY_TYPE_PARAM_FS)
559*323230efSJohn Youn 		valid = 0;
560*323230efSJohn Youn 
561*323230efSJohn Youn 	if (!valid) {
562*323230efSJohn Youn 		if (val >= 0)
563*323230efSJohn Youn 			dev_err(hsotg->dev,
564*323230efSJohn Youn 				"%d invalid for speed parameter. Check HW configuration.\n",
565*323230efSJohn Youn 				val);
566*323230efSJohn Youn 		val = dwc2_get_param_phy_type(hsotg) == DWC2_PHY_TYPE_PARAM_FS ?
567*323230efSJohn Youn 				DWC2_SPEED_PARAM_FULL : DWC2_SPEED_PARAM_HIGH;
568*323230efSJohn Youn 		dev_dbg(hsotg->dev, "Setting speed to %d\n", val);
569*323230efSJohn Youn 	}
570*323230efSJohn Youn 
571*323230efSJohn Youn 	hsotg->core_params->speed = val;
572*323230efSJohn Youn }
573*323230efSJohn Youn 
574*323230efSJohn Youn void dwc2_set_param_host_ls_low_power_phy_clk(struct dwc2_hsotg *hsotg, int val)
575*323230efSJohn Youn {
576*323230efSJohn Youn 	int valid = 1;
577*323230efSJohn Youn 
578*323230efSJohn Youn 	if (DWC2_OUT_OF_BOUNDS(val, DWC2_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ,
579*323230efSJohn Youn 			       DWC2_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ)) {
580*323230efSJohn Youn 		if (val >= 0) {
581*323230efSJohn Youn 			dev_err(hsotg->dev,
582*323230efSJohn Youn 				"Wrong value for host_ls_low_power_phy_clk parameter\n");
583*323230efSJohn Youn 			dev_err(hsotg->dev,
584*323230efSJohn Youn 				"host_ls_low_power_phy_clk must be 0 or 1\n");
585*323230efSJohn Youn 		}
586*323230efSJohn Youn 		valid = 0;
587*323230efSJohn Youn 	}
588*323230efSJohn Youn 
589*323230efSJohn Youn 	if (val == DWC2_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ &&
590*323230efSJohn Youn 	    dwc2_get_param_phy_type(hsotg) == DWC2_PHY_TYPE_PARAM_FS)
591*323230efSJohn Youn 		valid = 0;
592*323230efSJohn Youn 
593*323230efSJohn Youn 	if (!valid) {
594*323230efSJohn Youn 		if (val >= 0)
595*323230efSJohn Youn 			dev_err(hsotg->dev,
596*323230efSJohn Youn 				"%d invalid for host_ls_low_power_phy_clk. Check HW configuration.\n",
597*323230efSJohn Youn 				val);
598*323230efSJohn Youn 		val = dwc2_get_param_phy_type(hsotg) == DWC2_PHY_TYPE_PARAM_FS
599*323230efSJohn Youn 			? DWC2_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ
600*323230efSJohn Youn 			: DWC2_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ;
601*323230efSJohn Youn 		dev_dbg(hsotg->dev, "Setting host_ls_low_power_phy_clk to %d\n",
602*323230efSJohn Youn 			val);
603*323230efSJohn Youn 	}
604*323230efSJohn Youn 
605*323230efSJohn Youn 	hsotg->core_params->host_ls_low_power_phy_clk = val;
606*323230efSJohn Youn }
607*323230efSJohn Youn 
608*323230efSJohn Youn void dwc2_set_param_phy_ulpi_ddr(struct dwc2_hsotg *hsotg, int val)
609*323230efSJohn Youn {
610*323230efSJohn Youn 	if (DWC2_OUT_OF_BOUNDS(val, 0, 1)) {
611*323230efSJohn Youn 		if (val >= 0) {
612*323230efSJohn Youn 			dev_err(hsotg->dev, "Wrong value for phy_ulpi_ddr\n");
613*323230efSJohn Youn 			dev_err(hsotg->dev, "phy_upli_ddr must be 0 or 1\n");
614*323230efSJohn Youn 		}
615*323230efSJohn Youn 		val = 0;
616*323230efSJohn Youn 		dev_dbg(hsotg->dev, "Setting phy_upli_ddr to %d\n", val);
617*323230efSJohn Youn 	}
618*323230efSJohn Youn 
619*323230efSJohn Youn 	hsotg->core_params->phy_ulpi_ddr = val;
620*323230efSJohn Youn }
621*323230efSJohn Youn 
622*323230efSJohn Youn void dwc2_set_param_phy_ulpi_ext_vbus(struct dwc2_hsotg *hsotg, int val)
623*323230efSJohn Youn {
624*323230efSJohn Youn 	if (DWC2_OUT_OF_BOUNDS(val, 0, 1)) {
625*323230efSJohn Youn 		if (val >= 0) {
626*323230efSJohn Youn 			dev_err(hsotg->dev,
627*323230efSJohn Youn 				"Wrong value for phy_ulpi_ext_vbus\n");
628*323230efSJohn Youn 			dev_err(hsotg->dev,
629*323230efSJohn Youn 				"phy_ulpi_ext_vbus must be 0 or 1\n");
630*323230efSJohn Youn 		}
631*323230efSJohn Youn 		val = 0;
632*323230efSJohn Youn 		dev_dbg(hsotg->dev, "Setting phy_ulpi_ext_vbus to %d\n", val);
633*323230efSJohn Youn 	}
634*323230efSJohn Youn 
635*323230efSJohn Youn 	hsotg->core_params->phy_ulpi_ext_vbus = val;
636*323230efSJohn Youn }
637*323230efSJohn Youn 
638*323230efSJohn Youn void dwc2_set_param_phy_utmi_width(struct dwc2_hsotg *hsotg, int val)
639*323230efSJohn Youn {
640*323230efSJohn Youn 	int valid = 0;
641*323230efSJohn Youn 
642*323230efSJohn Youn 	switch (hsotg->hw_params.utmi_phy_data_width) {
643*323230efSJohn Youn 	case GHWCFG4_UTMI_PHY_DATA_WIDTH_8:
644*323230efSJohn Youn 		valid = (val == 8);
645*323230efSJohn Youn 		break;
646*323230efSJohn Youn 	case GHWCFG4_UTMI_PHY_DATA_WIDTH_16:
647*323230efSJohn Youn 		valid = (val == 16);
648*323230efSJohn Youn 		break;
649*323230efSJohn Youn 	case GHWCFG4_UTMI_PHY_DATA_WIDTH_8_OR_16:
650*323230efSJohn Youn 		valid = (val == 8 || val == 16);
651*323230efSJohn Youn 		break;
652*323230efSJohn Youn 	}
653*323230efSJohn Youn 
654*323230efSJohn Youn 	if (!valid) {
655*323230efSJohn Youn 		if (val >= 0) {
656*323230efSJohn Youn 			dev_err(hsotg->dev,
657*323230efSJohn Youn 				"%d invalid for phy_utmi_width. Check HW configuration.\n",
658*323230efSJohn Youn 				val);
659*323230efSJohn Youn 		}
660*323230efSJohn Youn 		val = (hsotg->hw_params.utmi_phy_data_width ==
661*323230efSJohn Youn 		       GHWCFG4_UTMI_PHY_DATA_WIDTH_8) ? 8 : 16;
662*323230efSJohn Youn 		dev_dbg(hsotg->dev, "Setting phy_utmi_width to %d\n", val);
663*323230efSJohn Youn 	}
664*323230efSJohn Youn 
665*323230efSJohn Youn 	hsotg->core_params->phy_utmi_width = val;
666*323230efSJohn Youn }
667*323230efSJohn Youn 
668*323230efSJohn Youn void dwc2_set_param_ulpi_fs_ls(struct dwc2_hsotg *hsotg, int val)
669*323230efSJohn Youn {
670*323230efSJohn Youn 	if (DWC2_OUT_OF_BOUNDS(val, 0, 1)) {
671*323230efSJohn Youn 		if (val >= 0) {
672*323230efSJohn Youn 			dev_err(hsotg->dev, "Wrong value for ulpi_fs_ls\n");
673*323230efSJohn Youn 			dev_err(hsotg->dev, "ulpi_fs_ls must be 0 or 1\n");
674*323230efSJohn Youn 		}
675*323230efSJohn Youn 		val = 0;
676*323230efSJohn Youn 		dev_dbg(hsotg->dev, "Setting ulpi_fs_ls to %d\n", val);
677*323230efSJohn Youn 	}
678*323230efSJohn Youn 
679*323230efSJohn Youn 	hsotg->core_params->ulpi_fs_ls = val;
680*323230efSJohn Youn }
681*323230efSJohn Youn 
682*323230efSJohn Youn void dwc2_set_param_ts_dline(struct dwc2_hsotg *hsotg, int val)
683*323230efSJohn Youn {
684*323230efSJohn Youn 	if (DWC2_OUT_OF_BOUNDS(val, 0, 1)) {
685*323230efSJohn Youn 		if (val >= 0) {
686*323230efSJohn Youn 			dev_err(hsotg->dev, "Wrong value for ts_dline\n");
687*323230efSJohn Youn 			dev_err(hsotg->dev, "ts_dline must be 0 or 1\n");
688*323230efSJohn Youn 		}
689*323230efSJohn Youn 		val = 0;
690*323230efSJohn Youn 		dev_dbg(hsotg->dev, "Setting ts_dline to %d\n", val);
691*323230efSJohn Youn 	}
692*323230efSJohn Youn 
693*323230efSJohn Youn 	hsotg->core_params->ts_dline = val;
694*323230efSJohn Youn }
695*323230efSJohn Youn 
696*323230efSJohn Youn void dwc2_set_param_i2c_enable(struct dwc2_hsotg *hsotg, int val)
697*323230efSJohn Youn {
698*323230efSJohn Youn 	int valid = 1;
699*323230efSJohn Youn 
700*323230efSJohn Youn 	if (DWC2_OUT_OF_BOUNDS(val, 0, 1)) {
701*323230efSJohn Youn 		if (val >= 0) {
702*323230efSJohn Youn 			dev_err(hsotg->dev, "Wrong value for i2c_enable\n");
703*323230efSJohn Youn 			dev_err(hsotg->dev, "i2c_enable must be 0 or 1\n");
704*323230efSJohn Youn 		}
705*323230efSJohn Youn 
706*323230efSJohn Youn 		valid = 0;
707*323230efSJohn Youn 	}
708*323230efSJohn Youn 
709*323230efSJohn Youn 	if (val == 1 && !(hsotg->hw_params.i2c_enable))
710*323230efSJohn Youn 		valid = 0;
711*323230efSJohn Youn 
712*323230efSJohn Youn 	if (!valid) {
713*323230efSJohn Youn 		if (val >= 0)
714*323230efSJohn Youn 			dev_err(hsotg->dev,
715*323230efSJohn Youn 				"%d invalid for i2c_enable. Check HW configuration.\n",
716*323230efSJohn Youn 				val);
717*323230efSJohn Youn 		val = hsotg->hw_params.i2c_enable;
718*323230efSJohn Youn 		dev_dbg(hsotg->dev, "Setting i2c_enable to %d\n", val);
719*323230efSJohn Youn 	}
720*323230efSJohn Youn 
721*323230efSJohn Youn 	hsotg->core_params->i2c_enable = val;
722*323230efSJohn Youn }
723*323230efSJohn Youn 
724*323230efSJohn Youn void dwc2_set_param_en_multiple_tx_fifo(struct dwc2_hsotg *hsotg, int val)
725*323230efSJohn Youn {
726*323230efSJohn Youn 	int valid = 1;
727*323230efSJohn Youn 
728*323230efSJohn Youn 	if (DWC2_OUT_OF_BOUNDS(val, 0, 1)) {
729*323230efSJohn Youn 		if (val >= 0) {
730*323230efSJohn Youn 			dev_err(hsotg->dev,
731*323230efSJohn Youn 				"Wrong value for en_multiple_tx_fifo,\n");
732*323230efSJohn Youn 			dev_err(hsotg->dev,
733*323230efSJohn Youn 				"en_multiple_tx_fifo must be 0 or 1\n");
734*323230efSJohn Youn 		}
735*323230efSJohn Youn 		valid = 0;
736*323230efSJohn Youn 	}
737*323230efSJohn Youn 
738*323230efSJohn Youn 	if (val == 1 && !hsotg->hw_params.en_multiple_tx_fifo)
739*323230efSJohn Youn 		valid = 0;
740*323230efSJohn Youn 
741*323230efSJohn Youn 	if (!valid) {
742*323230efSJohn Youn 		if (val >= 0)
743*323230efSJohn Youn 			dev_err(hsotg->dev,
744*323230efSJohn Youn 				"%d invalid for parameter en_multiple_tx_fifo. Check HW configuration.\n",
745*323230efSJohn Youn 				val);
746*323230efSJohn Youn 		val = hsotg->hw_params.en_multiple_tx_fifo;
747*323230efSJohn Youn 		dev_dbg(hsotg->dev, "Setting en_multiple_tx_fifo to %d\n", val);
748*323230efSJohn Youn 	}
749*323230efSJohn Youn 
750*323230efSJohn Youn 	hsotg->core_params->en_multiple_tx_fifo = val;
751*323230efSJohn Youn }
752*323230efSJohn Youn 
753*323230efSJohn Youn void dwc2_set_param_reload_ctl(struct dwc2_hsotg *hsotg, int val)
754*323230efSJohn Youn {
755*323230efSJohn Youn 	int valid = 1;
756*323230efSJohn Youn 
757*323230efSJohn Youn 	if (DWC2_OUT_OF_BOUNDS(val, 0, 1)) {
758*323230efSJohn Youn 		if (val >= 0) {
759*323230efSJohn Youn 			dev_err(hsotg->dev,
760*323230efSJohn Youn 				"'%d' invalid for parameter reload_ctl\n", val);
761*323230efSJohn Youn 			dev_err(hsotg->dev, "reload_ctl must be 0 or 1\n");
762*323230efSJohn Youn 		}
763*323230efSJohn Youn 		valid = 0;
764*323230efSJohn Youn 	}
765*323230efSJohn Youn 
766*323230efSJohn Youn 	if (val == 1 && hsotg->hw_params.snpsid < DWC2_CORE_REV_2_92a)
767*323230efSJohn Youn 		valid = 0;
768*323230efSJohn Youn 
769*323230efSJohn Youn 	if (!valid) {
770*323230efSJohn Youn 		if (val >= 0)
771*323230efSJohn Youn 			dev_err(hsotg->dev,
772*323230efSJohn Youn 				"%d invalid for parameter reload_ctl. Check HW configuration.\n",
773*323230efSJohn Youn 				val);
774*323230efSJohn Youn 		val = hsotg->hw_params.snpsid >= DWC2_CORE_REV_2_92a;
775*323230efSJohn Youn 		dev_dbg(hsotg->dev, "Setting reload_ctl to %d\n", val);
776*323230efSJohn Youn 	}
777*323230efSJohn Youn 
778*323230efSJohn Youn 	hsotg->core_params->reload_ctl = val;
779*323230efSJohn Youn }
780*323230efSJohn Youn 
781*323230efSJohn Youn void dwc2_set_param_ahbcfg(struct dwc2_hsotg *hsotg, int val)
782*323230efSJohn Youn {
783*323230efSJohn Youn 	if (val != -1)
784*323230efSJohn Youn 		hsotg->core_params->ahbcfg = val;
785*323230efSJohn Youn 	else
786*323230efSJohn Youn 		hsotg->core_params->ahbcfg = GAHBCFG_HBSTLEN_INCR4 <<
787*323230efSJohn Youn 						GAHBCFG_HBSTLEN_SHIFT;
788*323230efSJohn Youn }
789*323230efSJohn Youn 
790*323230efSJohn Youn void dwc2_set_param_otg_ver(struct dwc2_hsotg *hsotg, int val)
791*323230efSJohn Youn {
792*323230efSJohn Youn 	if (DWC2_OUT_OF_BOUNDS(val, 0, 1)) {
793*323230efSJohn Youn 		if (val >= 0) {
794*323230efSJohn Youn 			dev_err(hsotg->dev,
795*323230efSJohn Youn 				"'%d' invalid for parameter otg_ver\n", val);
796*323230efSJohn Youn 			dev_err(hsotg->dev,
797*323230efSJohn Youn 				"otg_ver must be 0 (for OTG 1.3 support) or 1 (for OTG 2.0 support)\n");
798*323230efSJohn Youn 		}
799*323230efSJohn Youn 		val = 0;
800*323230efSJohn Youn 		dev_dbg(hsotg->dev, "Setting otg_ver to %d\n", val);
801*323230efSJohn Youn 	}
802*323230efSJohn Youn 
803*323230efSJohn Youn 	hsotg->core_params->otg_ver = val;
804*323230efSJohn Youn }
805*323230efSJohn Youn 
806*323230efSJohn Youn static void dwc2_set_param_uframe_sched(struct dwc2_hsotg *hsotg, int val)
807*323230efSJohn Youn {
808*323230efSJohn Youn 	if (DWC2_OUT_OF_BOUNDS(val, 0, 1)) {
809*323230efSJohn Youn 		if (val >= 0) {
810*323230efSJohn Youn 			dev_err(hsotg->dev,
811*323230efSJohn Youn 				"'%d' invalid for parameter uframe_sched\n",
812*323230efSJohn Youn 				val);
813*323230efSJohn Youn 			dev_err(hsotg->dev, "uframe_sched must be 0 or 1\n");
814*323230efSJohn Youn 		}
815*323230efSJohn Youn 		val = 1;
816*323230efSJohn Youn 		dev_dbg(hsotg->dev, "Setting uframe_sched to %d\n", val);
817*323230efSJohn Youn 	}
818*323230efSJohn Youn 
819*323230efSJohn Youn 	hsotg->core_params->uframe_sched = val;
820*323230efSJohn Youn }
821*323230efSJohn Youn 
822*323230efSJohn Youn static void dwc2_set_param_external_id_pin_ctl(struct dwc2_hsotg *hsotg,
823*323230efSJohn Youn 					       int val)
824*323230efSJohn Youn {
825*323230efSJohn Youn 	if (DWC2_OUT_OF_BOUNDS(val, 0, 1)) {
826*323230efSJohn Youn 		if (val >= 0) {
827*323230efSJohn Youn 			dev_err(hsotg->dev,
828*323230efSJohn Youn 				"'%d' invalid for parameter external_id_pin_ctl\n",
829*323230efSJohn Youn 				val);
830*323230efSJohn Youn 			dev_err(hsotg->dev, "external_id_pin_ctl must be 0 or 1\n");
831*323230efSJohn Youn 		}
832*323230efSJohn Youn 		val = 0;
833*323230efSJohn Youn 		dev_dbg(hsotg->dev, "Setting external_id_pin_ctl to %d\n", val);
834*323230efSJohn Youn 	}
835*323230efSJohn Youn 
836*323230efSJohn Youn 	hsotg->core_params->external_id_pin_ctl = val;
837*323230efSJohn Youn }
838*323230efSJohn Youn 
839*323230efSJohn Youn static void dwc2_set_param_hibernation(struct dwc2_hsotg *hsotg,
840*323230efSJohn Youn 				       int val)
841*323230efSJohn Youn {
842*323230efSJohn Youn 	if (DWC2_OUT_OF_BOUNDS(val, 0, 1)) {
843*323230efSJohn Youn 		if (val >= 0) {
844*323230efSJohn Youn 			dev_err(hsotg->dev,
845*323230efSJohn Youn 				"'%d' invalid for parameter hibernation\n",
846*323230efSJohn Youn 				val);
847*323230efSJohn Youn 			dev_err(hsotg->dev, "hibernation must be 0 or 1\n");
848*323230efSJohn Youn 		}
849*323230efSJohn Youn 		val = 0;
850*323230efSJohn Youn 		dev_dbg(hsotg->dev, "Setting hibernation to %d\n", val);
851*323230efSJohn Youn 	}
852*323230efSJohn Youn 
853*323230efSJohn Youn 	hsotg->core_params->hibernation = val;
854*323230efSJohn Youn }
855*323230efSJohn Youn 
856*323230efSJohn Youn /*
857*323230efSJohn Youn  * This function is called during module intialization to pass module parameters
858*323230efSJohn Youn  * for the DWC_otg core.
859*323230efSJohn Youn  */
860*323230efSJohn Youn void dwc2_set_parameters(struct dwc2_hsotg *hsotg,
861*323230efSJohn Youn 			 const struct dwc2_core_params *params)
862*323230efSJohn Youn {
863*323230efSJohn Youn 	dev_dbg(hsotg->dev, "%s()\n", __func__);
864*323230efSJohn Youn 
865*323230efSJohn Youn 	dwc2_set_param_otg_cap(hsotg, params->otg_cap);
866*323230efSJohn Youn 	dwc2_set_param_dma_enable(hsotg, params->dma_enable);
867*323230efSJohn Youn 	dwc2_set_param_dma_desc_enable(hsotg, params->dma_desc_enable);
868*323230efSJohn Youn 	dwc2_set_param_dma_desc_fs_enable(hsotg, params->dma_desc_fs_enable);
869*323230efSJohn Youn 	dwc2_set_param_host_support_fs_ls_low_power(hsotg,
870*323230efSJohn Youn 			params->host_support_fs_ls_low_power);
871*323230efSJohn Youn 	dwc2_set_param_enable_dynamic_fifo(hsotg,
872*323230efSJohn Youn 			params->enable_dynamic_fifo);
873*323230efSJohn Youn 	dwc2_set_param_host_rx_fifo_size(hsotg,
874*323230efSJohn Youn 			params->host_rx_fifo_size);
875*323230efSJohn Youn 	dwc2_set_param_host_nperio_tx_fifo_size(hsotg,
876*323230efSJohn Youn 			params->host_nperio_tx_fifo_size);
877*323230efSJohn Youn 	dwc2_set_param_host_perio_tx_fifo_size(hsotg,
878*323230efSJohn Youn 			params->host_perio_tx_fifo_size);
879*323230efSJohn Youn 	dwc2_set_param_max_transfer_size(hsotg,
880*323230efSJohn Youn 			params->max_transfer_size);
881*323230efSJohn Youn 	dwc2_set_param_max_packet_count(hsotg,
882*323230efSJohn Youn 			params->max_packet_count);
883*323230efSJohn Youn 	dwc2_set_param_host_channels(hsotg, params->host_channels);
884*323230efSJohn Youn 	dwc2_set_param_phy_type(hsotg, params->phy_type);
885*323230efSJohn Youn 	dwc2_set_param_speed(hsotg, params->speed);
886*323230efSJohn Youn 	dwc2_set_param_host_ls_low_power_phy_clk(hsotg,
887*323230efSJohn Youn 			params->host_ls_low_power_phy_clk);
888*323230efSJohn Youn 	dwc2_set_param_phy_ulpi_ddr(hsotg, params->phy_ulpi_ddr);
889*323230efSJohn Youn 	dwc2_set_param_phy_ulpi_ext_vbus(hsotg,
890*323230efSJohn Youn 			params->phy_ulpi_ext_vbus);
891*323230efSJohn Youn 	dwc2_set_param_phy_utmi_width(hsotg, params->phy_utmi_width);
892*323230efSJohn Youn 	dwc2_set_param_ulpi_fs_ls(hsotg, params->ulpi_fs_ls);
893*323230efSJohn Youn 	dwc2_set_param_ts_dline(hsotg, params->ts_dline);
894*323230efSJohn Youn 	dwc2_set_param_i2c_enable(hsotg, params->i2c_enable);
895*323230efSJohn Youn 	dwc2_set_param_en_multiple_tx_fifo(hsotg,
896*323230efSJohn Youn 			params->en_multiple_tx_fifo);
897*323230efSJohn Youn 	dwc2_set_param_reload_ctl(hsotg, params->reload_ctl);
898*323230efSJohn Youn 	dwc2_set_param_ahbcfg(hsotg, params->ahbcfg);
899*323230efSJohn Youn 	dwc2_set_param_otg_ver(hsotg, params->otg_ver);
900*323230efSJohn Youn 	dwc2_set_param_uframe_sched(hsotg, params->uframe_sched);
901*323230efSJohn Youn 	dwc2_set_param_external_id_pin_ctl(hsotg, params->external_id_pin_ctl);
902*323230efSJohn Youn 	dwc2_set_param_hibernation(hsotg, params->hibernation);
903*323230efSJohn Youn }
904*323230efSJohn Youn 
905*323230efSJohn Youn /*
906*323230efSJohn Youn  * Gets host hardware parameters. Forces host mode if not currently in
907*323230efSJohn Youn  * host mode. Should be called immediately after a core soft reset in
908*323230efSJohn Youn  * order to get the reset values.
909*323230efSJohn Youn  */
910*323230efSJohn Youn static void dwc2_get_host_hwparams(struct dwc2_hsotg *hsotg)
911*323230efSJohn Youn {
912*323230efSJohn Youn 	struct dwc2_hw_params *hw = &hsotg->hw_params;
913*323230efSJohn Youn 	u32 gnptxfsiz;
914*323230efSJohn Youn 	u32 hptxfsiz;
915*323230efSJohn Youn 	bool forced;
916*323230efSJohn Youn 
917*323230efSJohn Youn 	if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL)
918*323230efSJohn Youn 		return;
919*323230efSJohn Youn 
920*323230efSJohn Youn 	forced = dwc2_force_mode_if_needed(hsotg, true);
921*323230efSJohn Youn 
922*323230efSJohn Youn 	gnptxfsiz = dwc2_readl(hsotg->regs + GNPTXFSIZ);
923*323230efSJohn Youn 	hptxfsiz = dwc2_readl(hsotg->regs + HPTXFSIZ);
924*323230efSJohn Youn 	dev_dbg(hsotg->dev, "gnptxfsiz=%08x\n", gnptxfsiz);
925*323230efSJohn Youn 	dev_dbg(hsotg->dev, "hptxfsiz=%08x\n", hptxfsiz);
926*323230efSJohn Youn 
927*323230efSJohn Youn 	if (forced)
928*323230efSJohn Youn 		dwc2_clear_force_mode(hsotg);
929*323230efSJohn Youn 
930*323230efSJohn Youn 	hw->host_nperio_tx_fifo_size = (gnptxfsiz & FIFOSIZE_DEPTH_MASK) >>
931*323230efSJohn Youn 				       FIFOSIZE_DEPTH_SHIFT;
932*323230efSJohn Youn 	hw->host_perio_tx_fifo_size = (hptxfsiz & FIFOSIZE_DEPTH_MASK) >>
933*323230efSJohn Youn 				      FIFOSIZE_DEPTH_SHIFT;
934*323230efSJohn Youn }
935*323230efSJohn Youn 
936*323230efSJohn Youn /*
937*323230efSJohn Youn  * Gets device hardware parameters. Forces device mode if not
938*323230efSJohn Youn  * currently in device mode. Should be called immediately after a core
939*323230efSJohn Youn  * soft reset in order to get the reset values.
940*323230efSJohn Youn  */
941*323230efSJohn Youn static void dwc2_get_dev_hwparams(struct dwc2_hsotg *hsotg)
942*323230efSJohn Youn {
943*323230efSJohn Youn 	struct dwc2_hw_params *hw = &hsotg->hw_params;
944*323230efSJohn Youn 	bool forced;
945*323230efSJohn Youn 	u32 gnptxfsiz;
946*323230efSJohn Youn 
947*323230efSJohn Youn 	if (hsotg->dr_mode == USB_DR_MODE_HOST)
948*323230efSJohn Youn 		return;
949*323230efSJohn Youn 
950*323230efSJohn Youn 	forced = dwc2_force_mode_if_needed(hsotg, false);
951*323230efSJohn Youn 
952*323230efSJohn Youn 	gnptxfsiz = dwc2_readl(hsotg->regs + GNPTXFSIZ);
953*323230efSJohn Youn 	dev_dbg(hsotg->dev, "gnptxfsiz=%08x\n", gnptxfsiz);
954*323230efSJohn Youn 
955*323230efSJohn Youn 	if (forced)
956*323230efSJohn Youn 		dwc2_clear_force_mode(hsotg);
957*323230efSJohn Youn 
958*323230efSJohn Youn 	hw->dev_nperio_tx_fifo_size = (gnptxfsiz & FIFOSIZE_DEPTH_MASK) >>
959*323230efSJohn Youn 				       FIFOSIZE_DEPTH_SHIFT;
960*323230efSJohn Youn }
961*323230efSJohn Youn 
962*323230efSJohn Youn /**
963*323230efSJohn Youn  * During device initialization, read various hardware configuration
964*323230efSJohn Youn  * registers and interpret the contents.
965*323230efSJohn Youn  */
966*323230efSJohn Youn int dwc2_get_hwparams(struct dwc2_hsotg *hsotg)
967*323230efSJohn Youn {
968*323230efSJohn Youn 	struct dwc2_hw_params *hw = &hsotg->hw_params;
969*323230efSJohn Youn 	unsigned int width;
970*323230efSJohn Youn 	u32 hwcfg1, hwcfg2, hwcfg3, hwcfg4;
971*323230efSJohn Youn 	u32 grxfsiz;
972*323230efSJohn Youn 
973*323230efSJohn Youn 	/*
974*323230efSJohn Youn 	 * Attempt to ensure this device is really a DWC_otg Controller.
975*323230efSJohn Youn 	 * Read and verify the GSNPSID register contents. The value should be
976*323230efSJohn Youn 	 * 0x45f42xxx or 0x45f43xxx, which corresponds to either "OT2" or "OT3",
977*323230efSJohn Youn 	 * as in "OTG version 2.xx" or "OTG version 3.xx".
978*323230efSJohn Youn 	 */
979*323230efSJohn Youn 	hw->snpsid = dwc2_readl(hsotg->regs + GSNPSID);
980*323230efSJohn Youn 	if ((hw->snpsid & 0xfffff000) != 0x4f542000 &&
981*323230efSJohn Youn 	    (hw->snpsid & 0xfffff000) != 0x4f543000) {
982*323230efSJohn Youn 		dev_err(hsotg->dev, "Bad value for GSNPSID: 0x%08x\n",
983*323230efSJohn Youn 			hw->snpsid);
984*323230efSJohn Youn 		return -ENODEV;
985*323230efSJohn Youn 	}
986*323230efSJohn Youn 
987*323230efSJohn Youn 	dev_dbg(hsotg->dev, "Core Release: %1x.%1x%1x%1x (snpsid=%x)\n",
988*323230efSJohn Youn 		hw->snpsid >> 12 & 0xf, hw->snpsid >> 8 & 0xf,
989*323230efSJohn Youn 		hw->snpsid >> 4 & 0xf, hw->snpsid & 0xf, hw->snpsid);
990*323230efSJohn Youn 
991*323230efSJohn Youn 	hwcfg1 = dwc2_readl(hsotg->regs + GHWCFG1);
992*323230efSJohn Youn 	hwcfg2 = dwc2_readl(hsotg->regs + GHWCFG2);
993*323230efSJohn Youn 	hwcfg3 = dwc2_readl(hsotg->regs + GHWCFG3);
994*323230efSJohn Youn 	hwcfg4 = dwc2_readl(hsotg->regs + GHWCFG4);
995*323230efSJohn Youn 	grxfsiz = dwc2_readl(hsotg->regs + GRXFSIZ);
996*323230efSJohn Youn 
997*323230efSJohn Youn 	dev_dbg(hsotg->dev, "hwcfg1=%08x\n", hwcfg1);
998*323230efSJohn Youn 	dev_dbg(hsotg->dev, "hwcfg2=%08x\n", hwcfg2);
999*323230efSJohn Youn 	dev_dbg(hsotg->dev, "hwcfg3=%08x\n", hwcfg3);
1000*323230efSJohn Youn 	dev_dbg(hsotg->dev, "hwcfg4=%08x\n", hwcfg4);
1001*323230efSJohn Youn 	dev_dbg(hsotg->dev, "grxfsiz=%08x\n", grxfsiz);
1002*323230efSJohn Youn 
1003*323230efSJohn Youn 	/*
1004*323230efSJohn Youn 	 * Host specific hardware parameters. Reading these parameters
1005*323230efSJohn Youn 	 * requires the controller to be in host mode. The mode will
1006*323230efSJohn Youn 	 * be forced, if necessary, to read these values.
1007*323230efSJohn Youn 	 */
1008*323230efSJohn Youn 	dwc2_get_host_hwparams(hsotg);
1009*323230efSJohn Youn 	dwc2_get_dev_hwparams(hsotg);
1010*323230efSJohn Youn 
1011*323230efSJohn Youn 	/* hwcfg1 */
1012*323230efSJohn Youn 	hw->dev_ep_dirs = hwcfg1;
1013*323230efSJohn Youn 
1014*323230efSJohn Youn 	/* hwcfg2 */
1015*323230efSJohn Youn 	hw->op_mode = (hwcfg2 & GHWCFG2_OP_MODE_MASK) >>
1016*323230efSJohn Youn 		      GHWCFG2_OP_MODE_SHIFT;
1017*323230efSJohn Youn 	hw->arch = (hwcfg2 & GHWCFG2_ARCHITECTURE_MASK) >>
1018*323230efSJohn Youn 		   GHWCFG2_ARCHITECTURE_SHIFT;
1019*323230efSJohn Youn 	hw->enable_dynamic_fifo = !!(hwcfg2 & GHWCFG2_DYNAMIC_FIFO);
1020*323230efSJohn Youn 	hw->host_channels = 1 + ((hwcfg2 & GHWCFG2_NUM_HOST_CHAN_MASK) >>
1021*323230efSJohn Youn 				GHWCFG2_NUM_HOST_CHAN_SHIFT);
1022*323230efSJohn Youn 	hw->hs_phy_type = (hwcfg2 & GHWCFG2_HS_PHY_TYPE_MASK) >>
1023*323230efSJohn Youn 			  GHWCFG2_HS_PHY_TYPE_SHIFT;
1024*323230efSJohn Youn 	hw->fs_phy_type = (hwcfg2 & GHWCFG2_FS_PHY_TYPE_MASK) >>
1025*323230efSJohn Youn 			  GHWCFG2_FS_PHY_TYPE_SHIFT;
1026*323230efSJohn Youn 	hw->num_dev_ep = (hwcfg2 & GHWCFG2_NUM_DEV_EP_MASK) >>
1027*323230efSJohn Youn 			 GHWCFG2_NUM_DEV_EP_SHIFT;
1028*323230efSJohn Youn 	hw->nperio_tx_q_depth =
1029*323230efSJohn Youn 		(hwcfg2 & GHWCFG2_NONPERIO_TX_Q_DEPTH_MASK) >>
1030*323230efSJohn Youn 		GHWCFG2_NONPERIO_TX_Q_DEPTH_SHIFT << 1;
1031*323230efSJohn Youn 	hw->host_perio_tx_q_depth =
1032*323230efSJohn Youn 		(hwcfg2 & GHWCFG2_HOST_PERIO_TX_Q_DEPTH_MASK) >>
1033*323230efSJohn Youn 		GHWCFG2_HOST_PERIO_TX_Q_DEPTH_SHIFT << 1;
1034*323230efSJohn Youn 	hw->dev_token_q_depth =
1035*323230efSJohn Youn 		(hwcfg2 & GHWCFG2_DEV_TOKEN_Q_DEPTH_MASK) >>
1036*323230efSJohn Youn 		GHWCFG2_DEV_TOKEN_Q_DEPTH_SHIFT;
1037*323230efSJohn Youn 
1038*323230efSJohn Youn 	/* hwcfg3 */
1039*323230efSJohn Youn 	width = (hwcfg3 & GHWCFG3_XFER_SIZE_CNTR_WIDTH_MASK) >>
1040*323230efSJohn Youn 		GHWCFG3_XFER_SIZE_CNTR_WIDTH_SHIFT;
1041*323230efSJohn Youn 	hw->max_transfer_size = (1 << (width + 11)) - 1;
1042*323230efSJohn Youn 	width = (hwcfg3 & GHWCFG3_PACKET_SIZE_CNTR_WIDTH_MASK) >>
1043*323230efSJohn Youn 		GHWCFG3_PACKET_SIZE_CNTR_WIDTH_SHIFT;
1044*323230efSJohn Youn 	hw->max_packet_count = (1 << (width + 4)) - 1;
1045*323230efSJohn Youn 	hw->i2c_enable = !!(hwcfg3 & GHWCFG3_I2C);
1046*323230efSJohn Youn 	hw->total_fifo_size = (hwcfg3 & GHWCFG3_DFIFO_DEPTH_MASK) >>
1047*323230efSJohn Youn 			      GHWCFG3_DFIFO_DEPTH_SHIFT;
1048*323230efSJohn Youn 
1049*323230efSJohn Youn 	/* hwcfg4 */
1050*323230efSJohn Youn 	hw->en_multiple_tx_fifo = !!(hwcfg4 & GHWCFG4_DED_FIFO_EN);
1051*323230efSJohn Youn 	hw->num_dev_perio_in_ep = (hwcfg4 & GHWCFG4_NUM_DEV_PERIO_IN_EP_MASK) >>
1052*323230efSJohn Youn 				  GHWCFG4_NUM_DEV_PERIO_IN_EP_SHIFT;
1053*323230efSJohn Youn 	hw->dma_desc_enable = !!(hwcfg4 & GHWCFG4_DESC_DMA);
1054*323230efSJohn Youn 	hw->power_optimized = !!(hwcfg4 & GHWCFG4_POWER_OPTIMIZ);
1055*323230efSJohn Youn 	hw->utmi_phy_data_width = (hwcfg4 & GHWCFG4_UTMI_PHY_DATA_WIDTH_MASK) >>
1056*323230efSJohn Youn 				  GHWCFG4_UTMI_PHY_DATA_WIDTH_SHIFT;
1057*323230efSJohn Youn 
1058*323230efSJohn Youn 	/* fifo sizes */
1059*323230efSJohn Youn 	hw->host_rx_fifo_size = (grxfsiz & GRXFSIZ_DEPTH_MASK) >>
1060*323230efSJohn Youn 				GRXFSIZ_DEPTH_SHIFT;
1061*323230efSJohn Youn 
1062*323230efSJohn Youn 	dev_dbg(hsotg->dev, "Detected values from hardware:\n");
1063*323230efSJohn Youn 	dev_dbg(hsotg->dev, "  op_mode=%d\n",
1064*323230efSJohn Youn 		hw->op_mode);
1065*323230efSJohn Youn 	dev_dbg(hsotg->dev, "  arch=%d\n",
1066*323230efSJohn Youn 		hw->arch);
1067*323230efSJohn Youn 	dev_dbg(hsotg->dev, "  dma_desc_enable=%d\n",
1068*323230efSJohn Youn 		hw->dma_desc_enable);
1069*323230efSJohn Youn 	dev_dbg(hsotg->dev, "  power_optimized=%d\n",
1070*323230efSJohn Youn 		hw->power_optimized);
1071*323230efSJohn Youn 	dev_dbg(hsotg->dev, "  i2c_enable=%d\n",
1072*323230efSJohn Youn 		hw->i2c_enable);
1073*323230efSJohn Youn 	dev_dbg(hsotg->dev, "  hs_phy_type=%d\n",
1074*323230efSJohn Youn 		hw->hs_phy_type);
1075*323230efSJohn Youn 	dev_dbg(hsotg->dev, "  fs_phy_type=%d\n",
1076*323230efSJohn Youn 		hw->fs_phy_type);
1077*323230efSJohn Youn 	dev_dbg(hsotg->dev, "  utmi_phy_data_width=%d\n",
1078*323230efSJohn Youn 		hw->utmi_phy_data_width);
1079*323230efSJohn Youn 	dev_dbg(hsotg->dev, "  num_dev_ep=%d\n",
1080*323230efSJohn Youn 		hw->num_dev_ep);
1081*323230efSJohn Youn 	dev_dbg(hsotg->dev, "  num_dev_perio_in_ep=%d\n",
1082*323230efSJohn Youn 		hw->num_dev_perio_in_ep);
1083*323230efSJohn Youn 	dev_dbg(hsotg->dev, "  host_channels=%d\n",
1084*323230efSJohn Youn 		hw->host_channels);
1085*323230efSJohn Youn 	dev_dbg(hsotg->dev, "  max_transfer_size=%d\n",
1086*323230efSJohn Youn 		hw->max_transfer_size);
1087*323230efSJohn Youn 	dev_dbg(hsotg->dev, "  max_packet_count=%d\n",
1088*323230efSJohn Youn 		hw->max_packet_count);
1089*323230efSJohn Youn 	dev_dbg(hsotg->dev, "  nperio_tx_q_depth=0x%0x\n",
1090*323230efSJohn Youn 		hw->nperio_tx_q_depth);
1091*323230efSJohn Youn 	dev_dbg(hsotg->dev, "  host_perio_tx_q_depth=0x%0x\n",
1092*323230efSJohn Youn 		hw->host_perio_tx_q_depth);
1093*323230efSJohn Youn 	dev_dbg(hsotg->dev, "  dev_token_q_depth=0x%0x\n",
1094*323230efSJohn Youn 		hw->dev_token_q_depth);
1095*323230efSJohn Youn 	dev_dbg(hsotg->dev, "  enable_dynamic_fifo=%d\n",
1096*323230efSJohn Youn 		hw->enable_dynamic_fifo);
1097*323230efSJohn Youn 	dev_dbg(hsotg->dev, "  en_multiple_tx_fifo=%d\n",
1098*323230efSJohn Youn 		hw->en_multiple_tx_fifo);
1099*323230efSJohn Youn 	dev_dbg(hsotg->dev, "  total_fifo_size=%d\n",
1100*323230efSJohn Youn 		hw->total_fifo_size);
1101*323230efSJohn Youn 	dev_dbg(hsotg->dev, "  host_rx_fifo_size=%d\n",
1102*323230efSJohn Youn 		hw->host_rx_fifo_size);
1103*323230efSJohn Youn 	dev_dbg(hsotg->dev, "  host_nperio_tx_fifo_size=%d\n",
1104*323230efSJohn Youn 		hw->host_nperio_tx_fifo_size);
1105*323230efSJohn Youn 	dev_dbg(hsotg->dev, "  host_perio_tx_fifo_size=%d\n",
1106*323230efSJohn Youn 		hw->host_perio_tx_fifo_size);
1107*323230efSJohn Youn 	dev_dbg(hsotg->dev, "\n");
1108*323230efSJohn Youn 
1109*323230efSJohn Youn 	return 0;
1110*323230efSJohn Youn }
1111*323230efSJohn Youn 
1112*323230efSJohn Youn /*
1113*323230efSJohn Youn  * Sets all parameters to the given value.
1114*323230efSJohn Youn  *
1115*323230efSJohn Youn  * Assumes that the dwc2_core_params struct contains only integers.
1116*323230efSJohn Youn  */
1117*323230efSJohn Youn void dwc2_set_all_params(struct dwc2_core_params *params, int value)
1118*323230efSJohn Youn {
1119*323230efSJohn Youn 	int *p = (int *)params;
1120*323230efSJohn Youn 	size_t size = sizeof(*params) / sizeof(*p);
1121*323230efSJohn Youn 	int i;
1122*323230efSJohn Youn 
1123*323230efSJohn Youn 	for (i = 0; i < size; i++)
1124*323230efSJohn Youn 		p[i] = value;
1125*323230efSJohn Youn }
1126