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