xref: /rk3399_rockchip-uboot/drivers/usb/host/ehci-atmel.c (revision 127efc4fe8cfc3ed525650b1ccbad9c3402e8d5d)
1cc30b780SBo Shen /*
2cc30b780SBo Shen  * (C) Copyright 2012
3cc30b780SBo Shen  * Atmel Semiconductor <www.atmel.com>
4cc30b780SBo Shen  * Written-by: Bo Shen <voice.shen@atmel.com>
5cc30b780SBo Shen  *
61a459660SWolfgang Denk  * SPDX-License-Identifier:	GPL-2.0+
7cc30b780SBo Shen  */
8cc30b780SBo Shen 
9cc30b780SBo Shen #include <common.h>
10cc30b780SBo Shen #include <watchdog.h>
11cc30b780SBo Shen #include <usb.h>
12cc30b780SBo Shen #include <asm/io.h>
13cc30b780SBo Shen #include <asm/arch/hardware.h>
14cc30b780SBo Shen #include <asm/arch/at91_pmc.h>
15cc30b780SBo Shen #include <asm/arch/clk.h>
16cc30b780SBo Shen 
17cc30b780SBo Shen #include "ehci.h"
18cc30b780SBo Shen 
19cc30b780SBo Shen /* Enable UTMI PLL time out 500us
20cc30b780SBo Shen  * 10 times as datasheet specified
21cc30b780SBo Shen  */
22cc30b780SBo Shen #define EN_UPLL_TIMEOUT	500UL
23cc30b780SBo Shen 
24*127efc4fSTroy Kisky int ehci_hcd_init(int index, enum usb_init_type init,
25*127efc4fSTroy Kisky 		struct ehci_hccr **hccr, struct ehci_hcor **hcor)
26cc30b780SBo Shen {
27cc30b780SBo Shen 	at91_pmc_t *pmc = (at91_pmc_t *)ATMEL_BASE_PMC;
28cc30b780SBo Shen 	ulong start_time, tmp_time;
29cc30b780SBo Shen 
30cc30b780SBo Shen 	start_time = get_timer(0);
31cc30b780SBo Shen 	/* Enable UTMI PLL */
32cc30b780SBo Shen 	writel(AT91_PMC_UPLLEN | AT91_PMC_BIASEN, &pmc->uckr);
3381f40345SAndreas Bießmann 	while ((readl(&pmc->sr) & AT91_PMC_LOCKU) != AT91_PMC_LOCKU) {
34cc30b780SBo Shen 		WATCHDOG_RESET();
35cc30b780SBo Shen 		tmp_time = get_timer(0);
36cc30b780SBo Shen 		if ((tmp_time - start_time) > EN_UPLL_TIMEOUT) {
37cc30b780SBo Shen 			printf("ERROR: failed to enable UPLL\n");
38cc30b780SBo Shen 			return -1;
39cc30b780SBo Shen 		}
40cc30b780SBo Shen 	}
41cc30b780SBo Shen 
42cc30b780SBo Shen 	/* Enable USB Host clock */
43cc30b780SBo Shen 	writel(1 << ATMEL_ID_UHPHS, &pmc->pcer);
44cc30b780SBo Shen 
45676ae068SLucas Stach 	*hccr = (struct ehci_hccr *)ATMEL_BASE_EHCI;
46676ae068SLucas Stach 	*hcor = (struct ehci_hcor *)((uint32_t)*hccr +
47676ae068SLucas Stach 			HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
48cc30b780SBo Shen 
49cc30b780SBo Shen 	return 0;
50cc30b780SBo Shen }
51cc30b780SBo Shen 
52676ae068SLucas Stach int ehci_hcd_stop(int index)
53cc30b780SBo Shen {
54cc30b780SBo Shen 	at91_pmc_t *pmc = (at91_pmc_t *)ATMEL_BASE_PMC;
55cc30b780SBo Shen 	ulong start_time, tmp_time;
56cc30b780SBo Shen 
57cc30b780SBo Shen 	/* Disable USB Host Clock */
58cc30b780SBo Shen 	writel(1 << ATMEL_ID_UHPHS, &pmc->pcdr);
59cc30b780SBo Shen 
60cc30b780SBo Shen 	start_time = get_timer(0);
61cc30b780SBo Shen 	/* Disable UTMI PLL */
62cc30b780SBo Shen 	writel(readl(&pmc->uckr) & ~AT91_PMC_UPLLEN, &pmc->uckr);
6381f40345SAndreas Bießmann 	while ((readl(&pmc->sr) & AT91_PMC_LOCKU) == AT91_PMC_LOCKU) {
64cc30b780SBo Shen 		WATCHDOG_RESET();
65cc30b780SBo Shen 		tmp_time = get_timer(0);
66cc30b780SBo Shen 		if ((tmp_time - start_time) > EN_UPLL_TIMEOUT) {
67cc30b780SBo Shen 			printf("ERROR: failed to stop UPLL\n");
68cc30b780SBo Shen 			return -1;
69cc30b780SBo Shen 		}
70cc30b780SBo Shen 	}
71cc30b780SBo Shen 
72cc30b780SBo Shen 	return 0;
73cc30b780SBo Shen }
74