62c3a51f7cbd813adc6ceac3657a95466a91aad2
[open-ath9k-htc-firmware.git] / target_firmware / magpie_fw_dev / target / hif / usb_api_k2_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 #include "usb_defs.h"
36 #include "usb_type.h"
37 #include "usb_pre.h"
38 #include "usb_extr.h"
39 #include "usb_std.h"
40 #include "reg_defs.h"
41 #include "athos_api.h"
42 #include "usbfifo_api.h"
43
44
45 #include "sys_cfg.h"
46
47 void _fw_usb_suspend_reboot();
48
49 extern Action      eUsbCxFinishAction;
50 extern CommandType eUsbCxCommand;
51 extern BOOLEAN     UsbChirpFinish;
52 extern USB_FIFO_CONFIG usbFifoConf;
53
54 #if SYSTEM_MODULE_USB
55 #define vUsb_ep0end(void)                                   \
56 {                                                           \
57     eUsbCxCommand = CMD_VOID;                               \
58     USB_BYTE_REG_WRITE(ZM_CX_CONFIG_STATUS_OFFSET, 0x01);   \
59 }
60
61 #define vUsb_ep0fail(void)  USB_BYTE_REG_WRITE(ZM_CX_CONFIG_STATUS_OFFSET, 0x04)
62
63 #define vUsb_rst()                                              \
64 {                                                               \
65     USB_BYTE_REG_WRITE(ZM_INTR_SOURCE_7_OFFSET,                 \
66         (USB_BYTE_REG_READ(ZM_INTR_SOURCE_7_OFFSET)&~BIT1));    \
67     UsbChirpFinish = FALSE;                                     \
68 }
69
70 #define vUsb_suspend()  USB_BYTE_REG_WRITE(ZM_INTR_SOURCE_7_OFFSET, \
71                             (USB_BYTE_REG_READ(ZM_INTR_SOURCE_7_OFFSET)&~BIT2))
72
73 #define vUsb_resm() USB_BYTE_REG_WRITE(ZM_INTR_SOURCE_7_OFFSET,     \
74                         (USB_BYTE_REG_READ(ZM_INTR_SOURCE_7_OFFSET)&~BIT3))
75
76 #define CHECK_SOF_LOOP_CNT    50
77
78 void _fw_usb_suspend_reboot()
79 {
80         volatile uint32_t gpio_in = 0;
81         volatile uint32_t pupd = 0;
82         volatile uint32_t t = 0;
83         volatile uint32_t sof_no=0,sof_no_new=0;
84         /* Set GO_TO_SUSPEND bit to USB main control register */
85         vUsb_suspend();
86         A_PRINTF("!USB suspend\n\r");
87
88         /* keep the record of suspend */
89 #if defined(PROJECT_MAGPIE)
90         *((volatile uint32_t*)WATCH_DOG_MAGIC_PATTERN_ADDR) = SUS_MAGIC_PATTERN;
91 #elif defined(PROJECT_K2)
92         HAL_WORD_REG_WRITE(MAGPIE_REG_RST_STATUS_ADDR, SUS_MAGIC_PATTERN);
93 #endif /* #if defined(PROJECT_MAGPIE) */
94
95         /* Reset USB FIFO */
96         A_USB_RESET_FIFO();
97
98         /* Turn off power */
99         A_USB_POWER_OFF();
100
101         DEBUG_SYSTEM_STATE = (DEBUG_SYSTEM_STATE&(~0xffff)) | 0x1000;
102
103         /* reset ep3/ep4 fifo in case there
104          * is data which might affect resuming */
105 //  HAL_BYTE_REG_WRITE(0x100ae, (HAL_BYTE_REG_READ(0x100ae)|0x10));
106 //  HAL_BYTE_REG_WRITE(0x100ae, (HAL_BYTE_REG_READ(0x100af)|0x10));
107
108         {
109                 /* config gpio to input before goto suspend */
110
111                 /* disable JTAG/ICE */
112                 //jtag = HAL_WORD_REG_READ(0x10004054);
113                 //HAL_WORD_REG_WRITE(0x10004054, (jtag|BIT17));
114
115                 /* disable SPI */
116                 //spi = HAL_WORD_REG_READ(0x50040);
117                 //HAL_WORD_REG_WRITE(0x50040, (spi&~(BIT8)));
118
119                 /* set all GPIO to input */
120                 gpio_in = HAL_WORD_REG_READ(0x1000404c);
121                 HAL_WORD_REG_WRITE(0x1000404c, 0x0);
122
123                 /* set PU/PD for all GPIO except two UART pins */
124                 pupd = HAL_WORD_REG_READ(0x10004088);
125                 HAL_WORD_REG_WRITE(0x10004088, 0xA982AA6A);
126         }
127
128         sof_no= HAL_WORD_REG_READ(0x10004); 
129         for (t = 0; t < CHECK_SOF_LOOP_CNT; t++)
130         {
131                 A_DELAY_USECS(1000);    /* delay 1ms */
132                 sof_no_new = HAL_WORD_REG_READ(0x10004);
133
134                 if(sof_no_new == sof_no)
135                         break;
136                 sof_no = sof_no_new;
137         }
138
139         /*
140          * Reset "printf" module patch point(RAM to ROM)
141          * when K2 warm start or suspend,
142          * which fixed the error issue cause by redownload
143          * another different firmware.
144          */
145         _indir_tbl.cmnos.printf._printf = save_cmnos_printf;
146
147         /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
148          * setting the go suspend here, power down right away!!!
149          */
150         if (t != CHECK_SOF_LOOP_CNT)   /* not time out */
151                 HAL_WORD_REG_WRITE(0x10000, HAL_WORD_REG_READ(0x10000)|(0x8));
152
153         DEBUG_SYSTEM_STATE = (DEBUG_SYSTEM_STATE&(~0xffff)) | 0x1100;
154
155 #if 0 /* pll unstable, h/w bug? */
156         HAL_WORD_REG_WRITE(0x50040, (0x300|6|(1>>1)<<12));
157         A_UART_HWINIT((40*1000*1000)/1, 19200);
158 #endif
159         /* restore gpio setting */
160         //HAL_WORD_REG_WRITE(0x10004054, jtag);
161         //HAL_WORD_REG_WRITE(0x50040, spi);
162         HAL_WORD_REG_WRITE(0x1000404c, gpio_in);
163         HAL_WORD_REG_WRITE(0x10004088, pupd);
164
165         DEBUG_SYSTEM_STATE = (DEBUG_SYSTEM_STATE&(~0xffff)) | 0x1200;
166
167         /* since we still need to touch mac_base address after resuming back,
168          * so that reset mac can't be done in ResetFifo function,
169          * move to here... whole mac control reset.... (bit1)
170          */
171         HAL_WORD_REG_WRITE(MAGPIE_REG_RST_PWDN_CTRL_ADDR, (BIT1));
172         HAL_WORD_REG_WRITE(MAGPIE_REG_RST_PWDN_CTRL_ADDR,
173                 (HAL_WORD_REG_READ(MAGPIE_REG_RST_PWDN_CTRL_ADDR)|BIT0));
174         HAL_WORD_REG_WRITE(MAGPIE_REG_RST_PWDN_CTRL_ADDR, 0x0);
175         A_DELAY_USECS(1000);
176
177         //A_PRINTF("reg(0x10020)=(%x)\n", HAL_WORD_REG_READ(0x10020));
178         /* disable ep3 int enable, so that resume back won't
179          * send wdt magic pattern out!!! */
180         mUSB_STATUS_IN_INT_DISABLE();
181
182         MAGPIE_REG_USB_RX0_SWAP_DATA = 0x1;
183         MAGPIE_REG_USB_TX0_SWAP_DATA = 0x1;
184         MAGPIE_REG_USB_RX1_SWAP_DATA = 0x1;
185         MAGPIE_REG_USB_RX2_SWAP_DATA = 0x1;
186
187         if (((DEBUG_SYSTEM_STATE&~(0x0000ffff))>>16 == 0x5342)) {
188                 /* UART_SEL and SPI_SEL */
189                 HAL_WORD_REG_WRITE(0x50040, (0x300|0|(1>>1)<<12));
190         }
191
192         /* Jump to boot code */
193         A_USB_JUMP_BOOT();
194 }
195
196 /*
197  * patch usb_fw_task
198  * usb zero length interrupt should not clear by s/w, h/w will handle that
199  * complete suspend handle, configure gpio, turn off related function,
200  * slow down the pll for stable issue
201  */
202 void _fw_usb_fw_task(void)
203 {
204         register uint8_t usb_interrupt_level1;
205         register uint8_t usb_interrupt_level2;
206
207         usb_interrupt_level1 = USB_BYTE_REG_READ(ZM_INTR_GROUP_OFFSET);
208 #if 0 /* these endpoints are handled by DMA */
209         if (usb_interrupt_level1 & BIT5)
210         {
211                 vUsb_Data_In();
212         }
213 #endif
214         if (usb_interrupt_level1 & BIT4) {
215                 usb_interrupt_level2 =
216                         USB_BYTE_REG_READ(ZM_INTR_SOURCE_4_OFFSET);
217
218                 if(usb_interrupt_level2 & BIT6)
219                         A_USB_REG_OUT(); /* vUsb_Reg_Out() */
220         }
221
222         if (usb_interrupt_level1 & BIT6) {
223                 /* zfGenWatchDogEvent(); ?? */
224                 usb_interrupt_level2 =
225                         USB_BYTE_REG_READ(ZM_INTR_SOURCE_6_OFFSET);
226                 if(usb_interrupt_level2 & BIT6)
227                         A_USB_STATUS_IN(); /* vUsb_Status_In() */
228         }
229
230         if (usb_interrupt_level1 & BIT0) {
231                 usb_interrupt_level2 =
232                         USB_BYTE_REG_READ(ZM_INTR_SOURCE_0_OFFSET);
233
234                 /* refer to FUSB200, p 48, offset:21H, bit7 description,
235                  * should clear the command abort interrupt first!?
236                  */
237                 if (usb_interrupt_level2 & BIT7) {
238                         /* Handle command abort */
239                         USB_BYTE_REG_WRITE(ZM_INTR_SOURCE_0_OFFSET,
240                                 (USB_BYTE_REG_READ(ZM_INTR_SOURCE_0_OFFSET)
241                                  & ~BIT7));
242                         A_PRINTF("![SOURCE_0] bit7 on\n\r");
243                 }
244
245                 if (usb_interrupt_level2 & BIT1)
246                         A_USB_EP0_TX(); /* USB EP0 tx interrupt */
247
248                 if (usb_interrupt_level2 & BIT2)
249                         A_USB_EP0_RX(); /* USB EP0 rx interrupt */
250
251                 if (usb_interrupt_level2 & BIT0) {
252                         A_USB_EP0_SETUP();
253                         /* vWriteUSBFakeData() */
254                 }
255
256                 if (usb_interrupt_level2 & BIT3)
257                         vUsb_ep0end();
258
259                 if (usb_interrupt_level2 & BIT4)
260                         vUsb_ep0fail();
261
262                 if (eUsbCxFinishAction == ACT_STALL) {
263                         /* set CX_STL to stall Endpoint0 &
264                          * will also clear FIFO0 */
265                         USB_BYTE_REG_WRITE(ZM_CX_CONFIG_STATUS_OFFSET, 0x04);
266                 } else if (eUsbCxFinishAction == ACT_DONE) {
267                         /* set CX_DONE to indicate the transmistion
268                          * of control frame */
269                         USB_BYTE_REG_WRITE(ZM_CX_CONFIG_STATUS_OFFSET, 0x01);
270                 }
271                 eUsbCxFinishAction = ACT_IDLE;
272         }
273
274         if (usb_interrupt_level1 & BIT7) {
275                 usb_interrupt_level2 =
276                         USB_BYTE_REG_READ(ZM_INTR_SOURCE_7_OFFSET);
277
278 #if 0
279         if (usb_interrupt_level2 & BIT7)
280                 vUsb_Data_Out0Byte();
281
282         if (usb_interrupt_level2 & BIT6)
283                 vUsb_Data_In0Byte();
284 #endif
285
286                 if (usb_interrupt_level2 & BIT1) {
287                         vUsb_rst();
288                         A_PRINTF("!USB reset\n\r");
289 //                      A_PRINTF("![0x1012c]: %\n\r", USB_WORD_REG_READ(0x12c));
290                 }
291                 if (usb_interrupt_level2 & BIT2) {
292                         /* TBD: the suspend resume code should put here,
293                          * Ryan, 07/18
294                          * issue, jump back to rom code and what peripherals
295                          * should we reset here? */
296                         _fw_usb_suspend_reboot();
297                 }
298                 if (usb_interrupt_level2 & BIT3) {
299                         vUsb_resm();
300                         A_PRINTF("!USB resume\n\r");
301                 }
302         }
303 }
304
305
306 void _fw_usb_reset_fifo(void)
307 {
308         volatile uint32_t   *reg_data;
309
310         HAL_BYTE_REG_WRITE(0x100ae, (HAL_BYTE_REG_READ(0x100ae)|0x10));
311         HAL_BYTE_REG_WRITE(0x100af, (HAL_BYTE_REG_READ(0x100af)|0x10));
312
313         /* disable ep3 int enable, so that resume back won't
314          * send wdt magic pattern out!!!
315          */
316         mUSB_STATUS_IN_INT_DISABLE();
317
318         /* update magic pattern to indicate this is a suspend
319          * k2: MAGPIE_REG_RST_WDT_TIMER_CTRL_ADDR
320          * magpie: MAGPIE_REG_RST_STATUS_ADDR
321          */
322         HAL_WORD_REG_WRITE(MAGPIE_REG_RST_STATUS_ADDR, SUS_MAGIC_PATTERN);
323
324         /*
325          * Before USB suspend, USB DMA must be reset(refer to Otus)
326          * Otus runs the following statements only
327          * HAL_WORD_REG_WRITE( MAGPIE_REG_RST_PWDN_CTRL_ADDR, BIT0|BIT2 );
328          * HAL_WORD_REG_WRITE( MAGPIE_REG_RST_PWDN_CTRL_ADDR, 0x0 );
329          * K2 must run the following statements additionally
330          * reg_data = (A_UINT32 *)(USB_CTRL_BASE_ADDRESS + 0x118);
331          * *reg_data = 0x00000000;
332          * *reg_data = 0x00000001;
333          * because of Hardware bug in K2
334          */
335         USB_WORD_REG_WRITE(ZM_SOC_USB_DMA_RESET_OFFSET, 0x0);
336
337         /* reset both usb(bit2)/wlan(bit1) dma */
338         HAL_WORD_REG_WRITE(MAGPIE_REG_RST_PWDN_CTRL_ADDR, (BIT2));
339         HAL_WORD_REG_WRITE(MAGPIE_REG_RST_PWDN_CTRL_ADDR,
340                         (HAL_WORD_REG_READ(MAGPIE_REG_RST_PWDN_CTRL_ADDR)|BIT0));
341         HAL_WORD_REG_WRITE(MAGPIE_REG_RST_PWDN_CTRL_ADDR, 0x0);
342
343         USB_WORD_REG_WRITE(ZM_SOC_USB_DMA_RESET_OFFSET, BIT0);
344
345         /* MAC warem reset */
346         //reg_data = (uint32_t *)(K2_REG_MAC_BASE_ADDR + 0x7000);
347         //*reg_data = 0x00000001;
348
349         //A_DELAY_USECS(1);
350
351         //*reg_data = 0x00000000;
352
353         //while (*reg_data)   ;
354
355         A_PRINTF("\n change clock to 22 and go to suspend now!");
356
357         /* UART_SEL */
358         HAL_WORD_REG_WRITE(0x50040, (0x200|0|(1>>1)<<12));
359         A_UART_HWINIT((22*1000*1000), 19200);
360 }
361 #endif