1 /*
2  * dev.h
3  *
4  * DSP-BIOS Bridge driver support functions for TI OMAP processors.
5  *
6  * Bridge Bridge driver device operations.
7  *
8  * Copyright (C) 2005-2006 Texas Instruments, Inc.
9  *
10  * This package is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2 as
12  * published by the Free Software Foundation.
13  *
14  * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
16  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
17  */
18 
19 #ifndef DEV_
20 #define DEV_
21 
22 /*  ----------------------------------- Module Dependent Headers */
23 #include <dspbridge/chnldefs.h>
24 #include <dspbridge/cmm.h>
25 #include <dspbridge/cod.h>
26 #include <dspbridge/dspdeh.h>
27 #include <dspbridge/nodedefs.h>
28 #include <dspbridge/disp.h>
29 #include <dspbridge/dspdefs.h>
30 #include <dspbridge/dmm.h>
31 #include <dspbridge/host_os.h>
32 
33 /*  ----------------------------------- This */
34 #include <dspbridge/devdefs.h>
35 
36 /*
37  *  ======== dev_brd_write_fxn ========
38  *  Purpose:
39  *      Exported function to be used as the COD write function.  This function
40  *      is passed a handle to a DEV_hObject by ZL in arb, then calls the
41  *      device's bridge_brd_write() function.
42  *  Parameters:
43  *      arb:           Handle to a Device Object.
44  *      dev_ctxt:    Handle to Bridge driver defined device info.
45  *      dsp_addr:       Address on DSP board (Destination).
46  *      host_buf:       Pointer to host buffer (Source).
47  *      ul_num_bytes:     Number of bytes to transfer.
48  *      mem_type:       Memory space on DSP to which to transfer.
49  *  Returns:
50  *      Number of bytes written.  Returns 0 if the DEV_hObject passed in via
51  *      arb is invalid.
52  *  Requires:
53  *      DEV Initialized.
54  *      host_buf != NULL
55  *  Ensures:
56  */
57 extern u32 dev_brd_write_fxn(void *arb,
58 			     u32 dsp_add,
59 			     void *host_buf, u32 ul_num_bytes, u32 mem_space);
60 
61 /*
62  *  ======== dev_create_device ========
63  *  Purpose:
64  *      Called by the operating system to load the Bridge Driver for a
65  *      'Bridge device.
66  *  Parameters:
67  *      device_obj:     Ptr to location to receive the device object handle.
68  *      driver_file_name: Name of Bridge driver PE DLL file to load.  If the
69  *                      absolute path is not provided, the file is loaded
70  *                      through 'Bridge's module search path.
71  *      host_config:    Host configuration information, to be passed down
72  *                      to the Bridge driver when bridge_dev_create() is called.
73  *      pDspConfig:     DSP resources, to be passed down to the Bridge driver
74  *                      when bridge_dev_create() is called.
75  *      dev_node_obj:       Platform specific device node.
76  *  Returns:
77  *      0:            Module is loaded, device object has been created
78  *      -ENOMEM:        Insufficient memory to create needed resources.
79  *      -EPERM:              Unable to find Bridge driver entry point function.
80  *      -ESPIPE:   Unable to load ZL DLL.
81  *  Requires:
82  *      DEV Initialized.
83  *      device_obj != NULL.
84  *      driver_file_name != NULL.
85  *      host_config != NULL.
86  *      pDspConfig != NULL.
87  *  Ensures:
88  *      0:  *device_obj will contain handle to the new device object.
89  *      Otherwise, does not create the device object, ensures the Bridge driver
90  *      module is unloaded, and sets *device_obj to NULL.
91  */
92 extern int dev_create_device(struct dev_object
93 				    **device_obj,
94 				    const char *driver_file_name,
95 				    struct cfg_devnode *dev_node_obj);
96 
97 /*
98  *  ======== dev_create2 ========
99  *  Purpose:
100  *      After successful loading of the image from api_init_complete2
101  *      (PROC Auto_Start) or proc_load this fxn is called. This creates
102  *      the Node Manager and updates the DEV Object.
103  *  Parameters:
104  *      hdev_obj: Handle to device object created with dev_create_device().
105  *  Returns:
106  *      0:    Successful Creation of Node Manager
107  *      -EPERM:  Some Error Occurred.
108  *  Requires:
109  *      DEV Initialized
110  *      Valid hdev_obj
111  *  Ensures:
112  *      0 and hdev_obj->node_mgr != NULL
113  *      else    hdev_obj->node_mgr == NULL
114  */
115 extern int dev_create2(struct dev_object *hdev_obj);
116 
117 /*
118  *  ======== dev_destroy2 ========
119  *  Purpose:
120  *      Destroys the Node manager for this device.
121  *  Parameters:
122  *      hdev_obj: Handle to device object created with dev_create_device().
123  *  Returns:
124  *      0:    Successful Creation of Node Manager
125  *      -EPERM:  Some Error Occurred.
126  *  Requires:
127  *      DEV Initialized
128  *      Valid hdev_obj
129  *  Ensures:
130  *      0 and hdev_obj->node_mgr == NULL
131  *      else    -EPERM.
132  */
133 extern int dev_destroy2(struct dev_object *hdev_obj);
134 
135 /*
136  *  ======== dev_destroy_device ========
137  *  Purpose:
138  *      Destroys the channel manager for this device, if any, calls
139  *      bridge_dev_destroy(), and then attempts to unload the Bridge module.
140  *  Parameters:
141  *      hdev_obj:     Handle to device object created with
142  *                      dev_create_device().
143  *  Returns:
144  *      0:        Success.
145  *      -EFAULT:    Invalid hdev_obj.
146  *      -EPERM:     The Bridge driver failed it's bridge_dev_destroy() function.
147  *  Requires:
148  *      DEV Initialized.
149  *  Ensures:
150  */
151 extern int dev_destroy_device(struct dev_object
152 				     *hdev_obj);
153 
154 /*
155  *  ======== dev_get_chnl_mgr ========
156  *  Purpose:
157  *      Retrieve the handle to the channel manager created for this device.
158  *  Parameters:
159  *      hdev_obj:     Handle to device object created with
160  *                      dev_create_device().
161  *      *mgr:           Ptr to location to store handle.
162  *  Returns:
163  *      0:        Success.
164  *      -EFAULT:    Invalid hdev_obj.
165  *  Requires:
166  *      mgr != NULL.
167  *      DEV Initialized.
168  *  Ensures:
169  *      0:        *mgr contains a handle to a channel manager object,
170  *                      or NULL.
171  *      else:           *mgr is NULL.
172  */
173 extern int dev_get_chnl_mgr(struct dev_object *hdev_obj,
174 				   struct chnl_mgr **mgr);
175 
176 /*
177  *  ======== dev_get_cmm_mgr ========
178  *  Purpose:
179  *      Retrieve the handle to the shared memory manager created for this
180  *      device.
181  *  Parameters:
182  *      hdev_obj:     Handle to device object created with
183  *                      dev_create_device().
184  *      *mgr:           Ptr to location to store handle.
185  *  Returns:
186  *      0:        Success.
187  *      -EFAULT:    Invalid hdev_obj.
188  *  Requires:
189  *      mgr != NULL.
190  *      DEV Initialized.
191  *  Ensures:
192  *      0:        *mgr contains a handle to a channel manager object,
193  *                      or NULL.
194  *      else:           *mgr is NULL.
195  */
196 extern int dev_get_cmm_mgr(struct dev_object *hdev_obj,
197 				  struct cmm_object **mgr);
198 
199 /*
200  *  ======== dev_get_dmm_mgr ========
201  *  Purpose:
202  *      Retrieve the handle to the dynamic memory manager created for this
203  *      device.
204  *  Parameters:
205  *      hdev_obj:     Handle to device object created with
206  *                      dev_create_device().
207  *      *mgr:           Ptr to location to store handle.
208  *  Returns:
209  *      0:        Success.
210  *      -EFAULT:    Invalid hdev_obj.
211  *  Requires:
212  *      mgr != NULL.
213  *      DEV Initialized.
214  *  Ensures:
215  *      0:        *mgr contains a handle to a channel manager object,
216  *                      or NULL.
217  *      else:           *mgr is NULL.
218  */
219 extern int dev_get_dmm_mgr(struct dev_object *hdev_obj,
220 				  struct dmm_object **mgr);
221 
222 /*
223  *  ======== dev_get_cod_mgr ========
224  *  Purpose:
225  *      Retrieve the COD manager create for this device.
226  *  Parameters:
227  *      hdev_obj:     Handle to device object created with
228  *                      dev_create_device().
229  *      *cod_mgr:       Ptr to location to store handle.
230  *  Returns:
231  *      0:        Success.
232  *      -EFAULT:    Invalid hdev_obj.
233  *  Requires:
234  *      cod_mgr != NULL.
235  *      DEV Initialized.
236  *  Ensures:
237  *      0:        *cod_mgr contains a handle to a COD manager object.
238  *      else:           *cod_mgr is NULL.
239  */
240 extern int dev_get_cod_mgr(struct dev_object *hdev_obj,
241 				  struct cod_manager **cod_mgr);
242 
243 /*
244  *  ======== dev_get_deh_mgr ========
245  *  Purpose:
246  *      Retrieve the DEH manager created for this device.
247  *  Parameters:
248  *      hdev_obj: Handle to device object created with dev_create_device().
249  *      *deh_manager:  Ptr to location to store handle.
250  *  Returns:
251  *      0:    Success.
252  *      -EFAULT:   Invalid hdev_obj.
253  *  Requires:
254  *      deh_manager != NULL.
255  *      DEH Initialized.
256  *  Ensures:
257  *      0:    *deh_manager contains a handle to a DEH manager object.
258  *      else:       *deh_manager is NULL.
259  */
260 extern int dev_get_deh_mgr(struct dev_object *hdev_obj,
261 				  struct deh_mgr **deh_manager);
262 
263 /*
264  *  ======== dev_get_dev_node ========
265  *  Purpose:
266  *      Retrieve the platform specific device ID for this device.
267  *  Parameters:
268  *      hdev_obj:     Handle to device object created with
269  *                      dev_create_device().
270  *      dev_nde:        Ptr to location to get the device node handle.
271  *  Returns:
272  *      0:        Returns a DEVNODE in *dev_node_obj.
273  *      -EFAULT:    Invalid hdev_obj.
274  *  Requires:
275  *      dev_nde != NULL.
276  *      DEV Initialized.
277  *  Ensures:
278  *      0:        *dev_nde contains a platform specific device ID;
279  *      else:           *dev_nde is NULL.
280  */
281 extern int dev_get_dev_node(struct dev_object *hdev_obj,
282 				   struct cfg_devnode **dev_nde);
283 
284 /*
285  *  ======== dev_get_dev_type ========
286  *  Purpose:
287  *      Retrieve the platform specific device ID for this device.
288  *  Parameters:
289  *      hdev_obj:     Handle to device object created with
290  *                      dev_create_device().
291  *      dev_nde:        Ptr to location to get the device node handle.
292  *  Returns:
293  *      0:        Success
294  *      -EFAULT:    Invalid hdev_obj.
295  *  Requires:
296  *      dev_nde != NULL.
297  *      DEV Initialized.
298  *  Ensures:
299  *      0:        *dev_nde contains a platform specific device ID;
300  *      else:           *dev_nde is NULL.
301  */
302 extern int dev_get_dev_type(struct dev_object *device_obj,
303 					u8 *dev_type);
304 
305 /*
306  *  ======== dev_get_first ========
307  *  Purpose:
308  *      Retrieve the first Device Object handle from an internal linked list of
309  *      of DEV_OBJECTs maintained by DEV.
310  *  Parameters:
311  *  Returns:
312  *      NULL if there are no device objects stored; else
313  *      a valid DEV_HOBJECT.
314  *  Requires:
315  *      No calls to dev_create_device or dev_destroy_device (which my modify the
316  *      internal device object list) may occur between calls to dev_get_first
317  *      and dev_get_next.
318  *  Ensures:
319  *      The DEV_HOBJECT returned is valid.
320  *      A subsequent call to dev_get_next will return the next device object in
321  *      the list.
322  */
323 extern struct dev_object *dev_get_first(void);
324 
325 /*
326  *  ======== dev_get_intf_fxns ========
327  *  Purpose:
328  *      Retrieve the Bridge driver interface function structure for the
329  *      loaded Bridge driver.
330  *  Parameters:
331  *      hdev_obj:     Handle to device object created with
332  *                      dev_create_device().
333  *      *if_fxns:       Ptr to location to store fxn interface.
334  *  Returns:
335  *      0:        Success.
336  *      -EFAULT:    Invalid hdev_obj.
337  *  Requires:
338  *      if_fxns != NULL.
339  *      DEV Initialized.
340  *  Ensures:
341  *      0:        *if_fxns contains a pointer to the Bridge
342  *                      driver interface;
343  *      else:           *if_fxns is NULL.
344  */
345 extern int dev_get_intf_fxns(struct dev_object *hdev_obj,
346 			    struct bridge_drv_interface **if_fxns);
347 
348 /*
349  *  ======== dev_get_io_mgr ========
350  *  Purpose:
351  *      Retrieve the handle to the IO manager created for this device.
352  *  Parameters:
353  *      hdev_obj:     Handle to device object created with
354  *                      dev_create_device().
355  *      *mgr:           Ptr to location to store handle.
356  *  Returns:
357  *      0:        Success.
358  *      -EFAULT:    Invalid hdev_obj.
359  *  Requires:
360  *      mgr != NULL.
361  *      DEV Initialized.
362  *  Ensures:
363  *      0:        *mgr contains a handle to an IO manager object.
364  *      else:           *mgr is NULL.
365  */
366 extern int dev_get_io_mgr(struct dev_object *hdev_obj,
367 				 struct io_mgr **mgr);
368 
369 /*
370  *  ======== dev_get_next ========
371  *  Purpose:
372  *      Retrieve the next Device Object handle from an internal linked list of
373  *      of DEV_OBJECTs maintained by DEV, after having previously called
374  *      dev_get_first() and zero or more dev_get_next
375  *  Parameters:
376  *      hdev_obj: Handle to the device object returned from a previous
377  *                  call to dev_get_first() or dev_get_next().
378  *  Returns:
379  *      NULL if there are no further device objects on the list or hdev_obj
380  *      was invalid;
381  *      else the next valid DEV_HOBJECT in the list.
382  *  Requires:
383  *      No calls to dev_create_device or dev_destroy_device (which my modify the
384  *      internal device object list) may occur between calls to dev_get_first
385  *      and dev_get_next.
386  *  Ensures:
387  *      The DEV_HOBJECT returned is valid.
388  *      A subsequent call to dev_get_next will return the next device object in
389  *      the list.
390  */
391 extern struct dev_object *dev_get_next(struct dev_object
392 				       *hdev_obj);
393 
394 /*
395  *  ========= dev_get_msg_mgr ========
396  *  Purpose:
397  *      Retrieve the msg_ctrl Manager Handle from the DevObject.
398  *  Parameters:
399  *      hdev_obj: Handle to the Dev Object
400  *      msg_man:    Location where msg_ctrl Manager handle will be returned.
401  *  Returns:
402  *  Requires:
403  *      DEV Initialized.
404  *      Valid hdev_obj.
405  *      node_man != NULL.
406  *  Ensures:
407  */
408 extern void dev_get_msg_mgr(struct dev_object *hdev_obj,
409 			    struct msg_mgr **msg_man);
410 
411 /*
412  *  ========= dev_get_node_manager ========
413  *  Purpose:
414  *      Retrieve the Node Manager Handle from the DevObject. It is an
415  *      accessor function
416  *  Parameters:
417  *      hdev_obj:     Handle to the Dev Object
418  *      node_man:       Location where Handle to the Node Manager will be
419  *                      returned..
420  *  Returns:
421  *      0:        Success
422  *      -EFAULT:    Invalid Dev Object handle.
423  *  Requires:
424  *      DEV Initialized.
425  *      node_man is not null
426  *  Ensures:
427  *      0:        *node_man contains a handle to a Node manager object.
428  *      else:           *node_man is NULL.
429  */
430 extern int dev_get_node_manager(struct dev_object
431 				       *hdev_obj,
432 				       struct node_mgr **node_man);
433 
434 /*
435  *  ======== dev_get_symbol ========
436  *  Purpose:
437  *      Get the value of a symbol in the currently loaded program.
438  *  Parameters:
439  *      hdev_obj:     Handle to device object created with
440  *                      dev_create_device().
441  *      str_sym:        Name of symbol to look up.
442  *      pul_value:       Ptr to symbol value.
443  *  Returns:
444  *      0:        Success.
445  *      -EFAULT:    Invalid hdev_obj.
446  *      -ESPIPE: Symbols couldn not be found or have not been loaded onto
447  *               the board.
448  *  Requires:
449  *      str_sym != NULL.
450  *      pul_value != NULL.
451  *      DEV Initialized.
452  *  Ensures:
453  *      0:        *pul_value contains the symbol value;
454  */
455 extern int dev_get_symbol(struct dev_object *hdev_obj,
456 				 const char *str_sym, u32 * pul_value);
457 
458 /*
459  *  ======== dev_get_bridge_context ========
460  *  Purpose:
461  *      Retrieve the Bridge Context handle, as returned by the
462  *      bridge_dev_create fxn.
463  *  Parameters:
464  *      hdev_obj:     Handle to device object created with dev_create_device()
465  *      *phbridge_context:  Ptr to location to store context handle.
466  *  Returns:
467  *      0:        Success.
468  *      -EFAULT:    Invalid hdev_obj.
469  *  Requires:
470  *      phbridge_context != NULL.
471  *      DEV Initialized.
472  *  Ensures:
473  *      0:        *phbridge_context contains context handle;
474  *      else:           *phbridge_context is NULL;
475  */
476 extern int dev_get_bridge_context(struct dev_object *hdev_obj,
477 				      struct bridge_dev_context
478 				      **phbridge_context);
479 
480 /*
481  *  ======== dev_exit ========
482  *  Purpose:
483  *      Decrement reference count, and free resources when reference count is
484  *      0.
485  *  Parameters:
486  *  Returns:
487  *  Requires:
488  *      DEV is initialized.
489  *  Ensures:
490  *      When reference count == 0, DEV's private resources are freed.
491  */
492 extern void dev_exit(void);
493 
494 /*
495  *  ======== dev_init ========
496  *  Purpose:
497  *      Initialize DEV's private state, keeping a reference count on each call.
498  *  Parameters:
499  *  Returns:
500  *      TRUE if initialized; FALSE if error occurred.
501  *  Requires:
502  *  Ensures:
503  *      TRUE: A requirement for the other public DEV functions.
504  */
505 extern bool dev_init(void);
506 
507 /*
508  *  ======== dev_insert_proc_object ========
509  *  Purpose:
510  *      Inserts the Processor Object into the List of PROC Objects
511  *      kept in the DEV Object
512  *  Parameters:
513  *      proc_obj:    Handle to the Proc Object
514  *      hdev_obj      Handle to the Dev Object
515  *      bAttachedNew    Specifies if there are already processors attached
516  *  Returns:
517  *      0:        Successfully inserted into the list
518  *  Requires:
519  *      proc_obj is not NULL
520  *      hdev_obj is a valid handle to the DEV.
521  *      DEV Initialized.
522  *      List(of Proc object in Dev) Exists.
523  *  Ensures:
524  *      0 & the PROC Object is inserted and the list is not empty
525  *  Details:
526  *      If the List of Proc Object is empty bAttachedNew is TRUE, it indicated
527  *      this is the first Processor attaching.
528  *      If it is False, there are already processors attached.
529  */
530 extern int dev_insert_proc_object(struct dev_object
531 					 *hdev_obj,
532 					 u32 proc_obj,
533 					 bool *already_attached);
534 
535 /*
536  *  ======== dev_remove_proc_object ========
537  *  Purpose:
538  *      Search for and remove a Proc object from the given list maintained
539  *      by the DEV
540  *  Parameters:
541  *      p_proc_object:        Ptr to ProcObject to insert.
542  *      dev_obj:         Ptr to Dev Object where the list is.
543  *      already_attached:  Ptr to return the bool
544  *  Returns:
545  *      0:            If successful.
546  *      -EPERM           Failure to Remove the PROC Object from the list
547  *  Requires:
548  *      DevObject is Valid
549  *      proc_obj != 0
550  *      dev_obj->proc_list != NULL
551  *      !LST_IS_EMPTY(dev_obj->proc_list)
552  *      already_attached !=NULL
553  *  Ensures:
554  *  Details:
555  *      List will be deleted when the DEV is destroyed.
556  *
557  */
558 extern int dev_remove_proc_object(struct dev_object
559 					 *hdev_obj, u32 proc_obj);
560 
561 /*
562  *  ======== dev_notify_clients ========
563  *  Purpose:
564  *      Notify all clients of this device of a change in device status.
565  *      Clients may include multiple users of BRD, as well as CHNL.
566  *      This function is asychronous, and may be called by a timer event
567  *      set up by a watchdog timer.
568  *  Parameters:
569  *      hdev_obj:  Handle to device object created with dev_create_device().
570  *      ret:         A status word, most likely a BRD_STATUS.
571  *  Returns:
572  *      0:     All registered clients were asynchronously notified.
573  *      -EINVAL:   Invalid hdev_obj.
574  *  Requires:
575  *      DEV Initialized.
576  *  Ensures:
577  *      0: Notifications are queued by the operating system to be
578  *      delivered to clients.  This function does not ensure that
579  *      the notifications will ever be delivered.
580  */
581 extern int dev_notify_clients(struct dev_object *hdev_obj, u32 ret);
582 
583 /*
584  *  ======== dev_remove_device ========
585  *  Purpose:
586  *      Destroys the Device Object created by dev_start_device.
587  *  Parameters:
588  *      dev_node_obj:       Device node as it is know to OS.
589  *  Returns:
590  *      0:        If success;
591  *      <error code>    Otherwise.
592  *  Requires:
593  *  Ensures:
594  */
595 extern int dev_remove_device(struct cfg_devnode *dev_node_obj);
596 
597 /*
598  *  ======== dev_set_chnl_mgr ========
599  *  Purpose:
600  *      Set the channel manager for this device.
601  *  Parameters:
602  *      hdev_obj:     Handle to device object created with
603  *                      dev_create_device().
604  *      hmgr:           Handle to a channel manager, or NULL.
605  *  Returns:
606  *      0:        Success.
607  *      -EFAULT:    Invalid hdev_obj.
608  *  Requires:
609  *      DEV Initialized.
610  *  Ensures:
611  */
612 extern int dev_set_chnl_mgr(struct dev_object *hdev_obj,
613 				   struct chnl_mgr *hmgr);
614 
615 /*
616  *  ======== dev_set_msg_mgr ========
617  *  Purpose:
618  *      Set the Message manager for this device.
619  *  Parameters:
620  *      hdev_obj: Handle to device object created with dev_create_device().
621  *      hmgr:       Handle to a message manager, or NULL.
622  *  Returns:
623  *  Requires:
624  *      DEV Initialized.
625  *  Ensures:
626  */
627 extern void dev_set_msg_mgr(struct dev_object *hdev_obj, struct msg_mgr *hmgr);
628 
629 /*
630  *  ======== dev_start_device ========
631  *  Purpose:
632  *      Initializes the new device with bridge environment.  This involves
633  *      querying CM for allocated resources, querying the registry for
634  *      necessary dsp resources (requested in the INF file), and using this
635  *      information to create a bridge device object.
636  *  Parameters:
637  *      dev_node_obj:       Device node as it is know to OS.
638  *  Returns:
639  *      0:        If success;
640  *      <error code>    Otherwise.
641  *  Requires:
642  *      DEV initialized.
643  *  Ensures:
644  */
645 extern int dev_start_device(struct cfg_devnode *dev_node_obj);
646 
647 #endif /* DEV_ */
648