ath9k_htc: Update to upstream's commit d19607454d656cb14d8c16dfbf161eebb542e8fe dated...
[linux-libre-firmware.git] / ath9k_htc / target_firmware / magpie_fw_dev / target / init / init.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 #if defined(_RAM_)
36
37 #include <wlan_pci.h>
38 #include <rom.h>
39
40 #include "athos_api.h"
41 #include "usb_defs.h"
42
43 #include "adf_os_io.h"
44
45 #if defined(PROJECT_MAGPIE)
46 #include "regdump.h"
47 extern  uint32_t *init_htc_handle;
48 uint8_t htc_complete_setup = 0;
49 void reset_EP4_FIFO(void);
50 #endif
51 #include "init.h"
52
53 void Magpie_init(void);
54
55
56 #if defined(PROJECT_MAGPIE)
57 extern BOOLEAN bEepromExist;
58 extern BOOLEAN bJumptoFlash;
59 #endif
60
61 static uint32_t loop_low, loop_high;
62
63 // reference idle count at the beginning
64 uint32_t idle_cnt = 0;
65
66 #if defined(PROJECT_K2)
67 // save the ROM printf function point
68 int (* save_cmnos_printf)(const char * fmt, ...);
69 #endif
70
71 static void idle_task();
72
73 #if defined(PROJECT_MAGPIE)
74 void fatal_exception_func()
75 {
76         // patch for execption
77         (void)_xtos_set_exception_handler(EXCCAUSE_UNALIGNED, AR6002_fatal_exception_handler_patch);
78         (void)_xtos_set_exception_handler(EXCCAUSE_LOAD_STORE_ERROR, AR6002_fatal_exception_handler_patch);
79         (void)_xtos_set_exception_handler(EXCCAUSE_ILLEGAL, AR6002_fatal_exception_handler_patch);
80         (void)_xtos_set_exception_handler(EXCCAUSE_INSTR_ERROR, AR6002_fatal_exception_handler_patch);
81         (void)_xtos_set_exception_handler(EXCCAUSE_PRIVILEGED, AR6002_fatal_exception_handler_patch);
82         (void)_xtos_set_exception_handler(EXCCAUSE_INSTR_DATA_ERROR, AR6002_fatal_exception_handler_patch);
83         (void)_xtos_set_exception_handler(EXCCAUSE_LOAD_STORE_DATA_ERROR, AR6002_fatal_exception_handler_patch);
84         (void)_xtos_set_exception_handler(EXCCAUSE_DIVIDE_BY_ZERO, AR6002_fatal_exception_handler_patch);
85 }
86 #endif
87
88 #if defined(PROJECT_MAGPIE)
89 void
90 change_magpie_clk(void)
91 {
92         iowrite32(0x00056004, BIT4 | BIT0);
93
94         /* Wait for the update bit (BIT0) to get cleared */
95         while (ioread32(0x00056004) & BIT0)
96                 ;
97
98         /* Put the PLL into reset */
99         io32_set(0x00050010, BIT1);
100
101         /*
102          * XXX: statically set the CPU clock to 200Mhz
103          */
104         /* Setting PLL to 400MHz */
105         iowrite32(0x00056000, 0x325);
106
107         /* Pull CPU PLL out of Reset */
108         io32_clr(0x00050010, BIT1);
109
110         A_DELAY_USECS(60); // wait for stable
111
112         /* CPU & AHB settings */
113         /*
114          * AHB clk = ( CPU clk / 2 )
115          */
116         iowrite32(0x00056004, 0x00001 | BIT16 | BIT8); /* set plldiv to 2 */
117
118         while (ioread32(0x00056004) & BIT0)
119                 ;
120
121         /* UART Setting */
122         A_UART_HWINIT((100*1000*1000), 115200);
123
124 }
125
126 void exception_reset(struct register_dump_s *dump)
127 {
128         A_PRINTF("exception_reset \n");
129
130         /* phase I dump info */
131         A_PRINTF("exception reset-phase 1\n");
132         if(_assfail_ori)
133                 _assfail_ori(dump);
134
135         /* phase II reset */
136         A_PRINTF("exception reset-phase 2\n");
137         iowrite32(WATCH_DOG_MAGIC_PATTERN_ADDR, WDT_MAGIC_PATTERN);
138
139         io32_set(MAGPIE_REG_RST_RESET_ADDR, BIT10 | BIT8 | BIT7 | BIT6);
140
141         io32_set(MAGPIE_REG_AHB_ARB_ADDR, BIT1);
142
143         iowrite32_usb(ZM_SOC_USB_DMA_RESET_OFFSET, 0x0);
144         io32_set(0x50010, BIT4);
145         A_DELAY_USECS(5);
146         io32_clr(0x50010, BIT4);
147         A_DELAY_USECS(5);
148         iowrite32_usb(ZM_SOC_USB_DMA_RESET_OFFSET, BIT0);
149
150         // set clock to bypass mode - 40Mhz from XTAL
151         iowrite32(MAGPIE_REG_CPU_PLL_BYPASS_ADDR, BIT0 | BIT4);
152         A_DELAY_USECS(100); // wait for stable
153         iowrite32(MAGPIE_REG_CPU_PLL_ADDR, BIT16);
154
155         A_UART_HWINIT((40*1000*1000), 115200);
156
157         A_PRINTF("do TX/RX swap\n");
158
159         MAGPIE_REG_USB_RX0_SWAP_DATA = 0x1;
160         MAGPIE_REG_USB_TX0_SWAP_DATA = 0x1;
161         MAGPIE_REG_USB_RX1_SWAP_DATA = 0x1;
162         MAGPIE_REG_USB_RX2_SWAP_DATA = 0x1;
163
164         A_PRINTF("Cold reboot initiated.");
165 #if defined(PROJECT_MAGPIE)
166         iowrite32(WATCH_DOG_MAGIC_PATTERN_ADDR, 0);
167 #elif defined(PROJECT_K2)
168         iowrite32(MAGPIE_REG_RST_STATUS_ADDR, 0);
169 #endif /* #if defined(PROJECT_MAGPIE) */
170         A_USB_JUMP_BOOT();
171 }
172
173 void reset_EP4_FIFO(void)
174 {
175         int i;
176
177         /* reset EP4 FIFO */
178         io8_set_usb(ZM_EP4_BYTE_COUNT_HIGH_OFFSET, BIT4);
179         for(i = 0; i < 100; i++) {}
180         io8_clr_usb(ZM_EP4_BYTE_COUNT_HIGH_OFFSET, BIT4);
181 }
182
183 LOCAL void zfGenExceptionEvent(uint32_t exccause, uint32_t pc, uint32_t badvaddr)
184 {
185         uint32_t pattern = 0x33221199;
186
187         A_PRINTF("<Exception>Tgt Drv send an event 44332211 to Host Drv\n");
188         mUSB_STATUS_IN_INT_DISABLE();
189
190         iowrite32_usb(ZM_CBUS_FIFO_SIZE_OFFSET, 0x0f);
191
192         iowrite32_usb(ZM_EP3_DATA_OFFSET, pattern);
193         iowrite32_usb(ZM_EP3_DATA_OFFSET, exccause);
194         iowrite32_usb(ZM_EP3_DATA_OFFSET, pc);
195         iowrite32_usb(ZM_EP3_DATA_OFFSET, badvaddr);
196
197         mUSB_EP3_XFER_DONE();
198 }
199
200 LOCAL void zfGenWrongEpidEvent(uint32_t epid)
201 {
202         uint32_t pattern   = 0x33221299;
203
204         A_PRINTF("<WrongEPID>Tgt Drv send an event 44332212 to Host Drv\n");
205         mUSB_STATUS_IN_INT_DISABLE();
206
207         iowrite32_usb(ZM_CBUS_FIFO_SIZE_OFFSET, 0x0f);
208
209         iowrite32_usb(ZM_EP3_DATA_OFFSET, pattern);
210         iowrite32_usb(ZM_EP3_DATA_OFFSET, epid);
211
212         mUSB_EP3_XFER_DONE();
213 }
214
215 void
216 AR6002_fatal_exception_handler_patch(CPU_exception_frame_t *exc_frame)
217 {
218         struct register_dump_s dump;
219         uint32_t  exc_cause, exc_vaddr;
220         asm volatile("rsr %0,%1" : "=r" (exc_cause) : "n" (EXCCAUSE));
221         asm volatile("rsr %0,%1" : "=r" (exc_vaddr) : "n" (EXCVADDR));
222
223         dump.exc_frame              = *exc_frame; /* structure copy */
224         dump.badvaddr               = exc_vaddr;
225         dump.exc_frame.xt_exccause  = exc_cause;
226         dump.pc                     = exc_frame->xt_pc;
227         dump.assline                = 0;
228
229         zfGenExceptionEvent(dump.exc_frame.xt_exccause, dump.pc, dump.badvaddr);
230
231 #if SYSTEM_MODULE_PRINT
232         A_PRINTF("\nFatal exception (%d): \tpc=0x%x \n\r\tbadvaddr=0x%x \n\r\tdump area=0x%x\n",
233                  dump.exc_frame.xt_exccause, dump.pc, dump.badvaddr, &dump);
234         PRINT_FAILURE_STATE();
235 #else
236         A_PUTS("Fatal exception\n\r");
237 #endif
238         A_ASSFAIL(&dump);
239
240 #if defined(_ROM_)
241         A_WDT_ENABLE();
242 #endif
243
244         while(1) ;
245 }
246
247 void
248 HTCControlSvcProcessMsg_patch(HTC_ENDPOINT_ID EndpointID, adf_nbuf_t hdr_buf,
249                               adf_nbuf_t pBuffers, void *arg)
250 {
251         a_uint8_t *anbdata;
252         a_uint32_t anblen;
253         HTC_UNKNOWN_MSG *pMsg;
254
255         /* we assume buffers are aligned such that we can access the message
256          * parameters directly*/
257         adf_nbuf_peek_header(pBuffers, &anbdata, &anblen);
258         pMsg = (HTC_UNKNOWN_MSG *)anbdata;
259
260         if (pMsg->MessageID == HTC_MSG_SETUP_COMPLETE_ID) {
261                 htc_complete_setup = 1;
262         }
263
264         HTCControlSvcProcessMsg(EndpointID, hdr_buf, pBuffers, arg);
265 }
266
267 /* Patch callback for check the endpoint ID is correct or not */
268 void
269 HTCMsgRecvHandler_patch(adf_nbuf_t hdr_buf, adf_nbuf_t buffer, void *context)
270 {
271         int eid;
272         a_uint8_t *anbdata;
273         a_uint32_t anblen;
274         adf_nbuf_t tmp_nbuf;
275         HTC_FRAME_HDR *pHTCHdr;
276
277         if (hdr_buf == ADF_NBUF_NULL) {
278                 /* HTC hdr is not in the hdr_buf */
279                 tmp_nbuf = buffer;
280         } else {
281                 tmp_nbuf = hdr_buf;
282         }
283
284         adf_nbuf_peek_header(tmp_nbuf, &anbdata, &anblen);
285         pHTCHdr = (HTC_FRAME_HDR *)anbdata;
286
287         eid = pHTCHdr->EndpointID;
288
289         if ((eid != 0) && (htc_complete_setup == 0)) {
290                 A_PRINTF("\nHTC Hdr EndpointID = %d, anblen = %d\n", pHTCHdr->EndpointID, anblen);
291                 A_PRINTF("HTC Hder : %2x-%2x-%2x-%2x-%2x-%2x-%2x-%2x-%2x-%2x-%2x-%2x\n",
292                          *anbdata, *(anbdata+1), *(anbdata+2), *(anbdata+3),
293                          *(anbdata+4), *(anbdata+5), *(anbdata+6), *(anbdata+7),
294                          *(anbdata+8), *(anbdata+9), *(anbdata+10), *(anbdata+11));
295                 A_PRINTF("init_htc_handle = 0x%8x\n", init_htc_handle);
296
297                 if (pHTCHdr->EndpointID == 1) {
298                         A_PRINTF("Return WMI Command buffer\n");
299                         HTC_ReturnBuffers(init_htc_handle, 1, tmp_nbuf);
300                 } else if ((pHTCHdr->EndpointID == 5) || (pHTCHdr->EndpointID == 6)) {
301                         A_PRINTF("Return Data buffer\n");
302                         HTC_ReturnBuffers(init_htc_handle, 6, tmp_nbuf);
303                 } else {
304                 }
305         } else {
306                 if ((pHTCHdr->EndpointID < 0) || (pHTCHdr->EndpointID >= ENDPOINT_MAX)) {
307                         A_PRINTF("HTC Hdr EndpointID = %d, anblen = %d\n", pHTCHdr->EndpointID, anblen);
308                         A_PRINTF("HTC Hder : %2x-%2x-%2x-%2x-%2x-%2x-%2x-%2x\n",
309                                  *anbdata, *(anbdata+1), *(anbdata+2), *(anbdata+3),
310                                  *(anbdata+4), *(anbdata+5), *(anbdata+6), *(anbdata+7));
311
312                         if (anblen > 64) {
313                                 A_PRINTF("EP1-Tx-Data with Wrong Htc Header Endpoint ID, WAR free this buffer\n");
314                                 HTC_ReturnBuffers(init_htc_handle, 6, tmp_nbuf);
315                                 A_PRINTF("EP1-Tx-Data > Free this buffer successfully\n");
316                         } else {
317                                 A_PRINTF("EP4-WMI-Cmd with Wrong Htc Header Endpoint ID, WAR free this buffer\n");
318                                 zfGenWrongEpidEvent((a_uint32_t)pHTCHdr->EndpointID);
319                                 HTC_ReturnBuffers(init_htc_handle, 1, tmp_nbuf);
320                                 A_PRINTF("EP4-WMI-Cmd > Free this buffer successfully\n");
321                         }
322                 } else
323                         HTCMsgRecvHandler( hdr_buf, buffer, context);
324         }
325 }
326 #endif
327
328 void init_mem()
329 {
330         int i = 0;
331         uint32_t *temp = (uint32_t *)ALLOCRAM_START;
332
333         /* clear bss segment */
334         for(temp = (uint32_t *)&START_BSS; temp < (uint32_t *)&END_BSS; temp++)
335                 *temp = 0;
336
337         /* clear heap segment */
338         for(i = 0; i < ((ALLOCRAM_SIZE - 4)/4); i++)
339                 temp[i] = 0;
340 }
341
342 static void idle_task()
343 {
344         if (loop_low == 0xffffffff) {
345                 loop_low = 0;
346                 loop_high++;
347         } else {
348                 loop_low++;
349         }
350         return;
351 }
352
353 void __noreturn wlan_task(void)
354 {
355         loop_low=loop_high=0;
356
357         while(1) {
358                 /* update wdt timer */
359                 A_WDT_TASK();
360
361                 /* UPDATE cticks - to be moved to idle_tsk, put here will be easier to read  */
362                 A_CLOCK_TICK();
363
364                 HIF_isr_handler(NULL);
365
366 #if MAGPIE_ENABLE_WLAN == 1
367                 wlan_pci_isr();
368 #endif
369
370                 A_TASKLET_RUN();
371                 A_TIMER_RUN();
372
373                 /* Very low priority tasks */
374                 if ((loop_low & 0x1fff) == 0x7)
375                         A_DBG_TASK();
376
377                 idle_task();
378         }
379 }
380
381 #endif /* #if defined(_RAM_) */