4 * DSP-BIOS Bridge driver support functions for TI OMAP processors.
6 * DSP/BIOS Bridge resource allocation module.
8 * Copyright (C) 2005-2006 Texas Instruments, Inc.
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.
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.
18 #include <linux/types.h>
20 /* ----------------------------------- Host OS */
21 #include <dspbridge/host_os.h>
23 /* ----------------------------------- DSP/BIOS Bridge */
24 #include <dspbridge/dbdefs.h>
26 /* ----------------------------------- Trace & Debug */
27 #include <dspbridge/dbc.h>
29 /* ----------------------------------- OS Adaptation Layer */
30 #include <dspbridge/list.h>
32 /* ----------------------------------- This */
33 #include <dspbridge/drv.h>
34 #include <dspbridge/dev.h>
36 #include <dspbridge/node.h>
37 #include <dspbridge/proc.h>
38 #include <dspbridge/strm.h>
39 #include <dspbridge/nodepriv.h>
40 #include <dspbridge/dspchnl.h>
41 #include <dspbridge/resourcecleanup.h>
43 /* ----------------------------------- Defines, Data Structures, Typedefs */
45 struct lst_list
*dev_list
;
46 struct lst_list
*dev_node_string
;
50 * This is the Device Extension. Named with the Prefix
51 * DRV_ since it is living in this module
54 struct list_head link
;
55 char sz_string
[MAXREGPATHLENGTH
];
58 /* ----------------------------------- Globals */
60 static bool ext_phys_mem_pool_enabled
;
61 struct ext_phys_mem_pool
{
65 u32 next_phys_alloc_ptr
;
67 static struct ext_phys_mem_pool ext_mem_pool
;
69 /* ----------------------------------- Function Prototypes */
70 static int request_bridge_resources(struct cfg_hostres
*res
);
73 /* GPP PROCESS CLEANUP CODE */
75 static int drv_proc_free_node_res(int id
, void *p
, void *data
);
77 /* Allocate and add a node resource element
78 * This function is called from .Node_Allocate. */
79 int drv_insert_node_res_element(void *hnode
, void *node_resource
,
82 struct node_res_object
**node_res_obj
=
83 (struct node_res_object
**)node_resource
;
84 struct process_context
*ctxt
= (struct process_context
*)process_ctxt
;
88 *node_res_obj
= kzalloc(sizeof(struct node_res_object
), GFP_KERNEL
);
94 (*node_res_obj
)->hnode
= hnode
;
95 retval
= idr_get_new(ctxt
->node_id
, *node_res_obj
,
96 &(*node_res_obj
)->id
);
97 if (retval
== -EAGAIN
) {
98 if (!idr_pre_get(ctxt
->node_id
, GFP_KERNEL
)) {
99 pr_err("%s: OUT OF MEMORY\n", __func__
);
104 retval
= idr_get_new(ctxt
->node_id
, *node_res_obj
,
105 &(*node_res_obj
)->id
);
108 pr_err("%s: FAILED, IDR is FULL\n", __func__
);
113 kfree(*node_res_obj
);
118 /* Release all Node resources and its context
119 * Actual Node De-Allocation */
120 static int drv_proc_free_node_res(int id
, void *p
, void *data
)
122 struct process_context
*ctxt
= data
;
124 struct node_res_object
*node_res_obj
= p
;
127 if (node_res_obj
->node_allocated
) {
128 node_state
= node_get_state(node_res_obj
->hnode
);
129 if (node_state
<= NODE_DELETING
) {
130 if ((node_state
== NODE_RUNNING
) ||
131 (node_state
== NODE_PAUSED
) ||
132 (node_state
== NODE_TERMINATING
))
134 (node_res_obj
->hnode
, &status
);
136 node_delete(node_res_obj
, ctxt
);
143 /* Release all Mapped and Reserved DMM resources */
144 int drv_remove_all_dmm_res_elements(void *process_ctxt
)
146 struct process_context
*ctxt
= (struct process_context
*)process_ctxt
;
148 struct dmm_map_object
*temp_map
, *map_obj
;
149 struct dmm_rsv_object
*temp_rsv
, *rsv_obj
;
151 /* Free DMM mapped memory resources */
152 list_for_each_entry_safe(map_obj
, temp_map
, &ctxt
->dmm_map_list
, link
) {
153 status
= proc_un_map(ctxt
->hprocessor
,
154 (void *)map_obj
->dsp_addr
, ctxt
);
156 pr_err("%s: proc_un_map failed!"
157 " status = 0x%xn", __func__
, status
);
160 /* Free DMM reserved memory resources */
161 list_for_each_entry_safe(rsv_obj
, temp_rsv
, &ctxt
->dmm_rsv_list
, link
) {
162 status
= proc_un_reserve_memory(ctxt
->hprocessor
, (void *)
163 rsv_obj
->dsp_reserved_addr
,
166 pr_err("%s: proc_un_reserve_memory failed!"
167 " status = 0x%xn", __func__
, status
);
172 /* Update Node allocation status */
173 void drv_proc_node_update_status(void *node_resource
, s32 status
)
175 struct node_res_object
*node_res_obj
=
176 (struct node_res_object
*)node_resource
;
177 DBC_ASSERT(node_resource
!= NULL
);
178 node_res_obj
->node_allocated
= status
;
181 /* Update Node Heap status */
182 void drv_proc_node_update_heap_status(void *node_resource
, s32 status
)
184 struct node_res_object
*node_res_obj
=
185 (struct node_res_object
*)node_resource
;
186 DBC_ASSERT(node_resource
!= NULL
);
187 node_res_obj
->heap_allocated
= status
;
190 /* Release all Node resources and its context
191 * This is called from .bridge_release.
193 int drv_remove_all_node_res_elements(void *process_ctxt
)
195 struct process_context
*ctxt
= process_ctxt
;
197 idr_for_each(ctxt
->node_id
, drv_proc_free_node_res
, ctxt
);
198 idr_destroy(ctxt
->node_id
);
203 /* Allocate the STRM resource element
204 * This is called after the actual resource is allocated
206 int drv_proc_insert_strm_res_element(void *stream_obj
,
207 void *strm_res
, void *process_ctxt
)
209 struct strm_res_object
**pstrm_res
=
210 (struct strm_res_object
**)strm_res
;
211 struct process_context
*ctxt
= (struct process_context
*)process_ctxt
;
215 *pstrm_res
= kzalloc(sizeof(struct strm_res_object
), GFP_KERNEL
);
216 if (*pstrm_res
== NULL
) {
221 (*pstrm_res
)->hstream
= stream_obj
;
222 retval
= idr_get_new(ctxt
->stream_id
, *pstrm_res
,
224 if (retval
== -EAGAIN
) {
225 if (!idr_pre_get(ctxt
->stream_id
, GFP_KERNEL
)) {
226 pr_err("%s: OUT OF MEMORY\n", __func__
);
231 retval
= idr_get_new(ctxt
->stream_id
, *pstrm_res
,
235 pr_err("%s: FAILED, IDR is FULL\n", __func__
);
243 static int drv_proc_free_strm_res(int id
, void *p
, void *process_ctxt
)
245 struct process_context
*ctxt
= process_ctxt
;
246 struct strm_res_object
*strm_res
= p
;
247 struct stream_info strm_info
;
248 struct dsp_streaminfo user
;
249 u8
**ap_buffer
= NULL
;
255 if (strm_res
->num_bufs
) {
256 ap_buffer
= kmalloc((strm_res
->num_bufs
*
257 sizeof(u8
*)), GFP_KERNEL
);
259 strm_free_buffer(strm_res
,
266 strm_info
.user_strm
= &user
;
267 user
.number_bufs_in_stream
= 0;
268 strm_get_info(strm_res
->hstream
, &strm_info
, sizeof(strm_info
));
269 while (user
.number_bufs_in_stream
--)
270 strm_reclaim(strm_res
->hstream
, &buf_ptr
, &ul_bytes
,
271 (u32
*) &ul_buf_size
, &dw_arg
);
272 strm_close(strm_res
, ctxt
);
276 /* Release all Stream resources and its context
277 * This is called from .bridge_release.
279 int drv_remove_all_strm_res_elements(void *process_ctxt
)
281 struct process_context
*ctxt
= process_ctxt
;
283 idr_for_each(ctxt
->stream_id
, drv_proc_free_strm_res
, ctxt
);
284 idr_destroy(ctxt
->stream_id
);
289 /* Updating the stream resource element */
290 int drv_proc_update_strm_res(u32 num_bufs
, void *strm_resources
)
293 struct strm_res_object
**strm_res
=
294 (struct strm_res_object
**)strm_resources
;
296 (*strm_res
)->num_bufs
= num_bufs
;
300 /* GPP PROCESS CLEANUP CODE END */
303 * ======== = drv_create ======== =
305 * DRV Object gets created only once during Driver Loading.
307 int drv_create(struct drv_object
**drv_obj
)
310 struct drv_object
*pdrv_object
= NULL
;
311 struct drv_data
*drv_datap
= dev_get_drvdata(bridge
);
313 DBC_REQUIRE(drv_obj
!= NULL
);
314 DBC_REQUIRE(refs
> 0);
316 pdrv_object
= kzalloc(sizeof(struct drv_object
), GFP_KERNEL
);
318 /* Create and Initialize List of device objects */
319 pdrv_object
->dev_list
= kzalloc(sizeof(struct lst_list
),
321 if (pdrv_object
->dev_list
) {
322 /* Create and Initialize List of device Extension */
323 pdrv_object
->dev_node_string
=
324 kzalloc(sizeof(struct lst_list
), GFP_KERNEL
);
325 if (!(pdrv_object
->dev_node_string
)) {
328 INIT_LIST_HEAD(&pdrv_object
->
329 dev_node_string
->head
);
330 INIT_LIST_HEAD(&pdrv_object
->dev_list
->head
);
338 /* Store the DRV Object in the driver data */
341 drv_datap
->drv_object
= (void *)pdrv_object
;
344 pr_err("%s: Failed to store DRV object\n", __func__
);
349 *drv_obj
= pdrv_object
;
351 kfree(pdrv_object
->dev_list
);
352 kfree(pdrv_object
->dev_node_string
);
353 /* Free the DRV Object */
357 DBC_ENSURE(status
|| pdrv_object
);
362 * ======== drv_exit ========
364 * Discontinue usage of the DRV module.
368 DBC_REQUIRE(refs
> 0);
372 DBC_ENSURE(refs
>= 0);
376 * ======== = drv_destroy ======== =
378 * Invoked during bridge de-initialization
380 int drv_destroy(struct drv_object
*driver_obj
)
383 struct drv_object
*pdrv_object
= (struct drv_object
*)driver_obj
;
384 struct drv_data
*drv_datap
= dev_get_drvdata(bridge
);
386 DBC_REQUIRE(refs
> 0);
387 DBC_REQUIRE(pdrv_object
);
390 * Delete the List if it exists.Should not come here
391 * as the drv_remove_dev_object and the Last drv_request_resources
392 * removes the list if the lists are empty.
394 kfree(pdrv_object
->dev_list
);
395 kfree(pdrv_object
->dev_node_string
);
397 /* Update the DRV Object in the driver data */
399 drv_datap
->drv_object
= NULL
;
402 pr_err("%s: Failed to store DRV object\n", __func__
);
409 * ======== drv_get_dev_object ========
411 * Given a index, returns a handle to DevObject from the list.
413 int drv_get_dev_object(u32 index
, struct drv_object
*hdrv_obj
,
414 struct dev_object
**device_obj
)
417 #ifdef CONFIG_TIDSPBRIDGE_DEBUG
418 /* used only for Assertions and debug messages */
419 struct drv_object
*pdrv_obj
= (struct drv_object
*)hdrv_obj
;
421 struct dev_object
*dev_obj
;
423 DBC_REQUIRE(pdrv_obj
);
424 DBC_REQUIRE(device_obj
!= NULL
);
425 DBC_REQUIRE(index
>= 0);
426 DBC_REQUIRE(refs
> 0);
427 DBC_ASSERT(!(LST_IS_EMPTY(pdrv_obj
->dev_list
)));
429 dev_obj
= (struct dev_object
*)drv_get_first_dev_object();
430 for (i
= 0; i
< index
; i
++) {
432 (struct dev_object
*)drv_get_next_dev_object((u32
) dev_obj
);
435 *device_obj
= (struct dev_object
*)dev_obj
;
445 * ======== drv_get_first_dev_object ========
447 * Retrieve the first Device Object handle from an internal linked list of
448 * of DEV_OBJECTs maintained by DRV.
450 u32
drv_get_first_dev_object(void)
452 u32 dw_dev_object
= 0;
453 struct drv_object
*pdrv_obj
;
454 struct drv_data
*drv_datap
= dev_get_drvdata(bridge
);
456 if (drv_datap
&& drv_datap
->drv_object
) {
457 pdrv_obj
= drv_datap
->drv_object
;
458 if ((pdrv_obj
->dev_list
!= NULL
) &&
459 !LST_IS_EMPTY(pdrv_obj
->dev_list
))
460 dw_dev_object
= (u32
) lst_first(pdrv_obj
->dev_list
);
462 pr_err("%s: Failed to retrieve the object handle\n", __func__
);
465 return dw_dev_object
;
469 * ======== DRV_GetFirstDevNodeString ========
471 * Retrieve the first Device Extension from an internal linked list of
472 * of Pointer to dev_node Strings maintained by DRV.
474 u32
drv_get_first_dev_extension(void)
476 u32 dw_dev_extension
= 0;
477 struct drv_object
*pdrv_obj
;
478 struct drv_data
*drv_datap
= dev_get_drvdata(bridge
);
480 if (drv_datap
&& drv_datap
->drv_object
) {
481 pdrv_obj
= drv_datap
->drv_object
;
482 if ((pdrv_obj
->dev_node_string
!= NULL
) &&
483 !LST_IS_EMPTY(pdrv_obj
->dev_node_string
)) {
485 (u32
) lst_first(pdrv_obj
->dev_node_string
);
488 pr_err("%s: Failed to retrieve the object handle\n", __func__
);
491 return dw_dev_extension
;
495 * ======== drv_get_next_dev_object ========
497 * Retrieve the next Device Object handle from an internal linked list of
498 * of DEV_OBJECTs maintained by DRV, after having previously called
499 * drv_get_first_dev_object() and zero or more DRV_GetNext.
501 u32
drv_get_next_dev_object(u32 hdev_obj
)
503 u32 dw_next_dev_object
= 0;
504 struct drv_object
*pdrv_obj
;
505 struct drv_data
*drv_datap
= dev_get_drvdata(bridge
);
507 DBC_REQUIRE(hdev_obj
!= 0);
509 if (drv_datap
&& drv_datap
->drv_object
) {
510 pdrv_obj
= drv_datap
->drv_object
;
511 if ((pdrv_obj
->dev_list
!= NULL
) &&
512 !LST_IS_EMPTY(pdrv_obj
->dev_list
)) {
513 dw_next_dev_object
= (u32
) lst_next(pdrv_obj
->dev_list
,
518 pr_err("%s: Failed to retrieve the object handle\n", __func__
);
521 return dw_next_dev_object
;
525 * ======== drv_get_next_dev_extension ========
527 * Retrieve the next Device Extension from an internal linked list of
528 * of pointer to DevNodeString maintained by DRV, after having previously
529 * called drv_get_first_dev_extension() and zero or more
530 * drv_get_next_dev_extension().
532 u32
drv_get_next_dev_extension(u32 dev_extension
)
534 u32 dw_dev_extension
= 0;
535 struct drv_object
*pdrv_obj
;
536 struct drv_data
*drv_datap
= dev_get_drvdata(bridge
);
538 DBC_REQUIRE(dev_extension
!= 0);
540 if (drv_datap
&& drv_datap
->drv_object
) {
541 pdrv_obj
= drv_datap
->drv_object
;
542 if ((pdrv_obj
->dev_node_string
!= NULL
) &&
543 !LST_IS_EMPTY(pdrv_obj
->dev_node_string
)) {
545 (u32
) lst_next(pdrv_obj
->dev_node_string
,
546 (struct list_head
*)dev_extension
);
549 pr_err("%s: Failed to retrieve the object handle\n", __func__
);
552 return dw_dev_extension
;
556 * ======== drv_init ========
558 * Initialize DRV module private state.
562 s32 ret
= 1; /* function return value */
564 DBC_REQUIRE(refs
>= 0);
569 DBC_ENSURE((ret
&& (refs
> 0)) || (!ret
&& (refs
>= 0)));
575 * ======== drv_insert_dev_object ========
577 * Insert a DevObject into the list of Manager object.
579 int drv_insert_dev_object(struct drv_object
*driver_obj
,
580 struct dev_object
*hdev_obj
)
582 struct drv_object
*pdrv_object
= (struct drv_object
*)driver_obj
;
584 DBC_REQUIRE(refs
> 0);
585 DBC_REQUIRE(hdev_obj
!= NULL
);
586 DBC_REQUIRE(pdrv_object
);
587 DBC_ASSERT(pdrv_object
->dev_list
);
589 lst_put_tail(pdrv_object
->dev_list
, (struct list_head
*)hdev_obj
);
591 DBC_ENSURE(!LST_IS_EMPTY(pdrv_object
->dev_list
));
597 * ======== drv_remove_dev_object ========
599 * Search for and remove a DeviceObject from the given list of DRV
602 int drv_remove_dev_object(struct drv_object
*driver_obj
,
603 struct dev_object
*hdev_obj
)
606 struct drv_object
*pdrv_object
= (struct drv_object
*)driver_obj
;
607 struct list_head
*cur_elem
;
609 DBC_REQUIRE(refs
> 0);
610 DBC_REQUIRE(pdrv_object
);
611 DBC_REQUIRE(hdev_obj
!= NULL
);
613 DBC_REQUIRE(pdrv_object
->dev_list
!= NULL
);
614 DBC_REQUIRE(!LST_IS_EMPTY(pdrv_object
->dev_list
));
616 /* Search list for p_proc_object: */
617 for (cur_elem
= lst_first(pdrv_object
->dev_list
); cur_elem
!= NULL
;
618 cur_elem
= lst_next(pdrv_object
->dev_list
, cur_elem
)) {
619 /* If found, remove it. */
620 if ((struct dev_object
*)cur_elem
== hdev_obj
) {
621 lst_remove_elem(pdrv_object
->dev_list
, cur_elem
);
626 /* Remove list if empty. */
627 if (LST_IS_EMPTY(pdrv_object
->dev_list
)) {
628 kfree(pdrv_object
->dev_list
);
629 pdrv_object
->dev_list
= NULL
;
631 DBC_ENSURE((pdrv_object
->dev_list
== NULL
) ||
632 !LST_IS_EMPTY(pdrv_object
->dev_list
));
638 * ======== drv_request_resources ========
640 * Requests resources from the OS.
642 int drv_request_resources(u32 dw_context
, u32
*dev_node_strg
)
645 struct drv_object
*pdrv_object
;
646 struct drv_ext
*pszdev_node
;
647 struct drv_data
*drv_datap
= dev_get_drvdata(bridge
);
649 DBC_REQUIRE(dw_context
!= 0);
650 DBC_REQUIRE(dev_node_strg
!= NULL
);
653 * Allocate memory to hold the string. This will live untill
654 * it is freed in the Release resources. Update the driver object
658 if (!drv_datap
|| !drv_datap
->drv_object
)
661 pdrv_object
= drv_datap
->drv_object
;
664 pszdev_node
= kzalloc(sizeof(struct drv_ext
), GFP_KERNEL
);
666 lst_init_elem(&pszdev_node
->link
);
667 strncpy(pszdev_node
->sz_string
,
668 (char *)dw_context
, MAXREGPATHLENGTH
- 1);
669 pszdev_node
->sz_string
[MAXREGPATHLENGTH
- 1] = '\0';
670 /* Update the Driver Object List */
671 *dev_node_strg
= (u32
) pszdev_node
->sz_string
;
672 lst_put_tail(pdrv_object
->dev_node_string
,
673 (struct list_head
*)pszdev_node
);
679 dev_dbg(bridge
, "%s: Failed to get Driver Object from Registry",
684 DBC_ENSURE((!status
&& dev_node_strg
!= NULL
&&
685 !LST_IS_EMPTY(pdrv_object
->dev_node_string
)) ||
686 (status
&& *dev_node_strg
== 0));
692 * ======== drv_release_resources ========
694 * Releases resources from the OS.
696 int drv_release_resources(u32 dw_context
, struct drv_object
*hdrv_obj
)
699 struct drv_object
*pdrv_object
= (struct drv_object
*)hdrv_obj
;
700 struct drv_ext
*pszdev_node
;
703 * Irrespective of the status go ahead and clean it
704 * The following will over write the status.
706 for (pszdev_node
= (struct drv_ext
*)drv_get_first_dev_extension();
707 pszdev_node
!= NULL
; pszdev_node
= (struct drv_ext
*)
708 drv_get_next_dev_extension((u32
) pszdev_node
)) {
709 if (!pdrv_object
->dev_node_string
) {
710 /* When this could happen? */
713 if ((u32
) pszdev_node
== dw_context
) {
715 /* Delete from the Driver object list */
716 lst_remove_elem(pdrv_object
->dev_node_string
,
717 (struct list_head
*)pszdev_node
);
718 kfree((void *)pszdev_node
);
721 /* Delete the List if it is empty */
722 if (LST_IS_EMPTY(pdrv_object
->dev_node_string
)) {
723 kfree(pdrv_object
->dev_node_string
);
724 pdrv_object
->dev_node_string
= NULL
;
731 * ======== request_bridge_resources ========
733 * Reserves shared memory for bridge.
735 static int request_bridge_resources(struct cfg_hostres
*res
)
737 struct cfg_hostres
*host_res
= res
;
739 /* num_mem_windows must not be more than CFG_MAXMEMREGISTERS */
740 host_res
->num_mem_windows
= 2;
742 /* First window is for DSP internal memory */
743 host_res
->dw_sys_ctrl_base
= ioremap(OMAP_SYSC_BASE
, OMAP_SYSC_SIZE
);
744 dev_dbg(bridge
, "dw_mem_base[0] 0x%x\n", host_res
->dw_mem_base
[0]);
745 dev_dbg(bridge
, "dw_mem_base[3] 0x%x\n", host_res
->dw_mem_base
[3]);
747 /* for 24xx base port is not mapping the mamory for DSP
748 * internal memory TODO Do a ioremap here */
749 /* Second window is for DSP external memory shared with MPU */
751 /* These are hard-coded values */
752 host_res
->birq_registers
= 0;
753 host_res
->birq_attrib
= 0;
754 host_res
->dw_offset_for_monitor
= 0;
755 host_res
->dw_chnl_offset
= 0;
756 /* CHNL_MAXCHANNELS */
757 host_res
->dw_num_chnls
= CHNL_MAXCHANNELS
;
758 host_res
->dw_chnl_buf_size
= 0x400;
764 * ======== drv_request_bridge_res_dsp ========
766 * Reserves shared memory for bridge.
768 int drv_request_bridge_res_dsp(void **phost_resources
)
771 struct cfg_hostres
*host_res
;
775 struct drv_data
*drv_datap
= dev_get_drvdata(bridge
);
777 dw_buff_size
= sizeof(struct cfg_hostres
);
779 host_res
= kzalloc(dw_buff_size
, GFP_KERNEL
);
781 if (host_res
!= NULL
) {
782 request_bridge_resources(host_res
);
783 /* num_mem_windows must not be more than CFG_MAXMEMREGISTERS */
784 host_res
->num_mem_windows
= 4;
786 host_res
->dw_mem_base
[0] = 0;
787 host_res
->dw_mem_base
[2] = (u32
) ioremap(OMAP_DSP_MEM1_BASE
,
789 host_res
->dw_mem_base
[3] = (u32
) ioremap(OMAP_DSP_MEM2_BASE
,
791 host_res
->dw_mem_base
[4] = (u32
) ioremap(OMAP_DSP_MEM3_BASE
,
793 host_res
->dw_per_base
= ioremap(OMAP_PER_CM_BASE
,
795 host_res
->dw_per_pm_base
= (u32
) ioremap(OMAP_PER_PRM_BASE
,
797 host_res
->dw_core_pm_base
= (u32
) ioremap(OMAP_CORE_PRM_BASE
,
800 dev_dbg(bridge
, "dw_mem_base[0] 0x%x\n",
801 host_res
->dw_mem_base
[0]);
802 dev_dbg(bridge
, "dw_mem_base[1] 0x%x\n",
803 host_res
->dw_mem_base
[1]);
804 dev_dbg(bridge
, "dw_mem_base[2] 0x%x\n",
805 host_res
->dw_mem_base
[2]);
806 dev_dbg(bridge
, "dw_mem_base[3] 0x%x\n",
807 host_res
->dw_mem_base
[3]);
808 dev_dbg(bridge
, "dw_mem_base[4] 0x%x\n",
809 host_res
->dw_mem_base
[4]);
811 shm_size
= drv_datap
->shm_size
;
812 if (shm_size
>= 0x10000) {
813 /* Allocate Physically contiguous,
814 * non-cacheable memory */
815 host_res
->dw_mem_base
[1] =
816 (u32
) mem_alloc_phys_mem(shm_size
, 0x100000,
818 if (host_res
->dw_mem_base
[1] == 0) {
820 pr_err("shm reservation Failed\n");
822 host_res
->dw_mem_length
[1] = shm_size
;
823 host_res
->dw_mem_phys
[1] = dma_addr
;
825 dev_dbg(bridge
, "%s: Bridge shm address 0x%x "
826 "dma_addr %x size %x\n", __func__
,
827 host_res
->dw_mem_base
[1],
832 /* These are hard-coded values */
833 host_res
->birq_registers
= 0;
834 host_res
->birq_attrib
= 0;
835 host_res
->dw_offset_for_monitor
= 0;
836 host_res
->dw_chnl_offset
= 0;
837 /* CHNL_MAXCHANNELS */
838 host_res
->dw_num_chnls
= CHNL_MAXCHANNELS
;
839 host_res
->dw_chnl_buf_size
= 0x400;
840 dw_buff_size
= sizeof(struct cfg_hostres
);
842 *phost_resources
= host_res
;
848 void mem_ext_phys_pool_init(u32 pool_phys_base
, u32 pool_size
)
852 /* get the virtual address for the physical memory pool passed */
853 pool_virt_base
= (u32
) ioremap(pool_phys_base
, pool_size
);
855 if ((void **)pool_virt_base
== NULL
) {
856 pr_err("%s: external physical memory map failed\n", __func__
);
857 ext_phys_mem_pool_enabled
= false;
859 ext_mem_pool
.phys_mem_base
= pool_phys_base
;
860 ext_mem_pool
.phys_mem_size
= pool_size
;
861 ext_mem_pool
.virt_mem_base
= pool_virt_base
;
862 ext_mem_pool
.next_phys_alloc_ptr
= pool_phys_base
;
863 ext_phys_mem_pool_enabled
= true;
867 void mem_ext_phys_pool_release(void)
869 if (ext_phys_mem_pool_enabled
) {
870 iounmap((void *)(ext_mem_pool
.virt_mem_base
));
871 ext_phys_mem_pool_enabled
= false;
876 * ======== mem_ext_phys_mem_alloc ========
878 * Allocate physically contiguous, uncached memory from external memory pool
881 static void *mem_ext_phys_mem_alloc(u32 bytes
, u32 align
, u32
* phys_addr
)
890 if (bytes
> ((ext_mem_pool
.phys_mem_base
+ ext_mem_pool
.phys_mem_size
)
891 - ext_mem_pool
.next_phys_alloc_ptr
)) {
895 offset
= (ext_mem_pool
.next_phys_alloc_ptr
& (align
- 1));
897 new_alloc_ptr
= ext_mem_pool
.next_phys_alloc_ptr
;
899 new_alloc_ptr
= (ext_mem_pool
.next_phys_alloc_ptr
) +
901 if ((new_alloc_ptr
+ bytes
) <=
902 (ext_mem_pool
.phys_mem_base
+ ext_mem_pool
.phys_mem_size
)) {
903 /* we can allocate */
904 *phys_addr
= new_alloc_ptr
;
905 ext_mem_pool
.next_phys_alloc_ptr
=
906 new_alloc_ptr
+ bytes
;
908 ext_mem_pool
.virt_mem_base
+ (new_alloc_ptr
-
911 return (void *)virt_addr
;
920 * ======== mem_alloc_phys_mem ========
922 * Allocate physically contiguous, uncached memory
924 void *mem_alloc_phys_mem(u32 byte_size
, u32 align_mask
,
925 u32
*physical_address
)
931 if (ext_phys_mem_pool_enabled
) {
932 va_mem
= mem_ext_phys_mem_alloc(byte_size
, align_mask
,
935 va_mem
= dma_alloc_coherent(NULL
, byte_size
, &pa_mem
,
938 *physical_address
= 0;
940 *physical_address
= pa_mem
;
946 * ======== mem_free_phys_mem ========
948 * Free the given block of physically contiguous memory.
950 void mem_free_phys_mem(void *virtual_address
, u32 physical_address
,
953 DBC_REQUIRE(virtual_address
!= NULL
);
955 if (!ext_phys_mem_pool_enabled
)
956 dma_free_coherent(NULL
, byte_size
, virtual_address
,