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 extern Action eUsbCxFinishAction;
50 extern CommandType eUsbCxCommand;
51 extern BOOLEAN UsbChirpFinish;
52 extern USB_FIFO_CONFIG usbFifoConf;
53 extern uint16_t *pu8DescriptorEX;
54 extern uint16_t u16TxRxCounter;
56 void zfTurnOffPower_patch(void);
58 static void _fw_reset_dma_fifo();
59 static void _fw_restore_dma_fifo();
60 static void _fw_power_on();
61 static void _fw_power_off();
63 BOOLEAN bEepromExist = TRUE;
64 BOOLEAN bJumptoFlash = FALSE;
66 void _fw_usb_suspend_reboot()
68 /* reset usb/wlan dma */
71 /* restore gpio setting and usb/wlan dma state */
72 _fw_restore_dma_fifo();
74 /* set clock to bypass mode - 40Mhz from XTAL */
75 HAL_WORD_REG_WRITE(MAGPIE_REG_CPU_PLL_BYPASS_ADDR, (BIT0|BIT4));
77 A_DELAY_USECS(100); /* wait for stable */
79 HAL_WORD_REG_WRITE(MAGPIE_REG_CPU_PLL_ADDR, (BIT16));
81 A_DELAY_USECS(100); /* wait for stable */
82 A_UART_HWINIT((40*1000*1000), 19200);
86 if (!bEepromExist) { /* jump to flash boot (eeprom data in flash) */
88 A_PRINTF("Jump to Flash BOOT\n");
91 A_PRINTF("receive the suspend command...\n");
98 #define PCI_RC_RESET_BIT BIT6
99 #define PCI_RC_PHY_RESET_BIT BIT7
100 #define PCI_RC_PLL_RESET_BIT BIT8
101 #define PCI_RC_PHY_SHIFT_RESET_BIT BIT10
104 * -- urn_off_merlin --
105 * . values suggested from Lalit
108 static void turn_off_merlin()
110 volatile uint32_t default_data[9];
115 A_PRINTF("turn_off_merlin_ep_start ......\n");
116 A_DELAY_USECS(measure_time);
117 default_data[0] = 0x9248fd00;
118 default_data[1] = 0x24924924;
119 default_data[2] = 0xa8000019;
120 default_data[3] = 0x17160820;
121 default_data[4] = 0x25980560;
122 default_data[5] = 0xc1c00000;
123 default_data[6] = 0x1aaabe40;
124 default_data[7] = 0xbe105554;
125 default_data[8] = 0x00043007;
131 HAL_WORD_REG_WRITE( 0x10ff4040, default_data[i]);
134 HAL_WORD_REG_WRITE(0x10ff4044, BIT0);
135 A_PRINTF("turn_off_merlin_ep_end ......\n");
142 * . write shift register to both pcie ep and rc
146 static void turn_off_phy()
149 volatile uint32_t default_data[9];
150 volatile uint32_t read_data = 0;
153 default_data[0] = 0x9248fd00;
154 default_data[1] = 0x24924924;
155 default_data[2] = 0xa8000019;
156 default_data[3] = 0x17160820;
157 default_data[4] = 0x25980560;
158 default_data[5] = 0xc1c00000;
159 default_data[6] = 0x1aaabe40;
160 default_data[7] = 0xbe105554;
161 default_data[8] = 0x00043007;
165 // check for the done bit to be set
169 read_data=HAL_WORD_REG_READ(0x40028);
170 if( read_data & BIT31 )
176 HAL_WORD_REG_WRITE( 0x40024, default_data[i]);
178 HAL_WORD_REG_WRITE(0x40028, BIT0);
181 static void turn_off_phy_rc()
184 volatile uint32_t default_data[9];
185 volatile uint32_t read_data = 0;
188 A_PRINTF("turn_off_phy_rc\n");
190 default_data[0] = 0x9248fd00;
191 default_data[1] = 0x24924924;
192 default_data[2] = 0xa8000019;
193 default_data[3] = 0x13160820;//PwdClk1MHz=0
194 default_data[4] = 0x25980560;
195 default_data[5] = 0xc1c00000;
196 default_data[6] = 0x1aaabe40;
197 default_data[7] = 0xbe105554;
198 default_data[8] = 0x00043007;
202 // check for the done bit to be set
206 read_data=HAL_WORD_REG_READ(0x40028);
207 if( read_data & BIT31 )
213 HAL_WORD_REG_WRITE( 0x40024, default_data[i]);
215 HAL_WORD_REG_WRITE(0x40028, BIT0);
218 volatile uint32_t gpio_func = 0x0;
219 volatile uint32_t gpio = 0x0;
222 * -- patch zfTurnOffPower --
224 * . set suspend counter to non-zero value
227 void zfTurnOffPower_patch(void)
229 A_PRINTF("+++ goto suspend ......\n");
231 // setting the go suspend here, power down right away...
232 HAL_WORD_REG_WRITE(0x10000, HAL_WORD_REG_READ(0x10000)|(0x8));
239 //32clk wait for External ETH PLL stable
242 HAL_WORD_REG_WRITE(0x52000, 0x70303);//read back 0x703f7
243 HAL_WORD_REG_WRITE(0x52008, 0x0e91c);//read back 0x1e948
245 HAL_WORD_REG_WRITE(MAGPIE_REG_SUSPEND_ENABLE_ADDR,
246 (HAL_WORD_REG_READ(MAGPIE_REG_SUSPEND_ENABLE_ADDR)|(BIT0))); //0x56030
247 // wake up, and turn on cpu, eth, pcie and usb pll
249 // restore gpio and other settings
250 _fw_restore_dma_fifo();
252 // clear suspend..................
253 HAL_WORD_REG_WRITE(MAGPIE_REG_SUSPEND_ENABLE_ADDR,
254 (HAL_WORD_REG_READ(MAGPIE_REG_SUSPEND_ENABLE_ADDR)&(~BIT0)));
255 HAL_WORD_REG_WRITE(0x52028, HAL_WORD_REG_READ(0x52028)&(~(BIT8|BIT12|BIT16)));
259 * -- patch zfResetUSBFIFO_patch --
261 * . clear ep3/ep4 fifo
262 * . set suspend magic pattern
263 * . reset pcie ep phy
264 * . reset pcie rc phy
265 * . turn off pcie pll
266 * . reset all pcie/gmac related registers
269 void zfResetUSBFIFO_patch(void)
271 A_PRINTF("0x9808 0x%x ......\n", HAL_WORD_REG_READ(0x10ff9808));
272 A_PRINTF("0x7890 0x%x ......\n", HAL_WORD_REG_READ(0x10ff7890));
273 A_PRINTF("0x7890 0x%x ......\n", HAL_WORD_REG_READ(0x10ff7890));
274 A_PRINTF("0x4088 0x%x ......\n", HAL_WORD_REG_READ(0x10ff4088));
275 _fw_reset_dma_fifo();
278 static void _fw_reset_dma_fifo()
280 HAL_BYTE_REG_WRITE(0x100ae, (HAL_BYTE_REG_READ(0x100ae)|0x10));
281 HAL_BYTE_REG_WRITE(0x100ae, (HAL_BYTE_REG_READ(0x100af)|0x10));
282 A_PRINTF("_fw_reset_dma_fifo\n");
284 // disable ep3 int enable, so that resume back won't send wdt magic pattern out!!!
285 mUSB_STATUS_IN_INT_DISABLE();
287 // update magic pattern to indicate this is a suspend
288 HAL_WORD_REG_WRITE(WATCH_DOG_MAGIC_PATTERN_ADDR, SUS_MAGIC_PATTERN);
290 A_PRINTF("org 0x4048 0x%x ......\n", HAL_WORD_REG_READ(0x10ff4048));
291 A_PRINTF("org 0x404C 0x%x ......\n", HAL_WORD_REG_READ(0x10ff404C));
292 A_PRINTF("org 0x4088 0x%x ......\n", HAL_WORD_REG_READ(0x10ff4088));
294 HAL_WORD_REG_WRITE(0x10ff4088,0xaaa6a);//1010.1010.1010.0110.1010 for UB94
295 HAL_WORD_REG_WRITE(0x10ff404C,0x0);
298 A_PRINTF("0x4048 0x%x ......\n", HAL_WORD_REG_READ(0x10ff4048));
299 A_PRINTF("0x404C 0x%x ......\n", HAL_WORD_REG_READ(0x10ff404C));
300 A_PRINTF("0x4088 0x%x ......\n", HAL_WORD_REG_READ(0x10ff4088));
305 A_PRINTF("turn_off_magpie_ep_start ......\n");
306 A_DELAY_USECS(measure_time);
307 HAL_WORD_REG_WRITE( 0x40040, (HAL_WORD_REG_READ(0x40040)|BIT0|(1<<1)));
309 HAL_WORD_REG_WRITE( 0x40040, (HAL_WORD_REG_READ(0x40040)&~(BIT0|(1<<1))));
310 A_PRINTF("turn_off_magpie_ep_end ......\n");
313 A_PRINTF("turn_off_magpie_rc_start ......\n");
314 A_DELAY_USECS(measure_time);
315 HAL_WORD_REG_WRITE( 0x40040, (HAL_WORD_REG_READ(0x40040)&(~BIT0)));
317 A_PRINTF("turn_off_magpie_rc_end ......down\n");
318 A_DELAY_USECS(measure_time);
320 A_PRINTF("0x4001C %p ......\n", HAL_WORD_REG_READ(0x4001c));
321 A_PRINTF("0x40040 %p ......\n", HAL_WORD_REG_READ(0x40040));
323 // turn off pcie_pll - power down (bit16)
324 A_PRINTF(" before pwd PCIE PLL CFG:0x5601C %p ......\n", HAL_WORD_REG_READ(0x5601C));
325 HAL_WORD_REG_WRITE(0x5601C, (HAL_WORD_REG_READ(0x5601C)|(BIT18)));
326 A_PRINTF(" after pwd PCIE PLL CFG:0x5601C %p ......\n", HAL_WORD_REG_READ(0x5601C));
328 /* set everything to reset state?, requested by Oligo */
329 HAL_WORD_REG_WRITE(0x50010, HAL_WORD_REG_READ(0x50010)|(BIT13|BIT12|BIT11|BIT9|BIT7|BIT6));
331 HAL_WORD_REG_WRITE(0x5C000, 0);
335 // reset usb DMA controller
336 HAL_WORD_REG_WRITE((USB_CTRL_BASE_ADDRESS+0x118), 0x0);
338 HAL_WORD_REG_WRITE(0x50010, (HAL_WORD_REG_READ(0x50010)|(BIT4)));
340 HAL_WORD_REG_WRITE(0x50010, (HAL_WORD_REG_READ(0x50010)&(~BIT4)));
343 HAL_WORD_REG_WRITE((USB_CTRL_BASE_ADDRESS+0x118), 0x1);
346 static void _fw_power_off()
350 * 2. turn off CPU PLL
351 * 3. turn off ETH PLL
352 * 4. disable ETH PLL bypass and update
353 * 4.1 set suspend timeout
354 * 5. set SUSPEND_ENABLE
357 HAL_WORD_REG_WRITE(MAGPIE_REG_CPU_PLL_BYPASS_ADDR, (BIT0|BIT4)); //0x56004
359 A_DELAY_USECS(100); // wait for stable
361 HAL_WORD_REG_WRITE(MAGPIE_REG_CPU_PLL_ADDR, (BIT16));//0x56000
363 A_DELAY_USECS(100); // wait for stable
365 A_UART_HWINIT((40*1000*1000), 19200);
368 HAL_WORD_REG_WRITE(MAGPIE_REG_ETH_PLL_ADDR,
369 (HAL_WORD_REG_READ(MAGPIE_REG_ETH_PLL_ADDR)|(BIT16))); //0x5600c
371 HAL_WORD_REG_WRITE(MAGPIE_REG_ETH_PLL_BYPASS_ADDR,
372 (HAL_WORD_REG_READ(MAGPIE_REG_ETH_PLL_BYPASS_ADDR)|(BIT4|BIT0))); //0x56010
374 HAL_WORD_REG_WRITE(MAGPIE_REG_SUSPEND_ENABLE_ADDR,
375 (HAL_WORD_REG_READ(MAGPIE_REG_SUSPEND_ENABLE_ADDR)|(0x10<<8))); //0x56030
378 static void _fw_power_on()
382 * 2. disable CPU bypass
384 * 4. disable ETH PLL bypass and update
385 * 5. turn on pcie pll
388 HAL_WORD_REG_WRITE(MAGPIE_REG_ETH_PLL_ADDR,
389 (HAL_WORD_REG_READ(MAGPIE_REG_ETH_PLL_ADDR)&(~BIT16)));
391 // deassert eth_pll bypass mode and trigger update bit
392 HAL_WORD_REG_WRITE(MAGPIE_REG_ETH_PLL_BYPASS_ADDR,
393 (HAL_WORD_REG_READ(MAGPIE_REG_ETH_PLL_BYPASS_ADDR)&(~(BIT4|BIT0))));
396 #define CMD_PCI_RC_RESET_ON() HAL_WORD_REG_WRITE(MAGPIE_REG_RST_RESET_ADDR, \
397 (HAL_WORD_REG_READ(MAGPIE_REG_RST_RESET_ADDR)| \
398 (PCI_RC_PHY_SHIFT_RESET_BIT|PCI_RC_PLL_RESET_BIT|PCI_RC_PHY_RESET_BIT|PCI_RC_RESET_BIT)))
400 static void _fw_restore_dma_fifo(void)
402 HAL_WORD_REG_WRITE(0x5601C, (HAL_WORD_REG_READ(0x5601C)&(~(BIT18))));
404 // reset pcie_rc shift
405 HAL_WORD_REG_WRITE(0x50010, (HAL_WORD_REG_READ(0x50010)&(~(BIT10|BIT8|BIT7))));
407 HAL_WORD_REG_WRITE(0x50010, (HAL_WORD_REG_READ(0x50010)|(BIT10|BIT8|BIT7)));
410 CMD_PCI_RC_RESET_ON();
413 // enable dma swap function
414 MAGPIE_REG_USB_RX0_SWAP_DATA = 0x1;
415 MAGPIE_REG_USB_TX0_SWAP_DATA = 0x1;
416 MAGPIE_REG_USB_RX1_SWAP_DATA = 0x1;
417 MAGPIE_REG_USB_RX2_SWAP_DATA = 0x1;