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