summaryrefslogtreecommitdiff
path: root/src/include/ehci.h
blob: ed54b7e347aba50269a676c718962de9df119949 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#ifndef EHCI_H
#define EHCI_H

struct ehci_caps {
        /* these fields are specified as 8 and 16 bit registers,
         * but some hosts can't perform 8 or 16 bit PCI accesses.
         */
        u32             hc_capbase;
#define HC_LENGTH(p)            (((p)>>00)&0x00ff)      /* bits 7:0 */
#define HC_VERSION(p)           (((p)>>16)&0xffff)      /* bits 31:16 */
        u32             hcs_params;     /* HCSPARAMS - offset 0x4 */
#define HCS_DEBUG_PORT(p)       (((p)>>20)&0xf) /* bits 23:20, debug port? */
#define HCS_INDICATOR(p)        ((p)&(1 << 16)) /* true: has port indicators */
#define HCS_N_CC(p)             (((p)>>12)&0xf) /* bits 15:12, #companion HCs */
#define HCS_N_PCC(p)            (((p)>>8)&0xf)  /* bits 11:8, ports per CC */
#define HCS_PORTROUTED(p)       ((p)&(1 << 7))  /* true: port routing */
#define HCS_PPC(p)              ((p)&(1 << 4))  /* true: port power control */
#define HCS_N_PORTS(p)          (((p)>>0)&0xf)  /* bits 3:0, ports on HC */

        u32             hcc_params;      /* HCCPARAMS - offset 0x8 */
#define HCC_EXT_CAPS(p)         (((p)>>8)&0xff) /* for pci extended caps */
#define HCC_ISOC_CACHE(p)       ((p)&(1 << 7))  /* true: can cache isoc frame */
#define HCC_ISOC_THRES(p)       (((p)>>4)&0x7)  /* bits 6:4, uframes cached */
#define HCC_CANPARK(p)          ((p)&(1 << 2))  /* true: can park on async qh */
#define HCC_PGM_FRAMELISTLEN(p) ((p)&(1 << 1))  /* true: periodic_size changes*/
#define HCC_64BIT_ADDR(p)       ((p)&(1))       /* true: can use 64-bit addr */
        u8              portroute [8];   /* nibbles for routing - offset 0xC */
} __attribute__ ((packed));

/* Section 2.3 Host Controller Operational Registers */
struct ehci_regs {

        /* USBCMD: offset 0x00 */
        u32             command;
/* 23:16 is r/w intr rate, in microframes; default "8" == 1/msec */
#define CMD_PARK        (1<<11)         /* enable "park" on async qh */
#define CMD_PARK_CNT(c) (((c)>>8)&3)    /* how many transfers to park for */
#define CMD_LRESET      (1<<7)          /* partial reset (no ports, etc) */
#define CMD_IAAD        (1<<6)          /* "doorbell" interrupt async advance */
#define CMD_ASE         (1<<5)          /* async schedule enable */
#define CMD_PSE         (1<<4)          /* periodic schedule enable */
/* 3:2 is periodic frame list size */
#define CMD_RESET       (1<<1)          /* reset HC not bus */
#define CMD_RUN         (1<<0)          /* start/stop HC */

        /* USBSTS: offset 0x04 */
        u32             status;
#define STS_ASS         (1<<15)         /* Async Schedule Status */
#define STS_PSS         (1<<14)         /* Periodic Schedule Status */
#define STS_RECL        (1<<13)         /* Reclamation */
#define STS_HALT        (1<<12)         /* Not running (any reason) */
/* some bits reserved */
        /* these STS_* flags are also intr_enable bits (USBINTR) */
#define STS_IAA         (1<<5)          /* Interrupted on async advance */
#define STS_FATAL       (1<<4)          /* such as some PCI access errors */
#define STS_FLR         (1<<3)          /* frame list rolled over */
#define STS_PCD         (1<<2)          /* port change detect */
#define STS_ERR         (1<<1)          /* "error" completion (overflow, ...) */
#define STS_INT         (1<<0)          /* "normal" completion (short, ...) */

        /* USBINTR: offset 0x08 */
        u32             intr_enable;

        /* FRINDEX: offset 0x0C */
        u32             frame_index;    /* current microframe number */
        /* CTRLDSSEGMENT: offset 0x10 */
        u32             segment;        /* address bits 63:32 if needed */
        /* PERIODICLISTBASE: offset 0x14 */
        u32             frame_list;     /* points to periodic list */
        /* ASYNCLISTADDR: offset 0x18 */
        u32             async_next;     /* address of next async queue head */

        u32             reserved [9];

        /* CONFIGFLAG: offset 0x40 */
        u32             configured_flag;
#define FLAG_CF         (1<<0)          /* true: we'll support "high speed" */

        /* PORTSC: offset 0x44 */
        u32             port_status [0];        /* up to N_PORTS */
/* 31:23 reserved */
#define PORT_WKOC_E     (1<<22)         /* wake on overcurrent (enable) */
#define PORT_WKDISC_E   (1<<21)         /* wake on disconnect (enable) */
#define PORT_WKCONN_E   (1<<20)         /* wake on connect (enable) */
/* 19:16 for port testing */
#define PORT_LED_OFF    (0<<14)
#define PORT_LED_AMBER  (1<<14)
#define PORT_LED_GREEN  (2<<14)
#define PORT_LED_MASK   (3<<14)
#define PORT_OWNER      (1<<13)         /* true: companion hc owns this port */
#define PORT_POWER      (1<<12)         /* true: has power (see PPC) */
#define PORT_USB11(x) (((x)&(3<<10))==(1<<10))  /* USB 1.1 device */
/* 11:10 for detecting lowspeed devices (reset vs release ownership) */
/* 9 reserved */
#define PORT_RESET      (1<<8)          /* reset port */
#define PORT_SUSPEND    (1<<7)          /* suspend port */
#define PORT_RESUME     (1<<6)          /* resume it */
#define PORT_OCC        (1<<5)          /* over current change */
#define PORT_OC         (1<<4)          /* over current active */
#define PORT_PEC        (1<<3)          /* port enable change */
#define PORT_PE         (1<<2)          /* port enable */
#define PORT_CSC        (1<<1)          /* connect status change */
#define PORT_CONNECT    (1<<0)          /* device connected */
#define PORT_RWC_BITS   (PORT_CSC | PORT_PEC | PORT_OCC)
} __attribute__ ((packed));

/* Appendix C, Debug port ... intended for use with special "debug devices"
 * that can help if there's no serial console.  (nonstandard enumeration.)
 */
struct ehci_dbg_port {
        u32     control;
#define DBGP_OWNER      (1<<30)
#define DBGP_ENABLED    (1<<28)
#define DBGP_DONE       (1<<16)
#define DBGP_INUSE      (1<<10)
#define DBGP_ERRCODE(x) (((x)>>7)&0x07)
#       define DBGP_ERR_BAD     1
#       define DBGP_ERR_SIGNAL  2
#define DBGP_ERROR      (1<<6)
#define DBGP_GO         (1<<5)
#define DBGP_OUT        (1<<4)
#define DBGP_LEN(x)     (((x)>>0)&0x0f)
        u32     pids;
#define DBGP_PID_GET(x)         (((x)>>16)&0xff)
#define DBGP_PID_SET(data,tok)  (((data)<<8)|(tok))
        u32     data03;
        u32     data47;
        u32     address;
#define DBGP_EPADDR(dev,ep)     (((dev)<<8)|(ep))
} __attribute__ ((packed));

#endif