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;
121 #define PCI_RC_RESET_BIT BIT6
122 #define PCI_RC_PHY_RESET_BIT BIT7
123 #define PCI_RC_PLL_RESET_BIT BIT8
124 #define PCI_RC_PHY_SHIFT_RESET_BIT BIT10
128 * -- urn_off_merlin --
129 * . values suggested from Lalit
132 static void turn_off_merlin()
134 volatile uint32_t default_data[9];
139 A_PRINTF("turn_off_merlin_ep_start ......\n");
140 A_DELAY_USECS(measure_time);
141 default_data[0] = 0x9248fd00;
142 default_data[1] = 0x24924924;
143 default_data[2] = 0xa8000019;
144 default_data[3] = 0x17160820;
145 default_data[4] = 0x25980560;
146 default_data[5] = 0xc1c00000;
147 default_data[6] = 0x1aaabe40;
148 default_data[7] = 0xbe105554;
149 default_data[8] = 0x00043007;
155 HAL_WORD_REG_WRITE( 0x10ff4040, default_data[i]);
158 HAL_WORD_REG_WRITE(0x10ff4044, BIT0);
159 A_PRINTF("turn_off_merlin_ep_end ......\n");
166 * . write shift register to both pcie ep and rc
170 static void turn_off_phy()
173 volatile uint32_t default_data[9];
174 volatile uint32_t read_data = 0;
177 default_data[0] = 0x9248fd00;
178 default_data[1] = 0x24924924;
179 default_data[2] = 0xa8000019;
180 default_data[3] = 0x17160820;
181 default_data[4] = 0x25980560;
182 default_data[5] = 0xc1c00000;
183 default_data[6] = 0x1aaabe40;
184 default_data[7] = 0xbe105554;
185 default_data[8] = 0x00043007;
189 // check for the done bit to be set
193 read_data=HAL_WORD_REG_READ(0x40028);
194 if( read_data & BIT31 )
200 HAL_WORD_REG_WRITE( 0x40024, default_data[i]);
202 HAL_WORD_REG_WRITE(0x40028, BIT0);
205 static void turn_off_phy_rc()
208 volatile uint32_t default_data[9];
209 volatile uint32_t read_data = 0;
212 A_PRINTF("turn_off_phy_rc\n");
214 default_data[0] = 0x9248fd00;
215 default_data[1] = 0x24924924;
216 default_data[2] = 0xa8000019;
217 default_data[3] = 0x13160820;//PwdClk1MHz=0
218 default_data[4] = 0x25980560;
219 default_data[5] = 0xc1c00000;
220 default_data[6] = 0x1aaabe40;
221 default_data[7] = 0xbe105554;
222 default_data[8] = 0x00043007;
226 // check for the done bit to be set
230 read_data=HAL_WORD_REG_READ(0x40028);
231 if( read_data & BIT31 )
237 HAL_WORD_REG_WRITE( 0x40024, default_data[i]);
239 HAL_WORD_REG_WRITE(0x40028, BIT0);
242 volatile uint32_t gpio_func = 0x0;
243 volatile uint32_t gpio = 0x0;
246 * -- patch zfTurnOffPower --
248 * . set suspend counter to non-zero value
251 void zfTurnOffPower_patch(void)
253 A_PRINTF("+++ goto suspend ......\n");
255 // setting the go suspend here, power down right away...
256 HAL_WORD_REG_WRITE(0x10000, HAL_WORD_REG_READ(0x10000)|(0x8));
263 //32clk wait for External ETH PLL stable
266 HAL_WORD_REG_WRITE(0x52000, 0x70303);//read back 0x703f7
267 HAL_WORD_REG_WRITE(0x52008, 0x0e91c);//read back 0x1e948
269 HAL_WORD_REG_WRITE(MAGPIE_REG_SUSPEND_ENABLE_ADDR,
270 (HAL_WORD_REG_READ(MAGPIE_REG_SUSPEND_ENABLE_ADDR)|(BIT0))); //0x56030
271 // wake up, and turn on cpu, eth, pcie and usb pll
273 // restore gpio and other settings
274 _fw_restore_dma_fifo();
276 // clear suspend..................
277 HAL_WORD_REG_WRITE(MAGPIE_REG_SUSPEND_ENABLE_ADDR,
278 (HAL_WORD_REG_READ(MAGPIE_REG_SUSPEND_ENABLE_ADDR)&(~BIT0)));
279 HAL_WORD_REG_WRITE(0x52028, HAL_WORD_REG_READ(0x52028)&(~(BIT8|BIT12|BIT16)));
283 * -- patch zfResetUSBFIFO_patch --
285 * . clear ep3/ep4 fifo
286 * . set suspend magic pattern
287 * . reset pcie ep phy
288 * . reset pcie rc phy
289 * . turn off pcie pll
290 * . reset all pcie/gmac related registers
293 void zfResetUSBFIFO_patch(void)
295 A_PRINTF("0x9808 0x%x ......\n", HAL_WORD_REG_READ(0x10ff9808));
296 A_PRINTF("0x7890 0x%x ......\n", HAL_WORD_REG_READ(0x10ff7890));
297 A_PRINTF("0x7890 0x%x ......\n", HAL_WORD_REG_READ(0x10ff7890));
298 A_PRINTF("0x4088 0x%x ......\n", HAL_WORD_REG_READ(0x10ff4088));
299 _fw_reset_dma_fifo();
302 static void _fw_reset_dma_fifo()
304 HAL_BYTE_REG_WRITE(0x100ae, (HAL_BYTE_REG_READ(0x100ae)|0x10));
305 HAL_BYTE_REG_WRITE(0x100ae, (HAL_BYTE_REG_READ(0x100af)|0x10));
306 A_PRINTF("_fw_reset_dma_fifo\n");
308 // disable ep3 int enable, so that resume back won't send wdt magic pattern out!!!
309 mUSB_STATUS_IN_INT_DISABLE();
311 // update magic pattern to indicate this is a suspend
312 HAL_WORD_REG_WRITE(WATCH_DOG_MAGIC_PATTERN_ADDR, SUS_MAGIC_PATTERN);
314 A_PRINTF("org 0x4048 0x%x ......\n", HAL_WORD_REG_READ(0x10ff4048));
315 A_PRINTF("org 0x404C 0x%x ......\n", HAL_WORD_REG_READ(0x10ff404C));
316 A_PRINTF("org 0x4088 0x%x ......\n", HAL_WORD_REG_READ(0x10ff4088));
318 HAL_WORD_REG_WRITE(0x10ff4088,0xaaa6a);//1010.1010.1010.0110.1010 for UB94
319 HAL_WORD_REG_WRITE(0x10ff404C,0x0);
322 A_PRINTF("0x4048 0x%x ......\n", HAL_WORD_REG_READ(0x10ff4048));
323 A_PRINTF("0x404C 0x%x ......\n", HAL_WORD_REG_READ(0x10ff404C));
324 A_PRINTF("0x4088 0x%x ......\n", HAL_WORD_REG_READ(0x10ff4088));
329 A_PRINTF("turn_off_magpie_ep_start ......\n");
330 A_DELAY_USECS(measure_time);
331 HAL_WORD_REG_WRITE( 0x40040, (HAL_WORD_REG_READ(0x40040)|BIT0|(1<<1)));
333 HAL_WORD_REG_WRITE( 0x40040, (HAL_WORD_REG_READ(0x40040)&~(BIT0|(1<<1))));
334 A_PRINTF("turn_off_magpie_ep_end ......\n");
337 A_PRINTF("turn_off_magpie_rc_start ......\n");
338 A_DELAY_USECS(measure_time);
339 HAL_WORD_REG_WRITE( 0x40040, (HAL_WORD_REG_READ(0x40040)&(~BIT0)));
341 A_PRINTF("turn_off_magpie_rc_end ......down\n");
342 A_DELAY_USECS(measure_time);
344 A_PRINTF("0x4001C %p ......\n", HAL_WORD_REG_READ(0x4001c));
345 A_PRINTF("0x40040 %p ......\n", HAL_WORD_REG_READ(0x40040));
347 // turn off pcie_pll - power down (bit16)
348 A_PRINTF(" before pwd PCIE PLL CFG:0x5601C %p ......\n", HAL_WORD_REG_READ(0x5601C));
349 HAL_WORD_REG_WRITE(0x5601C, (HAL_WORD_REG_READ(0x5601C)|(BIT18)));
350 A_PRINTF(" after pwd PCIE PLL CFG:0x5601C %p ......\n", HAL_WORD_REG_READ(0x5601C));
352 /* set everything to reset state?, requested by Oligo */
353 HAL_WORD_REG_WRITE(0x50010, HAL_WORD_REG_READ(0x50010)|(BIT13|BIT12|BIT11|BIT9|BIT7|BIT6));
355 HAL_WORD_REG_WRITE(0x5C000, 0);
359 // reset usb DMA controller
360 HAL_WORD_REG_WRITE((USB_CTRL_BASE_ADDRESS+0x118), 0x0);
362 HAL_WORD_REG_WRITE(0x50010, (HAL_WORD_REG_READ(0x50010)|(BIT4)));
364 HAL_WORD_REG_WRITE(0x50010, (HAL_WORD_REG_READ(0x50010)&(~BIT4)));
367 HAL_WORD_REG_WRITE((USB_CTRL_BASE_ADDRESS+0x118), 0x1);
370 static void _fw_power_off()
374 * 2. turn off CPU PLL
375 * 3. turn off ETH PLL
376 * 4. disable ETH PLL bypass and update
377 * 4.1 set suspend timeout
378 * 5. set SUSPEND_ENABLE
381 HAL_WORD_REG_WRITE(MAGPIE_REG_CPU_PLL_BYPASS_ADDR, (BIT0|BIT4)); //0x56004
383 A_DELAY_USECS(100); // wait for stable
385 HAL_WORD_REG_WRITE(MAGPIE_REG_CPU_PLL_ADDR, (BIT16));//0x56000
387 A_DELAY_USECS(100); // wait for stable
389 A_UART_HWINIT((40*1000*1000), 19200);
392 HAL_WORD_REG_WRITE(MAGPIE_REG_ETH_PLL_ADDR,
393 (HAL_WORD_REG_READ(MAGPIE_REG_ETH_PLL_ADDR)|(BIT16))); //0x5600c
395 HAL_WORD_REG_WRITE(MAGPIE_REG_ETH_PLL_BYPASS_ADDR,
396 (HAL_WORD_REG_READ(MAGPIE_REG_ETH_PLL_BYPASS_ADDR)|(BIT4|BIT0))); //0x56010
398 HAL_WORD_REG_WRITE(MAGPIE_REG_SUSPEND_ENABLE_ADDR,
399 (HAL_WORD_REG_READ(MAGPIE_REG_SUSPEND_ENABLE_ADDR)|(0x10<<8))); //0x56030
402 static void _fw_power_on()
406 * 2. disable CPU bypass
408 * 4. disable ETH PLL bypass and update
409 * 5. turn on pcie pll
412 HAL_WORD_REG_WRITE(MAGPIE_REG_ETH_PLL_ADDR,
413 (HAL_WORD_REG_READ(MAGPIE_REG_ETH_PLL_ADDR)&(~BIT16)));
415 // deassert eth_pll bypass mode and trigger update bit
416 HAL_WORD_REG_WRITE(MAGPIE_REG_ETH_PLL_BYPASS_ADDR,
417 (HAL_WORD_REG_READ(MAGPIE_REG_ETH_PLL_BYPASS_ADDR)&(~(BIT4|BIT0))));
420 #define CMD_PCI_RC_RESET_ON() HAL_WORD_REG_WRITE(MAGPIE_REG_RST_RESET_ADDR, \
421 (HAL_WORD_REG_READ(MAGPIE_REG_RST_RESET_ADDR)| \
422 (PCI_RC_PHY_SHIFT_RESET_BIT|PCI_RC_PLL_RESET_BIT|PCI_RC_PHY_RESET_BIT|PCI_RC_RESET_BIT)))
424 static void _fw_restore_dma_fifo(void)
426 HAL_WORD_REG_WRITE(0x5601C, (HAL_WORD_REG_READ(0x5601C)&(~(BIT18))));
428 // reset pcie_rc shift
429 HAL_WORD_REG_WRITE(0x50010, (HAL_WORD_REG_READ(0x50010)&(~(BIT10|BIT8|BIT7))));
431 HAL_WORD_REG_WRITE(0x50010, (HAL_WORD_REG_READ(0x50010)|(BIT10|BIT8|BIT7)));
434 CMD_PCI_RC_RESET_ON();
437 // enable dma swap function
438 MAGPIE_REG_USB_RX0_SWAP_DATA = 0x1;
439 MAGPIE_REG_USB_TX0_SWAP_DATA = 0x1;
440 MAGPIE_REG_USB_RX1_SWAP_DATA = 0x1;
441 MAGPIE_REG_USB_RX2_SWAP_DATA = 0x1;