1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * XHCI HCD glue for Cavium Octeon III SOCs.
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * Copyright (C) 2010-2017 Cavium Networks
5*4882a593Smuzhiyun *
6*4882a593Smuzhiyun * This file is subject to the terms and conditions of the GNU General Public
7*4882a593Smuzhiyun * License. See the file "COPYING" in the main directory of this archive
8*4882a593Smuzhiyun * for more details.
9*4882a593Smuzhiyun */
10*4882a593Smuzhiyun
11*4882a593Smuzhiyun #include <linux/module.h>
12*4882a593Smuzhiyun #include <linux/device.h>
13*4882a593Smuzhiyun #include <linux/mutex.h>
14*4882a593Smuzhiyun #include <linux/delay.h>
15*4882a593Smuzhiyun #include <linux/of_platform.h>
16*4882a593Smuzhiyun #include <linux/io.h>
17*4882a593Smuzhiyun
18*4882a593Smuzhiyun #include <asm/octeon/octeon.h>
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun /* USB Control Register */
21*4882a593Smuzhiyun union cvm_usbdrd_uctl_ctl {
22*4882a593Smuzhiyun uint64_t u64;
23*4882a593Smuzhiyun struct cvm_usbdrd_uctl_ctl_s {
24*4882a593Smuzhiyun /* 1 = BIST and set all USB RAMs to 0x0, 0 = BIST */
25*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t clear_bist:1,
26*4882a593Smuzhiyun /* 1 = Start BIST and cleared by hardware */
27*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t start_bist:1,
28*4882a593Smuzhiyun /* Reference clock select for SuperSpeed and HighSpeed PLLs:
29*4882a593Smuzhiyun * 0x0 = Both PLLs use DLMC_REF_CLK0 for reference clock
30*4882a593Smuzhiyun * 0x1 = Both PLLs use DLMC_REF_CLK1 for reference clock
31*4882a593Smuzhiyun * 0x2 = SuperSpeed PLL uses DLMC_REF_CLK0 for reference clock &
32*4882a593Smuzhiyun * HighSpeed PLL uses PLL_REF_CLK for reference clck
33*4882a593Smuzhiyun * 0x3 = SuperSpeed PLL uses DLMC_REF_CLK1 for reference clock &
34*4882a593Smuzhiyun * HighSpeed PLL uses PLL_REF_CLK for reference clck
35*4882a593Smuzhiyun */
36*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t ref_clk_sel:2,
37*4882a593Smuzhiyun /* 1 = Spread-spectrum clock enable, 0 = SS clock disable */
38*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t ssc_en:1,
39*4882a593Smuzhiyun /* Spread-spectrum clock modulation range:
40*4882a593Smuzhiyun * 0x0 = -4980 ppm downspread
41*4882a593Smuzhiyun * 0x1 = -4492 ppm downspread
42*4882a593Smuzhiyun * 0x2 = -4003 ppm downspread
43*4882a593Smuzhiyun * 0x3 - 0x7 = Reserved
44*4882a593Smuzhiyun */
45*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t ssc_range:3,
46*4882a593Smuzhiyun /* Enable non-standard oscillator frequencies:
47*4882a593Smuzhiyun * [55:53] = modules -1
48*4882a593Smuzhiyun * [52:47] = 2's complement push amount, 0 = Feature disabled
49*4882a593Smuzhiyun */
50*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t ssc_ref_clk_sel:9,
51*4882a593Smuzhiyun /* Reference clock multiplier for non-standard frequencies:
52*4882a593Smuzhiyun * 0x19 = 100MHz on DLMC_REF_CLK* if REF_CLK_SEL = 0x0 or 0x1
53*4882a593Smuzhiyun * 0x28 = 125MHz on DLMC_REF_CLK* if REF_CLK_SEL = 0x0 or 0x1
54*4882a593Smuzhiyun * 0x32 = 50MHz on DLMC_REF_CLK* if REF_CLK_SEL = 0x0 or 0x1
55*4882a593Smuzhiyun * Other Values = Reserved
56*4882a593Smuzhiyun */
57*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t mpll_multiplier:7,
58*4882a593Smuzhiyun /* Enable reference clock to prescaler for SuperSpeed functionality.
59*4882a593Smuzhiyun * Should always be set to "1"
60*4882a593Smuzhiyun */
61*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t ref_ssp_en:1,
62*4882a593Smuzhiyun /* Divide the reference clock by 2 before entering the
63*4882a593Smuzhiyun * REF_CLK_FSEL divider:
64*4882a593Smuzhiyun * If REF_CLK_SEL = 0x0 or 0x1, then only 0x0 is legal
65*4882a593Smuzhiyun * If REF_CLK_SEL = 0x2 or 0x3, then:
66*4882a593Smuzhiyun * 0x1 = DLMC_REF_CLK* is 125MHz
67*4882a593Smuzhiyun * 0x0 = DLMC_REF_CLK* is another supported frequency
68*4882a593Smuzhiyun */
69*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t ref_clk_div2:1,
70*4882a593Smuzhiyun /* Select reference clock freqnuency for both PLL blocks:
71*4882a593Smuzhiyun * 0x27 = REF_CLK_SEL is 0x0 or 0x1
72*4882a593Smuzhiyun * 0x07 = REF_CLK_SEL is 0x2 or 0x3
73*4882a593Smuzhiyun */
74*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t ref_clk_fsel:6,
75*4882a593Smuzhiyun /* Reserved */
76*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t reserved_31_31:1,
77*4882a593Smuzhiyun /* Controller clock enable. */
78*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t h_clk_en:1,
79*4882a593Smuzhiyun /* Select bypass input to controller clock divider:
80*4882a593Smuzhiyun * 0x0 = Use divided coprocessor clock from H_CLKDIV
81*4882a593Smuzhiyun * 0x1 = Use clock from GPIO pins
82*4882a593Smuzhiyun */
83*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t h_clk_byp_sel:1,
84*4882a593Smuzhiyun /* Reset controller clock divider. */
85*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t h_clkdiv_rst:1,
86*4882a593Smuzhiyun /* Reserved */
87*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t reserved_27_27:1,
88*4882a593Smuzhiyun /* Clock divider select:
89*4882a593Smuzhiyun * 0x0 = divide by 1
90*4882a593Smuzhiyun * 0x1 = divide by 2
91*4882a593Smuzhiyun * 0x2 = divide by 4
92*4882a593Smuzhiyun * 0x3 = divide by 6
93*4882a593Smuzhiyun * 0x4 = divide by 8
94*4882a593Smuzhiyun * 0x5 = divide by 16
95*4882a593Smuzhiyun * 0x6 = divide by 24
96*4882a593Smuzhiyun * 0x7 = divide by 32
97*4882a593Smuzhiyun */
98*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t h_clkdiv_sel:3,
99*4882a593Smuzhiyun /* Reserved */
100*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t reserved_22_23:2,
101*4882a593Smuzhiyun /* USB3 port permanently attached: 0x0 = No, 0x1 = Yes */
102*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t usb3_port_perm_attach:1,
103*4882a593Smuzhiyun /* USB2 port permanently attached: 0x0 = No, 0x1 = Yes */
104*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t usb2_port_perm_attach:1,
105*4882a593Smuzhiyun /* Reserved */
106*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t reserved_19_19:1,
107*4882a593Smuzhiyun /* Disable SuperSpeed PHY: 0x0 = No, 0x1 = Yes */
108*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t usb3_port_disable:1,
109*4882a593Smuzhiyun /* Reserved */
110*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t reserved_17_17:1,
111*4882a593Smuzhiyun /* Disable HighSpeed PHY: 0x0 = No, 0x1 = Yes */
112*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t usb2_port_disable:1,
113*4882a593Smuzhiyun /* Reserved */
114*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t reserved_15_15:1,
115*4882a593Smuzhiyun /* Enable PHY SuperSpeed block power: 0x0 = No, 0x1 = Yes */
116*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t ss_power_en:1,
117*4882a593Smuzhiyun /* Reserved */
118*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t reserved_13_13:1,
119*4882a593Smuzhiyun /* Enable PHY HighSpeed block power: 0x0 = No, 0x1 = Yes */
120*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t hs_power_en:1,
121*4882a593Smuzhiyun /* Reserved */
122*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t reserved_5_11:7,
123*4882a593Smuzhiyun /* Enable USB UCTL interface clock: 0xx = No, 0x1 = Yes */
124*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t csclk_en:1,
125*4882a593Smuzhiyun /* Controller mode: 0x0 = Host, 0x1 = Device */
126*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t drd_mode:1,
127*4882a593Smuzhiyun /* PHY reset */
128*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t uphy_rst:1,
129*4882a593Smuzhiyun /* Software reset UAHC */
130*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t uahc_rst:1,
131*4882a593Smuzhiyun /* Software resets UCTL */
132*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t uctl_rst:1,
133*4882a593Smuzhiyun ;)))))))))))))))))))))))))))))))))
134*4882a593Smuzhiyun } s;
135*4882a593Smuzhiyun };
136*4882a593Smuzhiyun
137*4882a593Smuzhiyun /* UAHC Configuration Register */
138*4882a593Smuzhiyun union cvm_usbdrd_uctl_host_cfg {
139*4882a593Smuzhiyun uint64_t u64;
140*4882a593Smuzhiyun struct cvm_usbdrd_uctl_host_cfg_s {
141*4882a593Smuzhiyun /* Reserved */
142*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t reserved_60_63:4,
143*4882a593Smuzhiyun /* Indicates minimum value of all received BELT values */
144*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t host_current_belt:12,
145*4882a593Smuzhiyun /* Reserved */
146*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t reserved_38_47:10,
147*4882a593Smuzhiyun /* HS jitter adjustment */
148*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t fla:6,
149*4882a593Smuzhiyun /* Reserved */
150*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t reserved_29_31:3,
151*4882a593Smuzhiyun /* Bus-master enable: 0x0 = Disabled (stall DMAs), 0x1 = enabled */
152*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t bme:1,
153*4882a593Smuzhiyun /* Overcurrent protection enable: 0x0 = unavailable, 0x1 = available */
154*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t oci_en:1,
155*4882a593Smuzhiyun /* Overcurrent sene selection:
156*4882a593Smuzhiyun * 0x0 = Overcurrent indication from off-chip is active-low
157*4882a593Smuzhiyun * 0x1 = Overcurrent indication from off-chip is active-high
158*4882a593Smuzhiyun */
159*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t oci_active_high_en:1,
160*4882a593Smuzhiyun /* Port power control enable: 0x0 = unavailable, 0x1 = available */
161*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t ppc_en:1,
162*4882a593Smuzhiyun /* Port power control sense selection:
163*4882a593Smuzhiyun * 0x0 = Port power to off-chip is active-low
164*4882a593Smuzhiyun * 0x1 = Port power to off-chip is active-high
165*4882a593Smuzhiyun */
166*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t ppc_active_high_en:1,
167*4882a593Smuzhiyun /* Reserved */
168*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t reserved_0_23:24,
169*4882a593Smuzhiyun ;)))))))))))
170*4882a593Smuzhiyun } s;
171*4882a593Smuzhiyun };
172*4882a593Smuzhiyun
173*4882a593Smuzhiyun /* UCTL Shim Features Register */
174*4882a593Smuzhiyun union cvm_usbdrd_uctl_shim_cfg {
175*4882a593Smuzhiyun uint64_t u64;
176*4882a593Smuzhiyun struct cvm_usbdrd_uctl_shim_cfg_s {
177*4882a593Smuzhiyun /* Out-of-bound UAHC register access: 0 = read, 1 = write */
178*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t xs_ncb_oob_wrn:1,
179*4882a593Smuzhiyun /* Reserved */
180*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t reserved_60_62:3,
181*4882a593Smuzhiyun /* SRCID error log for out-of-bound UAHC register access:
182*4882a593Smuzhiyun * [59:58] = chipID
183*4882a593Smuzhiyun * [57] = Request source: 0 = core, 1 = NCB-device
184*4882a593Smuzhiyun * [56:51] = Core/NCB-device number, [56] always 0 for NCB devices
185*4882a593Smuzhiyun * [50:48] = SubID
186*4882a593Smuzhiyun */
187*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t xs_ncb_oob_osrc:12,
188*4882a593Smuzhiyun /* Error log for bad UAHC DMA access: 0 = Read log, 1 = Write log */
189*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t xm_bad_dma_wrn:1,
190*4882a593Smuzhiyun /* Reserved */
191*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t reserved_44_46:3,
192*4882a593Smuzhiyun /* Encoded error type for bad UAHC DMA */
193*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t xm_bad_dma_type:4,
194*4882a593Smuzhiyun /* Reserved */
195*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t reserved_13_39:27,
196*4882a593Smuzhiyun /* Select the IOI read command used by DMA accesses */
197*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t dma_read_cmd:1,
198*4882a593Smuzhiyun /* Reserved */
199*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t reserved_10_11:2,
200*4882a593Smuzhiyun /* Select endian format for DMA accesses to the L2c:
201*4882a593Smuzhiyun * 0x0 = Little endian
202*4882a593Smuzhiyun *` 0x1 = Big endian
203*4882a593Smuzhiyun * 0x2 = Reserved
204*4882a593Smuzhiyun * 0x3 = Reserved
205*4882a593Smuzhiyun */
206*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t dma_endian_mode:2,
207*4882a593Smuzhiyun /* Reserved */
208*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t reserved_2_7:6,
209*4882a593Smuzhiyun /* Select endian format for IOI CSR access to UAHC:
210*4882a593Smuzhiyun * 0x0 = Little endian
211*4882a593Smuzhiyun *` 0x1 = Big endian
212*4882a593Smuzhiyun * 0x2 = Reserved
213*4882a593Smuzhiyun * 0x3 = Reserved
214*4882a593Smuzhiyun */
215*4882a593Smuzhiyun __BITFIELD_FIELD(uint64_t csr_endian_mode:2,
216*4882a593Smuzhiyun ;))))))))))))
217*4882a593Smuzhiyun } s;
218*4882a593Smuzhiyun };
219*4882a593Smuzhiyun
220*4882a593Smuzhiyun #define OCTEON_H_CLKDIV_SEL 8
221*4882a593Smuzhiyun #define OCTEON_MIN_H_CLK_RATE 150000000
222*4882a593Smuzhiyun #define OCTEON_MAX_H_CLK_RATE 300000000
223*4882a593Smuzhiyun
224*4882a593Smuzhiyun static DEFINE_MUTEX(dwc3_octeon_clocks_mutex);
225*4882a593Smuzhiyun static uint8_t clk_div[OCTEON_H_CLKDIV_SEL] = {1, 2, 4, 6, 8, 16, 24, 32};
226*4882a593Smuzhiyun
227*4882a593Smuzhiyun
dwc3_octeon_config_power(struct device * dev,u64 base)228*4882a593Smuzhiyun static int dwc3_octeon_config_power(struct device *dev, u64 base)
229*4882a593Smuzhiyun {
230*4882a593Smuzhiyun #define UCTL_HOST_CFG 0xe0
231*4882a593Smuzhiyun union cvm_usbdrd_uctl_host_cfg uctl_host_cfg;
232*4882a593Smuzhiyun union cvmx_gpio_bit_cfgx gpio_bit;
233*4882a593Smuzhiyun uint32_t gpio_pwr[3];
234*4882a593Smuzhiyun int gpio, len, power_active_low;
235*4882a593Smuzhiyun struct device_node *node = dev->of_node;
236*4882a593Smuzhiyun int index = (base >> 24) & 1;
237*4882a593Smuzhiyun
238*4882a593Smuzhiyun if (of_find_property(node, "power", &len) != NULL) {
239*4882a593Smuzhiyun if (len == 12) {
240*4882a593Smuzhiyun of_property_read_u32_array(node, "power", gpio_pwr, 3);
241*4882a593Smuzhiyun power_active_low = gpio_pwr[2] & 0x01;
242*4882a593Smuzhiyun gpio = gpio_pwr[1];
243*4882a593Smuzhiyun } else if (len == 8) {
244*4882a593Smuzhiyun of_property_read_u32_array(node, "power", gpio_pwr, 2);
245*4882a593Smuzhiyun power_active_low = 0;
246*4882a593Smuzhiyun gpio = gpio_pwr[1];
247*4882a593Smuzhiyun } else {
248*4882a593Smuzhiyun dev_err(dev, "dwc3 controller clock init failure.\n");
249*4882a593Smuzhiyun return -EINVAL;
250*4882a593Smuzhiyun }
251*4882a593Smuzhiyun if ((OCTEON_IS_MODEL(OCTEON_CN73XX) ||
252*4882a593Smuzhiyun OCTEON_IS_MODEL(OCTEON_CNF75XX))
253*4882a593Smuzhiyun && gpio <= 31) {
254*4882a593Smuzhiyun gpio_bit.u64 = cvmx_read_csr(CVMX_GPIO_BIT_CFGX(gpio));
255*4882a593Smuzhiyun gpio_bit.s.tx_oe = 1;
256*4882a593Smuzhiyun gpio_bit.s.output_sel = (index == 0 ? 0x14 : 0x15);
257*4882a593Smuzhiyun cvmx_write_csr(CVMX_GPIO_BIT_CFGX(gpio), gpio_bit.u64);
258*4882a593Smuzhiyun } else if (gpio <= 15) {
259*4882a593Smuzhiyun gpio_bit.u64 = cvmx_read_csr(CVMX_GPIO_BIT_CFGX(gpio));
260*4882a593Smuzhiyun gpio_bit.s.tx_oe = 1;
261*4882a593Smuzhiyun gpio_bit.s.output_sel = (index == 0 ? 0x14 : 0x19);
262*4882a593Smuzhiyun cvmx_write_csr(CVMX_GPIO_BIT_CFGX(gpio), gpio_bit.u64);
263*4882a593Smuzhiyun } else {
264*4882a593Smuzhiyun gpio_bit.u64 = cvmx_read_csr(CVMX_GPIO_XBIT_CFGX(gpio));
265*4882a593Smuzhiyun gpio_bit.s.tx_oe = 1;
266*4882a593Smuzhiyun gpio_bit.s.output_sel = (index == 0 ? 0x14 : 0x19);
267*4882a593Smuzhiyun cvmx_write_csr(CVMX_GPIO_XBIT_CFGX(gpio), gpio_bit.u64);
268*4882a593Smuzhiyun }
269*4882a593Smuzhiyun
270*4882a593Smuzhiyun /* Enable XHCI power control and set if active high or low. */
271*4882a593Smuzhiyun uctl_host_cfg.u64 = cvmx_read_csr(base + UCTL_HOST_CFG);
272*4882a593Smuzhiyun uctl_host_cfg.s.ppc_en = 1;
273*4882a593Smuzhiyun uctl_host_cfg.s.ppc_active_high_en = !power_active_low;
274*4882a593Smuzhiyun cvmx_write_csr(base + UCTL_HOST_CFG, uctl_host_cfg.u64);
275*4882a593Smuzhiyun } else {
276*4882a593Smuzhiyun /* Disable XHCI power control and set if active high. */
277*4882a593Smuzhiyun uctl_host_cfg.u64 = cvmx_read_csr(base + UCTL_HOST_CFG);
278*4882a593Smuzhiyun uctl_host_cfg.s.ppc_en = 0;
279*4882a593Smuzhiyun uctl_host_cfg.s.ppc_active_high_en = 0;
280*4882a593Smuzhiyun cvmx_write_csr(base + UCTL_HOST_CFG, uctl_host_cfg.u64);
281*4882a593Smuzhiyun dev_warn(dev, "dwc3 controller clock init failure.\n");
282*4882a593Smuzhiyun }
283*4882a593Smuzhiyun return 0;
284*4882a593Smuzhiyun }
285*4882a593Smuzhiyun
dwc3_octeon_clocks_start(struct device * dev,u64 base)286*4882a593Smuzhiyun static int dwc3_octeon_clocks_start(struct device *dev, u64 base)
287*4882a593Smuzhiyun {
288*4882a593Smuzhiyun union cvm_usbdrd_uctl_ctl uctl_ctl;
289*4882a593Smuzhiyun int ref_clk_sel = 2;
290*4882a593Smuzhiyun u64 div;
291*4882a593Smuzhiyun u32 clock_rate;
292*4882a593Smuzhiyun int mpll_mul;
293*4882a593Smuzhiyun int i;
294*4882a593Smuzhiyun u64 h_clk_rate;
295*4882a593Smuzhiyun u64 uctl_ctl_reg = base;
296*4882a593Smuzhiyun
297*4882a593Smuzhiyun if (dev->of_node) {
298*4882a593Smuzhiyun const char *ss_clock_type;
299*4882a593Smuzhiyun const char *hs_clock_type;
300*4882a593Smuzhiyun
301*4882a593Smuzhiyun i = of_property_read_u32(dev->of_node,
302*4882a593Smuzhiyun "refclk-frequency", &clock_rate);
303*4882a593Smuzhiyun if (i) {
304*4882a593Smuzhiyun pr_err("No UCTL \"refclk-frequency\"\n");
305*4882a593Smuzhiyun return -EINVAL;
306*4882a593Smuzhiyun }
307*4882a593Smuzhiyun i = of_property_read_string(dev->of_node,
308*4882a593Smuzhiyun "refclk-type-ss", &ss_clock_type);
309*4882a593Smuzhiyun if (i) {
310*4882a593Smuzhiyun pr_err("No UCTL \"refclk-type-ss\"\n");
311*4882a593Smuzhiyun return -EINVAL;
312*4882a593Smuzhiyun }
313*4882a593Smuzhiyun i = of_property_read_string(dev->of_node,
314*4882a593Smuzhiyun "refclk-type-hs", &hs_clock_type);
315*4882a593Smuzhiyun if (i) {
316*4882a593Smuzhiyun pr_err("No UCTL \"refclk-type-hs\"\n");
317*4882a593Smuzhiyun return -EINVAL;
318*4882a593Smuzhiyun }
319*4882a593Smuzhiyun if (strcmp("dlmc_ref_clk0", ss_clock_type) == 0) {
320*4882a593Smuzhiyun if (strcmp(hs_clock_type, "dlmc_ref_clk0") == 0)
321*4882a593Smuzhiyun ref_clk_sel = 0;
322*4882a593Smuzhiyun else if (strcmp(hs_clock_type, "pll_ref_clk") == 0)
323*4882a593Smuzhiyun ref_clk_sel = 2;
324*4882a593Smuzhiyun else
325*4882a593Smuzhiyun pr_err("Invalid HS clock type %s, using pll_ref_clk instead\n",
326*4882a593Smuzhiyun hs_clock_type);
327*4882a593Smuzhiyun } else if (strcmp(ss_clock_type, "dlmc_ref_clk1") == 0) {
328*4882a593Smuzhiyun if (strcmp(hs_clock_type, "dlmc_ref_clk1") == 0)
329*4882a593Smuzhiyun ref_clk_sel = 1;
330*4882a593Smuzhiyun else if (strcmp(hs_clock_type, "pll_ref_clk") == 0)
331*4882a593Smuzhiyun ref_clk_sel = 3;
332*4882a593Smuzhiyun else {
333*4882a593Smuzhiyun pr_err("Invalid HS clock type %s, using pll_ref_clk instead\n",
334*4882a593Smuzhiyun hs_clock_type);
335*4882a593Smuzhiyun ref_clk_sel = 3;
336*4882a593Smuzhiyun }
337*4882a593Smuzhiyun } else
338*4882a593Smuzhiyun pr_err("Invalid SS clock type %s, using dlmc_ref_clk0 instead\n",
339*4882a593Smuzhiyun ss_clock_type);
340*4882a593Smuzhiyun
341*4882a593Smuzhiyun if ((ref_clk_sel == 0 || ref_clk_sel == 1) &&
342*4882a593Smuzhiyun (clock_rate != 100000000))
343*4882a593Smuzhiyun pr_err("Invalid UCTL clock rate of %u, using 100000000 instead\n",
344*4882a593Smuzhiyun clock_rate);
345*4882a593Smuzhiyun
346*4882a593Smuzhiyun } else {
347*4882a593Smuzhiyun pr_err("No USB UCTL device node\n");
348*4882a593Smuzhiyun return -EINVAL;
349*4882a593Smuzhiyun }
350*4882a593Smuzhiyun
351*4882a593Smuzhiyun /*
352*4882a593Smuzhiyun * Step 1: Wait for all voltages to be stable...that surely
353*4882a593Smuzhiyun * happened before starting the kernel. SKIP
354*4882a593Smuzhiyun */
355*4882a593Smuzhiyun
356*4882a593Smuzhiyun /* Step 2: Select GPIO for overcurrent indication, if desired. SKIP */
357*4882a593Smuzhiyun
358*4882a593Smuzhiyun /* Step 3: Assert all resets. */
359*4882a593Smuzhiyun uctl_ctl.u64 = cvmx_read_csr(uctl_ctl_reg);
360*4882a593Smuzhiyun uctl_ctl.s.uphy_rst = 1;
361*4882a593Smuzhiyun uctl_ctl.s.uahc_rst = 1;
362*4882a593Smuzhiyun uctl_ctl.s.uctl_rst = 1;
363*4882a593Smuzhiyun cvmx_write_csr(uctl_ctl_reg, uctl_ctl.u64);
364*4882a593Smuzhiyun
365*4882a593Smuzhiyun /* Step 4a: Reset the clock dividers. */
366*4882a593Smuzhiyun uctl_ctl.u64 = cvmx_read_csr(uctl_ctl_reg);
367*4882a593Smuzhiyun uctl_ctl.s.h_clkdiv_rst = 1;
368*4882a593Smuzhiyun cvmx_write_csr(uctl_ctl_reg, uctl_ctl.u64);
369*4882a593Smuzhiyun
370*4882a593Smuzhiyun /* Step 4b: Select controller clock frequency. */
371*4882a593Smuzhiyun for (div = 0; div < OCTEON_H_CLKDIV_SEL; div++) {
372*4882a593Smuzhiyun h_clk_rate = octeon_get_io_clock_rate() / clk_div[div];
373*4882a593Smuzhiyun if (h_clk_rate <= OCTEON_MAX_H_CLK_RATE &&
374*4882a593Smuzhiyun h_clk_rate >= OCTEON_MIN_H_CLK_RATE)
375*4882a593Smuzhiyun break;
376*4882a593Smuzhiyun }
377*4882a593Smuzhiyun uctl_ctl.u64 = cvmx_read_csr(uctl_ctl_reg);
378*4882a593Smuzhiyun uctl_ctl.s.h_clkdiv_sel = div;
379*4882a593Smuzhiyun uctl_ctl.s.h_clk_en = 1;
380*4882a593Smuzhiyun cvmx_write_csr(uctl_ctl_reg, uctl_ctl.u64);
381*4882a593Smuzhiyun uctl_ctl.u64 = cvmx_read_csr(uctl_ctl_reg);
382*4882a593Smuzhiyun if ((div != uctl_ctl.s.h_clkdiv_sel) || (!uctl_ctl.s.h_clk_en)) {
383*4882a593Smuzhiyun dev_err(dev, "dwc3 controller clock init failure.\n");
384*4882a593Smuzhiyun return -EINVAL;
385*4882a593Smuzhiyun }
386*4882a593Smuzhiyun
387*4882a593Smuzhiyun /* Step 4c: Deassert the controller clock divider reset. */
388*4882a593Smuzhiyun uctl_ctl.u64 = cvmx_read_csr(uctl_ctl_reg);
389*4882a593Smuzhiyun uctl_ctl.s.h_clkdiv_rst = 0;
390*4882a593Smuzhiyun cvmx_write_csr(uctl_ctl_reg, uctl_ctl.u64);
391*4882a593Smuzhiyun
392*4882a593Smuzhiyun /* Step 5a: Reference clock configuration. */
393*4882a593Smuzhiyun uctl_ctl.u64 = cvmx_read_csr(uctl_ctl_reg);
394*4882a593Smuzhiyun uctl_ctl.s.ref_clk_sel = ref_clk_sel;
395*4882a593Smuzhiyun uctl_ctl.s.ref_clk_fsel = 0x07;
396*4882a593Smuzhiyun uctl_ctl.s.ref_clk_div2 = 0;
397*4882a593Smuzhiyun switch (clock_rate) {
398*4882a593Smuzhiyun default:
399*4882a593Smuzhiyun dev_err(dev, "Invalid ref_clk %u, using 100000000 instead\n",
400*4882a593Smuzhiyun clock_rate);
401*4882a593Smuzhiyun fallthrough;
402*4882a593Smuzhiyun case 100000000:
403*4882a593Smuzhiyun mpll_mul = 0x19;
404*4882a593Smuzhiyun if (ref_clk_sel < 2)
405*4882a593Smuzhiyun uctl_ctl.s.ref_clk_fsel = 0x27;
406*4882a593Smuzhiyun break;
407*4882a593Smuzhiyun case 50000000:
408*4882a593Smuzhiyun mpll_mul = 0x32;
409*4882a593Smuzhiyun break;
410*4882a593Smuzhiyun case 125000000:
411*4882a593Smuzhiyun mpll_mul = 0x28;
412*4882a593Smuzhiyun break;
413*4882a593Smuzhiyun }
414*4882a593Smuzhiyun uctl_ctl.s.mpll_multiplier = mpll_mul;
415*4882a593Smuzhiyun
416*4882a593Smuzhiyun /* Step 5b: Configure and enable spread-spectrum for SuperSpeed. */
417*4882a593Smuzhiyun uctl_ctl.s.ssc_en = 1;
418*4882a593Smuzhiyun
419*4882a593Smuzhiyun /* Step 5c: Enable SuperSpeed. */
420*4882a593Smuzhiyun uctl_ctl.s.ref_ssp_en = 1;
421*4882a593Smuzhiyun
422*4882a593Smuzhiyun /* Step 5d: Cofngiure PHYs. SKIP */
423*4882a593Smuzhiyun
424*4882a593Smuzhiyun /* Step 6a & 6b: Power up PHYs. */
425*4882a593Smuzhiyun uctl_ctl.s.hs_power_en = 1;
426*4882a593Smuzhiyun uctl_ctl.s.ss_power_en = 1;
427*4882a593Smuzhiyun cvmx_write_csr(uctl_ctl_reg, uctl_ctl.u64);
428*4882a593Smuzhiyun
429*4882a593Smuzhiyun /* Step 7: Wait 10 controller-clock cycles to take effect. */
430*4882a593Smuzhiyun udelay(10);
431*4882a593Smuzhiyun
432*4882a593Smuzhiyun /* Step 8a: Deassert UCTL reset signal. */
433*4882a593Smuzhiyun uctl_ctl.u64 = cvmx_read_csr(uctl_ctl_reg);
434*4882a593Smuzhiyun uctl_ctl.s.uctl_rst = 0;
435*4882a593Smuzhiyun cvmx_write_csr(uctl_ctl_reg, uctl_ctl.u64);
436*4882a593Smuzhiyun
437*4882a593Smuzhiyun /* Step 8b: Wait 10 controller-clock cycles. */
438*4882a593Smuzhiyun udelay(10);
439*4882a593Smuzhiyun
440*4882a593Smuzhiyun /* Steo 8c: Setup power-power control. */
441*4882a593Smuzhiyun if (dwc3_octeon_config_power(dev, base)) {
442*4882a593Smuzhiyun dev_err(dev, "Error configuring power.\n");
443*4882a593Smuzhiyun return -EINVAL;
444*4882a593Smuzhiyun }
445*4882a593Smuzhiyun
446*4882a593Smuzhiyun /* Step 8d: Deassert UAHC reset signal. */
447*4882a593Smuzhiyun uctl_ctl.u64 = cvmx_read_csr(uctl_ctl_reg);
448*4882a593Smuzhiyun uctl_ctl.s.uahc_rst = 0;
449*4882a593Smuzhiyun cvmx_write_csr(uctl_ctl_reg, uctl_ctl.u64);
450*4882a593Smuzhiyun
451*4882a593Smuzhiyun /* Step 8e: Wait 10 controller-clock cycles. */
452*4882a593Smuzhiyun udelay(10);
453*4882a593Smuzhiyun
454*4882a593Smuzhiyun /* Step 9: Enable conditional coprocessor clock of UCTL. */
455*4882a593Smuzhiyun uctl_ctl.u64 = cvmx_read_csr(uctl_ctl_reg);
456*4882a593Smuzhiyun uctl_ctl.s.csclk_en = 1;
457*4882a593Smuzhiyun cvmx_write_csr(uctl_ctl_reg, uctl_ctl.u64);
458*4882a593Smuzhiyun
459*4882a593Smuzhiyun /*Step 10: Set for host mode only. */
460*4882a593Smuzhiyun uctl_ctl.u64 = cvmx_read_csr(uctl_ctl_reg);
461*4882a593Smuzhiyun uctl_ctl.s.drd_mode = 0;
462*4882a593Smuzhiyun cvmx_write_csr(uctl_ctl_reg, uctl_ctl.u64);
463*4882a593Smuzhiyun
464*4882a593Smuzhiyun return 0;
465*4882a593Smuzhiyun }
466*4882a593Smuzhiyun
dwc3_octeon_set_endian_mode(u64 base)467*4882a593Smuzhiyun static void __init dwc3_octeon_set_endian_mode(u64 base)
468*4882a593Smuzhiyun {
469*4882a593Smuzhiyun #define UCTL_SHIM_CFG 0xe8
470*4882a593Smuzhiyun union cvm_usbdrd_uctl_shim_cfg shim_cfg;
471*4882a593Smuzhiyun
472*4882a593Smuzhiyun shim_cfg.u64 = cvmx_read_csr(base + UCTL_SHIM_CFG);
473*4882a593Smuzhiyun #ifdef __BIG_ENDIAN
474*4882a593Smuzhiyun shim_cfg.s.dma_endian_mode = 1;
475*4882a593Smuzhiyun shim_cfg.s.csr_endian_mode = 1;
476*4882a593Smuzhiyun #else
477*4882a593Smuzhiyun shim_cfg.s.dma_endian_mode = 0;
478*4882a593Smuzhiyun shim_cfg.s.csr_endian_mode = 0;
479*4882a593Smuzhiyun #endif
480*4882a593Smuzhiyun cvmx_write_csr(base + UCTL_SHIM_CFG, shim_cfg.u64);
481*4882a593Smuzhiyun }
482*4882a593Smuzhiyun
483*4882a593Smuzhiyun #define CVMX_USBDRDX_UCTL_CTL(index) \
484*4882a593Smuzhiyun (CVMX_ADD_IO_SEG(0x0001180068000000ull) + \
485*4882a593Smuzhiyun ((index & 1) * 0x1000000ull))
dwc3_octeon_phy_reset(u64 base)486*4882a593Smuzhiyun static void __init dwc3_octeon_phy_reset(u64 base)
487*4882a593Smuzhiyun {
488*4882a593Smuzhiyun union cvm_usbdrd_uctl_ctl uctl_ctl;
489*4882a593Smuzhiyun int index = (base >> 24) & 1;
490*4882a593Smuzhiyun
491*4882a593Smuzhiyun uctl_ctl.u64 = cvmx_read_csr(CVMX_USBDRDX_UCTL_CTL(index));
492*4882a593Smuzhiyun uctl_ctl.s.uphy_rst = 0;
493*4882a593Smuzhiyun cvmx_write_csr(CVMX_USBDRDX_UCTL_CTL(index), uctl_ctl.u64);
494*4882a593Smuzhiyun }
495*4882a593Smuzhiyun
dwc3_octeon_device_init(void)496*4882a593Smuzhiyun static int __init dwc3_octeon_device_init(void)
497*4882a593Smuzhiyun {
498*4882a593Smuzhiyun const char compat_node_name[] = "cavium,octeon-7130-usb-uctl";
499*4882a593Smuzhiyun struct platform_device *pdev;
500*4882a593Smuzhiyun struct device_node *node;
501*4882a593Smuzhiyun struct resource *res;
502*4882a593Smuzhiyun void __iomem *base;
503*4882a593Smuzhiyun
504*4882a593Smuzhiyun /*
505*4882a593Smuzhiyun * There should only be three universal controllers, "uctl"
506*4882a593Smuzhiyun * in the device tree. Two USB and a SATA, which we ignore.
507*4882a593Smuzhiyun */
508*4882a593Smuzhiyun node = NULL;
509*4882a593Smuzhiyun do {
510*4882a593Smuzhiyun node = of_find_node_by_name(node, "uctl");
511*4882a593Smuzhiyun if (!node)
512*4882a593Smuzhiyun return -ENODEV;
513*4882a593Smuzhiyun
514*4882a593Smuzhiyun if (of_device_is_compatible(node, compat_node_name)) {
515*4882a593Smuzhiyun pdev = of_find_device_by_node(node);
516*4882a593Smuzhiyun if (!pdev)
517*4882a593Smuzhiyun return -ENODEV;
518*4882a593Smuzhiyun
519*4882a593Smuzhiyun res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
520*4882a593Smuzhiyun if (res == NULL) {
521*4882a593Smuzhiyun put_device(&pdev->dev);
522*4882a593Smuzhiyun dev_err(&pdev->dev, "No memory resources\n");
523*4882a593Smuzhiyun return -ENXIO;
524*4882a593Smuzhiyun }
525*4882a593Smuzhiyun
526*4882a593Smuzhiyun /*
527*4882a593Smuzhiyun * The code below maps in the registers necessary for
528*4882a593Smuzhiyun * setting up the clocks and reseting PHYs. We must
529*4882a593Smuzhiyun * release the resources so the dwc3 subsystem doesn't
530*4882a593Smuzhiyun * know the difference.
531*4882a593Smuzhiyun */
532*4882a593Smuzhiyun base = devm_ioremap_resource(&pdev->dev, res);
533*4882a593Smuzhiyun if (IS_ERR(base)) {
534*4882a593Smuzhiyun put_device(&pdev->dev);
535*4882a593Smuzhiyun return PTR_ERR(base);
536*4882a593Smuzhiyun }
537*4882a593Smuzhiyun
538*4882a593Smuzhiyun mutex_lock(&dwc3_octeon_clocks_mutex);
539*4882a593Smuzhiyun dwc3_octeon_clocks_start(&pdev->dev, (u64)base);
540*4882a593Smuzhiyun dwc3_octeon_set_endian_mode((u64)base);
541*4882a593Smuzhiyun dwc3_octeon_phy_reset((u64)base);
542*4882a593Smuzhiyun dev_info(&pdev->dev, "clocks initialized.\n");
543*4882a593Smuzhiyun mutex_unlock(&dwc3_octeon_clocks_mutex);
544*4882a593Smuzhiyun devm_iounmap(&pdev->dev, base);
545*4882a593Smuzhiyun devm_release_mem_region(&pdev->dev, res->start,
546*4882a593Smuzhiyun resource_size(res));
547*4882a593Smuzhiyun put_device(&pdev->dev);
548*4882a593Smuzhiyun }
549*4882a593Smuzhiyun } while (node != NULL);
550*4882a593Smuzhiyun
551*4882a593Smuzhiyun return 0;
552*4882a593Smuzhiyun }
553*4882a593Smuzhiyun device_initcall(dwc3_octeon_device_init);
554*4882a593Smuzhiyun
555*4882a593Smuzhiyun MODULE_AUTHOR("David Daney <david.daney@cavium.com>");
556*4882a593Smuzhiyun MODULE_LICENSE("GPL");
557*4882a593Smuzhiyun MODULE_DESCRIPTION("USB driver for OCTEON III SoC");
558