blob: a33fb49de9e866f03dad15b97072001a76467573 [file] [log] [blame]
Bo Shencc30b782012-06-27 21:58:20 +00001/*
2 * (C) Copyright 2012
3 * Atmel Semiconductor <www.atmel.com>
4 * Written-by: Bo Shen <voice.shen@atmel.com>
5 *
Wolfgang Denk1a459662013-07-08 09:37:19 +02006 * SPDX-License-Identifier: GPL-2.0+
Bo Shencc30b782012-06-27 21:58:20 +00007 */
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"
Bo Shencc30b782012-06-27 21:58:20 +000018
19/* Enable UTMI PLL time out 500us
20 * 10 times as datasheet specified
21 */
22#define EN_UPLL_TIMEOUT 500UL
23
Troy Kisky127efc42013-10-10 15:27:57 -070024int ehci_hcd_init(int index, enum usb_init_type init,
25 struct ehci_hccr **hccr, struct ehci_hcor **hcor)
Bo Shencc30b782012-06-27 21:58:20 +000026{
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);
Andreas Bießmann81f40342012-06-28 02:50:37 +000033 while ((readl(&pmc->sr) & AT91_PMC_LOCKU) != AT91_PMC_LOCKU) {
Bo Shencc30b782012-06-27 21:58:20 +000034 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 */
Bo Shen97b20432014-08-06 17:24:57 +080043 at91_periph_clk_enable(ATMEL_ID_UHPHS);
Bo Shencc30b782012-06-27 21:58:20 +000044
Lucas Stach676ae062012-09-26 00:14:35 +020045 *hccr = (struct ehci_hccr *)ATMEL_BASE_EHCI;
46 *hcor = (struct ehci_hcor *)((uint32_t)*hccr +
47 HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
Bo Shencc30b782012-06-27 21:58:20 +000048
49 return 0;
50}
51
Lucas Stach676ae062012-09-26 00:14:35 +020052int ehci_hcd_stop(int index)
Bo Shencc30b782012-06-27 21:58:20 +000053{
54 at91_pmc_t *pmc = (at91_pmc_t *)ATMEL_BASE_PMC;
55 ulong start_time, tmp_time;
56
57 /* Disable USB Host Clock */
Bo Shen97b20432014-08-06 17:24:57 +080058 at91_periph_clk_disable(ATMEL_ID_UHPHS);
Bo Shencc30b782012-06-27 21:58:20 +000059
60 start_time = get_timer(0);
61 /* Disable UTMI PLL */
62 writel(readl(&pmc->uckr) & ~AT91_PMC_UPLLEN, &pmc->uckr);
Andreas Bießmann81f40342012-06-28 02:50:37 +000063 while ((readl(&pmc->sr) & AT91_PMC_LOCKU) == AT91_PMC_LOCKU) {
Bo Shencc30b782012-06-27 21:58:20 +000064 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}