2 * Copyright (c) 2013 Qualcomm Atheros, Inc.
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:
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
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
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.
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.
37 #include "athos_api.h"
40 #if defined(PROJECT_MAGPIE)
42 extern uint32_t *init_htc_handle;
43 uint8_t htc_complete_setup = 0;
44 void reset_EP4_FIFO(void);
48 void Magpie_init(void);
51 #if defined(PROJECT_MAGPIE)
52 extern BOOLEAN bEepromExist;
53 extern BOOLEAN bJumptoFlash;
56 static uint32_t loop_low, loop_high;
58 // reference idle count at the beginning
59 uint32_t idle_cnt = 0;
61 #if defined(PROJECT_K2)
62 // save the ROM printf function point
63 int (* save_cmnos_printf)(const char * fmt, ...);
66 #define ATH_DATE_STRING __DATE__" "__TIME__
68 static void idle_task();
70 #if defined(PROJECT_MAGPIE)
71 void fatal_exception_func()
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);
85 #if defined(PROJECT_MAGPIE)
87 change_magpie_clk(void)
89 volatile uint32_t rd_data;
91 HAL_WORD_REG_WRITE(0x00056004, 0x11);
92 rd_data = HAL_WORD_REG_READ(0x00056004) & 0x1;
94 /* Wait for the update bit to get cleared */
96 rd_data = HAL_WORD_REG_READ(0x00056004) & 0x1;
98 /* Put the PLL into reset */
99 rd_data = HAL_WORD_REG_READ(0x00050010) | (1<<1);
100 HAL_WORD_REG_WRITE(0x00050010,rd_data);
103 * XXX: statically set the CPU clock to 200Mhz
105 /* Setting of the PLL */
106 HAL_WORD_REG_WRITE(0x00056000, 0x325);//400 MHz
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);
112 A_DELAY_USECS(60); // wait for stable
114 /* CPU & AHB settings */
116 * AHB clk = ( CPU clk / 2 )
118 HAL_WORD_REG_WRITE(0x00056004, ((0x00001 | (1 << 16)|(1 << 8)))); // set plldiv to 2
119 rd_data = HAL_WORD_REG_READ(0x00056004) & 0x1;
122 rd_data = HAL_WORD_REG_READ(0x00056004) & 0x1;
125 A_UART_HWINIT((100*1000*1000), 115200);
129 void exception_reset(struct register_dump_s *dump)
131 A_PRINTF("exception_reset \n");
133 /* phase I dump info */
134 A_PRINTF("exception reset-phase 1\n");
139 A_PRINTF("exception reset-phase 2\n");
140 *((volatile uint32_t*)WATCH_DOG_MAGIC_PATTERN_ADDR) = WDT_MAGIC_PATTERN;
142 HAL_WORD_REG_WRITE(MAGPIE_REG_RST_RESET_ADDR,
143 HAL_WORD_REG_READ(MAGPIE_REG_RST_RESET_ADDR)|(BIT10|BIT8|BIT7|BIT6));
145 HAL_WORD_REG_WRITE(MAGPIE_REG_AHB_ARB_ADDR,
146 (HAL_WORD_REG_READ(MAGPIE_REG_AHB_ARB_ADDR)|BIT1));
148 USB_WORD_REG_WRITE(ZM_SOC_USB_DMA_RESET_OFFSET, 0x0);
149 HAL_WORD_REG_WRITE(0x50010, HAL_WORD_REG_READ(0x50010)|BIT4);
151 HAL_WORD_REG_WRITE(0x50010, HAL_WORD_REG_READ(0x50010)&~BIT4);
153 USB_WORD_REG_WRITE(ZM_SOC_USB_DMA_RESET_OFFSET, BIT0);
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));
160 A_UART_HWINIT((40*1000*1000), 115200);
162 A_PRINTF("do TX/RX swap\n");
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;
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) */
178 void reset_EP4_FIFO(void)
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));
188 LOCAL void zfGenExceptionEvent(uint32_t exccause, uint32_t pc, uint32_t badvaddr)
190 uint32_t pattern = 0x33221199;
192 A_PRINTF("<Exception>Tgt Drv send an event 44332211 to Host Drv\n");
193 mUSB_STATUS_IN_INT_DISABLE();
195 USB_WORD_REG_WRITE(ZM_CBUS_FIFO_SIZE_OFFSET, 0x0f);
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);
202 mUSB_EP3_XFER_DONE();
205 LOCAL void zfGenWrongEpidEvent(uint32_t epid)
207 uint32_t pattern = 0x33221299;
209 A_PRINTF("<WrongEPID>Tgt Drv send an event 44332212 to Host Drv\n");
210 mUSB_STATUS_IN_INT_DISABLE();
212 USB_WORD_REG_WRITE(ZM_CBUS_FIFO_SIZE_OFFSET, 0x0f);
214 USB_WORD_REG_WRITE(ZM_EP3_DATA_OFFSET, pattern);
215 USB_WORD_REG_WRITE(ZM_EP3_DATA_OFFSET, epid);
217 mUSB_EP3_XFER_DONE();
221 AR6002_fatal_exception_handler_patch(CPU_exception_frame_t *exc_frame)
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));
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;
234 zfGenExceptionEvent(dump.exc_frame.xt_exccause, dump.pc, dump.badvaddr);
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();
241 A_PUTS("Fatal exception\n\r");
253 HTCControlSvcProcessMsg_patch(HTC_ENDPOINT_ID EndpointID, adf_nbuf_t hdr_buf,
254 adf_nbuf_t pBuffers, void *arg)
258 HTC_UNKNOWN_MSG *pMsg;
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;
265 if (pMsg->MessageID == HTC_MSG_SETUP_COMPLETE_ID) {
266 htc_complete_setup = 1;
269 HTCControlSvcProcessMsg(EndpointID, hdr_buf, pBuffers, arg);
272 /* Patch callback for check the endpoint ID is correct or not */
274 HTCMsgRecvHandler_patch(adf_nbuf_t hdr_buf, adf_nbuf_t buffer, void *context)
280 HTC_FRAME_HDR *pHTCHdr;
282 if (hdr_buf == ADF_NBUF_NULL) {
283 /* HTC hdr is not in the hdr_buf */
289 adf_nbuf_peek_header(tmp_nbuf, &anbdata, &anblen);
290 pHTCHdr = (HTC_FRAME_HDR *)anbdata;
292 eid = pHTCHdr->EndpointID;
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);
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);
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));
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");
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");
328 HTCMsgRecvHandler( hdr_buf, buffer, context);
336 uint32_t *temp = (uint32_t *)ALLOCRAM_START;
338 /* clear bss segment */
339 for(temp = (uint32_t *)&START_BSS; temp < (uint32_t *)&END_BSS; temp++)
342 /* clear heap segment */
343 for(i = 0; i < ((ALLOCRAM_SIZE - 4)/4); i++)
347 static void idle_task()
349 if (loop_low == 0xffffffff) {
358 void __noreturn wlan_task(void)
360 loop_low=loop_high=0;
363 /* update wdt timer */
366 /* UPDATE cticks - to be moved to idle_tsk, put here will be easier to read */
369 HIF_isr_handler(NULL);
371 #if MAGPIE_ENABLE_WLAN == 1
378 /* Very low priority tasks */
379 if ((loop_low & 0x1fff) == 0x7)
386 #endif /* #if defined(_RAM_) */