ath9k_htc: Update to upstream's commit d19607454d656cb14d8c16dfbf161eebb542e8fe dated...
[linux-libre-firmware.git] / ath9k_htc / target_firmware / magpie_fw_dev / target / hif / usb_api_magpie_patch.c
1 /*
2  * Copyright (c) 2013 Qualcomm Atheros, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted (subject to the limitations in the
7  * disclaimer below) provided that the following conditions are met:
8  *
9  *  * Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  *  * Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the
15  *    distribution.
16  *
17  *  * Neither the name of Qualcomm Atheros nor the names of its
18  *    contributors may be used to endorse or promote products derived
19  *    from this software without specific prior written permission.
20  *
21  * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
22  * GRANTED BY THIS LICENSE.  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
23  * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
24  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
30  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
31  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
32  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
33  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35
36 #include <init/app_start.h>
37
38 #include "usb_defs.h"
39 #include "usb_type.h"
40 #include "usb_pre.h"
41 #include "usb_extr.h"
42 #include "usb_std.h"
43 #include "reg_defs.h"
44 #include "athos_api.h"
45 #include "usbfifo_api.h"
46 #include "adf_os_io.h"
47 #include "sys_cfg.h"
48
49 #define measure_time 0
50 #define measure_time_pll 10000000
51
52 extern Action eUsbCxFinishAction;
53 extern CommandType eUsbCxCommand;
54 extern BOOLEAN UsbChirpFinish;
55 extern USB_FIFO_CONFIG usbFifoConf;
56 extern uint16_t *pu8DescriptorEX;
57 extern uint16_t u16TxRxCounter;
58
59 void zfTurnOffPower_patch(void);
60
61 static void _fw_reset_dma_fifo();
62 static void _fw_restore_dma_fifo();
63 static void _fw_power_on();
64 static void _fw_power_off();
65
66 BOOLEAN bEepromExist = TRUE;
67 BOOLEAN bJumptoFlash = FALSE;
68
69 void _fw_usb_suspend_reboot()
70 {
71         /* reset usb/wlan dma */
72         _fw_reset_dma_fifo();
73
74         /* restore gpio setting and usb/wlan dma state */
75         _fw_restore_dma_fifo();
76
77         /* set clock to bypass mode - 40Mhz from XTAL */
78         iowrite32(MAGPIE_REG_CPU_PLL_BYPASS_ADDR, BIT0 | BIT4);
79
80         A_DELAY_USECS(100); /* wait for stable */
81
82         iowrite32(MAGPIE_REG_CPU_PLL_ADDR, BIT16);
83
84         A_DELAY_USECS(100); /* wait for stable */
85         A_UART_HWINIT((40*1000*1000), 19200);
86
87         A_CLOCK_INIT(40);
88
89         if (!bEepromExist) { /* jump to flash boot (eeprom data in flash) */
90                 bJumptoFlash = TRUE;
91                 A_PRINTF("Jump to Flash BOOT\n");
92                 app_start();
93         } else {
94                 A_PRINTF("receive the suspend command...\n");
95                 /* reboot..... */
96                 A_USB_JUMP_BOOT();
97         }
98
99 }
100
101 #define PCI_RC_RESET_BIT                            BIT6
102 #define PCI_RC_PHY_RESET_BIT                        BIT7
103 #define PCI_RC_PLL_RESET_BIT                        BIT8
104 #define PCI_RC_PHY_SHIFT_RESET_BIT                  BIT10
105
106 /*
107  * -- urn_off_merlin --
108  * . values suggested from Lalit
109  *
110  */
111 static void turn_off_merlin()
112 {
113         volatile uint32_t default_data[9];
114         uint32_t i=0;
115
116         if(1)
117         {
118                 A_PRINTF("turn_off_merlin_ep_start ......\n");
119                 A_DELAY_USECS(measure_time);
120                 default_data[0] = 0x9248fd00;
121                 default_data[1] = 0x24924924;
122                 default_data[2] = 0xa8000019;
123                 default_data[3] = 0x17160820;
124                 default_data[4] = 0x25980560;
125                 default_data[5] = 0xc1c00000;
126                 default_data[6] = 0x1aaabe40;
127                 default_data[7] = 0xbe105554;
128                 default_data[8] = 0x00043007;
129
130                 for(i=0; i<9; i++)
131                 {
132                         A_DELAY_USECS(10);
133
134                         iowrite32(0x10ff4040, default_data[i]);
135                 }
136                 A_DELAY_USECS(10);
137                 iowrite32(0x10ff4044, BIT0);
138                 A_PRINTF("turn_off_merlin_ep_end ......\n");
139         }
140 }
141
142 /*
143  * -- turn_off_phy --
144  *
145  * . write shift register to both pcie ep and rc
146  * .
147  */
148
149 static void turn_off_phy()
150 {
151
152         volatile uint32_t default_data[9];
153         uint32_t i=0;
154
155         default_data[0] = 0x9248fd00;
156         default_data[1] = 0x24924924;
157         default_data[2] = 0xa8000019;
158         default_data[3] = 0x17160820;
159         default_data[4] = 0x25980560;
160         default_data[5] = 0xc1c00000;
161         default_data[6] = 0x1aaabe40;
162         default_data[7] = 0xbe105554;
163         default_data[8] = 0x00043007;
164
165         for(i=0; i<9; i++)
166         {
167                 // check for the done bit to be set
168
169                 while (1)
170                 {
171                         if (ioread32(0x40028) & BIT31)
172                                 break;
173                 }
174
175                 A_DELAY_USECS(1);
176
177                 iowrite32(0x40024, default_data[i]);
178         }
179         iowrite32(0x40028, BIT0);
180 }
181
182 static void turn_off_phy_rc()
183 {
184
185         volatile uint32_t default_data[9];
186         uint32_t i=0;
187
188         A_PRINTF("turn_off_phy_rc\n");
189
190         default_data[0] = 0x9248fd00;
191         default_data[1] = 0x24924924;
192         default_data[2] = 0xa8000019;
193         default_data[3] = 0x13160820;//PwdClk1MHz=0
194         default_data[4] = 0x25980560;
195         default_data[5] = 0xc1c00000;
196         default_data[6] = 0x1aaabe40;
197         default_data[7] = 0xbe105554;
198         default_data[8] = 0x00043007;
199
200         for(i=0; i<9; i++)
201         {
202                 // check for the done bit to be set
203
204                 while (1)
205                 {
206                         if (ioread32(0x40028) & BIT31)
207                                 break;
208                 }
209
210                 A_DELAY_USECS(1);
211
212                 iowrite32(0x40024, default_data[i]);
213         }
214         iowrite32(0x40028, BIT0);
215 }
216
217 volatile uint32_t gpio_func = 0x0;
218 volatile uint32_t gpio = 0x0;
219
220 /*
221  * -- patch zfTurnOffPower --
222  *
223  * . set suspend counter to non-zero value
224  * .
225  */
226 void zfTurnOffPower_patch(void)
227 {
228         A_PRINTF("+++ goto suspend ......\n");
229
230         /* setting the go suspend here, power down right away */
231         io32_set(0x10000, BIT3);
232
233         A_DELAY_USECS(100);
234
235         // TURN OFF ETH PLL
236         _fw_power_off();
237
238         //32clk wait for External ETH PLL stable
239         A_DELAY_USECS(100);
240
241         iowrite32(0x52000, 0x70303); /* read back 0x703f7 */
242         iowrite32(0x52008, 0x0e91c); /* read back 0x1e948 */
243
244         io32_set(MAGPIE_REG_SUSPEND_ENABLE_ADDR, BIT0);
245
246         // wake up, and turn on cpu, eth, pcie and usb pll
247         _fw_power_on();
248         // restore gpio and other settings
249         _fw_restore_dma_fifo();
250
251         /* clear suspend */
252         io32_clr(MAGPIE_REG_SUSPEND_ENABLE_ADDR, BIT0);
253         io32_clr(0x52028, BIT8 | BIT12 | BIT16);
254 }
255
256 /*
257  * -- patch zfResetUSBFIFO_patch --
258  *
259  * . clear ep3/ep4 fifo
260  * . set suspend magic pattern
261  * . reset pcie ep phy
262  * . reset pcie rc phy
263  * . turn off pcie pll
264  * . reset all pcie/gmac related registers
265  * . reset usb dma
266  */
267 void zfResetUSBFIFO_patch(void)
268 {
269         A_PRINTF("0x9808  0x%x ......\n", ioread32(0x10ff9808));
270         A_PRINTF("0x7890  0x%x ......\n", ioread32(0x10ff7890));
271         A_PRINTF("0x7890  0x%x ......\n", ioread32(0x10ff7890));
272         A_PRINTF("0x4088  0x%x ......\n", ioread32(0x10ff4088));
273         _fw_reset_dma_fifo();
274 }
275
276 static void _fw_reset_dma_fifo()
277 {
278         io8_set(0x100ae, 0x10);
279         io8_set(0x100af, 0x10);
280         A_PRINTF("_fw_reset_dma_fifo\n");
281
282         // disable ep3 int enable, so that resume back won't send wdt magic pattern out!!!
283         mUSB_STATUS_IN_INT_DISABLE();
284
285         /* update magic pattern to indicate this is a suspend */
286         iowrite32(WATCH_DOG_MAGIC_PATTERN_ADDR, SUS_MAGIC_PATTERN);
287
288         A_PRINTF("org 0x4048  0x%x ......\n", ioread32(0x10ff4048));
289         A_PRINTF("org 0x404C  0x%x ......\n", ioread32(0x10ff404C));
290         A_PRINTF("org 0x4088  0x%x ......\n", ioread32(0x10ff4088));
291
292         /* 1010.1010.1010.0110.1010 for UB94 */
293         iowrite32(0x10ff4088, 0xaaa6a);
294         iowrite32(0x10ff404C, 0x0);
295
296         A_DELAY_USECS(1000);
297         A_PRINTF("0x4048  0x%x ......\n", ioread32(0x10ff4048));
298         A_PRINTF("0x404C  0x%x ......\n", ioread32(0x10ff404C));
299         A_PRINTF("0x4088  0x%x ......\n", ioread32(0x10ff4088));
300
301         // turn off merlin
302         turn_off_merlin();
303         // pcie ep
304         A_PRINTF("turn_off_magpie_ep_start ......\n");
305         A_DELAY_USECS(measure_time);
306         io32_set(0x40040, BIT0 | BIT1);
307         turn_off_phy();
308         io32_clr(0x40040, BIT0 | BIT1);
309         A_PRINTF("turn_off_magpie_ep_end ......\n");
310
311         // pcie rc
312         A_PRINTF("turn_off_magpie_rc_start ......\n");
313         A_DELAY_USECS(measure_time);
314         io32_clr(0x40040, BIT0);
315         turn_off_phy_rc();
316         A_PRINTF("turn_off_magpie_rc_end ......down\n");
317         A_DELAY_USECS(measure_time);
318
319         A_PRINTF("0x4001C  %p ......\n", ioread32(0x4001c));
320         A_PRINTF("0x40040  %p ......\n", ioread32(0x40040));
321
322         /* turn off pcie_pll - power down (bit16) */
323         A_PRINTF(" before pwd PCIE PLL CFG:0x5601C: 0x%08x\n",
324                  ioread32(0x5601C));
325         io32_set(0x5601C, BIT18);
326         A_PRINTF(" after pwd PCIE PLL CFG:0x5601C:  0x%08x\n",
327                  ioread32(0x5601C));
328
329         /* set everything to reset state?, requested by Oligo */
330         io32_set(0x50010, BIT13 | BIT12
331                  | BIT11 | BIT9 | BIT7 | BIT6);
332
333         iowrite32(0x5C000, 0);
334
335         A_DELAY_USECS(10);
336
337         /* reset usb DMA controller */
338         iowrite32_usb(ZM_SOC_USB_DMA_RESET_OFFSET, 0x0);
339
340         io32_set(0x50010, BIT4);
341         A_DELAY_USECS(5);
342         io32_clr(0x50010, BIT4);
343
344         iowrite32_usb(ZM_SOC_USB_DMA_RESET_OFFSET, BIT0);
345 }
346
347 static void _fw_power_off()
348 {
349         /*
350          *  1. set CPU bypass
351          *  2. turn off CPU PLL
352          *  3. turn off ETH PLL
353          *  4. disable ETH PLL bypass and update
354          *  4.1 set suspend timeout
355          *  5. set SUSPEND_ENABLE
356          */
357
358         iowrite32(MAGPIE_REG_CPU_PLL_BYPASS_ADDR, BIT0 | BIT4);
359
360         A_DELAY_USECS(100); // wait for stable
361
362         iowrite32(MAGPIE_REG_CPU_PLL_ADDR, BIT16);
363
364         A_DELAY_USECS(100); // wait for stable
365
366         A_UART_HWINIT((40*1000*1000), 19200);
367         A_CLOCK_INIT(40);
368
369         io32_set(MAGPIE_REG_ETH_PLL_ADDR, BIT16);
370
371         io32_set(MAGPIE_REG_ETH_PLL_BYPASS_ADDR, BIT4 | BIT0);
372
373         io32_set(MAGPIE_REG_SUSPEND_ENABLE_ADDR, 0x10 << 8);
374 }
375
376 static void _fw_power_on()
377 {
378     /*
379      *  1. turn on CPU PLL
380      *  2. disable CPU bypass
381      *  3. turn on ETH PLL
382      *  4. disable ETH PLL bypass and update
383      *  5. turn on pcie pll
384      */
385
386         io32_clr(MAGPIE_REG_ETH_PLL_ADDR, BIT16);
387
388         /* deassert eth_pll bypass mode and trigger update bit */
389         io32_clr(MAGPIE_REG_ETH_PLL_BYPASS_ADDR, BIT4 | BIT0);
390 }
391
392 static void _fw_restore_dma_fifo(void)
393 {
394         io32_clr(0x5601C, BIT18);
395
396         /* reset pcie_rc shift */
397         io32_clr(0x50010, BIT10 | BIT8 | BIT7);
398         A_DELAY_USECS(1);
399         io32_set(0x50010, BIT10 | BIT8 | BIT7);
400
401         /* reset pci_rc phy */
402         io32_set(MAGPIE_REG_RST_RESET_ADDR,
403                  PCI_RC_PHY_SHIFT_RESET_BIT
404                  | PCI_RC_PLL_RESET_BIT | PCI_RC_PHY_RESET_BIT
405                  | PCI_RC_RESET_BIT);
406         A_DELAY_USECS(20);
407
408         // enable dma swap function
409         MAGPIE_REG_USB_RX0_SWAP_DATA = 0x1;
410         MAGPIE_REG_USB_TX0_SWAP_DATA = 0x1;
411         MAGPIE_REG_USB_RX1_SWAP_DATA = 0x1;
412         MAGPIE_REG_USB_RX2_SWAP_DATA = 0x1;
413 }