source: mainline/uspace/drv/platform/amdm37x/main.c

Last change on this file was 09ab0a9a, checked in by Jiri Svoboda <jiri@…>, 7 years ago

Fix vertical spacing with new Ccheck revision.

  • 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 * @addtogroup amdm37x
31 * @{
32 */
33
34/** @file
35 */
36
37#define DEBUG_CM 0
38
39#include <ddf/log.h>
40#include <errno.h>
41#include <ops/hw_res.h>
42#include <stdio.h>
43
44#include "amdm37x.h"
45
46#define NAME "amdm37x"
47
48typedef struct {
49 const char *name;
50 const char *id;
51 int score;
52 hw_resource_list_t hw_resources;
53} amdm37x_fun_t;
54
55/* See amdm37x TRM page 3316 for these values */
56#define OHCI_BASE_ADDRESS 0x48064400
57#define OHCI_SIZE 1024
58#define EHCI_BASE_ADDRESS 0x48064800
59#define EHCI_SIZE 1024
60
61/* See amdm37x TRM page 1813 for these values */
62#define DSS_BASE_ADDRESS 0x48050000
63#define DSS_SIZE 512
64#define DISPC_BASE_ADDRESS 0x48050400
65#define DISPC_SIZE 1024
66#define VIDEO_ENC_BASE_ADDRESS 0x48050C00
67#define VIDEO_ENC_SIZE 256
68
69static hw_resource_t ohci_res[] = {
70 {
71 .type = MEM_RANGE,
72 .res.io_range = {
73 .address = OHCI_BASE_ADDRESS,
74 .size = OHCI_SIZE,
75 .endianness = LITTLE_ENDIAN
76 },
77 },
78 {
79 .type = INTERRUPT,
80 .res.interrupt = { .irq = 76 },
81 },
82};
83
84static hw_resource_t ehci_res[] = {
85 {
86 .type = MEM_RANGE,
87 /* See amdm37x TRM page. 3316 for these values */
88 .res.io_range = {
89 .address = EHCI_BASE_ADDRESS,
90 .size = EHCI_SIZE,
91 .endianness = LITTLE_ENDIAN
92 },
93 },
94 {
95 .type = INTERRUPT,
96 .res.interrupt = { .irq = 77 },
97 },
98};
99
100static hw_resource_t disp_res[] = {
101 {
102 .type = MEM_RANGE,
103 .res.io_range = {
104 .address = DSS_BASE_ADDRESS,
105 .size = DSS_SIZE,
106 .endianness = LITTLE_ENDIAN
107 },
108 },
109 {
110 .type = MEM_RANGE,
111 .res.io_range = {
112 .address = DISPC_BASE_ADDRESS,
113 .size = DISPC_SIZE,
114 .endianness = LITTLE_ENDIAN
115 },
116 },
117 {
118 .type = MEM_RANGE,
119 .res.io_range = {
120 .address = VIDEO_ENC_BASE_ADDRESS,
121 .size = VIDEO_ENC_SIZE,
122 .endianness = LITTLE_ENDIAN
123 },
124 },
125 {
126 .type = INTERRUPT,
127 .res.interrupt = { .irq = 25 },
128 },
129};
130
131static const amdm37x_fun_t amdm37x_funcs[] = {
132 {
133 .name = "ohci",
134 .id = "usb/host=ohci",
135 .score = 90,
136 .hw_resources = { .resources = ohci_res, .count = ARRAY_SIZE(ohci_res) }
137 },
138 {
139 .name = "ehci",
140 .id = "usb/host=ehci",
141 .score = 90,
142 .hw_resources = { .resources = ehci_res, .count = ARRAY_SIZE(ehci_res) }
143 },
144 {
145 .name = "fb",
146 .id = "amdm37x&dispc",
147 .score = 90,
148 .hw_resources = { .resources = disp_res, .count = ARRAY_SIZE(disp_res) }
149 },
150};
151
152static hw_resource_list_t *amdm37x_get_resources(ddf_fun_t *fnode);
153static errno_t amdm37x_enable_interrupt(ddf_fun_t *fun, int);
154
155static hw_res_ops_t fun_hw_res_ops = {
156 .get_resource_list = &amdm37x_get_resources,
157 .enable_interrupt = &amdm37x_enable_interrupt,
158};
159
160static ddf_dev_ops_t amdm37x_fun_ops = {
161 .interfaces[HW_RES_DEV_IFACE] = &fun_hw_res_ops
162};
163
164static errno_t amdm37x_add_fun(ddf_dev_t *dev, const amdm37x_fun_t *fun)
165{
166 assert(dev);
167 assert(fun);
168
169 ddf_msg(LVL_DEBUG, "Adding new function '%s'.", fun->name);
170
171 /* Create new device function. */
172 ddf_fun_t *fnode = ddf_fun_create(dev, fun_inner, fun->name);
173 if (fnode == NULL)
174 return ENOMEM;
175
176 /* Add match id */
177 errno_t ret = ddf_fun_add_match_id(fnode, fun->id, fun->score);
178 if (ret != EOK) {
179 ddf_fun_destroy(fnode);
180 return ret;
181 }
182
183 /* Alloc needed data */
184 amdm37x_fun_t *rf =
185 ddf_fun_data_alloc(fnode, sizeof(amdm37x_fun_t));
186 if (!rf) {
187 ddf_fun_destroy(fnode);
188 return ENOMEM;
189 }
190 *rf = *fun;
191
192 /* Set provided operations to the device. */
193 ddf_fun_set_ops(fnode, &amdm37x_fun_ops);
194
195 /* Register function. */
196 ret = ddf_fun_bind(fnode);
197 if (ret != EOK) {
198 ddf_msg(LVL_ERROR, "Failed binding function %s.", fun->name);
199 ddf_fun_destroy(fnode);
200 return ret;
201 }
202
203 return EOK;
204}
205
206/** Add the root device.
207 *
208 * @param dev Device which is root of the whole device tree
209 * (both of HW and pseudo devices).
210 *
211 * @return Zero on success, error number otherwise.
212 *
213 */
214static errno_t amdm37x_dev_add(ddf_dev_t *dev)
215{
216 assert(dev);
217 amdm37x_t *device = ddf_dev_data_alloc(dev, sizeof(amdm37x_t));
218 if (!device)
219 return ENOMEM;
220 errno_t ret = amdm37x_init(device, DEBUG_CM);
221 if (ret != EOK) {
222 ddf_msg(LVL_FATAL, "Failed to setup hw access!.\n");
223 return ret;
224 }
225
226 /* Set dplls to ON and automatic */
227 amdm37x_setup_dpll_on_autoidle(device);
228
229 /* Enable function and interface clocks */
230 amdm37x_usb_clocks_set(device, true);
231
232 /* Init TLL */
233 ret = amdm37x_usb_tll_init(device);
234 if (ret != EOK) {
235 ddf_msg(LVL_FATAL, "Failed to init USB TLL!.\n");
236 amdm37x_usb_clocks_set(device, false);
237 return ret;
238 }
239
240 /* Register functions */
241 for (unsigned i = 0; i < ARRAY_SIZE(amdm37x_funcs); ++i) {
242 if (amdm37x_add_fun(dev, &amdm37x_funcs[i]) != EOK)
243 ddf_msg(LVL_ERROR, "Failed to add %s function for "
244 "BeagleBoard-xM platform.", amdm37x_funcs[i].name);
245 }
246 return EOK;
247}
248
249/** The root device driver's standard operations. */
250static driver_ops_t amdm37x_ops = {
251 .dev_add = &amdm37x_dev_add
252};
253
254/** The root device driver structure. */
255static driver_t amdm37x_driver = {
256 .name = NAME,
257 .driver_ops = &amdm37x_ops
258};
259
260static hw_resource_list_t *amdm37x_get_resources(ddf_fun_t *fnode)
261{
262 amdm37x_fun_t *fun = ddf_fun_data_get(fnode);
263 assert(fun != NULL);
264 return &fun->hw_resources;
265}
266
267static errno_t amdm37x_enable_interrupt(ddf_fun_t *fun, int irq)
268{
269 //TODO: Implement
270 return false;
271}
272
273int main(int argc, char *argv[])
274{
275 printf("%s: HelenOS AM/DM37x(OMAP37x) platform driver\n", NAME);
276 ddf_log_init(NAME);
277 return ddf_driver_main(&amdm37x_driver);
278}
279
280/**
281 * @}
282 */
Note: See TracBrowser for help on using the repository browser.