1 // Copyright 2018 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <ddk/debug.h>
6 #include <ddk/mmio-buffer.h>
7 #include <ddk/platform-defs.h>
8 #include <hw/reg.h>
9 #include <soc/aml-common/aml-usb-phy-v2.h>
10 #include <soc/aml-s905d2/s905d2-hw.h>
11
12 #include "astro.h"
13
14 static const pbus_mmio_t xhci_mmios[] = {
15 {
16 .base = S905D2_USB0_BASE,
17 .length = S905D2_USB0_LENGTH,
18 },
19 };
20
21 static const pbus_irq_t xhci_irqs[] = {
22 {
23 .irq = S905D2_USB0_IRQ,
24 .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
25 },
26 };
27
28 static const pbus_bti_t xhci_btis[] = {
29 {
30 .iommu_index = 0,
31 .bti_id = BTI_USB_XHCI,
32 },
33 };
34
35 static const pbus_dev_t xhci_dev = {
36 .name = "xhci",
37 .vid = PDEV_VID_GENERIC,
38 .pid = PDEV_PID_GENERIC,
39 .did = PDEV_DID_USB_XHCI,
40 .mmio_list = xhci_mmios,
41 .mmio_count = countof(xhci_mmios),
42 .irq_list = xhci_irqs,
43 .irq_count = countof(xhci_irqs),
44 .bti_list = xhci_btis,
45 .bti_count = countof(xhci_btis),
46 };
47
48 // magic numbers for USB PHY tuning
49 #define PLL_SETTING_3 0xfe18
50 #define PLL_SETTING_4 0xfff
51 #define PLL_SETTING_5 0x78000
52 #define PLL_SETTING_6 0xe0004
53 #define PLL_SETTING_7 0xe000c
54
astro_usb_tuning(bool host,bool default_val)55 static zx_status_t astro_usb_tuning(bool host, bool default_val) {
56 mmio_buffer_t buf;
57 zx_status_t status;
58
59 status = mmio_buffer_init_physical(&buf, S905D2_USBPHY21_BASE, S905D2_USBPHY21_LENGTH,
60 get_root_resource(), ZX_CACHE_POLICY_UNCACHED_DEVICE);
61 if (status != ZX_OK) {
62 return status;
63 }
64
65 volatile void* base = buf.vaddr;
66
67 if (default_val) {
68 writel(0, base + 0x38);
69 writel(PLL_SETTING_5, base + 0x34);
70 } else {
71 writel(PLL_SETTING_3, base + 0x50);
72 writel(PLL_SETTING_4, base + 0x10);
73 if (host) {
74 writel(PLL_SETTING_6, base + 0x38);
75 } else {
76 writel(PLL_SETTING_7, base + 0x38);
77 }
78 writel(PLL_SETTING_5, base + 0x34);
79 }
80
81 mmio_buffer_release(&buf);
82 return ZX_OK;
83 }
84
aml_usb_init(aml_bus_t * bus)85 zx_status_t aml_usb_init(aml_bus_t* bus) {
86 zx_handle_t bti;
87
88 zx_status_t status = iommu_get_bti(&bus->iommu, 0, BTI_BOARD, &bti);
89 if (status != ZX_OK) {
90 zxlogf(ERROR, "aml_usb_init: iommu_get_bti failed: %d\n", status);
91 return status;
92 }
93
94 status = aml_usb_phy_v2_init(bti);
95 if (status != ZX_OK) {
96 return status;
97 }
98
99 status = astro_usb_tuning(true, false);
100 zx_handle_close(bti);
101 if (status != ZX_OK) {
102 return status;
103 }
104
105 return pbus_device_add(&bus->pbus, &xhci_dev);
106 }
107