1 /*
2  * cmm.h
3  *
4  * DSP-BIOS Bridge driver support functions for TI OMAP processors.
5  *
6  * The Communication Memory Management(CMM) module provides shared memory
7  * management services for DSP/BIOS Bridge data streaming and messaging.
8  * Multiple shared memory segments can be registered with CMM. Memory is
9  * coelesced back to the appropriate pool when a buffer is freed.
10  *
11  * The CMM_Xlator[xxx] functions are used for node messaging and data
12  * streaming address translation to perform zero-copy inter-processor
13  * data transfer(GPP<->DSP). A "translator" object is created for a node or
14  * stream object that contains per thread virtual address information. This
15  * translator info is used at runtime to perform SM address translation
16  * to/from the DSP address space.
17  *
18  * Notes:
19  *   cmm_xlator_alloc_buf - Used by Node and Stream modules for SM address
20  *			  translation.
21  *
22  * Copyright (C) 2008 Texas Instruments, Inc.
23  *
24  * This package is free software; you can redistribute it and/or modify
25  * it under the terms of the GNU General Public License version 2 as
26  * published by the Free Software Foundation.
27  *
28  * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
29  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
30  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
31  */
32 
33 #ifndef CMM_
34 #define CMM_
35 
36 #include <dspbridge/devdefs.h>
37 
38 #include <dspbridge/cmmdefs.h>
39 #include <dspbridge/host_os.h>
40 
41 /*
42  *  ======== cmm_calloc_buf ========
43  *  Purpose:
44  *      Allocate memory buffers that can be used for data streaming or
45  *      messaging.
46  *  Parameters:
47  *      hcmm_mgr:   Cmm Mgr handle.
48  *      usize:     Number of bytes to allocate.
49  *      pattr:     Attributes of memory to allocate.
50  *      pp_buf_va:   Address of where to place VA.
51  *  Returns:
52  *      Pointer to a zero'd block of SM memory;
53  *      NULL if memory couldn't be allocated,
54  *      or if byte_size == 0,
55  *  Requires:
56  *      Valid hcmm_mgr.
57  *      CMM initialized.
58  *  Ensures:
59  *      The returned pointer, if not NULL, points to a valid memory block of
60  *      the size requested.
61  *
62  */
63 extern void *cmm_calloc_buf(struct cmm_object *hcmm_mgr,
64 			    u32 usize, struct cmm_attrs *pattrs,
65 			    void **pp_buf_va);
66 
67 /*
68  *  ======== cmm_create ========
69  *  Purpose:
70  *      Create a communication memory manager object.
71  *  Parameters:
72  *      ph_cmm_mgr:	Location to store a communication manager handle on
73  *      		output.
74  *      hdev_obj: Handle to a device object.
75  *      mgr_attrts: Comm mem manager attributes.
76  *  Returns:
77  *      0:        Success;
78  *      -ENOMEM:    Insufficient memory for requested resources.
79  *      -EPERM:      Failed to initialize critical sect sync object.
80  *
81  *  Requires:
82  *      cmm_init(void) called.
83  *      ph_cmm_mgr != NULL.
84  *      mgr_attrts->min_block_size >= 4 bytes.
85  *  Ensures:
86  *
87  */
88 extern int cmm_create(struct cmm_object **ph_cmm_mgr,
89 			     struct dev_object *hdev_obj,
90 			     const struct cmm_mgrattrs *mgr_attrts);
91 
92 /*
93  *  ======== cmm_destroy ========
94  *  Purpose:
95  *      Destroy the communication memory manager object.
96  *  Parameters:
97  *      hcmm_mgr:   Cmm Mgr handle.
98  *      force:     Force deallocation of all cmm memory immediately if set TRUE.
99  *                 If FALSE, and outstanding allocations will return -EPERM
100  *                 status.
101  *  Returns:
102  *      0:        CMM object & resources deleted.
103  *      -EPERM:      Unable to free CMM object due to outstanding allocation.
104  *      -EFAULT:    Unable to free CMM due to bad handle.
105  *  Requires:
106  *      CMM is initialized.
107  *      hcmm_mgr != NULL.
108  *  Ensures:
109  *      Memory resources used by Cmm Mgr are freed.
110  */
111 extern int cmm_destroy(struct cmm_object *hcmm_mgr, bool force);
112 
113 /*
114  *  ======== cmm_exit ========
115  *  Purpose:
116  *     Discontinue usage of module. Cleanup CMM module if CMM cRef reaches zero.
117  *  Parameters:
118  *     n/a
119  *  Returns:
120  *     n/a
121  *  Requires:
122  *     CMM is initialized.
123  *  Ensures:
124  */
125 extern void cmm_exit(void);
126 
127 /*
128  *  ======== cmm_free_buf ========
129  *  Purpose:
130  *      Free the given buffer.
131  *  Parameters:
132  *      hcmm_mgr:    Cmm Mgr handle.
133  *      pbuf:       Pointer to memory allocated by cmm_calloc_buf().
134  *      ul_seg_id:    SM segment Id used in CMM_Calloc() attrs.
135  *                  Set to 0 to use default segment.
136  *  Returns:
137  *      0
138  *      -EPERM
139  *  Requires:
140  *      CMM initialized.
141  *      buf_pa != NULL
142  *  Ensures:
143  *
144  */
145 extern int cmm_free_buf(struct cmm_object *hcmm_mgr,
146 			       void *buf_pa, u32 ul_seg_id);
147 
148 /*
149  *  ======== cmm_get_handle ========
150  *  Purpose:
151  *      Return the handle to the cmm mgr for the given device obj.
152  *  Parameters:
153  *      hprocessor:   Handle to a Processor.
154  *      ph_cmm_mgr:	Location to store the shared memory mgr handle on
155  *      		output.
156  *
157  *  Returns:
158  *      0:        Cmm Mgr opaque handle returned.
159  *      -EFAULT:    Invalid handle.
160  *  Requires:
161  *      ph_cmm_mgr != NULL
162  *      hdev_obj != NULL
163  *  Ensures:
164  */
165 extern int cmm_get_handle(void *hprocessor,
166 				 struct cmm_object **ph_cmm_mgr);
167 
168 /*
169  *  ======== cmm_get_info ========
170  *  Purpose:
171  *      Return the current SM and VM utilization information.
172  *  Parameters:
173  *      hcmm_mgr:     Handle to a Cmm Mgr.
174  *      cmm_info_obj:    Location to store the Cmm information on output.
175  *
176  *  Returns:
177  *      0:        Success.
178  *      -EFAULT:    Invalid handle.
179  *      -EINVAL Invalid input argument.
180  *  Requires:
181  *  Ensures:
182  *
183  */
184 extern int cmm_get_info(struct cmm_object *hcmm_mgr,
185 			       struct cmm_info *cmm_info_obj);
186 
187 /*
188  *  ======== cmm_init ========
189  *  Purpose:
190  *      Initializes private state of CMM module.
191  *  Parameters:
192  *  Returns:
193  *      TRUE if initialized; FALSE if error occurred.
194  *  Requires:
195  *  Ensures:
196  *      CMM initialized.
197  */
198 extern bool cmm_init(void);
199 
200 /*
201  *  ======== cmm_register_gppsm_seg ========
202  *  Purpose:
203  *      Register a block of SM with the CMM.
204  *  Parameters:
205  *      hcmm_mgr:         Handle to a Cmm Mgr.
206  *      lpGPPBasePA:     GPP Base Physical address.
207  *      ul_size:          Size in GPP bytes.
208  *      dsp_addr_offset  GPP PA to DSP PA Offset.
209  *      c_factor:         Add offset if CMM_ADDTODSPPA, sub if CMM_SUBFROMDSPPA.
210  *      dw_dsp_base:       DSP virtual base byte address.
211  *      ul_dsp_size:       Size of DSP segment in bytes.
212  *      sgmt_id:         Address to store segment Id.
213  *
214  *  Returns:
215  *      0:         Success.
216  *      -EFAULT:     Invalid hcmm_mgr handle.
217  *      -EINVAL: Invalid input argument.
218  *      -EPERM:       Unable to register.
219  *      - On success *sgmt_id is a valid SM segment ID.
220  *  Requires:
221  *      ul_size > 0
222  *      sgmt_id != NULL
223  *      dw_gpp_base_pa != 0
224  *      c_factor = CMM_ADDTODSPPA || c_factor = CMM_SUBFROMDSPPA
225  *  Ensures:
226  *
227  */
228 extern int cmm_register_gppsm_seg(struct cmm_object *hcmm_mgr,
229 					 unsigned int dw_gpp_base_pa,
230 					 u32 ul_size,
231 					 u32 dsp_addr_offset,
232 					 s8 c_factor,
233 					 unsigned int dw_dsp_base,
234 					 u32 ul_dsp_size,
235 					 u32 *sgmt_id, u32 gpp_base_va);
236 
237 /*
238  *  ======== cmm_un_register_gppsm_seg ========
239  *  Purpose:
240  *      Unregister the given memory segment that was previously registered
241  *      by cmm_register_gppsm_seg.
242  *  Parameters:
243  *      hcmm_mgr:    Handle to a Cmm Mgr.
244  *      ul_seg_id     Segment identifier returned by cmm_register_gppsm_seg.
245  *  Returns:
246  *       0:         Success.
247  *       -EFAULT:     Invalid handle.
248  *       -EINVAL: Invalid ul_seg_id.
249  *       -EPERM:       Unable to unregister for unknown reason.
250  *  Requires:
251  *  Ensures:
252  *
253  */
254 extern int cmm_un_register_gppsm_seg(struct cmm_object *hcmm_mgr,
255 					    u32 ul_seg_id);
256 
257 /*
258  *  ======== cmm_xlator_alloc_buf ========
259  *  Purpose:
260  *      Allocate the specified SM buffer and create a local memory descriptor.
261  *      Place on the descriptor on the translator's HaQ (Host Alloc'd Queue).
262  *  Parameters:
263  *      xlator:    Handle to a Xlator object.
264  *      va_buf:     Virtual address ptr(client context)
265  *      pa_size:    Size of SM memory to allocate.
266  *  Returns:
267  *      Ptr to valid physical address(Pa) of pa_size bytes, NULL if failed.
268  *  Requires:
269  *      va_buf != 0.
270  *      pa_size != 0.
271  *  Ensures:
272  *
273  */
274 extern void *cmm_xlator_alloc_buf(struct cmm_xlatorobject *xlator,
275 				  void *va_buf, u32 pa_size);
276 
277 /*
278  *  ======== cmm_xlator_create ========
279  *  Purpose:
280  *     Create a translator(xlator) object used for process specific Va<->Pa
281  *     address translation. Node messaging and streams use this to perform
282  *     inter-processor(GPP<->DSP) zero-copy data transfer.
283  *  Parameters:
284  *     xlator:         Address to place handle to a new Xlator handle.
285  *     hcmm_mgr:        Handle to Cmm Mgr associated with this translator.
286  *     xlator_attrs:   Translator attributes used for the client NODE or STREAM.
287  *  Returns:
288  *     0:            Success.
289  *     -EINVAL:    Bad input Attrs.
290  *     -ENOMEM:   Insufficient memory(local) for requested resources.
291  *  Requires:
292  *     xlator != NULL
293  *     hcmm_mgr != NULL
294  *     xlator_attrs != NULL
295  *  Ensures:
296  *
297  */
298 extern int cmm_xlator_create(struct cmm_xlatorobject **xlator,
299 				    struct cmm_object *hcmm_mgr,
300 				    struct cmm_xlatorattrs *xlator_attrs);
301 
302 /*
303  *  ======== cmm_xlator_free_buf ========
304  *  Purpose:
305  *      Free SM buffer and descriptor.
306  *      Does not free client process VM.
307  *  Parameters:
308  *      xlator:    handle to translator.
309  *      buf_va      Virtual address of PA to free.
310  *  Returns:
311  *      0:        Success.
312  *      -EFAULT:    Bad translator handle.
313  *  Requires:
314  *  Ensures:
315  *
316  */
317 extern int cmm_xlator_free_buf(struct cmm_xlatorobject *xlator,
318 				      void *buf_va);
319 
320 /*
321  *  ======== cmm_xlator_info ========
322  *  Purpose:
323  *      Set/Get process specific "translator" address info.
324  *      This is used to perform fast virtaul address translation
325  *      for shared memory buffers between the GPP and DSP.
326  *  Parameters:
327  *     xlator:     handle to translator.
328  *     paddr:       Virtual base address of segment.
329  *     ul_size:      Size in bytes.
330  *     segm_id:     Segment identifier of SM segment(s)
331  *     set_info     Set xlator fields if TRUE, else return base addr
332  *  Returns:
333  *      0:        Success.
334  *      -EFAULT:    Bad translator handle.
335  *  Requires:
336  *      (refs > 0)
337  *      (paddr != NULL)
338  *      (ul_size > 0)
339  *  Ensures:
340  *
341  */
342 extern int cmm_xlator_info(struct cmm_xlatorobject *xlator,
343 				  u8 **paddr,
344 				  u32 ul_size, u32 segm_id, bool set_info);
345 
346 /*
347  *  ======== cmm_xlator_translate ========
348  *  Purpose:
349  *      Perform address translation VA<->PA for the specified stream or
350  *      message shared memory buffer.
351  *  Parameters:
352  *     xlator: handle to translator.
353  *     paddr    address of buffer to translate.
354  *     xtype    Type of address xlation. CMM_PA2VA or CMM_VA2PA.
355  *  Returns:
356  *     Valid address on success, else NULL.
357  *  Requires:
358  *      refs > 0
359  *      paddr != NULL
360  *      xtype >= CMM_VA2PA) && (xtype <= CMM_DSPPA2PA)
361  *  Ensures:
362  *
363  */
364 extern void *cmm_xlator_translate(struct cmm_xlatorobject *xlator,
365 				  void *paddr, enum cmm_xlatetype xtype);
366 
367 #endif /* CMM_ */
368