4 * DSP-BIOS Bridge driver support functions for TI OMAP processors.
6 * Implementation of Manager interface to the device object at the
7 * driver level. This queries the NDB data base and retrieves the
8 * data about Node and Processor.
10 * Copyright (C) 2005-2006 Texas Instruments, Inc.
12 * This package is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
16 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
18 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21 /* ----------------------------------- DSP/BIOS Bridge */
22 #include <dspbridge/std.h>
23 #include <dspbridge/dbdefs.h>
25 /* ----------------------------------- Trace & Debug */
26 #include <dspbridge/dbc.h>
28 /* ----------------------------------- OS Adaptation Layer */
29 #include <dspbridge/cfg.h>
30 #include <dspbridge/sync.h>
32 /* ----------------------------------- Others */
33 #include <dspbridge/dbdcd.h>
34 #include <dspbridge/drv.h>
35 #include <dspbridge/dev.h>
37 /* ----------------------------------- This */
38 #include <dspbridge/mgr.h>
40 /* ----------------------------------- Defines, Data Structures, Typedefs */
44 struct dcd_manager
*hdcd_mgr
; /* Proc/Node data manager */
47 /* ----------------------------------- Globals */
51 * ========= mgr_create =========
53 * MGR Object gets created only once during driver Loading.
55 int mgr_create(OUT
struct mgr_object
**phMgrObject
,
56 struct cfg_devnode
*dev_node_obj
)
59 struct mgr_object
*pmgr_obj
= NULL
;
61 DBC_REQUIRE(phMgrObject
!= NULL
);
62 DBC_REQUIRE(refs
> 0);
64 pmgr_obj
= kzalloc(sizeof(struct mgr_object
), GFP_KERNEL
);
66 status
= dcd_create_manager(ZLDLLNAME
, &pmgr_obj
->hdcd_mgr
);
67 if (DSP_SUCCEEDED(status
)) {
68 /* If succeeded store the handle in the MGR Object */
69 status
= cfg_set_object((u32
) pmgr_obj
, REG_MGR_OBJECT
);
70 if (DSP_SUCCEEDED(status
)) {
71 *phMgrObject
= pmgr_obj
;
73 dcd_destroy_manager(pmgr_obj
->hdcd_mgr
);
77 /* failed to Create DCD Manager */
84 DBC_ENSURE(DSP_FAILED(status
) || pmgr_obj
);
89 * ========= mgr_destroy =========
90 * This function is invoked during bridge driver unloading.Frees MGR object.
92 int mgr_destroy(struct mgr_object
*hmgr_obj
)
95 struct mgr_object
*pmgr_obj
= (struct mgr_object
*)hmgr_obj
;
97 DBC_REQUIRE(refs
> 0);
98 DBC_REQUIRE(hmgr_obj
);
101 if (hmgr_obj
->hdcd_mgr
)
102 dcd_destroy_manager(hmgr_obj
->hdcd_mgr
);
105 /* Update the Registry with NULL for MGR Object */
106 (void)cfg_set_object(0, REG_MGR_OBJECT
);
112 * ======== mgr_enum_node_info ========
113 * Enumerate and get configuration information about nodes configured
114 * in the node database.
116 int mgr_enum_node_info(u32 node_id
, OUT
struct dsp_ndbprops
*pndb_props
,
117 u32 undb_props_size
, OUT u32
*pu_num_nodes
)
120 struct dsp_uuid node_uuid
, temp_uuid
;
123 struct dcd_genericobj gen_obj
;
124 struct mgr_object
*pmgr_obj
= NULL
;
126 DBC_REQUIRE(pndb_props
!= NULL
);
127 DBC_REQUIRE(pu_num_nodes
!= NULL
);
128 DBC_REQUIRE(undb_props_size
>= sizeof(struct dsp_ndbprops
));
129 DBC_REQUIRE(refs
> 0);
132 /* Get The Manager Object from the Registry */
133 status
= cfg_get_object((u32
*) &pmgr_obj
, REG_MGR_OBJECT
);
134 if (DSP_FAILED(status
))
137 DBC_ASSERT(pmgr_obj
);
138 /* Forever loop till we hit failed or no more items in the
139 * Enumeration. We will exit the loop other than 0; */
140 while (status
== 0) {
141 status
= dcd_enumerate_object(temp_index
++, DSP_DCDNODETYPE
,
145 if (node_id
== (node_index
- 1))
146 node_uuid
= temp_uuid
;
150 if (DSP_SUCCEEDED(status
)) {
151 if (node_id
> (node_index
- 1)) {
154 status
= dcd_get_object_def(pmgr_obj
->hdcd_mgr
,
156 &node_uuid
, DSP_DCDNODETYPE
,
158 if (DSP_SUCCEEDED(status
)) {
159 /* Get the Obj def */
161 gen_obj
.obj_data
.node_obj
.ndb_props
;
162 *pu_num_nodes
= node_index
;
168 DBC_ENSURE((DSP_SUCCEEDED(status
) && *pu_num_nodes
> 0) ||
169 (DSP_FAILED(status
) && *pu_num_nodes
== 0));
175 * ======== mgr_enum_processor_info ========
176 * Enumerate and get configuration information about available
179 int mgr_enum_processor_info(u32 processor_id
,
180 OUT
struct dsp_processorinfo
*
181 processor_info
, u32 processor_info_size
,
182 OUT u8
*pu_num_procs
)
187 struct dsp_uuid temp_uuid
;
190 struct dcd_genericobj gen_obj
;
191 struct mgr_object
*pmgr_obj
= NULL
;
192 struct mgr_processorextinfo
*ext_info
;
193 struct dev_object
*hdev_obj
;
194 struct drv_object
*hdrv_obj
;
196 struct cfg_devnode
*dev_node
;
197 bool proc_detect
= false;
199 DBC_REQUIRE(processor_info
!= NULL
);
200 DBC_REQUIRE(pu_num_procs
!= NULL
);
201 DBC_REQUIRE(processor_info_size
>= sizeof(struct dsp_processorinfo
));
202 DBC_REQUIRE(refs
> 0);
205 status
= cfg_get_object((u32
*) &hdrv_obj
, REG_DRV_OBJECT
);
206 if (DSP_SUCCEEDED(status
)) {
207 status
= drv_get_dev_object(processor_id
, hdrv_obj
, &hdev_obj
);
208 if (DSP_SUCCEEDED(status
)) {
209 status
= dev_get_dev_type(hdev_obj
, (u8
*) &dev_type
);
210 status
= dev_get_dev_node(hdev_obj
, &dev_node
);
211 if (dev_type
!= DSP_UNIT
)
214 if (DSP_SUCCEEDED(status
))
215 processor_info
->processor_type
= DSPTYPE64
;
218 if (DSP_FAILED(status
))
221 /* Get The Manager Object from the Registry */
222 if (DSP_FAILED(cfg_get_object((u32
*) &pmgr_obj
, REG_MGR_OBJECT
))) {
223 dev_dbg(bridge
, "%s: Failed to get MGR Object\n", __func__
);
226 DBC_ASSERT(pmgr_obj
);
227 /* Forever loop till we hit no more items in the
228 * Enumeration. We will exit the loop other than 0; */
229 while (status1
== 0) {
230 status1
= dcd_enumerate_object(temp_index
++,
231 DSP_DCDPROCESSORTYPE
,
237 /* Get the Object properties to find the Device/Processor
239 if (proc_detect
!= false)
242 status2
= dcd_get_object_def(pmgr_obj
->hdcd_mgr
,
243 (struct dsp_uuid
*)&temp_uuid
,
244 DSP_DCDPROCESSORTYPE
, &gen_obj
);
245 if (DSP_SUCCEEDED(status2
)) {
246 /* Get the Obj def */
247 if (processor_info_size
<
248 sizeof(struct mgr_processorextinfo
)) {
249 *processor_info
= gen_obj
.obj_data
.proc_info
;
252 ext_info
= (struct mgr_processorextinfo
*)
254 *ext_info
= gen_obj
.obj_data
.ext_proc_obj
;
256 dev_dbg(bridge
, "%s: Got proctype from DCD %x\n",
257 __func__
, processor_info
->processor_type
);
258 /* See if we got the needed processor */
259 if (dev_type
== DSP_UNIT
) {
260 if (processor_info
->processor_type
==
263 } else if (dev_type
== IVA_UNIT
) {
264 if (processor_info
->processor_type
==
268 /* User applciatiuons aonly check for chip type, so
269 * this clumsy overwrite */
270 processor_info
->processor_type
= DSPTYPE64
;
272 dev_dbg(bridge
, "%s: Failed to get DCD processor info "
273 "%x\n", __func__
, status2
);
277 *pu_num_procs
= proc_index
;
278 if (proc_detect
== false) {
279 dev_dbg(bridge
, "%s: Failed to get proc info from DCD, so use "
280 "CFG registry\n", __func__
);
281 processor_info
->processor_type
= DSPTYPE64
;
288 * ======== mgr_exit ========
289 * Decrement reference count, and free resources when reference count is
294 DBC_REQUIRE(refs
> 0);
299 DBC_ENSURE(refs
>= 0);
303 * ======== mgr_get_dcd_handle ========
304 * Retrieves the MGR handle. Accessor Function.
306 int mgr_get_dcd_handle(struct mgr_object
*mgr_handle
,
310 struct mgr_object
*pmgr_obj
= (struct mgr_object
*)mgr_handle
;
312 DBC_REQUIRE(refs
> 0);
313 DBC_REQUIRE(dcd_handle
!= NULL
);
315 *dcd_handle
= (u32
) NULL
;
317 *dcd_handle
= (u32
) pmgr_obj
->hdcd_mgr
;
320 DBC_ENSURE((DSP_SUCCEEDED(status
) && *dcd_handle
!= (u32
) NULL
) ||
321 (DSP_FAILED(status
) && *dcd_handle
== (u32
) NULL
));
327 * ======== mgr_init ========
328 * Initialize MGR's private state, keeping a reference count on each call.
333 bool init_dcd
= false;
335 DBC_REQUIRE(refs
>= 0);
338 init_dcd
= dcd_init(); /* DCD Module */
347 DBC_ENSURE((ret
&& (refs
> 0)) || (!ret
&& (refs
>= 0)));
353 * ======== mgr_wait_for_bridge_events ========
354 * Block on any Bridge event(s)
356 int mgr_wait_for_bridge_events(struct dsp_notification
**anotifications
,
357 u32 count
, OUT u32
*pu_index
,
361 struct sync_object
*sync_events
[MAX_EVENTS
];
364 DBC_REQUIRE(count
< MAX_EVENTS
);
366 for (i
= 0; i
< count
; i
++)
367 sync_events
[i
] = anotifications
[i
]->handle
;
369 status
= sync_wait_on_multiple_events(sync_events
, count
, utimeout
,