dwctwo_plb.c revision 1.1 1 /* $NetBSD: dwctwo_plb.c,v 1.1 2013/11/21 13:33:15 kiyohara Exp $ */
2 /*
3 * Copyright (c) 2013 KIYOHARA Takashi
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
19 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
23 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
24 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 #include <sys/cdefs.h>
29 __KERNEL_RCSID(0, "$NetBSD: dwctwo_plb.c,v 1.1 2013/11/21 13:33:15 kiyohara Exp $");
30
31 #include <sys/param.h>
32 #include <sys/bus.h>
33 #include <sys/device.h>
34 #include <sys/errno.h>
35 #include <sys/extent.h>
36
37 #include <powerpc/ibm4xx/cpu.h>
38 #include <powerpc/ibm4xx/dev/plbvar.h>
39
40 #include <dev/usb/usb.h>
41 #include <dev/usb/usbdi.h>
42 #include <dev/usb/usbdivar.h>
43 #include <dev/usb/usb_mem.h>
44
45 #include <dwc2/dwc2.h>
46 #include <dwc2/dwc2var.h>
47 #include "dwc2_core.h"
48
49 #include "locators.h"
50
51 #define DWCTWO_SIZE 0x40000
52
53 static int dwctwo_plb_match(device_t, cfdata_t, void *);
54 static void dwctwo_plb_attach(device_t, device_t, void *);
55
56 static void dwctwo_plb_deferred(device_t);
57
58 CFATTACH_DECL_NEW(dwctwo_plb, sizeof(struct dwc2_softc),
59 dwctwo_plb_match, dwctwo_plb_attach, NULL, NULL);
60
61 static struct powerpc_bus_space dwctwo_tag = {
62 _BUS_SPACE_LITTLE_ENDIAN | _BUS_SPACE_MEM_TYPE,
63 0x00000000,
64 0x00000000,
65 DWCTWO_SIZE
66 };
67 static char ex_storage[EXTENT_FIXED_STORAGE_SIZE(8)]
68 __attribute__((aligned(8)));
69
70 static struct dwc2_core_params dwctwo_405ex_params = {
71 .otg_cap = 0, /* HNP/SRP capable */
72 .otg_ver = 0, /* 1.3 */
73 .dma_enable = 1,
74 .dma_desc_enable = 0,
75 .speed = 0, /* High Speed */
76 .enable_dynamic_fifo = 1,
77 .en_multiple_tx_fifo = 0,
78 .host_rx_fifo_size = 531, /* 531 DWORDs */
79 .host_nperio_tx_fifo_size = 256, /* 256 DWORDs */
80 .host_perio_tx_fifo_size = 256, /* 256 DWORDs */
81 .max_transfer_size = 524287,
82 .max_packet_count = 1023,
83 .host_channels = 4,
84 .phy_type = 2, /* ULPI */
85 .phy_utmi_width = 8, /* 8 bits */
86 .phy_ulpi_ddr = 0, /* Single */
87 .phy_ulpi_ext_vbus = 0,
88 .i2c_enable = 0,
89 .ulpi_fs_ls = 0,
90 .host_support_fs_ls_low_power = 0,
91 .host_ls_low_power_phy_clk = 0, /* 48 MHz */
92 .ts_dline = 0,
93 .reload_ctl = 0,
94 .ahbcfg = 0x10,
95 .uframe_sched = 1,
96 };
97
98
99 static int
100 dwctwo_plb_match(device_t parent, cfdata_t match, void *aux)
101 {
102 struct plb_attach_args *paa = aux;
103
104 if (strcmp(paa->plb_name, match->cf_name) != 0)
105 return 0;
106
107 if (match->cf_loc[PLBCF_ADDR] == PLBCF_ADDR_DEFAULT)
108 panic("dwctwo_plb_match: wildcard addr not allowed");
109 if (match->cf_loc[PLBCF_IRQ] == PLBCF_IRQ_DEFAULT)
110 panic("dwctwo_plb_match: wildcard IRQ not allowed");
111
112 paa->plb_addr = match->cf_loc[PLBCF_ADDR];
113 paa->plb_irq = match->cf_loc[PLBCF_IRQ];
114 return 1;
115 }
116
117 static void
118 dwctwo_plb_attach(device_t parent, device_t self, void *aux)
119 {
120 struct dwc2_softc *sc = device_private(self);
121 struct plb_attach_args *paa = aux;
122 uint32_t srst0;
123
124 sc->sc_dev = self;
125 sc->sc_params = &dwctwo_405ex_params;
126
127 dwctwo_tag.pbs_base = paa->plb_addr;
128 dwctwo_tag.pbs_limit += paa->plb_addr;
129 if (bus_space_init(&dwctwo_tag, "dwctwotag", ex_storage,
130 sizeof(ex_storage)))
131 panic("dwctwo_attach: Failed to initialise opb_tag");
132 sc->sc_iot = &dwctwo_tag;
133 bus_space_map(sc->sc_iot, paa->plb_addr, DWCTWO_SIZE, 0, &sc->sc_ioh);
134 sc->sc_bus.dmatag = paa->plb_dmat;
135
136 intr_establish(paa->plb_irq, IST_LEVEL, IPL_USB, dwc2_intr, sc);
137
138 /* Enable the USB interface. */
139 mtsdr(DCR_SDR0_PFC1, mfsdr(DCR_SDR0_PFC1) | SDR0_PFC1_USBEN);
140 srst0 = mfsdr(DCR_SDR0_SRST0);
141 mtsdr(DCR_SDR0_SRST0, srst0 | SDR0_SRST0_UPRST | SDR0_SRST0_AHB);
142 delay(200 * 1000); /* XXXX */
143 mtsdr(DCR_SDR0_SRST0, srst0);
144
145 config_defer(self, dwctwo_plb_deferred);
146 }
147
148 static void
149 dwctwo_plb_deferred(device_t self)
150 {
151 struct dwc2_softc *sc = device_private(self);
152 int error;
153
154 error = dwc2_init(sc);
155 if (error != 0) {
156 aprint_error_dev(self, "couldn't initialize host, error=%d\n",
157 error);
158 return;
159 }
160 sc->sc_child = config_found(sc->sc_dev, &sc->sc_bus, usbctlprint);
161 }
162