xref: /rk3399_rockchip-uboot/drivers/usb/host/ehci-fsl.c (revision 0ecb15c8e98edf6a4a120eefc43bcb1e8f48d97b)
12731b9a8SJean-Christophe PLAGNIOL-VILLARD /*
21b719e66SRamneek Mehresh  * (C) Copyright 2009, 2011 Freescale Semiconductor, Inc.
34ef01010SVivek Mahajan  *
42731b9a8SJean-Christophe PLAGNIOL-VILLARD  * (C) Copyright 2008, Excito Elektronik i Sk=E5ne AB
52731b9a8SJean-Christophe PLAGNIOL-VILLARD  *
62731b9a8SJean-Christophe PLAGNIOL-VILLARD  * Author: Tor Krill tor@excito.com
72731b9a8SJean-Christophe PLAGNIOL-VILLARD  *
81a459660SWolfgang Denk  * SPDX-License-Identifier:	GPL-2.0+
92731b9a8SJean-Christophe PLAGNIOL-VILLARD  */
102731b9a8SJean-Christophe PLAGNIOL-VILLARD 
112731b9a8SJean-Christophe PLAGNIOL-VILLARD #include <common.h>
122731b9a8SJean-Christophe PLAGNIOL-VILLARD #include <pci.h>
132731b9a8SJean-Christophe PLAGNIOL-VILLARD #include <usb.h>
142731b9a8SJean-Christophe PLAGNIOL-VILLARD #include <asm/io.h>
154ef01010SVivek Mahajan #include <usb/ehci-fsl.h>
161b719e66SRamneek Mehresh #include <hwconfig.h>
172731b9a8SJean-Christophe PLAGNIOL-VILLARD 
182731b9a8SJean-Christophe PLAGNIOL-VILLARD #include "ehci.h"
192731b9a8SJean-Christophe PLAGNIOL-VILLARD 
20047cea36SShengzhou Liu /* Check USB PHY clock valid */
21047cea36SShengzhou Liu static int usb_phy_clk_valid(struct usb_ehci *ehci)
22047cea36SShengzhou Liu {
23047cea36SShengzhou Liu 	if (!((in_be32(&ehci->control) & PHY_CLK_VALID) ||
24047cea36SShengzhou Liu 			in_be32(&ehci->prictrl))) {
25047cea36SShengzhou Liu 		printf("USB PHY clock invalid!\n");
26047cea36SShengzhou Liu 		return 0;
27047cea36SShengzhou Liu 	} else {
28047cea36SShengzhou Liu 		return 1;
29047cea36SShengzhou Liu 	}
30047cea36SShengzhou Liu }
31047cea36SShengzhou Liu 
322731b9a8SJean-Christophe PLAGNIOL-VILLARD /*
332731b9a8SJean-Christophe PLAGNIOL-VILLARD  * Create the appropriate control structures to manage
342731b9a8SJean-Christophe PLAGNIOL-VILLARD  * a new EHCI host controller.
352731b9a8SJean-Christophe PLAGNIOL-VILLARD  *
362731b9a8SJean-Christophe PLAGNIOL-VILLARD  * Excerpts from linux ehci fsl driver.
372731b9a8SJean-Christophe PLAGNIOL-VILLARD  */
38127efc4fSTroy Kisky int ehci_hcd_init(int index, enum usb_init_type init,
39127efc4fSTroy Kisky 		struct ehci_hccr **hccr, struct ehci_hcor **hcor)
402731b9a8SJean-Christophe PLAGNIOL-VILLARD {
4177354e9dSramneek mehresh 	struct usb_ehci *ehci = NULL;
421b719e66SRamneek Mehresh 	const char *phy_type = NULL;
431b719e66SRamneek Mehresh 	size_t len;
44*0ecb15c8SNikhil Badola 	char current_usb_controller[5];
45dd22f7cfSKumar Gala #ifdef CONFIG_SYS_FSL_USB_INTERNAL_UTMI_PHY
46dd22f7cfSKumar Gala 	char usb_phy[5];
471b719e66SRamneek Mehresh 
481b719e66SRamneek Mehresh 	usb_phy[0] = '\0';
49dd22f7cfSKumar Gala #endif
50*0ecb15c8SNikhil Badola 	memset(current_usb_controller, '\0', 5);
51*0ecb15c8SNikhil Badola 	snprintf(current_usb_controller, 4, "usb%d", index+1);
522731b9a8SJean-Christophe PLAGNIOL-VILLARD 
5377354e9dSramneek mehresh 	switch (index) {
5477354e9dSramneek mehresh 	case 0:
5577354e9dSramneek mehresh 		ehci = (struct usb_ehci *)CONFIG_SYS_FSL_USB1_ADDR;
5677354e9dSramneek mehresh 		break;
5777354e9dSramneek mehresh 	case 1:
5877354e9dSramneek mehresh 		ehci = (struct usb_ehci *)CONFIG_SYS_FSL_USB2_ADDR;
5977354e9dSramneek mehresh 		break;
6077354e9dSramneek mehresh 	default:
6177354e9dSramneek mehresh 		printf("ERROR: wrong controller index!!\n");
6277354e9dSramneek mehresh 		break;
6377354e9dSramneek mehresh 	};
6477354e9dSramneek mehresh 
65676ae068SLucas Stach 	*hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength);
66676ae068SLucas Stach 	*hcor = (struct ehci_hcor *)((uint32_t) *hccr +
67676ae068SLucas Stach 			HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
682731b9a8SJean-Christophe PLAGNIOL-VILLARD 
692731b9a8SJean-Christophe PLAGNIOL-VILLARD 	/* Set to Host mode */
7008066152SVivek Mahajan 	setbits_le32(&ehci->usbmode, CM_HOST);
712731b9a8SJean-Christophe PLAGNIOL-VILLARD 
7208066152SVivek Mahajan 	out_be32(&ehci->snoop1, SNOOP_SIZE_2GB);
7308066152SVivek Mahajan 	out_be32(&ehci->snoop2, 0x80000000 | SNOOP_SIZE_2GB);
742731b9a8SJean-Christophe PLAGNIOL-VILLARD 
752731b9a8SJean-Christophe PLAGNIOL-VILLARD 	/* Init phy */
76*0ecb15c8SNikhil Badola 	if (hwconfig_sub(current_usb_controller, "phy_type"))
77*0ecb15c8SNikhil Badola 		phy_type = hwconfig_subarg(current_usb_controller,
78*0ecb15c8SNikhil Badola 				"phy_type", &len);
794ef01010SVivek Mahajan 	else
801b719e66SRamneek Mehresh 		phy_type = getenv("usb_phy_type");
811b719e66SRamneek Mehresh 
821b719e66SRamneek Mehresh 	if (!phy_type) {
831b719e66SRamneek Mehresh #ifdef CONFIG_SYS_FSL_USB_INTERNAL_UTMI_PHY
841b719e66SRamneek Mehresh 		/* if none specified assume internal UTMI */
851b719e66SRamneek Mehresh 		strcpy(usb_phy, "utmi");
861b719e66SRamneek Mehresh 		phy_type = usb_phy;
871b719e66SRamneek Mehresh #else
881b719e66SRamneek Mehresh 		printf("WARNING: USB phy type not defined !!\n");
891b719e66SRamneek Mehresh 		return -1;
901b719e66SRamneek Mehresh #endif
911b719e66SRamneek Mehresh 	}
921b719e66SRamneek Mehresh 
9391d7746dSNikhil Badola 	if (!strncmp(phy_type, "utmi", 4)) {
941b719e66SRamneek Mehresh #if defined(CONFIG_SYS_FSL_USB_INTERNAL_UTMI_PHY)
951b719e66SRamneek Mehresh 		setbits_be32(&ehci->control, PHY_CLK_SEL_UTMI);
961b719e66SRamneek Mehresh 		setbits_be32(&ehci->control, UTMI_PHY_EN);
971b719e66SRamneek Mehresh 		udelay(1000); /* delay required for PHY Clk to appear */
981b719e66SRamneek Mehresh #endif
99676ae068SLucas Stach 		out_le32(&(*hcor)->or_portsc[0], PORT_PTS_UTMI);
100047cea36SShengzhou Liu 		setbits_be32(&ehci->control, USB_EN);
1011b719e66SRamneek Mehresh 	} else {
1021b719e66SRamneek Mehresh 		setbits_be32(&ehci->control, PHY_CLK_SEL_ULPI);
103047cea36SShengzhou Liu 		clrsetbits_be32(&ehci->control, UTMI_PHY_EN, USB_EN);
1041b719e66SRamneek Mehresh 		udelay(1000); /* delay required for PHY Clk to appear */
105047cea36SShengzhou Liu 		if (!usb_phy_clk_valid(ehci))
106047cea36SShengzhou Liu 			return -EINVAL;
107676ae068SLucas Stach 		out_le32(&(*hcor)->or_portsc[0], PORT_PTS_ULPI);
1081b719e66SRamneek Mehresh 	}
1092731b9a8SJean-Christophe PLAGNIOL-VILLARD 
11008066152SVivek Mahajan 	out_be32(&ehci->prictrl, 0x0000000c);
11108066152SVivek Mahajan 	out_be32(&ehci->age_cnt_limit, 0x00000040);
11208066152SVivek Mahajan 	out_be32(&ehci->sictrl, 0x00000001);
1132731b9a8SJean-Christophe PLAGNIOL-VILLARD 
11408066152SVivek Mahajan 	in_le32(&ehci->usbmode);
1152731b9a8SJean-Christophe PLAGNIOL-VILLARD 
1162731b9a8SJean-Christophe PLAGNIOL-VILLARD 	return 0;
1172731b9a8SJean-Christophe PLAGNIOL-VILLARD }
1182731b9a8SJean-Christophe PLAGNIOL-VILLARD 
1192731b9a8SJean-Christophe PLAGNIOL-VILLARD /*
1202731b9a8SJean-Christophe PLAGNIOL-VILLARD  * Destroy the appropriate control structures corresponding
1212731b9a8SJean-Christophe PLAGNIOL-VILLARD  * the the EHCI host controller.
1222731b9a8SJean-Christophe PLAGNIOL-VILLARD  */
123676ae068SLucas Stach int ehci_hcd_stop(int index)
1242731b9a8SJean-Christophe PLAGNIOL-VILLARD {
1252731b9a8SJean-Christophe PLAGNIOL-VILLARD 	return 0;
1262731b9a8SJean-Christophe PLAGNIOL-VILLARD }
127