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