Merge pull request #163 from cloudswei/ctlframe_injection
[open-ath9k-htc-firmware.git] / target_firmware / magpie_fw_dev / target / init / app_start.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
36 #include <wlan_pci.h>
37 #include <Magpie_api.h>
38 #include <rom.h>
39
40 #include "dt_defs.h"
41 #include "athos_api.h"
42
43 #include "regdump.h"
44 #include "usb_defs.h"
45
46 #include "adf_os_io.h"
47
48 #include "init.h"
49 #include "app_start.h"
50
51 // @TODO: Should define the memory region later~
52 #define ALLOCRAM_START       ( ((unsigned int)&_fw_image_end) + 4)
53 #define ALLOCRAM_SIZE        ( SYS_RAM_SZIE - ( ALLOCRAM_START - SYS_D_RAM_REGION_0_BASE) - SYS_D_RAM_STACK_SIZE)
54
55 void (* _assfail_ori)(struct register_dump_s *);
56
57 // support for more than 64 bytes on command pipe
58 extern void usb_reg_out_patch(void);
59 extern int _HIFusb_get_max_msg_len_patch(hif_handle_t handle, int pipe);
60 extern void _HIFusb_isr_handler_patch(hif_handle_t h);
61 extern BOOLEAN bSet_configuration_patch(void);
62 extern void vUSBFIFO_EP6Cfg_FS_patch(void);
63 extern void usb_status_in_patch(void);
64 extern void _fw_usbfifo_init(USB_FIFO_CONFIG *pConfig);
65 extern void zfTurnOffPower_patch(void);
66 extern void zfResetUSBFIFO_patch(void);
67 extern void _HIFusb_start_patch(hif_handle_t handle);
68 extern void hif_pci_patch_install(struct hif_api *apis);
69 extern BOOLEAN bGet_descriptor_patch(void);
70 extern BOOLEAN bStandardCommand_patch(void);
71
72 // patch for clock
73 extern void cmnos_clock_init_patch(a_uint32_t refclk);
74 extern a_uint32_t cmnos_refclk_speed_get_patch(void);
75 extern void cmnos_delay_us_patch(int us);
76 extern void cmnos_tick_patch(void);
77 extern a_uint32_t cmnos_milliseconds_patch(void);
78
79 extern BOOLEAN bJumptoFlash;
80 extern BOOLEAN bEepromExist;
81
82 void __section(boot) __noreturn __visible app_start(void)
83 {
84         uint32_t rst_status;
85         A_HOSTIF hostif;
86 #if defined(PROJECT_MAGPIE)
87         T_EEP_RET retEEP;
88 #endif
89
90         /* Zero BSS segment & dynamic memory section. */
91         init_mem();
92
93 #if defined(PROJECT_MAGPIE)
94         fatal_exception_func();
95 #endif
96
97         if( IS_FLASHBOOT() ) {
98                 athos_indirection_table_install();
99                 DBG_MODULE_INSTALL();
100                 A_CLOCK_INIT(SYSTEM_CLK);
101                 A_UART_INIT();
102                 A_PRINTF_INIT();
103                 A_DBG_INIT();
104                 A_EEP_INIT();
105                 A_TASKLET_INIT();
106                 _indir_tbl.cmnos.timer._timer_init();
107
108 #if defined(PROJECT_K2)
109                 /*
110                  * WAR: these variable is not initialized when boot from flash
111                  *      either re-enumeration or config them to default value = 0 would fix the issue
112                  */
113                 u8UsbInterfaceAlternateSetting = u8UsbConfigValue = u8UsbInterfaceValue = 0;
114 #endif
115         }
116 #ifdef ROM_VER_1_1
117         else
118                 A_EEP_INIT(); /*Required for 1_1*/
119 #endif
120
121 #if defined(PROJECT_MAGPIE)
122         retEEP = A_EEP_IS_EXIST();
123         bJumptoFlash = FALSE;
124         if ( RET_SUCCESS == retEEP ) {
125                 bEepromExist = TRUE;
126         } else {
127                 bEepromExist = FALSE;
128         }
129 #endif
130
131         hostif = A_IS_HOST_PRESENT();
132
133 #if defined(PROJECT_MAGPIE)
134         rst_status = ioread32(WATCH_DOG_MAGIC_PATTERN_ADDR);
135 #elif defined(PROJECT_K2)
136         rst_status = ioread32(MAGPIE_REG_RST_STATUS_ADDR);
137 #endif /* #if defined(PROJECT_MAGPIE) */
138
139
140         A_PRINTF(" A_WDT_INIT()\n\r");
141
142 #if defined(PROJECT_K2)
143         save_cmnos_printf = fw_cmnos_printf;
144 #endif
145
146         if( hostif == HIF_USB ) {
147 #if defined(PROJECT_K2)
148 #if MOVE_PRINT_TO_RAM
149                 save_cmnos_printf = _indir_tbl.cmnos.printf._printf;
150                 _indir_tbl.cmnos.printf._printf = fw_cmnos_printf;
151 #endif
152                 _indir_tbl.cmnos.usb._usb_fw_task = _fw_usb_fw_task;
153                 _indir_tbl.cmnos.usb._usb_reset_fifo = _fw_usb_reset_fifo;
154 #endif
155         }
156
157         if( rst_status == WDT_MAGIC_PATTERN ) {
158                 A_PRINTF(" ==>WDT reset<==\n");
159 #if defined(PROJECT_MAGPIE)
160                 reset_EP4_FIFO();
161 #endif
162                 *((volatile uint32_t*)WATCH_DOG_RESET_COUNTER_ADDR)+=1;
163         } else if (rst_status == SUS_MAGIC_PATTERN) {
164                 A_PRINTF(" ==>warm start<==\n");
165         } else
166                 A_PRINTF(" ==>cold start<==\n");
167
168 #if defined(PROJECT_MAGPIE)
169         *((volatile uint32_t*)WATCH_DOG_MAGIC_PATTERN_ADDR)=WDT_MAGIC_PATTERN;
170 #elif defined(PROJECT_K2)
171         iowrite32(MAGPIE_REG_RST_STATUS_ADDR, WDT_MAGIC_PATTERN);
172 #endif /* #if defined(PROJECT_MAGPIE) */
173
174         /* intr enable would left for firmware */
175         /* athos_interrupt_init(); */
176
177         DBG_MODULE_INSTALL();
178 #if defined(PROJECT_K2)
179         A_DBG_INIT();
180 #endif
181
182 #if defined(PROJECT_K2)
183 #if SYSTEM_MODULE_SFLASH
184         SFLASH_MODULE_INSTALL();
185         A_SFLASH_INIT();
186 #endif
187 #endif
188
189         HIF_MODULE_INSTALL();
190         HTC_MODULE_INSTALL();
191         WMI_SERVICE_MODULE_INSTALL();
192         BUF_POOL_MODULE_INSTALL();
193         VBUF_MODULE_INSTALL();
194         VDESC_MODULE_INSTALL();
195
196         //init each module, should be put together..
197         A_PRINTF("ALLOCRAM start 0x%x size %d\n", ALLOCRAM_START, ALLOCRAM_SIZE);
198         A_ALLOCRAM_INIT(ALLOCRAM_START, ALLOCRAM_SIZE);
199
200         if( hostif == HIF_USB ) {
201                 _indir_tbl.hif._get_max_msg_len = _HIFusb_get_max_msg_len_patch;
202                 _indir_tbl.cmnos.usb._usb_reg_out = usb_reg_out_patch;
203                 _indir_tbl.hif._isr_handler = _HIFusb_isr_handler_patch;
204                 _indir_tbl.cmnos.usb._usb_set_configuration = bSet_configuration_patch;
205                 _indir_tbl.cmnos.usb._usb_status_in = usb_status_in_patch;
206                 _indir_tbl.cmnos.usb._usb_get_descriptor = bGet_descriptor_patch;
207                 _indir_tbl.cmnos.usb._usb_standard_cmd = bStandardCommand_patch;
208                 _indir_tbl.usbfifo_api._init = _fw_usbfifo_init;
209
210 #if defined(PROJECT_MAGPIE)
211                 _indir_tbl.cmnos.usb._usb_power_off = zfTurnOffPower_patch;
212                 _indir_tbl.cmnos.usb._usb_reset_fifo = zfResetUSBFIFO_patch;
213                 _indir_tbl.hif._start = _HIFusb_start_patch;
214                 _indir_tbl.htc._HTC_MsgRecvHandler = HTCMsgRecvHandler_patch;
215                 _indir_tbl.htc._HTC_ControlSvcProcessMsg = HTCControlSvcProcessMsg_patch;
216 #endif
217
218                 if (!(ioread8_usb(ZM_MAIN_CTRL_OFFSET) & BIT6))
219                         vUSBFIFO_EP6Cfg_FS_patch();
220
221 #ifdef FUSION_USB_ENABLE_TX_STREAM
222                 // For K2, enable tx stream mode
223                 A_PRINTF("Enable Tx Stream mode: 0x%x\r\n",
224                         ioread32_usb(ZM_SOC_USB_MODE_CTRL_OFFSET));
225
226                 /* Patch for K2 USB STREAM mode */
227                 /* disable down stream DMA mode */
228                 io32_rmw_usb(ZM_SOC_USB_MODE_CTRL_OFFSET, BIT6, BIT0);
229 #if SYSTEM_MODULE_HP_EP5
230                 io32_set_usb(ZM_SOC_USB_MODE_CTRL_OFFSET, BIT8);
231 #endif
232
233 #if SYSTEM_MODULE_HP_EP6
234                 io32_set_usb(ZM_SOC_USB_MODE_CTRL_OFFSET, BIT9);
235 #endif
236                 /* enable down stream DMA mode */
237                 io32_set_usb(ZM_SOC_USB_MODE_CTRL_OFFSET, BIT0);
238 #endif
239
240 #ifdef FUSION_USB_ENABLE_RX_STREAM
241                 /* Patch for K2 USB STREAM mode */
242                 /* disable upstream DMA mode and enable upstream stream mode */
243                 io32_clr_usb(ZM_SOC_USB_MODE_CTRL_OFFSET, BIT1 | BIT3);
244
245                 /* K2, Set maximum IN transfer to 8K */
246                 io32_rmw_usb(ZM_SOC_USB_MODE_CTRL_OFFSET, 0x20, 0x30);
247
248                 /* enable upstream DMA mode */
249                 io32_set_usb(ZM_SOC_USB_MODE_CTRL_OFFSET, BIT1);
250
251                 /* set stream mode timeout critirea */
252                 iowrite32_usb(ZM_SOC_USB_TIME_CTRL_OFFSET, 0xa0);
253 #if defined(PROJECT_K2)
254                 /*0x10004020 is vaild in k2 but could be invaild in other chip*/
255                 if ((ioread32(0x10004020) & 0x2000) != 0) {
256                         /* disable stream mode for AR9270 */
257                         iowrite32_usb(ZM_SOC_USB_MAX_AGGREGATE_OFFSET, 0);
258                 } else {
259                         /* enable stream mode for AR9271 */
260                         iowrite32_usb(ZM_SOC_USB_MAX_AGGREGATE_OFFSET, 9);
261                 }
262 #else
263                 iowrite32_usb(ZM_SOC_USB_MAX_AGGREGATE_OFFSET, 9);
264 #endif
265 #endif
266         }
267 #if defined(PROJECT_MAGPIE) && !defined(ROM_VER_1_1)
268         else if (hostif == HIF_PCI )
269                 hif_pci_patch_install(&_indir_tbl.hif);
270 #endif
271         A_PRINTF("USB mode: 0x%x\r\n", ioread32_usb(0x100));
272
273         // patch the clock function
274         if(1) {
275                 _indir_tbl.cmnos.clock._clock_init = cmnos_clock_init_patch;
276                 _indir_tbl.cmnos.clock._refclk_speed_get = cmnos_refclk_speed_get_patch;
277                 _indir_tbl.cmnos.clock._delay_us = cmnos_delay_us_patch;
278                 _indir_tbl.cmnos.clock._clock_tick = cmnos_tick_patch;
279                 _indir_tbl.cmnos.clock._milliseconds = cmnos_milliseconds_patch;
280
281                 //default clock, setup initial variable, SYSTEM_FREQ=40
282                 A_CLOCK_INIT(SYSTEM_FREQ);
283         }
284
285         Magpie_init();
286
287 #if MAGPIE_ENABLE_WLAN == 1
288         io32_clr(MAGPIE_REG_RST_RESET_ADDR, BIT10 | BIT8 | BIT7 | BIT6);
289 #if defined(PROJECT_MAGPIE)
290         io32_set(MAGPIE_REG_AHB_ARB_ADDR, BIT1);
291 #endif
292
293         wlan_pci_module_init();
294         wlan_pci_probe();
295 #endif
296
297
298         A_PRINTF("Tgt running\n\r");
299
300 #if defined(PROJECT_MAGPIE)
301         if(1) {
302                 A_PRINTF("======= Apply MISC Assert patch\n\r");
303                 _assfail_ori =  _indir_tbl.cmnos.misc._assfail;
304                 _indir_tbl.cmnos.misc._assfail = exception_reset;
305         }
306
307         change_magpie_clk();
308 #endif
309         wlan_task(); //never return
310 }