1 /*
2  * Copyright (c) 2022, sakumisu
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #ifndef _USB_EHCI_PRIV_H
7 #define _USB_EHCI_PRIV_H
8 
9 #include "usbh_core.h"
10 #include "usbh_hub.h"
11 #include "usb_ehci_reg.h"
12 
13 #define EHCI_HCCR ((struct ehci_hccr *)(uintptr_t)(bus->hcd.reg_base + CONFIG_USB_EHCI_HCCR_OFFSET))
14 #define EHCI_HCOR ((struct ehci_hcor *)(uintptr_t)(bus->hcd.reg_base + CONFIG_USB_EHCI_HCCR_OFFSET + g_ehci_hcd[bus->hcd.hcd_id].hcor_offset))
15 
16 #define EHCI_PTR2ADDR(x) ((uint32_t)(uintptr_t)(x) & ~0x1F)
17 #define EHCI_ADDR2QH(x)  ((struct ehci_qh_hw *)(uintptr_t)((uint32_t)(x) & ~0x1F))
18 #define EHCI_ADDR2QTD(x) ((struct ehci_qtd_hw *)(uintptr_t)((uint32_t)(x) & ~0x1F))
19 #define EHCI_ADDR2ITD(x) ((struct ehci_itd_hw *)(uintptr_t)((uint32_t)(x) & ~0x1F))
20 
21 #ifndef CONFIG_USB_EHCI_QH_NUM
22 #define CONFIG_USB_EHCI_QH_NUM 10
23 #endif
24 #ifndef CONFIG_USB_EHCI_QTD_NUM
25 #define CONFIG_USB_EHCI_QTD_NUM (CONFIG_USB_EHCI_QH_NUM * 3)
26 #endif
27 #ifndef CONFIG_USB_EHCI_ITD_NUM
28 #define CONFIG_USB_EHCI_ITD_NUM 5
29 #endif
30 #ifndef CONFIG_USB_EHCI_ISO_NUM
31 #define CONFIG_USB_EHCI_ISO_NUM 4
32 #endif
33 
34 #if CONFIG_USB_ALIGN_SIZE <= 32
35 #define CONFIG_USB_EHCI_ALIGN_SIZE 32
36 #elif CONFIG_USB_ALIGN_SIZE <= 64
37 #define CONFIG_USB_EHCI_ALIGN_SIZE 64
38 #else
39 #error "CONFIG_USB_ALIGN_SIZE must be 32 or 64"
40 #endif
41 
42 #if CONFIG_USB_EHCI_QTD_NUM < 9
43 #error CONFIG_USB_EHCI_QTD_NUM is too small, recommand CONFIG_USB_EHCI_QH_NUM * 3
44 #endif
45 
46 struct ehci_qtd_hw {
47     struct ehci_qtd hw;
48 #if defined(CONFIG_USB_EHCI_DESC_DCACHE_ENABLE) && (CONFIG_USB_ALIGN_SIZE == 64)
49     uint8_t pad[32];
50 #endif
51     bool inuse;
52     struct usbh_urb *urb;
53     uintptr_t bufaddr;
54     uint32_t length;
55 } __attribute__((aligned(CONFIG_USB_EHCI_ALIGN_SIZE)));
56 
57 struct ehci_qh_hw {
58     struct ehci_qh hw;
59 #if defined(CONFIG_USB_EHCI_DESC_DCACHE_ENABLE)
60     uint16_t pad[16];
61 #endif
62     bool inuse;
63     uint32_t first_qtd;
64     struct usbh_urb *urb;
65     usb_osal_sem_t waitsem;
66     uint8_t remove_in_iaad;
67 } __attribute__((aligned(CONFIG_USB_EHCI_ALIGN_SIZE)));
68 
69 struct ehci_itd_hw {
70     struct ehci_itd hw;
71     struct usbh_urb *urb;
72     uint16_t start_frame;
73     uint8_t mf_unmask;
74     uint8_t mf_valid;
75     uint32_t pkt_idx[8];
76     bool dir_in;
77 } __attribute__((aligned(CONFIG_USB_EHCI_ALIGN_SIZE)));
78 
79 struct ehci_iso_hw {
80     struct ehci_itd_hw itd_pool[CONFIG_USB_EHCI_ITD_NUM];
81     uint32_t itd_num;
82 };
83 
84 struct ehci_hcd {
85     bool ehci_iso_used[CONFIG_USB_EHCI_ISO_NUM];
86     bool ppc;      /* Port Power Control */
87     bool has_tt;   /* if use tt instead of Companion Controller */
88     uint8_t n_cc;  /* Number of Companion Controller */
89     uint8_t n_pcc; /* Number of ports supported per companion host controller */
90     uint8_t n_ports;
91     uint8_t hcor_offset;
92 };
93 
94 extern struct ehci_hcd g_ehci_hcd[CONFIG_USBHOST_MAX_BUS];
95 extern uint32_t g_framelist[CONFIG_USBHOST_MAX_BUS][USB_ALIGN_UP(CONFIG_USB_EHCI_FRAME_LIST_SIZE, 1024)];
96 extern uint8_t usbh_get_port_speed(struct usbh_bus *bus, const uint8_t port);
97 
98 int ehci_iso_urb_init(struct usbh_bus *bus, struct usbh_urb *urb);
99 void ehci_kill_iso_urb(struct usbh_bus *bus, struct usbh_urb *urb);
100 void ehci_scan_isochronous_list(struct usbh_bus *bus);
101 
102 #endif
103