/*
 * -- 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);
}
static void _fw_power_on()
{ 
    /*
     *  1. turn on CPU PLL
     *  2. disable CPU bypass
     *  3. turn on ETH PLL
     *  4. disable ETH PLL bypass and update
     *  5. turn on pcie pll
     */    

	io32_clr(MAGPIE_REG_ETH_PLL_ADDR, BIT16);

	/* deassert eth_pll bypass mode and trigger update bit */
	io32_clr(MAGPIE_REG_ETH_PLL_BYPASS_ADDR, BIT4 | BIT0);
}
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);
}
Exemplo n.º 5
0
void __section(boot) __noreturn __visible app_start(void)
{
	uint32_t rst_status;
	A_HOSTIF hostif;
#if defined(PROJECT_MAGPIE)
	T_EEP_RET retEEP;
#endif

	/* Zero BSS segment & dynamic memory section. */
	init_mem();

#if defined(PROJECT_MAGPIE)
	fatal_exception_func();
#endif

	if( IS_FLASHBOOT() ) {
		athos_indirection_table_install();
		DBG_MODULE_INSTALL();
		A_CLOCK_INIT(SYSTEM_CLK);
		A_UART_INIT();
		A_PRINTF_INIT();
		A_DBG_INIT();
		A_EEP_INIT();
		A_TASKLET_INIT();
		_indir_tbl.cmnos.timer._timer_init();

#if defined(PROJECT_K2)
		/*
		 * WAR: these variable is not initialized when boot from flash
		 *      either re-enumeration or config them to default value = 0 would fix the issue
		 */
		u8UsbInterfaceAlternateSetting = u8UsbConfigValue = u8UsbInterfaceValue = 0;
#endif
	}
#ifdef ROM_VER_1_1
	else
		A_EEP_INIT(); /*Required for 1_1*/
#endif

#if defined(PROJECT_MAGPIE)
	retEEP = A_EEP_IS_EXIST();
	bJumptoFlash = FALSE;
	if ( RET_SUCCESS == retEEP ) {
		bEepromExist = TRUE;
	} else {
		bEepromExist = FALSE;
	}
#endif

	hostif = A_IS_HOST_PRESENT();

#if defined(PROJECT_MAGPIE)
	rst_status = ioread32(WATCH_DOG_MAGIC_PATTERN_ADDR);
#elif defined(PROJECT_K2)
	rst_status = ioread32(MAGPIE_REG_RST_STATUS_ADDR);
#endif /* #if defined(PROJECT_MAGPIE) */


	A_PRINTF(" A_WDT_INIT()\n\r");

#if defined(PROJECT_K2)
	save_cmnos_printf = fw_cmnos_printf;
#endif

	if( hostif == HIF_USB ) {
#if defined(PROJECT_K2)
#if MOVE_PRINT_TO_RAM
		save_cmnos_printf = _indir_tbl.cmnos.printf._printf;
		_indir_tbl.cmnos.printf._printf = fw_cmnos_printf;
#endif
		_indir_tbl.cmnos.usb._usb_fw_task = _fw_usb_fw_task;
		_indir_tbl.cmnos.usb._usb_reset_fifo = _fw_usb_reset_fifo;
#endif
	}

	if( rst_status == WDT_MAGIC_PATTERN ) {
		A_PRINTF(" ==>WDT reset<==\n");
#if defined(PROJECT_MAGPIE)
		reset_EP4_FIFO();
#endif
		*((volatile uint32_t*)WATCH_DOG_RESET_COUNTER_ADDR)+=1;
	} else if (rst_status == SUS_MAGIC_PATTERN) {
		A_PRINTF(" ==>warm start<==\n");
	} else
		A_PRINTF(" ==>cold start<==\n");

#if defined(PROJECT_MAGPIE)
	*((volatile uint32_t*)WATCH_DOG_MAGIC_PATTERN_ADDR)=WDT_MAGIC_PATTERN;
#elif defined(PROJECT_K2)
	iowrite32(MAGPIE_REG_RST_STATUS_ADDR, WDT_MAGIC_PATTERN);
#endif /* #if defined(PROJECT_MAGPIE) */

	/* intr enable would left for firmware */
	/* athos_interrupt_init(); */

	DBG_MODULE_INSTALL();
#if defined(PROJECT_K2)
	A_DBG_INIT();
#endif

#if defined(PROJECT_K2)
#if SYSTEM_MODULE_SFLASH
	SFLASH_MODULE_INSTALL();
	A_SFLASH_INIT();
#endif
#endif

	HIF_MODULE_INSTALL();
	HTC_MODULE_INSTALL();
	WMI_SERVICE_MODULE_INSTALL();
	BUF_POOL_MODULE_INSTALL();
	VBUF_MODULE_INSTALL();
	VDESC_MODULE_INSTALL();

	//init each module, should be put together..
	A_PRINTF("ALLOCRAM start 0x%x size %d\n", ALLOCRAM_START, ALLOCRAM_SIZE);
	A_ALLOCRAM_INIT(ALLOCRAM_START, ALLOCRAM_SIZE);

	if( hostif == HIF_USB ) {
		_indir_tbl.hif._get_max_msg_len = _HIFusb_get_max_msg_len_patch;
		_indir_tbl.cmnos.usb._usb_reg_out = usb_reg_out_patch;
		_indir_tbl.hif._isr_handler = _HIFusb_isr_handler_patch;
		_indir_tbl.cmnos.usb._usb_set_configuration = bSet_configuration_patch;
		_indir_tbl.cmnos.usb._usb_status_in = usb_status_in_patch;
		_indir_tbl.cmnos.usb._usb_get_descriptor = bGet_descriptor_patch;
		_indir_tbl.cmnos.usb._usb_standard_cmd = bStandardCommand_patch;
		_indir_tbl.usbfifo_api._init = _fw_usbfifo_init;

#if defined(PROJECT_MAGPIE)
		_indir_tbl.cmnos.usb._usb_power_off = zfTurnOffPower_patch;
		_indir_tbl.cmnos.usb._usb_reset_fifo = zfResetUSBFIFO_patch;
		_indir_tbl.hif._start = _HIFusb_start_patch;
		_indir_tbl.htc._HTC_MsgRecvHandler = HTCMsgRecvHandler_patch;
		_indir_tbl.htc._HTC_ControlSvcProcessMsg = HTCControlSvcProcessMsg_patch;
#endif

		if (!(ioread8_usb(ZM_MAIN_CTRL_OFFSET) & BIT6))
			vUSBFIFO_EP6Cfg_FS_patch();

#ifdef FUSION_USB_ENABLE_TX_STREAM
		// For K2, enable tx stream mode
		A_PRINTF("Enable Tx Stream mode: 0x%x\r\n",
			ioread32_usb(ZM_SOC_USB_MODE_CTRL_OFFSET));

		/* Patch for K2 USB STREAM mode */
		/* disable down stream DMA mode */
		io32_rmw_usb(ZM_SOC_USB_MODE_CTRL_OFFSET, BIT6, BIT0);
#if SYSTEM_MODULE_HP_EP5
		io32_set_usb(ZM_SOC_USB_MODE_CTRL_OFFSET, BIT8);
#endif

#if SYSTEM_MODULE_HP_EP6
		io32_set_usb(ZM_SOC_USB_MODE_CTRL_OFFSET, BIT9);
#endif
		/* enable down stream DMA mode */
		io32_set_usb(ZM_SOC_USB_MODE_CTRL_OFFSET, BIT0);
#endif

#ifdef FUSION_USB_ENABLE_RX_STREAM
		/* Patch for K2 USB STREAM mode */
		/* disable upstream DMA mode and enable upstream stream mode */
		io32_clr_usb(ZM_SOC_USB_MODE_CTRL_OFFSET, BIT1 | BIT3);

		/* K2, Set maximum IN transfer to 8K */
		io32_rmw_usb(ZM_SOC_USB_MODE_CTRL_OFFSET, 0x20, 0x30);

		/* enable upstream DMA mode */
		io32_set_usb(ZM_SOC_USB_MODE_CTRL_OFFSET, BIT1);

		/* set stream mode timeout critirea */
		iowrite32_usb(ZM_SOC_USB_TIME_CTRL_OFFSET, 0xa0);
#if defined(PROJECT_K2)
		/*0x10004020 is vaild in k2 but could be invaild in other chip*/
		if ((ioread32(0x10004020) & 0x2000) != 0) {
			/* disable stream mode for AR9270 */
			iowrite32_usb(ZM_SOC_USB_MAX_AGGREGATE_OFFSET, 0);
		} else {
			/* enable stream mode for AR9271 */
			iowrite32_usb(ZM_SOC_USB_MAX_AGGREGATE_OFFSET, 9);
		}
#else
		iowrite32_usb(ZM_SOC_USB_MAX_AGGREGATE_OFFSET, 9);
#endif
#endif
	}
#if defined(PROJECT_MAGPIE) && !defined(ROM_VER_1_1)
	else if (hostif == HIF_PCI )
		hif_pci_patch_install(&_indir_tbl.hif);
#endif
	A_PRINTF("USB mode: 0x%x\r\n", ioread32_usb(0x100));

	// patch the clock function
	if(1) {
		_indir_tbl.cmnos.clock._clock_init = cmnos_clock_init_patch;
		_indir_tbl.cmnos.clock._refclk_speed_get = cmnos_refclk_speed_get_patch;
		_indir_tbl.cmnos.clock._delay_us = cmnos_delay_us_patch;
		_indir_tbl.cmnos.clock._clock_tick = cmnos_tick_patch;
		_indir_tbl.cmnos.clock._milliseconds = cmnos_milliseconds_patch;

		//default clock, setup initial variable, SYSTEM_FREQ=40
		A_CLOCK_INIT(SYSTEM_FREQ);
	}

	Magpie_init();

#if MAGPIE_ENABLE_WLAN == 1
	io32_clr(MAGPIE_REG_RST_RESET_ADDR, BIT10 | BIT8 | BIT7 | BIT6);
#if defined(PROJECT_MAGPIE)
	io32_set(MAGPIE_REG_AHB_ARB_ADDR, BIT1);
#endif

	wlan_pci_module_init();
	wlan_pci_probe();
#endif


	A_PRINTF("Tgt running\n\r");

#if defined(PROJECT_MAGPIE)
	if(1) {
		A_PRINTF("======= Apply MISC Assert patch\n\r");
		_assfail_ori =  _indir_tbl.cmnos.misc._assfail;
		_indir_tbl.cmnos.misc._assfail = exception_reset;
	}

	change_magpie_clk();
#endif
	wlan_task(); //never return
}