void usb11_hs_slew_rate_cal(void){

  unsigned long data;
  unsigned long x;
  unsigned char value;
  unsigned long start_time, timeout;
  unsigned int timeout_flag = 0;
  //4 s1:enable usb ring oscillator.
  USB11PHY_WRITE8(0x15,0x80);
  
  //4 s2:wait 1us.
  udelay(1);
  
  //4 s3:enable free run clock
  USB11PHY_WRITE8 (0xf00-0x900+0x11,0x01);
  //4 s4:setting cyclecnt.
  USB11PHY_WRITE8 (0xf00-0x900+0x01,0x04);
  //4 s5:enable frequency meter
  USB11PHY_SET8 (0xf00-0x900+0x03,0x05);
  
  //4 s6:wait for frequency valid.
  start_time = jiffies;
  timeout = jiffies + 3 * HZ;
  while(!(USB11PHY_READ8(0xf00-0x900+0x10)&0x1)){
    if(time_after(jiffies, timeout)){
        timeout_flag = 1;
        break;
        }
    }
    
  //4 s7: read result.
  if(timeout_flag){
    printk("[USBPHY] Slew Rate Calibration: Timeout\n");
    value = 0x4;
    }
  else{
      data = USB11PHY_READ32 (0xf00-0x900+0x0c);
      x = ((1024*FRA*PARA)/data);
      value = (unsigned char)(x/1000);
      if((x-value*1000)/100>=5)
        value += 1;
        // printk("[USB11PHY]slew calibration:FM_OUT =%d, x=%d,value=%d\n",data,x,value);
    }
   
  //4 s8: disable Frequency and run clock.
  USB11PHY_CLR8 (0xf00-0x900+0x03,0x05);//disable frequency meter
  USB11PHY_CLR8 (0xf00-0x900+0x11,0x01);//disable free run clock
  
  //4 s9: 
  USB11PHY_WRITE8(0x15,value<<4);
  
  //4 s10:disable usb ring oscillator.
  USB11PHY_CLR8(0x15,0x80);  
}
static void musbfsh_port_reset(struct musbfsh *musbfsh, bool do_reset)
{
	u8 power;
	void __iomem *mbase = musbfsh->mregs;

	/* NOTE:  caller guarantees it will turn off the reset when
	 * the appropriate amount of time has passed
	 */
	power = musbfsh_readb(mbase, MUSBFSH_POWER);
	WARNING("reset=%d power=0x%x\n", do_reset, power);
	if (do_reset) {
		if (power & MUSBFSH_POWER_SUSPENDM) {
			WARNING("reset a suspended device\n");
#ifdef CONFIG_MTK_DT_USB_SUPPORT
			request_wakeup_md_timeout(0, 0);
#endif

#ifdef MTK_USB_RUNTIME_SUPPORT
			/* ERR("EINT to wake up MD for reset\n"); */
			/* wx, we may have to reset a suspended MD */
			/* request_wakeup_md_timeout(0, 0); */
#endif
			musbfsh_writeb(mbase,
				       MUSBFSH_POWER, power |
				       MUSBFSH_POWER_RESUME);
			mdelay(20);
			musbfsh_writeb(mbase, MUSBFSH_POWER,
				       power & ~MUSBFSH_POWER_RESUME);
		}

		/*
		 * If RESUME is set, we must make sure it stays minimum 20 ms.
		 * Then we must clear RESUME and wait a bit to let musb start
		 * generating SOFs. If we don't do this, OPT HS A 6.8 tests
		 * fail with "Error! Did not receive an SOF before suspend
		 * detected".
		 */
		if (power & MUSBFSH_POWER_RESUME) {
			WARNING("reset a resuming device\n");
			while (time_before(jiffies, musbfsh->rh_timer))
				mdelay(1);
			/* stop the resume signal */
			musbfsh_writeb(mbase, MUSBFSH_POWER,
				       power & ~MUSBFSH_POWER_RESUME);
			mdelay(1);
		}

		musbfsh->ignore_disconnect = true;
		power &= 0xf0;
		musbfsh_writeb(mbase, MUSBFSH_POWER,
			       power | MUSBFSH_POWER_RESET);
		mb();  /* flush POWER and PHY setting immediately */
		musbfsh->port1_status |= USB_PORT_STAT_RESET;
		musbfsh->port1_status &= ~USB_PORT_STAT_ENABLE;
		musbfsh->rh_timer = jiffies + msecs_to_jiffies(50);
	} else {
		INFO("Root port reset stopped\n");

#ifdef CONFIG_MTK_ICUSB_SUPPORT

		if (resistor_control_attr.value) {
			/* improve signal quality, from Dingjun */
#if 0
			/* FS_DISC_DISABLE */
			u32 TM1;

			TM1 = musbfsh_readl(mbase, 0x604);
			musbfsh_writel(mbase, 0x604, TM1 | 0x4);
			MYDBG("set FS_DISC_DISABLE\n");
#endif

			/* original flow from SS5 */
			USB11PHY_SET8(U1PHTCR2,
				      force_usb11_dm_rpd | force_usb11_dp_rpd);

			/*
			 * disconnect host port's pull down resistors
			 * on D+ and D-
			 */
			USB11PHY_CLR8(U1PHTCR2,
				      RG_USB11_DM_RPD | RG_USB11_DP_RPD);

			/*
			 * Tell MAC there still is a device attached,
			 * ohterwise we will get disconnect interrupt
			 */
			USB11PHY_SET8(U1PHTCR2,
				      force_usb11_dp_rpu | RG_USB11_DP_RPU);

			/* force */
			USB11PHY_SET8(0x6a, 0x20 | 0x10);
			/* RG */
			/*
			 * disconnect host port's pull down resistors
			 * on D+ and D-
			 */
			USB11PHY_CLR8(0x68, 0x80 | 0x40);

			/*
			 * Tell MAC there still is a device attached,
			 * ohterwise we will get disconnect interrupt.
			 */
			/* USB11PHY_SET8(U1PHTCR2,
			 *		 force_usb11_dp_rpu |
			 *		 RG_USB11_DP_RPU);
			 */

			MYDBG("USB1.1 PHY special config for IC-USB\n");
		} else {
			MYDBG("");
		}
#endif
		musbfsh_writeb(mbase,
			       MUSBFSH_POWER, power & ~MUSBFSH_POWER_RESET);


#ifdef CONFIG_MTK_ICUSB_SUPPORT
		if (resistor_control_attr.value)
			USB11PHY_CLR8(0x6a, 0x20 | 0x10);
		else
			MYDBG("");
#endif
		mb(); /* flush POWER and PHY setting immediately */
		musbfsh->ignore_disconnect = false;

		power = musbfsh_readb(mbase, MUSBFSH_POWER);
		if (power & MUSBFSH_POWER_HSMODE) {
			INFO("high-speed device connected\n");
			musbfsh->port1_status |= USB_PORT_STAT_HIGH_SPEED;
		}
#if 0				/* IC_USB from SS5 */
#ifdef IC_USB
		USB11PHY_SET8(U1PHTCR2,
			      force_usb11_dm_rpd | force_usb11_dp_rpd);

		/* disconnect host port's pull down resistors on D+ and D- */
		USB11PHY_CLR8(U1PHTCR2, RG_USB11_DM_RPD | RG_USB11_DP_RPD);

		/*
		 * tell MAC there still is a device attached,
		 * ohterwise we will get disconnect interrupt
		 */
		USB11PHY_SET8(U1PHTCR2, force_usb11_dp_rpu | RG_USB11_DP_RPU);
		WARNING("USB1.1 PHY special config for IC-USB 0x%X=%x\n",
			U1PHTCR2, USB11PHY_READ8(U1PHTCR2));
#endif
#endif
		musbfsh->port1_status &= ~USB_PORT_STAT_RESET;
		musbfsh->port1_status |=
			USB_PORT_STAT_ENABLE | (USB_PORT_STAT_C_RESET << 16) |
			(USB_PORT_STAT_C_ENABLE << 16);

		/* call back func to notify the hub thread the state of hub! */
		usb_hcd_poll_rh_status(musbfsh_to_hcd(musbfsh));

		musbfsh->vbuserr_retry = VBUSERR_RETRY_COUNT;
	}
}
Exemple #3
0
static void musbfsh_port_reset(struct musbfsh *musbfsh, bool do_reset)
{
	u8		power;
	void __iomem	*mbase = musbfsh->mregs;

	/* NOTE:  caller guarantees it will turn off the reset when
	 * the appropriate amount of time has passed
	 */
	power = musbfsh_readb(mbase, MUSBFSH_POWER);
	WARNING("reset=%d power=0x%x\n", do_reset, power);
	if (do_reset) {
		if(power & MUSBFSH_POWER_SUSPENDM) {
			WARNING("reset a suspended device\n");

#ifdef MTK_USB_RUNTIME_SUPPORT
			//ERR("EINT to wake up MD for reset\n");
			//request_wakeup_md_timeout(0, 0); //wx, we may have to reset a suspended MD
#endif
			musbfsh_writeb(mbase, MUSBFSH_POWER,
				power | MUSBFSH_POWER_RESUME);
			mdelay(20);
			musbfsh_writeb(mbase, MUSBFSH_POWER,
				power & ~MUSBFSH_POWER_RESUME);
		}

		/*
		 * If RESUME is set, we must make sure it stays minimum 20 ms.
		 * Then we must clear RESUME and wait a bit to let musb start
		 * generating SOFs. If we don't do this, OPT HS A 6.8 tests
		 * fail with "Error! Did not receive an SOF before suspend
		 * detected".
		 */
		if (power &  MUSBFSH_POWER_RESUME) {
			WARNING("reset a resuming device\n");
			while (time_before(jiffies, musbfsh->rh_timer))
				mdelay(1);
			musbfsh_writeb(mbase, MUSBFSH_POWER,//stop the resume signal
				power & ~MUSBFSH_POWER_RESUME);
			mdelay(1);
		}

		musbfsh->ignore_disconnect = true;
		power &= 0xf0;
		musbfsh_writeb(mbase, MUSBFSH_POWER,
				power | MUSBFSH_POWER_RESET);
		mb();
		musbfsh->port1_status |= USB_PORT_STAT_RESET;
		musbfsh->port1_status &= ~USB_PORT_STAT_ENABLE;
		musbfsh->rh_timer = jiffies + msecs_to_jiffies(50);
	} else {
		INFO( "Root port reset stopped\n");
		musbfsh_writeb(mbase, MUSBFSH_POWER,
				power & ~MUSBFSH_POWER_RESET);
		mb();
		musbfsh->ignore_disconnect = false;

		power = musbfsh_readb(mbase, MUSBFSH_POWER);
		if (power & MUSBFSH_POWER_HSMODE) {
			INFO( "high-speed device connected\n");
			musbfsh->port1_status |= USB_PORT_STAT_HIGH_SPEED;
		}
#ifdef IC_USB
		USB11PHY_SET8(U1PHTCR2, force_usb11_dm_rpd | force_usb11_dp_rpd);
		USB11PHY_CLR8(U1PHTCR2, RG_USB11_DM_RPD | RG_USB11_DP_RPD);  // disconnect host port's pull down resistors on D+ and D-
		USB11PHY_SET8(U1PHTCR2, force_usb11_dp_rpu | RG_USB11_DP_RPU); // tell MAC there still is a device attached, ohterwise we will get disconnect interrupt
		WARNING("USB1.1 PHY special config for IC-USB 0x%X=%x\n", U1PHTCR2, USB11PHY_READ8(U1PHTCR2));
#endif
		musbfsh->port1_status &= ~USB_PORT_STAT_RESET;
		musbfsh->port1_status |= USB_PORT_STAT_ENABLE
					| (USB_PORT_STAT_C_RESET << 16)
					| (USB_PORT_STAT_C_ENABLE << 16);
		usb_hcd_poll_rh_status(musbfsh_to_hcd(musbfsh));//call back func to notify the hub thread the state of hub!

		musbfsh->vbuserr_retry = VBUSERR_RETRY_COUNT;
	}
}