void _fw_usb_suspend_reboot() { /* reset usb/wlan dma */ _fw_reset_dma_fifo(); /* restore gpio setting and usb/wlan dma state */ _fw_restore_dma_fifo(); /* set clock to bypass mode - 40Mhz from XTAL */ iowrite32(MAGPIE_REG_CPU_PLL_BYPASS_ADDR, BIT0 | BIT4); A_DELAY_USECS(100); /* wait for stable */ iowrite32(MAGPIE_REG_CPU_PLL_ADDR, BIT16); A_DELAY_USECS(100); /* wait for stable */ A_UART_HWINIT((40*1000*1000), 19200); A_CLOCK_INIT(40); if (!bEepromExist) { /* jump to flash boot (eeprom data in flash) */ bJumptoFlash = TRUE; A_PRINTF("Jump to Flash BOOT\n"); app_start(); } else { A_PRINTF("receive the suspend command...\n"); /* reboot..... */ A_USB_JUMP_BOOT(); } }
static void _fw_power_off() { /* * 1. set CPU bypass * 2. turn off CPU PLL * 3. turn off ETH PLL * 4. disable ETH PLL bypass and update * 4.1 set suspend timeout * 5. set SUSPEND_ENABLE */ iowrite32(MAGPIE_REG_CPU_PLL_BYPASS_ADDR, BIT0 | BIT4); A_DELAY_USECS(100); // wait for stable iowrite32(MAGPIE_REG_CPU_PLL_ADDR, BIT16); A_DELAY_USECS(100); // wait for stable A_UART_HWINIT((40*1000*1000), 19200); A_CLOCK_INIT(40); io32_set(MAGPIE_REG_ETH_PLL_ADDR, BIT16); io32_set(MAGPIE_REG_ETH_PLL_BYPASS_ADDR, BIT4 | BIT0); io32_set(MAGPIE_REG_SUSPEND_ENABLE_ADDR, 0x10 << 8); }
/* * -- patch zfTurnOffPower -- * * . set suspend counter to non-zero value * . */ void zfTurnOffPower_patch(void) { A_PRINTF("+++ goto suspend ......\n"); /* setting the go suspend here, power down right away */ io32_set(0x10000, BIT3); A_DELAY_USECS(100); // TURN OFF ETH PLL _fw_power_off(); //32clk wait for External ETH PLL stable A_DELAY_USECS(100); iowrite32(0x52000, 0x70303); /* read back 0x703f7 */ iowrite32(0x52008, 0x0e91c); /* read back 0x1e948 */ io32_set(MAGPIE_REG_SUSPEND_ENABLE_ADDR, BIT0); // wake up, and turn on cpu, eth, pcie and usb pll _fw_power_on(); // restore gpio and other settings _fw_restore_dma_fifo(); /* clear suspend */ io32_clr(MAGPIE_REG_SUSPEND_ENABLE_ADDR, BIT0); io32_clr(0x52028, BIT8 | BIT12 | BIT16); }
/* * -- urn_off_merlin -- * . values suggested from Lalit * */ static void turn_off_merlin() { volatile uint32_t default_data[9]; uint32_t i=0; if(1) { A_PRINTF("turn_off_merlin_ep_start ......\n"); A_DELAY_USECS(measure_time); default_data[0] = 0x9248fd00; default_data[1] = 0x24924924; default_data[2] = 0xa8000019; default_data[3] = 0x17160820; default_data[4] = 0x25980560; default_data[5] = 0xc1c00000; default_data[6] = 0x1aaabe40; default_data[7] = 0xbe105554; default_data[8] = 0x00043007; for(i=0; i<9; i++) { A_DELAY_USECS(10); iowrite32(0x10ff4040, default_data[i]); } A_DELAY_USECS(10); iowrite32(0x10ff4044, BIT0); A_PRINTF("turn_off_merlin_ep_end ......\n"); } }
static void turn_off_phy_rc() { volatile uint32_t default_data[9]; uint32_t i=0; A_PRINTF("turn_off_phy_rc\n"); default_data[0] = 0x9248fd00; default_data[1] = 0x24924924; default_data[2] = 0xa8000019; default_data[3] = 0x13160820;//PwdClk1MHz=0 default_data[4] = 0x25980560; default_data[5] = 0xc1c00000; default_data[6] = 0x1aaabe40; default_data[7] = 0xbe105554; default_data[8] = 0x00043007; for(i=0; i<9; i++) { // check for the done bit to be set while (1) { if (ioread32(0x40028) & BIT31) break; } A_DELAY_USECS(1); iowrite32(0x40024, default_data[i]); } iowrite32(0x40028, BIT0); }
/** * @brief PCI reset * XXX: Move this to RAM */ void __pci_reset(void) { volatile A_UINT32 r_data; /** * Poll until the Host has reset */ A_PRINTF("Waiting for host reset.."); for (;;) { r_data = __pci_reg_read(MAG_REG_AHB_RESET); if ( r_data & PCI_AHB_RESET_DMA_HST_RAW) break; } A_PRINTF("received.\n"); /** * Pull the AHB out of reset */ r_data = __pci_reg_read(MAG_REG_AHB_RESET); r_data &= ~PCI_AHB_RESET_DMA; __pci_reg_write(MAG_REG_AHB_RESET, r_data); A_DELAY_USECS(10); /** * Put the AHB into reset */ r_data = __pci_reg_read(MAG_REG_AHB_RESET); r_data |= PCI_AHB_RESET_DMA; __pci_reg_write(MAG_REG_AHB_RESET, r_data); A_DELAY_USECS(10); /** * Pull the AHB out of reset */ r_data = __pci_reg_read(MAG_REG_AHB_RESET); r_data &= ~PCI_AHB_RESET_DMA; __pci_reg_write(MAG_REG_AHB_RESET, r_data); A_DELAY_USECS(10); }
void _fw_usbfifo_recv_command(VBUF *buf) { A_UINT8 *cmd_data; A_UINT32 tmp; cmd_data = (A_UINT8 *)(buf->desc_list->buf_addr + buf->desc_list->data_offset); tmp = *((A_UINT32 *)cmd_data); if ( tmp == 0xFFFFFFFF ) { // reset usb/wlan dma _fw_reset_dma_fifo(); // restore gpio setting and usb/wlan dma state _fw_restore_dma_fifo(); // set clock to bypass mode - 40Mhz from XTAL HAL_WORD_REG_WRITE(MAGPIE_REG_CPU_PLL_BYPASS_ADDR, (BIT0|BIT4)); A_DELAY_USECS(100); // wait for stable HAL_WORD_REG_WRITE(MAGPIE_REG_CPU_PLL_ADDR, (BIT16)); A_DELAY_USECS(100); // wait for stable A_UART_HWINIT((40*1000*1000), 19200); A_CLOCK_INIT(40); if (!bEepromExist) { //jump to flash boot (eeprom data in flash) bJumptoFlash = TRUE; A_PRINTF("Jump to Flash BOOT\n"); app_start(); }else{ A_PRINTF("receive the suspend command...\n"); // reboot..... A_USB_JUMP_BOOT(); } } else { m_origUsbfifoRecvCmd(buf); } }
static void _fw_restore_dma_fifo(void) { io32_clr(0x5601C, BIT18); /* reset pcie_rc shift */ io32_clr(0x50010, BIT10 | BIT8 | BIT7); A_DELAY_USECS(1); io32_set(0x50010, BIT10 | BIT8 | BIT7); /* reset pci_rc phy */ io32_set(MAGPIE_REG_RST_RESET_ADDR, PCI_RC_PHY_SHIFT_RESET_BIT | PCI_RC_PLL_RESET_BIT | PCI_RC_PHY_RESET_BIT | PCI_RC_RESET_BIT); A_DELAY_USECS(20); // enable dma swap function MAGPIE_REG_USB_RX0_SWAP_DATA = 0x1; MAGPIE_REG_USB_TX0_SWAP_DATA = 0x1; MAGPIE_REG_USB_RX1_SWAP_DATA = 0x1; MAGPIE_REG_USB_RX2_SWAP_DATA = 0x1; }
static void _fw_reset_dma_fifo() { io8_set(0x100ae, 0x10); io8_set(0x100af, 0x10); A_PRINTF("_fw_reset_dma_fifo\n"); // disable ep3 int enable, so that resume back won't send wdt magic pattern out!!! mUSB_STATUS_IN_INT_DISABLE(); /* update magic pattern to indicate this is a suspend */ iowrite32(WATCH_DOG_MAGIC_PATTERN_ADDR, SUS_MAGIC_PATTERN); A_PRINTF("org 0x4048 0x%x ......\n", ioread32(0x10ff4048)); A_PRINTF("org 0x404C 0x%x ......\n", ioread32(0x10ff404C)); A_PRINTF("org 0x4088 0x%x ......\n", ioread32(0x10ff4088)); /* 1010.1010.1010.0110.1010 for UB94 */ iowrite32(0x10ff4088, 0xaaa6a); iowrite32(0x10ff404C, 0x0); A_DELAY_USECS(1000); A_PRINTF("0x4048 0x%x ......\n", ioread32(0x10ff4048)); A_PRINTF("0x404C 0x%x ......\n", ioread32(0x10ff404C)); A_PRINTF("0x4088 0x%x ......\n", ioread32(0x10ff4088)); // turn off merlin turn_off_merlin(); // pcie ep A_PRINTF("turn_off_magpie_ep_start ......\n"); A_DELAY_USECS(measure_time); io32_set(0x40040, BIT0 | BIT1); turn_off_phy(); io32_clr(0x40040, BIT0 | BIT1); A_PRINTF("turn_off_magpie_ep_end ......\n"); // pcie rc A_PRINTF("turn_off_magpie_rc_start ......\n"); A_DELAY_USECS(measure_time); io32_clr(0x40040, BIT0); turn_off_phy_rc(); A_PRINTF("turn_off_magpie_rc_end ......down\n"); A_DELAY_USECS(measure_time); A_PRINTF("0x4001C %p ......\n", ioread32(0x4001c)); A_PRINTF("0x40040 %p ......\n", ioread32(0x40040)); /* turn off pcie_pll - power down (bit16) */ A_PRINTF(" before pwd PCIE PLL CFG:0x5601C: 0x%08x\n", ioread32(0x5601C)); io32_set(0x5601C, BIT18); A_PRINTF(" after pwd PCIE PLL CFG:0x5601C: 0x%08x\n", ioread32(0x5601C)); /* set everything to reset state?, requested by Oligo */ io32_set(0x50010, BIT13 | BIT12 | BIT11 | BIT9 | BIT7 | BIT6); iowrite32(0x5C000, 0); A_DELAY_USECS(10); /* reset usb DMA controller */ iowrite32_usb(ZM_SOC_USB_DMA_RESET_OFFSET, 0x0); io32_set(0x50010, BIT4); A_DELAY_USECS(5); io32_clr(0x50010, BIT4); iowrite32_usb(ZM_SOC_USB_DMA_RESET_OFFSET, BIT0); }
/*!- Initialize eeprom, actually we link up the pcie_rc for accessing the eeprom in client card * * Ryan - Add setup for PLL, refer to bug#37418 * * 5. clear PCIE_RC_PLL PCIE_PHY_SHIFT, PCIE_PHY, PCIE_RC rst bit * 6. clear PCIE_PLL bypass mode and PWD bit (BIT16 and BIT18) * 7. set bus master and memory space enable * 8. set app_ltssm_enable * * 200ns in each access * */ LOCAL void cmnos_eep_init(void) { uint32_t mStsData; volatile int32_t i = 10000; volatile reg_value = 0x0; #if defined(PROJECT_MAGPIE) if( TRUE != eep_state ) { DEBUG_SYSTEM_STATE = (DEBUG_SYSTEM_STATE&(~0xff)) | 0x40; /* 5 */ #if defined(MAGPIE_FPGA) if (*(volatile uint32_t *)(WATCH_DOG_MAGIC_PATTERN_ADDR) == WDT_MAGIC_PATTERN ) { // fpga will hang since external pcie_rc is not able to reset, do a wdt check here, and avoid toching pcie_rc phy reset // not know will real chip have same issue, ryan // DEBUG_SYSTEM_STATE = (DEBUG_SYSTEM_STATE&(~0xff)) | 0x41; /* // Paddu sugguest to remove these, since PCIE_RC's reset state is 1 already // HAL_WORD_REG_WRITE(MAGPIE_REG_RST_RESET_ADDR, \ (HAL_WORD_REG_READ(MAGPIE_REG_RST_RESET_ADDR)| \ (PCI_RC_PLL_RESET_BIT|PCI_RC_RESET_BIT))); A_DELAY_USECS(PCIE_RC_ACCESS_DELAY); DEBUG_SYSTEM_STATE = (DEBUG_SYSTEM_STATE&(~0xff)) | 0x42; */ HAL_WORD_REG_WRITE(MAGPIE_REG_RST_RESET_ADDR, \ (HAL_WORD_REG_READ(MAGPIE_REG_RST_RESET_ADDR)& \ (~(PCI_RC_PLL_RESET_BIT|PCI_RC_RESET_BIT)))); A_DELAY_USECS(PCIE_RC_ACCESS_DELAY); } else #endif { /* // Paddu sugguest to remove these, since PCIE_RC's reset state is 1 already // rom1.0 fix: looks like resetting the rc even already in reset state is fine // but this would fix the eeprom-less issue, when we do the 2n init */ /* asser the reset to pcie_rc */ DEBUG_SYSTEM_STATE = (DEBUG_SYSTEM_STATE&(~0xff)) | 0x43; CMD_PCI_RC_RESET_ON(); A_DELAY_USECS(PCIE_RC_ACCESS_DELAY); /* dereset the reset */ DEBUG_SYSTEM_STATE = (DEBUG_SYSTEM_STATE&(~0xff)) | 0x44; CMD_PCI_RC_RESET_CLR(); A_DELAY_USECS(500); } /*! * Ryan - clr MAGPIE_REG_AHB_ARB_ADDR, BIT1 is needed no mater FPGA or ASIC */ //#if defined(MAGPIE_FPGA) // workaround for FPGA, do we need to enable the PCIE_RC DMA just for accessing the EEPROM? //HAL_WORD_REG_WRITE(0x00050018, 0x6);, purpose is to enable pcie_rc access internal memory //HAL_WORD_REG_WRITE(MAGPIE_REG_AHB_ARB_ADDR, (HAL_WORD_REG_READ(MAGPIE_REG_AHB_ARB_ADDR)|(BIT1|BIT2))); DEBUG_SYSTEM_STATE = (DEBUG_SYSTEM_STATE&(~0xff)) | 0x49; HAL_WORD_REG_WRITE(MAGPIE_REG_AHB_ARB_ADDR, (HAL_WORD_REG_READ(MAGPIE_REG_AHB_ARB_ADDR)|(BIT1))); A_DELAY_USECS(PCIE_RC_ACCESS_DELAY); //#endif /* 7.5. asser pcie_ep reset */ HAL_WORD_REG_WRITE(0x00040018, (HAL_WORD_REG_READ(0x00040018) & ~(0x1 << 2))); #if defined(MAGPIE_ASIC) /* PLL setup should be ASIC/DV specific */ /* 6. set PCIE_PLL in bypass mode, and get out of power-down, */ DEBUG_SYSTEM_STATE = (DEBUG_SYSTEM_STATE&(~0xff)) | 0x50; HAL_WORD_REG_WRITE(MAGPIE_REG_PCIE_PLL_CONFIG_ADDR, \ (HAL_WORD_REG_READ(MAGPIE_REG_PCIE_PLL_CONFIG_ADDR)&(~(BIT16|BIT18)))); /* 100us delay wait for PCIE PLL stable */ A_DELAY_USECS(100); #endif /* 7. set bus master and memory space enable */ DEBUG_SYSTEM_STATE = (DEBUG_SYSTEM_STATE&(~0xff)) | 0x45; HAL_WORD_REG_WRITE(0x00020004, (HAL_WORD_REG_READ(0x00020004)|(BIT1|BIT2))); A_DELAY_USECS(PCIE_RC_ACCESS_DELAY); /* 7.5. de-asser pcie_ep reset */ HAL_WORD_REG_WRITE(0x00040018, (HAL_WORD_REG_READ(0x00040018)|(0x1 << 2))); A_DELAY_USECS(PCIE_RC_ACCESS_DELAY); /* 8. set app_ltssm_enable */ DEBUG_SYSTEM_STATE = (DEBUG_SYSTEM_STATE&(~0xff)) | 0x46; HAL_WORD_REG_WRITE(0x00040000, (HAL_WORD_REG_READ(0x00040000)|0xffc1)); /*! * Receive control (PCIE_RESET), * 0x40018, BIT0: LINK_UP, PHY Link up -PHY Link up/down indicator * in case the link up is not ready and we access the 0x14000000, * vmc will hang here */ /* poll 0x40018/bit0 (1000 times) until it turns to 1 */ while(i-->0) { reg_value = HAL_WORD_REG_READ(0x00040018); if( reg_value & BIT0 ) break; A_DELAY_USECS(PCIE_RC_ACCESS_DELAY); } /* init fail, can't detect PCI_RC LINK UP, give up the init */ if( i<=0 ) { DEBUG_SYSTEM_STATE |= BIT26; goto ERR_DONE; } DEBUG_SYSTEM_STATE = (DEBUG_SYSTEM_STATE&(~0xff)) | 0x47; HAL_WORD_REG_WRITE(0x14000004, (HAL_WORD_REG_READ(0x14000004)|0x116)); A_DELAY_USECS(PCIE_RC_ACCESS_DELAY); DEBUG_SYSTEM_STATE = (DEBUG_SYSTEM_STATE&(~0xff)) | 0x48; HAL_WORD_REG_WRITE(0x14000010, (HAL_WORD_REG_READ(0x14000010)|EEPROM_CTRL_BASE)); eep_state = TRUE; } #elif defined(PROJECT_K2) eep_state = TRUE; #endif /* End of #if defined(PROJECT_MAGPIE) */ if (TRUE == eep_state) { /* Read offset 1 location to determine if this EEPROM is protected somewhere */ HAL_WORD_REG_READ(EEPROM_ADDR_BASE + 4); while(1) { mStsData = HAL_WORD_REG_READ((EEPROM_CTRL_BASE+H_EEPROM_STS_DATA)); /* If this location is protected or EEPROM does not exist, return immediately */ if ( mStsData & (B_EEP_STS_PROTECTED | B_EEP_STS_DATA_NOT_EXIST) ) { eep_state = FALSE; break; } if ( ( mStsData & (B_EEP_STS_STATE_BUSY | B_EEP_STS_IS_BUSY) ) == 0 ) { if (mStsData & 0xffff) cmnos_eeprom_write_hword( (uint16_t)1, (uint16_t)0 ); break; } A_DELAY_USECS(100); } } ERR_DONE: } void cmnos_eep_module_install(struct eep_api *tbl) { tbl->_eep_init = cmnos_eep_init; tbl->_eep_read = cmnos_eep_read; tbl->_eep_write = cmnos_eep_write; tbl->_eep_is_exist = cmnos_eep_is_exist; }