1 /* 2 * Sunxi ehci glue 3 * 4 * Copyright (C) 2015 Hans de Goede <hdegoede@redhat.com> 5 * Copyright (C) 2014 Roman Byshko <rbyshko@gmail.com> 6 * 7 * Based on code from 8 * Allwinner Technology Co., Ltd. <www.allwinnertech.com> 9 * 10 * SPDX-License-Identifier: GPL-2.0+ 11 */ 12 13 #include <common.h> 14 #include <asm/arch/clock.h> 15 #include <asm/arch/usb_phy.h> 16 #include <asm/io.h> 17 #include "ehci.h" 18 19 int ehci_hcd_init(int index, enum usb_init_type init, struct ehci_hccr **hccr, 20 struct ehci_hcor **hcor) 21 { 22 struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; 23 int ahb_gate_offset; 24 25 ahb_gate_offset = index ? AHB_GATE_OFFSET_USB_EHCI1 : 26 AHB_GATE_OFFSET_USB_EHCI0; 27 setbits_le32(&ccm->ahb_gate0, 1 << ahb_gate_offset); 28 #ifdef CONFIG_SUNXI_GEN_SUN6I 29 setbits_le32(&ccm->ahb_reset0_cfg, 1 << ahb_gate_offset); 30 #endif 31 32 sunxi_usb_phy_init(index + 1); 33 sunxi_usb_phy_power_on(index + 1); 34 35 if (index == 0) 36 *hccr = (void *)SUNXI_USB1_BASE; 37 else 38 *hccr = (void *)SUNXI_USB2_BASE; 39 40 *hcor = (struct ehci_hcor *)((uint32_t) *hccr 41 + HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase))); 42 43 debug("sunxi-ehci: init hccr %x and hcor %x hc_length %d\n", 44 (uint32_t)*hccr, (uint32_t)*hcor, 45 (uint32_t)HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase))); 46 47 return 0; 48 } 49 50 int ehci_hcd_stop(int index) 51 { 52 struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; 53 int ahb_gate_offset; 54 55 sunxi_usb_phy_power_off(index + 1); 56 sunxi_usb_phy_exit(index + 1); 57 58 ahb_gate_offset = index ? AHB_GATE_OFFSET_USB_EHCI1 : 59 AHB_GATE_OFFSET_USB_EHCI0; 60 #ifdef CONFIG_SUNXI_GEN_SUN6I 61 clrbits_le32(&ccm->ahb_reset0_cfg, 1 << ahb_gate_offset); 62 #endif 63 clrbits_le32(&ccm->ahb_gate0, 1 << ahb_gate_offset); 64 65 return 0; 66 } 67