source: mainline/uspace/drv/infrastructure/rootamdm37x/rootamdm37x.c@ 063ae706

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 063ae706 was 063ae706, checked in by Jan Vesely <jano.vesely@…>, 14 years ago

rootamdm37x: Add USB TLL and UHH headers, TLL initialization stub.

  • Property mode set to 100644
File size: 6.7 KB
Line 
1/*
2 * Copyright (c) 2012 Jan Vesely
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - 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 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/**
30 * @defgroup root_amdm37x TI AM/DM37x platform driver.
31 * @brief HelenOS TI AM/DM37x platform driver.
32 * @{
33 */
34
35/** @file
36 */
37
38#include <ddf/driver.h>
39#include <ddf/log.h>
40#include <errno.h>
41#include <ops/hw_res.h>
42#include <stdio.h>
43#include <ddi.h>
44
45#include "uhh.h"
46#include "usbtll.h"
47
48#define NAME "rootamdm37x"
49
50/** Obtain function soft-state from DDF function node */
51#define ROOTARM_FUN(fnode) \
52 ((rootamdm37x_fun_t *) (fnode)->driver_data)
53
54typedef struct {
55 hw_resource_list_t hw_resources;
56} rootamdm37x_fun_t;
57
58#define OHCI_BASE_ADDRESS 0x48064400
59#define OHCI_SIZE 1024
60#define EHCI_BASE_ADDRESS 0x48064800
61#define EHCI_SIZE 1024
62
63static hw_resource_t ohci_res[] = {
64 {
65 .type = MEM_RANGE,
66 /* See amdm37x TRM page. 3316 for these values */
67 .res.io_range = {
68 .address = OHCI_BASE_ADDRESS,
69 .size = OHCI_SIZE,
70 .endianness = LITTLE_ENDIAN
71 },
72 },
73 {
74 .type = INTERRUPT,
75 .res.interrupt = { .irq = 76 },
76 },
77};
78
79static const rootamdm37x_fun_t ohci = {
80 .hw_resources = {
81 .resources = ohci_res,
82 .count = sizeof(ohci_res)/sizeof(ohci_res[0]),
83 }
84};
85
86static hw_resource_t ehci_res[] = {
87 {
88 .type = MEM_RANGE,
89 /* See amdm37x TRM page. 3316 for these values */
90 .res.io_range = {
91 .address = EHCI_BASE_ADDRESS,
92 .size = EHCI_SIZE,
93 .endianness = LITTLE_ENDIAN
94 },
95 },
96 {
97 .type = INTERRUPT,
98 .res.interrupt = { .irq = 77 },
99 },
100};
101
102static const rootamdm37x_fun_t ehci = {
103 .hw_resources = {
104 .resources = ehci_res,
105 .count = sizeof(ehci_res)/sizeof(ehci_res[0]),
106 }
107};
108
109static hw_resource_list_t *rootamdm37x_get_resources(ddf_fun_t *fnode);
110static bool rootamdm37x_enable_interrupt(ddf_fun_t *fun);
111
112static hw_res_ops_t fun_hw_res_ops = {
113 .get_resource_list = &rootamdm37x_get_resources,
114 .enable_interrupt = &rootamdm37x_enable_interrupt,
115};
116
117static ddf_dev_ops_t rootamdm37x_fun_ops =
118{
119 .interfaces[HW_RES_DEV_IFACE] = &fun_hw_res_ops
120};
121
122static int usb_clocks(bool on)
123{
124 uint32_t *usb_host_cm = NULL;
125 uint32_t *l4_core_cm = NULL;
126
127 int ret = pio_enable((void*)0x48005400, 8192, (void**)&usb_host_cm);
128 if (ret != EOK)
129 return ret;
130
131 ret = pio_enable((void*)0x48004a00, 8192, (void**)&l4_core_cm);
132 if (ret != EOK)
133 return ret;
134
135 assert(l4_core_cm);
136 assert(usb_host_cm);
137 if (on) {
138 l4_core_cm[0xe] |= 0x4; /* iclk */
139 l4_core_cm[0x3] |= 0x4; /* fclk */
140
141 /* offset 0x10 (0x4 int32)[0] enables fclk,
142 * offset 0x00 (0x0 int32)[0 and 1] enables iclk,
143 * offset 0x30 (0xc int32)[0] enables autoidle
144 */
145 usb_host_cm[0x4] = 0x1;
146 usb_host_cm[0x0] = 0x3;
147 usb_host_cm[0xc] = 0x1;
148 } else {
149 usb_host_cm[0xc] = 0;
150 usb_host_cm[0x0] = 0;
151 usb_host_cm[0x4] = 0;
152 l4_core_cm[0xe] &= ~0x4;
153 l4_core_cm[0x3] &= ~0x4;
154 }
155
156 return ret;
157}
158
159static int usb_tll_init()
160{
161 return EOK;
162}
163
164static bool rootamdm37x_add_fun(ddf_dev_t *dev, const char *name,
165 const char *str_match_id, const rootamdm37x_fun_t *fun)
166{
167 ddf_msg(LVL_DEBUG, "Adding new function '%s'.", name);
168
169 ddf_fun_t *fnode = NULL;
170 match_id_t *match_id = NULL;
171
172 /* Create new device. */
173 fnode = ddf_fun_create(dev, fun_inner, name);
174 if (fnode == NULL)
175 goto failure;
176
177 fnode->driver_data = (void*)fun;
178
179 /* Initialize match id list */
180 match_id = create_match_id();
181 if (match_id == NULL)
182 goto failure;
183
184 match_id->id = str_match_id;
185 match_id->score = 100;
186 add_match_id(&fnode->match_ids, match_id);
187
188 /* Set provided operations to the device. */
189 fnode->ops = &rootamdm37x_fun_ops;
190
191 /* Register function. */
192 if (ddf_fun_bind(fnode) != EOK) {
193 ddf_msg(LVL_ERROR, "Failed binding function %s.", name);
194 goto failure;
195 }
196
197 return true;
198
199failure:
200 if (match_id != NULL)
201 match_id->id = NULL;
202
203 if (fnode != NULL) {
204 fnode->driver_data = NULL;
205 ddf_fun_destroy(fnode);
206 }
207
208 ddf_msg(LVL_ERROR, "Failed adding function '%s'.", name);
209
210 return false;
211}
212
213/** Add the root device.
214 *
215 * @param dev Device which is root of the whole device tree
216 * (both of HW and pseudo devices).
217 *
218 * @return Zero on success, negative error number otherwise.
219 *
220 */
221static int rootamdm37x_dev_add(ddf_dev_t *dev)
222{
223 int ret = usb_clocks(true);
224 if (ret != EOK) {
225 ddf_msg(LVL_FATAL, "Failed to enable USB HC clocks!.\n");
226 return ret;
227 }
228
229 ret = usb_tll_init();
230 if (ret != EOK) {
231 ddf_msg(LVL_FATAL, "Failed to init USB TLL!.\n");
232 usb_clocks(false);
233 return ret;
234 }
235
236 /* Register functions */
237 if (!rootamdm37x_add_fun(dev, "ohci", "usb/host=ohci", &ohci))
238 ddf_msg(LVL_ERROR, "Failed to add OHCI function for "
239 "BeagleBoard-xM platform.");
240 if (!rootamdm37x_add_fun(dev, "ehci", "usb/host=ehci", &ehci))
241 ddf_msg(LVL_ERROR, "Failed to add EHCI function for "
242 "BeagleBoard-xM platform.");
243
244 return EOK;
245}
246
247/** The root device driver's standard operations. */
248static driver_ops_t rootamdm37x_ops = {
249 .dev_add = &rootamdm37x_dev_add
250};
251
252/** The root device driver structure. */
253static driver_t rootamdm37x_driver = {
254 .name = NAME,
255 .driver_ops = &rootamdm37x_ops
256};
257
258static hw_resource_list_t *rootamdm37x_get_resources(ddf_fun_t *fnode)
259{
260 rootamdm37x_fun_t *fun = ROOTARM_FUN(fnode);
261 assert(fun != NULL);
262 return &fun->hw_resources;
263}
264
265static bool rootamdm37x_enable_interrupt(ddf_fun_t *fun)
266{
267 /* TODO */
268 return false;
269}
270
271int main(int argc, char *argv[])
272{
273 printf("%s: HelenOS AM/DM37x(OMAP37x) platform driver\n", NAME);
274 ddf_log_init(NAME, LVL_ERROR);
275 return ddf_driver_main(&rootamdm37x_driver);
276}
277
278/**
279 * @}
280 */
Note: See TracBrowser for help on using the repository browser.