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"
43 #include "adf_os_io.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 iowrite32(MAGPIE_REG_CPU_PLL_BYPASS_ADDR, BIT0 | BIT4);
77 A_DELAY_USECS(100); /* wait for stable */
79 iowrite32(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 iowrite32(0x10ff4040, default_data[i]);
134 iowrite32(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];
152 default_data[0] = 0x9248fd00;
153 default_data[1] = 0x24924924;
154 default_data[2] = 0xa8000019;
155 default_data[3] = 0x17160820;
156 default_data[4] = 0x25980560;
157 default_data[5] = 0xc1c00000;
158 default_data[6] = 0x1aaabe40;
159 default_data[7] = 0xbe105554;
160 default_data[8] = 0x00043007;
164 // check for the done bit to be set
168 if (ioread32(0x40028) & BIT31)
174 iowrite32(0x40024, default_data[i]);
176 iowrite32(0x40028, BIT0);
179 static void turn_off_phy_rc()
182 volatile uint32_t default_data[9];
185 A_PRINTF("turn_off_phy_rc\n");
187 default_data[0] = 0x9248fd00;
188 default_data[1] = 0x24924924;
189 default_data[2] = 0xa8000019;
190 default_data[3] = 0x13160820;//PwdClk1MHz=0
191 default_data[4] = 0x25980560;
192 default_data[5] = 0xc1c00000;
193 default_data[6] = 0x1aaabe40;
194 default_data[7] = 0xbe105554;
195 default_data[8] = 0x00043007;
199 // check for the done bit to be set
203 if (ioread32(0x40028) & BIT31)
209 iowrite32(0x40024, default_data[i]);
211 iowrite32(0x40028, BIT0);
214 volatile uint32_t gpio_func = 0x0;
215 volatile uint32_t gpio = 0x0;
218 * -- patch zfTurnOffPower --
220 * . set suspend counter to non-zero value
223 void zfTurnOffPower_patch(void)
225 A_PRINTF("+++ goto suspend ......\n");
227 /* setting the go suspend here, power down right away */
228 io32_set(0x10000, BIT3);
235 //32clk wait for External ETH PLL stable
238 iowrite32(0x52000, 0x70303); /* read back 0x703f7 */
239 iowrite32(0x52008, 0x0e91c); /* read back 0x1e948 */
241 io32_set(MAGPIE_REG_SUSPEND_ENABLE_ADDR, BIT0);
243 // wake up, and turn on cpu, eth, pcie and usb pll
245 // restore gpio and other settings
246 _fw_restore_dma_fifo();
249 io32_clr(MAGPIE_REG_SUSPEND_ENABLE_ADDR, BIT0);
250 io32_clr(0x52028, BIT8 | BIT12 | BIT16);
254 * -- patch zfResetUSBFIFO_patch --
256 * . clear ep3/ep4 fifo
257 * . set suspend magic pattern
258 * . reset pcie ep phy
259 * . reset pcie rc phy
260 * . turn off pcie pll
261 * . reset all pcie/gmac related registers
264 void zfResetUSBFIFO_patch(void)
266 A_PRINTF("0x9808 0x%x ......\n", ioread32(0x10ff9808));
267 A_PRINTF("0x7890 0x%x ......\n", ioread32(0x10ff7890));
268 A_PRINTF("0x7890 0x%x ......\n", ioread32(0x10ff7890));
269 A_PRINTF("0x4088 0x%x ......\n", ioread32(0x10ff4088));
270 _fw_reset_dma_fifo();
273 static void _fw_reset_dma_fifo()
275 io8_set(0x100ae, 0x10);
276 io8_set(0x100af, 0x10);
277 A_PRINTF("_fw_reset_dma_fifo\n");
279 // disable ep3 int enable, so that resume back won't send wdt magic pattern out!!!
280 mUSB_STATUS_IN_INT_DISABLE();
282 /* update magic pattern to indicate this is a suspend */
283 iowrite32(WATCH_DOG_MAGIC_PATTERN_ADDR, SUS_MAGIC_PATTERN);
285 A_PRINTF("org 0x4048 0x%x ......\n", ioread32(0x10ff4048));
286 A_PRINTF("org 0x404C 0x%x ......\n", ioread32(0x10ff404C));
287 A_PRINTF("org 0x4088 0x%x ......\n", ioread32(0x10ff4088));
289 /* 1010.1010.1010.0110.1010 for UB94 */
290 iowrite32(0x10ff4088, 0xaaa6a);
291 iowrite32(0x10ff404C, 0x0);
294 A_PRINTF("0x4048 0x%x ......\n", ioread32(0x10ff4048));
295 A_PRINTF("0x404C 0x%x ......\n", ioread32(0x10ff404C));
296 A_PRINTF("0x4088 0x%x ......\n", ioread32(0x10ff4088));
301 A_PRINTF("turn_off_magpie_ep_start ......\n");
302 A_DELAY_USECS(measure_time);
303 io32_set(0x40040, BIT0 | BIT1);
305 io32_clr(0x40040, BIT0 | BIT1);
306 A_PRINTF("turn_off_magpie_ep_end ......\n");
309 A_PRINTF("turn_off_magpie_rc_start ......\n");
310 A_DELAY_USECS(measure_time);
311 io32_clr(0x40040, BIT0);
313 A_PRINTF("turn_off_magpie_rc_end ......down\n");
314 A_DELAY_USECS(measure_time);
316 A_PRINTF("0x4001C %p ......\n", ioread32(0x4001c));
317 A_PRINTF("0x40040 %p ......\n", ioread32(0x40040));
319 /* turn off pcie_pll - power down (bit16) */
320 A_PRINTF(" before pwd PCIE PLL CFG:0x5601C: 0x%08x\n",
322 io32_set(0x5601C, BIT18);
323 A_PRINTF(" after pwd PCIE PLL CFG:0x5601C: 0x%08x\n",
326 /* set everything to reset state?, requested by Oligo */
327 io32_set(0x50010, BIT13 | BIT12
328 | BIT11 | BIT9 | BIT7 | BIT6);
330 iowrite32(0x5C000, 0);
334 /* reset usb DMA controller */
335 iowrite32_usb(ZM_SOC_USB_DMA_RESET_OFFSET, 0x0);
337 io32_set(0x50010, BIT4);
339 io32_clr(0x50010, BIT4);
341 iowrite32_usb(ZM_SOC_USB_DMA_RESET_OFFSET, BIT0);
344 static void _fw_power_off()
348 * 2. turn off CPU PLL
349 * 3. turn off ETH PLL
350 * 4. disable ETH PLL bypass and update
351 * 4.1 set suspend timeout
352 * 5. set SUSPEND_ENABLE
355 iowrite32(MAGPIE_REG_CPU_PLL_BYPASS_ADDR, BIT0 | BIT4);
357 A_DELAY_USECS(100); // wait for stable
359 iowrite32(MAGPIE_REG_CPU_PLL_ADDR, BIT16);
361 A_DELAY_USECS(100); // wait for stable
363 A_UART_HWINIT((40*1000*1000), 19200);
366 io32_set(MAGPIE_REG_ETH_PLL_ADDR, BIT16);
368 io32_set(MAGPIE_REG_ETH_PLL_BYPASS_ADDR, BIT4 | BIT0);
370 io32_set(MAGPIE_REG_SUSPEND_ENABLE_ADDR, 0x10 << 8);
373 static void _fw_power_on()
377 * 2. disable CPU bypass
379 * 4. disable ETH PLL bypass and update
380 * 5. turn on pcie pll
383 io32_clr(MAGPIE_REG_ETH_PLL_ADDR, BIT16);
385 /* deassert eth_pll bypass mode and trigger update bit */
386 io32_clr(MAGPIE_REG_ETH_PLL_BYPASS_ADDR, BIT4 | BIT0);
389 static void _fw_restore_dma_fifo(void)
391 io32_clr(0x5601C, BIT18);
393 /* reset pcie_rc shift */
394 io32_clr(0x50010, BIT10 | BIT8 | BIT7);
396 io32_set(0x50010, BIT10 | BIT8 | BIT7);
398 /* reset pci_rc phy */
399 io32_set(MAGPIE_REG_RST_RESET_ADDR,
400 PCI_RC_PHY_SHIFT_RESET_BIT
401 | PCI_RC_PLL_RESET_BIT | PCI_RC_PHY_RESET_BIT
405 // enable dma swap function
406 MAGPIE_REG_USB_RX0_SWAP_DATA = 0x1;
407 MAGPIE_REG_USB_TX0_SWAP_DATA = 0x1;
408 MAGPIE_REG_USB_RX1_SWAP_DATA = 0x1;
409 MAGPIE_REG_USB_RX2_SWAP_DATA = 0x1;