hif/usb_api: unify platform specific patch file names
[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 is data which might affect resuming
104 //  HAL_BYTE_REG_WRITE(0x100ae, (HAL_BYTE_REG_READ(0x100ae)|0x10));
105 //  HAL_BYTE_REG_WRITE(0x100ae, (HAL_BYTE_REG_READ(0x100af)|0x10));
106
107     {
108         // config gpio to input before goto suspend
109
110         //disable JTAG/ICE
111         //jtag = HAL_WORD_REG_READ(0x10004054);
112         //HAL_WORD_REG_WRITE(0x10004054, (jtag|BIT17));
113                 
114                 //disable SPI
115         //spi = HAL_WORD_REG_READ(0x50040);
116         //HAL_WORD_REG_WRITE(0x50040, (spi&~(BIT8)));
117                 
118                 //set all GPIO to input
119         gpio_in = HAL_WORD_REG_READ(0x1000404c);
120         HAL_WORD_REG_WRITE(0x1000404c, 0x0);
121                 
122                 //set PU/PD for all GPIO except two UART pins
123         pupd = HAL_WORD_REG_READ(0x10004088);
124         HAL_WORD_REG_WRITE(0x10004088, 0xA982AA6A);
125     }
126
127     sof_no= HAL_WORD_REG_READ(0x10004); 
128     for (t = 0; t < CHECK_SOF_LOOP_CNT; t++)
129     {
130         A_DELAY_USECS(1000);    //delay 1ms     
131         sof_no_new = HAL_WORD_REG_READ(0x10004);
132
133         if(sof_no_new == sof_no)
134             break; 
135
136         sof_no = sof_no_new;      
137     } 
138     
139     /* 
140      * Reset "printf" module patch point(RAM to ROM) when K2 warm start or suspend,  
141      * which fixed the error issue cause by redownload another different firmware. 
142      */
143     _indir_tbl.cmnos.printf._printf = save_cmnos_printf;
144     
145     ///////////////////////////////////////////////////////////////
146     // setting the go suspend here, power down right away...
147     if (t != CHECK_SOF_LOOP_CNT)   // not time out
148         HAL_WORD_REG_WRITE(0x10000, HAL_WORD_REG_READ(0x10000)|(0x8));
149     ///////////////////////////////////////////////////////////////
150
151     DEBUG_SYSTEM_STATE = (DEBUG_SYSTEM_STATE&(~0xffff)) | 0x1100;
152
153 #if 0 // pll unstable, h/w bug?
154     HAL_WORD_REG_WRITE(0x50040, (0x300|6|(1>>1)<<12));
155     A_UART_HWINIT((40*1000*1000)/1, 19200);
156 #endif
157     {
158         // restore gpio setting
159         //HAL_WORD_REG_WRITE(0x10004054, jtag);
160         //HAL_WORD_REG_WRITE(0x50040, spi);
161         HAL_WORD_REG_WRITE(0x1000404c, gpio_in);
162         HAL_WORD_REG_WRITE(0x10004088, pupd);
163     }
164     DEBUG_SYSTEM_STATE = (DEBUG_SYSTEM_STATE&(~0xffff)) | 0x1200;
165
166     {
167         // since we still need to touch mac_base address after resuming back, so that
168         // reset mac can't be done in ResetFifo function, move to here... 
169         // whole mac control reset.... (bit1)
170         HAL_WORD_REG_WRITE( MAGPIE_REG_RST_PWDN_CTRL_ADDR, (BIT1) );
171         HAL_WORD_REG_WRITE( MAGPIE_REG_RST_PWDN_CTRL_ADDR, (HAL_WORD_REG_READ(MAGPIE_REG_RST_PWDN_CTRL_ADDR)|BIT0));
172         HAL_WORD_REG_WRITE( MAGPIE_REG_RST_PWDN_CTRL_ADDR, 0x0 );
173         A_DELAY_USECS(1000);
174     }
175
176     //A_PRINTF("reg(0x10020)=(%x)\n", HAL_WORD_REG_READ(0x10020));
177     // disable ep3 int enable, so that resume back won't send wdt magic pattern out!!!
178     mUSB_STATUS_IN_INT_DISABLE();            
179
180     MAGPIE_REG_USB_RX0_SWAP_DATA = 0x1;
181     MAGPIE_REG_USB_TX0_SWAP_DATA = 0x1;
182     MAGPIE_REG_USB_RX1_SWAP_DATA = 0x1;
183     MAGPIE_REG_USB_RX2_SWAP_DATA = 0x1;
184
185     if (((DEBUG_SYSTEM_STATE&~(0x0000ffff))>>16 == 0x5342)) {
186         /* UART_SEL and SPI_SEL */
187         HAL_WORD_REG_WRITE(0x50040, (0x300|0|(1>>1)<<12));
188     }
189
190     /* Jump to boot code */
191     A_USB_JUMP_BOOT();
192
193 }
194
195 /*
196  * -- patch usb_fw_task --
197  * . usb zero length interrupt should not clear by s/w, h/w will handle that
198  * . complete suspend handle, configure gpio, turn off related function, 
199  *   slow down the pll for stable issue
200  */
201 void _fw_usb_fw_task(void)
202 {
203     register uint8_t usb_interrupt_level1;
204     register uint8_t usb_interrupt_level2;
205
206     usb_interrupt_level1 = USB_BYTE_REG_READ(ZM_INTR_GROUP_OFFSET);
207 #if 0 // these endpoints are handled by DMA
208     if (usb_interrupt_level1 & BIT5)            //Group Byte 5
209     {
210         vUsb_Data_In();
211     }
212 #endif
213     if (usb_interrupt_level1 & BIT4)
214     {
215         usb_interrupt_level2 = USB_BYTE_REG_READ(ZM_INTR_SOURCE_4_OFFSET);
216         if( usb_interrupt_level2 & BIT6)
217             A_USB_REG_OUT();//vUsb_Reg_Out();
218     }
219
220     if (usb_interrupt_level1 & BIT6)
221     {
222         //zfGenWatchDogEvent();
223     usb_interrupt_level2 = USB_BYTE_REG_READ(ZM_INTR_SOURCE_6_OFFSET);
224         if( usb_interrupt_level2 & BIT6)
225              A_USB_STATUS_IN();//vUsb_Status_In();
226     }
227
228     if (usb_interrupt_level1 & BIT0)            //Group Byte 0
229     {
230         //usb_interrupt_level2 = ZM_INTR_SOURCE_0_REG;
231         usb_interrupt_level2 = USB_BYTE_REG_READ(ZM_INTR_SOURCE_0_OFFSET);
232
233         // refer to FUSB200, p 48, offset:21H, bit7 description, should clear the command abort interrupt first!?
234         if (usb_interrupt_level2 & BIT7)
235         {
236             //ZM_INTR_SOURCE_0_REG &= 0x7f;       // Handle command abort
237             USB_BYTE_REG_WRITE(ZM_INTR_SOURCE_0_OFFSET, (USB_BYTE_REG_READ(ZM_INTR_SOURCE_0_OFFSET)& ~BIT7));
238             A_PRINTF("![SOURCE_0] bit7 on\n\r");
239         }
240
241         if (usb_interrupt_level2 & BIT1)
242         {
243             //A_PRINTF("![USB] ep0 IN in \n\r");
244             A_USB_EP0_TX();                       // USB EP0 tx interrupt
245         }
246         if (usb_interrupt_level2 & BIT2)
247         {
248             //A_PRINTF("![USB] ep0 OUT in\n\r");
249             A_USB_EP0_RX();                       // USB EP0 rx interrupt
250         }
251         if (usb_interrupt_level2 & BIT0)
252         {
253             //A_PRINTF("![USB] ep0 SETUP in\n\r");
254             A_USB_EP0_SETUP();
255             //vWriteUSBFakeData();
256         }
257 //        else if (usb_interrupt_level2 & BIT3)
258         if (usb_interrupt_level2 & BIT3)
259         {
260             vUsb_ep0end();
261 //            A_PRINTF("![SOURCE_0] ep0 CMD_END\n\r");
262         }
263         if (usb_interrupt_level2 & BIT4)
264         {
265             vUsb_ep0fail();
266 //            A_PRINTF("![SOURCE_0] ep0 CMD_FAIL\n\r");
267         }
268         if (eUsbCxFinishAction == ACT_STALL)
269         {
270             // set CX_STL to stall Endpoint0 & will also clear FIFO0
271             USB_BYTE_REG_WRITE(ZM_CX_CONFIG_STATUS_OFFSET, 0x04);
272 //            A_PRINTF("![USB] ZM_CX_CONFIG_STATUS_REG = 0x04\n\r");
273         }
274         else if (eUsbCxFinishAction == ACT_DONE)
275         {
276             // set CX_DONE to indicate the transmistion of control frame
277             USB_BYTE_REG_WRITE(ZM_CX_CONFIG_STATUS_OFFSET, 0x01);
278         }
279         eUsbCxFinishAction = ACT_IDLE;
280     }
281
282     if (usb_interrupt_level1 & BIT7)            //Group Byte 7
283     {
284         //usb_interrupt_level2 = ZM_INTR_SOURCE_7_REG;
285         usb_interrupt_level2 = USB_BYTE_REG_READ(ZM_INTR_SOURCE_7_OFFSET);
286
287 #if 0
288         if (usb_interrupt_level2 & BIT7)
289         {
290             vUsb_Data_Out0Byte();
291 //            A_PRINTF("![SOURCE_7] bit7 on, clear it\n\r");
292         }
293         if (usb_interrupt_level2 & BIT6)
294         {
295             vUsb_Data_In0Byte();
296 //            A_PRINTF("![SOURCE_7] bit6 on, clear it\n\r");
297         }
298 #endif
299         
300         if (usb_interrupt_level2 & BIT1)
301         {
302             vUsb_rst();
303             //USB_BYTE_REG_WRITE(ZM_INTR_SOURCE_7_REG, (USB_BYTE_REG_READ(ZM_INTR_SOURCE_7_OFFSET)&~0x2));
304             A_PRINTF("!USB reset\n\r");
305 //            A_PRINTF("![0x1012c]: %\n\r", USB_WORD_REG_READ(0x12c));
306         }
307         if (usb_interrupt_level2 & BIT2)
308         {
309            // TBD: the suspend resume code should put here, Ryan, 07/18
310            //
311            //  issue, jump back to rom code and what peripherals should we reset here?
312            //
313            _fw_usb_suspend_reboot();            
314         }
315         if (usb_interrupt_level2 & BIT3)
316         {
317             vUsb_resm();
318             A_PRINTF("!USB resume\n\r");
319         }
320     }
321
322 }
323
324
325 void _fw_usb_reset_fifo(void)
326 {
327     volatile uint32_t   *reg_data;
328
329     HAL_BYTE_REG_WRITE(0x100ae, (HAL_BYTE_REG_READ(0x100ae)|0x10));
330     HAL_BYTE_REG_WRITE(0x100af, (HAL_BYTE_REG_READ(0x100af)|0x10));
331
332     // disable ep3 int enable, so that resume back won't send wdt magic pattern out!!!
333     mUSB_STATUS_IN_INT_DISABLE();
334
335     // update magic pattern to indicate this is a suspend
336     // k2: MAGPIE_REG_RST_WDT_TIMER_CTRL_ADDR
337     // magpie: MAGPIE_REG_RST_STATUS_ADDR
338     HAL_WORD_REG_WRITE(MAGPIE_REG_RST_STATUS_ADDR, SUS_MAGIC_PATTERN);
339
340     /*
341      * Before USB suspend, USB DMA must be reset(refer to Otus)
342      * Otus runs the following statements only
343      * HAL_WORD_REG_WRITE( MAGPIE_REG_RST_PWDN_CTRL_ADDR, BIT0|BIT2 );
344      * HAL_WORD_REG_WRITE( MAGPIE_REG_RST_PWDN_CTRL_ADDR, 0x0 );
345      * K2 must run the following statements additionally
346      * reg_data = (A_UINT32 *)(USB_CTRL_BASE_ADDRESS + 0x118);
347      * *reg_data = 0x00000000;
348      * *reg_data = 0x00000001;
349      * because of Hardware bug in K2
350      */
351     reg_data = (uint32_t *)(USB_CTRL_BASE_ADDRESS + 0x118);
352     *reg_data = 0x00000000;
353
354     // reset both usb(bit2)/wlan(bit1) dma
355     HAL_WORD_REG_WRITE( MAGPIE_REG_RST_PWDN_CTRL_ADDR, (BIT2) );
356     HAL_WORD_REG_WRITE( MAGPIE_REG_RST_PWDN_CTRL_ADDR, (HAL_WORD_REG_READ(MAGPIE_REG_RST_PWDN_CTRL_ADDR)|BIT0));
357     HAL_WORD_REG_WRITE( MAGPIE_REG_RST_PWDN_CTRL_ADDR, 0x0 );
358
359     *reg_data = 0x00000001;
360
361     /* MAC warem reset */
362     //reg_data = (uint32_t *)(K2_REG_MAC_BASE_ADDR + 0x7000);
363     //*reg_data = 0x00000001;
364
365     //A_DELAY_USECS(1);
366
367     //*reg_data = 0x00000000;
368
369     //while (*reg_data)   ;
370
371     A_PRINTF("\n change clock to 22 and go to suspend now!");
372     
373     /* UART_SEL */
374     HAL_WORD_REG_WRITE(0x50040, (0x200|0|(1>>1)<<12));
375     A_UART_HWINIT((22*1000*1000), 19200);
376 }
377 #endif