blob: 67444b26ef9d067ecb5d1ace327ee54ff760a241 [file] [log] [blame]
Bo Shenc0eede02012-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 Denkd79de1d2013-07-08 09:37:19 +02006 * SPDX-License-Identifier: GPL-2.0+
Bo Shenc0eede02012-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 Shenc0eede02012-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
Lucas Stach3494a4c2012-09-26 00:14:35 +020024int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor)
Bo Shenc0eede02012-06-27 21:58:20 +000025{
26 at91_pmc_t *pmc = (at91_pmc_t *)ATMEL_BASE_PMC;
27 ulong start_time, tmp_time;
28
29 start_time = get_timer(0);
30 /* Enable UTMI PLL */
31 writel(AT91_PMC_UPLLEN | AT91_PMC_BIASEN, &pmc->uckr);
Andreas Bießmanned42bf72012-06-28 02:50:37 +000032 while ((readl(&pmc->sr) & AT91_PMC_LOCKU) != AT91_PMC_LOCKU) {
Bo Shenc0eede02012-06-27 21:58:20 +000033 WATCHDOG_RESET();
34 tmp_time = get_timer(0);
35 if ((tmp_time - start_time) > EN_UPLL_TIMEOUT) {
36 printf("ERROR: failed to enable UPLL\n");
37 return -1;
38 }
39 }
40
41 /* Enable USB Host clock */
42 writel(1 << ATMEL_ID_UHPHS, &pmc->pcer);
43
Lucas Stach3494a4c2012-09-26 00:14:35 +020044 *hccr = (struct ehci_hccr *)ATMEL_BASE_EHCI;
45 *hcor = (struct ehci_hcor *)((uint32_t)*hccr +
46 HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
Bo Shenc0eede02012-06-27 21:58:20 +000047
48 return 0;
49}
50
Lucas Stach3494a4c2012-09-26 00:14:35 +020051int ehci_hcd_stop(int index)
Bo Shenc0eede02012-06-27 21:58:20 +000052{
53 at91_pmc_t *pmc = (at91_pmc_t *)ATMEL_BASE_PMC;
54 ulong start_time, tmp_time;
55
56 /* Disable USB Host Clock */
57 writel(1 << ATMEL_ID_UHPHS, &pmc->pcdr);
58
59 start_time = get_timer(0);
60 /* Disable UTMI PLL */
61 writel(readl(&pmc->uckr) & ~AT91_PMC_UPLLEN, &pmc->uckr);
Andreas Bießmanned42bf72012-06-28 02:50:37 +000062 while ((readl(&pmc->sr) & AT91_PMC_LOCKU) == AT91_PMC_LOCKU) {
Bo Shenc0eede02012-06-27 21:58:20 +000063 WATCHDOG_RESET();
64 tmp_time = get_timer(0);
65 if ((tmp_time - start_time) > EN_UPLL_TIMEOUT) {
66 printf("ERROR: failed to stop UPLL\n");
67 return -1;
68 }
69 }
70
71 return 0;
72}