drivers: at91: clean up peripheral clock code
[platform/kernel/u-boot.git] / drivers / usb / host / ehci-atmel.c
1 /*
2  * (C) Copyright 2012
3  * Atmel Semiconductor <www.atmel.com>
4  * Written-by: Bo Shen <voice.shen@atmel.com>
5  *
6  * SPDX-License-Identifier:     GPL-2.0+
7  */
8
9 #include <common.h>
10 #include <watchdog.h>
11 #include <usb.h>
12 #include <asm/io.h>
13 #include <asm/arch/hardware.h>
14 #include <asm/arch/at91_pmc.h>
15 #include <asm/arch/clk.h>
16
17 #include "ehci.h"
18
19 /* Enable UTMI PLL time out 500us
20  * 10 times as datasheet specified
21  */
22 #define EN_UPLL_TIMEOUT 500UL
23
24 int ehci_hcd_init(int index, enum usb_init_type init,
25                 struct ehci_hccr **hccr, struct ehci_hcor **hcor)
26 {
27         at91_pmc_t *pmc = (at91_pmc_t *)ATMEL_BASE_PMC;
28         ulong start_time, tmp_time;
29
30         start_time = get_timer(0);
31         /* Enable UTMI PLL */
32         writel(AT91_PMC_UPLLEN | AT91_PMC_BIASEN, &pmc->uckr);
33         while ((readl(&pmc->sr) & AT91_PMC_LOCKU) != AT91_PMC_LOCKU) {
34                 WATCHDOG_RESET();
35                 tmp_time = get_timer(0);
36                 if ((tmp_time - start_time) > EN_UPLL_TIMEOUT) {
37                         printf("ERROR: failed to enable UPLL\n");
38                         return -1;
39                 }
40         }
41
42         /* Enable USB Host clock */
43         at91_periph_clk_enable(ATMEL_ID_UHPHS);
44
45         *hccr = (struct ehci_hccr *)ATMEL_BASE_EHCI;
46         *hcor = (struct ehci_hcor *)((uint32_t)*hccr +
47                         HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
48
49         return 0;
50 }
51
52 int ehci_hcd_stop(int index)
53 {
54         at91_pmc_t *pmc = (at91_pmc_t *)ATMEL_BASE_PMC;
55         ulong start_time, tmp_time;
56
57         /* Disable USB Host Clock */
58         at91_periph_clk_disable(ATMEL_ID_UHPHS);
59
60         start_time = get_timer(0);
61         /* Disable UTMI PLL */
62         writel(readl(&pmc->uckr) & ~AT91_PMC_UPLLEN, &pmc->uckr);
63         while ((readl(&pmc->sr) & AT91_PMC_LOCKU) == AT91_PMC_LOCKU) {
64                 WATCHDOG_RESET();
65                 tmp_time = get_timer(0);
66                 if ((tmp_time - start_time) > EN_UPLL_TIMEOUT) {
67                         printf("ERROR: failed to stop UPLL\n");
68                         return -1;
69                 }
70         }
71
72         return 0;
73 }