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.
36 #include <init/app_start.h>
44 #include "athos_api.h"
45 #include "usbfifo_api.h"
46 #include "adf_os_io.h"
49 #define measure_time 0
50 #define measure_time_pll 10000000
52 extern Action eUsbCxFinishAction;
53 extern CommandType eUsbCxCommand;
54 extern BOOLEAN UsbChirpFinish;
55 extern USB_FIFO_CONFIG usbFifoConf;
56 extern uint16_t *pu8DescriptorEX;
57 extern uint16_t u16TxRxCounter;
59 void zfTurnOffPower_patch(void);
61 static void _fw_reset_dma_fifo();
62 static void _fw_restore_dma_fifo();
63 static void _fw_power_on();
64 static void _fw_power_off();
66 BOOLEAN bEepromExist = TRUE;
67 BOOLEAN bJumptoFlash = FALSE;
69 void _fw_usb_suspend_reboot()
71 /* reset usb/wlan dma */
74 /* restore gpio setting and usb/wlan dma state */
75 _fw_restore_dma_fifo();
77 /* set clock to bypass mode - 40Mhz from XTAL */
78 iowrite32(MAGPIE_REG_CPU_PLL_BYPASS_ADDR, BIT0 | BIT4);
80 A_DELAY_USECS(100); /* wait for stable */
82 iowrite32(MAGPIE_REG_CPU_PLL_ADDR, BIT16);
84 A_DELAY_USECS(100); /* wait for stable */
85 A_UART_HWINIT((40*1000*1000), 19200);
89 if (!bEepromExist) { /* jump to flash boot (eeprom data in flash) */
91 A_PRINTF("Jump to Flash BOOT\n");
94 A_PRINTF("receive the suspend command...\n");
101 #define PCI_RC_RESET_BIT BIT6
102 #define PCI_RC_PHY_RESET_BIT BIT7
103 #define PCI_RC_PLL_RESET_BIT BIT8
104 #define PCI_RC_PHY_SHIFT_RESET_BIT BIT10
107 * -- urn_off_merlin --
108 * . values suggested from Lalit
111 static void turn_off_merlin()
113 volatile uint32_t default_data[9];
118 A_PRINTF("turn_off_merlin_ep_start ......\n");
119 A_DELAY_USECS(measure_time);
120 default_data[0] = 0x9248fd00;
121 default_data[1] = 0x24924924;
122 default_data[2] = 0xa8000019;
123 default_data[3] = 0x17160820;
124 default_data[4] = 0x25980560;
125 default_data[5] = 0xc1c00000;
126 default_data[6] = 0x1aaabe40;
127 default_data[7] = 0xbe105554;
128 default_data[8] = 0x00043007;
134 iowrite32(0x10ff4040, default_data[i]);
137 iowrite32(0x10ff4044, BIT0);
138 A_PRINTF("turn_off_merlin_ep_end ......\n");
145 * . write shift register to both pcie ep and rc
149 static void turn_off_phy()
152 volatile uint32_t default_data[9];
155 default_data[0] = 0x9248fd00;
156 default_data[1] = 0x24924924;
157 default_data[2] = 0xa8000019;
158 default_data[3] = 0x17160820;
159 default_data[4] = 0x25980560;
160 default_data[5] = 0xc1c00000;
161 default_data[6] = 0x1aaabe40;
162 default_data[7] = 0xbe105554;
163 default_data[8] = 0x00043007;
167 // check for the done bit to be set
171 if (ioread32(0x40028) & BIT31)
177 iowrite32(0x40024, default_data[i]);
179 iowrite32(0x40028, BIT0);
182 static void turn_off_phy_rc()
185 volatile uint32_t default_data[9];
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 if (ioread32(0x40028) & BIT31)
212 iowrite32(0x40024, default_data[i]);
214 iowrite32(0x40028, BIT0);
217 volatile uint32_t gpio_func = 0x0;
218 volatile uint32_t gpio = 0x0;
221 * -- patch zfTurnOffPower --
223 * . set suspend counter to non-zero value
226 void zfTurnOffPower_patch(void)
228 A_PRINTF("+++ goto suspend ......\n");
230 /* setting the go suspend here, power down right away */
231 io32_set(0x10000, BIT3);
238 //32clk wait for External ETH PLL stable
241 iowrite32(0x52000, 0x70303); /* read back 0x703f7 */
242 iowrite32(0x52008, 0x0e91c); /* read back 0x1e948 */
244 io32_set(MAGPIE_REG_SUSPEND_ENABLE_ADDR, BIT0);
246 // wake up, and turn on cpu, eth, pcie and usb pll
248 // restore gpio and other settings
249 _fw_restore_dma_fifo();
252 io32_clr(MAGPIE_REG_SUSPEND_ENABLE_ADDR, BIT0);
253 io32_clr(0x52028, BIT8 | BIT12 | BIT16);
257 * -- patch zfResetUSBFIFO_patch --
259 * . clear ep3/ep4 fifo
260 * . set suspend magic pattern
261 * . reset pcie ep phy
262 * . reset pcie rc phy
263 * . turn off pcie pll
264 * . reset all pcie/gmac related registers
267 void zfResetUSBFIFO_patch(void)
269 A_PRINTF("0x9808 0x%x ......\n", ioread32(0x10ff9808));
270 A_PRINTF("0x7890 0x%x ......\n", ioread32(0x10ff7890));
271 A_PRINTF("0x7890 0x%x ......\n", ioread32(0x10ff7890));
272 A_PRINTF("0x4088 0x%x ......\n", ioread32(0x10ff4088));
273 _fw_reset_dma_fifo();
276 static void _fw_reset_dma_fifo()
278 io8_set(0x100ae, 0x10);
279 io8_set(0x100af, 0x10);
280 A_PRINTF("_fw_reset_dma_fifo\n");
282 // disable ep3 int enable, so that resume back won't send wdt magic pattern out!!!
283 mUSB_STATUS_IN_INT_DISABLE();
285 /* update magic pattern to indicate this is a suspend */
286 iowrite32(WATCH_DOG_MAGIC_PATTERN_ADDR, SUS_MAGIC_PATTERN);
288 A_PRINTF("org 0x4048 0x%x ......\n", ioread32(0x10ff4048));
289 A_PRINTF("org 0x404C 0x%x ......\n", ioread32(0x10ff404C));
290 A_PRINTF("org 0x4088 0x%x ......\n", ioread32(0x10ff4088));
292 /* 1010.1010.1010.0110.1010 for UB94 */
293 iowrite32(0x10ff4088, 0xaaa6a);
294 iowrite32(0x10ff404C, 0x0);
297 A_PRINTF("0x4048 0x%x ......\n", ioread32(0x10ff4048));
298 A_PRINTF("0x404C 0x%x ......\n", ioread32(0x10ff404C));
299 A_PRINTF("0x4088 0x%x ......\n", ioread32(0x10ff4088));
304 A_PRINTF("turn_off_magpie_ep_start ......\n");
305 A_DELAY_USECS(measure_time);
306 io32_set(0x40040, BIT0 | BIT1);
308 io32_clr(0x40040, BIT0 | BIT1);
309 A_PRINTF("turn_off_magpie_ep_end ......\n");
312 A_PRINTF("turn_off_magpie_rc_start ......\n");
313 A_DELAY_USECS(measure_time);
314 io32_clr(0x40040, BIT0);
316 A_PRINTF("turn_off_magpie_rc_end ......down\n");
317 A_DELAY_USECS(measure_time);
319 A_PRINTF("0x4001C %p ......\n", ioread32(0x4001c));
320 A_PRINTF("0x40040 %p ......\n", ioread32(0x40040));
322 /* turn off pcie_pll - power down (bit16) */
323 A_PRINTF(" before pwd PCIE PLL CFG:0x5601C: 0x%08x\n",
325 io32_set(0x5601C, BIT18);
326 A_PRINTF(" after pwd PCIE PLL CFG:0x5601C: 0x%08x\n",
329 /* set everything to reset state?, requested by Oligo */
330 io32_set(0x50010, BIT13 | BIT12
331 | BIT11 | BIT9 | BIT7 | BIT6);
333 iowrite32(0x5C000, 0);
337 /* reset usb DMA controller */
338 iowrite32_usb(ZM_SOC_USB_DMA_RESET_OFFSET, 0x0);
340 io32_set(0x50010, BIT4);
342 io32_clr(0x50010, BIT4);
344 iowrite32_usb(ZM_SOC_USB_DMA_RESET_OFFSET, BIT0);
347 static void _fw_power_off()
351 * 2. turn off CPU PLL
352 * 3. turn off ETH PLL
353 * 4. disable ETH PLL bypass and update
354 * 4.1 set suspend timeout
355 * 5. set SUSPEND_ENABLE
358 iowrite32(MAGPIE_REG_CPU_PLL_BYPASS_ADDR, BIT0 | BIT4);
360 A_DELAY_USECS(100); // wait for stable
362 iowrite32(MAGPIE_REG_CPU_PLL_ADDR, BIT16);
364 A_DELAY_USECS(100); // wait for stable
366 A_UART_HWINIT((40*1000*1000), 19200);
369 io32_set(MAGPIE_REG_ETH_PLL_ADDR, BIT16);
371 io32_set(MAGPIE_REG_ETH_PLL_BYPASS_ADDR, BIT4 | BIT0);
373 io32_set(MAGPIE_REG_SUSPEND_ENABLE_ADDR, 0x10 << 8);
376 static void _fw_power_on()
380 * 2. disable CPU bypass
382 * 4. disable ETH PLL bypass and update
383 * 5. turn on pcie pll
386 io32_clr(MAGPIE_REG_ETH_PLL_ADDR, BIT16);
388 /* deassert eth_pll bypass mode and trigger update bit */
389 io32_clr(MAGPIE_REG_ETH_PLL_BYPASS_ADDR, BIT4 | BIT0);
392 static void _fw_restore_dma_fifo(void)
394 io32_clr(0x5601C, BIT18);
396 /* reset pcie_rc shift */
397 io32_clr(0x50010, BIT10 | BIT8 | BIT7);
399 io32_set(0x50010, BIT10 | BIT8 | BIT7);
401 /* reset pci_rc phy */
402 io32_set(MAGPIE_REG_RST_RESET_ADDR,
403 PCI_RC_PHY_SHIFT_RESET_BIT
404 | PCI_RC_PLL_RESET_BIT | PCI_RC_PHY_RESET_BIT
408 // enable dma swap function
409 MAGPIE_REG_USB_RX0_SWAP_DATA = 0x1;
410 MAGPIE_REG_USB_TX0_SWAP_DATA = 0x1;
411 MAGPIE_REG_USB_RX1_SWAP_DATA = 0x1;
412 MAGPIE_REG_USB_RX2_SWAP_DATA = 0x1;