iPXE
dwusb.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2025 Michael Brown <mbrown@fensystems.co.uk>.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 *
19 * You can also choose to distribute this program under the terms of
20 * the Unmodified Binary Distribution Licence (as given in the file
21 * COPYING.UBDL), provided that you have satisfied its requirements.
22 */
23
24FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25
26#include <stdlib.h>
27#include <string.h>
28#include <errno.h>
29#include <ipxe/timer.h>
30#include <ipxe/devtree.h>
31#include <ipxe/fdt.h>
32#include "dwusb.h"
33
34/** @file
35 *
36 * Synopsys DesignWare USB3 host controller driver
37 *
38 */
39
40/**
41 * Probe devicetree device
42 *
43 * @v dt Devicetree device
44 * @v offset Starting node offset
45 * @ret rc Return status code
46 */
47static int dwusb_probe ( struct dt_device *dt, unsigned int offset ) {
48 struct xhci_device *xhci;
49 uint32_t gctl;
50 int rc;
51
52 /* Allocate and initialise structure */
53 xhci = zalloc ( sizeof ( *xhci ) );
54 if ( ! xhci ) {
55 rc = -ENOMEM;
56 goto err_alloc;
57 }
58 xhci->dev = &dt->dev;
59 xhci->dma = &dt->dma;
60
61 /* Map registers */
62 xhci->regs = dt_ioremap ( dt, offset, 0, 0 );
63 if ( ! xhci->regs ) {
64 rc = -ENODEV;
65 goto err_ioremap;
66 }
67
68 /* Reset via global core control register */
69 gctl = readl ( xhci->regs + DWUSB_GCTL );
70 writel ( ( gctl | DWUSB_GCTL_RESET ), ( xhci->regs + DWUSB_GCTL ) );
71 mdelay ( 100 );
72 writel ( gctl, ( xhci->regs + DWUSB_GCTL ) );
73
74 /* Configure as a host controller */
77 writel ( gctl, ( xhci->regs + DWUSB_GCTL ) );
78
79 /* Initialise xHCI device */
80 xhci_init ( xhci );
81
82 /* Register xHCI device */
83 if ( ( rc = xhci_register ( xhci ) ) != 0 ) {
84 DBGC ( xhci, "XHCI %s could not register: %s\n",
85 xhci->name, strerror ( rc ) );
86 goto err_register;
87 }
88
89 dt_set_drvdata ( dt, xhci );
90 return 0;
91
92 xhci_unregister ( xhci );
93 err_register:
94 iounmap ( xhci->regs );
95 err_ioremap:
96 free ( xhci );
97 err_alloc:
98 return rc;
99}
100
101/**
102 * Remove devicetree device
103 *
104 * @v dt Devicetree device
105 */
106static void dwusb_remove ( struct dt_device *dt ) {
107 struct xhci_device *xhci = dt_get_drvdata ( dt );
108
109 /* Unregister xHCI device */
110 xhci_unregister ( xhci );
111
112 /* Unmap registers */
113 iounmap ( xhci->regs );
114
115 /* Free device */
116 free ( xhci );
117}
118
119/** DesignWare USB3 compatible model identifiers */
120static const char * dwusb_ids[] = {
121 DT_ID ( "snps,dwc3", "DesignWare USB3" ),
122};
123
124/** DesignWare USB3 devicetree driver */
125struct dt_driver dwusb_driver __dt_driver = {
126 .name = "dwusb",
127 .ids = dwusb_ids,
128 .id_count = ( sizeof ( dwusb_ids ) / sizeof ( dwusb_ids[0] ) ),
131};
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
unsigned int uint32_t
Definition stdint.h:12
uint16_t offset
Offset to command line.
Definition bzimage.h:3
void * dt_ioremap(struct dt_device *dt, unsigned int offset, unsigned int index, size_t len)
Map devicetree range.
Definition devtree.c:52
Devicetree bus.
static void * dt_get_drvdata(struct dt_device *dt)
Get devicetree driver-private data.
Definition devtree.h:82
#define DT_ID(_name, _desc)
Definition devtree.h:31
static void dt_set_drvdata(struct dt_device *dt, void *priv)
Set devicetree driver-private data.
Definition devtree.h:72
#define __dt_driver
Declare a devicetree driver.
Definition devtree.h:64
static int dwusb_probe(struct dt_device *dt, unsigned int offset)
Probe devicetree device.
Definition dwusb.c:47
static const char * dwusb_ids[]
DesignWare USB3 compatible model identifiers.
Definition dwusb.c:120
static void dwusb_remove(struct dt_device *dt)
Remove devicetree device.
Definition dwusb.c:106
Synopsys DesignWare USB3 host controller driver.
#define DWUSB_GCTL
Global core control register.
Definition dwusb.h:15
#define DWUSB_GCTL_PRTDIR_HOST
Operate as a host.
Definition dwusb.h:17
#define DWUSB_GCTL_RESET
Core soft reset.
Definition dwusb.h:21
#define DWUSB_GCTL_PRTDIR_MASK
Port direction mask.
Definition dwusb.h:19
Error codes.
#define DBGC(...)
Definition compiler.h:505
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
#define ENOMEM
Not enough space.
Definition errno.h:535
#define ENODEV
No such device.
Definition errno.h:510
Flattened Device Tree.
void iounmap(volatile const void *io_addr)
Unmap I/O address.
iPXE timers
String functions.
void * zalloc(size_t size)
Allocate cleared memory.
Definition malloc.c:662
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
A devicetree device.
Definition devtree.h:17
struct dma_device dma
DMA device.
Definition devtree.h:23
struct device dev
Generic device.
Definition devtree.h:21
A devicetree driver.
Definition devtree.h:37
int(* probe)(struct dt_device *dt, unsigned int offset)
Probe device.
Definition devtree.h:51
An xHCI device.
Definition xhci.h:1067
struct device * dev
Underlying hardware device.
Definition xhci.h:1071
const char * name
Name.
Definition xhci.h:1075
void * regs
Registers.
Definition xhci.h:1069
struct dma_device * dma
DMA device.
Definition xhci.h:1073
void mdelay(unsigned long msecs)
Delay for a fixed number of milliseconds.
Definition timer.c:79
#define readl
Definition w89c840.c:157
#define writel
Definition w89c840.c:160
static struct xen_remove_from_physmap * remove
Definition xenmem.h:40
void xhci_unregister(struct xhci_device *xhci)
Unregister xHCI controller.
Definition xhci.c:3364
int xhci_register(struct xhci_device *xhci)
Register xHCI controller.
Definition xhci.c:3319
void xhci_init(struct xhci_device *xhci)
Initialise device.
Definition xhci.c:264