hif/usb_api: remove dup code - usb_reg_out_patch
[open-ath9k-htc-firmware.git] / target_firmware / magpie_fw_dev / target / rompatch / usb_api_patch.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 "usb_defs.h"
36 #include "usb_type.h"
37 #include "usb_pre.h"
38 #include "usb_extr.h"
39 #include "usb_std.h"
40 #include "reg_defs.h"
41 #include "athos_api.h"
42 #include "usbfifo_api.h"
43
44 #include "sys_cfg.h"
45
46 #define measure_time 0
47 #define measure_time_pll 10000000
48
49 typedef void (* USBFIFO_recv_command)(VBUF *cmd);
50
51 extern Action eUsbCxFinishAction;
52 extern CommandType eUsbCxCommand;
53 extern BOOLEAN UsbChirpFinish;
54 extern USB_FIFO_CONFIG usbFifoConf;
55 extern uint16_t *pu8DescriptorEX;
56 extern uint16_t u16TxRxCounter;
57
58 USBFIFO_recv_command m_origUsbfifoRecvCmd = NULL;
59
60 void zfTurnOffPower_patch(void);
61
62 static void _fw_reset_dma_fifo();
63 static void _fw_restore_dma_fifo();
64 static void _fw_power_on();
65 static void _fw_power_off();
66
67 BOOLEAN bEepromExist = TRUE;
68 BOOLEAN bJumptoFlash = FALSE;
69
70 void _fw_usbfifo_recv_command(VBUF *buf)
71 {
72         A_UINT8 *cmd_data;
73         A_UINT32 tmp;
74
75         cmd_data = (A_UINT8 *)(buf->desc_list->buf_addr + buf->desc_list->data_offset);
76         tmp = *((A_UINT32 *)cmd_data);
77         if ( tmp == 0xFFFFFFFF ) {      
78                 // reset usb/wlan dma
79                 _fw_reset_dma_fifo();
80
81                 // restore gpio setting and usb/wlan dma state
82                 _fw_restore_dma_fifo();
83
84                 // set clock to bypass mode - 40Mhz from XTAL 
85                 HAL_WORD_REG_WRITE(MAGPIE_REG_CPU_PLL_BYPASS_ADDR, (BIT0|BIT4));
86
87                 A_DELAY_USECS(100); // wait for stable
88
89                 HAL_WORD_REG_WRITE(MAGPIE_REG_CPU_PLL_ADDR, (BIT16));
90
91                 A_DELAY_USECS(100); // wait for stable
92                 A_UART_HWINIT((40*1000*1000), 19200);
93
94                 A_CLOCK_INIT(40);
95
96                 if (!bEepromExist) { //jump to flash boot (eeprom data in flash)
97                         bJumptoFlash = TRUE;
98                         A_PRINTF("Jump to Flash BOOT\n");
99                         app_start();
100                 }else{
101                         A_PRINTF("receive the suspend command...\n");
102                         // reboot.....
103                         A_USB_JUMP_BOOT();              
104                 }
105
106         } else {
107                 m_origUsbfifoRecvCmd(buf);
108         }
109 }
110
111 void _fw_usbfifo_init(USB_FIFO_CONFIG *pConfig)
112 {
113         m_origUsbfifoRecvCmd = pConfig->recv_command;
114
115         usbFifoConf.get_command_buf = pConfig->get_command_buf;
116         usbFifoConf.recv_command    = _fw_usbfifo_recv_command;
117         usbFifoConf.get_event_buf   = pConfig->get_event_buf;
118         usbFifoConf.send_event_done = pConfig->send_event_done;
119 }
120
121 /* 
122  *  -- usb1.1 ep6 fix --
123  */
124 extern uint16_t       u8UsbConfigValue;
125 extern uint16_t       u8UsbInterfaceValue;
126 extern uint16_t       u8UsbInterfaceAlternateSetting;
127 extern SetupPacket    ControlCmd;
128 extern void vUsbClrEPx(void);
129
130 #undef FS_C1_I0_A0_EP_NUMBER
131 #define FS_C1_I0_A0_EP_NUMBER 6
132
133 #define FS_C1_I0_A0_EP6_BLKSIZE    BLK512BYTE
134 #define FS_C1_I0_A0_EP6_BLKNO      DOUBLE_BLK
135 #define FS_C1_I0_A0_EP6_DIRECTION  DIRECTION_OUT
136 #define FS_C1_I0_A0_EP6_TYPE       TF_TYPE_BULK
137 #define FS_C1_I0_A0_EP6_MAX_PACKET 0x0040
138 #define FS_C1_I0_A0_EP6_bInterval  00
139
140 // EP6
141 #define FS_C1_I0_A0_EP6_FIFO_START  (FS_C1_I0_A0_EP5_FIFO_START + FS_C1_I0_A0_EP5_FIFO_NO)
142 #define FS_C1_I0_A0_EP6_FIFO_NO     (FS_C1_I0_A0_EP6_BLKNO * FS_C1_I0_A0_EP6_BLKSIZE)
143 #define FS_C1_I0_A0_EP6_FIFO_CONFIG (0x80 | ((FS_C1_I0_A0_EP6_BLKSIZE - 1) << 4) | ((FS_C1_I0_A0_EP6_BLKNO - 1) << 2) | FS_C1_I0_A0_EP6_TYPE)
144 #define FS_C1_I0_A0_EP6_FIFO_MAP    (((1 - FS_C1_I0_A0_EP6_DIRECTION) << 4) | EP6)
145 #define FS_C1_I0_A0_EP6_MAP         (FS_C1_I0_A0_EP6_FIFO_START |   (FS_C1_I0_A0_EP6_FIFO_START << 4)   | (MASK_F0 >> (4*FS_C1_I0_A0_EP6_DIRECTION)))
146
147
148 #define CMD_PCI_RC_RESET_ON() HAL_WORD_REG_WRITE(MAGPIE_REG_RST_RESET_ADDR, \
149                          (HAL_WORD_REG_READ(MAGPIE_REG_RST_RESET_ADDR)| \
150                           (PCI_RC_PHY_SHIFT_RESET_BIT|PCI_RC_PLL_RESET_BIT|PCI_RC_PHY_RESET_BIT|PCI_RC_RESET_BIT)))
151
152 void vUSBFIFO_EP6Cfg_FS_patch(void)
153 {
154 #if (FS_C1_I0_A0_EP_NUMBER >= 6)
155         int i;
156
157         //EP0X06
158         mUsbEPMap(EP6, FS_C1_I0_A0_EP6_MAP);
159         mUsbFIFOMap(FS_C1_I0_A0_EP6_FIFO_START, FS_C1_I0_A0_EP6_FIFO_MAP);
160         mUsbFIFOConfig(FS_C1_I0_A0_EP6_FIFO_START, FS_C1_I0_A0_EP6_FIFO_CONFIG);
161
162         for(i = FS_C1_I0_A0_EP6_FIFO_START + 1 ;
163             i < FS_C1_I0_A0_EP6_FIFO_START + FS_C1_I0_A0_EP6_FIFO_NO ; i ++)
164         {
165                 mUsbFIFOConfig(i, (FS_C1_I0_A0_EP6_FIFO_CONFIG & (~BIT7)) );
166         }
167
168         mUsbEPMxPtSzHigh(EP6, FS_C1_I0_A0_EP6_DIRECTION, (FS_C1_I0_A0_EP6_MAX_PACKET & 0x7ff));
169         mUsbEPMxPtSzLow(EP6, FS_C1_I0_A0_EP6_DIRECTION, (FS_C1_I0_A0_EP6_MAX_PACKET & 0x7ff));
170         mUsbEPinHighBandSet(EP6 , FS_C1_I0_A0_EP6_DIRECTION, FS_C1_I0_A0_EP6_MAX_PACKET);
171 #endif
172 }
173
174 void vUsbFIFO_EPxCfg_FS_patch(void)
175 {
176         switch (u8UsbConfigValue)
177         {
178 #if (FS_CONFIGURATION_NUMBER >= 1)
179                 // Configuration 0X01
180         case 0X01:
181                 switch (u8UsbInterfaceValue)
182                 {
183 #if (FS_C1_INTERFACE_NUMBER >= 1)
184                         // Interface 0
185                 case 0:
186                         switch (u8UsbInterfaceAlternateSetting)
187                         {
188
189 #if (FS_C1_I0_ALT_NUMBER >= 1)
190                                 // AlternateSetting 0
191                         case 0:
192
193                                 // snapped....
194
195                                 // patch up this ep6_fs config
196                                 vUSBFIFO_EP6Cfg_FS_patch();
197
198                                 break;
199
200 #endif
201                         default:
202                                 break;
203                         }
204                         break;
205 #endif
206                 default:
207                         break;
208                 }
209                 break;
210 #endif
211         default:
212                 break;
213         }
214         //mCHECK_STACK();
215 }
216
217
218 BOOLEAN bSet_configuration_patch(void)
219 {
220         bSet_configuration();
221
222         if (mLOW_BYTE(mDEV_REQ_VALUE()) == 0)
223         {
224                 // snapped....
225                 ;
226         }
227         else
228         {
229                 if (mUsbHighSpeedST())                  // First judge HS or FS??
230                 {
231                         // snapped....
232                         ;
233                 }
234                 else
235                 {
236                         // snapped....
237                         vUsbFIFO_EPxCfg_FS_patch();
238                 }
239
240                 // snapped....
241         }
242
243         eUsbCxFinishAction = ACT_DONE;
244         return TRUE;
245 }
246
247
248 /*
249  * -- support more than 64 bytes command on ep3 -- 
250  */
251 void vUsb_Status_In_patch(void)
252 {
253         uint16_t count;
254         uint16_t remainder;
255         u16_t RegBufLen;
256         BOOLEAN cmdEnd = FALSE;
257
258         static u16_t mBufLen;
259         static VBUF *evntbuf = NULL;
260         static volatile u32_t *regaddr;
261         static BOOLEAN cmd_is_new = TRUE;
262
263         if( cmd_is_new )
264         {
265                 evntbuf = usbFifoConf.get_event_buf();
266                 if ( evntbuf != NULL )
267                 {
268                         regaddr = (u32_t *)VBUF_GET_DATA_ADDR(evntbuf);
269                         mBufLen = evntbuf->buf_length;
270                 }
271                 else
272                 {
273                         mUSB_STATUS_IN_INT_DISABLE();
274                         goto ERR_DONE;
275                 }
276
277                 cmd_is_new = FALSE;
278         }
279
280         if( mBufLen > bUSB_EP_MAX_PKT_SIZE_64 ) {
281                 RegBufLen = bUSB_EP_MAX_PKT_SIZE_64;
282                 mBufLen -= bUSB_EP_MAX_PKT_SIZE_64;
283         }
284         // TODO: 64 byes... controller supposed will take care of zero-length?
285         else {
286                 RegBufLen = mBufLen;
287                 cmdEnd = TRUE;
288         }
289
290         /* INT use EP3 */
291         for(count = 0; count < (RegBufLen / 4); count++)
292         {
293                 USB_WORD_REG_WRITE(ZM_EP3_DATA_OFFSET, *regaddr);
294                 regaddr++;
295         }
296
297         remainder = RegBufLen % 4;
298
299         if (remainder)
300         {
301                 switch(remainder)
302                 {
303                 case 3:
304                         USB_WORD_REG_WRITE(ZM_CBUS_FIFO_SIZE_OFFSET, 0x7);
305                         break;
306                 case 2:
307                         USB_WORD_REG_WRITE(ZM_CBUS_FIFO_SIZE_OFFSET, 0x3);
308                         break;
309                 case 1:
310                         USB_WORD_REG_WRITE(ZM_CBUS_FIFO_SIZE_OFFSET, 0x1);
311                         break;
312                 }
313
314                 USB_WORD_REG_WRITE(ZM_EP3_DATA_OFFSET, *regaddr);
315
316                 // Restore CBus FIFO size to word size            
317                 USB_WORD_REG_WRITE(ZM_CBUS_FIFO_SIZE_OFFSET, 0xF);
318         }
319
320         mUSB_EP3_XFER_DONE();
321
322         if ( evntbuf != NULL && cmdEnd )
323         {
324                 usbFifoConf.send_event_done(evntbuf);
325                 cmd_is_new = TRUE;
326         }
327
328 ERR_DONE:
329         ;
330 }
331
332
333 #define PCI_RC_RESET_BIT                            BIT6
334 #define PCI_RC_PHY_RESET_BIT                        BIT7
335 #define PCI_RC_PLL_RESET_BIT                        BIT8
336 #define PCI_RC_PHY_SHIFT_RESET_BIT                  BIT10
337
338
339 /*
340  * -- urn_off_merlin --
341  * . values suggested from Lalit
342  *
343  */
344 static void turn_off_merlin()
345 {
346         volatile uint32_t default_data[9];
347         uint32_t i=0;
348
349         if(1)
350         {
351                 A_PRINTF("turn_off_merlin_ep_start ......\n");
352                 A_DELAY_USECS(measure_time);
353                 default_data[0] = 0x9248fd00;
354                 default_data[1] = 0x24924924;
355                 default_data[2] = 0xa8000019;
356                 default_data[3] = 0x17160820;
357                 default_data[4] = 0x25980560;
358                 default_data[5] = 0xc1c00000;
359                 default_data[6] = 0x1aaabe40;
360                 default_data[7] = 0xbe105554;
361                 default_data[8] = 0x00043007;
362         
363                 for(i=0; i<9; i++)
364                 {
365                         A_DELAY_USECS(10);
366         
367                         HAL_WORD_REG_WRITE( 0x10ff4040, default_data[i]); 
368                 }
369                 A_DELAY_USECS(10);
370                 HAL_WORD_REG_WRITE(0x10ff4044, BIT0);
371                 A_PRINTF("turn_off_merlin_ep_end ......\n");
372         }
373 }
374
375 /*
376  * -- turn_off_phy --
377  *
378  * . write shift register to both pcie ep and rc
379  * . 
380  */
381
382 static void turn_off_phy()
383 {
384
385         volatile uint32_t default_data[9];
386         volatile uint32_t read_data = 0;
387         uint32_t i=0;
388
389         default_data[0] = 0x9248fd00;
390         default_data[1] = 0x24924924;
391         default_data[2] = 0xa8000019;
392         default_data[3] = 0x17160820;
393         default_data[4] = 0x25980560;
394         default_data[5] = 0xc1c00000;
395         default_data[6] = 0x1aaabe40;
396         default_data[7] = 0xbe105554;
397         default_data[8] = 0x00043007;
398
399         for(i=0; i<9; i++)
400         {
401                 // check for the done bit to be set 
402
403                 while (1)
404                 {
405                         read_data=HAL_WORD_REG_READ(0x40028);
406                         if( read_data & BIT31 )
407                                 break;
408                 }
409         
410                 A_DELAY_USECS(1);
411     
412                 HAL_WORD_REG_WRITE( 0x40024, default_data[i]); 
413         }
414         HAL_WORD_REG_WRITE(0x40028, BIT0);
415 }
416
417 static void turn_off_phy_rc()
418 {
419     
420         volatile uint32_t default_data[9];
421         volatile uint32_t read_data = 0;
422         uint32_t i=0;
423     
424         A_PRINTF("turn_off_phy_rc\n");
425     
426         default_data[0] = 0x9248fd00;
427         default_data[1] = 0x24924924;
428         default_data[2] = 0xa8000019;
429         default_data[3] = 0x13160820;//PwdClk1MHz=0
430         default_data[4] = 0x25980560;
431         default_data[5] = 0xc1c00000;
432         default_data[6] = 0x1aaabe40;
433         default_data[7] = 0xbe105554;
434         default_data[8] = 0x00043007;
435         
436         for(i=0; i<9; i++)
437         {
438                 // check for the done bit to be set 
439      
440                 while (1)
441                 {
442                         read_data=HAL_WORD_REG_READ(0x40028);
443                         if( read_data & BIT31 )
444                                 break;
445                 }
446
447                 A_DELAY_USECS(1);
448
449                 HAL_WORD_REG_WRITE( 0x40024, default_data[i]); 
450         }
451         HAL_WORD_REG_WRITE(0x40028, BIT0);
452 }
453
454 volatile uint32_t gpio_func = 0x0;
455 volatile uint32_t gpio = 0x0;
456
457 /*
458  * -- patch zfTurnOffPower --
459  *
460  * . set suspend counter to non-zero value
461  * . 
462  */
463 void zfTurnOffPower_patch(void)
464 {
465         A_PRINTF("+++ goto suspend ......\n");
466
467         // setting the go suspend here, power down right away...
468         HAL_WORD_REG_WRITE(0x10000, HAL_WORD_REG_READ(0x10000)|(0x8));
469
470         A_DELAY_USECS(100);
471
472         // TURN OFF ETH PLL
473         _fw_power_off();
474
475         //32clk wait for External ETH PLL stable
476         A_DELAY_USECS(100);
477     
478         HAL_WORD_REG_WRITE(0x52000, 0x70303);//read back 0x703f7
479         HAL_WORD_REG_WRITE(0x52008, 0x0e91c);//read back 0x1e948    
480     
481         HAL_WORD_REG_WRITE(MAGPIE_REG_SUSPEND_ENABLE_ADDR,
482                            (HAL_WORD_REG_READ(MAGPIE_REG_SUSPEND_ENABLE_ADDR)|(BIT0))); //0x56030
483         // wake up, and turn on cpu, eth, pcie and usb pll 
484         _fw_power_on();
485         // restore gpio and other settings
486         _fw_restore_dma_fifo();
487
488         // clear suspend..................
489         HAL_WORD_REG_WRITE(MAGPIE_REG_SUSPEND_ENABLE_ADDR,
490                            (HAL_WORD_REG_READ(MAGPIE_REG_SUSPEND_ENABLE_ADDR)&(~BIT0)));
491         HAL_WORD_REG_WRITE(0x52028, HAL_WORD_REG_READ(0x52028)&(~(BIT8|BIT12|BIT16)));
492 }
493
494 /*
495  * -- patch zfResetUSBFIFO_patch --
496  *
497  * . clear ep3/ep4 fifo
498  * . set suspend magic pattern
499  * . reset pcie ep phy
500  * . reset pcie rc phy
501  * . turn off pcie pll
502  * . reset all pcie/gmac related registers
503  * . reset usb dma
504  */
505 void zfResetUSBFIFO_patch(void)
506 {
507         A_PRINTF("0x9808  0x%x ......\n", HAL_WORD_REG_READ(0x10ff9808));
508         A_PRINTF("0x7890  0x%x ......\n", HAL_WORD_REG_READ(0x10ff7890));
509         A_PRINTF("0x7890  0x%x ......\n", HAL_WORD_REG_READ(0x10ff7890));
510         A_PRINTF("0x4088  0x%x ......\n", HAL_WORD_REG_READ(0x10ff4088));
511         _fw_reset_dma_fifo();
512 }
513
514 static void _fw_reset_dma_fifo()
515 {
516         HAL_BYTE_REG_WRITE(0x100ae, (HAL_BYTE_REG_READ(0x100ae)|0x10));
517         HAL_BYTE_REG_WRITE(0x100ae, (HAL_BYTE_REG_READ(0x100af)|0x10));
518         A_PRINTF("_fw_reset_dma_fifo\n");
519
520         // disable ep3 int enable, so that resume back won't send wdt magic pattern out!!!
521         mUSB_STATUS_IN_INT_DISABLE();
522
523         // update magic pattern to indicate this is a suspend
524         HAL_WORD_REG_WRITE(WATCH_DOG_MAGIC_PATTERN_ADDR, SUS_MAGIC_PATTERN);
525
526         A_PRINTF("org 0x4048  0x%x ......\n", HAL_WORD_REG_READ(0x10ff4048));
527         A_PRINTF("org 0x404C  0x%x ......\n", HAL_WORD_REG_READ(0x10ff404C));
528         A_PRINTF("org 0x4088  0x%x ......\n", HAL_WORD_REG_READ(0x10ff4088));
529
530         HAL_WORD_REG_WRITE(0x10ff4088,0xaaa6a);//1010.1010.1010.0110.1010 for UB94
531         HAL_WORD_REG_WRITE(0x10ff404C,0x0);
532
533         A_DELAY_USECS(1000);
534         A_PRINTF("0x4048  0x%x ......\n", HAL_WORD_REG_READ(0x10ff4048));
535         A_PRINTF("0x404C  0x%x ......\n", HAL_WORD_REG_READ(0x10ff404C));
536         A_PRINTF("0x4088  0x%x ......\n", HAL_WORD_REG_READ(0x10ff4088));
537          
538         // turn off merlin
539         turn_off_merlin();
540         // pcie ep
541         A_PRINTF("turn_off_magpie_ep_start ......\n");
542         A_DELAY_USECS(measure_time);
543         HAL_WORD_REG_WRITE( 0x40040, (HAL_WORD_REG_READ(0x40040)|BIT0|(1<<1)));
544         turn_off_phy();
545         HAL_WORD_REG_WRITE( 0x40040, (HAL_WORD_REG_READ(0x40040)&~(BIT0|(1<<1))));
546         A_PRINTF("turn_off_magpie_ep_end ......\n");
547
548         // pcie rc 
549         A_PRINTF("turn_off_magpie_rc_start ......\n");
550         A_DELAY_USECS(measure_time);
551         HAL_WORD_REG_WRITE( 0x40040, (HAL_WORD_REG_READ(0x40040)&(~BIT0)));
552         turn_off_phy_rc();
553         A_PRINTF("turn_off_magpie_rc_end ......down\n");
554         A_DELAY_USECS(measure_time);
555
556         A_PRINTF("0x4001C  %p ......\n", HAL_WORD_REG_READ(0x4001c)); 
557         A_PRINTF("0x40040  %p ......\n", HAL_WORD_REG_READ(0x40040));
558     
559         // turn off pcie_pll - power down (bit16)
560         A_PRINTF(" before pwd PCIE PLL CFG:0x5601C  %p ......\n", HAL_WORD_REG_READ(0x5601C));
561         HAL_WORD_REG_WRITE(0x5601C, (HAL_WORD_REG_READ(0x5601C)|(BIT18)));   
562         A_PRINTF(" after pwd PCIE PLL CFG:0x5601C  %p ......\n", HAL_WORD_REG_READ(0x5601C));
563
564         /* set everything to reset state?, requested by Oligo */
565         HAL_WORD_REG_WRITE(0x50010, HAL_WORD_REG_READ(0x50010)|(BIT13|BIT12|BIT11|BIT9|BIT7|BIT6));
566
567         HAL_WORD_REG_WRITE(0x5C000, 0);
568
569         A_DELAY_USECS(10);
570
571         // reset usb DMA controller
572         HAL_WORD_REG_WRITE((USB_CTRL_BASE_ADDRESS+0x118), 0x0);
573
574         HAL_WORD_REG_WRITE(0x50010, (HAL_WORD_REG_READ(0x50010)|(BIT4)));
575         A_DELAY_USECS(5);
576         HAL_WORD_REG_WRITE(0x50010, (HAL_WORD_REG_READ(0x50010)&(~BIT4)));
577
578
579         HAL_WORD_REG_WRITE((USB_CTRL_BASE_ADDRESS+0x118), 0x1);
580 }
581
582 static void _fw_power_off()
583 {
584         /*
585          *  1. set CPU bypass
586          *  2. turn off CPU PLL
587          *  3. turn off ETH PLL
588          *  4. disable ETH PLL bypass and update
589          *  4.1 set suspend timeout 
590          *  5. set SUSPEND_ENABLE
591          */
592
593         HAL_WORD_REG_WRITE(MAGPIE_REG_CPU_PLL_BYPASS_ADDR, (BIT0|BIT4)); //0x56004
594
595         A_DELAY_USECS(100); // wait for stable
596
597         HAL_WORD_REG_WRITE(MAGPIE_REG_CPU_PLL_ADDR, (BIT16));//0x56000
598
599         A_DELAY_USECS(100); // wait for stable
600
601         A_UART_HWINIT((40*1000*1000), 19200);
602         A_CLOCK_INIT(40);
603
604         HAL_WORD_REG_WRITE(MAGPIE_REG_ETH_PLL_ADDR,
605                            (HAL_WORD_REG_READ(MAGPIE_REG_ETH_PLL_ADDR)|(BIT16)));   //0x5600c
606
607         HAL_WORD_REG_WRITE(MAGPIE_REG_ETH_PLL_BYPASS_ADDR,
608                            (HAL_WORD_REG_READ(MAGPIE_REG_ETH_PLL_BYPASS_ADDR)|(BIT4|BIT0))); //0x56010
609
610         HAL_WORD_REG_WRITE(MAGPIE_REG_SUSPEND_ENABLE_ADDR,
611                            (HAL_WORD_REG_READ(MAGPIE_REG_SUSPEND_ENABLE_ADDR)|(0x10<<8))); //0x56030
612 }
613
614 static void _fw_power_on()
615
616     /*
617      *  1. turn on CPU PLL
618      *  2. disable CPU bypass
619      *  3. turn on ETH PLL
620      *  4. disable ETH PLL bypass and update
621      *  5. turn on pcie pll
622      */    
623
624         HAL_WORD_REG_WRITE(MAGPIE_REG_ETH_PLL_ADDR,
625                            (HAL_WORD_REG_READ(MAGPIE_REG_ETH_PLL_ADDR)&(~BIT16)));
626
627         // deassert eth_pll bypass mode and trigger update bit
628         HAL_WORD_REG_WRITE(MAGPIE_REG_ETH_PLL_BYPASS_ADDR,
629                            (HAL_WORD_REG_READ(MAGPIE_REG_ETH_PLL_BYPASS_ADDR)&(~(BIT4|BIT0))));
630 }
631
632 static void _fw_restore_dma_fifo(void)
633 {
634         HAL_WORD_REG_WRITE(0x5601C, (HAL_WORD_REG_READ(0x5601C)&(~(BIT18))));
635     
636         // reset pcie_rc shift 
637         HAL_WORD_REG_WRITE(0x50010, (HAL_WORD_REG_READ(0x50010)&(~(BIT10|BIT8|BIT7))));
638         A_DELAY_USECS(1);
639         HAL_WORD_REG_WRITE(0x50010, (HAL_WORD_REG_READ(0x50010)|(BIT10|BIT8|BIT7)));
640
641         // reset pci_rc phy
642         CMD_PCI_RC_RESET_ON();
643         A_DELAY_USECS(20);
644
645         // enable dma swap function
646         MAGPIE_REG_USB_RX0_SWAP_DATA = 0x1;
647         MAGPIE_REG_USB_TX0_SWAP_DATA = 0x1;
648         MAGPIE_REG_USB_RX1_SWAP_DATA = 0x1;
649         MAGPIE_REG_USB_RX2_SWAP_DATA = 0x1;
650 }
651
652 extern uint16_t *u8ConfigDescriptorEX;
653 extern uint16_t *pu8DescriptorEX;
654 extern uint16_t u16TxRxCounter;
655
656 extern uint16_t *u8UsbDeviceDescriptor;
657
658 extern BOOLEAN bGet_descriptor(void);
659
660 uint16_t ConfigDescriptorPatch[30];
661
662 uint16_t UsbDeviceDescriptorPatch[9];
663 #define BCD_DEVICE_OFFSET               6
664 #define BCD_DEVICE_FW_SIGNATURE         0xffff
665 #define VENDOR_ID_OFFSET                4
666 #define PRODUCT_ID_OFFSET               5
667
668 #define EP3_TRANSFER_TYPE_OFFSET    17
669 #define EP3_INT_INTERVAL            19
670 #define EP4_TRANSFER_TYPE_OFFSET    21
671 #define EP4_INT_INTERVAL            22
672
673
674
675  #define A_SFLASH_READ_4B(u32Data, start_addr) u32Data = *(uint32_t *)(0xf000000+start_addr);
676  #define FLASH_SIZE 0x800000 //8M
677  #define FLASH_USB_VENDOR_ID_OFFSET     0x86
678  #define FLASH_USB_PRODUCT_ID_OFFSET    0x87
679
680  // flash reserved size for saving eeprom data is 4K.
681  #define EE_DATA_RESERVED_LEN 0x1000 //4K
682
683 #define mLOW_MASK(u16)          ((uint8_t) ((u16) & mMASK(8)))
684 #define mHIGH_MASK(u16)         ((uint8_t) ((u16) & ~mMASK(8)))
685
686 /* (1234) -> 0034 */
687 //#define mLOW_BYTE(u16)          ((U_8)(u16))
688 #define mLOW_BYTE(u16)          mLOW_MASK(u16)
689 /* (1234) -> 0012 */
690 #define mHIGH_BYTE(u16)         ((uint8_t) (((uint16_t) (u16)) >> 8))
691
692 #define mLOW_WORD0(u32)         ((uint16_t) ((u32) & 0xFFFF))
693 #define mHIGH_WORD0(u32)        ((uint16_t) ((u32) >> 16))
694
695 /* (1234) -> 3412 */
696 #define mSWAP_BYTE(u16)         ((mLOW_MASK(u16) << 8) | mHIGH_BYTE(u16))
697  
698 BOOLEAN bGet_descriptor_patch(void)
699 {
700         if (mDEV_REQ_VALUE_HIGH() == 1)
701         {
702                 uint8_t *p = (uint8_t *)u8UsbDeviceDescriptor;
703                 uint32_t u32Tmp=0;
704                 /* Copy Usb Device Descriptor */
705                 ath_hal_memcpy(UsbDeviceDescriptorPatch, p, sizeof(UsbDeviceDescriptorPatch));
706
707                 UsbDeviceDescriptorPatch[BCD_DEVICE_OFFSET] =
708                         BCD_DEVICE_FW_SIGNATURE;
709
710                 /* Patch for custom id from flash */
711                 if (bEepromExist == FALSE) {
712                         A_SFLASH_READ_4B(u32Tmp, FLASH_SIZE -
713                                 EE_DATA_RESERVED_LEN + FLASH_USB_VENDOR_ID_OFFSET*2);
714                         UsbDeviceDescriptorPatch[VENDOR_ID_OFFSET] =
715                                 mSWAP_BYTE(mLOW_WORD0(u32Tmp));
716                         UsbDeviceDescriptorPatch[PRODUCT_ID_OFFSET] =
717                                 mSWAP_BYTE(mHIGH_WORD0(u32Tmp));
718                 }
719       
720                 pu8DescriptorEX = UsbDeviceDescriptorPatch;
721                 u16TxRxCounter = mTABLE_LEN(u8UsbDeviceDescriptor[0]);
722   
723                 if (u16TxRxCounter > mDEV_REQ_LENGTH())  
724                         u16TxRxCounter = mDEV_REQ_LENGTH();
725              
726                 A_USB_EP0_TX_DATA();
727            
728                 //u16TxRxCounter = 18;
729                 return TRUE;
730         }  
731         if (mDEV_REQ_VALUE_HIGH() == 2) {
732                 uint8_t *p = (uint8_t *)u8ConfigDescriptorEX;
733
734                 /* Copy ConfigDescriptor */
735                 ath_hal_memcpy(ConfigDescriptorPatch, p, sizeof(ConfigDescriptorPatch));
736
737                  /* place holder for EPx patches */
738
739                 switch (mDEV_REQ_VALUE_LOW())
740                 {
741                 case 0x00:      // configuration no: 0
742                         pu8DescriptorEX = ConfigDescriptorPatch;
743                         u16TxRxCounter = ConfigDescriptorPatch[1];
744                         //u16TxRxCounter = 46;
745                         break;
746                 default:
747                         return FALSE;
748                 }
749
750                 if (u16TxRxCounter > mDEV_REQ_LENGTH())
751                         u16TxRxCounter = mDEV_REQ_LENGTH();
752
753                 A_USB_EP0_TX_DATA();
754                 return TRUE;
755         }
756         else {
757                 return bGet_descriptor();
758         }
759 }
760
761 extern BOOLEAN bStandardCommand(void);
762
763 BOOLEAN bStandardCommand_patch(void)
764 {
765         if (mDEV_REQ_REQ() == USB_SET_CONFIGURATION) {
766                 A_USB_SET_CONFIG();
767
768 #if ENABLE_SWAP_DATA_MODE
769                 // SWAP FUNCTION should be enabled while DMA engine is not working,
770                 // the best place to enable it is before we trigger the DMA
771                 MAGPIE_REG_USB_RX0_SWAP_DATA = 0x1;
772                 MAGPIE_REG_USB_TX0_SWAP_DATA = 0x1;
773
774 #if SYSTEM_MODULE_HP_EP5
775                 MAGPIE_REG_USB_RX1_SWAP_DATA = 0x1;
776 #endif
777
778 #if SYSTEM_MODULE_HP_EP6
779                 MAGPIE_REG_USB_RX2_SWAP_DATA = 0x1;
780 #endif
781
782 #endif //ENABLE_SWAP_DATA_MODE
783                 return TRUE;
784         }
785         else {
786                 return bStandardCommand();
787         }
788 }