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 #include <linux/types.h>
23 /* ----------------------------------- Host OS */
24 #include <dspbridge/host_os.h>
26 /* ----------------------------------- DSP/BIOS Bridge */
27 #include <dspbridge/dbdefs.h>
29 /* ----------------------------------- Trace & Debug */
30 #include <dspbridge/dbc.h>
32 /* ----------------------------------- OS Adaptation Layer */
33 #include <dspbridge/sync.h>
35 /* ----------------------------------- Others */
36 #include <dspbridge/dbdcd.h>
37 #include <dspbridge/drv.h>
38 #include <dspbridge/dev.h>
40 /* ----------------------------------- This */
41 #include <dspbridge/mgr.h>
43 /* ----------------------------------- Defines, Data Structures, Typedefs */
47 struct dcd_manager *hdcd_mgr; /* Proc/Node data manager */
50 /* ----------------------------------- Globals */
54 * ========= mgr_create =========
56 * MGR Object gets created only once during driver Loading.
58 int mgr_create(struct mgr_object **mgr_obj,
59 struct cfg_devnode *dev_node_obj)
62 struct mgr_object *pmgr_obj = NULL;
63 struct drv_data *drv_datap = dev_get_drvdata(bridge);
65 DBC_REQUIRE(mgr_obj != NULL);
66 DBC_REQUIRE(refs > 0);
68 pmgr_obj = kzalloc(sizeof(struct mgr_object), GFP_KERNEL);
70 status = dcd_create_manager(ZLDLLNAME, &pmgr_obj->hdcd_mgr);
72 /* If succeeded store the handle in the MGR Object */
74 drv_datap->mgr_object = (void *)pmgr_obj;
77 pr_err("%s: Failed to store MGR object\n",
84 dcd_destroy_manager(pmgr_obj->hdcd_mgr);
88 /* failed to Create DCD Manager */
95 DBC_ENSURE(status || pmgr_obj);
100 * ========= mgr_destroy =========
101 * This function is invoked during bridge driver unloading.Frees MGR object.
103 int mgr_destroy(struct mgr_object *hmgr_obj)
106 struct mgr_object *pmgr_obj = (struct mgr_object *)hmgr_obj;
107 struct drv_data *drv_datap = dev_get_drvdata(bridge);
109 DBC_REQUIRE(refs > 0);
110 DBC_REQUIRE(hmgr_obj);
113 if (hmgr_obj->hdcd_mgr)
114 dcd_destroy_manager(hmgr_obj->hdcd_mgr);
117 /* Update the driver data with NULL for MGR Object */
119 drv_datap->mgr_object = NULL;
122 pr_err("%s: Failed to store MGR object\n", __func__);
129 * ======== mgr_enum_node_info ========
130 * Enumerate and get configuration information about nodes configured
131 * in the node database.
133 int mgr_enum_node_info(u32 node_id, struct dsp_ndbprops *pndb_props,
134 u32 undb_props_size, u32 *pu_num_nodes)
137 struct dsp_uuid node_uuid, temp_uuid;
140 struct dcd_genericobj gen_obj;
141 struct mgr_object *pmgr_obj = NULL;
142 struct drv_data *drv_datap = dev_get_drvdata(bridge);
144 DBC_REQUIRE(pndb_props != NULL);
145 DBC_REQUIRE(pu_num_nodes != NULL);
146 DBC_REQUIRE(undb_props_size >= sizeof(struct dsp_ndbprops));
147 DBC_REQUIRE(refs > 0);
150 /* Get the Manager Object from the driver data */
151 if (!drv_datap || !drv_datap->mgr_object) {
153 pr_err("%s: Failed to retrieve the object handle\n", __func__);
156 pmgr_obj = drv_datap->mgr_object;
159 DBC_ASSERT(pmgr_obj);
160 /* Forever loop till we hit failed or no more items in the
161 * Enumeration. We will exit the loop other than 0; */
162 while (status == 0) {
163 status = dcd_enumerate_object(temp_index++, DSP_DCDNODETYPE,
167 if (node_id == (node_index - 1))
168 node_uuid = temp_uuid;
173 if (node_id > (node_index - 1)) {
176 status = dcd_get_object_def(pmgr_obj->hdcd_mgr,
178 &node_uuid, DSP_DCDNODETYPE,
181 /* Get the Obj def */
183 gen_obj.obj_data.node_obj.ndb_props;
184 *pu_num_nodes = node_index;
190 DBC_ENSURE((!status && *pu_num_nodes > 0) ||
191 (status && *pu_num_nodes == 0));
197 * ======== mgr_enum_processor_info ========
198 * Enumerate and get configuration information about available
201 int mgr_enum_processor_info(u32 processor_id,
202 struct dsp_processorinfo *
203 processor_info, u32 processor_info_size,
209 struct dsp_uuid temp_uuid;
212 struct dcd_genericobj gen_obj;
213 struct mgr_object *pmgr_obj = NULL;
214 struct mgr_processorextinfo *ext_info;
215 struct dev_object *hdev_obj;
216 struct drv_object *hdrv_obj;
218 struct cfg_devnode *dev_node;
219 struct drv_data *drv_datap = dev_get_drvdata(bridge);
220 bool proc_detect = false;
222 DBC_REQUIRE(processor_info != NULL);
223 DBC_REQUIRE(pu_num_procs != NULL);
224 DBC_REQUIRE(processor_info_size >= sizeof(struct dsp_processorinfo));
225 DBC_REQUIRE(refs > 0);
229 /* Retrieve the Object handle from the driver data */
230 if (!drv_datap || !drv_datap->drv_object) {
232 pr_err("%s: Failed to retrieve the object handle\n", __func__);
234 hdrv_obj = drv_datap->drv_object;
238 status = drv_get_dev_object(processor_id, hdrv_obj, &hdev_obj);
240 status = dev_get_dev_type(hdev_obj, (u8 *) &dev_type);
241 status = dev_get_dev_node(hdev_obj, &dev_node);
242 if (dev_type != DSP_UNIT)
246 processor_info->processor_type = DSPTYPE64;
252 /* Get The Manager Object from the driver data */
253 if (drv_datap && drv_datap->mgr_object) {
254 pmgr_obj = drv_datap->mgr_object;
256 dev_dbg(bridge, "%s: Failed to get MGR Object\n", __func__);
259 DBC_ASSERT(pmgr_obj);
260 /* Forever loop till we hit no more items in the
261 * Enumeration. We will exit the loop other than 0; */
262 while (status1 == 0) {
263 status1 = dcd_enumerate_object(temp_index++,
264 DSP_DCDPROCESSORTYPE,
270 /* Get the Object properties to find the Device/Processor
272 if (proc_detect != false)
275 status2 = dcd_get_object_def(pmgr_obj->hdcd_mgr,
276 (struct dsp_uuid *)&temp_uuid,
277 DSP_DCDPROCESSORTYPE, &gen_obj);
279 /* Get the Obj def */
280 if (processor_info_size <
281 sizeof(struct mgr_processorextinfo)) {
282 *processor_info = gen_obj.obj_data.proc_info;
285 ext_info = (struct mgr_processorextinfo *)
287 *ext_info = gen_obj.obj_data.ext_proc_obj;
289 dev_dbg(bridge, "%s: Got proctype from DCD %x\n",
290 __func__, processor_info->processor_type);
291 /* See if we got the needed processor */
292 if (dev_type == DSP_UNIT) {
293 if (processor_info->processor_type ==
296 } else if (dev_type == IVA_UNIT) {
297 if (processor_info->processor_type ==
301 /* User applciatiuons aonly check for chip type, so
302 * this clumsy overwrite */
303 processor_info->processor_type = DSPTYPE64;
305 dev_dbg(bridge, "%s: Failed to get DCD processor info "
306 "%x\n", __func__, status2);
310 *pu_num_procs = proc_index;
311 if (proc_detect == false) {
312 dev_dbg(bridge, "%s: Failed to get proc info from DCD, so use "
313 "CFG registry\n", __func__);
314 processor_info->processor_type = DSPTYPE64;
321 * ======== mgr_exit ========
322 * Decrement reference count, and free resources when reference count is
327 DBC_REQUIRE(refs > 0);
332 DBC_ENSURE(refs >= 0);
336 * ======== mgr_get_dcd_handle ========
337 * Retrieves the MGR handle. Accessor Function.
339 int mgr_get_dcd_handle(struct mgr_object *mgr_handle,
343 struct mgr_object *pmgr_obj = (struct mgr_object *)mgr_handle;
345 DBC_REQUIRE(refs > 0);
346 DBC_REQUIRE(dcd_handle != NULL);
348 *dcd_handle = (u32) NULL;
350 *dcd_handle = (u32) pmgr_obj->hdcd_mgr;
353 DBC_ENSURE((!status && *dcd_handle != (u32) NULL) ||
354 (status && *dcd_handle == (u32) NULL));
360 * ======== mgr_init ========
361 * Initialize MGR's private state, keeping a reference count on each call.
366 bool init_dcd = false;
368 DBC_REQUIRE(refs >= 0);
371 init_dcd = dcd_init(); /* DCD Module */
380 DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs >= 0)));
386 * ======== mgr_wait_for_bridge_events ========
387 * Block on any Bridge event(s)
389 int mgr_wait_for_bridge_events(struct dsp_notification **anotifications,
390 u32 count, u32 *pu_index,
394 struct sync_object *sync_events[MAX_EVENTS];
397 DBC_REQUIRE(count < MAX_EVENTS);
399 for (i = 0; i < count; i++)
400 sync_events[i] = anotifications[i]->handle;
402 status = sync_wait_on_multiple_events(sync_events, count, utimeout,