blob: 0edb6438cbd74348df57d529c987d370caffe80b [file] [log] [blame]
Roman Byshko637fbb62014-07-27 19:32:44 +02001/*
Hans de Goede86979092015-04-27 14:54:47 +02002 * Sunxi ehci glue
Roman Byshko637fbb62014-07-27 19:32:44 +02003 *
Hans de Goede86979092015-04-27 14:54:47 +02004 * Copyright (C) 2015 Hans de Goede <hdegoede@redhat.com>
5 * Copyright (C) 2014 Roman Byshko <rbyshko@gmail.com>
Roman Byshko637fbb62014-07-27 19:32:44 +02006 *
7 * Based on code from
8 * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
9 *
10 * SPDX-License-Identifier: GPL-2.0+
11 */
12
Roman Byshko637fbb62014-07-27 19:32:44 +020013#include <common.h>
Hans de Goede7e5aabd2015-04-27 11:44:22 +020014#include <asm/arch/clock.h>
Hans de Goede26a90052015-04-27 15:05:10 +020015#include <asm/arch/usb_phy.h>
Hans de Goede7e5aabd2015-04-27 11:44:22 +020016#include <asm/io.h>
Roman Byshko637fbb62014-07-27 19:32:44 +020017#include "ehci.h"
18
Roman Byshko637fbb62014-07-27 19:32:44 +020019int ehci_hcd_init(int index, enum usb_init_type init, struct ehci_hccr **hccr,
20 struct ehci_hcor **hcor)
21{
Hans de Goede7e5aabd2015-04-27 11:44:22 +020022 struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
Hans de Goede1168e092015-04-27 16:50:04 +020023 int ahb_gate_offset;
Hans de Goedeaf4273b2014-11-07 16:09:00 +010024
Hans de Goede7e5aabd2015-04-27 11:44:22 +020025 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
Hans de Goede86979092015-04-27 14:54:47 +020032 sunxi_usb_phy_init(index + 1);
33 sunxi_usb_phy_power_on(index + 1);
Roman Byshko637fbb62014-07-27 19:32:44 +020034
Hans de Goede1f4e1d12015-04-27 14:36:23 +020035 if (index == 0)
36 *hccr = (void *)SUNXI_USB1_BASE;
37 else
38 *hccr = (void *)SUNXI_USB2_BASE;
Roman Byshko637fbb62014-07-27 19:32:44 +020039
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
Roman Byshko637fbb62014-07-27 19:32:44 +020047 return 0;
48}
49
50int ehci_hcd_stop(int index)
51{
Hans de Goede7e5aabd2015-04-27 11:44:22 +020052 struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
53 int ahb_gate_offset;
54
Hans de Goede86979092015-04-27 14:54:47 +020055 sunxi_usb_phy_power_off(index + 1);
56 sunxi_usb_phy_exit(index + 1);
Hans de Goedeea7851d2014-10-31 17:04:52 +010057
Hans de Goede7e5aabd2015-04-27 11:44:22 +020058 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
Hans de Goede1168e092015-04-27 16:50:04 +020065 return 0;
Roman Byshko637fbb62014-07-27 19:32:44 +020066}