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