summaryrefslogtreecommitdiff
path: root/drivers/dsp/syslink/procmgr
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/dsp/syslink/procmgr')
-rwxr-xr-xdrivers/dsp/syslink/procmgr/Kbuild10
-rwxr-xr-xdrivers/dsp/syslink/procmgr/proc4430/Kbuild10
-rwxr-xr-xdrivers/dsp/syslink/procmgr/proc4430/dmm4430.c355
-rwxr-xr-xdrivers/dsp/syslink/procmgr/proc4430/dmm4430.h50
-rw-r--r--drivers/dsp/syslink/procmgr/proc4430/ducatienabler.c1332
-rwxr-xr-xdrivers/dsp/syslink/procmgr/proc4430/hw_mmu.c643
-rw-r--r--drivers/dsp/syslink/procmgr/proc4430/proc4430.c1021
-rwxr-xr-xdrivers/dsp/syslink/procmgr/proc4430/proc4430.h147
-rwxr-xr-xdrivers/dsp/syslink/procmgr/proc4430/proc4430_drv.c400
-rwxr-xr-xdrivers/dsp/syslink/procmgr/proc4430/proc4430_drvdefs.h169
-rwxr-xr-xdrivers/dsp/syslink/procmgr/procdefs.h203
-rwxr-xr-xdrivers/dsp/syslink/procmgr/processor.c398
-rwxr-xr-xdrivers/dsp/syslink/procmgr/processor.h84
-rwxr-xr-xdrivers/dsp/syslink/procmgr/procmgr.c957
-rwxr-xr-xdrivers/dsp/syslink/procmgr/procmgr_drv.c758
-rwxr-xr-xdrivers/dsp/syslink/procmgr/procmgr_drvdefs.h541
16 files changed, 7078 insertions, 0 deletions
diff --git a/drivers/dsp/syslink/procmgr/Kbuild b/drivers/dsp/syslink/procmgr/Kbuild
new file mode 100755
index 000000000000..58f6d3155250
--- /dev/null
+++ b/drivers/dsp/syslink/procmgr/Kbuild
@@ -0,0 +1,10 @@
+libomap_syslink_proc = processor.o procmgr.o procmgr_drv.o
+
+obj-$(CONFIG_SYSLINK_PROC) += syslink_proc.o
+syslink_proc-objs = $(libomap_syslink_proc)
+
+ccflags-y += -Wno-strict-prototypes
+
+#Header files
+ccflags-y += -Iarch/arm/plat-omap/include/syslink
+
diff --git a/drivers/dsp/syslink/procmgr/proc4430/Kbuild b/drivers/dsp/syslink/procmgr/proc4430/Kbuild
new file mode 100755
index 000000000000..f82f2e23f79a
--- /dev/null
+++ b/drivers/dsp/syslink/procmgr/proc4430/Kbuild
@@ -0,0 +1,10 @@
+libomap_proc4430 = proc4430.o proc4430_drv.o dmm4430.o \
+ ducatienabler.o hw_mmu.o
+
+obj-$(CONFIG_SYSLINK_PROC) += syslink_proc4430.o
+syslink_proc4430-objs = $(libomap_proc4430)
+
+ccflags-y += -Wno-strict-prototypes -DUSE_LEVEL_1_MACROS
+
+#Header files
+ccflags-y += -Iarch/arm/plat-omap/include/syslink
diff --git a/drivers/dsp/syslink/procmgr/proc4430/dmm4430.c b/drivers/dsp/syslink/procmgr/proc4430/dmm4430.c
new file mode 100755
index 000000000000..d2ed9ece2245
--- /dev/null
+++ b/drivers/dsp/syslink/procmgr/proc4430/dmm4430.c
@@ -0,0 +1,355 @@
+/*
+ * dmm4430.c
+ *
+ * Syslink support functions for TI OMAP processors.
+ *
+ * Copyright (C) 2009-2010 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/*
+ * ======== dmm.c ========
+ * Purpose:
+ *The Dynamic Memory Manager (DMM) module manages the DSP Virtual address
+ *space that can be directly mapped to any MPU buffer or memory region
+ *
+ * Public Functions:
+ *dmm_create_tables
+ *dmm_create
+ *dmm_destroy
+ *dmm_exit
+ *dmm_init
+ *dmm_map_memory
+ *DMM_Reset
+ *dmm_reserve_memory
+ *dmm_unmap_memory
+ *dmm_unreserve_memory
+ *
+ * Private Functions:
+ *add_region
+ *create_region
+ *get_region
+ * get_free_region
+ * get_mapped_region
+ *
+ * Notes:
+ *Region: Generic memory entitiy having a start address and a size
+ *Chunk: Reserved region
+ *
+ *!
+ */
+
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/mutex.h>
+#include <linux/vmalloc.h>
+#include <asm/page.h>
+#include "dmm4430.h"
+
+
+#define DMM_ADDR_VIRTUAL(x, a) \
+ do { \
+ x = (((struct map_page *)(a) - p_virt_mapping_tbl) * PAGE_SIZE \
+ + dyn_mem_map_begin);\
+ } while (0)
+
+#define DMM_ADDR_TO_INDEX(i, a) \
+ do { \
+ i = (((a) - dyn_mem_map_begin) / PAGE_SIZE); \
+ } while (0)
+
+struct map_page {
+ u32 region_size:31;
+ u32 b_reserved:1;
+};
+
+/* Create the free list */
+static struct map_page *p_virt_mapping_tbl;
+static u32 i_freeregion; /* The index of free region */
+static u32 i_freesize;
+static u32 table_size;/* The size of virtual and physical pages tables */
+static u32 dyn_mem_map_begin;
+struct mutex *dmm_lock;
+
+static struct map_page *get_free_region(u32 size);
+static struct map_page *get_mapped_region(u32 addr);
+
+/* ======== dmm_create_tables ========
+ * Purpose:
+ *Create table to hold information of the virtual memory that is reserved
+ *for DSP.
+ */
+int dmm_create_tables(u32 addr, u32 size)
+{
+ int status = 0;
+
+ dmm_delete_tables();
+ if (WARN_ON(mutex_lock_interruptible(dmm_lock)) < 0) {
+ status = -EFAULT;
+ goto func_exit;
+ }
+ dyn_mem_map_begin = addr;
+ table_size = (size/PAGE_SIZE) + 1;
+ /* Create the free list */
+ p_virt_mapping_tbl = (struct map_page *)vmalloc(
+ table_size*sizeof(struct map_page));
+ if (WARN_ON(p_virt_mapping_tbl == NULL))
+ status = -ENOMEM;
+ /* On successful allocation,
+ * all entries are zero ('free') */
+ i_freeregion = 0;
+ i_freesize = table_size*PAGE_SIZE;
+ p_virt_mapping_tbl[0].region_size = table_size;
+ mutex_unlock(dmm_lock);
+
+func_exit:
+ return status;
+}
+
+/*
+ * ======== dmm_create ========
+ * Purpose:
+ *Create a dynamic memory manager object.
+ */
+int dmm_create(void)
+{
+ int status = 0;
+ dmm_lock = kmalloc(sizeof(struct mutex), GFP_KERNEL);
+ if (WARN_ON(dmm_lock == NULL)) {
+ status = -EFAULT;
+ goto func_exit;
+ }
+ mutex_init(dmm_lock);
+func_exit:
+ return status;
+}
+
+/*
+ * ======== dmm_destroy ========
+ * Purpose:
+ *Release the communication memory manager resources.
+ */
+void dmm_destroy(void)
+{
+ dmm_delete_tables();
+ kfree(dmm_lock);
+}
+
+
+/*
+ * ======== dmm_delete_tables ========
+ * Purpose:
+ *Delete DMM Tables.
+ */
+void dmm_delete_tables(void)
+{
+ /* Delete all DMM tables */
+ WARN_ON(mutex_lock_interruptible(dmm_lock));
+ if (p_virt_mapping_tbl != NULL) {
+ vfree(p_virt_mapping_tbl);
+ p_virt_mapping_tbl = NULL;
+ }
+ mutex_unlock(dmm_lock);
+}
+
+/*
+ * ======== dmm_init ========
+ * Purpose:
+ *Initializes private state of DMM module.
+ */
+void dmm_init(void)
+{
+ p_virt_mapping_tbl = NULL ;
+ table_size = 0;
+ return;
+}
+
+/*
+ * ======== dmm_reserve_memory ========
+ * Purpose:
+ *Reserve a chunk of virtually contiguous DSP/IVA address space.
+ */
+int dmm_reserve_memory(u32 size, u32 *p_rsv_addr)
+{
+ int status = 0;
+ struct map_page *node;
+ u32 rsv_addr = 0;
+ u32 rsv_size = 0;
+
+ if (WARN_ON(mutex_lock_interruptible(dmm_lock)) < 0) {
+ status = -EFAULT;
+ goto func_exit;
+ }
+
+ /* Try to get a DSP chunk from the free list */
+ node = get_free_region(size);
+ if (node != NULL) {
+ /* DSP chunk of given size is available. */
+ DMM_ADDR_VIRTUAL(rsv_addr, node);
+ /* Calculate the number entries to use */
+ rsv_size = size/PAGE_SIZE;
+ if (rsv_size < node->region_size) {
+ /* Mark remainder of free region */
+ node[rsv_size].b_reserved = false;
+ node[rsv_size].region_size =
+ node->region_size - rsv_size;
+ }
+ /* get_region will return first fit chunk. But we only use what
+ is requested. */
+ node->b_reserved = true;
+ node->region_size = rsv_size;
+ /* Return the chunk's starting address */
+ *p_rsv_addr = rsv_addr;
+ } else
+ /*dSP chunk of given size is not available */
+ status = -ENOMEM;
+
+ mutex_unlock(dmm_lock);
+func_exit:
+ return status;
+}
+
+
+/*
+ * ======== dmm_unreserve_memory ========
+ * Purpose:
+ *Free a chunk of reserved DSP/IVA address space.
+ */
+int dmm_unreserve_memory(u32 rsv_addr, u32 *psize)
+{
+ struct map_page *chunk;
+ int status = 0;
+
+ WARN_ON(mutex_lock_interruptible(dmm_lock));
+
+ /* Find the chunk containing the reserved address */
+ chunk = get_mapped_region(rsv_addr);
+ if (chunk == NULL)
+ status = -ENXIO;
+ WARN_ON(status < 0);
+ if (status == 0) {
+ chunk->b_reserved = false;
+ *psize = chunk->region_size * PAGE_SIZE;
+ /* NOTE: We do NOT coalesce free regions here.
+ * Free regions are coalesced in get_region(), as it traverses
+ *the whole mapping table
+ */
+ }
+ mutex_unlock(dmm_lock);
+ return status;
+}
+
+/*
+ * ======== get_free_region ========
+ * Purpose:
+ * Returns the requested free region
+ */
+static struct map_page *get_free_region(u32 size)
+{
+ struct map_page *curr_region = NULL;
+ u32 i = 0;
+ u32 region_size = 0;
+ u32 next_i = 0;
+
+ if (p_virt_mapping_tbl == NULL)
+ return curr_region;
+ if (size > i_freesize) {
+ /* Find the largest free region
+ * (coalesce during the traversal) */
+ while (i < table_size) {
+ region_size = p_virt_mapping_tbl[i].region_size;
+ next_i = i+region_size;
+ if (p_virt_mapping_tbl[i].b_reserved == false) {
+ /* Coalesce, if possible */
+ if (next_i < table_size &&
+ p_virt_mapping_tbl[next_i].b_reserved
+ == false) {
+ p_virt_mapping_tbl[i].region_size +=
+ p_virt_mapping_tbl[next_i].region_size;
+ continue;
+ }
+ region_size *= PAGE_SIZE;
+ if (region_size > i_freesize) {
+ i_freeregion = i;
+ i_freesize = region_size;
+ }
+ }
+ i = next_i;
+ }
+ }
+ if (size <= i_freesize) {
+ curr_region = p_virt_mapping_tbl + i_freeregion;
+ i_freeregion += (size / PAGE_SIZE);
+ i_freesize -= size;
+ }
+ return curr_region;
+}
+
+/*
+ * ======== get_mapped_region ========
+ * Purpose:
+ * Returns the requestedmapped region
+ */
+static struct map_page *get_mapped_region(u32 addr)
+{
+ u32 i = 0;
+ struct map_page *curr_region = NULL;
+
+ if (p_virt_mapping_tbl == NULL)
+ return curr_region;
+
+ DMM_ADDR_TO_INDEX(i, addr);
+ if (i < table_size && (p_virt_mapping_tbl[i].b_reserved))
+ curr_region = p_virt_mapping_tbl + i;
+ return curr_region;
+}
+
+#ifdef DSP_DMM_DEBUG
+int dmm_mem_map_dump(void)
+{
+ struct map_page *curNode = NULL;
+ u32 i;
+ u32 freemem = 0;
+ u32 bigsize = 0;
+
+ WARN_ON(mutex_lock_interruptible(dmm_lock));
+
+ if (p_virt_mapping_tbl != NULL) {
+ for (i = 0; i < table_size; i +=
+ p_virt_mapping_tbl[i].region_size) {
+ curNode = p_virt_mapping_tbl + i;
+ if (curNode->b_reserved == true) {
+ /*printk("RESERVED size = 0x%x, "
+ "Map size = 0x%x\n",
+ (curNode->region_size * PAGE_SIZE),
+ (curNode->b_mapped == false) ? 0 :
+ (curNode->mapped_size * PAGE_SIZE));
+*/
+ } else {
+/* printk("UNRESERVED size = 0x%x\n",
+ (curNode->region_size * PAGE_SIZE));
+*/
+ freemem += (curNode->region_size * PAGE_SIZE);
+ if (curNode->region_size > bigsize)
+ bigsize = curNode->region_size;
+ }
+ }
+ }
+ printk(KERN_INFO "Total DSP VA FREE memory = %d Mbytes\n",
+ freemem/(1024*1024));
+ printk(KERN_INFO "Total DSP VA USED memory= %d Mbytes \n",
+ (((table_size * PAGE_SIZE)-freemem))/(1024*1024));
+ printk(KERN_INFO "DSP VA - Biggest FREE block = %d Mbytes \n\n",
+ (bigsize*PAGE_SIZE/(1024*1024)));
+ mutex_unlock(dmm_lock);
+
+ return 0;
+}
+#endif
diff --git a/drivers/dsp/syslink/procmgr/proc4430/dmm4430.h b/drivers/dsp/syslink/procmgr/proc4430/dmm4430.h
new file mode 100755
index 000000000000..7d879f4fe123
--- /dev/null
+++ b/drivers/dsp/syslink/procmgr/proc4430/dmm4430.h
@@ -0,0 +1,50 @@
+/*
+ * dmm.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+
+/*
+ * ======== dmm.h ========
+ * Purpose:
+ *The Dynamic Memory Mapping(DMM) module manages the DSP Virtual address
+ *space that can be directly mapped to any MPU buffer or memory region
+ *
+ * Public Functions:
+ *
+ */
+
+#ifndef DMM_4430_
+#define DMM_4430_
+
+#include <linux/types.h>
+
+int dmm_reserve_memory(u32 size, u32 *p_rsv_addr);
+
+int dmm_unreserve_memory(u32 rsv_addr, u32 *psize);
+
+void dmm_destroy(void);
+
+void dmm_delete_tables(void);
+
+int dmm_create(void);
+
+void dmm_init(void);
+
+int dmm_create_tables(u32 addr, u32 size);
+
+#ifdef DSP_DMM_DEBUG
+int dmm_mem_map_dump(void);
+#endif
+#endif/* DMM_4430_ */
diff --git a/drivers/dsp/syslink/procmgr/proc4430/ducatienabler.c b/drivers/dsp/syslink/procmgr/proc4430/ducatienabler.c
new file mode 100644
index 000000000000..766005b56702
--- /dev/null
+++ b/drivers/dsp/syslink/procmgr/proc4430/ducatienabler.c
@@ -0,0 +1,1332 @@
+/*
+ * ducatienabler.c
+ *
+ * Syslink driver support for TI OMAP processors.
+ *
+ * Copyright (C) 2008-2009 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+
+
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/gfp.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <asm/page.h>
+#include <linux/kernel.h>
+#include <linux/pagemap.h>
+
+
+#include <linux/autoconf.h>
+#include <asm/system.h>
+#include <asm/atomic.h>
+#include <linux/semaphore.h>
+#include <linux/uaccess.h>
+#include <asm/irq.h>
+#include <linux/io.h>
+#include <linux/syscalls.h>
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/stddef.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/sched.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/ctype.h>
+#include <linux/mm.h>
+#include <linux/device.h>
+#include <linux/vmalloc.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/pagemap.h>
+#include <asm/cacheflush.h>
+#include <linux/dma-mapping.h>
+
+#include <syslink/ducatienabler.h>
+
+
+#ifdef DEBUG_DUCATI_IPC
+#define DPRINTK(fmt, args...) printk(KERN_INFO "%s: " fmt, __func__, ## args)
+#else
+#define DPRINTK(fmt, args...)
+#endif
+
+
+#define base_ducati_l2_mmuPhys 0x55082000
+
+/*
+ * Macro to define the physical memory address for the
+ * Ducati Base image. The 74Mb memory is preallocated
+ * during the make menuconfig.
+ *
+ */
+/* #define DUCATI_BASEIMAGE_PHYSICAL_ADDRESS 0x87200000 */
+#define DUCATI_BASEIMAGE_PHYSICAL_ADDRESS 0x9CF00000
+
+#define phys_to_page(phys) pfn_to_page((phys) >> PAGE_SHIFT)
+
+
+/* Attributes used to manage the DSP MMU page tables */
+struct pg_table_attrs {
+ struct sync_cs_object *hcs_object;/* Critical section object handle */
+ u32 l1_base_pa; /* Physical address of the L1 PT */
+ u32 l1_base_va; /* Virtual address of the L1 PT */
+ u32 l1_size; /* Size of the L1 PT */
+ u32 l1_tbl_alloc_pa;
+ /* Physical address of Allocated mem for L1 table. May not be aligned */
+ u32 l1_tbl_alloc_va;
+ /* Virtual address of Allocated mem for L1 table. May not be aligned */
+ u32 l1_tbl_alloc_sz;
+ /* Size of consistent memory allocated for L1 table.
+ * May not be aligned */
+ u32 l2_base_pa; /* Physical address of the L2 PT */
+ u32 l2_base_va; /* Virtual address of the L2 PT */
+ u32 l2_size; /* Size of the L2 PT */
+ u32 l2_tbl_alloc_pa;
+ /* Physical address of Allocated mem for L2 table. May not be aligned */
+ u32 l2_tbl_alloc_va;
+ /* Virtual address of Allocated mem for L2 table. May not be aligned */
+ u32 ls_tbl_alloc_sz;
+ /* Size of consistent memory allocated for L2 table.
+ * May not be aligned */
+ u32 l2_num_pages; /* Number of allocated L2 PT */
+ struct page_info *pg_info;
+};
+
+/* Attributes of L2 page tables for DSP MMU.*/
+struct page_info {
+ /* Number of valid PTEs in the L2 PT*/
+ u32 num_entries;
+};
+
+enum pagetype {
+ SECTION = 0,
+ LARGE_PAGE = 1,
+ SMALL_PAGE = 2,
+ SUPER_SECTION = 3
+};
+
+static struct pg_table_attrs *p_pt_attrs;
+static u32 mmu_index_next;
+static u32 base_ducati_l2_mmu;
+
+static u32 shm_phys_addr;
+static u32 shm_virt_addr;
+
+static void bad_page_dump(u32 pa, struct page *pg)
+{
+ pr_emerg("DSPBRIDGE: MAP function: COUNT 0 FOR PA 0x%x\n", pa);
+ pr_emerg("Bad page state in process '%s'\n", current->comm);
+ BUG();
+}
+
+/*============================================
+ * Print the DSP MMU Table Entries
+ */
+void dbg_print_ptes(bool ashow_inv_entries, bool ashow_repeat_entries)
+{
+ u32 pte_val;
+ u32 pte_size;
+ u32 last_sect = 0;
+ u32 this_sect = 0;
+ u32 cur_l1_entry;
+ u32 cur_l2_entry;
+ u32 pg_tbl_va;
+ u32 l1_base_va;
+ u32 l2_base_va = 0;
+ u32 l2_base_pa = 0;
+
+ l1_base_va = p_pt_attrs->l1_base_va;
+ pg_tbl_va = l1_base_va;
+
+ DPRINTK("\n*** Currently programmed PTEs : Max possible L1 Entries"
+ "[%d] ***\n", (p_pt_attrs->l1_size / sizeof(u32)));
+
+ /* Walk all L1 entries, dump out info. Dive into L2 if necessary */
+ for (cur_l1_entry = 0; cur_l1_entry <
+ (p_pt_attrs->l1_size / sizeof(u32)); cur_l1_entry++) {
+ /*pte_val = pL1PgTbl[cur_l1_entry];*/
+ pte_val = *((u32 *)(pg_tbl_va + (cur_l1_entry * sizeof(u32))));
+ pte_size = hw_mmu_pte_sizel1(pte_val);
+
+ if (pte_size == HW_PAGE_SIZE_16MB) {
+ this_sect = hw_mmu_pte_phyaddr(pte_val, pte_size);
+ if (this_sect != last_sect) {
+ last_sect = this_sect;
+ DPRINTK("PTE L1 [16 MB] -> VA = "
+ "0x%x PA = 0x%x\n",
+ cur_l1_entry << 24, this_sect);
+
+ } else if (ashow_repeat_entries != false)
+ DPRINTK(" {REPEAT}\n");
+ } else if (pte_size == HW_PAGE_SIZE_1MB) {
+ this_sect = hw_mmu_pte_phyaddr(pte_val, pte_size);
+ if (this_sect != last_sect) {
+
+ last_sect = this_sect;
+
+ DPRINTK("PTE L1 [1 MB ] -> VA = "
+ "0x%x PA = 0x%x\n",
+ cur_l1_entry << 20, this_sect);
+
+ } else if (ashow_repeat_entries != false)
+ DPRINTK(" {REPEAT}\n");
+
+ } else if (pte_size == HW_MMU_COARSE_PAGE_SIZE) {
+ /* Get the L2 data for this */
+ DPRINTK("PTE L1 [L2 ] -> VA = "
+ "0x%x\n", cur_l1_entry << 20);
+ /* Get the L2 PA from the L1 PTE, and find corresponding L2 VA*/
+ l2_base_pa = hw_mmu_pte_coarsel1(pte_val);
+ l2_base_va = l2_base_pa - p_pt_attrs->l2_base_pa +
+ p_pt_attrs->l2_base_va;
+ for (cur_l2_entry = 0;
+ cur_l2_entry < (HW_MMU_COARSE_PAGE_SIZE / sizeof(u32));
+ cur_l2_entry++) {
+ pte_val = *((u32 *)(l2_base_va +
+ (cur_l2_entry * sizeof(u32))));
+ pte_size = hw_mmu_pte_sizel2(pte_val);
+ if ((pte_size == HW_PAGE_SIZE_64KB) ||
+ (pte_size == HW_PAGE_SIZE_4KB)) {
+ this_sect = hw_mmu_pte_phyaddr
+ (pte_val, pte_size);
+ if (this_sect != last_sect) {
+ last_sect = this_sect;
+ DPRINTK("PTE L2 [%s KB] ->"
+ "VA = 0x%x PA = 0x%x\n",
+ (pte_size ==
+ HW_PAGE_SIZE_64KB) ?
+ "64" : "4",
+ ((cur_l1_entry << 20)
+ | (cur_l2_entry << 12)),
+ this_sect);
+ } else if (ashow_repeat_entries
+ != false)
+
+ DPRINTK("{REPEAT}");
+ } else if (ashow_inv_entries != false) {
+
+ DPRINTK("PTE L2 [INVALID] -> VA = "
+ "0x%x",
+ ((cur_l1_entry << 20) |
+ (cur_l2_entry << 12)));
+ continue;
+ }
+ }
+ } else if (ashow_inv_entries != false) {
+ /* Entry is invalid (not set), skip it */
+ DPRINTK("PTE L1 [INVALID] -> VA = 0x%x",
+ cur_l1_entry << 20);
+ continue;
+ }
+ }
+ /* Dump the TLB entries as well */
+ DPRINTK("\n*** Currently programmed TLBs ***\n");
+ hw_mmu_tlb_dump(base_ducati_l2_mmu, true);
+ DPRINTK("*** DSP MMU DUMP COMPLETED ***\n");
+}
+
+/*============================================
+ * This function calculates PTE address (MPU virtual) to be updated
+ * It also manages the L2 page tables
+ */
+static int pte_set(u32 pa, u32 va, u32 size, struct hw_mmu_map_attrs_t *attrs)
+{
+ u32 i;
+ u32 pte_val;
+ u32 pte_addr_l1;
+ u32 pte_size;
+ u32 pg_tbl_va; /* Base address of the PT that will be updated */
+ u32 l1_base_va;
+ /* Compiler warns that the next three variables might be used
+ * uninitialized in this function. Doesn't seem so. Working around,
+ * anyways. */
+ u32 l2_base_va = 0;
+ u32 l2_base_pa = 0;
+ u32 l2_page_num = 0;
+ struct pg_table_attrs *pt = p_pt_attrs;
+ int status = 0;
+ DPRINTK("> pte_set ppg_table_attrs %x, pa %x, va %x, "
+ "size %x, attrs %x\n", (u32)pt, pa, va, size, (u32)attrs);
+ l1_base_va = pt->l1_base_va;
+ pg_tbl_va = l1_base_va;
+ if ((size == HW_PAGE_SIZE_64KB) || (size == HW_PAGE_SIZE_4KB)) {
+ /* Find whether the L1 PTE points to a valid L2 PT */
+ pte_addr_l1 = hw_mmu_pte_addr_l1(l1_base_va, va);
+ if (pte_addr_l1 <= (pt->l1_base_va + pt->l1_size)) {
+ pte_val = *(u32 *)pte_addr_l1;
+ pte_size = hw_mmu_pte_sizel1(pte_val);
+ } else {
+ return -EINVAL;
+ }
+ /* FIX ME */
+ /* TODO: ADD synchronication element*/
+ /* sync_enter_cs(pt->hcs_object);*/
+ if (pte_size == HW_MMU_COARSE_PAGE_SIZE) {
+ /* Get the L2 PA from the L1 PTE, and find
+ * corresponding L2 VA */
+ l2_base_pa = hw_mmu_pte_coarsel1(pte_val);
+ l2_base_va = l2_base_pa - pt->l2_base_pa +
+ pt->l2_base_va;
+ l2_page_num = (l2_base_pa - pt->l2_base_pa) /
+ HW_MMU_COARSE_PAGE_SIZE;
+ } else if (pte_size == 0) {
+ /* L1 PTE is invalid. Allocate a L2 PT and
+ * point the L1 PTE to it */
+ /* Find a free L2 PT. */
+ for (i = 0; (i < pt->l2_num_pages) &&
+ (pt->pg_info[i].num_entries != 0); i++)
+ ;;
+ if (i < pt->l2_num_pages) {
+ l2_page_num = i;
+ l2_base_pa = pt->l2_base_pa + (l2_page_num *
+ HW_MMU_COARSE_PAGE_SIZE);
+ l2_base_va = pt->l2_base_va + (l2_page_num *
+ HW_MMU_COARSE_PAGE_SIZE);
+ /* Endianness attributes are ignored for
+ * HW_MMU_COARSE_PAGE_SIZE */
+ status =
+ hw_mmu_pte_set(l1_base_va, l2_base_pa, va,
+ HW_MMU_COARSE_PAGE_SIZE, attrs);
+ } else {
+ status = -ENOMEM;
+ }
+ } else {
+ /* Found valid L1 PTE of another size.
+ * Should not overwrite it. */
+ status = -EINVAL;
+ }
+ if (status == 0) {
+ pg_tbl_va = l2_base_va;
+ if (size == HW_PAGE_SIZE_64KB)
+ pt->pg_info[l2_page_num].num_entries += 16;
+ else
+ pt->pg_info[l2_page_num].num_entries++;
+
+ DPRINTK("L2 BaseVa %x, BasePa %x, "
+ "PageNum %x num_entries %x\n", l2_base_va,
+ l2_base_pa, l2_page_num,
+ pt->pg_info[l2_page_num].num_entries);
+ }
+/* sync_leave_cs(pt->hcs_object);*/
+ }
+ if (status == 0) {
+ DPRINTK("PTE pg_tbl_va %x, pa %x, va %x, size %x\n",
+ pg_tbl_va, pa, va, size);
+ DPRINTK("PTE endianism %x, element_size %x, "
+ "mixedSize %x\n", attrs->endianism,
+ attrs->element_size, attrs->mixedSize);
+ status = hw_mmu_pte_set(pg_tbl_va, pa, va, size, attrs);
+ if (status == RET_OK)
+ status = 0;
+ }
+ DPRINTK("< pte_set status %x\n", status);
+ return status;
+}
+
+
+/*=============================================
+ * This function calculates the optimum page-aligned addresses and sizes
+ * Caller must pass page-aligned values
+ */
+static int pte_update(u32 pa, u32 va, u32 size,
+ struct hw_mmu_map_attrs_t *map_attrs)
+{
+ u32 i;
+ u32 all_bits;
+ u32 pa_curr = pa;
+ u32 va_curr = va;
+ u32 num_bytes = size;
+ int status = 0;
+ u32 pg_size[] = {HW_PAGE_SIZE_16MB, HW_PAGE_SIZE_1MB,
+ HW_PAGE_SIZE_64KB, HW_PAGE_SIZE_4KB};
+ DPRINTK("> pte_update pa %x, va %x, "
+ "size %x, map_attrs %x\n", pa, va, size, (u32)map_attrs);
+ while (num_bytes && (status == 0)) {
+ /* To find the max. page size with which both PA & VA are
+ * aligned */
+ all_bits = pa_curr | va_curr;
+ DPRINTK("all_bits %x, pa_curr %x, va_curr %x, "
+ "num_bytes %x\n ",
+ all_bits, pa_curr, va_curr, num_bytes);
+
+ for (i = 0; i < 4; i++) {
+ if ((num_bytes >= pg_size[i]) && ((all_bits &
+ (pg_size[i] - 1)) == 0)) {
+ DPRINTK("pg_size %x\n", pg_size[i]);
+ status = pte_set(pa_curr,
+ va_curr, pg_size[i], map_attrs);
+ pa_curr += pg_size[i];
+ va_curr += pg_size[i];
+ num_bytes -= pg_size[i];
+ /* Don't try smaller sizes. Hopefully we have
+ * reached an address aligned to a bigger page
+ * size */
+ break;
+ }
+ }
+ }
+ DPRINTK("< pte_update status %x num_bytes %x\n", status, num_bytes);
+ return status;
+}
+
+/*
+ * ======== ducati_mem_unmap ========
+ * Invalidate the PTEs for the DSP VA block to be unmapped.
+ *
+ * PTEs of a mapped memory block are contiguous in any page table
+ * So, instead of looking up the PTE address for every 4K block,
+ * we clear consecutive PTEs until we unmap all the bytes
+ */
+int ducati_mem_unmap(u32 da, u32 num_bytes)
+{
+ u32 L1_base_va;
+ u32 L2_base_va;
+ u32 L2_base_pa;
+ u32 L2_page_num;
+ u32 pte_val;
+ u32 pte_size;
+ u32 pte_count;
+ u32 pte_addr_l1;
+ u32 pte_addr_l2 = 0;
+ u32 rem_bytes;
+ u32 rem_bytes_l2;
+ u32 vaCurr;
+ struct page *pg = NULL;
+ int status = 0;
+ u32 temp;
+ u32 patemp = 0;
+ u32 pAddr;
+ u32 numof4Kpages = 0;
+ DPRINTK("> ducati_mem_unmap da 0x%x, "
+ "NumBytes 0x%x\n", da, num_bytes);
+ vaCurr = da;
+ rem_bytes = num_bytes;
+ rem_bytes_l2 = 0;
+ L1_base_va = p_pt_attrs->l1_base_va;
+ pte_addr_l1 = hw_mmu_pte_addr_l1(L1_base_va, vaCurr);
+ while (rem_bytes) {
+ u32 vaCurrOrig = vaCurr;
+ /* Find whether the L1 PTE points to a valid L2 PT */
+ pte_addr_l1 = hw_mmu_pte_addr_l1(L1_base_va, vaCurr);
+ pte_val = *(u32 *)pte_addr_l1;
+ pte_size = hw_mmu_pte_sizel1(pte_val);
+ if (pte_size == HW_MMU_COARSE_PAGE_SIZE) {
+ /*
+ * Get the L2 PA from the L1 PTE, and find
+ * corresponding L2 VA
+ */
+ L2_base_pa = hw_mmu_pte_coarsel1(pte_val);
+ L2_base_va = L2_base_pa - p_pt_attrs->l2_base_pa
+ + p_pt_attrs->l2_base_va;
+ L2_page_num = (L2_base_pa - p_pt_attrs->l2_base_pa) /
+ HW_MMU_COARSE_PAGE_SIZE;
+ /*
+ * Find the L2 PTE address from which we will start
+ * clearing, the number of PTEs to be cleared on this
+ * page, and the size of VA space that needs to be
+ * cleared on this L2 page
+ */
+ pte_addr_l2 = hw_mmu_pte_addr_l2(L2_base_va, vaCurr);
+ pte_count = pte_addr_l2 & (HW_MMU_COARSE_PAGE_SIZE - 1);
+ pte_count = (HW_MMU_COARSE_PAGE_SIZE - pte_count) /
+ sizeof(u32);
+ if (rem_bytes < (pte_count * PAGE_SIZE))
+ pte_count = rem_bytes / PAGE_SIZE;
+
+ rem_bytes_l2 = pte_count * PAGE_SIZE;
+ DPRINTK("ducati_mem_unmap L2_base_pa %x, "
+ "L2_base_va %x pte_addr_l2 %x,"
+ "rem_bytes_l2 %x\n", L2_base_pa, L2_base_va,
+ pte_addr_l2, rem_bytes_l2);
+ /*
+ * Unmap the VA space on this L2 PT. A quicker way
+ * would be to clear pte_count entries starting from
+ * pte_addr_l2. However, below code checks that we don't
+ * clear invalid entries or less than 64KB for a 64KB
+ * entry. Similar checking is done for L1 PTEs too
+ * below
+ */
+ while (rem_bytes_l2) {
+ pte_val = *(u32 *)pte_addr_l2;
+ pte_size = hw_mmu_pte_sizel2(pte_val);
+ /* vaCurr aligned to pte_size? */
+ if ((pte_size != 0) && (rem_bytes_l2
+ >= pte_size) &&
+ !(vaCurr & (pte_size - 1))) {
+ /* Collect Physical addresses from VA */
+ pAddr = (pte_val & ~(pte_size - 1));
+ if (pte_size == HW_PAGE_SIZE_64KB)
+ numof4Kpages = 16;
+ else
+ numof4Kpages = 1;
+ temp = 0;
+ while (temp++ < numof4Kpages) {
+ if (pfn_valid
+ (__phys_to_pfn
+ (patemp))) {
+ pg = phys_to_page
+ (pAddr);
+ if (page_count
+ (pg) < 1) {
+ bad_page_dump
+ (pAddr, pg);
+ }
+ SetPageDirty(pg);
+ page_cache_release(pg);
+ }
+ pAddr += HW_PAGE_SIZE_4KB;
+ }
+ if (hw_mmu_pte_clear(pte_addr_l2,
+ vaCurr, pte_size) == RET_OK) {
+ rem_bytes_l2 -= pte_size;
+ vaCurr += pte_size;
+ pte_addr_l2 += (pte_size >> 12)
+ * sizeof(u32);
+ } else {
+ status = -EFAULT;
+ goto EXIT_LOOP;
+ }
+ } else
+ status = -EFAULT;
+ }
+ if (rem_bytes_l2 != 0) {
+ status = -EFAULT;
+ goto EXIT_LOOP;
+ }
+ p_pt_attrs->pg_info[L2_page_num].num_entries -=
+ pte_count;
+ if (p_pt_attrs->pg_info[L2_page_num].num_entries
+ == 0) {
+ /*
+ * Clear the L1 PTE pointing to the
+ * L2 PT
+ */
+ if (RET_OK != hw_mmu_pte_clear(L1_base_va,
+ vaCurrOrig, HW_MMU_COARSE_PAGE_SIZE)) {
+ status = -EFAULT;
+ goto EXIT_LOOP;
+ }
+ }
+ rem_bytes -= pte_count * PAGE_SIZE;
+ DPRINTK("ducati_mem_unmap L2_page_num %x, "
+ "num_entries %x, pte_count %x, status: 0x%x\n",
+ L2_page_num,
+ p_pt_attrs->pg_info[L2_page_num].num_entries,
+ pte_count, status);
+ } else
+ /* vaCurr aligned to pte_size? */
+ /* pte_size = 1 MB or 16 MB */
+ if ((pte_size != 0) && (rem_bytes >= pte_size) &&
+ !(vaCurr & (pte_size - 1))) {
+ if (pte_size == HW_PAGE_SIZE_1MB)
+ numof4Kpages = 256;
+ else
+ numof4Kpages = 4096;
+ temp = 0;
+ /* Collect Physical addresses from VA */
+ pAddr = (pte_val & ~(pte_size - 1));
+ while (temp++ < numof4Kpages) {
+ pg = phys_to_page(pAddr);
+ if (page_count(pg) < 1)
+ bad_page_dump(pAddr, pg);
+ SetPageDirty(pg);
+ page_cache_release(pg);
+ pAddr += HW_PAGE_SIZE_4KB;
+ }
+ if (hw_mmu_pte_clear(L1_base_va, vaCurr,
+ pte_size) == RET_OK) {
+ rem_bytes -= pte_size;
+ vaCurr += pte_size;
+ } else {
+ status = -EFAULT;
+ goto EXIT_LOOP;
+ }
+ } else {
+ status = -EFAULT;
+ }
+ }
+ /*
+ * It is better to flush the TLB here, so that any stale old entries
+ * get flushed
+ */
+EXIT_LOOP:
+ hw_mmu_tlb_flushAll(base_ducati_l2_mmu);
+ DPRINTK("ducati_mem_unmap vaCurr %x, pte_addr_l1 %x "
+ "pte_addr_l2 %x\n", vaCurr, pte_addr_l1, pte_addr_l2);
+ DPRINTK("< ducati_mem_unmap status %x rem_bytes %x, "
+ "rem_bytes_l2 %x\n", status, rem_bytes, rem_bytes_l2);
+ return status;
+}
+
+
+/*
+ * ======== ducati_mem_virtToPhys ========
+ * This funciton provides the translation from
+ * Remote virtual address to Physical address
+ */
+
+inline u32 ducati_mem_virtToPhys(u32 da)
+{
+#if 0
+ /* FIXME: temp work around till L2MMU issue
+ * is resolved
+ */
+ u32 *iopgd = iopgd_offset(ducati_iommu_ptr, da);
+ u32 phyaddress;
+
+ if (*iopgd & IOPGD_TABLE) {
+ u32 *iopte = iopte_offset(iopgd, da);
+ if (*iopte & IOPTE_LARGE) {
+ phyaddress = *iopte & IOLARGE_MASK;
+ phyaddress |= (da & (IOLARGE_SIZE - 1));
+ } else
+ phyaddress = (*iopte) & IOPAGE_MASK;
+ } else {
+ if ((*iopgd & IOPGD_SUPER) == IOPGD_SUPER) {
+ phyaddress = *iopgd & IOSUPER_MASK;
+ phyaddress |= (da & (IOSUPER_SIZE - 1));
+ } else {
+ phyaddress = (*iopgd) & IOPGD_MASK;
+ phyaddress |= (da & (IOPGD_SIZE - 1));
+ }
+ }
+#endif
+ return da;
+}
+
+
+/*
+ * ======== user_va2pa ========
+ * Purpose:
+ * This function walks through the Linux page tables to convert a userland
+ * virtual address to physical address
+ */
+u32 user_va2pa(struct mm_struct *mm, u32 address)
+{
+ pgd_t *pgd;
+ pmd_t *pmd;
+ pte_t *ptep, pte;
+
+ pgd = pgd_offset(mm, address);
+ if (!(pgd_none(*pgd) || pgd_bad(*pgd))) {
+ pmd = pmd_offset(pgd, address);
+ if (!(pmd_none(*pmd) || pmd_bad(*pmd))) {
+ ptep = pte_offset_map(pmd, address);
+ if (ptep) {
+ pte = *ptep;
+ if (pte_present(pte))
+ return pte & PAGE_MASK;
+ }
+ }
+ }
+
+ return 0;
+}
+
+/*============================================
+ * This function maps MPU buffer to the DSP address space. It performs
+* linear to physical address translation if required. It translates each
+* page since linear addresses can be physically non-contiguous
+* All address & size arguments are assumed to be page aligned (in proc.c)
+ *
+ */
+int ducati_mem_map(u32 mpu_addr, u32 ul_virt_addr,
+ u32 num_bytes, u32 map_attr)
+{
+ u32 attrs;
+ int status = 0;
+ struct hw_mmu_map_attrs_t hw_attrs;
+ struct vm_area_struct *vma;
+ struct mm_struct *mm = current->mm;
+ struct task_struct *curr_task = current;
+ u32 write = 0;
+ u32 da = ul_virt_addr;
+ u32 pa = 0;
+ int pg_i = 0;
+ int pg_num = 0;
+ struct page *mappedPage, *pg;
+ int num_usr_pages = 0;
+
+ DPRINTK("> WMD_BRD_MemMap pa %x, va %x, "
+ "size %x, map_attr %x\n", mpu_addr, ul_virt_addr,
+ num_bytes, map_attr);
+ if (num_bytes == 0)
+ return -EINVAL;
+ if (map_attr != 0) {
+ attrs = map_attr;
+ attrs |= DSP_MAPELEMSIZE32;
+ } else {
+ /* Assign default attributes */
+ attrs = DSP_MAPVIRTUALADDR | DSP_MAPELEMSIZE32;
+ }
+ /* Take mapping properties */
+ if (attrs & DSP_MAPBIGENDIAN)
+ hw_attrs.endianism = HW_BIG_ENDIAN;
+ else
+ hw_attrs.endianism = HW_LITTLE_ENDIAN;
+
+ hw_attrs.mixedSize = (enum hw_mmu_mixed_size_t)
+ ((attrs & DSP_MAPMIXEDELEMSIZE) >> 2);
+ /* Ignore element_size if mixedSize is enabled */
+ if (hw_attrs.mixedSize == 0) {
+ if (attrs & DSP_MAPELEMSIZE8) {
+ /* Size is 8 bit */
+ hw_attrs.element_size = HW_ELEM_SIZE_8BIT;
+ } else if (attrs & DSP_MAPELEMSIZE16) {
+ /* Size is 16 bit */
+ hw_attrs.element_size = HW_ELEM_SIZE_16BIT;
+ } else if (attrs & DSP_MAPELEMSIZE32) {
+ /* Size is 32 bit */
+ hw_attrs.element_size = HW_ELEM_SIZE_32BIT;
+ } else if (attrs & DSP_MAPELEMSIZE64) {
+ /* Size is 64 bit */
+ hw_attrs.element_size = HW_ELEM_SIZE_64BIT;
+ } else {
+ /* Mixedsize isn't enabled, so size can't be
+ * zero here */
+ DPRINTK("WMD_BRD_MemMap: MMU element size is zero\n");
+ return -EINVAL;
+ }
+ }
+ /*
+ * Do OS-specific user-va to pa translation.
+ * Combine physically contiguous regions to reduce TLBs.
+ * Pass the translated pa to PteUpdate.
+ */
+ if ((attrs & DSP_MAPPHYSICALADDR)) {
+ status = pte_update(mpu_addr, ul_virt_addr, num_bytes,
+ &hw_attrs);
+ goto func_cont;
+ }
+ /*
+ * Important Note: mpu_addr is mapped from user application process
+ * to current process - it must lie completely within the current
+ * virtual memory address space in order to be of use to us here!
+ */
+ down_read(&mm->mmap_sem);
+ vma = find_vma(mm, mpu_addr);
+ /*
+ * It is observed that under some circumstances, the user buffer is
+ * spread across several VMAs. So loop through and check if the entire
+ * user buffer is covered
+ */
+ while ((vma) && (mpu_addr + num_bytes > vma->vm_end)) {
+ /* jump to the next VMA region */
+ vma = find_vma(mm, vma->vm_end + 1);
+ }
+ if (!vma) {
+ status = -EINVAL;
+ up_read(&mm->mmap_sem);
+ goto func_cont;
+ }
+ if (vma->vm_flags & VM_IO) {
+ num_usr_pages = num_bytes / PAGE_SIZE;
+ /* Get the physical addresses for user buffer */
+ for (pg_i = 0; pg_i < num_usr_pages; pg_i++) {
+ pa = user_va2pa(mm, mpu_addr);
+ if (!pa) {
+ status = -EFAULT;
+ pr_err("DSPBRIDGE: VM_IO mapping physical"
+ "address is invalid\n");
+ break;
+ }
+ if (pfn_valid(__phys_to_pfn(pa))) {
+ pg = phys_to_page(pa);
+ get_page(pg);
+ if (page_count(pg) < 1) {
+ pr_err("Bad page in VM_IO buffer\n");
+ bad_page_dump(pa, pg);
+ }
+ }
+ status = pte_set(pa, da, HW_PAGE_SIZE_4KB, &hw_attrs);
+ if (WARN_ON(status < 0))
+ break;
+ mpu_addr += HW_PAGE_SIZE_4KB;
+ da += HW_PAGE_SIZE_4KB;
+ }
+ } else {
+ num_usr_pages = num_bytes / PAGE_SIZE;
+ if (vma->vm_flags & (VM_WRITE | VM_MAYWRITE))
+ write = 1;
+
+ for (pg_i = 0; pg_i < num_usr_pages; pg_i++) {
+ pg_num = get_user_pages(curr_task, mm, mpu_addr, 1,
+ write, 1, &mappedPage, NULL);
+ if (pg_num > 0) {
+ if (page_count(mappedPage) < 1) {
+ pr_err("Bad page count after doing"
+ "get_user_pages on"
+ "user buffer\n");
+ bad_page_dump(page_to_phys(mappedPage),
+ mappedPage);
+ }
+ status = pte_set(page_to_phys(mappedPage), da,
+ HW_PAGE_SIZE_4KB, &hw_attrs);
+ if (WARN_ON(status < 0))
+ break;
+ da += HW_PAGE_SIZE_4KB;
+ mpu_addr += HW_PAGE_SIZE_4KB;
+ } else {
+ pr_err("DSPBRIDGE: get_user_pages FAILED,"
+ "MPU addr = 0x%x,"
+ "vma->vm_flags = 0x%lx,"
+ "get_user_pages Err"
+ "Value = %d, Buffer"
+ "size=0x%x\n", mpu_addr,
+ vma->vm_flags, pg_num,
+ num_bytes);
+ status = -EFAULT;
+ break;
+ }
+ }
+ }
+ up_read(&mm->mmap_sem);
+func_cont:
+ /* Don't propogate Linux or HW status to upper layers */
+ if (status < 0) {
+ /*
+ * Roll out the mapped pages incase it failed in middle of
+ * mapping
+ */
+ if (pg_i)
+ ducati_mem_unmap(ul_virt_addr, (pg_i * PAGE_SIZE));
+ }
+ /* In any case, flush the TLB
+ * This is called from here instead from pte_update to avoid unnecessary
+ * repetition while mapping non-contiguous physical regions of a virtual
+ * region */
+ hw_mmu_tlb_flushAll(base_ducati_l2_mmu);
+ WARN_ON(status < 0);
+ DPRINTK("< WMD_BRD_MemMap status %x\n", status);
+ return status;
+}
+
+ /*=========================================
+ * Decides a TLB entry size
+ *
+ */
+static int get_mmu_entry_size(u32 phys_addr, u32 size, enum pagetype *size_tlb,
+ u32 *entry_size)
+{
+ int status = 0;
+ bool page_align_4kb = false;
+ bool page_align_64kb = false;
+ bool page_align_1mb = false;
+ bool page_align_16mb = false;
+
+ /* First check the page alignment*/
+ if ((phys_addr % PAGE_SIZE_4KB) == 0)
+ page_align_4kb = true;
+ if ((phys_addr % PAGE_SIZE_64KB) == 0)
+ page_align_64kb = true;
+ if ((phys_addr % PAGE_SIZE_1MB) == 0)
+ page_align_1mb = true;
+ if ((phys_addr % PAGE_SIZE_16MB) == 0)
+ page_align_16mb = true;
+
+ if ((!page_align_64kb) && (!page_align_1mb) && (!page_align_4kb)) {
+ status = -EINVAL;
+ goto error_exit;
+ }
+ if (status == 0) {
+ /* Now decide the entry size */
+ if (size >= PAGE_SIZE_16MB) {
+ if (page_align_16mb) {
+ *size_tlb = SUPER_SECTION;
+ *entry_size = PAGE_SIZE_16MB;
+ } else if (page_align_1mb) {
+ *size_tlb = SECTION;
+ *entry_size = PAGE_SIZE_1MB;
+ } else if (page_align_64kb) {
+ *size_tlb = LARGE_PAGE;
+ *entry_size = PAGE_SIZE_64KB;
+ } else if (page_align_4kb) {
+ *size_tlb = SMALL_PAGE;
+ *entry_size = PAGE_SIZE_4KB;
+ } else {
+ status = -EINVAL;
+ goto error_exit;
+ }
+ } else if (size >= PAGE_SIZE_1MB && size < PAGE_SIZE_16MB) {
+ if (page_align_1mb) {
+ *size_tlb = SECTION;
+ *entry_size = PAGE_SIZE_1MB;
+ } else if (page_align_64kb) {
+ *size_tlb = LARGE_PAGE;
+ *entry_size = PAGE_SIZE_64KB;
+ } else if (page_align_4kb) {
+ *size_tlb = SMALL_PAGE;
+ *entry_size = PAGE_SIZE_4KB;
+ } else {
+ status = -EINVAL;
+ goto error_exit;
+ }
+ } else if (size > PAGE_SIZE_4KB &&
+ size < PAGE_SIZE_1MB) {
+ if (page_align_64kb) {
+ *size_tlb = LARGE_PAGE;
+ *entry_size = PAGE_SIZE_64KB;
+ } else if (page_align_4kb) {
+ *size_tlb = SMALL_PAGE;
+ *entry_size = PAGE_SIZE_4KB;
+ } else {
+ status = -EINVAL;
+ goto error_exit;
+ }
+ } else if (size == PAGE_SIZE_4KB) {
+ if (page_align_4kb) {
+ *size_tlb = SMALL_PAGE;
+ *entry_size = PAGE_SIZE_4KB;
+ } else {
+ status = -EINVAL;
+ goto error_exit;
+ }
+ } else {
+ status = -EINVAL;
+ goto error_exit;
+ }
+ }
+ DPRINTK("< GetMMUEntrySize status %x\n", status);
+ return 0;
+error_exit:
+ DPRINTK("< GetMMUEntrySize FAILED !!!!!!\n");
+ return status;
+}
+
+/*=========================================
+ * Add DSP MMU entries corresponding to given MPU-Physical address
+ * and DSP-virtual address
+ */
+static int add_dsp_mmu_entry(u32 *phys_addr, u32 *dsp_addr,
+ u32 size)
+{
+ u32 mapped_size = 0;
+ enum pagetype size_tlb = SECTION;
+ u32 entry_size = 0;
+ int status = 0;
+ u32 page_size = HW_PAGE_SIZE_1MB;
+ struct hw_mmu_map_attrs_t map_attrs = { HW_LITTLE_ENDIAN,
+ HW_ELEM_SIZE_16BIT,
+ HW_MMU_CPUES };
+
+ DPRINTK("Entered add_dsp_mmu_entry phys_addr = "
+ "0x%x, dsp_addr = 0x%x,size = 0x%x\n",
+ *phys_addr, *dsp_addr, size);
+
+ while ((mapped_size < size) && (status == 0)) {
+ status = get_mmu_entry_size(*phys_addr,
+ (size - mapped_size), &size_tlb, &entry_size);
+
+ if (size_tlb == SUPER_SECTION)
+ page_size = HW_PAGE_SIZE_16MB;
+
+ else if (size_tlb == SECTION)
+ page_size = HW_PAGE_SIZE_1MB;
+
+ else if (size_tlb == LARGE_PAGE)
+ page_size = HW_PAGE_SIZE_64KB;
+
+ else if (size_tlb == SMALL_PAGE)
+ page_size = HW_PAGE_SIZE_4KB;
+ if (status == 0) {
+ hw_mmu_tlb_add((base_ducati_l2_mmu),
+ *phys_addr, *dsp_addr,
+ page_size, mmu_index_next++,
+ &map_attrs, HW_SET, HW_SET);
+ mapped_size += entry_size;
+ *phys_addr += entry_size;
+ *dsp_addr += entry_size;
+ if (mmu_index_next > 32) {
+ status = -EINVAL;
+ break;
+ }
+ /* Lock the base counter*/
+ hw_mmu_numlocked_set(base_ducati_l2_mmu,
+ mmu_index_next);
+
+ hw_mmu_victim_numset(base_ducati_l2_mmu,
+ mmu_index_next);
+ }
+ }
+ DPRINTK("Exited add_dsp_mmu_entryphys_addr = \
+ 0x%x, dsp_addr = 0x%x\n",
+ *phys_addr, *dsp_addr);
+ return status;
+ }
+
+
+/*=============================================
+ * Add DSP MMU entries corresponding to given MPU-Physical address
+ * and DSP-virtual address
+ *
+ */
+#if 0
+static int add_entry_ext(u32 *phys_addr, u32 *dsp_addr,
+ u32 size)
+{
+ u32 mapped_size = 0;
+ enum pagetype size_tlb = SECTION;
+ u32 entry_size = 0;
+ int status = 0;
+ u32 page_size = HW_PAGE_SIZE_1MB;
+ u32 flags = 0;
+
+ flags = (DSP_MAPELEMSIZE32 | DSP_MAPLITTLEENDIAN |
+ DSP_MAPPHYSICALADDR);
+ while ((mapped_size < size) && (status == 0)) {
+
+ /* get_mmu_entry_size fills the size_tlb and entry_size
+ based on alignment and size of memory to map
+ to DSP - size */
+ status = get_mmu_entry_size(*phys_addr,
+ (size - mapped_size),
+ &size_tlb,
+ &entry_size);
+
+ if (size_tlb == SUPER_SECTION)
+ page_size = HW_PAGE_SIZE_16MB;
+ else if (size_tlb == SECTION)
+ page_size = HW_PAGE_SIZE_1MB;
+ else if (size_tlb == LARGE_PAGE)
+ page_size = HW_PAGE_SIZE_64KB;
+ else if (size_tlb == SMALL_PAGE)
+ page_size = HW_PAGE_SIZE_4KB;
+
+ if (status == 0) {
+
+ ducati_mem_map(*phys_addr,
+ *dsp_addr, page_size, flags);
+ mapped_size += entry_size;
+ *phys_addr += entry_size;
+ *dsp_addr += entry_size;
+ }
+ }
+ return status;
+}
+#endif
+/*================================
+ * Initialize the Ducati MMU.
+ */
+int ducati_mmu_init(u32 a_phy_addr)
+{
+ int ret_val = 0;
+ u32 ducati_mmu_linear_addr = base_ducati_l2_mmu;
+ u32 reg_value = 0;
+ u32 phys_addr = 0;
+ u32 num_l4_entries;
+ u32 i = 0;
+ u32 map_attrs;
+ u32 num_l3_mem_entries = 0;
+ u32 virt_addr = 0;
+#if 0
+ u32 tiler_mapbeg = 0;
+ u32 tiler_totalsize = 0;
+#endif
+
+ num_l4_entries = (sizeof(l4_map) / sizeof(struct mmu_entry));
+ num_l3_mem_entries = sizeof(l3_memory_regions) /
+ sizeof(struct memory_entry);
+
+ DPRINTK("\n Programming Ducati MMU using linear address [0x%x]",
+ ducati_mmu_linear_addr);
+
+ /* Disable the MMU & TWL */
+ hw_mmu_disable(base_ducati_l2_mmu);
+ hw_mmu_twl_disable(base_ducati_l2_mmu);
+
+ mmu_index_next = 0;
+ phys_addr = a_phy_addr;
+
+ printk(KERN_ALERT " Programming Ducati memory regions\n");
+ printk(KERN_ALERT "=========================================\n");
+ for (i = 0; i < num_l3_mem_entries; i++) {
+
+ printk(KERN_ALERT "VA = [0x%x] of size [0x%x] at PA = [0x%x]\n",
+ l3_memory_regions[i].ul_virt_addr,
+ l3_memory_regions[i].ul_size, phys_addr);
+
+#if 0
+ /* OMAP4430 original code */
+ if (l3_memory_regions[i].ul_virt_addr == DUCATI_SHARED_IPC_ADDR)
+ shm_phys_addr = phys_addr;
+ */
+#endif
+ /* OMAP4430 SDC code */
+ /* Adjust below logic if using cacheable shared memory */
+ if (l3_memory_regions[i].ul_virt_addr == \
+ DUCATI_MEM_IPC_HEAP0_ADDR) {
+ shm_phys_addr = phys_addr;
+ }
+ virt_addr = l3_memory_regions[i].ul_virt_addr;
+ ret_val = add_dsp_mmu_entry(&phys_addr, &virt_addr,
+ (l3_memory_regions[i].ul_size));
+
+ if (WARN_ON(ret_val < 0))
+ goto error_exit;
+ }
+
+#if 0
+ /* OMAP4430 original code */
+ tiler_mapbeg = L3_TILER_VIEW0_ADDR;
+ tiler_totalsize = DUCATIVA_TILER_VIEW0_LEN;
+ phys_addr = L3_TILER_VIEW0_ADDR;
+
+ printk(KERN_ALERT " Programming TILER memory region at "
+ "[VA = 0x%x] of size [0x%x] at [PA = 0x%x]\n",
+ tiler_mapbeg, tiler_totalsize, phys_addr);
+ ret_val = add_entry_ext(&phys_addr, &tiler_mapbeg, tiler_totalsize);
+ if (WARN_ON(ret_val < 0))
+ goto error_exit;
+#endif
+
+ map_attrs = 0x00000000;
+ map_attrs |= DSP_MAPLITTLEENDIAN;
+ map_attrs |= DSP_MAPPHYSICALADDR;
+ map_attrs |= DSP_MAPELEMSIZE32;
+ printk(KERN_ALERT " Programming Ducati L4 peripherals\n");
+ printk(KERN_ALERT "=========================================\n");
+ for (i = 0; i < num_l4_entries; i++) {
+ printk(KERN_INFO "PA [0x%x] VA [0x%x] size [0x%x]\n",
+ l4_map[i].ul_phy_addr, l4_map[i].ul_virt_addr,
+ l4_map[i].ul_size);
+ virt_addr = l4_map[i].ul_virt_addr;
+ phys_addr = l4_map[i].ul_phy_addr;
+ ret_val = add_dsp_mmu_entry(&phys_addr,
+ &virt_addr, (l4_map[i].ul_size));
+ if (WARN_ON(ret_val < 0)) {
+
+ DPRINTK("**** Failed to map Peripheral ****");
+ DPRINTK("Phys addr [0x%x] Virt addr [0x%x] size [0x%x]",
+ l4_map[i].ul_phy_addr, l4_map[i].ul_virt_addr,
+ l4_map[i].ul_size);
+ DPRINTK(" Status [0x%x]", ret_val);
+ goto error_exit;
+ }
+ }
+
+ /* Set the TTB to point to the L1 page table's physical address */
+ hw_mmu_ttbset(ducati_mmu_linear_addr, p_pt_attrs->l1_base_pa);
+
+ /* Enable the TWL */
+ hw_mmu_twl_enable(ducati_mmu_linear_addr);
+
+ hw_mmu_enable(ducati_mmu_linear_addr);
+
+ /* MMU Debug Statements */
+ reg_value = *((REG u32 *)(ducati_mmu_linear_addr + 0x40));
+ DPRINTK(" Ducati TWL Status [0x%x]\n", reg_value);
+
+ reg_value = *((REG u32 *)(ducati_mmu_linear_addr + 0x4C));
+ DPRINTK(" Ducati TTB Address [0x%x]\n", reg_value);
+
+ reg_value = *((REG u32 *)(ducati_mmu_linear_addr + 0x44));
+ DPRINTK(" Ducati MMU Status [0x%x]\n", reg_value);
+
+ /* Dump the MMU Entries */
+ dbg_print_ptes(false, false);
+
+ return 0;
+error_exit:
+ return ret_val;
+}
+
+
+/*========================================
+ * This sets up the Ducati processor MMU Page tables
+ *
+ */
+int init_mmu_page_attribs(u32 l1_size, u32 l1_allign, u32 ls_num_of_pages)
+{
+ u32 pg_tbl_pa;
+ u32 pg_tbl_va;
+ u32 align_size;
+ int status = 0;
+
+ base_ducati_l2_mmu = (u32)ioremap(base_ducati_l2_mmuPhys, 0x4000);
+ p_pt_attrs = kmalloc(sizeof(struct pg_table_attrs), GFP_ATOMIC);
+ if (p_pt_attrs)
+ memset(p_pt_attrs, 0, sizeof(struct pg_table_attrs));
+ else {
+ status = -ENOMEM;
+ goto error_exit;
+ }
+ p_pt_attrs->l1_size = l1_size;
+ align_size = p_pt_attrs->l1_size;
+ /* Align sizes are expected to be power of 2 */
+ /* we like to get aligned on L1 table size */
+ pg_tbl_va = (u32)__get_dma_pages(GFP_KERNEL,
+ get_order(p_pt_attrs->l1_size));
+ if (pg_tbl_va == (u32)NULL) {
+ DPRINTK("dma_alloc_coherent failed 0x%x\n", pg_tbl_va);
+ status = -ENOMEM;
+ goto error_exit;
+ }
+ pg_tbl_pa = __pa(pg_tbl_va);
+ /* Check if the PA is aligned for us */
+ if ((pg_tbl_pa) & (align_size-1)) {
+ /* PA not aligned to page table size ,*/
+ /* try with more allocation and align */
+ free_pages(pg_tbl_va, get_order(p_pt_attrs->l1_size));
+ /* we like to get aligned on L1 table size */
+ pg_tbl_va = (u32)__get_dma_pages(GFP_KERNEL,
+ get_order(p_pt_attrs->l1_size * 2));
+ if (pg_tbl_va == (u32)NULL) {
+ DPRINTK("__get_dma_pages failed 0x%x\n", pg_tbl_va);
+ status = -ENOMEM;
+ goto error_exit;
+ }
+ pg_tbl_pa = __pa(pg_tbl_va);
+ /* We should be able to get aligned table now */
+ p_pt_attrs->l1_tbl_alloc_pa = pg_tbl_pa;
+ p_pt_attrs->l1_tbl_alloc_va = pg_tbl_va;
+ p_pt_attrs->l1_tbl_alloc_sz = p_pt_attrs->l1_size * 2;
+ /* Align the PA to the next 'align' boundary */
+ p_pt_attrs->l1_base_pa = ((pg_tbl_pa) + (align_size-1)) &
+ (~(align_size-1));
+ p_pt_attrs->l1_base_va = pg_tbl_va + (p_pt_attrs->l1_base_pa -
+ pg_tbl_pa);
+ } else {
+ /* We got aligned PA, cool */
+ p_pt_attrs->l1_tbl_alloc_pa = pg_tbl_pa;
+ p_pt_attrs->l1_tbl_alloc_va = pg_tbl_va;
+ p_pt_attrs->l1_tbl_alloc_sz = p_pt_attrs->l1_size;
+ p_pt_attrs->l1_base_pa = pg_tbl_pa;
+ p_pt_attrs->l1_base_va = pg_tbl_va;
+ }
+ if (p_pt_attrs->l1_base_va)
+ memset((u8 *)p_pt_attrs->l1_base_va, 0x00, p_pt_attrs->l1_size);
+ p_pt_attrs->l2_num_pages = ls_num_of_pages;
+ p_pt_attrs->l2_size = HW_MMU_COARSE_PAGE_SIZE *
+ p_pt_attrs->l2_num_pages;
+ align_size = 4; /* Make it u32 aligned */
+ /* we like to get aligned on L1 table size */
+ pg_tbl_va = (u32)__get_dma_pages(GFP_KERNEL,
+ get_order(p_pt_attrs->l2_size));
+ if (pg_tbl_va == (u32)NULL) {
+ DPRINTK("dma_alloc_coherent failed 0x%x\n", pg_tbl_va);
+ status = -ENOMEM;
+ goto error_exit;
+ }
+ pg_tbl_pa = __pa(pg_tbl_va);
+ p_pt_attrs->l2_tbl_alloc_pa = pg_tbl_pa;
+ p_pt_attrs->l2_tbl_alloc_va = pg_tbl_va;
+ p_pt_attrs->ls_tbl_alloc_sz = p_pt_attrs->l2_size;
+ p_pt_attrs->l2_base_pa = pg_tbl_pa;
+ p_pt_attrs->l2_base_va = pg_tbl_va;
+ if (p_pt_attrs->l2_base_va)
+ memset((u8 *)p_pt_attrs->l2_base_va, 0x00, p_pt_attrs->l2_size);
+
+ p_pt_attrs->pg_info = kmalloc(sizeof(struct page_info), GFP_ATOMIC);
+ if (p_pt_attrs->pg_info)
+ memset(p_pt_attrs->pg_info, 0, sizeof(struct page_info));
+ else {
+ DPRINTK("memory allocation fails for p_pt_attrs->pg_info ");
+ status = -ENOMEM;
+ goto error_exit;
+ }
+ DPRINTK("L1 pa %x, va %x, size %x\n L2 pa %x, va "
+ "%x, size %x\n", p_pt_attrs->l1_base_pa,
+ p_pt_attrs->l1_base_va, p_pt_attrs->l1_size,
+ p_pt_attrs->l2_base_pa, p_pt_attrs->l2_base_va,
+ p_pt_attrs->l2_size);
+ DPRINTK("p_pt_attrs %x L2 NumPages %x pg_info %x\n",
+ (u32)p_pt_attrs, p_pt_attrs->l2_num_pages,
+ (u32)p_pt_attrs->pg_info);
+ return 0;
+error_exit:
+ kfree(p_pt_attrs->pg_info);
+ if (p_pt_attrs->l1_base_va) {
+ free_pages(p_pt_attrs->l1_base_va,
+ get_order(p_pt_attrs->l1_tbl_alloc_sz));
+ }
+ if (p_pt_attrs->l2_base_va) {
+ free_pages(p_pt_attrs->l2_base_va,
+ get_order(p_pt_attrs->ls_tbl_alloc_sz));
+ }
+ WARN_ON(1);
+ printk(KERN_ALERT "init_mmu_page_attribs FAILED !!!!!\n");
+ return status;
+}
+
+/*========================================
+ * This sets up the Ducati processor
+ *
+ */
+int ducati_setup(void)
+{
+ int ret_val = 0;
+ ret_val = init_mmu_page_attribs(0x8000, 14, 128);
+ if (WARN_ON(ret_val < 0))
+ goto error_exit;
+ ret_val = ducati_mmu_init(DUCATI_BASEIMAGE_PHYSICAL_ADDRESS);
+ if (WARN_ON(ret_val < 0))
+ goto error_exit;
+ return 0;
+error_exit:
+ WARN_ON(1);
+ printk(KERN_ERR "DUCATI SETUP FAILED !!!!!\n");
+ return ret_val;
+}
+EXPORT_SYMBOL(ducati_setup);
+
+/*============================================
+ * De-Initialize the Ducati MMU and free the
+ * memory allocation for L1 and L2 pages
+ *
+ */
+void ducati_destroy(void)
+{
+ DPRINTK(" Freeing memory allocated in mmu_de_init\n");
+ if (p_pt_attrs->l2_tbl_alloc_va) {
+ free_pages(p_pt_attrs->l2_tbl_alloc_va,
+ get_order(p_pt_attrs->ls_tbl_alloc_sz));
+ }
+ if (p_pt_attrs->l1_tbl_alloc_va) {
+ free_pages(p_pt_attrs->l1_tbl_alloc_va,
+ get_order(p_pt_attrs->l1_tbl_alloc_sz));
+ }
+ if (p_pt_attrs)
+ kfree((void *)p_pt_attrs);
+ iounmap((unsigned int *)base_ducati_l2_mmu);
+ return;
+}
+EXPORT_SYMBOL(ducati_destroy);
+
+/*============================================
+ * Returns the ducati virtual address for IPC shared memory
+ *
+ */
+u32 get_ducati_virt_mem()
+{
+ /*shm_virt_addr = (u32)ioremap(shm_phys_addr, DUCATI_SHARED_IPC_LEN);*/
+ shm_virt_addr = (u32)ioremap(shm_phys_addr, DUCATI_MEM_IPC_SHMEM_LEN);
+ return shm_virt_addr;
+}
+EXPORT_SYMBOL(get_ducati_virt_mem);
+
+/*============================================
+ * Unmaps the ducati virtual address for IPC shared memory
+ *
+ */
+void unmap_ducati_virt_mem(u32 shm_virt_addr)
+{
+ iounmap((unsigned int *) shm_virt_addr);
+ return;
+}
+EXPORT_SYMBOL(unmap_ducati_virt_mem);
diff --git a/drivers/dsp/syslink/procmgr/proc4430/hw_mmu.c b/drivers/dsp/syslink/procmgr/proc4430/hw_mmu.c
new file mode 100755
index 000000000000..f2e4ccbe860f
--- /dev/null
+++ b/drivers/dsp/syslink/procmgr/proc4430/hw_mmu.c
@@ -0,0 +1,643 @@
+/*
+ * hw_mbox.c
+ *
+ * Syslink driver support for OMAP Processors.
+ *
+ * Copyright (C) 2008-2009 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE.
+ */
+
+#include<linux/kernel.h>
+#include<linux/module.h>
+
+#include <syslink/GlobalTypes.h>
+#include <syslink/MMURegAcM.h>
+#include <syslink/hw_defs.h>
+#include <syslink/hw_mmu.h>
+
+#define MMU_BASE_VAL_MASK 0xFC00
+#define MMU_PAGE_MAX 3
+#define MMU_ELEMENTSIZE_MAX 3
+#define MMU_ADDR_MASK 0xFFFFF000
+#define MMU_TTB_MASK 0xFFFFC000
+#define MMU_SECTION_ADDR_MASK 0xFFF00000
+#define MMU_SSECTION_ADDR_MASK 0xFF000000
+#define MMU_PAGE_TABLE_MASK 0xFFFFFC00
+#define MMU_LARGE_PAGE_MASK 0xFFFF0000
+#define MMU_SMALL_PAGE_MASK 0xFFFFF000
+
+#define MMU_LOAD_TLB 0x00000001
+#define NUM_TLB_ENTRIES 32
+
+
+
+/*
+* type: hw_mmu_pgsiz_t
+*
+* desc: Enumerated Type used to specify the MMU Page Size(SLSS)
+*
+*
+*/
+enum hw_mmu_pgsiz_t {
+ HW_MMU_SECTION,
+ HW_MMU_LARGE_PAGE,
+ HW_MMU_SMALL_PAGE,
+ HW_MMU_SUPERSECTION
+
+};
+
+/*
+* function : mmu_flsh_entry
+*/
+
+static hw_status mmu_flsh_entry(const u32 base_address);
+
+ /*
+* function : mme_set_cam_entry
+*
+*/
+
+static hw_status mme_set_cam_entry(const u32 base_address,
+ const u32 page_size,
+ const u32 preserve_bit,
+ const u32 valid_bit,
+ const u32 virt_addr_tag);
+
+/*
+* function : mmu_set_ram_entry
+*/
+static hw_status mmu_set_ram_entry(const u32 base_address,
+ const u32 physical_addr,
+ enum hw_endianism_t endianism,
+ enum hw_elemnt_siz_t element_size,
+ enum hw_mmu_mixed_size_t mixedSize);
+
+/*
+* hw functions
+*
+*/
+
+hw_status hw_mmu_enable(const u32 base_address)
+{
+ hw_status status = RET_OK;
+
+ MMUMMU_CNTLMMUEnableWrite32(base_address, HW_SET);
+
+ return status;
+}
+EXPORT_SYMBOL(hw_mmu_enable);
+
+hw_status hw_mmu_disable(const u32 base_address)
+{
+ hw_status status = RET_OK;
+
+ MMUMMU_CNTLMMUEnableWrite32(base_address, HW_CLEAR);
+
+ return status;
+}
+EXPORT_SYMBOL(hw_mmu_disable);
+
+hw_status hw_mmu_autoidle_en(const u32 base_address)
+{
+ hw_status status;
+
+ status = mmu_sisconf_auto_idle_set32(base_address, HW_SET);
+ status = RET_OK;
+ return status;
+}
+EXPORT_SYMBOL(hw_mmu_autoidle_en);
+
+hw_status hw_mmu_nulck_set(const u32 base_address, u32 *num_lcked_entries)
+{
+ hw_status status = RET_OK;
+
+ *num_lcked_entries = MMUMMU_LOCKBaseValueRead32(base_address);
+
+ return status;
+}
+EXPORT_SYMBOL(hw_mmu_nulck_set);
+
+
+hw_status hw_mmu_numlocked_set(const u32 base_address, u32 num_lcked_entries)
+{
+ hw_status status = RET_OK;
+
+ MMUMMU_LOCKBaseValueWrite32(base_address, num_lcked_entries);
+
+ return status;
+}
+EXPORT_SYMBOL(hw_mmu_numlocked_set);
+
+
+hw_status hw_mmu_vctm_numget(const u32 base_address, u32 *vctm_entry_num)
+{
+ hw_status status = RET_OK;
+
+ *vctm_entry_num = MMUMMU_LOCKCurrentVictimRead32(base_address);
+
+ return status;
+}
+EXPORT_SYMBOL(hw_mmu_vctm_numget);
+
+
+hw_status hw_mmu_victim_numset(const u32 base_address, u32 vctm_entry_num)
+{
+ hw_status status = RET_OK;
+
+ mmu_lck_crnt_vctmwite32(base_address, vctm_entry_num);
+
+ return status;
+}
+EXPORT_SYMBOL(hw_mmu_victim_numset);
+
+hw_status hw_mmu_tlb_flushAll(const u32 base_address)
+{
+ hw_status status = RET_OK;
+
+ MMUMMU_GFLUSHGlobalFlushWrite32(base_address, HW_SET);
+
+ return status;
+}
+EXPORT_SYMBOL(hw_mmu_tlb_flushAll);
+
+hw_status hw_mmu_eventack(const u32 base_address, u32 irq_mask)
+{
+ hw_status status = RET_OK;
+
+ MMUMMU_IRQSTATUSWriteRegister32(base_address, irq_mask);
+
+ return status;
+}
+EXPORT_SYMBOL(hw_mmu_eventack);
+
+hw_status hw_mmu_event_disable(const u32 base_address, u32 irq_mask)
+{
+ hw_status status = RET_OK;
+ u32 irqReg;
+ irqReg = MMUMMU_IRQENABLEReadRegister32(base_address);
+
+ MMUMMU_IRQENABLEWriteRegister32(base_address, irqReg & ~irq_mask);
+
+ return status;
+}
+EXPORT_SYMBOL(hw_mmu_event_disable);
+
+hw_status hw_mmu_event_enable(const u32 base_address, u32 irq_mask)
+{
+ hw_status status = RET_OK;
+ u32 irqReg;
+
+ irqReg = MMUMMU_IRQENABLEReadRegister32(base_address);
+
+ MMUMMU_IRQENABLEWriteRegister32(base_address, irqReg | irq_mask);
+
+ return status;
+}
+EXPORT_SYMBOL(hw_mmu_event_enable);
+
+hw_status hw_mmu_event_status(const u32 base_address, u32 *irq_mask)
+{
+ hw_status status = RET_OK;
+
+ *irq_mask = MMUMMU_IRQSTATUSReadRegister32(base_address);
+
+ return status;
+}
+EXPORT_SYMBOL(hw_mmu_event_status);
+
+hw_status hw_mmu_flt_adr_rd(const u32 base_address, u32 *addr)
+{
+ hw_status status = RET_OK;
+
+ /*Check the input Parameters*/
+ CHECK_INPUT_PARAM(base_address, 0, RET_BAD_NULL_PARAM,
+ RES_MMU_BASE + RES_INVALID_INPUT_PARAM);
+ /* read values from register */
+ *addr = MMUMMU_FAULT_ADReadRegister32(base_address);
+
+ return status;
+}
+EXPORT_SYMBOL(hw_mmu_flt_adr_rd);
+
+
+hw_status hw_mmu_ttbset(const u32 base_address, u32 ttb_phys_addr)
+{
+ hw_status status = RET_OK;
+ u32 loadTTB;
+
+ /*Check the input Parameters*/
+ CHECK_INPUT_PARAM(base_address, 0, RET_BAD_NULL_PARAM,
+ RES_MMU_BASE + RES_INVALID_INPUT_PARAM);
+
+ loadTTB = ttb_phys_addr & ~0x7FUL;
+ /* write values to register */
+ MMUMMU_TTBWriteRegister32(base_address, loadTTB);
+
+ return status;
+}
+EXPORT_SYMBOL(hw_mmu_ttbset);
+
+hw_status hw_mmu_twl_enable(const u32 base_address)
+{
+ hw_status status = RET_OK;
+
+ MMUMMU_CNTLTWLEnableWrite32(base_address, HW_SET);
+
+ return status;
+}
+EXPORT_SYMBOL(hw_mmu_twl_enable);
+
+hw_status hw_mmu_twl_disable(const u32 base_address)
+{
+ hw_status status = RET_OK;
+
+ MMUMMU_CNTLTWLEnableWrite32(base_address, HW_CLEAR);
+
+ return status;
+}
+EXPORT_SYMBOL(hw_mmu_twl_disable);
+
+
+hw_status hw_mmu_tlb_flush(const u32 base_address,
+ u32 virtual_addr,
+ u32 page_size)
+{
+ hw_status status = RET_OK;
+ u32 virt_addr_tag;
+ enum hw_mmu_pgsiz_t pg_sizeBits;
+
+ switch (page_size) {
+ case HW_PAGE_SIZE_4KB:
+ pg_sizeBits = HW_MMU_SMALL_PAGE;
+ break;
+
+ case HW_PAGE_SIZE_64KB:
+ pg_sizeBits = HW_MMU_LARGE_PAGE;
+ break;
+
+ case HW_PAGE_SIZE_1MB:
+ pg_sizeBits = HW_MMU_SECTION;
+ break;
+
+ case HW_PAGE_SIZE_16MB:
+ pg_sizeBits = HW_MMU_SUPERSECTION;
+ break;
+
+ default:
+ return RET_FAIL;
+ }
+
+ /* Generate the 20-bit tag from virtual address */
+ virt_addr_tag = ((virtual_addr & MMU_ADDR_MASK) >> 12);
+
+ mme_set_cam_entry(base_address, pg_sizeBits, 0, 0, virt_addr_tag);
+
+ mmu_flsh_entry(base_address);
+
+ return status;
+}
+EXPORT_SYMBOL(hw_mmu_tlb_flush);
+
+
+hw_status hw_mmu_tlb_add(const u32 base_address,
+ u32 physical_addr,
+ u32 virtual_addr,
+ u32 page_size,
+ u32 entryNum,
+ struct hw_mmu_map_attrs_t *map_attrs,
+ enum hw_set_clear_t preserve_bit,
+ enum hw_set_clear_t valid_bit)
+{
+ hw_status status = RET_OK;
+ u32 lockReg;
+ u32 virt_addr_tag;
+ enum hw_mmu_pgsiz_t mmu_pg_size;
+
+ /*Check the input Parameters*/
+ CHECK_INPUT_PARAM(base_address, 0, RET_BAD_NULL_PARAM,
+ RES_MMU_BASE + RES_INVALID_INPUT_PARAM);
+ CHECK_INPUT_RANGE_MIN0(page_size, MMU_PAGE_MAX, RET_PARAM_OUT_OF_RANGE,
+ RES_MMU_BASE + RES_INVALID_INPUT_PARAM);
+ CHECK_INPUT_RANGE_MIN0(map_attrs->element_size,
+ MMU_ELEMENTSIZE_MAX, RET_PARAM_OUT_OF_RANGE,
+ RES_MMU_BASE + RES_INVALID_INPUT_PARAM);
+
+ switch (page_size) {
+ case HW_PAGE_SIZE_4KB:
+ mmu_pg_size = HW_MMU_SMALL_PAGE;
+ break;
+
+ case HW_PAGE_SIZE_64KB:
+ mmu_pg_size = HW_MMU_LARGE_PAGE;
+ break;
+
+ case HW_PAGE_SIZE_1MB:
+ mmu_pg_size = HW_MMU_SECTION;
+ break;
+
+ case HW_PAGE_SIZE_16MB:
+ mmu_pg_size = HW_MMU_SUPERSECTION;
+ break;
+
+ default:
+ return RET_FAIL;
+ }
+
+ lockReg = mmu_lckread_reg_32(base_address);
+
+ /* Generate the 20-bit tag from virtual address */
+ virt_addr_tag = ((virtual_addr & MMU_ADDR_MASK) >> 12);
+
+ /* Write the fields in the CAM Entry Register */
+ mme_set_cam_entry(base_address, mmu_pg_size, preserve_bit, valid_bit,
+ virt_addr_tag);
+
+ /* Write the different fields of the RAM Entry Register */
+ /* endianism of the page,Element Size of the page (8, 16, 32, 64 bit) */
+ mmu_set_ram_entry(base_address, physical_addr,
+ map_attrs->endianism, map_attrs->element_size, map_attrs->mixedSize);
+
+ /* Update the MMU Lock Register */
+ /* currentVictim between lockedBaseValue and (MMU_Entries_Number - 1) */
+ mmu_lck_crnt_vctmwite32(base_address, entryNum);
+
+ /* Enable loading of an entry in TLB by writing 1 into LD_TLB_REG
+ register */
+ mmu_ld_tlbwrt_reg32(base_address, MMU_LOAD_TLB);
+
+
+ mmu_lck_write_reg32(base_address, lockReg);
+
+ return status;
+}
+EXPORT_SYMBOL(hw_mmu_tlb_add);
+
+
+
+hw_status hw_mmu_pte_set(const u32 pg_tbl_va,
+ u32 physical_addr,
+ u32 virtual_addr,
+ u32 page_size,
+ struct hw_mmu_map_attrs_t *map_attrs)
+{
+ hw_status status = RET_OK;
+ u32 pte_addr, pte_val;
+ long int num_entries = 1;
+
+ switch (page_size) {
+
+ case HW_PAGE_SIZE_4KB:
+ pte_addr = hw_mmu_pte_addr_l2(pg_tbl_va, virtual_addr &
+ MMU_SMALL_PAGE_MASK);
+ pte_val = ((physical_addr & MMU_SMALL_PAGE_MASK) |
+ (map_attrs->endianism << 9) |
+ (map_attrs->element_size << 4) |
+ (map_attrs->mixedSize << 11) | 2
+ );
+ break;
+
+ case HW_PAGE_SIZE_64KB:
+ num_entries = 16;
+ pte_addr = hw_mmu_pte_addr_l2(pg_tbl_va, virtual_addr &
+ MMU_LARGE_PAGE_MASK);
+ pte_val = ((physical_addr & MMU_LARGE_PAGE_MASK) |
+ (map_attrs->endianism << 9) |
+ (map_attrs->element_size << 4) |
+ (map_attrs->mixedSize << 11) | 1
+ );
+ break;
+
+ case HW_PAGE_SIZE_1MB:
+ pte_addr = hw_mmu_pte_addr_l1(pg_tbl_va, virtual_addr &
+ MMU_SECTION_ADDR_MASK);
+ pte_val = ((((physical_addr & MMU_SECTION_ADDR_MASK) |
+ (map_attrs->endianism << 15) |
+ (map_attrs->element_size << 10) |
+ (map_attrs->mixedSize << 17)) &
+ ~0x40000) | 0x2
+ );
+ break;
+
+ case HW_PAGE_SIZE_16MB:
+ num_entries = 16;
+ pte_addr = hw_mmu_pte_addr_l1(pg_tbl_va, virtual_addr &
+ MMU_SSECTION_ADDR_MASK);
+ pte_val = (((physical_addr & MMU_SSECTION_ADDR_MASK) |
+ (map_attrs->endianism << 15) |
+ (map_attrs->element_size << 10) |
+ (map_attrs->mixedSize << 17)
+ ) | 0x40000 | 0x2
+ );
+ break;
+
+ case HW_MMU_COARSE_PAGE_SIZE:
+ pte_addr = hw_mmu_pte_addr_l1(pg_tbl_va, virtual_addr &
+ MMU_SECTION_ADDR_MASK);
+ pte_val = (physical_addr & MMU_PAGE_TABLE_MASK) | 1;
+ break;
+
+ default:
+ return RET_FAIL;
+ }
+
+ while (--num_entries >= 0)
+ ((u32 *)pte_addr)[num_entries] = pte_val;
+
+
+ return status;
+}
+EXPORT_SYMBOL(hw_mmu_pte_set);
+
+hw_status hw_mmu_pte_clear(const u32 pg_tbl_va,
+ u32 virtual_addr,
+ u32 pg_size)
+{
+ hw_status status = RET_OK;
+ u32 pte_addr;
+ long int num_entries = 1;
+
+ switch (pg_size) {
+ case HW_PAGE_SIZE_4KB:
+ pte_addr = hw_mmu_pte_addr_l2(pg_tbl_va,
+ virtual_addr & MMU_SMALL_PAGE_MASK);
+ break;
+
+ case HW_PAGE_SIZE_64KB:
+ num_entries = 16;
+ pte_addr = hw_mmu_pte_addr_l2(pg_tbl_va,
+ virtual_addr & MMU_LARGE_PAGE_MASK);
+ break;
+
+ case HW_PAGE_SIZE_1MB:
+ case HW_MMU_COARSE_PAGE_SIZE:
+ pte_addr = hw_mmu_pte_addr_l1(pg_tbl_va,
+ virtual_addr & MMU_SECTION_ADDR_MASK);
+ break;
+
+ case HW_PAGE_SIZE_16MB:
+ num_entries = 16;
+ pte_addr = hw_mmu_pte_addr_l1(pg_tbl_va,
+ virtual_addr & MMU_SSECTION_ADDR_MASK);
+ break;
+
+ default:
+ return RET_FAIL;
+ }
+
+ while (--num_entries >= 0)
+ ((u32 *)pte_addr)[num_entries] = 0;
+
+ return status;
+}
+EXPORT_SYMBOL(hw_mmu_pte_clear);
+
+/*
+* function: mmu_flsh_entry
+*/
+static hw_status mmu_flsh_entry(const u32 base_address)
+{
+ hw_status status = RET_OK;
+ u32 flushEntryData = 0x1;
+
+ /*Check the input Parameters*/
+ CHECK_INPUT_PARAM(base_address, 0, RET_BAD_NULL_PARAM,
+ RES_MMU_BASE + RES_INVALID_INPUT_PARAM);
+
+ /* write values to register */
+ MMUMMU_FLUSH_ENTRYWriteRegister32(base_address, flushEntryData);
+
+ return status;
+}
+EXPORT_SYMBOL(mmu_flsh_entry);
+/*
+* function : mme_set_cam_entry
+*/
+static hw_status mme_set_cam_entry(const u32 base_address,
+ const u32 page_size,
+ const u32 preserve_bit,
+ const u32 valid_bit,
+ const u32 virt_addr_tag)
+{
+ hw_status status = RET_OK;
+ u32 mmuCamReg;
+
+ /*Check the input Parameters*/
+ CHECK_INPUT_PARAM(base_address, 0, RET_BAD_NULL_PARAM,
+ RES_MMU_BASE + RES_INVALID_INPUT_PARAM);
+
+ mmuCamReg = (virt_addr_tag << 12);
+ mmuCamReg = (mmuCamReg) | (page_size) | (valid_bit << 2)
+ | (preserve_bit << 3);
+
+ /* write values to register */
+ MMUMMU_CAMWriteRegister32(base_address, mmuCamReg);
+
+ return status;
+}
+EXPORT_SYMBOL(mme_set_cam_entry);
+/*
+* function: mmu_set_ram_entry
+*/
+static hw_status mmu_set_ram_entry(const u32 base_address,
+ const u32 physical_addr,
+ enum hw_endianism_t endianism,
+ enum hw_elemnt_siz_t element_size,
+ enum hw_mmu_mixed_size_t mixedSize)
+{
+ hw_status status = RET_OK;
+ u32 mmuRamReg;
+
+ /*Check the input Parameters*/
+ CHECK_INPUT_PARAM(base_address, 0, RET_BAD_NULL_PARAM,
+ RES_MMU_BASE + RES_INVALID_INPUT_PARAM);
+ CHECK_INPUT_RANGE_MIN0(element_size, MMU_ELEMENTSIZE_MAX,
+ RET_PARAM_OUT_OF_RANGE,
+ RES_MMU_BASE + RES_INVALID_INPUT_PARAM);
+
+
+ mmuRamReg = (physical_addr & MMU_ADDR_MASK);
+ mmuRamReg = (mmuRamReg) | ((endianism << 9) | (element_size << 7)
+ | (mixedSize << 6));
+
+ /* write values to register */
+ MMUMMU_RAMWriteRegister32(base_address, mmuRamReg);
+
+ return status;
+
+}
+EXPORT_SYMBOL(mmu_set_ram_entry);
+
+long hw_mmu_tlb_dump(const u32 base_address, bool shw_inv_entries)
+{
+ u32 i;
+ u32 lockSave;
+ u32 cam;
+ u32 ram;
+
+
+ /* Save off the lock register contents,
+ we'll restore it when we are done */
+
+ lockSave = mmu_lckread_reg_32(base_address);
+
+ printk(KERN_INFO "TLB locked entries = %u, current victim = %u\n",
+ ((lockSave & MMU_MMU_LOCK_BaseValue_MASK)
+ >> MMU_MMU_LOCK_BaseValue_OFFSET),
+ ((lockSave & MMU_MMU_LOCK_CurrentVictim_MASK)
+ >> MMU_MMU_LOCK_CurrentVictim_OFFSET));
+ printk(KERN_INFO "=============================================\n");
+ for (i = 0; i < NUM_TLB_ENTRIES; i++) {
+ mmu_lck_crnt_vctmwite32(base_address, i);
+ cam = MMUMMU_CAMReadRegister32(base_address);
+ ram = MMUMMU_RAMReadRegister32(base_address);
+
+ if ((cam & 0x4) != 0) {
+ printk(KERN_INFO "TLB Entry [0x%x]: VA = 0x%x"
+ "PA = 0x%x Protected = 0x%x\n)",
+ i, (cam & MMU_ADDR_MASK), (ram & MMU_ADDR_MASK),
+ (cam & 0x8) ? 1 : 0);
+
+ } else if (shw_inv_entries != false)
+ printk(KERN_ALERT "TLB Entry [0x%x]: <INVALID>\n", i);
+ }
+ mmu_lck_write_reg32(base_address, lockSave);
+ return RET_OK;
+}
+EXPORT_SYMBOL(hw_mmu_tlb_dump);
+
+u32 hw_mmu_pte_phyaddr(u32 pte_val, u32 pte_size)
+{
+ u32 ret_val = 0;
+
+ switch (pte_size) {
+
+ case HW_PAGE_SIZE_4KB:
+ ret_val = pte_val & MMU_SMALL_PAGE_MASK;
+ break;
+ case HW_PAGE_SIZE_64KB:
+ ret_val = pte_val & MMU_LARGE_PAGE_MASK;
+ break;
+
+ case HW_PAGE_SIZE_1MB:
+ ret_val = pte_val & MMU_SECTION_ADDR_MASK;
+ break;
+ case HW_PAGE_SIZE_16MB:
+ ret_val = pte_val & MMU_SSECTION_ADDR_MASK;
+ break;
+ default:
+ /* Invalid */
+ break;
+
+ }
+
+ return ret_val;
+}
+EXPORT_SYMBOL(hw_mmu_pte_phyaddr);
diff --git a/drivers/dsp/syslink/procmgr/proc4430/proc4430.c b/drivers/dsp/syslink/procmgr/proc4430/proc4430.c
new file mode 100644
index 000000000000..e752a7932c9e
--- /dev/null
+++ b/drivers/dsp/syslink/procmgr/proc4430/proc4430.c
@@ -0,0 +1,1021 @@
+/*
+ * proc4430.c
+ *
+ * Syslink driver support functions for TI OMAP processors.
+ *
+ * Copyright (C) 2009-2010 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/vmalloc.h>
+#include <linux/uaccess.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+
+/* Module level headers */
+#include "../procdefs.h"
+#include "../processor.h"
+#include <procmgr.h>
+#include "../procmgr_drvdefs.h"
+#include "proc4430.h"
+#include "dmm4430.h"
+#include <syslink/multiproc.h>
+#include <syslink/ducatienabler.h>
+#include <syslink/platform_mem.h>
+#include <syslink/atomic_linux.h>
+
+#define DUCATI_DMM_START_ADDR 0xa0000000
+#define DUCATI_DMM_POOL_SIZE 0x6000000
+
+#define SYS_M3 2
+#define APP_M3 3
+#define CORE_PRM_BASE OMAP2_L4_IO_ADDRESS(0x4a306700)
+#define CORE_CM2_DUCATI_CLKSTCTRL OMAP2_L4_IO_ADDRESS(0x4A008900)
+#define CORE_CM2_DUCATI_CLKCTRL OMAP2_L4_IO_ADDRESS(0x4A008920)
+#define RM_MPU_M3_RSTCTRL_OFFSET 0x210
+#define RM_MPU_M3_RSTST_OFFSET 0x214
+#define RM_MPU_M3_RST1 0x1
+#define RM_MPU_M3_RST2 0x2
+#define RM_MPU_M3_RST3 0x4
+
+#define OMAP4430PROC_MODULEID (u16) 0xbbec
+
+/* Macro to make a correct module magic number with refCount */
+#define OMAP4430PROC_MAKE_MAGICSTAMP(x) ((OMAP4430PROC_MODULEID << 12u) | (x))
+
+/*OMAP4430 Module state object */
+struct proc4430_module_object {
+ u32 config_size;
+ /* Size of configuration structure */
+ struct proc4430_config cfg;
+ /* OMAP4430 configuration structure */
+ struct proc4430_config def_cfg;
+ /* Default module configuration */
+ struct proc4430_params def_inst_params;
+ /* Default parameters for the OMAP4430 instances */
+ void *proc_handles[MULTIPROC_MAXPROCESSORS];
+ /* Processor handle array. */
+ struct mutex *gate_handle;
+ /* void * of gate to be used for local thread safety */
+ atomic_t ref_count;
+};
+
+/*
+ OMAP4430 instance object.
+ */
+struct proc4430_object {
+ struct proc4430_params params;
+ /* Instance parameters (configuration values) */
+};
+
+
+/* =================================
+ * Globals
+ * =================================
+ */
+/*
+ OMAP4430 state object variable
+ */
+
+static struct proc4430_module_object proc4430_state = {
+ .config_size = sizeof(struct proc4430_config),
+ .gate_handle = NULL,
+ .def_inst_params.num_mem_entries = 0u,
+ .def_inst_params.mem_entries = NULL,
+ .def_inst_params.reset_vector_mem_entry = 0
+};
+
+
+/* =================================
+ * APIs directly called by applications
+ * =================================
+ */
+/*
+ * Function to get the default configuration for the OMAP4430
+ * module.
+ *
+ * This function can be called by the application to get their
+ * configuration parameter to proc4430_setup filled in by the
+ * OMAP4430 module with the default parameters. If the user
+ * does not wish to make any change in the default parameters, this
+ * API is not required to be called.
+ */
+void proc4430_get_config(struct proc4430_config *cfg)
+{
+ BUG_ON(cfg == NULL);
+ memcpy(cfg, &(proc4430_state.def_cfg),
+ sizeof(struct proc4430_config));
+}
+EXPORT_SYMBOL(proc4430_get_config);
+
+/*
+ * Function to setup the OMAP4430 module.
+ *
+ * This function sets up the OMAP4430 module. This function
+ * must be called before any other instance-level APIs can be
+ * invoked.
+ * Module-level configuration needs to be provided to this
+ * function. If the user wishes to change some specific config
+ * parameters, then proc4430_get_config can be called to get the
+ * configuration filled with the default values. After this, only
+ * the required configuration values can be changed. If the user
+ * does not wish to make any change in the default parameters, the
+ * application can simply call proc4430_setup with NULL
+ * parameters. The default parameters would get automatically used.
+ */
+int proc4430_setup(struct proc4430_config *cfg)
+{
+ int retval = 0;
+ struct proc4430_config tmp_cfg;
+ atomic_cmpmask_and_set(&proc4430_state.ref_count,
+ OMAP4430PROC_MAKE_MAGICSTAMP(0),
+ OMAP4430PROC_MAKE_MAGICSTAMP(0));
+
+ if (atomic_inc_return(&proc4430_state.ref_count) !=
+ OMAP4430PROC_MAKE_MAGICSTAMP(1)) {
+ return 1;
+ }
+
+ if (cfg == NULL) {
+ proc4430_get_config(&tmp_cfg);
+ cfg = &tmp_cfg;
+ }
+
+ dmm_create();
+ dmm_create_tables(DUCATI_DMM_START_ADDR, DUCATI_DMM_POOL_SIZE);
+
+ /* Create a default gate handle for local module protection. */
+ proc4430_state.gate_handle =
+ kmalloc(sizeof(struct mutex), GFP_KERNEL);
+ if (proc4430_state.gate_handle == NULL) {
+ retval = -ENOMEM;
+ goto error;
+ }
+
+ mutex_init(proc4430_state.gate_handle);
+
+ /* Initialize the name to handles mapping array. */
+ memset(&proc4430_state.proc_handles, 0,
+ (sizeof(void *) * MULTIPROC_MAXPROCESSORS));
+
+ /* Copy the user provided values into the state object. */
+ memcpy(&proc4430_state.cfg, cfg,
+ sizeof(struct proc4430_config));
+
+ return 0;
+
+error:
+ atomic_dec_return(&proc4430_state.ref_count);
+ dmm_delete_tables();
+ dmm_destroy();
+
+ return retval;
+}
+EXPORT_SYMBOL(proc4430_setup);
+
+/*
+ * Function to destroy the OMAP4430 module.
+ *
+ * Once this function is called, other OMAP4430 module APIs,
+ * except for the proc4430_get_config API cannot be called
+ * anymore.
+ */
+int proc4430_destroy(void)
+{
+ int retval = 0;
+ u16 i;
+
+ if (atomic_cmpmask_and_lt(&proc4430_state.ref_count,
+ OMAP4430PROC_MAKE_MAGICSTAMP(0),
+ OMAP4430PROC_MAKE_MAGICSTAMP(1))
+ == true) {
+ retval = -ENODEV;
+ goto exit;
+ }
+ if (!(atomic_dec_return(&proc4430_state.ref_count)
+ == OMAP4430PROC_MAKE_MAGICSTAMP(0))) {
+
+ retval = 1;
+ goto exit;
+ }
+
+ /* Check if any OMAP4430 instances have not been
+ * deleted so far. If not,delete them.
+ */
+
+ for (i = 0; i < MULTIPROC_MAXPROCESSORS; i++) {
+ if (proc4430_state.proc_handles[i] == NULL)
+ continue;
+ proc4430_delete(&(proc4430_state.proc_handles[i]));
+ }
+
+ /* Check if the gate_handle was created internally. */
+ if (proc4430_state.gate_handle != NULL) {
+ mutex_destroy(proc4430_state.gate_handle);
+ kfree(proc4430_state.gate_handle);
+ }
+
+exit:
+ return retval;
+}
+EXPORT_SYMBOL(proc4430_destroy);
+
+/*=================================================
+ * Function to initialize the parameters for this Processor
+ * instance.
+ */
+void proc4430_params_init(void *handle, struct proc4430_params *params)
+{
+ struct proc4430_object *proc_object = (struct proc4430_object *)handle;
+
+ if (atomic_cmpmask_and_lt(&proc4430_state.ref_count,
+ OMAP4430PROC_MAKE_MAGICSTAMP(0),
+ OMAP4430PROC_MAKE_MAGICSTAMP(1))
+ == true) {
+ printk(KERN_ERR "proc4430_params_init failed "
+ "Module not initialized");
+ return;
+ }
+
+ if (WARN_ON(params == NULL)) {
+ printk(KERN_ERR "proc4430_params_init failed "
+ "Argument of type proc4430_params * "
+ "is NULL");
+ return;
+ }
+
+ if (handle == NULL)
+ memcpy(params, &(proc4430_state.def_inst_params),
+ sizeof(struct proc4430_params));
+ else
+ memcpy(params, &(proc_object->params),
+ sizeof(struct proc4430_params));
+}
+EXPORT_SYMBOL(proc4430_params_init);
+
+/*===================================================
+ *Function to create an instance of this Processor.
+ *
+ */
+void *proc4430_create(u16 proc_id, const struct proc4430_params *params)
+{
+ struct processor_object *handle = NULL;
+ struct proc4430_object *object = NULL;
+
+ BUG_ON(!IS_VALID_PROCID(proc_id));
+ BUG_ON(params == NULL);
+
+ if (atomic_cmpmask_and_lt(&proc4430_state.ref_count,
+ OMAP4430PROC_MAKE_MAGICSTAMP(0),
+ OMAP4430PROC_MAKE_MAGICSTAMP(1))
+ == true) {
+ printk(KERN_ERR "proc4430_create failed "
+ "Module not initialized");
+ goto error;
+ }
+
+ /* Enter critical section protection. */
+ WARN_ON(mutex_lock_interruptible(proc4430_state.gate_handle));
+ if (proc4430_state.proc_handles[proc_id] != NULL) {
+ handle = proc4430_state.proc_handles[proc_id];
+ goto func_end;
+ } else {
+ handle = (struct processor_object *)
+ vmalloc(sizeof(struct processor_object));
+ if (WARN_ON(handle == NULL))
+ goto func_end;
+
+ handle->proc_fxn_table.attach = &proc4430_attach;
+ handle->proc_fxn_table.detach = &proc4430_detach;
+ handle->proc_fxn_table.start = &proc4430_start;
+ handle->proc_fxn_table.stop = &proc4430_stop;
+ handle->proc_fxn_table.read = &proc4430_read;
+ handle->proc_fxn_table.write = &proc4430_write;
+ handle->proc_fxn_table.control = &proc4430_control;
+ handle->proc_fxn_table.translateAddr =
+ &proc4430_translate_addr;
+ handle->proc_fxn_table.map = &proc4430_map;
+ handle->proc_fxn_table.unmap = &proc4430_unmap;
+ handle->proc_fxn_table.procinfo = &proc4430_proc_info;
+ handle->proc_fxn_table.virt_to_phys = &proc4430_virt_to_phys;
+ handle->state = PROC_MGR_STATE_UNKNOWN;
+ handle->object = vmalloc(sizeof(struct proc4430_object));
+ handle->proc_id = proc_id;
+ object = (struct proc4430_object *)handle->object;
+ if (params != NULL) {
+ /* Copy params into instance object. */
+ memcpy(&(object->params), (void *)params,
+ sizeof(struct proc4430_params));
+ }
+ if ((params != NULL) && (params->mem_entries != NULL)
+ && (params->num_mem_entries > 0)) {
+ /* Allocate memory for, and copy mem_entries table*/
+ object->params.mem_entries = vmalloc(sizeof(struct
+ proc4430_mem_entry) *
+ params->num_mem_entries);
+ memcpy(object->params.mem_entries,
+ params->mem_entries,
+ (sizeof(struct proc4430_mem_entry) *
+ params->num_mem_entries));
+ }
+ handle->boot_mode = PROC_MGR_BOOTMODE_NOLOAD;
+ /* Set the handle in the state object. */
+ proc4430_state.proc_handles[proc_id] = handle;
+ }
+
+func_end:
+ mutex_unlock(proc4430_state.gate_handle);
+error:
+ return (void *)handle;
+}
+EXPORT_SYMBOL(proc4430_create);
+
+/*=================================================
+ * Function to delete an instance of this Processor.
+ *
+ * The user provided pointer to the handle is reset after
+ * successful completion of this function.
+ *
+ */
+int proc4430_delete(void **handle_ptr)
+{
+ int retval = 0;
+ struct proc4430_object *object = NULL;
+ struct processor_object *handle;
+
+ BUG_ON(handle_ptr == NULL);
+ BUG_ON(*handle_ptr == NULL);
+
+ if (atomic_cmpmask_and_lt(&proc4430_state.ref_count,
+ OMAP4430PROC_MAKE_MAGICSTAMP(0),
+ OMAP4430PROC_MAKE_MAGICSTAMP(1))
+ == true) {
+ printk(KERN_ERR "proc4430_delete failed "
+ "Module not initialized");
+ return -ENODEV;
+ }
+
+ handle = (struct processor_object *)(*handle_ptr);
+ BUG_ON(!IS_VALID_PROCID(handle->proc_id));
+ /* Enter critical section protection. */
+ WARN_ON(mutex_lock_interruptible(proc4430_state.gate_handle));
+ /* Reset handle in PwrMgr handle array. */
+ proc4430_state.proc_handles[handle->proc_id] = NULL;
+ /* Free memory used for the OMAP4430 object. */
+ if (handle->object != NULL) {
+ object = (struct proc4430_object *)handle->object;
+ if (object->params.mem_entries != NULL) {
+ vfree(object->params.mem_entries);
+ object->params.mem_entries = NULL;
+ }
+ vfree(handle->object);
+ handle->object = NULL;
+ }
+ /* Free memory used for the Processor object. */
+ vfree(handle);
+ *handle_ptr = NULL;
+ /* Leave critical section protection. */
+ mutex_unlock(proc4430_state.gate_handle);
+ return retval;
+}
+EXPORT_SYMBOL(proc4430_delete);
+
+/*===================================================
+ * Function to open a handle to an instance of this Processor. This
+ * function is called when access to the Processor is required from
+ * a different process.
+ */
+int proc4430_open(void **handle_ptr, u16 proc_id)
+{
+ int retval = 0;
+
+ BUG_ON(handle_ptr == NULL);
+ BUG_ON(!IS_VALID_PROCID(proc_id));
+
+ if (atomic_cmpmask_and_lt(&proc4430_state.ref_count,
+ OMAP4430PROC_MAKE_MAGICSTAMP(0),
+ OMAP4430PROC_MAKE_MAGICSTAMP(1))
+ == true) {
+ printk(KERN_ERR "proc4430_open failed "
+ "Module not initialized");
+ return -ENODEV;
+ }
+
+ /* Initialize return parameter handle. */
+ *handle_ptr = NULL;
+
+ /* Check if the PwrMgr exists and return the handle if found. */
+ if (proc4430_state.proc_handles[proc_id] == NULL) {
+ retval = -ENODEV;
+ goto func_exit;
+ } else
+ *handle_ptr = proc4430_state.proc_handles[proc_id];
+func_exit:
+ return retval;
+}
+EXPORT_SYMBOL(proc4430_open);
+
+/*===============================================
+ * Function to close a handle to an instance of this Processor.
+ *
+ */
+int proc4430_close(void *handle)
+{
+ int retval = 0;
+
+ BUG_ON(handle == NULL);
+
+ if (atomic_cmpmask_and_lt(&proc4430_state.ref_count,
+ OMAP4430PROC_MAKE_MAGICSTAMP(0),
+ OMAP4430PROC_MAKE_MAGICSTAMP(1))
+ == true) {
+ printk(KERN_ERR "proc4430_close failed "
+ "Module not initialized");
+ return -ENODEV;
+ }
+
+ /* nothing to be done for now */
+ return retval;
+}
+EXPORT_SYMBOL(proc4430_close);
+
+/* =================================
+ * APIs called by Processor module (part of function table interface)
+ * =================================
+ */
+/*================================
+ * Function to initialize the slave processor
+ *
+ */
+int proc4430_attach(void *handle, struct processor_attach_params *params)
+{
+ int retval = 0;
+
+ struct processor_object *proc_handle = NULL;
+ struct proc4430_object *object = NULL;
+ u32 map_count = 0;
+ u32 i;
+ memory_map_info map_info;
+
+ if (atomic_cmpmask_and_lt(&proc4430_state.ref_count,
+ OMAP4430PROC_MAKE_MAGICSTAMP(0),
+ OMAP4430PROC_MAKE_MAGICSTAMP(1))
+ == true) {
+ printk(KERN_ERR "proc4430_attach failed"
+ "Module not initialized");
+ return -ENODEV;
+ }
+
+ if (WARN_ON(handle == NULL)) {
+ printk(KERN_ERR "proc4430_attach failed"
+ "Driver handle is NULL");
+ return -EINVAL;
+ }
+
+ if (WARN_ON(params == NULL)) {
+ printk(KERN_ERR "proc4430_attach failed"
+ "Argument processor_attach_params * is NULL");
+ return -EINVAL;
+ }
+
+ proc_handle = (struct processor_object *)handle;
+
+ object = (struct proc4430_object *)proc_handle->object;
+ /* Return memory information in params. */
+ for (i = 0; (i < object->params.num_mem_entries); i++) {
+ /* If the configured master virtual address is invalid, get the
+ * actual address by mapping the physical address into master
+ * kernel memory space.
+ */
+ if ((object->params.mem_entries[i].master_virt_addr == (u32)-1)
+ && (object->params.mem_entries[i].shared == true)) {
+ map_info.src = object->params.mem_entries[i].phys_addr;
+ map_info.size = object->params.mem_entries[i].size;
+ map_info.is_cached = false;
+ retval = platform_mem_map(&map_info);
+ if (retval != 0) {
+ printk(KERN_ERR "proc4430_attach failed\n");
+ return -EFAULT;
+ }
+ map_count++;
+ object->params.mem_entries[i].master_virt_addr =
+ map_info.dst;
+ params->mem_entries[i].addr
+ [PROC_MGR_ADDRTYPE_MASTERKNLVIRT] =
+ map_info.dst;
+ params->mem_entries[i].addr
+ [PROC_MGR_ADDRTYPE_SLAVEVIRT] =
+ (object->params.mem_entries[i].slave_virt_addr);
+ /* User virtual will be filled by user side. For now,
+ fill in the physical address so that it can be used
+ by mmap to remap this region into user-space */
+ params->mem_entries[i].addr
+ [PROC_MGR_ADDRTYPE_MASTERUSRVIRT] = \
+ object->params.mem_entries[i].phys_addr;
+ params->mem_entries[i].size =
+ object->params.mem_entries[i].size;
+ }
+ }
+ params->num_mem_entries = map_count;
+ return retval;
+}
+
+
+/*==========================================
+ * Function to detach from the Processor.
+ *
+ */
+int proc4430_detach(void *handle)
+{
+ struct processor_object *proc_handle = NULL;
+ struct proc4430_object *object = NULL;
+ u32 i;
+ memory_unmap_info unmap_info;
+
+ if (atomic_cmpmask_and_lt(&proc4430_state.ref_count,
+ OMAP4430PROC_MAKE_MAGICSTAMP(0),
+ OMAP4430PROC_MAKE_MAGICSTAMP(1))
+ == true) {
+
+ printk(KERN_ERR "proc4430_detach failed "
+ "Module not initialized");
+ return -ENODEV;
+ }
+
+ if (WARN_ON(handle == NULL)) {
+ printk(KERN_ERR "proc4430_detach failed "
+ "Argument Driverhandle is NULL");
+ return -EINVAL;
+ }
+
+ proc_handle = (struct processor_object *)handle;
+ object = (struct proc4430_object *)proc_handle->object;
+ for (i = 0; (i < object->params.num_mem_entries); i++) {
+ if ((object->params.mem_entries[i].master_virt_addr > 0)
+ && (object->params.mem_entries[i].shared == true)) {
+ unmap_info.addr =
+ object->params.mem_entries[i].master_virt_addr;
+ unmap_info.size = object->params.mem_entries[i].size;
+ platform_mem_unmap(&unmap_info);
+ object->params.mem_entries[i].master_virt_addr =
+ (u32)-1;
+ }
+ }
+ return 0;
+}
+
+/*==========================================
+ * Function to start the slave processor
+ *
+ * Start the slave processor running from its entry point.
+ * Depending on the boot mode, this involves configuring the boot
+ * address and releasing the slave from reset.
+ *
+ */
+int proc4430_start(void *handle, u32 entry_pt,
+ struct processor_start_params *start_params)
+{
+ u32 reg;
+ int counter = 10;
+ if (atomic_cmpmask_and_lt(&proc4430_state.ref_count,
+ OMAP4430PROC_MAKE_MAGICSTAMP(0),
+ OMAP4430PROC_MAKE_MAGICSTAMP(1))
+ == true) {
+
+ printk(KERN_ERR "proc4430_start failed "
+ "Module not initialized");
+ return -ENODEV;
+ }
+
+ /*FIXME: Remove handle and entry_pt if not used */
+ if (WARN_ON(start_params == NULL)) {
+ printk(KERN_ERR "proc4430_start failed "
+ "Argument processor_start_params * is NULL");
+ return -EINVAL;
+ }
+ switch (start_params->params->proc_id) {
+ case SYS_M3:
+ /* Module is managed automatically by HW */
+ __raw_writel(0x01, CORE_CM2_DUCATI_CLKCTRL);
+ /* Enable the M3 clock */
+ __raw_writel(0x02, CORE_CM2_DUCATI_CLKSTCTRL);
+ do {
+ reg = __raw_readl(CORE_CM2_DUCATI_CLKSTCTRL);
+ if (reg & 0x100) {
+ printk(KERN_INFO "M3 clock enabled:"
+ "CORE_CM2_DUCATI_CLKSTCTRL = 0x%x\n", reg);
+ break;
+ }
+ msleep(1);
+ } while (--counter);
+ if (counter == 0) {
+ printk(KERN_ERR "FAILED TO ENABLE DUCATI M3 CLOCK !\n");
+ return -EFAULT;
+ }
+ /* De-assert RST 3 */
+ __raw_writel(0x3, CORE_PRM_BASE + RM_MPU_M3_RSTCTRL_OFFSET);
+ ducati_setup();
+ printk(KERN_INFO "De-assert RST1\n");
+ __raw_writel(0x2, CORE_PRM_BASE + RM_MPU_M3_RSTCTRL_OFFSET);
+ return 0;
+ break;
+ case APP_M3:
+ __raw_writel(0x0, CORE_PRM_BASE + RM_MPU_M3_RSTCTRL_OFFSET);
+ printk(KERN_INFO "De-assert RST2\n");
+ break;
+ default:
+ printk(KERN_ERR "proc4430_start: ERROR input\n");
+ break;
+ }
+ return 0;
+}
+
+
+/*
+ * Function to stop the slave processor
+ *
+ * Stop the execution of the slave processor. Depending on the boot
+ * mode, this may result in placing the slave processor in reset.
+ *
+ * @param handle void * to the Processor instance
+ *
+ * @sa proc4430_start, OMAP3530_halResetCtrl
+ */
+int
+proc4430_stop(void *handle, struct processor_stop_params *stop_params)
+{
+ if (atomic_cmpmask_and_lt(&proc4430_state.ref_count,
+ OMAP4430PROC_MAKE_MAGICSTAMP(0),
+ OMAP4430PROC_MAKE_MAGICSTAMP(1))
+ == true) {
+ printk(KERN_ERR "proc4430_stop failed "
+ "Module not initialized");
+ return -ENODEV;
+ }
+ switch (stop_params->params->proc_id) {
+ case SYS_M3:
+ ducati_destroy();
+ printk(KERN_INFO "Assert RST1 and RST2 and RST3\n");
+ __raw_writel(0x7, CORE_PRM_BASE + RM_MPU_M3_RSTCTRL_OFFSET);
+ /* Disable the M3 clock */
+ __raw_writel(0x01, CORE_CM2_DUCATI_CLKSTCTRL);
+ break;
+ case APP_M3:
+ printk(KERN_INFO "Assert RST2\n");
+ __raw_writel(0x2, CORE_PRM_BASE + RM_MPU_M3_RSTCTRL_OFFSET);
+ break;
+ default:
+ printk(KERN_ERR "proc4430_stop: ERROR input\n");
+ break;
+ }
+ return 0;
+}
+
+
+/*==============================================
+ * Function to read from the slave processor's memory.
+ *
+ * Read from the slave processor's memory and copy into the
+ * provided buffer.
+ */
+int proc4430_read(void *handle, u32 proc_addr, u32 *num_bytes,
+ void *buffer)
+{
+ int retval = 0;
+ if (atomic_cmpmask_and_lt(&proc4430_state.ref_count,
+ OMAP4430PROC_MAKE_MAGICSTAMP(0),
+ OMAP4430PROC_MAKE_MAGICSTAMP(1))
+ == true) {
+ printk(KERN_ERR "proc4430_read failed "
+ "Module not initialized");
+ return -ENODEV;
+ }
+
+ /* TODO */
+ return retval;
+}
+
+
+/*==============================================
+ * Function to write into the slave processor's memory.
+ *
+ * Read from the provided buffer and copy into the slave
+ * processor's memory.
+ *
+ */
+int proc4430_write(void *handle, u32 proc_addr, u32 *num_bytes,
+ void *buffer)
+{
+ int retval = 0;
+
+ if (atomic_cmpmask_and_lt(&proc4430_state.ref_count,
+ OMAP4430PROC_MAKE_MAGICSTAMP(0),
+ OMAP4430PROC_MAKE_MAGICSTAMP(1))
+ == true) {
+ printk(KERN_ERR "proc4430_write failed "
+ "Module not initialized");
+ return -ENODEV;
+ }
+
+ /* TODO */
+ return retval;
+}
+
+
+/*=========================================================
+ * Function to perform device-dependent operations.
+ *
+ * Performs device-dependent control operations as exposed by this
+ * implementation of the Processor module.
+ */
+int proc4430_control(void *handle, int cmd, void *arg)
+{
+ int retval = 0;
+
+ /*FIXME: Remove handle,etc if not used */
+
+ if (atomic_cmpmask_and_lt(&proc4430_state.ref_count,
+ OMAP4430PROC_MAKE_MAGICSTAMP(0),
+ OMAP4430PROC_MAKE_MAGICSTAMP(1))
+ == true) {
+ printk(KERN_ERR "proc4430_control failed "
+ "Module not initialized");
+ return -ENODEV;
+ }
+
+ return retval;
+}
+
+
+/*=====================================================
+ * Function to translate between two types of address spaces.
+ *
+ * Translate between the specified address spaces.
+ */
+int proc4430_translate_addr(void *handle,
+ void **dst_addr, enum proc_mgr_addr_type dst_addr_type,
+ void *src_addr, enum proc_mgr_addr_type src_addr_type)
+{
+ int retval = 0;
+ struct processor_object *proc_handle = NULL;
+ struct proc4430_object *object = NULL;
+ struct proc4430_mem_entry *entry = NULL;
+ bool found = false;
+ u32 fm_addr_base = (u32)NULL;
+ u32 to_addr_base = (u32)NULL;
+ u32 i;
+
+ if (atomic_cmpmask_and_lt(&proc4430_state.ref_count,
+ OMAP4430PROC_MAKE_MAGICSTAMP(0),
+ OMAP4430PROC_MAKE_MAGICSTAMP(1))
+ == true) {
+ printk(KERN_ERR "proc4430_translate_addr failed "
+ "Module not initialized");
+ retval = -ENODEV;
+ goto error_exit;
+ }
+
+ if (WARN_ON(handle == NULL)) {
+ retval = -EINVAL;
+ goto error_exit;
+ }
+ if (WARN_ON(dst_addr == NULL)) {
+ retval = -EINVAL;
+ goto error_exit;
+ }
+ if (WARN_ON(dst_addr_type > PROC_MGR_ADDRTYPE_ENDVALUE)) {
+ retval = -EINVAL;
+ goto error_exit;
+ }
+ if (WARN_ON(src_addr == NULL)) {
+ retval = -EINVAL;
+ goto error_exit;
+ }
+ if (WARN_ON(src_addr_type > PROC_MGR_ADDRTYPE_ENDVALUE)) {
+ retval = -EINVAL;
+ goto error_exit;
+ }
+
+ proc_handle = (struct processor_object *)handle;
+ object = (struct proc4430_object *)proc_handle->object;
+ *dst_addr = NULL;
+ for (i = 0 ; i < object->params.num_mem_entries ; i++) {
+ entry = &(object->params.mem_entries[i]);
+ fm_addr_base =
+ (src_addr_type == PROC_MGR_ADDRTYPE_MASTERKNLVIRT) ?
+ entry->master_virt_addr : entry->slave_virt_addr;
+ to_addr_base =
+ (dst_addr_type == PROC_MGR_ADDRTYPE_MASTERKNLVIRT) ?
+ entry->master_virt_addr : entry->slave_virt_addr;
+ /* Determine whether which way to convert */
+ if (((u32)src_addr < (fm_addr_base + entry->size)) &&
+ ((u32)src_addr >= fm_addr_base)) {
+ found = true;
+ *dst_addr = (void *)(((u32)src_addr - fm_addr_base)
+ + to_addr_base);
+ break;
+ }
+ }
+
+ /* This check must not be removed even with build optimize. */
+ if (WARN_ON(found == false)) {
+ /*Failed to translate address. */
+ retval = -ENXIO;
+ goto error_exit;
+ }
+ return 0;
+
+error_exit:
+ return retval;
+}
+
+
+/*=================================================
+ * Function to map slave address to host address space
+ *
+ * Map the provided slave address to master address space. This
+ * function also maps the specified address to slave MMU space.
+ */
+int proc4430_map(void *handle, u32 proc_addr,
+ u32 size, u32 *mapped_addr, u32 *mapped_size, u32 map_attribs)
+{
+ int retval = 0;
+ u32 da_align;
+ u32 da;
+ u32 va_align;
+ u32 size_align;
+
+ if (atomic_cmpmask_and_lt(&proc4430_state.ref_count,
+ OMAP4430PROC_MAKE_MAGICSTAMP(0),
+ OMAP4430PROC_MAKE_MAGICSTAMP(1))
+ == true) {
+ printk(KERN_ERR "proc4430_map failed "
+ "Module not initialized");
+ retval = -ENODEV;
+ goto error_exit;
+ }
+
+ /*FIXME: Remove handle,etc if not used */
+
+ /* FIX ME: Temporary work around until the dynamic memory mapping
+ * for Tiler address space is available
+ */
+ if ((map_attribs & DSP_MAPTILERADDR)) {
+ da_align = user_va2pa(current->mm, proc_addr);
+ *mapped_addr = (da_align | (proc_addr & (PAGE_SIZE - 1)));
+ printk(KERN_INFO "proc4430_map -tiler: user_va2pa: mapped_addr"
+ "= 0x%x\n", *mapped_addr);
+ return 0;
+ }
+
+ /* Calculate the page-aligned PA, VA and size */
+ va_align = PG_ALIGN_LOW(proc_addr, PAGE_SIZE);
+ size_align = PG_ALIGN_HIGH(size + (u32)proc_addr - va_align, PAGE_SIZE);
+
+ dmm_reserve_memory(size_align, &da);
+ da_align = PG_ALIGN_LOW((u32)da, PAGE_SIZE);
+ retval = ducati_mem_map(va_align, da_align, size_align, map_attribs);
+
+ /* Mapped address = MSB of DA | LSB of VA */
+ *mapped_addr = (da_align | (proc_addr & (PAGE_SIZE - 1)));
+
+error_exit:
+ return retval;
+}
+
+/*=================================================
+ * Function to unmap slave address to host address space
+ *
+ * UnMap the provided slave address to master address space. This
+ * function also unmaps the specified address to slave MMU space.
+ */
+int proc4430_unmap(void *handle, u32 mapped_addr)
+{
+ int da_align;
+ int ret_val = 0;
+ int size_align;
+
+ if (atomic_cmpmask_and_lt(&proc4430_state.ref_count,
+ OMAP4430PROC_MAKE_MAGICSTAMP(0),
+ OMAP4430PROC_MAKE_MAGICSTAMP(1))
+ == true) {
+ printk(KERN_ERR "proc4430_map failed "
+ "Module not initialized");
+ ret_val = -1;
+ goto error_exit;
+ }
+
+ /*FIXME: Remove handle,etc if not used */
+
+ da_align = PG_ALIGN_LOW((u32)mapped_addr, PAGE_SIZE);
+ ret_val = dmm_unreserve_memory(da_align, &size_align);
+ if (WARN_ON(ret_val < 0))
+ goto error_exit;
+ ret_val = ducati_mem_unmap(da_align, size_align);
+ if (WARN_ON(ret_val < 0))
+ goto error_exit;
+ return 0;
+
+error_exit:
+ printk(KERN_WARNING "proc4430_unmap failed !!!!\n");
+ return ret_val;
+}
+
+/*=================================================
+ * Function to return list of translated mem entries
+ *
+ * This function takes the remote processor address as
+ * an input and returns the mapped Page entries in the
+ * buffer passed
+ */
+int proc4430_virt_to_phys(void *handle, u32 da, u32 *mapped_entries,
+ u32 num_of_entries)
+{
+ int da_align;
+ int i;
+ int ret_val = 0;
+
+ if (atomic_cmpmask_and_lt(&proc4430_state.ref_count,
+ OMAP4430PROC_MAKE_MAGICSTAMP(0),
+ OMAP4430PROC_MAKE_MAGICSTAMP(1))
+ == true) {
+ printk(KERN_ERR "proc4430_virt_to_phys failed "
+ "Module not initialized");
+ ret_val = -EFAULT;
+ goto error_exit;
+ }
+
+ if (handle == NULL || mapped_entries == NULL || num_of_entries == 0) {
+ ret_val = -EFAULT;
+ goto error_exit;
+ }
+ da_align = PG_ALIGN_LOW((u32)da, PAGE_SIZE);
+ for (i = 0; i < num_of_entries; i++) {
+ mapped_entries[i] = ducati_mem_virtToPhys(da_align);
+ da_align += PAGE_SIZE;
+ }
+ return 0;
+
+error_exit:
+ printk(KERN_WARNING "proc4430_virtToPhys failed !!!!\n");
+ return ret_val;
+}
+
+
+/*=================================================
+ * Function to return PROC4430 mem_entries info
+ *
+ */
+int proc4430_proc_info(void *handle, struct proc_mgr_proc_info *procinfo)
+{
+ struct processor_object *proc_handle = NULL;
+ struct proc4430_object *object = NULL;
+ struct proc4430_mem_entry *entry = NULL;
+ int i;
+
+ if (atomic_cmpmask_and_lt(&proc4430_state.ref_count,
+ OMAP4430PROC_MAKE_MAGICSTAMP(0),
+ OMAP4430PROC_MAKE_MAGICSTAMP(1))
+ == true) {
+ printk(KERN_ERR "proc4430_proc_info failed "
+ "Module not initialized");
+ goto error_exit;
+ }
+
+ if (WARN_ON(handle == NULL))
+ goto error_exit;
+ if (WARN_ON(procinfo == NULL))
+ goto error_exit;
+
+ proc_handle = (struct processor_object *)handle;
+
+ object = (struct proc4430_object *)proc_handle->object;
+
+ for (i = 0 ; i < object->params.num_mem_entries ; i++) {
+ entry = &(object->params.mem_entries[i]);
+ procinfo->mem_entries[i].addr[PROC_MGR_ADDRTYPE_MASTERKNLVIRT]
+ = entry->master_virt_addr;
+ procinfo->mem_entries[i].addr[PROC_MGR_ADDRTYPE_SLAVEVIRT]
+ = entry->slave_virt_addr;
+ procinfo->mem_entries[i].size = entry->size;
+ }
+ procinfo->num_mem_entries = object->params.num_mem_entries;
+ procinfo->boot_mode = proc_handle->boot_mode;
+ return 0;
+
+error_exit:
+ printk(KERN_WARNING "proc4430_proc_info failed !!!!\n");
+ return -EFAULT;
+}
diff --git a/drivers/dsp/syslink/procmgr/proc4430/proc4430.h b/drivers/dsp/syslink/procmgr/proc4430/proc4430.h
new file mode 100755
index 000000000000..5903daeadaa3
--- /dev/null
+++ b/drivers/dsp/syslink/procmgr/proc4430/proc4430.h
@@ -0,0 +1,147 @@
+/*
+ * proc4430.h
+ *
+ * Syslink driver support functions for TI OMAP processors.
+ *
+ * Copyright (C) 2009-2010 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+
+
+
+#ifndef _SYSLINK_PROC_4430_H_
+#define _SYSLINK_PROC_4430_H_
+
+
+/* Module headers */
+#include <procmgr.h>
+#include "../procdefs.h"
+#include <linux/types.h>
+
+/*
+ Module configuration structure.
+ */
+struct proc4430_config {
+ struct mutex *gate_handle;
+ /* void * of gate to be used for local thread safety */
+};
+
+/*
+ Memory entry for slave memory map configuration
+ */
+struct proc4430_mem_entry {
+ char name[PROCMGR_MAX_STRLEN];
+ /* Name identifying the memory region. */
+ u32 phys_addr;
+ /* Physical address of the memory region. */
+ u32 slave_virt_addr;
+ /* Slave virtual address of the memory region. */
+ u32 master_virt_addr;
+ /* Master virtual address of the memory region. If specified as -1,
+ * the master virtual address is assumed to be invalid, and shall be
+ * set internally within the Processor module. */
+ u32 size;
+ /* Size (in bytes) of the memory region. */
+ bool shared;
+ /* Flag indicating whether the memory region is shared between master
+ * and slave. */
+};
+
+/*
+ Configuration parameters specific to this processor.
+ */
+struct proc4430_params {
+ int num_mem_entries;
+ /* Number of memory regions to be configured. */
+ struct proc4430_mem_entry *mem_entries;
+ /* Array of information structures for memory regions
+ * to be configured. */
+ u32 reset_vector_mem_entry;
+ /* Index of the memory entry within the mem_entries array,
+ * which is the resetVector memory region. */
+};
+
+
+/* Function to initialize the slave processor */
+int proc4430_attach(void *handle, struct processor_attach_params *params);
+
+/* Function to finalize the slave processor */
+int proc4430_detach(void *handle);
+
+/* Function to start the slave processor */
+int proc4430_start(void *handle, u32 entry_pt,
+ struct processor_start_params *params);
+
+/* Function to start the stop processor */
+int proc4430_stop(void *handle,
+ struct processor_stop_params *params);
+
+/* Function to read from the slave processor's memory. */
+int proc4430_read(void *handle, u32 proc_addr, u32 *num_bytes,
+ void *buffer);
+
+/* Function to write into the slave processor's memory. */
+int proc4430_write(void *handle, u32 proc_addr, u32 *num_bytes,
+ void *buffer);
+
+/* Function to perform device-dependent operations. */
+int proc4430_control(void *handle, int cmd, void *arg);
+
+/* Function to translate between two types of address spaces. */
+int proc4430_translate_addr(void *handle, void **dst_addr,
+ enum proc_mgr_addr_type dst_addr_type,
+ void *src_addr, enum proc_mgr_addr_type src_addr_type);
+
+/* Function to map slave address to host address space */
+int proc4430_map(void *handle, u32 proc_addr, u32 size, u32 *mapped_addr,
+ u32 *mapped_size, u32 map_attribs);
+
+/* Function to unmap the slave address to host address space */
+int proc4430_unmap(void *handle, u32 mapped_addr);
+
+/* Function to retrive physical address translations */
+int proc4430_virt_to_phys(void *handle, u32 da, u32 *mapped_entries,
+ u32 num_of_entries);
+
+/* =================================================
+ * APIs
+ * =================================================
+ */
+
+/* Function to get the default configuration for the OMAP4430PROC module */
+void proc4430_get_config(struct proc4430_config *cfg);
+
+/* Function to setup the OMAP4430PROC module. */
+int proc4430_setup(struct proc4430_config *cfg);
+
+/* Function to destroy the OMAP4430PROC module. */
+int proc4430_destroy(void);
+
+/* Function to initialize the parameters for this processor instance. */
+void proc4430_params_init(void *handle,
+ struct proc4430_params *params);
+
+/* Function to create an instance of this processor. */
+void *proc4430_create(u16 proc_id, const struct proc4430_params *params);
+
+/* Function to delete an instance of this processor. */
+int proc4430_delete(void **handle_ptr);
+
+/* Function to open an instance of this processor. */
+int proc4430_open(void **handle_ptr, u16 proc_id);
+
+/* Function to close an instance of this processor. */
+int proc4430_close(void *handle);
+
+/* Function to get the proc info */
+int proc4430_proc_info(void *handle, struct proc_mgr_proc_info *procinfo);
+
+#endif
diff --git a/drivers/dsp/syslink/procmgr/proc4430/proc4430_drv.c b/drivers/dsp/syslink/procmgr/proc4430/proc4430_drv.c
new file mode 100755
index 000000000000..92fc35b9e684
--- /dev/null
+++ b/drivers/dsp/syslink/procmgr/proc4430/proc4430_drv.c
@@ -0,0 +1,400 @@
+/*
+ * proc4430_drv.c
+ *
+ * Syslink driver support functions for TI OMAP processors.
+ *
+ * Copyright (C) 2009-2010 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include <linux/autoconf.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/cdev.h>
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/vmalloc.h>
+#include <linux/uaccess.h>
+#include <linux/platform_device.h>
+
+
+/* Module headers */
+#include "proc4430.h"
+#include "proc4430_drvdefs.h"
+
+
+
+/** ============================================================================
+ * Macros and types
+ * ============================================================================
+ */
+#define PROC4430_NAME "syslink-proc4430"
+
+static char *driver_name = PROC4430_NAME;
+
+static s32 driver_major;
+
+static s32 driver_minor;
+
+struct proc_4430_dev {
+ struct cdev cdev;
+};
+
+static struct proc_4430_dev *proc_4430_device;
+
+static struct class *proc_4430_class;
+
+
+
+/** ============================================================================
+ * Forward declarations of internal functions
+ * ============================================================================
+ */
+/* Linux driver function to open the driver object. */
+static int proc4430_drv_open(struct inode *inode, struct file *filp);
+
+/* Linux driver function to close the driver object. */
+static int proc4430_drv_release(struct inode *inode, struct file *filp);
+
+/* Linux driver function to invoke the APIs through ioctl. */
+static int proc4430_drv_ioctl(struct inode *inode,
+ struct file *filp, unsigned int cmd,
+ unsigned long args);
+
+/* Linux driver function to map memory regions to user space. */
+static int proc4430_drv_mmap(struct file *filp,
+ struct vm_area_struct *vma);
+
+/* Module initialization function for Linux driver. */
+static int __init proc4430_drv_initializeModule(void);
+
+/* Module finalization function for Linux driver. */
+static void __exit proc4430_drv_finalizeModule(void);
+
+
+
+/** ============================================================================
+ * Globals
+ * ============================================================================
+ */
+
+/*
+ File operations table for PROC4430.
+ */
+static const struct file_operations proc_4430_fops = {
+ .open = proc4430_drv_open,
+ .release = proc4430_drv_release,
+ .ioctl = proc4430_drv_ioctl,
+ .mmap = proc4430_drv_mmap,
+};
+
+static int proc4430_drv_open(struct inode *inode, struct file *filp)
+{
+ return 0;
+}
+
+static int proc4430_drv_release(struct inode *inode, struct file *filp)
+{
+ return 0;
+}
+
+
+/*
+ Linux driver function to invoke the APIs through ioctl.
+ *
+ */
+static int proc4430_drv_ioctl(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long args)
+{
+ int retval = 0;
+ struct proc_mgr_cmd_args *cmd_args = (struct proc_mgr_cmd_args *)args;
+ struct proc_mgr_cmd_args command_args;
+
+ switch (cmd) {
+ case CMD_PROC4430_GETCONFIG:
+ {
+ struct proc4430_cmd_args_get_config *src_args =
+ (struct proc4430_cmd_args_get_config *)args;
+ struct proc4430_config cfg;
+
+ /* copy_from_useris not needed for
+ * proc4430_get_config, since the
+ * user's config is not used.
+ */
+ proc4430_get_config(&cfg);
+
+ retval = copy_to_user((void *)(src_args->cfg),
+ (const void *)&cfg,
+ sizeof(struct proc4430_config));
+ if (WARN_ON(retval < 0))
+ goto func_exit;
+ }
+ break;
+
+ case CMD_PROC4430_SETUP:
+ {
+ struct proc4430_cmd_args_setup *src_args =
+ (struct proc4430_cmd_args_setup *)args;
+ struct proc4430_config cfg;
+
+ retval = copy_from_user((void *)&cfg,
+ (const void *)(src_args->cfg),
+ sizeof(struct proc4430_config));
+ if (WARN_ON(retval < 0))
+ goto func_exit;
+ proc4430_setup(&cfg);
+ }
+ break;
+
+ case CMD_PROC4430_DESTROY:
+ {
+ proc4430_destroy();
+ }
+ break;
+
+ case CMD_PROC4430_PARAMS_INIT:
+ {
+ struct proc4430_cmd_args_params_init src_args;
+ struct proc4430_params params;
+
+ /* Copy the full args from user-side. */
+ retval = copy_from_user((void *)&src_args,
+ (const void *)(args),
+ sizeof(struct proc4430_cmd_args_params_init));
+ if (WARN_ON(retval < 0))
+ goto func_exit;
+ proc4430_params_init(src_args.handle, &params);
+ retval = copy_to_user((void *)(src_args.params),
+ (const void *) &params,
+ sizeof(struct proc4430_params));
+ if (WARN_ON(retval < 0))
+ goto func_exit;
+ }
+ break;
+
+ case CMD_PROC4430_CREATE:
+ {
+ struct proc4430_cmd_args_create src_args;
+ struct proc4430_params params;
+ struct proc4430_mem_entry *entries = NULL;
+
+ /* Copy the full args from user-side. */
+ retval = copy_from_user((void *)&src_args,
+ (const void *)(args),
+ sizeof(struct proc4430_cmd_args_create));
+ if (WARN_ON(retval < 0))
+ goto func_exit;
+ retval = copy_from_user((void *) &params,
+ (const void *)(src_args.params),
+ sizeof(struct proc4430_params));
+ if (WARN_ON(retval < 0))
+ goto func_exit;
+ /* Copy the contents of mem_entries from user-side */
+ if (params.num_mem_entries) {
+ entries = vmalloc(params.num_mem_entries * \
+ sizeof(struct proc4430_mem_entry));
+ if (WARN_ON(!entries))
+ goto func_exit;
+ retval = copy_from_user((void *) (entries),
+ (const void *)(params.mem_entries),
+ params.num_mem_entries * \
+ sizeof(struct proc4430_mem_entry));
+ if (WARN_ON(retval < 0)) {
+ vfree(entries);
+ goto func_exit;
+ }
+ params.mem_entries = entries;
+ }
+ src_args.handle = proc4430_create(src_args.proc_id,
+ &params);
+ if (WARN_ON(src_args.handle == NULL))
+ goto func_exit;
+ retval = copy_to_user((void *)(args),
+ (const void *)&src_args,
+ sizeof(struct proc4430_cmd_args_create));
+ /* Free the memory created */
+ if (params.num_mem_entries)
+ vfree(entries);
+ }
+ break;
+
+ case CMD_PROC4430_DELETE:
+ {
+ struct proc4430_cmd_args_delete src_args;
+
+ /* Copy the full args from user-side. */
+ retval = copy_from_user((void *)&src_args,
+ (const void *)(args),
+ sizeof(struct proc4430_cmd_args_delete));
+ if (WARN_ON(retval < 0))
+ goto func_exit;
+ retval = proc4430_delete(&(src_args.handle));
+ WARN_ON(retval < 0);
+ }
+ break;
+
+ case CMD_PROC4430_OPEN:
+ {
+ struct proc4430_cmd_args_open src_args;
+
+ /*Copy the full args from user-side. */
+ retval = copy_from_user((void *)&src_args,
+ (const void *)(args),
+ sizeof(struct proc4430_cmd_args_open));
+ if (WARN_ON(retval < 0))
+ goto func_exit;
+ retval = proc4430_open(&(src_args.handle),
+ src_args.proc_id);
+ retval = copy_to_user((void *)(args),
+ (const void *)&src_args,
+ sizeof(struct proc4430_cmd_args_open));
+ WARN_ON(retval < 0);
+ }
+ break;
+
+ case CMD_PROC4430_CLOSE:
+ {
+ struct proc4430_cmd_args_close src_args;
+
+ /*Copy the full args from user-side. */
+ retval = copy_from_user((void *)&src_args,
+ (const void *)(args),
+ sizeof(struct proc4430_cmd_args_close));
+ if (WARN_ON(retval < 0))
+ goto func_exit;
+ retval = proc4430_close(src_args.handle);
+ WARN_ON(retval < 0);
+ }
+ break;
+
+ default:
+ {
+ printk(KERN_ERR "unsupported ioctl\n");
+ }
+ break;
+ }
+func_exit:
+ /* Set the status and copy the common args to user-side. */
+ command_args.api_status = retval;
+ retval = copy_to_user((void *) cmd_args,
+ (const void *) &command_args,
+ sizeof(struct proc_mgr_cmd_args));
+ WARN_ON(retval < 0);
+ return retval;
+}
+
+
+/*
+ Linux driver function to map memory regions to user space.
+ *
+ */
+static int proc4430_drv_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+ if (remap_pfn_range(vma,
+ vma->vm_start,
+ vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot)) {
+ return -EAGAIN;
+ }
+ return 0;
+}
+
+
+/** ==================================================================
+ * Functions required for multiple .ko modules configuration
+ * ==================================================================
+ */
+/*
+ Module initialization function for Linux driver.
+ */
+static int __init proc4430_drv_initializeModule(void)
+{
+ dev_t dev = 0 ;
+ int retval;
+
+ /* Display the version info and created date/time */
+ printk(KERN_INFO "proc4430_drv_initializeModule\n");
+
+ if (driver_major) {
+ dev = MKDEV(driver_major, driver_minor);
+ retval = register_chrdev_region(dev, 1, driver_name);
+ } else {
+ retval = alloc_chrdev_region(&dev, driver_minor, 1,
+ driver_name);
+ driver_major = MAJOR(dev);
+ }
+
+ proc_4430_device = kmalloc(sizeof(struct proc_4430_dev), GFP_KERNEL);
+ if (!proc_4430_device) {
+ retval = -ENOMEM;
+ unregister_chrdev_region(dev, 1);
+ goto exit;
+ }
+ memset(proc_4430_device, 0, sizeof(struct proc_4430_dev));
+ cdev_init(&proc_4430_device->cdev, &proc_4430_fops);
+ proc_4430_device->cdev.owner = THIS_MODULE;
+ proc_4430_device->cdev.ops = &proc_4430_fops;
+
+ retval = cdev_add(&proc_4430_device->cdev, dev, 1);
+
+ if (retval) {
+ printk(KERN_ERR "Failed to add the syslink proc_4430 device \n");
+ goto exit;
+ }
+
+ /* udev support */
+ proc_4430_class = class_create(THIS_MODULE, "syslink-proc4430");
+
+ if (IS_ERR(proc_4430_class)) {
+ printk(KERN_ERR "Error creating bridge class \n");
+ goto exit;
+ }
+ device_create(proc_4430_class, NULL, MKDEV(driver_major, driver_minor),
+ NULL, PROC4430_NAME);
+exit:
+ return 0;
+}
+
+/*
+ function to finalize the driver module.
+ */
+static void __exit proc4430_drv_finalizeModule(void)
+{
+ dev_t devno = 0;
+
+ /* FIX ME: THIS MIGHT NOT BE THE RIGHT PLACE TO CALL THE SETUP */
+ proc4430_destroy();
+
+ devno = MKDEV(driver_major, driver_minor);
+ if (proc_4430_device) {
+ cdev_del(&proc_4430_device->cdev);
+ kfree(proc_4430_device);
+ }
+ unregister_chrdev_region(devno, 1);
+ if (proc_4430_class) {
+ /* remove the device from sysfs */
+ device_destroy(proc_4430_class, MKDEV(driver_major,
+ driver_minor));
+ class_destroy(proc_4430_class);
+ }
+ return;
+}
+
+/*
+ Macro calls that indicate initialization and finalization functions
+ * to the kernel.
+ */
+MODULE_LICENSE("GPL v2");
+module_init(proc4430_drv_initializeModule);
+module_exit(proc4430_drv_finalizeModule);
diff --git a/drivers/dsp/syslink/procmgr/proc4430/proc4430_drvdefs.h b/drivers/dsp/syslink/procmgr/proc4430/proc4430_drvdefs.h
new file mode 100755
index 000000000000..4176d731f1d4
--- /dev/null
+++ b/drivers/dsp/syslink/procmgr/proc4430/proc4430_drvdefs.h
@@ -0,0 +1,169 @@
+/*
+ * proc4430_drvdefs.h
+ *
+ * Syslink driver support functions for TI OMAP processors.
+ *
+ * Copyright (C) 2009-2010 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+
+#ifndef _SYSLINK_PROC4430_H
+#define _SYSLINK_PROC4430_H
+
+
+/* Module headers */
+#include "../procmgr_drvdefs.h"
+#include "proc4430.h"
+
+
+/* ----------------------------------------------------------------------------
+ * IOCTL command IDs for OMAP4430PROC
+ * ----------------------------------------------------------------------------
+ */
+/*
+ * Base command ID for OMAP4430PROC
+ */
+#define PROC4430_BASE_CMD 0x200
+
+/*
+ * Command for PROC4430_getConfig
+ */
+#define CMD_PROC4430_GETCONFIG (PROC4430_BASE_CMD + 1)
+
+/*
+ * Command for PROC4430_setup
+ */
+#define CMD_PROC4430_SETUP (PROC4430_BASE_CMD + 2)
+
+/*
+ * Command for PROC4430_setup
+ */
+#define CMD_PROC4430_DESTROY (PROC4430_BASE_CMD + 3)
+
+/*
+ * Command for PROC4430_destroy
+ */
+#define CMD_PROC4430_PARAMS_INIT (PROC4430_BASE_CMD + 4)
+
+/*
+ * Command for PROC4430_create
+ */
+#define CMD_PROC4430_CREATE (PROC4430_BASE_CMD + 5)
+
+/*
+ * Command for PROC4430_delete
+ */
+#define CMD_PROC4430_DELETE (PROC4430_BASE_CMD + 6)
+
+/*
+ * Command for PROC4430_open
+ */
+#define CMD_PROC4430_OPEN (PROC4430_BASE_CMD + 7)
+
+/*
+ * Command for PROC4430_close
+ */
+#define CMD_PROC4430_CLOSE (PROC4430_BASE_CMD + 8)
+
+
+/* ---------------------------------------------------
+ * Command arguments for OMAP4430PROC
+ * ---------------------------------------------------
+ */
+/*
+ * Command arguments for PROC4430_getConfig
+ */
+struct proc4430_cmd_args_get_config {
+ struct proc_mgr_cmd_args command_args;
+ /* Common command args */
+ struct proc4430_config *cfg;
+ /* Pointer to the OMAP4430PROC module configuration structure
+ * in which the default config is to be returned. */
+};
+
+/*
+ * Command arguments for PROC4430_setup
+ */
+struct proc4430_cmd_args_setup {
+ struct proc_mgr_cmd_args command_args;
+ /* Common command args */
+ struct proc4430_config *cfg;
+ /* Optional OMAP4430PROC module configuration. If provided as NULL,
+ * default configuration is used. */
+};
+
+/*
+ * Command arguments for PROC4430_destroy
+ */
+struct proc4430_cmd_args_destroy {
+ struct proc_mgr_cmd_args command_args;
+ /* Common command args */
+};
+
+/*
+ * Command arguments for struct struct proc4430_params_init
+ */
+struct proc4430_cmd_args_params_init {
+ struct proc_mgr_cmd_args command_args;
+ /* Common command args */
+ void *handle;
+ /* void * to the processor instance. */
+ struct proc4430_params *params;
+ /* Configuration parameters. */
+};
+
+/*
+ * Command arguments for PROC4430_create
+ */
+struct proc4430_cmd_args_create {
+ struct proc_mgr_cmd_args command_args;
+ /* Common command args */
+ u16 proc_id;
+ /* Processor ID for which this processor instance is required. */
+ struct proc4430_params *params;
+ /*Configuration parameters. */
+ void *handle;
+ /* void * to the created processor instance. */
+};
+
+/*
+ * Command arguments for PROC4430_delete
+ */
+struct proc4430_cmd_args_delete {
+ struct proc_mgr_cmd_args command_args;
+ /* Common command args */
+ void *handle;
+ /* Pointer to handle to the processor instance */
+};
+
+/*
+ * Command arguments for PROC4430_open
+ */
+struct proc4430_cmd_args_open {
+ struct proc_mgr_cmd_args command_args;
+ /* Common command args */
+ u16 proc_id;
+ /* Processor ID addressed by this OMAP4430PROC instance. */
+ void *handle;
+ /* Return parameter: void * to the processor instance */
+};
+
+/*
+ * Command arguments for PROC4430_close
+ */
+struct proc4430_cmd_args_close {
+ struct proc_mgr_cmd_args command_args;
+ /* Common command args */
+ void *handle;
+ /* void * to the processor instance */
+};
+
+#endif
diff --git a/drivers/dsp/syslink/procmgr/procdefs.h b/drivers/dsp/syslink/procmgr/procdefs.h
new file mode 100755
index 000000000000..eb73626d27e1
--- /dev/null
+++ b/drivers/dsp/syslink/procmgr/procdefs.h
@@ -0,0 +1,203 @@
+/*
+ * procdefs.h
+ *
+ * Syslink driver support functions for TI OMAP processors.
+ *
+ * Copyright (C) 2009-2010 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef SYSLINK_PROCDEFS_H
+#define SYSLINK_PROCDEFS_H
+
+#include <linux/types.h>
+
+/* Module level headers */
+#include <procmgr.h>
+
+
+/* =============================
+ * Macros and types
+ * =============================
+ */
+/*
+ * Enumerates the types of Endianism of slave processor.
+ */
+enum processor_endian{
+ PROCESSOR_ENDIAN_DEFAULT = 0,
+ /* Default endianism (no conversion required) */
+ PROCESSOR_ENDIAN_BIG = 1,
+ /* Big endian */
+ PROCESSOR_ENDIAN_LITTLE = 2,
+ /* Little endian */
+ PROCESSOR_ENDIAN_ENDVALUE = 3
+ /* End delimiter indicating start of invalid values for this enum */
+};
+
+
+/*
+ * Configuration parameters for attaching to the slave Processor
+ */
+struct processor_attach_params {
+ struct proc_mgr_attach_params *params;
+ /* Common attach parameters for ProcMgr */
+ u16 num_mem_entries;
+ /* Number of valid memory entries */
+ struct proc_mgr_addr_info mem_entries[PROCMGR_MAX_MEMORY_REGIONS];
+ /* Configuration of memory regions */
+};
+
+/*
+ *Configuration parameters for starting the slave Processor
+ */
+struct processor_start_params {
+ struct proc_mgr_start_params *params;
+ /* Common start parameters for ProcMgr */
+};
+
+/*
+ *Configuration parameters for stopping the slave Processor
+ */
+struct processor_stop_params {
+ struct proc_mgr_stop_params *params;
+ /* Common start parameters for ProcMgr */
+};
+/*
+ * Function pointer type for the function to attach to the processor.
+ */
+typedef int (*processor_attach_fxn) (void *handle,
+ struct processor_attach_params *params);
+
+/*
+ * Function pointer type for the function to detach from the
+ * procssor
+ */
+typedef int (*processor_detach_fxn) (void *handle);
+
+/*
+ * Function pointer type for the function to start the processor.
+ */
+typedef int (*processor_start_fxn) (void *handle, u32 entry_pt,
+ struct processor_start_params *params);
+
+/*
+ *Function pointer type for the function to stop the processor.
+ */
+typedef int (*processor_stop_fxn) (void *handle,
+ struct processor_stop_params *params);
+
+/*
+ * Function pointer type for the function to read from the slave
+ * processor's memory.
+ */
+typedef int (*processor_read_fxn) (void *handle, u32 proc_addr,
+ u32 *num_bytes, void *buffer);
+
+/*
+ *Function pointer type for the function to write into the slave
+ *processor's memory.
+ */
+typedef int (*processor_write_fxn) (void *handle, u32 proc_addr,
+ u32 *num_bytes, void *buffer);
+
+/*
+ *Function pointer type for the function to perform device-dependent
+ * operations.
+ */
+typedef int (*processor_control_fxn) (void *handle, int cmd, void *arg);
+
+/*
+ *Function pointer type for the function to translate between
+ * two types of address spaces.
+ */
+typedef int (*processor_translate_addr_fxn) (void *handle, void **dst_addr,
+ enum proc_mgr_addr_type dstAddrType, void *srcAddr,
+ enum proc_mgr_addr_type srcAddrType);
+
+/*
+ *Function pointer type for the function to map address to slave
+ * address space
+ */
+typedef int (*processor_map_fxn) (void *handle, u32 proc_addr, u32 size,
+ u32 *mapped_addr, u32 *mapped_size, u32 map_attribs);
+
+/*
+ *Function pointer type for the function to map address to slave
+ * address space
+ */
+typedef int (*processor_unmap_fxn) (void *handle, u32 mapped_addr);
+
+/*
+ *Function pointer type for the function that returns proc info
+ */
+typedef int (*processor_proc_info) (void *handle,
+ struct proc_mgr_proc_info *proc_info);
+
+/*
+ *Function pointer type for the function that returns proc info
+ */
+typedef int (*processor_virt_to_phys_fxn) (void *handle, u32 da,
+ u32 *mapped_entries, u32 num_of_entries);
+
+
+/* =============================
+ * Function table interface
+ * =============================
+ */
+/*
+ *Function table interface for Processor.
+ */
+struct processor_fxn_table {
+ processor_attach_fxn attach;
+ /* Function to attach to the slave processor */
+ processor_detach_fxn detach;
+ /* Function to detach from the slave processor */
+ processor_start_fxn start;
+ /* Function to start the slave processor */
+ processor_stop_fxn stop;
+ /* Function to stop the slave processor */
+ processor_read_fxn read;
+ /* Function to read from the slave processor's memory */
+ processor_write_fxn write;
+ /* Function to write into the slave processor's memory */
+ processor_control_fxn control;
+ /* Function to perform device-dependent control function */
+ processor_translate_addr_fxn translateAddr;
+ /* Function to translate between address ranges */
+ processor_map_fxn map;
+ /* Function to map slave addresses to master address space */
+ processor_unmap_fxn unmap;
+ /* Function to unmap slave addresses to master address space */
+ processor_proc_info procinfo;
+ /* Function to convert Virtual to Physical pages */
+ processor_virt_to_phys_fxn virt_to_phys;
+};
+
+/* =============================
+ * Processor structure
+ * =============================
+ */
+/*
+ * Generic Processor object. This object defines the handle type for all
+ * Processor operations.
+ */
+struct processor_object {
+ struct processor_fxn_table proc_fxn_table;
+ /* interface function table to plug into the generic Processor. */
+ enum proc_mgr_state state;
+ /* State of the slave processor */
+ enum proc_mgr_boot_mode boot_mode;
+ /* Boot mode for the slave processor. */
+ void *object;
+ /* Pointer to Processor-specific object. */
+ u16 proc_id;
+ /* Processor ID addressed by this Processor instance. */
+};
+#endif
diff --git a/drivers/dsp/syslink/procmgr/processor.c b/drivers/dsp/syslink/procmgr/processor.c
new file mode 100755
index 000000000000..4548d12ad967
--- /dev/null
+++ b/drivers/dsp/syslink/procmgr/processor.c
@@ -0,0 +1,398 @@
+/*
+ * processor.c
+ *
+ * Syslink driver support functions for TI OMAP processors.
+ *
+ * Copyright (C) 2009-2010 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include <linux/types.h>
+#include <linux/module.h>
+
+/* Module level headers */
+#include "procdefs.h"
+#include "processor.h"
+
+
+
+/* =========================================
+ * Functions called by ProcMgr
+ * =========================================
+ */
+/*
+ * Function to attach to the Processor.
+ *
+ * This function calls into the specific Processor implementation
+ * to attach to it.
+ * This function is called from the ProcMgr attach function, and
+ * hence is used to perform any activities that may be required
+ * once the slave is powered up.
+ * Depending on the type of Processor, this function may or may not
+ * perform any activities.
+ */
+inline int processor_attach(void *handle,
+ struct processor_attach_params *params)
+{
+ int retval = 0;
+ struct processor_object *proc_handle =
+ (struct processor_object *)handle;
+
+ BUG_ON(handle == NULL);
+ BUG_ON(params == NULL);
+ BUG_ON(proc_handle->proc_fxn_table.attach == NULL);
+
+ proc_handle->boot_mode = params->params->boot_mode;
+ retval = proc_handle->proc_fxn_table.attach(handle, params);
+
+ if (proc_handle->boot_mode == PROC_MGR_BOOTMODE_BOOT)
+ proc_handle->state = PROC_MGR_STATE_POWERED;
+ else if (proc_handle->boot_mode == PROC_MGR_BOOTMODE_NOLOAD)
+ proc_handle->state = PROC_MGR_STATE_LOADED;
+ else if (proc_handle->boot_mode == PROC_MGR_BOOTMODE_NOBOOT)
+ proc_handle->state = PROC_MGR_STATE_RUNNNING;
+ return retval;
+}
+
+
+/*
+ * Function to detach from the Processor.
+ *
+ * This function calls into the specific Processor implementation
+ * to detach from it.
+ * This function is called from the ProcMgr detach function, and
+ * hence is useful to perform any activities that may be required
+ * before the slave is powered down.
+ * Depending on the type of Processor, this function may or may not
+ * perform any activities.
+ */
+inline int processor_detach(void *handle)
+{
+ int retval = 0;
+ struct processor_object *proc_handle =
+ (struct processor_object *)handle;
+
+ BUG_ON(handle == NULL);
+ BUG_ON(proc_handle->proc_fxn_table.detach == NULL);
+
+ retval = proc_handle->proc_fxn_table.detach(handle);
+ /* For all boot modes, at the end of detach, the Processor is in
+ * unknown state.
+ */
+ proc_handle->state = PROC_MGR_STATE_UNKNOWN;
+ return retval;
+}
+
+
+/*
+ * Function to start the processor.
+ *
+ * This function calls into the specific Processor implementation
+ * to start the slave processor running.
+ * This function starts the slave processor running, in most
+ * devices, by programming its entry point into the boot location
+ * of the slave processor and releasing it from reset.
+ * The handle specifies the specific Processor instance to be used.
+ *
+ * @param handle void * to the Processor object
+ * @param entryPt Entry point of the file loaded on the slave Processor
+ *
+ * @sa Processor_stop
+ */
+inline int processor_start(void *handle, u32 entry_pt,
+ struct processor_start_params *params)
+{
+ int retval = 0;
+ struct processor_object *proc_handle =
+ (struct processor_object *)handle;
+
+ BUG_ON(handle == NULL);
+ /* entryPt may be 0 for some devices. Cannot check for valid/invalid. */
+ BUG_ON(params == NULL);
+ BUG_ON(proc_handle->proc_fxn_table.start == NULL);
+ retval = proc_handle->proc_fxn_table.start(handle, entry_pt, params);
+
+ if ((proc_handle->boot_mode == PROC_MGR_BOOTMODE_BOOT)
+ || (proc_handle->boot_mode == PROC_MGR_BOOTMODE_NOLOAD))
+ proc_handle->state = PROC_MGR_STATE_RUNNNING;
+
+ return retval;
+}
+
+
+/*
+ * Function to stop the processor.
+ *
+ * This function calls into the specific Processor implementation
+ * to stop the slave processor.
+ * This function stops the slave processor running, in most
+ * devices, by placing it in reset.
+ * The handle specifies the specific Processor instance to be used.
+ */
+inline int processor_stop(void *handle,
+ struct processor_stop_params *params)
+{
+ int retval = 0;
+ struct processor_object *proc_handle =
+ (struct processor_object *)handle;
+
+ BUG_ON(handle == NULL);
+ BUG_ON(proc_handle->proc_fxn_table.stop == NULL);
+
+ retval = proc_handle->proc_fxn_table.stop(handle, params);
+
+ if ((proc_handle->boot_mode == PROC_MGR_BOOTMODE_BOOT)
+ || (proc_handle->boot_mode == PROC_MGR_BOOTMODE_NOLOAD))
+ proc_handle->state = PROC_MGR_STATE_RESET;
+
+ return retval;
+}
+
+
+/*
+ * Function to read from the slave processor's memory.
+ *
+ * This function calls into the specific Processor implementation
+ * to read from the slave processor's memory. It reads from the
+ * specified address in the processor's address space and copies
+ * the required number of bytes into the specified buffer.
+ * It returns the number of bytes actually read in the num_bytes
+ * parameter.
+ * Depending on the processor implementation, it may result in
+ * reading from shared memory or across a peripheral physical
+ * connectivity.
+ * The handle specifies the specific Processor instance to be used.
+ */
+inline int processor_read(void *handle, u32 proc_addr,
+ u32 *num_bytes, void *buffer)
+{
+ int retval = 0;
+ struct processor_object *proc_handle =
+ (struct processor_object *)handle;
+
+ BUG_ON(handle == NULL);
+ BUG_ON(proc_addr == 0);
+ BUG_ON(num_bytes == 0);
+ BUG_ON(buffer == NULL);
+ BUG_ON(proc_handle->proc_fxn_table.read == NULL);
+
+ retval = proc_handle->proc_fxn_table.read(handle, proc_addr,
+ num_bytes, buffer);
+ return retval;
+}
+
+
+/*
+ * Function to write into the slave processor's memory.
+ *
+ * This function calls into the specific Processor implementation
+ * to write into the slave processor's memory. It writes into the
+ * specified address in the processor's address space and copies
+ * the required number of bytes from the specified buffer.
+ * It returns the number of bytes actually written in the num_bytes
+ * parameter.
+ * Depending on the processor implementation, it may result in
+ * writing into shared memory or across a peripheral physical
+ * connectivity.
+ * The handle specifies the specific Processor instance to be used.
+ */
+inline int processor_write(void *handle, u32 proc_addr, u32 *num_bytes,
+ void *buffer)
+{
+ int retval = 0;
+ struct processor_object *proc_handle =
+ (struct processor_object *)handle;
+ BUG_ON(handle == NULL);
+ BUG_ON(proc_addr == 0);
+ BUG_ON(num_bytes == 0);
+ BUG_ON(buffer == NULL);
+ BUG_ON(proc_handle->proc_fxn_table.write == NULL);
+
+ retval = proc_handle->proc_fxn_table.write(handle, proc_addr,
+ num_bytes, buffer);
+ return retval;
+}
+
+
+/*
+ * Function to get the current state of the slave Processor.
+ *
+ * This function gets the state of the slave processor as
+ * maintained on the master Processor state machine. It does not
+ * go to the slave processor to get its actual state at the time
+ * when this API is called.
+ */
+enum proc_mgr_state processor_get_state(void *handle)
+{
+ struct processor_object *proc_handle =
+ (struct processor_object *)handle;
+
+ BUG_ON(handle == NULL);
+
+ return proc_handle->state;
+}
+
+
+/*
+ * Function to set the current state of the slave Processor
+ * to specified value.
+ *
+ * This function is used to set the state of the processor to the
+ * value as specified. This function may be used by external
+ * entities that affect the state of the slave processor, such as
+ * PwrMgr, error handler, or ProcMgr.
+ */
+void processor_set_state(void *handle, enum proc_mgr_state state)
+{
+ struct processor_object *proc_handle =
+ (struct processor_object *)handle;
+
+ BUG_ON(handle == NULL);
+ proc_handle->state = state;
+}
+
+
+/*
+ * Function to perform device-dependent operations.
+ *
+ * This function calls into the specific Processor implementation
+ * to perform device dependent control operations. The control
+ * operations supported by the device are exposed directly by the
+ * specific implementation of the Processor interface. These
+ * commands and their specific argument types are used with this
+ * function.
+ */
+inline int processor_control(void *handle, int cmd, void *arg)
+{
+ int retval = 0;
+ struct processor_object *proc_handle =
+ (struct processor_object *)handle;
+
+ BUG_ON(handle == NULL);
+ BUG_ON(proc_handle->proc_fxn_table.control == NULL);
+
+ retval = proc_handle->proc_fxn_table.control(handle, cmd, arg);
+ return retval;
+}
+
+
+/*
+ * Function to translate between two types of address spaces.
+ *
+ * This function translates addresses between two types of address
+ * spaces. The destination and source address types are indicated
+ * through parameters specified in this function.
+ */
+inline int processor_translate_addr(void *handle, void **dst_addr,
+ enum proc_mgr_addr_type dst_addr_type, void *src_addr,
+ enum proc_mgr_addr_type src_addr_type)
+{
+ int retval = 0;
+ struct processor_object *proc_handle =
+ (struct processor_object *)handle;
+
+ BUG_ON(handle == NULL);
+ BUG_ON(dst_addr == NULL);
+ BUG_ON(src_addr == NULL);
+ BUG_ON(dst_addr_type >= PROC_MGR_ADDRTYPE_ENDVALUE);
+ BUG_ON(src_addr_type >= PROC_MGR_ADDRTYPE_ENDVALUE);
+ BUG_ON(proc_handle->proc_fxn_table.translateAddr == NULL);
+
+ retval = proc_handle->proc_fxn_table.translateAddr(handle,
+ dst_addr, dst_addr_type, src_addr, src_addr_type);
+ return retval;
+}
+
+
+/*
+ * Function to map address to slave address space.
+ *
+ * This function maps the provided slave address to a host address
+ * and returns the mapped address and size.
+ */
+inline int processor_map(void *handle, u32 proc_addr, u32 size,
+ u32 *mapped_addr, u32 *mapped_size, u32 map_attribs)
+{
+ int retval = 0;
+ struct processor_object *proc_handle =
+ (struct processor_object *)handle;
+
+ BUG_ON(handle == NULL);
+ BUG_ON(proc_addr == 0);
+ BUG_ON(size == 0);
+ BUG_ON(mapped_addr == NULL);
+ BUG_ON(mapped_size == NULL);
+ BUG_ON(proc_handle->proc_fxn_table.map == NULL);
+
+ retval = proc_handle->proc_fxn_table.map(handle, proc_addr,
+ size, mapped_addr, mapped_size, map_attribs);
+ return retval;
+}
+
+/*
+ * Function to unmap address to slave address space.
+ *
+ * This function unmap the provided slave address
+ */
+inline int processor_unmap(void *handle, u32 mapped_addr)
+{
+ int retval = 0;
+ struct processor_object *proc_handle =
+ (struct processor_object *)handle;
+
+ retval = proc_handle->proc_fxn_table.unmap(handle, mapped_addr);
+ return retval;
+}
+
+/*
+ * Function that registers for notification when the slave
+ * processor transitions to any of the states specified.
+ *
+ * This function allows the user application to register for
+ * changes in processor state and take actions accordingly.
+
+ */
+inline int processor_register_notify(void *handle, proc_mgr_callback_fxn fxn,
+ void *args, enum proc_mgr_state state[])
+{
+ int retval = 0;
+
+ BUG_ON(handle == NULL);
+ BUG_ON(fxn == NULL);
+
+ /* TODO: TBD: To be implemented. */
+ return retval;
+}
+
+/*
+ * Function that returns the proc instance mem info
+ */
+int processor_get_proc_info(void *handle, struct proc_mgr_proc_info *procinfo)
+{
+ struct processor_object *proc_handle =
+ (struct processor_object *)handle;
+ int retval;
+ retval = proc_handle->proc_fxn_table.procinfo(proc_handle, procinfo);
+ return retval;
+}
+
+/*
+ * Function that returns the address translations
+ */
+int processor_virt_to_phys(void *handle, u32 da, u32 *mapped_entries,
+ u32 num_of_entries)
+{
+ struct processor_object *proc_handle =
+ (struct processor_object *)handle;
+ int retval;
+ retval = proc_handle->proc_fxn_table.virt_to_phys(handle, da,
+ mapped_entries, num_of_entries);
+ return retval;
+}
diff --git a/drivers/dsp/syslink/procmgr/processor.h b/drivers/dsp/syslink/procmgr/processor.h
new file mode 100755
index 000000000000..b4f78581839e
--- /dev/null
+++ b/drivers/dsp/syslink/procmgr/processor.h
@@ -0,0 +1,84 @@
+/*
+ * processor.h
+ *
+ * Syslink driver support functions for TI OMAP processors.
+ *
+ * Copyright (C) 2009-2010 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef SYSLINK_PROCESSOR_H_
+#define SYSLINK_PROCESSOR_H_
+
+#include <linux/types.h>
+
+/* Module level headers */
+#include "procdefs.h"
+
+/* ===================================
+ * APIs
+ * ===================================
+ */
+/* Function to attach to the Processor. */
+int processor_attach(void *handle, struct processor_attach_params *params);
+
+/* Function to detach from the Processor. */
+int processor_detach(void *handle);
+
+/* Function to start the processor. */
+int processor_start(void *handle, u32 entry_pt,
+ struct processor_start_params *params);
+
+/* Function to stop the processor. */
+int processor_stop(void *handle,
+ struct processor_stop_params *params);
+
+/* Function to read from the slave processor's memory. */
+int processor_read(void *handle, u32 proc_addr, u32 *num_bytes, void *buffer);
+
+/* Function to read write into the slave processor's memory. */
+int processor_write(void *handle, u32 proc_addr, u32 *num_bytes, void *buffer);
+
+/* Function to get the current state of the slave Processor as maintained on
+ * the master Processor state machine.
+ */
+enum proc_mgr_state processor_get_state(void *handle);
+
+/* Function to set the current state of the slave Processor to specified value.
+ */
+void processor_set_state(void *handle, enum proc_mgr_state state);
+
+/* Function to perform device-dependent operations. */
+int processor_control(void *handle, int cmd, void *arg);
+
+/* Function to translate between two types of address spaces. */
+int processor_translate_addr(void *handle, void **dst_addr,
+ enum proc_mgr_addr_type dst_addr_type, void *src_addr,
+ enum proc_mgr_addr_type src_addr_type);
+
+/* Function to map address to slave address space */
+int processor_map(void *handle, u32 proc_addr, u32 size, u32 *mapped_addr,
+ u32 *mapped_size, u32 map_attribs);
+/* Function to unmap address to slave address space */
+int processor_unmap(void *handle, u32 mapped_addr);
+
+/* Function that registers for notification when the slave processor
+ * transitions to any of the states specified.
+ */
+int processor_register_notify(void *handle, proc_mgr_callback_fxn fxn,
+ void *args, enum proc_mgr_state state[]);
+
+/* Function that returns the return value of specific processor info
+ */
+int processor_get_proc_info(void *handle, struct proc_mgr_proc_info *procinfo);
+
+int processor_virt_to_phys(void *handle, u32 da, u32 *mapped_entries,
+ u32 num_of_entries);
+#endif
diff --git a/drivers/dsp/syslink/procmgr/procmgr.c b/drivers/dsp/syslink/procmgr/procmgr.c
new file mode 100755
index 000000000000..a7124c5b9028
--- /dev/null
+++ b/drivers/dsp/syslink/procmgr/procmgr.c
@@ -0,0 +1,957 @@
+/*
+ * procmgr.c
+ *
+ * Syslink driver support functions for TI OMAP processors.
+ *
+ * Copyright (C) 2009-2010 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/vmalloc.h>
+#include <asm/atomic.h>
+
+/* Module level headers */
+#include <procmgr.h>
+#include "procdefs.h"
+#include "processor.h"
+#include <syslink/atomic_linux.h>
+
+/* ================================
+ * Macros and types
+ * ================================
+ */
+/*! @brief Macro to make a correct module magic number with refCount */
+#define PROCMGR_MAKE_MAGICSTAMP(x) ((PROCMGR_MODULEID << 12u) | (x))
+
+/*
+ * ProcMgr Module state object
+ */
+struct proc_mgr_module_object {
+ atomic_t ref_count;
+ u32 config_size;
+ /* Size of configuration structure */
+ struct proc_mgr_config cfg;
+ /* ProcMgr configuration structure */
+ struct proc_mgr_config def_cfg;
+ /* Default module configuration */
+ struct proc_mgr_params def_inst_params;
+ /* Default parameters for the ProcMgr instances */
+ struct proc_mgr_attach_params def_attach_params;
+ /* Default parameters for the ProcMgr attach function */
+ struct proc_mgr_start_params def_start_params;
+ /* Default parameters for the ProcMgr start function */
+ struct proc_mgr_stop_params def_stop_params;
+ /* Default parameters for the ProcMgr stop function */
+ struct mutex *gate_handle;
+ /* handle of gate to be used for local thread safety */
+ void *proc_handles[MULTIPROC_MAXPROCESSORS];
+ /* Array of handles of ProcMgr instances */
+};
+
+/*
+ * ProcMgr instance object
+ */
+struct proc_mgr_object {
+ u16 proc_id;
+ /* Processor ID associated with this ProcMgr. */
+ struct processor_object *proc_handle;
+ /* Processor ID of the processor being represented by this instance. */
+ void *loader_handle;
+ /*!< Handle to the Loader object associated with this ProcMgr. */
+ void *pwr_handle;
+ /*!< Handle to the PwrMgr object associated with this ProcMgr. */
+ /*!< Processor ID of the processor being represented by this instance */
+ struct proc_mgr_params params;
+ /* ProcMgr instance params structure */
+ struct proc_mgr_attach_params attach_params;
+ /* ProcMgr attach params structure */
+ struct proc_mgr_start_params start_params;
+ /* ProcMgr start params structure */
+ struct proc_mgr_stop_params stop_params;
+ /* ProcMgr start params structure */
+ u32 file_id;
+ /*!< File ID of the loaded static executable */
+ u16 num_mem_entries;
+ /* Number of valid memory entries */
+ struct proc_mgr_addr_info mem_entries[PROCMGR_MAX_MEMORY_REGIONS];
+ /* Configuration of memory regions */
+};
+
+struct proc_mgr_module_object proc_mgr_obj_state = {
+ .config_size = sizeof(struct proc_mgr_config),
+ .def_cfg.gate_handle = NULL,
+ .gate_handle = NULL,
+ .def_inst_params.proc_handle = NULL,
+ .def_attach_params.boot_mode = PROC_MGR_BOOTMODE_BOOT,
+ .def_start_params.proc_id = 0
+};
+
+
+/*======================================
+ * Function to get the default configuration for the ProcMgr
+ * module.
+ *
+* This function can be called by the application to get their
+* configuration parameter to ProcMgr_setup filled in by the
+* ProcMgr module with the default parameters. If the user does
+* not wish to make any change in the default parameters, this API
+* is not required to be called.
+ */
+void proc_mgr_get_config(struct proc_mgr_config *cfg)
+{
+ BUG_ON(cfg == NULL);
+ memcpy(cfg, &proc_mgr_obj_state.def_cfg,
+ sizeof(struct proc_mgr_config));
+ return;
+}
+EXPORT_SYMBOL(proc_mgr_get_config);
+
+/*
+ * Function to setup the ProcMgr module.
+ *
+ *This function sets up the ProcMgr module. This function must
+ *be called before any other instance-level APIs can be invoked.
+ *Module-level configuration needs to be provided to this
+ *function. If the user wishes to change some specific config
+ *parameters, then ProcMgr_getConfig can be called to get the
+ *configuration filled with the default values. After this, only
+ *the required configuration values can be changed. If the user
+ *does not wish to make any change in the default parameters, the
+ *application can simply call ProcMgr_setup with NULL parameters.
+ *The default parameters would get automatically used.
+ */
+int proc_mgr_setup(struct proc_mgr_config *cfg)
+{
+ int retval = 0;
+ struct proc_mgr_config tmp_cfg;
+
+ /* This sets the refCount variable is not initialized, upper 16 bits is
+ * written with module Id to ensure correctness of refCount variable.
+ */
+ atomic_cmpmask_and_set(&proc_mgr_obj_state.ref_count,
+ PROCMGR_MAKE_MAGICSTAMP(0), PROCMGR_MAKE_MAGICSTAMP(0));
+
+ if (atomic_inc_return(&proc_mgr_obj_state.ref_count)
+ != PROCMGR_MAKE_MAGICSTAMP(1u))
+ return 0;
+ if (cfg == NULL) {
+ proc_mgr_get_config(&tmp_cfg);
+ cfg = &tmp_cfg;
+ }
+ if (cfg->gate_handle != NULL) {
+ proc_mgr_obj_state.gate_handle = cfg->gate_handle;
+ } else {
+ /* User has not provided any gate handle, so create a
+ *default handle.
+ */
+ proc_mgr_obj_state.gate_handle = kmalloc(sizeof(struct mutex),
+ GFP_KERNEL);
+ mutex_init(proc_mgr_obj_state.gate_handle);
+ }
+ memcpy(&proc_mgr_obj_state.cfg, cfg, sizeof(struct proc_mgr_config));
+ /* Initialize the procHandles array. */
+ memset(&proc_mgr_obj_state.proc_handles, 0,
+ (sizeof(void *) * MULTIPROC_MAXPROCESSORS));
+ return retval;
+}
+EXPORT_SYMBOL(proc_mgr_setup);
+
+/*==================================
+ * Function to destroy the ProcMgr module.
+ *
+ * Once this function is called, other ProcMgr module APIs, except
+ * for the proc_mgr_get_config API cannot be called anymore.
+ */
+int proc_mgr_destroy(void)
+{
+ int retval = 0;
+ int i;
+
+ if (atomic_cmpmask_and_lt(&(proc_mgr_obj_state.ref_count),
+ PROCMGR_MAKE_MAGICSTAMP(0), PROCMGR_MAKE_MAGICSTAMP(1))
+ == true) {
+ printk(KERN_ERR "proc_mgr_destroy: Error - module not initialized\n");
+ return -EFAULT;
+ }
+ if (atomic_dec_return(&proc_mgr_obj_state.ref_count)
+ == PROCMGR_MAKE_MAGICSTAMP(0)) {
+
+ /* Check if any ProcMgr instances have not been deleted so far
+ *. If not,delete them
+ */
+ for (i = 0 ; i < MULTIPROC_MAXPROCESSORS; i++) {
+ if (proc_mgr_obj_state.proc_handles[i] != NULL)
+ proc_mgr_delete
+ (&(proc_mgr_obj_state.proc_handles[i]));
+ }
+
+ mutex_destroy(proc_mgr_obj_state.gate_handle);
+ kfree(proc_mgr_obj_state.gate_handle);
+ /* Decrease the refCount */
+ atomic_set(&proc_mgr_obj_state.ref_count,
+ PROCMGR_MAKE_MAGICSTAMP(0));
+ }
+ return retval;;
+}
+EXPORT_SYMBOL(proc_mgr_destroy);
+
+/*=====================================
+ * Function to initialize the parameters for the ProcMgr instance.
+ *
+ * This function can be called by the application to get their
+ * configuration parameter to ProcMgr_create filled in by the
+ * ProcMgr module with the default parameters.
+ */
+void proc_mgr_params_init(void *handle, struct proc_mgr_params *params)
+{
+ struct proc_mgr_object *proc_handle = (struct proc_mgr_object *)handle;
+
+ if (WARN_ON(params == NULL))
+ goto exit;
+ if (atomic_cmpmask_and_lt(&(proc_mgr_obj_state.ref_count),
+ PROCMGR_MAKE_MAGICSTAMP(0), PROCMGR_MAKE_MAGICSTAMP(1))
+ == true) {
+ printk(KERN_ERR "proc_mgr_params_init: Error - module not initialized\n");
+ }
+ if (handle == NULL) {
+ memcpy(params, &(proc_mgr_obj_state.def_inst_params),
+ sizeof(struct proc_mgr_params));
+ } else {
+ /* Return updated ProcMgr instance specific parameters. */
+ memcpy(params, &(proc_handle->params),
+ sizeof(struct proc_mgr_params));
+ }
+exit:
+ return;
+}
+EXPORT_SYMBOL(proc_mgr_params_init);
+
+/*=====================================
+ * Function to create a ProcMgr object for a specific slave
+ * processor.
+ *
+ * This function creates an instance of the ProcMgr module and
+ * returns an instance handle, which is used to access the
+ * specified slave processor. The processor ID specified here is
+ * the ID of the slave processor as configured with the MultiProc
+ * module.
+ * Instance-level configuration needs to be provided to this
+ * function. If the user wishes to change some specific config
+ * parameters, then struct proc_mgr_params_init can be called to get the
+ * configuration filled with the default values. After this, only
+ * the required configuration values can be changed. For this
+ * API, the params argument is not optional, since the user needs
+ * to provide some essential values such as loader, PwrMgr and
+ * Processor instances to be used with this ProcMgr instance.
+ */
+void *proc_mgr_create(u16 proc_id, const struct proc_mgr_params *params)
+{
+ struct proc_mgr_object *handle = NULL;
+
+ BUG_ON(!IS_VALID_PROCID(proc_id));
+ BUG_ON(params == NULL);
+ BUG_ON(params->proc_handle == NULL);
+ if (atomic_cmpmask_and_lt(&(proc_mgr_obj_state.ref_count),
+ PROCMGR_MAKE_MAGICSTAMP(0), PROCMGR_MAKE_MAGICSTAMP(1))
+ == true) {
+ printk(KERN_ERR "proc_mgr_create: Error - module not initialized\n");
+ return NULL;
+ }
+ if (proc_mgr_obj_state.proc_handles[proc_id] != NULL) {
+ handle = proc_mgr_obj_state.proc_handles[proc_id];
+ printk(KERN_WARNING "proc_mgr_create:"
+ "Processor already exists for specified"
+ "%d proc_id, handle = 0x%x\n", proc_id, (u32)handle);
+ return handle;
+ }
+ WARN_ON(mutex_lock_interruptible(proc_mgr_obj_state.gate_handle));
+ handle = (struct proc_mgr_object *)
+ vmalloc(sizeof(struct proc_mgr_object));
+ BUG_ON(handle == NULL);
+ memset(handle, 0, sizeof(struct proc_mgr_object));
+ memcpy(&(handle->params), params, sizeof(struct proc_mgr_params));
+ handle->proc_id = proc_id;
+ handle->proc_handle = params->proc_handle;
+ handle->loader_handle = params->loader_handle;
+ handle->pwr_handle = params->pwr_handle;
+ proc_mgr_obj_state.proc_handles[proc_id] = handle;
+ mutex_unlock(proc_mgr_obj_state.gate_handle);
+ return handle;
+}
+EXPORT_SYMBOL(proc_mgr_create);
+
+/*===================================
+ * Function to delete a ProcMgr object for a specific slave
+ * processor.
+ *
+ * Once this function is called, other ProcMgr instance level APIs
+ * that require the instance handle cannot be called.
+ *
+ */
+int
+proc_mgr_delete(void **handle_ptr)
+{
+ int retval = 0;
+ struct proc_mgr_object *handle;
+
+ BUG_ON(handle_ptr == NULL);
+ if (atomic_cmpmask_and_lt(&(proc_mgr_obj_state.ref_count),
+ PROCMGR_MAKE_MAGICSTAMP(0), PROCMGR_MAKE_MAGICSTAMP(1))
+ == true) {
+ printk(KERN_ERR "proc_mgr_delete: Error - module not initialized\n");
+ return -EFAULT;
+ }
+
+ handle = (struct proc_mgr_object *)(*handle_ptr);
+ WARN_ON(mutex_lock_interruptible(proc_mgr_obj_state.gate_handle));
+ proc_mgr_obj_state.proc_handles[handle->proc_id] = NULL;
+ vfree(handle);
+ *handle_ptr = NULL;
+ mutex_unlock(proc_mgr_obj_state.gate_handle);
+ return retval;
+}
+EXPORT_SYMBOL(proc_mgr_delete);
+
+/*======================================
+ * Function to open a handle to an existing ProcMgr object handling
+ * the proc_id.
+ *
+ * This function returns a handle to an existing ProcMgr instance
+ * created for this proc_id. It enables other entities to access
+ * and use this ProcMgr instance.
+ */
+int proc_mgr_open(void **handle_ptr, u16 proc_id)
+{
+ int retval = 0;
+
+ BUG_ON(handle_ptr == NULL);
+ BUG_ON(!IS_VALID_PROCID(proc_id));
+ if (atomic_cmpmask_and_lt(&(proc_mgr_obj_state.ref_count),
+ PROCMGR_MAKE_MAGICSTAMP(0), PROCMGR_MAKE_MAGICSTAMP(1))
+ == true) {
+ printk(KERN_ERR "proc_mgr_open: Error - module not initialized\n");
+ return -EFAULT;
+ }
+
+ WARN_ON(mutex_lock_interruptible(proc_mgr_obj_state.gate_handle));
+ *handle_ptr = proc_mgr_obj_state.proc_handles[proc_id];
+ mutex_unlock(proc_mgr_obj_state.gate_handle);
+ return retval;
+}
+EXPORT_SYMBOL(proc_mgr_open);
+
+/*=====================================
+ * Function to close this handle to the ProcMgr instance.
+ *
+ * This function closes the handle to the ProcMgr instance
+ * obtained through proc_mgr_open call made earlier.
+ */
+int proc_mgr_close(void *handle)
+{
+ int retval = 0;
+
+ BUG_ON(handle == NULL);
+ if (atomic_cmpmask_and_lt(&(proc_mgr_obj_state.ref_count),
+ PROCMGR_MAKE_MAGICSTAMP(0), PROCMGR_MAKE_MAGICSTAMP(1))
+ == true) {
+ printk(KERN_ERR "proc_mgr_close: Error - module not initialized\n");
+ return -EFAULT;
+ }
+ /* Nothing to be done for closing the handle. */
+ return retval;
+}
+EXPORT_SYMBOL(proc_mgr_close);
+
+/*========================================
+ * Function to initialize the parameters for the ProcMgr attach
+ * function.
+ *
+ * This function can be called by the application to get their
+ * configuration parameter to proc_mgr_attach filled in by the
+ * ProcMgr module with the default parameters. If the user does
+ * not wish to make any change in the default parameters, this API
+ * is not required to be called.
+ */
+void proc_mgr_get_attach_params(void *handle,
+ struct proc_mgr_attach_params *params)
+{
+ struct proc_mgr_object *proc_mgr_handle =
+ (struct proc_mgr_object *)handle;
+ BUG_ON(params == NULL);
+ if (atomic_cmpmask_and_lt(&(proc_mgr_obj_state.ref_count),
+ PROCMGR_MAKE_MAGICSTAMP(0), PROCMGR_MAKE_MAGICSTAMP(1))
+ == true) {
+ printk(KERN_ERR "proc_mgr_get_attach_params:"
+ "Error - module not initialized\n");
+ }
+ if (handle == NULL) {
+ memcpy(params, &(proc_mgr_obj_state.def_attach_params),
+ sizeof(struct proc_mgr_attach_params));
+ } else {
+ /* Return updated ProcMgr instance specific parameters. */
+ memcpy(params, &(proc_mgr_handle->attach_params),
+ sizeof(struct proc_mgr_attach_params));
+ }
+ return;
+}
+EXPORT_SYMBOL(proc_mgr_get_attach_params);
+
+/*
+ * Function to attach the client to the specified slave and also
+ * initialize the slave (if required).
+ *
+ * This function attaches to an instance of the ProcMgr module and
+ * performs any hardware initialization required to power up the
+ * slave device. This function also performs the required state
+ * transitions for this ProcMgr instance to ensure that the local
+ * object representing the slave device correctly indicates the
+ * state of the slave device. Depending on the slave boot mode
+ * being used, the slave may be powered up, in reset, or even
+ * running state.
+ * Configuration parameters need to be provided to this
+ * function. If the user wishes to change some specific config
+ * parameters, then proc_mgr_get_attach_params can be called to get
+ * the configuration filled with the default values. After this,
+ * only the required configuration values can be changed. If the
+ * user does not wish to make any change in the default parameters,
+ * the application can simply call proc_mgr_attach with NULL
+ * parameters.
+ * The default parameters would get automatically used.
+ */
+int proc_mgr_attach(void *handle, struct proc_mgr_attach_params *params)
+{
+ int retval = 0;
+ struct proc_mgr_object *proc_mgr_handle =
+ (struct proc_mgr_object *)handle;
+ struct proc_mgr_attach_params tmp_params;
+ struct processor_attach_params proc_attach_params;
+
+ if (params == NULL) {
+ proc_mgr_get_attach_params(handle, &tmp_params);
+ params = &tmp_params;
+ }
+ if (atomic_cmpmask_and_lt(&(proc_mgr_obj_state.ref_count),
+ PROCMGR_MAKE_MAGICSTAMP(0), PROCMGR_MAKE_MAGICSTAMP(1))
+ == true) {
+ printk(KERN_ERR "proc_mgr_attach:"
+ "Error - module not initialized\n");
+ return -EFAULT;
+ }
+ if (WARN_ON(handle == NULL)) {
+ retval = -EFAULT;
+ goto exit;
+ }
+ if (WARN_ON(params->boot_mode == PROC_MGR_BOOTMODE_ENDVALUE)) {
+ retval = -EINVAL;
+ goto exit;
+ }
+ WARN_ON(mutex_lock_interruptible(proc_mgr_obj_state.gate_handle));
+ /* Copy the user provided values into the instance object. */
+ memcpy(&(proc_mgr_handle->attach_params), params,
+ sizeof(struct proc_mgr_attach_params));
+ proc_attach_params.params = params;
+ proc_attach_params.num_mem_entries = 0;
+ /* Attach to the specified Processor instance. */
+ retval = processor_attach(proc_mgr_handle->proc_handle,
+ &proc_attach_params);
+ proc_mgr_handle->num_mem_entries = proc_attach_params.num_mem_entries;
+ printk(KERN_INFO "proc_mgr_attach:proc_mgr_handle->num_mem_entries = %d\n",
+ proc_mgr_handle->num_mem_entries);
+ /* Store memory information in local object.*/
+ memcpy(&(proc_mgr_handle->mem_entries),
+ &(proc_attach_params.mem_entries),
+ sizeof(proc_mgr_handle->mem_entries));
+ mutex_unlock(proc_mgr_obj_state.gate_handle);
+exit:
+ return retval;
+}
+EXPORT_SYMBOL(proc_mgr_attach);
+
+/*===================================
+ * Function to detach the client from the specified slave and also
+ * finalze the slave (if required).
+ *
+ * This function detaches from an instance of the ProcMgr module
+ * and performs any hardware finalization required to power down
+ * the slave device. This function also performs the required state
+ * transitions for this ProcMgr instance to ensure that the local
+ * object representing the slave device correctly indicates the
+ * state of the slave device. Depending on the slave boot mode
+ * being used, the slave may be powered down, in reset, or left in
+ * its original state.
+*/
+int proc_mgr_detach(void *handle)
+{
+ int retval = 0;
+ struct proc_mgr_object *proc_mgr_handle =
+ (struct proc_mgr_object *)handle;
+ if (atomic_cmpmask_and_lt(&(proc_mgr_obj_state.ref_count),
+ PROCMGR_MAKE_MAGICSTAMP(0), PROCMGR_MAKE_MAGICSTAMP(1))
+ == true) {
+ printk(KERN_ERR "proc_mgr_detach:"
+ "Error - module not initialized\n");
+ return -EFAULT;
+ }
+ BUG_ON(handle == NULL);
+ WARN_ON(mutex_lock_interruptible(proc_mgr_obj_state.gate_handle));
+ /* Detach from the Processor. */
+ retval = processor_detach(proc_mgr_handle->proc_handle);
+ mutex_unlock(proc_mgr_obj_state.gate_handle);
+ return retval;
+}
+EXPORT_SYMBOL(proc_mgr_detach);
+
+/*===============================
+ * Function to initialize the parameters for the ProcMgr start
+ * function.
+ *
+ * This function can be called by the application to get their
+ * configuration parameter to proc_mgr_start filled in by the
+ * ProcMgr module with the default parameters. If the user does
+ * not wish to make any change in the default parameters, this API
+ * is not required to be called.
+ *
+ */
+void proc_mgr_get_start_params(void *handle,
+ struct proc_mgr_start_params *params)
+{
+ struct proc_mgr_object *proc_mgr_handle =
+ (struct proc_mgr_object *)handle;
+ if (atomic_cmpmask_and_lt(&(proc_mgr_obj_state.ref_count),
+ PROCMGR_MAKE_MAGICSTAMP(0), PROCMGR_MAKE_MAGICSTAMP(1))
+ == true) {
+ printk(KERN_ERR "proc_mgr_get_start_params:"
+ "Error - module not initialized\n");
+ }
+ BUG_ON(params == NULL);
+
+ if (handle == NULL) {
+ memcpy(params, &(proc_mgr_obj_state.def_start_params),
+ sizeof(struct proc_mgr_start_params));
+ } else {
+ /* Return updated ProcMgr instance specific parameters. */
+ memcpy(params, &(proc_mgr_handle->start_params),
+ sizeof(struct proc_mgr_start_params));
+ }
+ return;
+}
+EXPORT_SYMBOL(proc_mgr_get_start_params);
+
+/*==========================================
+ * Function to start the slave processor running.
+ *
+ * Function to start execution of the loaded code on the slave
+ * from the entry point specified in the slave executable loaded
+ * earlier by call to proc_mgr_load ().
+ * After successful completion of this function, the ProcMgr
+ * instance is expected to be in the proc_mgr_State_Running state.
+ */
+int proc_mgr_start(void *handle, u32 entry_point,
+ struct proc_mgr_start_params *params)
+{
+ int retval = 0;
+ struct proc_mgr_object *proc_mgr_handle =
+ (struct proc_mgr_object *)handle;
+ struct proc_mgr_start_params tmp_params;
+ struct processor_start_params proc_params;
+
+ if (atomic_cmpmask_and_lt(&(proc_mgr_obj_state.ref_count),
+ PROCMGR_MAKE_MAGICSTAMP(0), PROCMGR_MAKE_MAGICSTAMP(1))
+ == true) {
+ printk(KERN_ERR "proc_mgr_start:"
+ "Error - module not initialized\n");
+ return -EFAULT;
+ }
+ BUG_ON(handle == NULL);
+
+ if (params == NULL) {
+ proc_mgr_get_start_params(handle, &tmp_params);
+ params = &tmp_params;
+ }
+ WARN_ON(mutex_lock_interruptible(proc_mgr_obj_state.gate_handle));
+ memcpy(&(proc_mgr_handle->start_params), params,
+ sizeof(struct proc_mgr_start_params));
+ /* Start the slave processor running. */
+ proc_params.params = params;
+ retval = processor_start(proc_mgr_handle->proc_handle,
+ entry_point, &proc_params);
+
+ mutex_unlock(proc_mgr_obj_state.gate_handle);
+ return retval;;
+}
+EXPORT_SYMBOL(proc_mgr_start);
+
+/*========================================
+ * Function to stop the slave processor.
+ *
+ * Function to stop execution of the slave processor.
+ * Depending on the boot mode, after successful completion of this
+ * function, the ProcMgr instance may be in the proc_mgr_State_Reset
+ * state.
+ *
+ */
+int proc_mgr_stop(void *handle, struct proc_mgr_stop_params *params)
+{
+ int retval = 0;
+ struct proc_mgr_object *proc_mgr_handle =
+ (struct proc_mgr_object *)handle;
+ struct processor_stop_params proc_params;
+ if (atomic_cmpmask_and_lt(&(proc_mgr_obj_state.ref_count),
+ PROCMGR_MAKE_MAGICSTAMP(0), PROCMGR_MAKE_MAGICSTAMP(1))
+ == true) {
+ printk(KERN_ERR "proc_mgr_stop:"
+ "Error - module not initialized\n");
+ return -EFAULT;
+ }
+ BUG_ON(handle == NULL);
+ WARN_ON(mutex_lock_interruptible(proc_mgr_obj_state.gate_handle));
+ proc_params.params = params;
+ retval = processor_stop(proc_mgr_handle->proc_handle,
+ &proc_params);
+ mutex_unlock(proc_mgr_obj_state.gate_handle);
+ return retval;;
+}
+EXPORT_SYMBOL(proc_mgr_stop);
+
+/*===================================
+ * Function to get the current state of the slave Processor.
+ *
+ * This function gets the state of the slave processor as
+ * maintained on the master Processor state machine. It does not
+ * go to the slave processor to get its actual state at the time
+ * when this API is called.
+ *
+ */
+enum proc_mgr_state proc_mgr_get_state(void *handle)
+{
+ struct proc_mgr_object *proc_mgr_handle =
+ (struct proc_mgr_object *)handle;
+ enum proc_mgr_state state = PROC_MGR_STATE_UNKNOWN;
+ if (atomic_cmpmask_and_lt(&(proc_mgr_obj_state.ref_count),
+ PROCMGR_MAKE_MAGICSTAMP(0), PROCMGR_MAKE_MAGICSTAMP(1))
+ == true) {
+ printk(KERN_ERR "proc_mgr_get_state:"
+ "Error - module not initialized\n");
+ return -EFAULT;
+ }
+ BUG_ON(handle == NULL);
+
+ WARN_ON(mutex_lock_interruptible(proc_mgr_obj_state.gate_handle));
+ state = processor_get_state(proc_mgr_handle->proc_handle);
+ mutex_unlock(proc_mgr_obj_state.gate_handle);
+ return state;
+}
+EXPORT_SYMBOL(proc_mgr_get_state);
+
+/*==================================================
+ * Function to read from the slave processor's memory.
+ *
+ * This function reads from the specified address in the
+ * processor's address space and copies the required number of
+ * bytes into the specified buffer.
+ * It returns the number of bytes actually read in thenum_bytes
+ * parameter.
+ */
+int proc_mgr_read(void *handle, u32 proc_addr, u32 *num_bytes, void *buffer)
+{
+ int retval = 0;
+ struct proc_mgr_object *proc_mgr_handle =
+ (struct proc_mgr_object *)handle;
+ if (atomic_cmpmask_and_lt(&(proc_mgr_obj_state.ref_count),
+ PROCMGR_MAKE_MAGICSTAMP(0), PROCMGR_MAKE_MAGICSTAMP(1))
+ == true) {
+ printk(KERN_ERR "proc_mgr_read:"
+ "Error - module not initialized\n");
+ return -EFAULT;
+ }
+ BUG_ON(handle == NULL);
+ BUG_ON(proc_addr == 0);
+ BUG_ON(num_bytes == NULL);
+ BUG_ON(buffer == NULL);
+
+ WARN_ON(mutex_lock_interruptible(proc_mgr_obj_state.gate_handle));
+
+ retval = processor_read(proc_mgr_handle->proc_handle, proc_addr,
+ num_bytes, buffer);
+ WARN_ON(retval < 0);
+ mutex_unlock(proc_mgr_obj_state.gate_handle);
+ return retval;
+}
+EXPORT_SYMBOL(proc_mgr_read);
+
+/*
+ * Function to write into the slave processor's memory.
+ *
+ * This function writes into the specified address in the
+ * processor's address space and copies the required number of
+ * bytes from the specified buffer.
+ * It returns the number of bytes actually written in thenum_bytes
+ * parameter.
+ */
+int proc_mgr_write(void *handle, u32 proc_addr, u32 *num_bytes, void *buffer)
+{
+ int retval = 0;
+ struct proc_mgr_object *proc_mgr_handle =
+ (struct proc_mgr_object *)handle;
+ if (atomic_cmpmask_and_lt(&(proc_mgr_obj_state.ref_count),
+ PROCMGR_MAKE_MAGICSTAMP(0), PROCMGR_MAKE_MAGICSTAMP(1))
+ == true) {
+ printk(KERN_ERR "proc_mgr_write:"
+ "Error - module not initialized\n");
+ return -EFAULT;
+ }
+ BUG_ON(proc_addr == 0);
+ BUG_ON(num_bytes == NULL);
+ BUG_ON(buffer == NULL);
+
+ WARN_ON(mutex_lock_interruptible(proc_mgr_obj_state.gate_handle));
+ retval = processor_write(proc_mgr_handle->proc_handle, proc_addr,
+ num_bytes, buffer);
+ WARN_ON(retval < 0);
+ mutex_unlock(proc_mgr_obj_state.gate_handle);
+ return retval;;
+}
+EXPORT_SYMBOL(proc_mgr_write);
+
+
+/*===================================
+ * Function to perform device-dependent operations.
+ *
+ * This function performs control operations supported by the
+ * as exposed directly by the specific implementation of the
+ * Processor interface. These commands and their specific argument
+ * types are used with this function.
+ */
+int proc_mgr_control(void *handle, int cmd, void *arg)
+{
+ int retval = 0;
+ struct proc_mgr_object *proc_mgr_handle
+ = (struct proc_mgr_object *)handle;
+ if (atomic_cmpmask_and_lt(&(proc_mgr_obj_state.ref_count),
+ PROCMGR_MAKE_MAGICSTAMP(0), PROCMGR_MAKE_MAGICSTAMP(1))
+ == true) {
+ printk(KERN_ERR "proc_mgr_control:"
+ "Error - module not initialized\n");
+ return -EFAULT;
+ }
+ BUG_ON(handle == NULL);
+ WARN_ON(mutex_lock_interruptible(proc_mgr_obj_state.gate_handle));
+ /* Perform device-dependent control operation. */
+ retval = processor_control(proc_mgr_handle->proc_handle, cmd, arg);
+ WARN_ON(retval < 0);
+ mutex_unlock(proc_mgr_obj_state.gate_handle);
+ return retval;;
+}
+EXPORT_SYMBOL(proc_mgr_control);
+
+/*========================================
+ * Function to translate between two types of address spaces.
+ *
+ * This function translates addresses between two types of address
+ * spaces. The destination and source address types are indicated
+ * through parameters specified in this function.
+ */
+int proc_mgr_translate_addr(void *handle, void **dst_addr,
+ enum proc_mgr_addr_type dst_addr_type, void *src_addr,
+ enum proc_mgr_addr_type src_addr_type)
+{
+ int retval = 0;
+ struct proc_mgr_object *proc_mgr_handle =
+ (struct proc_mgr_object *)handle;
+ if (atomic_cmpmask_and_lt(&(proc_mgr_obj_state.ref_count),
+ PROCMGR_MAKE_MAGICSTAMP(0), PROCMGR_MAKE_MAGICSTAMP(1))
+ == true) {
+ printk(KERN_ERR "proc_mgr_translate_addr:"
+ "Error - module not initialized\n");
+ return -EFAULT;
+ }
+ BUG_ON(dst_addr == NULL);
+ BUG_ON(handle == NULL);
+ BUG_ON(dst_addr_type > PROC_MGR_ADDRTYPE_ENDVALUE);
+ BUG_ON(src_addr == NULL);
+ BUG_ON(src_addr_type > PROC_MGR_ADDRTYPE_ENDVALUE);
+
+ WARN_ON(mutex_lock_interruptible(proc_mgr_obj_state.gate_handle));
+ /* Translate the address. */
+ retval = processor_translate_addr(proc_mgr_handle->proc_handle,
+ dst_addr, dst_addr_type, src_addr, src_addr_type);
+ WARN_ON(retval < 0);
+ mutex_unlock(proc_mgr_obj_state.gate_handle);
+ return retval;;
+}
+EXPORT_SYMBOL(proc_mgr_translate_addr);
+
+/*============================================
+ * Function to map address to slave address space.
+ *
+ * This function maps the provided slave address to a host address
+ * and returns the mapped address and size.
+ *
+ */
+int proc_mgr_map(void *handle, u32 proc_addr, u32 size, u32 *mapped_addr,
+ u32 *mapped_size, u32 map_attribs)
+{
+ int retval = 0;
+ struct proc_mgr_object *proc_mgr_handle =
+ (struct proc_mgr_object *)handle;
+ if (atomic_cmpmask_and_lt(&(proc_mgr_obj_state.ref_count),
+ PROCMGR_MAKE_MAGICSTAMP(0), PROCMGR_MAKE_MAGICSTAMP(1))
+ == true) {
+ printk(KERN_ERR "proc_mgr_map:"
+ "Error - module not initialized\n");
+ return -EFAULT;
+ }
+ BUG_ON(handle == NULL);
+ BUG_ON(proc_addr == 0);
+ BUG_ON(mapped_addr == NULL);
+ BUG_ON(mapped_size == NULL);
+
+ WARN_ON(mutex_lock_interruptible(proc_mgr_obj_state.gate_handle));
+
+ /* Map to host address space. */
+ retval = processor_map(proc_mgr_handle->proc_handle, proc_addr,
+ size, mapped_addr, mapped_size, map_attribs);
+ WARN_ON(retval < 0);
+ mutex_unlock(proc_mgr_obj_state.gate_handle);
+ return retval;;
+}
+EXPORT_SYMBOL(proc_mgr_map);
+
+/*============================================
+ * Function to unmap address to slave address space.
+ *
+ * This function unmaps the provided slave address to a host address
+ *
+ */
+int proc_mgr_unmap(void *handle, u32 mapped_addr)
+{
+ int retval = 0;
+ struct proc_mgr_object *proc_mgr_handle =
+ (struct proc_mgr_object *)handle;
+ if (atomic_cmpmask_and_lt(&(proc_mgr_obj_state.ref_count),
+ PROCMGR_MAKE_MAGICSTAMP(0), PROCMGR_MAKE_MAGICSTAMP(1))
+ == true) {
+ printk(KERN_ERR "proc_mgr_unmap:"
+ "Error - module not initialized\n");
+ return -EFAULT;
+ }
+ WARN_ON(mutex_lock_interruptible(proc_mgr_obj_state.gate_handle));
+
+ /* Map to host address space. */
+ retval = processor_unmap(proc_mgr_handle->proc_handle, mapped_addr);
+ WARN_ON(retval < 0);
+ mutex_unlock(proc_mgr_obj_state.gate_handle);
+ return retval;;
+}
+EXPORT_SYMBOL(proc_mgr_unmap);
+
+/*=================================
+ * Function that registers for notification when the slave
+ * processor transitions to any of the states specified.
+ *
+ * This function allows the user application to register for
+ * changes in processor state and take actions accordingly.
+ *
+ */
+int proc_mgr_register_notify(void *handle, proc_mgr_callback_fxn fxn,
+ void *args, enum proc_mgr_state state[])
+{
+ int retval = 0;
+ struct proc_mgr_object *proc_mgr_handle
+ = (struct proc_mgr_object *)handle;
+ if (atomic_cmpmask_and_lt(&(proc_mgr_obj_state.ref_count),
+ PROCMGR_MAKE_MAGICSTAMP(0), PROCMGR_MAKE_MAGICSTAMP(1))
+ == true) {
+ printk(KERN_ERR "proc_mgr_register_notify:"
+ "Error - module not initialized\n");
+ return -EFAULT;
+ }
+ BUG_ON(handle == NULL);
+ BUG_ON(fxn == NULL);
+ WARN_ON(mutex_lock_interruptible(proc_mgr_obj_state.gate_handle));
+ retval = processor_register_notify(proc_mgr_handle->proc_handle, fxn,
+ args, state);
+ WARN_ON(retval < 0);
+ mutex_unlock(proc_mgr_obj_state.gate_handle);
+ return retval;
+}
+EXPORT_SYMBOL(proc_mgr_register_notify);
+
+/*
+ * Function that returns information about the characteristics of
+ * the slave processor.
+ */
+int proc_mgr_get_proc_info(void *handle, struct proc_mgr_proc_info *proc_info)
+{
+ struct proc_mgr_object *proc_mgr_handle =
+ (struct proc_mgr_object *)handle;
+ struct processor_object *proc_handle;
+
+ struct proc_mgr_proc_info proc_info_test;
+
+ if (atomic_cmpmask_and_lt(&(proc_mgr_obj_state.ref_count),
+ PROCMGR_MAKE_MAGICSTAMP(0), PROCMGR_MAKE_MAGICSTAMP(1))
+ == true) {
+ printk(KERN_ERR "proc_mgr_get_proc_info:"
+ "Error - module not initialized\n");
+ return -EFAULT;
+ }
+ if (WARN_ON(handle == NULL))
+ goto error_exit;
+ if (WARN_ON(proc_info == NULL))
+ goto error_exit;
+ proc_handle = proc_mgr_handle->proc_handle;
+ if (WARN_ON(proc_handle == NULL))
+ goto error_exit;
+
+ WARN_ON(mutex_lock_interruptible(proc_mgr_obj_state.gate_handle));
+
+ processor_get_proc_info(proc_handle, &proc_info_test);
+ /* Return bootMode information. */
+ proc_info->boot_mode = proc_mgr_handle->attach_params.boot_mode;
+ /* Return memory information. */
+ proc_info->num_mem_entries = proc_mgr_handle->num_mem_entries;
+ memcpy(&(proc_info->mem_entries),
+ &(proc_mgr_handle->mem_entries),
+ sizeof(proc_mgr_handle->mem_entries));
+ mutex_unlock(proc_mgr_obj_state.gate_handle);
+ return 0;
+error_exit:
+ return -EFAULT;
+}
+EXPORT_SYMBOL(proc_mgr_get_proc_info);
+
+/*============================================
+ * Function to get virtual to physical address translations
+ *
+ * This function retrieves physical entries
+ *
+ */
+int proc_mgr_virt_to_phys(void *handle, u32 da, u32 *mapped_entries,
+ u32 num_of_entries)
+{
+ int retval = 0;
+ struct proc_mgr_object *proc_mgr_handle =
+ (struct proc_mgr_object *)handle;
+
+ WARN_ON(mutex_lock_interruptible(proc_mgr_obj_state.gate_handle));
+
+ /* Map to host address space. */
+ retval = processor_virt_to_phys(proc_mgr_handle->proc_handle, da,
+ mapped_entries, num_of_entries);
+ WARN_ON(retval < 0);
+ mutex_unlock(proc_mgr_obj_state.gate_handle);
+ return retval;;
+}
+EXPORT_SYMBOL(proc_mgr_virt_to_phys);
+
diff --git a/drivers/dsp/syslink/procmgr/procmgr_drv.c b/drivers/dsp/syslink/procmgr/procmgr_drv.c
new file mode 100755
index 000000000000..e35bb51259b6
--- /dev/null
+++ b/drivers/dsp/syslink/procmgr/procmgr_drv.c
@@ -0,0 +1,758 @@
+/*
+ * procmgr_drv.c
+ *
+ * Syslink driver support functions for TI OMAP processors.
+ *
+ * Copyright (C) 2009-2010 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+
+#include <linux/autoconf.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/cdev.h>
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/uaccess.h>
+#include <linux/platform_device.h>
+
+/* Module headers */
+#include <procmgr.h>
+#include "procmgr_drvdefs.h"
+
+#define PROCMGR_NAME "syslink-procmgr"
+
+static char *driver_name = PROCMGR_NAME;
+
+static s32 driver_major;
+
+static s32 driver_minor;
+
+struct procmgr_dev {
+ struct cdev cdev;
+};
+
+struct platform_device *omap_proc_dev;
+static struct platform_device *procmgr_pdev;
+static struct procmgr_dev *procmgr_device;
+
+static struct class *proc_mgr_class;
+
+
+/** ====================================
+ * Forward declarations of internal functions
+ * ====================================
+ */
+/* Linux driver function to open the driver object. */
+static int proc_mgr_drv_open(struct inode *inode, struct file *filp);
+
+/* Linux driver function to close the driver object. */
+static int proc_mgr_drv_release(struct inode *inode, struct file *filp);
+
+/* Linux driver function to invoke the APIs through ioctl. */
+static int proc_mgr_drv_ioctl(struct inode *inode,
+ struct file *filp,
+ unsigned int cmd,
+ unsigned long args);
+
+/* Linux driver function to map memory regions to user space. */
+static int proc_mgr_drv_mmap(struct file *filp, struct vm_area_struct *vma);
+
+/* Module initialization function for Linux driver. */
+static int __init proc_mgr_drv_initialize_module(void);
+
+/* Module finalization function for Linux driver. */
+static void __exit proc_mgr_drv_finalize_module(void);
+
+/* Platform driver probe function */
+static int __devinit proc_mgr_probe(struct platform_device *pdev);
+
+/* Platform driver remove function */
+static int __devexit proc_mgr_remove(struct platform_device *pdev);
+
+/*
+ * name DriverOps
+ *
+ * desc Function to invoke the APIs through ioctl
+ *
+ */
+static const struct file_operations procmgr_fops = {
+ .open = proc_mgr_drv_open,
+ .ioctl = proc_mgr_drv_ioctl,
+ .release = proc_mgr_drv_release,
+ .mmap = proc_mgr_drv_mmap,
+} ;
+
+/* Imtiaz changed places */
+static struct platform_driver procmgr_driver_ldm = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = PROCMGR_NAME,
+ },
+ .probe = proc_mgr_probe,
+ .remove = __devexit_p(proc_mgr_remove),
+ .shutdown = NULL,
+ .suspend = NULL,
+ .resume = NULL,
+};
+
+/*
+* brief Linux specific function to open the driver.
+ */
+static int proc_mgr_drv_open(struct inode *inode, struct file *filp)
+{
+ return 0;
+}
+
+/*
+* brief Linux driver function to close the driver object.
+ */
+static int proc_mgr_drv_release(struct inode *inode, struct file *filp)
+{
+ return 0;
+}
+
+/*
+* Linux driver function to invoke the APIs through ioctl.
+ */
+static int proc_mgr_drv_ioctl(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long args)
+{
+ int retval = 0;
+ struct proc_mgr_cmd_args *cmd_args = (struct proc_mgr_cmd_args *)args;
+ struct proc_mgr_cmd_args command_args;
+
+ switch (cmd) {
+ case CMD_PROCMGR_GETCONFIG:
+ {
+ struct proc_mgr_cmd_args_get_config *src_args =
+ (struct proc_mgr_cmd_args_get_config *)args;
+ struct proc_mgr_config cfg;
+
+ /* copy_from_user is not needed for proc_mgr_get_config,
+ * since the user's config is not used.
+ */
+ proc_mgr_get_config(&cfg);
+
+ retval = copy_to_user((void *)(src_args->cfg),
+ (const void *)&cfg,
+ sizeof(struct proc_mgr_config));
+
+ WARN_ON(retval < 0);
+ }
+ break;
+
+ case CMD_PROCMGR_SETUP:
+ {
+ struct proc_mgr_cmd_args_setup *src_args =
+ (struct proc_mgr_cmd_args_setup *)args;
+ struct proc_mgr_config cfg;
+
+ retval = copy_from_user((void *)&cfg,
+ (const void *)(src_args->cfg),
+ sizeof(struct proc_mgr_config));
+
+ /* This check is needed at run-time also since it
+ * depends on run environment.
+ * It must not be optimized out.
+ */
+ if (WARN_ON(retval != 0))
+ goto func_exit;
+
+ retval = proc_mgr_setup(&cfg);
+ }
+ break;
+
+ case CMD_PROCMGR_DESTROY:
+ {
+ retval = proc_mgr_destroy();
+ WARN_ON(retval < 0);
+ }
+ break;
+
+ case CMD_PROCMGR_PARAMS_INIT:
+ {
+ struct proc_mgr_cmd_args_params_init src_args;
+ struct proc_mgr_params params;
+
+ /* Copy the full args from user-side. */
+ retval = copy_from_user((void *)&src_args,
+ (const void *)(args),
+ sizeof(struct proc_mgr_cmd_args_params_init));
+
+ if (WARN_ON(retval != 0))
+ goto func_exit;
+
+ proc_mgr_params_init(src_args.handle, &params);
+
+ /* Copy only the params to user-side */
+ retval = copy_to_user((void *)(src_args.params),
+ (const void *)&params,
+ sizeof(struct proc_mgr_params));
+ WARN_ON(retval < 0);
+ }
+ break;
+
+ case CMD_PROCMGR_CREATE:
+ {
+ struct proc_mgr_cmd_args_create src_args;
+
+ /* Copy the full args from user-side. */
+ retval = copy_from_user((void *)&src_args,
+ (const void *)(args),
+ sizeof(struct proc_mgr_cmd_args_create));
+
+ src_args.handle = proc_mgr_create(src_args.proc_id,
+ &(src_args.params));
+ if (src_args.handle == NULL) {
+ retval = -EFAULT;
+ goto func_exit;
+ }
+ retval = copy_to_user((void *)(args),
+ (const void *)&src_args,
+ sizeof(struct proc_mgr_cmd_args_create));
+ WARN_ON(retval < 0);
+ }
+ break;
+
+ case CMD_PROCMGR_DELETE:
+ {
+ struct proc_mgr_cmd_args_delete src_args;
+
+ /* Copy the full args from user-side. */
+ retval = copy_from_user((void *)&src_args,
+ (const void *)(args),
+ sizeof(struct proc_mgr_cmd_args_delete));
+ if (WARN_ON(retval != 0))
+ goto func_exit;
+
+ retval = proc_mgr_delete(&(src_args.handle));
+ }
+ break;
+
+ case CMD_PROCMGR_OPEN:
+ {
+ struct proc_mgr_cmd_args_open src_args;
+
+ /* Copy the full args from user-side. */
+ retval = copy_from_user((void *)&src_args,
+ (const void *)(args),
+ sizeof(struct proc_mgr_cmd_args_open));
+
+ if (WARN_ON(retval != 0))
+ goto func_exit;
+ retval = proc_mgr_open(&(src_args.handle),
+ src_args.proc_id);
+ if (WARN_ON(retval < 0))
+ goto func_exit;
+ retval = proc_mgr_get_proc_info(src_args.handle,
+ &(src_args.proc_info));
+ if (WARN_ON(retval < 0))
+ goto func_exit;
+ retval = copy_to_user((void *)(args), (const void *)&src_args,
+ sizeof(struct proc_mgr_cmd_args_open));
+ WARN_ON(retval);
+ }
+ break;
+
+ case CMD_PROCMGR_CLOSE:
+ {
+ struct proc_mgr_cmd_args_close src_args;
+
+ /* Copy the full args from user-side. */
+ retval = copy_from_user((void *)&src_args,
+ (const void *)(args),
+ sizeof(struct proc_mgr_cmd_args_close));
+ if (WARN_ON(retval != 0))
+ goto func_exit;
+ retval = proc_mgr_close(&(src_args.handle));
+ }
+ break;
+
+ case CMD_PROCMGR_GETATTACHPARAMS:
+ {
+ struct proc_mgr_cmd_args_get_attach_params src_args;
+ struct proc_mgr_attach_params params;
+
+ /* Copy the full args from user-side. */
+ retval = copy_from_user((void *)&src_args,
+ (const void *)(args),
+ sizeof(struct proc_mgr_cmd_args_get_attach_params));
+ if (WARN_ON(retval != 0))
+ goto func_exit;
+ proc_mgr_get_attach_params(src_args.handle, &params);
+ retval = copy_to_user((void *)(src_args.params),
+ (const void *)&params,
+ sizeof(struct proc_mgr_attach_params));
+ WARN_ON(retval);
+ }
+ break;
+
+ case CMD_PROCMGR_ATTACH:
+ {
+ struct proc_mgr_cmd_args_attach src_args;
+ struct proc_mgr_attach_params params;
+
+ /* Copy the full args from user-side. */
+ retval = copy_from_user((void *)&src_args,
+ (const void *)(args),
+ sizeof(struct proc_mgr_cmd_args_attach));
+ if (WARN_ON(retval != 0))
+ goto func_exit;
+ /* Copy params from user-side. */
+ retval = copy_from_user((void *)&params,
+ (const void *)(src_args.params),
+ sizeof(struct proc_mgr_attach_params));
+ retval = proc_mgr_attach(src_args.handle, &params);
+ if (WARN_ON(retval < 0))
+ goto func_exit;
+ /* Get memory information. */
+ retval = proc_mgr_get_proc_info(src_args.handle,
+ &(src_args.proc_info));
+ if (WARN_ON(retval < 0))
+ goto func_exit;
+ retval = copy_to_user((void *)(args),
+ (const void *)&src_args,
+ sizeof(struct proc_mgr_cmd_args_attach));
+ }
+ break;
+
+ case CMD_PROCMGR_DETACH:
+ {
+ struct proc_mgr_cmd_args_detach src_args;
+
+ /* Copy the full args from user-side. */
+ retval = copy_from_user((void *)&src_args,
+ (const void *)(args),
+ sizeof(struct proc_mgr_cmd_args_detach));
+ if (WARN_ON(retval != 0))
+ goto func_exit;
+ retval = proc_mgr_detach(src_args.handle);
+ if (WARN_ON(retval < 0))
+ goto func_exit;
+ }
+ break;
+
+ case CMD_PROCMGR_GETSTARTPARAMS:
+ {
+ struct proc_mgr_cmd_args_get_start_params src_args;
+ struct proc_mgr_start_params params;
+
+ /* Copy the full args from user-side. */
+ retval = copy_from_user((void *)&src_args,
+ (const void *)(args),
+ sizeof(struct proc_mgr_cmd_args_get_start_params));
+ if (WARN_ON(retval != 0))
+ goto func_exit;
+ proc_mgr_get_start_params(src_args.handle, &params);
+ if (WARN_ON(retval < 0))
+ goto func_exit;
+ retval = copy_to_user((void *)(src_args.params),
+ (const void *)&params,
+ sizeof(struct proc_mgr_start_params));
+ WARN_ON(retval);
+ }
+ break;
+
+ case CMD_PROCMGR_START:
+ {
+ struct proc_mgr_cmd_args_start src_args;
+ struct proc_mgr_start_params params;
+
+ /* Copy the full args from user-side. */
+ retval = copy_from_user((void *)&src_args,
+ (const void *)(args),
+ sizeof(struct proc_mgr_cmd_args_start));
+ /* Copy params from user-side. */
+ retval = copy_from_user((void *)&params,
+ (const void *)(src_args.params),
+ sizeof(struct proc_mgr_start_params));
+ if (WARN_ON(retval != 0))
+ goto func_exit;
+ retval = proc_mgr_start(src_args.handle,
+ src_args.entry_point, &params);
+
+ WARN_ON(retval);
+ }
+ break;
+
+ case CMD_PROCMGR_STOP:
+ {
+ struct proc_mgr_cmd_args_stop src_args;
+
+ struct proc_mgr_stop_params params;
+ /* Copy the full args from user-side. */
+ retval = copy_from_user((void *)&src_args,
+ (const void *)(args),
+ sizeof(struct proc_mgr_cmd_args_stop));
+ /* Copy params from user-side. */
+ retval = copy_from_user((void *)&params,
+ (const void *)(src_args.params),
+ sizeof(struct proc_mgr_stop_params));
+
+ if (WARN_ON(retval != 0))
+ goto func_exit;
+ retval = proc_mgr_stop(src_args.handle, &params);
+ WARN_ON(retval < 0);
+ }
+ break;
+
+ case CMD_PROCMGR_GETSTATE:
+ {
+ struct proc_mgr_cmd_args_get_state src_args;
+ enum proc_mgr_state procmgrstate;
+
+ /* Copy the full args from user-side. */
+ retval = copy_from_user((void *)&src_args,
+ (const void *)(args),
+ sizeof(struct proc_mgr_cmd_args_get_state));
+ if (WARN_ON(retval != 0))
+ goto func_exit;
+ procmgrstate = proc_mgr_get_state(src_args.handle);
+ src_args.proc_mgr_state = procmgrstate;
+ retval = copy_to_user((void *)(args), (const void *)&src_args,
+ sizeof(struct proc_mgr_cmd_args_get_state));
+ WARN_ON(retval < 0);
+ }
+ break;
+
+ case CMD_PROCMGR_READ:
+ {
+ struct proc_mgr_cmd_args_read src_args;
+
+ /* Copy the full args from user-side. */
+ retval = copy_from_user((void *)&src_args,
+ (const void *)(args),
+ sizeof(struct proc_mgr_cmd_args_read));
+ if (WARN_ON(retval != 0))
+ goto func_exit;
+ retval = proc_mgr_read(src_args.handle,
+ src_args.proc_addr, &(src_args.num_bytes),
+ src_args.buffer);
+ if (WARN_ON(retval < 0))
+ goto func_exit;
+ retval = copy_to_user((void *)(args),
+ (const void *)&src_args,
+ sizeof(struct proc_mgr_cmd_args_read));
+ WARN_ON(retval < 0);
+ }
+ break;
+
+ case CMD_PROCMGR_WRITE:
+ {
+ struct proc_mgr_cmd_args_write src_args;
+
+ /* Copy the full args from user-side. */
+ retval = copy_from_user((void *)&src_args,
+ (const void *)(args),
+ sizeof(struct proc_mgr_cmd_args_write));
+ if (WARN_ON(retval != 0))
+ goto func_exit;
+ retval = proc_mgr_write(src_args.handle,
+ src_args.proc_addr, &(src_args.num_bytes),
+ src_args.buffer);
+ if (WARN_ON(retval < 0))
+ goto func_exit;
+ retval = copy_to_user((void *)(args),
+ (const void *)&src_args,
+ sizeof(struct proc_mgr_cmd_args_write));
+ WARN_ON(retval < 0);
+ }
+ break;
+
+ case CMD_PROCMGR_CONTROL:
+ {
+ struct proc_mgr_cmd_args_control src_args;
+
+ /* Copy the full args from user-side. */
+ retval = copy_from_user((void *)&src_args,
+ (const void *)(args),
+ sizeof(struct proc_mgr_cmd_args_control));
+ if (WARN_ON(retval != 0))
+ goto func_exit;
+ retval = proc_mgr_control(src_args.handle,
+ src_args.cmd, src_args.arg);
+ WARN_ON(retval < 0);
+ }
+ break;
+
+ case CMD_PROCMGR_TRANSLATEADDR:
+ {
+ struct proc_mgr_cmd_args_translate_addr src_args;
+
+ /* Copy the full args from user-side. */
+ retval = copy_from_user((void *)&src_args,
+ (const void *)(args),
+ sizeof(struct proc_mgr_cmd_args_translate_addr));
+ if (WARN_ON(retval != 0))
+ goto func_exit;
+ retval = proc_mgr_translate_addr(src_args.handle,
+ &(src_args.dst_addr), src_args.dst_addr_type,
+ src_args.src_addr, src_args.src_addr_type);
+ if (WARN_ON(retval < 0))
+ goto func_exit;
+ retval = copy_to_user((void *)(args),
+ (const void *)&src_args, sizeof
+ (struct proc_mgr_cmd_args_translate_addr));
+ WARN_ON(retval < 0);
+ }
+ break;
+
+ case CMD_PROCMGR_MAP:
+ {
+ struct proc_mgr_cmd_args_map src_args;
+
+ /* Copy the full args from user-side. */
+ retval = copy_from_user((void *)&src_args,
+ (const void *)(args),
+ sizeof(struct proc_mgr_cmd_args_map));
+ if (WARN_ON(retval != 0))
+ goto func_exit;
+ retval = proc_mgr_map(src_args.handle,
+ src_args.proc_addr, src_args.size,
+ &(src_args.mapped_addr),
+ &(src_args.mapped_size),
+ src_args.map_attribs);
+ if (WARN_ON(retval < 0))
+ goto func_exit;
+ retval = copy_to_user((void *)(args),
+ (const void *)&src_args,
+ sizeof(struct proc_mgr_cmd_args_map));
+ WARN_ON(retval < 0);
+ }
+ break;
+
+ case CMD_PROCMGR_UNMAP:
+ {
+ struct proc_mgr_cmd_args_unmap src_args;
+
+ /* Copy the full args from user-side. */
+ retval = copy_from_user((void *)&src_args,
+ (const void *)(args),
+ sizeof(struct proc_mgr_cmd_args_unmap));
+ if (WARN_ON(retval != 0))
+ goto func_exit;
+ retval = proc_mgr_unmap(src_args.handle,
+ (src_args.mapped_addr));
+ WARN_ON(retval < 0);
+ }
+
+ case CMD_PROCMGR_REGISTERNOTIFY:
+ {
+ struct proc_mgr_cmd_args_register_notify src_args;
+
+ /* Copy the full args from user-side. */
+ retval = copy_from_user((void *)&src_args,
+ (const void *)(args),
+ sizeof(struct proc_mgr_cmd_args_register_notify));
+ if (WARN_ON(retval != 0))
+ goto func_exit;
+ retval = proc_mgr_register_notify(src_args.handle,
+ src_args.callback_fxn,
+ src_args.args, src_args.state);
+ WARN_ON(retval < 0);
+ }
+ break;
+
+ case CMD_PROCMGR_GETPROCINFO:
+ {
+ struct proc_mgr_cmd_args_get_proc_info src_args;
+ struct proc_mgr_proc_info proc_info;
+
+ /* Copy the full args from user-side. */
+ retval = copy_from_user((void *)&src_args,
+ (const void *)(args),
+ sizeof(struct proc_mgr_cmd_args_get_proc_info));
+ if (WARN_ON(retval != 0))
+ goto func_exit;
+ retval = proc_mgr_get_proc_info
+ (src_args.handle, &proc_info);
+ if (WARN_ON(retval < 0))
+ goto func_exit;
+ retval = copy_to_user((void *)(src_args.proc_info),
+ (const void *) &proc_info,
+ sizeof(struct proc_mgr_proc_info));
+ WARN_ON(retval < 0);
+ }
+ break;
+
+ case CMD_PROCMGR_GETVIRTTOPHYS:
+ {
+ struct proc_mgr_cmd_args_get_virt_to_phys src_args;
+
+ retval = copy_from_user((void *)&src_args,
+ (const void *)(args),
+ sizeof(struct proc_mgr_cmd_args_get_virt_to_phys));
+ retval = proc_mgr_virt_to_phys(src_args.handle,
+ src_args.da, (src_args.mem_entries),
+ src_args.num_of_entries);
+ if (WARN_ON(retval < 0))
+ goto func_exit;
+ retval = copy_to_user((void *)(args), (const void *)&src_args,
+ sizeof(struct proc_mgr_cmd_args_get_virt_to_phys));
+ WARN_ON(retval < 0);
+ }
+ break;
+
+ default:
+ printk(KERN_ERR"PROC_MGR_DRV: WRONG IOCTL !!!!\n");
+ BUG_ON(1);
+ break;
+ }
+func_exit:
+ /* Set the retval and copy the common args to user-side. */
+ command_args.api_status = retval;
+ retval = copy_to_user((void *)cmd_args,
+ (const void *)&command_args, sizeof(struct proc_mgr_cmd_args));
+
+ WARN_ON(retval < 0);
+ return retval;
+}
+
+
+/*
+ Driver function to map memory regions to user space.
+ */
+static int proc_mgr_drv_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ vma->vm_flags |= VM_RESERVED;
+
+ if (remap_pfn_range(vma,
+ vma->vm_start,
+ vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot)) {
+ return -EAGAIN;
+ }
+ return 0;
+}
+
+static int __devinit proc_mgr_probe(struct platform_device *pdev)
+{
+ dev_t dev = 0 ;
+ int retval = -ENOMEM;
+
+ /* Display the version info and created date/time */
+ dev_dbg(&omap_proc_dev->dev, "Entering %s function\n\n", __func__);
+
+ if (driver_major) {
+ dev = MKDEV(driver_major, driver_minor);
+ retval = register_chrdev_region(dev, 1, driver_name);
+ } else {
+ retval = alloc_chrdev_region(&dev, driver_minor, 1,
+ driver_name);
+ driver_major = MAJOR(dev);
+ }
+
+ procmgr_device = kmalloc(sizeof(struct procmgr_dev), GFP_KERNEL);
+ if (!procmgr_device) {
+ retval = -ENOMEM;
+ unregister_chrdev_region(dev, 1);
+ goto exit;
+ }
+ memset(procmgr_device, 0, sizeof(struct procmgr_dev));
+ cdev_init(&procmgr_device->cdev, &procmgr_fops);
+ procmgr_device->cdev.owner = THIS_MODULE;
+ procmgr_device->cdev.ops = &procmgr_fops;
+
+ retval = cdev_add(&procmgr_device->cdev, dev, 1);
+
+ if (retval) {
+ printk(KERN_ERR "Failed to add the syslink procmgr device \n");
+ goto exit;
+ }
+
+ /* udev support */
+ proc_mgr_class = class_create(THIS_MODULE, "syslink-procmgr");
+
+ if (IS_ERR(proc_mgr_class)) {
+ printk(KERN_ERR "Error creating bridge class \n");
+ goto exit;
+ }
+ device_create(proc_mgr_class, NULL, MKDEV(driver_major, driver_minor),
+ NULL, PROCMGR_NAME);
+
+exit:
+ dev_dbg(&omap_proc_dev->dev, "Leaving %s function\n\n", __func__);
+ return retval;
+}
+
+
+static int __devexit proc_mgr_remove(struct platform_device *pdev)
+{
+ dev_t devno = 0;
+
+ dev_dbg(&omap_proc_dev->dev, "Entering %s function\n", __func__);
+ devno = MKDEV(driver_major, driver_minor);
+ if (procmgr_device) {
+ cdev_del(&procmgr_device->cdev);
+ kfree(procmgr_device);
+ }
+ unregister_chrdev_region(devno, 1);
+ if (proc_mgr_class) {
+ /* remove the device from sysfs */
+ device_destroy(proc_mgr_class, MKDEV(driver_major,
+ driver_minor));
+ class_destroy(proc_mgr_class);
+ }
+ dev_dbg(&omap_proc_dev->dev, "Entering %s function\n", __func__);
+ return 0;
+}
+
+/*
+* Module initialization function for Linux driver.
+ */
+static int __init proc_mgr_drv_initialize_module(void)
+{
+ int retval = -ENOMEM;
+
+ procmgr_pdev = platform_device_alloc(PROCMGR_NAME, -1);
+ if (!procmgr_pdev) {
+ printk(KERN_ERR "%s:device allocation failed\n", __func__);
+ return -ENOMEM;
+ }
+ retval = platform_device_add(procmgr_pdev);
+ if (retval)
+ goto err_out;
+
+ /*Saving the context for future use*/
+ omap_proc_dev = procmgr_pdev;
+
+ retval = platform_driver_register(&procmgr_driver_ldm);
+ if (!retval)
+ return retval;
+err_out:
+ platform_device_put(procmgr_pdev);
+ return retval;
+}
+
+/*
+* driver function to finalize the driver module.
+ */
+static void __exit proc_mgr_drv_finalize_module(void)
+{
+
+ dev_dbg(&omap_proc_dev->dev, "Entering %s function\n", __func__);
+ platform_device_unregister(procmgr_pdev);
+ platform_driver_unregister(&procmgr_driver_ldm);
+ dev_dbg(&omap_proc_dev->dev, "Leaving %s function\n", __func__);
+}
+
+/*
+* brief Macro calls that indicate initialization and finalization functions
+ * to the kernel.
+ */
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Mugdha Kamoolkar");
+module_init(proc_mgr_drv_initialize_module);
+module_exit(proc_mgr_drv_finalize_module);
diff --git a/drivers/dsp/syslink/procmgr/procmgr_drvdefs.h b/drivers/dsp/syslink/procmgr/procmgr_drvdefs.h
new file mode 100755
index 000000000000..2be14bf7a20e
--- /dev/null
+++ b/drivers/dsp/syslink/procmgr/procmgr_drvdefs.h
@@ -0,0 +1,541 @@
+/*
+ * procmgr_drvdefs.h
+ *
+ * Syslink driver support functions for TI OMAP processors.
+ *
+ * Copyright (C) 2009-2010 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+
+#ifndef SYSLINK_PROCMGR_DRVDEFS_H
+#define SYSLINK_PROCMGR_DRVDEFS_H
+
+#include <linux/types.h>
+
+/* Module headers */
+#include <procmgr.h>
+
+
+/* =================================
+ * Macros and types
+ * =================================
+ */
+/*
+ * Base structure for ProcMgr command args. This needs to be the first
+ * field in all command args structures.
+ */
+struct proc_mgr_cmd_args {
+ int api_status;
+ /*Status of the API being called. */
+};
+
+/* --------------------------------------
+ * IOCTL command IDs for ProcMgr
+ * ---------------------------------------
+ */
+/*
+ * Base command ID for ProcMgr
+ */
+#define PROCMGR_BASE_CMD 0x100
+
+/*
+ * Command for ProcMgr_getConfig
+ */
+#define CMD_PROCMGR_GETCONFIG (PROCMGR_BASE_CMD + 1)
+
+/*
+ * Command for ProcMgr_setup
+ */
+#define CMD_PROCMGR_SETUP (PROCMGR_BASE_CMD + 2)
+
+/*
+ * Command for ProcMgr_setup
+ */
+#define CMD_PROCMGR_DESTROY (PROCMGR_BASE_CMD + 3)
+
+/*
+ * Command for ProcMgr_destroy
+ */
+#define CMD_PROCMGR_PARAMS_INIT (PROCMGR_BASE_CMD + 4)
+
+/*
+ * Command for ProcMgr_create
+ */
+#define CMD_PROCMGR_CREATE (PROCMGR_BASE_CMD + 5)
+
+/*
+ * Command for ProcMgr_delete
+ */
+#define CMD_PROCMGR_DELETE (PROCMGR_BASE_CMD + 6)
+
+/*
+ * Command for ProcMgr_open
+ */
+#define CMD_PROCMGR_OPEN (PROCMGR_BASE_CMD + 7)
+
+/*
+ * Command for ProcMgr_close
+ */
+#define CMD_PROCMGR_CLOSE (PROCMGR_BASE_CMD + 8)
+
+/*
+ * Command for ProcMgr_getAttachParams
+ */
+#define CMD_PROCMGR_GETATTACHPARAMS (PROCMGR_BASE_CMD + 9)
+
+/*
+ * Command for ProcMgr_attach
+ */
+#define CMD_PROCMGR_ATTACH (PROCMGR_BASE_CMD + 10)
+
+/*
+ * Command for ProcMgr_detach
+ */
+#define CMD_PROCMGR_DETACH (PROCMGR_BASE_CMD + 11)
+
+/*
+ * Command for ProcMgr_load
+ */
+#define CMD_PROCMGR_LOAD (PROCMGR_BASE_CMD + 12)
+
+/*
+ * Command for ProcMgr_unload
+ */
+#define CMD_PROCMGR_UNLOAD (PROCMGR_BASE_CMD + 13)
+
+/*
+ * Command for ProcMgr_getStartParams
+ */
+#define CMD_PROCMGR_GETSTARTPARAMS (PROCMGR_BASE_CMD + 14)
+
+/*
+ * Command for ProcMgr_start
+ */
+#define CMD_PROCMGR_START (PROCMGR_BASE_CMD + 15)
+
+/*
+ * Command for ProcMgr_stop
+ */
+#define CMD_PROCMGR_STOP (PROCMGR_BASE_CMD + 16)
+
+/*
+ * Command for ProcMgr_getState
+ */
+#define CMD_PROCMGR_GETSTATE (PROCMGR_BASE_CMD + 17)
+
+/*
+ * Command for ProcMgr_read
+ */
+#define CMD_PROCMGR_READ (PROCMGR_BASE_CMD + 18)
+
+/*
+ * Command for ProcMgr_write
+ */
+#define CMD_PROCMGR_WRITE (PROCMGR_BASE_CMD + 19)
+
+/*
+ * Command for ProcMgr_control
+ */
+#define CMD_PROCMGR_CONTROL (PROCMGR_BASE_CMD + 20)
+
+/*
+ * Command for ProcMgr_translateAddr
+ */
+#define CMD_PROCMGR_TRANSLATEADDR (PROCMGR_BASE_CMD + 22)
+
+/*
+ * Command for ProcMgr_getSymbolAddress
+ */
+#define CMD_PROCMGR_GETSYMBOLADDRESS (PROCMGR_BASE_CMD + 23)
+
+/*
+ * Command for ProcMgr_map
+ */
+#define CMD_PROCMGR_MAP (PROCMGR_BASE_CMD + 24)
+
+/*
+ * Command for ProcMgr_registerNotify
+ */
+#define CMD_PROCMGR_REGISTERNOTIFY (PROCMGR_BASE_CMD + 25)
+
+/*
+ * Command for ProcMgr_getProcInfo
+ */
+#define CMD_PROCMGR_GETPROCINFO (PROCMGR_BASE_CMD + 26)
+
+/*
+ * Command for ProcMgr_unmap
+ */
+#define CMD_PROCMGR_UNMAP (PROCMGR_BASE_CMD + 27)
+
+/*
+ * Command for ProcMgr_getVirtToPhysPages
+ */
+#define CMD_PROCMGR_GETVIRTTOPHYS (PROCMGR_BASE_CMD + 28)
+
+
+
+
+/* ----------------------------------------------------------------------------
+ * Command arguments for ProcMgr
+ * ----------------------------------------------------------------------------
+ */
+/*
+ * Command arguments for ProcMgr_getConfig
+ */
+struct proc_mgr_cmd_args_get_config {
+ struct proc_mgr_cmd_args commond_args;
+ /*Common command args */
+ struct proc_mgr_config *cfg;
+ /*Pointer to the ProcMgr module configuration structure in which the
+ default config is to be returned. */
+};
+
+/*
+ * Command arguments for ProcMgr_setup
+ */
+struct proc_mgr_cmd_args_setup {
+ struct proc_mgr_cmd_args commond_args;
+ /*Common command args */
+ struct proc_mgr_config *cfg;
+ /*Optional ProcMgr module configuration. If provided as NULL, default
+ configuration is used. */
+};
+
+/*
+ * Command arguments for ProcMgr_destroy
+ */
+struct proc_mgr_cmd_args_destroy {
+ struct proc_mgr_cmd_args commond_args;
+ /*Common command args */
+};
+
+/*
+ * Command arguments for ProcMgr_Params_init
+ */
+struct proc_mgr_cmd_args_params_init {
+ struct proc_mgr_cmd_args commond_args;
+ /*Common command args */
+ void *handle;
+ /*Handle to the ProcMgr object. */
+ struct proc_mgr_params *params;
+ /*Pointer to the ProcMgr instance params structure in which the default
+ params is to be returned. */
+};
+
+/*
+ * Command arguments for ProcMgr_create
+ */
+struct proc_mgr_cmd_args_create {
+ struct proc_mgr_cmd_args commond_args;
+ /*Common command args */
+ u16 proc_id;
+ /*Processor ID represented by this ProcMgr instance */
+ struct proc_mgr_params params;
+ /*ProcMgr instance configuration parameters. */
+ void *handle;
+ /*Handle to the created ProcMgr object */
+};
+
+/*
+ * Command arguments for ProcMgr_delete
+ */
+struct proc_mgr_cmd_args_delete{
+ struct proc_mgr_cmd_args commond_args;
+ /*Common command args */
+ void *handle;
+ /*Pointer to Handle to the ProcMgr object */
+};
+
+/*
+ * Command arguments for ProcMgr_open
+ */
+struct proc_mgr_cmd_args_open {
+ struct proc_mgr_cmd_args commond_args;
+ /*Common command args */
+ u16 proc_id;
+ /*Processor ID represented by this ProcMgr instance */
+ void *handle;
+ /*Handle to the opened ProcMgr object. */
+ struct proc_mgr_proc_info proc_info;
+ /*Processor information. */
+};
+
+/*
+ * Command arguments for ProcMgr_close
+ */
+struct proc_mgr_cmd_args_close{
+ struct proc_mgr_cmd_args commond_args;
+ /*Common command args */
+ void *handle;
+ /*Handle to the ProcMgr object */
+ struct proc_mgr_proc_info proc_info;
+ /*Processor information. */
+};
+
+/*
+ * Command arguments for ProcMgr_getAttachParams
+ */
+struct proc_mgr_cmd_args_get_attach_params{
+ struct proc_mgr_cmd_args commond_args;
+ /*Common command args */
+ void *handle;
+ /*Handle to the ProcMgr object. */
+ struct proc_mgr_attach_params *params;
+ /*Pointer to the ProcMgr attach params structure in which the default
+ params is to be returned. */
+};
+
+/*
+ * Command arguments for ProcMgr_attach
+ */
+struct proc_mgr_cmd_args_attach {
+ struct proc_mgr_cmd_args commond_args;
+ /*Common command args */
+ void *handle;
+ /*Handle to the ProcMgr object. */
+ struct proc_mgr_attach_params *params;
+ /*Optional ProcMgr attach parameters. */
+ struct proc_mgr_proc_info proc_info;
+ /*Processor information. */
+};
+
+/*
+ * Command arguments for ProcMgr_detach
+ */
+struct proc_mgr_cmd_args_detach {
+ struct proc_mgr_cmd_args commond_args;
+ /*Common command args */
+ void *handle;
+ /*Handle to the ProcMgr object */
+ struct proc_mgr_proc_info proc_info;
+ /*Processor information. */
+};
+
+
+/*
+ * Command arguments for ProcMgr_getStartParams
+ */
+struct proc_mgr_cmd_args_get_start_params {
+ struct proc_mgr_cmd_args commond_args;
+ /*Common command args */
+ void *handle;
+ /*Entry point for the image*/
+ u32 entry_point;
+ /*Handle to the ProcMgr object */
+ struct proc_mgr_start_params *params;
+ /*Pointer to the ProcMgr start params structure in which the default
+ params is to be returned. */
+};
+
+/*
+ * Command arguments for ProcMgr_start
+ */
+struct proc_mgr_cmd_args_start {
+ struct proc_mgr_cmd_args commond_args;
+ /*Common command args */
+ void *handle;
+ /*Entry point for the image*/
+ u32 entry_point;
+ /*Handle to the ProcMgr object */
+ struct proc_mgr_start_params *params;
+ /*Optional ProcMgr start parameters. */
+};
+
+/*
+ * Command arguments for ProcMgr_stop
+ */
+struct proc_mgr_cmd_args_stop {
+ struct proc_mgr_cmd_args commond_args;
+ /*Common command args */
+ void *handle;
+ /*Handle to the ProcMgr object */
+ struct proc_mgr_stop_params *params;
+ /*Optional ProcMgr stop parameters. */
+};
+
+/*
+ * Command arguments for ProcMgr_getState
+ */
+struct proc_mgr_cmd_args_get_state {
+ struct proc_mgr_cmd_args commond_args;
+ /*Common command args */
+ void *handle;
+ /* Handle to the ProcMgr object */
+ enum proc_mgr_state proc_mgr_state;
+ /*Current state of the ProcMgr object. */
+};
+
+/*
+ * Command arguments for ProcMgr_read
+ */
+struct proc_mgr_cmd_args_read {
+ struct proc_mgr_cmd_args commond_args;
+ /*Common command args */
+ void *handle;
+ /*Handle to the ProcMgr object */
+ u32 proc_addr;
+ /*Address in space processor's address space of the memory region to
+ read from. */
+ u32 num_bytes;
+ /*IN/OUT parameter. As an IN-parameter, it takes in the number of bytes
+ to be read. When the function returns, this parameter contains the
+ number of bytes actually read. */
+ void *buffer;
+ /*User-provided buffer in which the slave processor's memory contents
+ are to be copied. */
+};
+
+/*
+ * Command arguments for ProcMgr_write
+ */
+struct proc_mgr_cmd_args_write {
+ struct proc_mgr_cmd_args commond_args;
+ /*Common command args */
+ void *handle;
+ /*Handle to the ProcMgr object */
+ u32 proc_addr;
+ /*Address in space processor's address space of the memory region to
+ write into. */
+ u32 num_bytes;
+ /*IN/OUT parameter. As an IN-parameter, it takes in the number of bytes
+ to be written. When the function returns, this parameter contains the
+ number of bytes actually written. */
+ void *buffer;
+ /*User-provided buffer from which the data is to be written into the
+ slave processor's memory. */
+};
+
+/*
+ * Command arguments for ProcMgr_control
+ */
+struct proc_mgr_cmd_args_control {
+ struct proc_mgr_cmd_args commond_args;
+ /*Common command args */
+ void *handle;
+ /*Handle to the ProcMgr object */
+ int cmd;
+ /*Device specific processor command */
+ void *arg;
+ /*Arguments specific to the type of command. */
+};
+
+/*
+ * Command arguments for ProcMgr_translateAddr
+ */
+struct proc_mgr_cmd_args_translate_addr {
+ struct proc_mgr_cmd_args commond_args;
+ /*Common command args */
+ void *handle;
+ /*Handle to the ProcMgr object */
+ void *dst_addr;
+ /*Return parameter: Pointer to receive the translated address. */
+ enum proc_mgr_addr_type dst_addr_type;
+ /*Destination address type requested */
+ void *src_addr;
+ /*Source address in the source address space */
+ enum proc_mgr_addr_type src_addr_type;
+ /*Source address type */
+};
+
+/*
+ * Command arguments for ProcMgr_getSymbolAddress
+ */
+struct proc_mgr_cmd_args_get_symbol_address {
+ struct proc_mgr_cmd_args commond_args;
+ /*Common command args */
+ void *handle;
+ /*Handle to the ProcMgr object */
+ u32 file_id;
+ /*ID of the file received from the load function */
+ char *symbol_name;
+ /*Name of the symbol */
+ u32 sym_value;
+ /*Return parameter: Symbol address */
+};
+
+/*
+ * Command arguments for ProcMgr_map
+ */
+struct proc_mgr_cmd_args_map {
+ struct proc_mgr_cmd_args commond_args;
+ /*Common command args */
+ void *handle;
+ /*Handle to the ProcMgr object */
+ u32 proc_addr;
+ /*Slave address to be mapped */
+ u32 size;
+ /*Size (in bytes) of region to be mapped */
+ u32 mapped_addr;
+ /*Return parameter: Mapped address in host address space */
+ u32 mapped_size;
+ /*Return parameter: Mapped size */
+ u32 map_attribs;
+ /*Type of mapping. */
+};
+
+/*
+ * Command arguments for ProcMgr_map
+ */
+struct proc_mgr_cmd_args_unmap {
+ struct proc_mgr_cmd_args commond_args;
+ /*Common command args */
+ void *handle;
+ /*Handle to the ProcMgr object */
+ u32 mapped_addr;
+ /* Mapped address in host address space */
+};
+
+/*
+ * Command arguments for ProcMgr_registerNotify
+ */
+struct proc_mgr_cmd_args_register_notify {
+ struct proc_mgr_cmd_args commond_args;
+ /*Common command args */
+ void *handle;
+ /*Handle to the ProcMgr object */
+ int (*callback_fxn)(u16 proc_id, void *handle,
+ enum proc_mgr_state from_state, enum proc_mgr_state to_state);
+ /*Handling function to be registered. */
+ void *args;
+ /*Optional arguments associated with the handler fxn. */
+ enum proc_mgr_state state[];
+ /*Array of target states for which registration is required. */
+};
+
+/*
+ * Command arguments for ProcMgr_getProcInfo
+ */
+struct proc_mgr_cmd_args_get_proc_info {
+ struct proc_mgr_cmd_args commond_args;
+ /*Common command args */
+ void *handle;
+ /*Handle to the ProcMgr object */
+ struct proc_mgr_proc_info *proc_info;
+ /*Pointer to the ProcInfo object to be populated. */
+};
+
+/*
+ * Command arguments for ProcMgr_virtToPhys
+ */
+struct proc_mgr_cmd_args_get_virt_to_phys {
+ struct proc_mgr_cmd_args commond_args;
+ /*Common command args */
+ void *handle;
+ u32 da;
+ /* mem entries buffer */
+ u32 *mem_entries;
+ /* number of entries */
+ u32 num_of_entries;
+};
+
+#endif
+