Example #1
0
int xhci_hcd_init(int index, struct xhci_hccr **hccr, struct xhci_hcor **hcor)
{
	u3phy_init();
	mt7621_phy_init(u3phy);

	reinitIP();

	u2_slew_rate_calibration(u3phy);
	u2_slew_rate_calibration(u3phy_p1);

	*hccr = (uint32_t)XHC_IO_START;
	*hcor = (struct xhci_hcor *)((uint32_t) *hccr
				+ HC_LENGTH(xhci_readl(&(*hccr)->cr_capbase)));

	debug("mtk-xhci: init hccr %x and hcor %x hc_length %d\n",
		(uint32_t)*hccr, (uint32_t)*hcor,
		(uint32_t)HC_LENGTH(xhci_readl(&(*hccr)->cr_capbase)));

	return 0;
}
Example #2
0
int
uphy_init(void)
{
	u32 i, reg_val, check_val, num_port_u2, num_port_u3;

	if (atomic_inc_return(&uphy_init_instance) != 1)
		return 0;

	/* patch TxDetRx Timing for E1, from DR 20160421, Biker_20160516 */
	reg_val = uphy_read32(ADDR_SIFSLV_PHYD_B2_BASE + 0x28);
	reg_val &= ~(0x1ff << 9);
	reg_val |=  (0x010 << 9);
	uphy_write32(ADDR_SIFSLV_PHYD_B2_BASE + 0x28, reg_val);

	reg_val = uphy_read32(ADDR_SIFSLV_PHYD_B2_BASE + 0x2c);
	reg_val &= ~0x1ff;
	reg_val |=  0x010;
	uphy_write32(ADDR_SIFSLV_PHYD_B2_BASE + 0x2c, reg_val);

	/* patch LFPS Filter Threshold for E1, from DR 20160421, Biker_20160516 */
	reg_val = uphy_read32(ADDR_SIFSLV_PHYD_BASE + 0x0c);
	reg_val &= ~(0x3f << 16);
	reg_val |=  (0x34 << 16);
	uphy_write32(ADDR_SIFSLV_PHYD_BASE + 0x0c, reg_val);

	/* configure for XTAL 25MHz */
	if (VPint(CR_AHB_HWCONF) & 0x01) {
		uphy_write8(ADDR_SIFSLV_PHYA_DA_BASE + 0x1c, 0x18);
		uphy_write8(ADDR_SIFSLV_PHYA_DA_BASE + 0x1d, 0x18);
		uphy_write8(ADDR_SIFSLV_PHYA_DA_BASE + 0x1f, 0x18);
		uphy_write32(ADDR_SIFSLV_PHYA_DA_BASE + 0x24, 0x18000000);
		uphy_write32(ADDR_SIFSLV_PHYA_DA_BASE + 0x28, 0x18000000);
		uphy_write32(ADDR_SIFSLV_PHYA_DA_BASE + 0x30, 0x18000000);
		uphy_write32(ADDR_SIFSLV_PHYA_DA_BASE + 0x38, 0x004a004a);
		uphy_write8(ADDR_SIFSLV_PHYA_DA_BASE + 0x3e, 0x4a);
		uphy_write8(ADDR_SIFSLV_PHYA_DA_BASE + 0x3f, 0x0);
		uphy_write8(ADDR_SIFSLV_PHYA_DA_BASE + 0x42, 0x48);
		uphy_write8(ADDR_SIFSLV_PHYA_DA_BASE + 0x43, 0x0);
		uphy_write8(ADDR_SIFSLV_PHYA_DA_BASE + 0x44, 0x48);
		uphy_write8(ADDR_SIFSLV_PHYA_DA_BASE + 0x45, 0x0);
		uphy_write8(ADDR_SIFSLV_PHYA_DA_BASE + 0x48, 0x48);
		uphy_write8(ADDR_SIFSLV_PHYA_DA_BASE + 0x49, 0x0);

		uphy_write8(ADDR_SIFSLV_PHYA_BASE + 0x24, 0x90);
		uphy_write8(ADDR_SIFSLV_PHYA_BASE + 0x25, 0x1);
		uphy_write32(ADDR_SIFSLV_PHYA_BASE + 0x10, 0x1c000000);
		uphy_write8(ADDR_SIFSLV_PHYA_BASE + 0x0b, 0xe);
	}

	reg_val = uphy_read32(REG_SSUSB_IP_CAP);
	num_port_u3 = SSUSB_U3_PORT_NUM(reg_val);
	num_port_u2 = SSUSB_U2_PORT_NUM(reg_val);

	if (isEN7513 || isEN7513G) {
		printk(KERN_INFO "%s USB PHY config\n", "EN7513 (BGA)");

		uphy_write32(ADDR_U2_PHY_P0_BASE + 0x1c, 0xC0240008); /* enable port 0 */
		uphy_write32(ADDR_U2_PHY_P1_BASE + 0x1c, 0xC0240000); /* enable port 1 */
	} else if (isEN7512) {
		printk(KERN_INFO "%s USB PHY config\n", "EN7512 (QFP)");

		uphy_write32(ADDR_U2_PHY_P0_BASE + 0x1c, 0xC0241580); /* disable port 0 */
		uphy_write32(ADDR_U2_PHY_P1_BASE + 0x1c, 0xC0240000); /* enable port 1 */
	}

	/* calibrate UPHY */
	u2_slew_rate_calibration(0, ADDR_U2_PHY_P0_BASE);
	u2_slew_rate_calibration(1, ADDR_U2_PHY_P1_BASE);

	/* soft reset xHCI HC */
	reg_val = uphy_read32(REG_SSUSB_IP_PW_CTRL0);
	uphy_write32(REG_SSUSB_IP_PW_CTRL0, (reg_val |  (SSUSB_IP_SW_RST)));
	uphy_write32(REG_SSUSB_IP_PW_CTRL0, (reg_val & (~SSUSB_IP_SW_RST)));

	/* enable xHCI HC power */
	reg_val = uphy_read32(REG_SSUSB_IP_PW_CTRL1);
	reg_val &= ~SSUSB_IP_PDN;
	uphy_write32(REG_SSUSB_IP_PW_CTRL1, reg_val);

	/* enable target USB3 ports */
	for (i = 0; i < num_port_u3; i++) {
		reg_val = uphy_read32(REG_SSUSB_U3_CTRL(i));
		reg_val &= ~(SSUSB_U3_PORT_PDN | SSUSB_U3_PORT_DIS);
		uphy_write32(REG_SSUSB_U3_CTRL(i), reg_val);
	}

	/* enable target USB2 ports */
	for (i = 0; i < num_port_u2; i++) {
		reg_val = uphy_read32(REG_SSUSB_U2_CTRL(i));
		reg_val &= ~(SSUSB_U2_PORT_PDN | SSUSB_U2_PORT_DIS);
		uphy_write32(REG_SSUSB_U2_CTRL(i), reg_val);
	}

	/* wait for clocks to be stable */
	check_val = SSUSB_STS1_SYSPLL_STABLE |
		    SSUSB_STS1_REF_RST |
		    SSUSB_STS1_SYS125_RST |
		    SSUSB_STS1_XHCI_RST;

	if (num_port_u3 > 0)
		check_val |= SSUSB_STS1_U3_MAC_RST;

	for (i = 0; i < 10; i++) {
		msleep(50);
		reg_val = uphy_read32(REG_SSUSB_IP_PW_STS1);

		if ((reg_val & check_val) == check_val)
			return 0;
	}

	printk(KERN_ERR "xhci clocks are not stable (IP_PW_STS1: 0x%x)\n", reg_val);

	return -ENODEV;
}