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.
41 #include "athos_api.h"
42 #include "usbfifo_api.h"
46 #define measure_time 0
47 #define measure_time_pll 10000000
49 typedef void (* USBFIFO_recv_command)(VBUF *cmd);
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;
58 USBFIFO_recv_command m_origUsbfifoRecvCmd = NULL;
60 void zfTurnOffPower_patch(void);
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();
67 BOOLEAN bEepromExist = TRUE;
68 BOOLEAN bJumptoFlash = FALSE;
70 void _fw_usbfifo_recv_command(VBUF *buf)
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 ) {
81 // restore gpio setting and usb/wlan dma state
82 _fw_restore_dma_fifo();
84 // set clock to bypass mode - 40Mhz from XTAL
85 HAL_WORD_REG_WRITE(MAGPIE_REG_CPU_PLL_BYPASS_ADDR, (BIT0|BIT4));
87 A_DELAY_USECS(100); // wait for stable
89 HAL_WORD_REG_WRITE(MAGPIE_REG_CPU_PLL_ADDR, (BIT16));
91 A_DELAY_USECS(100); // wait for stable
92 A_UART_HWINIT((40*1000*1000), 19200);
96 if (!bEepromExist) { //jump to flash boot (eeprom data in flash)
98 A_PRINTF("Jump to Flash BOOT\n");
101 A_PRINTF("receive the suspend command...\n");
107 m_origUsbfifoRecvCmd(buf);
111 void _fw_usbfifo_init(USB_FIFO_CONFIG *pConfig)
113 m_origUsbfifoRecvCmd = pConfig->recv_command;
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;
122 * -- support more than 64 bytes command on ep4 --
124 void vUsb_Reg_Out_patch(void)
129 static volatile uint32_t *regaddr;
130 static uint16_t cmdLen;
132 BOOLEAN cmd_is_last = FALSE;
133 static BOOLEAN cmd_is_new = TRUE;
135 // get the size of this transcation
136 usbfifolen = USB_BYTE_REG_READ(ZM_EP4_BYTE_COUNT_LOW_OFFSET);
138 // check is command is new
141 buf = usbFifoConf.get_command_buf();
147 // copy free, assignment buffer of the address
148 regaddr = (uint32_t *)buf->desc_list->buf_addr;
153 // just in case, suppose should not happen
157 // if size is smaller, this is the last command!
158 // zero-length supposed should be set through 0x27/bit7->0x19/bit4, not here
159 if( usbfifolen<64 ) {
163 // accumulate the size
164 cmdLen += usbfifolen;
166 // round it to alignment
168 usbfifolen = (usbfifolen >> 2) + 1;
170 usbfifolen = usbfifolen >> 2;
172 // retrieve the data from fifo
173 for(ii = 0; ii < usbfifolen; ii++)
175 ep4_data = USB_WORD_REG_READ(ZM_EP4_DATA_OFFSET); // read fifo data out
180 // if this is the last command, callback to HTC
183 buf->desc_list->next_desc = NULL;
184 buf->desc_list->data_offset = 0;
185 buf->desc_list->data_size = cmdLen;
186 buf->desc_list->control = 0;
187 buf->next_buf = NULL;
188 buf->buf_length = cmdLen;
190 usbFifoConf.recv_command(buf);
197 // we might get no command buffer here?
198 // but if we return here, the ep4 fifo will be lock out,
199 // so that we still read them out but just drop it ?
200 for(ii = 0; ii < usbfifolen; ii++)
202 ep4_data = USB_WORD_REG_READ(ZM_EP4_DATA_OFFSET); // read fifo data out
206 //mUSB_STATUS_IN_INT_ENABLE();
212 * -- usb1.1 ep6 fix --
214 extern uint16_t u8UsbConfigValue;
215 extern uint16_t u8UsbInterfaceValue;
216 extern uint16_t u8UsbInterfaceAlternateSetting;
217 extern SetupPacket ControlCmd;
218 extern void vUsbClrEPx(void);
220 #undef FS_C1_I0_A0_EP_NUMBER
221 #define FS_C1_I0_A0_EP_NUMBER 6
223 #define FS_C1_I0_A0_EP6_BLKSIZE BLK512BYTE
224 #define FS_C1_I0_A0_EP6_BLKNO DOUBLE_BLK
225 #define FS_C1_I0_A0_EP6_DIRECTION DIRECTION_OUT
226 #define FS_C1_I0_A0_EP6_TYPE TF_TYPE_BULK
227 #define FS_C1_I0_A0_EP6_MAX_PACKET 0x0040
228 #define FS_C1_I0_A0_EP6_bInterval 00
231 #define FS_C1_I0_A0_EP6_FIFO_START (FS_C1_I0_A0_EP5_FIFO_START + FS_C1_I0_A0_EP5_FIFO_NO)
232 #define FS_C1_I0_A0_EP6_FIFO_NO (FS_C1_I0_A0_EP6_BLKNO * FS_C1_I0_A0_EP6_BLKSIZE)
233 #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)
234 #define FS_C1_I0_A0_EP6_FIFO_MAP (((1 - FS_C1_I0_A0_EP6_DIRECTION) << 4) | EP6)
235 #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)))
238 #define CMD_PCI_RC_RESET_ON() HAL_WORD_REG_WRITE(MAGPIE_REG_RST_RESET_ADDR, \
239 (HAL_WORD_REG_READ(MAGPIE_REG_RST_RESET_ADDR)| \
240 (PCI_RC_PHY_SHIFT_RESET_BIT|PCI_RC_PLL_RESET_BIT|PCI_RC_PHY_RESET_BIT|PCI_RC_RESET_BIT)))
242 void vUSBFIFO_EP6Cfg_FS_patch(void)
244 #if (FS_C1_I0_A0_EP_NUMBER >= 6)
248 mUsbEPMap(EP6, FS_C1_I0_A0_EP6_MAP);
249 mUsbFIFOMap(FS_C1_I0_A0_EP6_FIFO_START, FS_C1_I0_A0_EP6_FIFO_MAP);
250 mUsbFIFOConfig(FS_C1_I0_A0_EP6_FIFO_START, FS_C1_I0_A0_EP6_FIFO_CONFIG);
252 for(i = FS_C1_I0_A0_EP6_FIFO_START + 1 ;
253 i < FS_C1_I0_A0_EP6_FIFO_START + FS_C1_I0_A0_EP6_FIFO_NO ; i ++)
255 mUsbFIFOConfig(i, (FS_C1_I0_A0_EP6_FIFO_CONFIG & (~BIT7)) );
258 mUsbEPMxPtSzHigh(EP6, FS_C1_I0_A0_EP6_DIRECTION, (FS_C1_I0_A0_EP6_MAX_PACKET & 0x7ff));
259 mUsbEPMxPtSzLow(EP6, FS_C1_I0_A0_EP6_DIRECTION, (FS_C1_I0_A0_EP6_MAX_PACKET & 0x7ff));
260 mUsbEPinHighBandSet(EP6 , FS_C1_I0_A0_EP6_DIRECTION, FS_C1_I0_A0_EP6_MAX_PACKET);
264 void vUsbFIFO_EPxCfg_FS_patch(void)
266 switch (u8UsbConfigValue)
268 #if (FS_CONFIGURATION_NUMBER >= 1)
269 // Configuration 0X01
271 switch (u8UsbInterfaceValue)
273 #if (FS_C1_INTERFACE_NUMBER >= 1)
276 switch (u8UsbInterfaceAlternateSetting)
279 #if (FS_C1_I0_ALT_NUMBER >= 1)
280 // AlternateSetting 0
285 // patch up this ep6_fs config
286 vUSBFIFO_EP6Cfg_FS_patch();
308 BOOLEAN bSet_configuration_patch(void)
310 bSet_configuration();
312 if (mLOW_BYTE(mDEV_REQ_VALUE()) == 0)
319 if (mUsbHighSpeedST()) // First judge HS or FS??
327 vUsbFIFO_EPxCfg_FS_patch();
333 eUsbCxFinishAction = ACT_DONE;
339 * -- support more than 64 bytes command on ep3 --
341 void vUsb_Status_In_patch(void)
346 BOOLEAN cmdEnd = FALSE;
348 static u16_t mBufLen;
349 static VBUF *evntbuf = NULL;
350 static volatile u32_t *regaddr;
351 static BOOLEAN cmd_is_new = TRUE;
355 evntbuf = usbFifoConf.get_event_buf();
356 if ( evntbuf != NULL )
358 regaddr = (u32_t *)VBUF_GET_DATA_ADDR(evntbuf);
359 mBufLen = evntbuf->buf_length;
363 mUSB_STATUS_IN_INT_DISABLE();
370 if( mBufLen > bUSB_EP_MAX_PKT_SIZE_64 ) {
371 RegBufLen = bUSB_EP_MAX_PKT_SIZE_64;
372 mBufLen -= bUSB_EP_MAX_PKT_SIZE_64;
374 // TODO: 64 byes... controller supposed will take care of zero-length?
381 for(count = 0; count < (RegBufLen / 4); count++)
383 USB_WORD_REG_WRITE(ZM_EP3_DATA_OFFSET, *regaddr);
387 remainder = RegBufLen % 4;
394 USB_WORD_REG_WRITE(ZM_CBUS_FIFO_SIZE_OFFSET, 0x7);
397 USB_WORD_REG_WRITE(ZM_CBUS_FIFO_SIZE_OFFSET, 0x3);
400 USB_WORD_REG_WRITE(ZM_CBUS_FIFO_SIZE_OFFSET, 0x1);
404 USB_WORD_REG_WRITE(ZM_EP3_DATA_OFFSET, *regaddr);
406 // Restore CBus FIFO size to word size
407 USB_WORD_REG_WRITE(ZM_CBUS_FIFO_SIZE_OFFSET, 0xF);
410 mUSB_EP3_XFER_DONE();
412 if ( evntbuf != NULL && cmdEnd )
414 usbFifoConf.send_event_done(evntbuf);
423 #define PCI_RC_RESET_BIT BIT6
424 #define PCI_RC_PHY_RESET_BIT BIT7
425 #define PCI_RC_PLL_RESET_BIT BIT8
426 #define PCI_RC_PHY_SHIFT_RESET_BIT BIT10
430 * -- urn_off_merlin --
431 * . values suggested from Lalit
434 static void turn_off_merlin()
436 volatile uint32_t default_data[9];
441 A_PRINTF("turn_off_merlin_ep_start ......\n");
442 A_DELAY_USECS(measure_time);
443 default_data[0] = 0x9248fd00;
444 default_data[1] = 0x24924924;
445 default_data[2] = 0xa8000019;
446 default_data[3] = 0x17160820;
447 default_data[4] = 0x25980560;
448 default_data[5] = 0xc1c00000;
449 default_data[6] = 0x1aaabe40;
450 default_data[7] = 0xbe105554;
451 default_data[8] = 0x00043007;
457 HAL_WORD_REG_WRITE( 0x10ff4040, default_data[i]);
460 HAL_WORD_REG_WRITE(0x10ff4044, BIT0);
461 A_PRINTF("turn_off_merlin_ep_end ......\n");
468 * . write shift register to both pcie ep and rc
472 static void turn_off_phy()
475 volatile uint32_t default_data[9];
476 volatile uint32_t read_data = 0;
479 default_data[0] = 0x9248fd00;
480 default_data[1] = 0x24924924;
481 default_data[2] = 0xa8000019;
482 default_data[3] = 0x17160820;
483 default_data[4] = 0x25980560;
484 default_data[5] = 0xc1c00000;
485 default_data[6] = 0x1aaabe40;
486 default_data[7] = 0xbe105554;
487 default_data[8] = 0x00043007;
491 // check for the done bit to be set
495 read_data=HAL_WORD_REG_READ(0x40028);
496 if( read_data & BIT31 )
502 HAL_WORD_REG_WRITE( 0x40024, default_data[i]);
504 HAL_WORD_REG_WRITE(0x40028, BIT0);
507 static void turn_off_phy_rc()
510 volatile uint32_t default_data[9];
511 volatile uint32_t read_data = 0;
514 A_PRINTF("turn_off_phy_rc\n");
516 default_data[0] = 0x9248fd00;
517 default_data[1] = 0x24924924;
518 default_data[2] = 0xa8000019;
519 default_data[3] = 0x13160820;//PwdClk1MHz=0
520 default_data[4] = 0x25980560;
521 default_data[5] = 0xc1c00000;
522 default_data[6] = 0x1aaabe40;
523 default_data[7] = 0xbe105554;
524 default_data[8] = 0x00043007;
528 // check for the done bit to be set
532 read_data=HAL_WORD_REG_READ(0x40028);
533 if( read_data & BIT31 )
539 HAL_WORD_REG_WRITE( 0x40024, default_data[i]);
541 HAL_WORD_REG_WRITE(0x40028, BIT0);
544 volatile uint32_t gpio_func = 0x0;
545 volatile uint32_t gpio = 0x0;
548 * -- patch zfTurnOffPower --
550 * . set suspend counter to non-zero value
553 void zfTurnOffPower_patch(void)
555 A_PRINTF("+++ goto suspend ......\n");
557 // setting the go suspend here, power down right away...
558 HAL_WORD_REG_WRITE(0x10000, HAL_WORD_REG_READ(0x10000)|(0x8));
565 //32clk wait for External ETH PLL stable
568 HAL_WORD_REG_WRITE(0x52000, 0x70303);//read back 0x703f7
569 HAL_WORD_REG_WRITE(0x52008, 0x0e91c);//read back 0x1e948
571 HAL_WORD_REG_WRITE(MAGPIE_REG_SUSPEND_ENABLE_ADDR,
572 (HAL_WORD_REG_READ(MAGPIE_REG_SUSPEND_ENABLE_ADDR)|(BIT0))); //0x56030
573 // wake up, and turn on cpu, eth, pcie and usb pll
575 // restore gpio and other settings
576 _fw_restore_dma_fifo();
578 // clear suspend..................
579 HAL_WORD_REG_WRITE(MAGPIE_REG_SUSPEND_ENABLE_ADDR,
580 (HAL_WORD_REG_READ(MAGPIE_REG_SUSPEND_ENABLE_ADDR)&(~BIT0)));
581 HAL_WORD_REG_WRITE(0x52028, HAL_WORD_REG_READ(0x52028)&(~(BIT8|BIT12|BIT16)));
585 * -- patch zfResetUSBFIFO_patch --
587 * . clear ep3/ep4 fifo
588 * . set suspend magic pattern
589 * . reset pcie ep phy
590 * . reset pcie rc phy
591 * . turn off pcie pll
592 * . reset all pcie/gmac related registers
595 void zfResetUSBFIFO_patch(void)
597 A_PRINTF("0x9808 0x%x ......\n", HAL_WORD_REG_READ(0x10ff9808));
598 A_PRINTF("0x7890 0x%x ......\n", HAL_WORD_REG_READ(0x10ff7890));
599 A_PRINTF("0x7890 0x%x ......\n", HAL_WORD_REG_READ(0x10ff7890));
600 A_PRINTF("0x4088 0x%x ......\n", HAL_WORD_REG_READ(0x10ff4088));
601 _fw_reset_dma_fifo();
604 static void _fw_reset_dma_fifo()
606 HAL_BYTE_REG_WRITE(0x100ae, (HAL_BYTE_REG_READ(0x100ae)|0x10));
607 HAL_BYTE_REG_WRITE(0x100ae, (HAL_BYTE_REG_READ(0x100af)|0x10));
608 A_PRINTF("_fw_reset_dma_fifo\n");
610 // disable ep3 int enable, so that resume back won't send wdt magic pattern out!!!
611 mUSB_STATUS_IN_INT_DISABLE();
613 // update magic pattern to indicate this is a suspend
614 HAL_WORD_REG_WRITE(WATCH_DOG_MAGIC_PATTERN_ADDR, SUS_MAGIC_PATTERN);
616 A_PRINTF("org 0x4048 0x%x ......\n", HAL_WORD_REG_READ(0x10ff4048));
617 A_PRINTF("org 0x404C 0x%x ......\n", HAL_WORD_REG_READ(0x10ff404C));
618 A_PRINTF("org 0x4088 0x%x ......\n", HAL_WORD_REG_READ(0x10ff4088));
620 HAL_WORD_REG_WRITE(0x10ff4088,0xaaa6a);//1010.1010.1010.0110.1010 for UB94
621 HAL_WORD_REG_WRITE(0x10ff404C,0x0);
624 A_PRINTF("0x4048 0x%x ......\n", HAL_WORD_REG_READ(0x10ff4048));
625 A_PRINTF("0x404C 0x%x ......\n", HAL_WORD_REG_READ(0x10ff404C));
626 A_PRINTF("0x4088 0x%x ......\n", HAL_WORD_REG_READ(0x10ff4088));
631 A_PRINTF("turn_off_magpie_ep_start ......\n");
632 A_DELAY_USECS(measure_time);
633 HAL_WORD_REG_WRITE( 0x40040, (HAL_WORD_REG_READ(0x40040)|BIT0|(1<<1)));
635 HAL_WORD_REG_WRITE( 0x40040, (HAL_WORD_REG_READ(0x40040)&~(BIT0|(1<<1))));
636 A_PRINTF("turn_off_magpie_ep_end ......\n");
639 A_PRINTF("turn_off_magpie_rc_start ......\n");
640 A_DELAY_USECS(measure_time);
641 HAL_WORD_REG_WRITE( 0x40040, (HAL_WORD_REG_READ(0x40040)&(~BIT0)));
643 A_PRINTF("turn_off_magpie_rc_end ......down\n");
644 A_DELAY_USECS(measure_time);
646 A_PRINTF("0x4001C %p ......\n", HAL_WORD_REG_READ(0x4001c));
647 A_PRINTF("0x40040 %p ......\n", HAL_WORD_REG_READ(0x40040));
649 // turn off pcie_pll - power down (bit16)
650 A_PRINTF(" before pwd PCIE PLL CFG:0x5601C %p ......\n", HAL_WORD_REG_READ(0x5601C));
651 HAL_WORD_REG_WRITE(0x5601C, (HAL_WORD_REG_READ(0x5601C)|(BIT18)));
652 A_PRINTF(" after pwd PCIE PLL CFG:0x5601C %p ......\n", HAL_WORD_REG_READ(0x5601C));
654 /* set everything to reset state?, requested by Oligo */
655 HAL_WORD_REG_WRITE(0x50010, HAL_WORD_REG_READ(0x50010)|(BIT13|BIT12|BIT11|BIT9|BIT7|BIT6));
657 HAL_WORD_REG_WRITE(0x5C000, 0);
661 // reset usb DMA controller
662 HAL_WORD_REG_WRITE((USB_CTRL_BASE_ADDRESS+0x118), 0x0);
664 HAL_WORD_REG_WRITE(0x50010, (HAL_WORD_REG_READ(0x50010)|(BIT4)));
666 HAL_WORD_REG_WRITE(0x50010, (HAL_WORD_REG_READ(0x50010)&(~BIT4)));
669 HAL_WORD_REG_WRITE((USB_CTRL_BASE_ADDRESS+0x118), 0x1);
672 static void _fw_power_off()
676 * 2. turn off CPU PLL
677 * 3. turn off ETH PLL
678 * 4. disable ETH PLL bypass and update
679 * 4.1 set suspend timeout
680 * 5. set SUSPEND_ENABLE
683 HAL_WORD_REG_WRITE(MAGPIE_REG_CPU_PLL_BYPASS_ADDR, (BIT0|BIT4)); //0x56004
685 A_DELAY_USECS(100); // wait for stable
687 HAL_WORD_REG_WRITE(MAGPIE_REG_CPU_PLL_ADDR, (BIT16));//0x56000
689 A_DELAY_USECS(100); // wait for stable
691 A_UART_HWINIT((40*1000*1000), 19200);
694 HAL_WORD_REG_WRITE(MAGPIE_REG_ETH_PLL_ADDR,
695 (HAL_WORD_REG_READ(MAGPIE_REG_ETH_PLL_ADDR)|(BIT16))); //0x5600c
697 HAL_WORD_REG_WRITE(MAGPIE_REG_ETH_PLL_BYPASS_ADDR,
698 (HAL_WORD_REG_READ(MAGPIE_REG_ETH_PLL_BYPASS_ADDR)|(BIT4|BIT0))); //0x56010
700 HAL_WORD_REG_WRITE(MAGPIE_REG_SUSPEND_ENABLE_ADDR,
701 (HAL_WORD_REG_READ(MAGPIE_REG_SUSPEND_ENABLE_ADDR)|(0x10<<8))); //0x56030
704 static void _fw_power_on()
708 * 2. disable CPU bypass
710 * 4. disable ETH PLL bypass and update
711 * 5. turn on pcie pll
714 HAL_WORD_REG_WRITE(MAGPIE_REG_ETH_PLL_ADDR,
715 (HAL_WORD_REG_READ(MAGPIE_REG_ETH_PLL_ADDR)&(~BIT16)));
717 // deassert eth_pll bypass mode and trigger update bit
718 HAL_WORD_REG_WRITE(MAGPIE_REG_ETH_PLL_BYPASS_ADDR,
719 (HAL_WORD_REG_READ(MAGPIE_REG_ETH_PLL_BYPASS_ADDR)&(~(BIT4|BIT0))));
722 static void _fw_restore_dma_fifo(void)
724 HAL_WORD_REG_WRITE(0x5601C, (HAL_WORD_REG_READ(0x5601C)&(~(BIT18))));
726 // reset pcie_rc shift
727 HAL_WORD_REG_WRITE(0x50010, (HAL_WORD_REG_READ(0x50010)&(~(BIT10|BIT8|BIT7))));
729 HAL_WORD_REG_WRITE(0x50010, (HAL_WORD_REG_READ(0x50010)|(BIT10|BIT8|BIT7)));
732 CMD_PCI_RC_RESET_ON();
735 // enable dma swap function
736 MAGPIE_REG_USB_RX0_SWAP_DATA = 0x1;
737 MAGPIE_REG_USB_TX0_SWAP_DATA = 0x1;
738 MAGPIE_REG_USB_RX1_SWAP_DATA = 0x1;
739 MAGPIE_REG_USB_RX2_SWAP_DATA = 0x1;
742 extern uint16_t *u8ConfigDescriptorEX;
743 extern uint16_t *pu8DescriptorEX;
744 extern uint16_t u16TxRxCounter;
746 extern uint16_t *u8UsbDeviceDescriptor;
748 extern BOOLEAN bGet_descriptor(void);
750 uint16_t ConfigDescriptorPatch[30];
752 uint16_t UsbDeviceDescriptorPatch[18];
753 #define VENDOR_ID_OFFSET 8
754 #define PRODUCT_ID_OFFSET 10
756 #define EP3_TRANSFER_TYPE_OFFSET 17
757 #define EP3_INT_INTERVAL 19
758 #define EP4_TRANSFER_TYPE_OFFSET 21
759 #define EP4_INT_INTERVAL 22
763 #define A_SFLASH_READ_4B(u32Data, start_addr) u32Data = *(uint32_t *)(0xf000000+start_addr);
764 #define FLASH_SIZE 0x800000 //8M
765 #define FLASH_USB_VENDOR_ID_OFFSET 0x86
766 #define FLASH_USB_PRODUCT_ID_OFFSET 0x87
768 // flash reserved size for saving eeprom data is 4K.
769 #define EE_DATA_RESERVED_LEN 0x1000 //4K
771 #define mLOW_MASK(u16) ((uint8_t) ((u16) & mMASK(8)))
772 #define mHIGH_MASK(u16) ((uint8_t) ((u16) & ~mMASK(8)))
775 //#define mLOW_BYTE(u16) ((U_8)(u16))
776 #define mLOW_BYTE(u16) mLOW_MASK(u16)
778 #define mHIGH_BYTE(u16) ((uint8_t) (((uint16_t) (u16)) >> 8))
780 #define mLOW_WORD0(u32) ((uint16_t) ((u32) & 0xFFFF))
781 #define mHIGH_WORD0(u32) ((uint16_t) ((u32) >> 16))
784 #define mSWAP_BYTE(u16) ((mLOW_MASK(u16) << 8) | mHIGH_BYTE(u16))
786 BOOLEAN bGet_descriptor_patch(void)
788 /* Patch for custom id from flash */
789 if (bEepromExist == FALSE && mDEV_REQ_VALUE_HIGH() == 1)
791 uint8_t *p = (uint8_t *)u8UsbDeviceDescriptor;
793 /* Copy Usb Device Descriptor */
794 ath_hal_memcpy(UsbDeviceDescriptorPatch, p, sizeof(UsbDeviceDescriptorPatch));
796 A_SFLASH_READ_4B(u32Tmp, FLASH_SIZE - EE_DATA_RESERVED_LEN + FLASH_USB_VENDOR_ID_OFFSET*2);
797 UsbDeviceDescriptorPatch[VENDOR_ID_OFFSET] = mSWAP_BYTE(mLOW_WORD0(u32Tmp));
798 UsbDeviceDescriptorPatch[PRODUCT_ID_OFFSET] = mSWAP_BYTE(mHIGH_WORD0(u32Tmp));
800 pu8DescriptorEX = UsbDeviceDescriptorPatch;
801 u16TxRxCounter = mTABLE_LEN(u8UsbDeviceDescriptor[0]);
803 if (u16TxRxCounter > mDEV_REQ_LENGTH())
804 u16TxRxCounter = mDEV_REQ_LENGTH();
808 //u16TxRxCounter = 18;
811 if (mDEV_REQ_VALUE_HIGH() == 2) {
812 uint8_t *p = (uint8_t *)u8ConfigDescriptorEX;
814 /* Copy ConfigDescriptor */
815 ath_hal_memcpy(ConfigDescriptorPatch, p, sizeof(ConfigDescriptorPatch));
817 p = (uint8_t *)ConfigDescriptorPatch;
819 /* Patch the transfer type of EP3 and EP4 */
820 ConfigDescriptorPatch[EP3_TRANSFER_TYPE_OFFSET] = 0x0283;
821 ConfigDescriptorPatch[EP3_INT_INTERVAL] = 0x0700;
822 ConfigDescriptorPatch[EP4_TRANSFER_TYPE_OFFSET] = 0x4002;
823 ConfigDescriptorPatch[EP4_INT_INTERVAL] = 0x00;
825 switch (mDEV_REQ_VALUE_LOW())
827 case 0x00: // configuration no: 0
828 pu8DescriptorEX = ConfigDescriptorPatch;
829 u16TxRxCounter = ConfigDescriptorPatch[1];
830 //u16TxRxCounter = 46;
836 if (u16TxRxCounter > mDEV_REQ_LENGTH())
837 u16TxRxCounter = mDEV_REQ_LENGTH();
843 return bGet_descriptor();
847 extern BOOLEAN bStandardCommand(void);
849 BOOLEAN bStandardCommand_patch(void)
851 if (mDEV_REQ_REQ() == USB_SET_CONFIGURATION) {
854 #if ENABLE_SWAP_DATA_MODE
855 // SWAP FUNCTION should be enabled while DMA engine is not working,
856 // the best place to enable it is before we trigger the DMA
857 MAGPIE_REG_USB_RX0_SWAP_DATA = 0x1;
858 MAGPIE_REG_USB_TX0_SWAP_DATA = 0x1;
860 #if SYSTEM_MODULE_HP_EP5
861 MAGPIE_REG_USB_RX1_SWAP_DATA = 0x1;
864 #if SYSTEM_MODULE_HP_EP6
865 MAGPIE_REG_USB_RX2_SWAP_DATA = 0x1;
868 #endif //ENABLE_SWAP_DATA_MODE
872 return bStandardCommand();