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