2011-04-28 15:43:18

by Ramirez Luna, Omar

[permalink] [raw]
Subject: [PATCH v4 0/6] staging tidspbridge: iommu migration

DO-NOT-APPLY to staging yet.

Rework and rebase of the previous set of patches for iommu migration[1].

Reorganized the patches to avoid several iterations to change the same code.

Patches were tested with an OMAP3630 board, with both, basic samples and
gst-dsp; these are dependant on patch:
"OMAP: iovmm: fix SW flags passed by user"[2].

[1] http://bit.ly/lUxbRO
[2] http://bit.ly/mgSrr8

Fernando Guzman Lugo (3):
staging: tidspbridge: remove custom mmu code
staging: tidspbridge: remove dmm module
staging: tidspbridge: decouple mmu functions from regular code

Omar Ramirez Luna (3):
staging: tidspbridge: introduce mapping search based on device
address
staging: tidspbridge: replace custom mmu for omap iommu framework
staging: tidspbridge: mapping support when SG_CHAIN is not defined

drivers/staging/tidspbridge/Kconfig | 11 +
drivers/staging/tidspbridge/Makefile | 7 +-
drivers/staging/tidspbridge/core/_deh.h | 5 +-
drivers/staging/tidspbridge/core/_tiomap.h | 19 +-
drivers/staging/tidspbridge/core/dsp_mmu.c | 396 +++++++
drivers/staging/tidspbridge/core/io_sm.c | 181 +---
drivers/staging/tidspbridge/core/tiomap3430.c | 1087 +++-----------------
drivers/staging/tidspbridge/core/tiomap3430_pwr.c | 6 +-
drivers/staging/tidspbridge/core/tiomap_io.c | 14 +-
drivers/staging/tidspbridge/core/ue_deh.c | 115 +--
drivers/staging/tidspbridge/hw/EasiGlobal.h | 41 -
drivers/staging/tidspbridge/hw/MMUAccInt.h | 76 --
drivers/staging/tidspbridge/hw/MMURegAcM.h | 225 ----
drivers/staging/tidspbridge/hw/hw_defs.h | 58 -
drivers/staging/tidspbridge/hw/hw_mmu.c | 562 ----------
drivers/staging/tidspbridge/hw/hw_mmu.h | 163 ---
.../tidspbridge/include/dspbridge/cfgdefs.h | 1 -
.../staging/tidspbridge/include/dspbridge/dev.h | 24 -
.../staging/tidspbridge/include/dspbridge/dmm.h | 75 --
.../staging/tidspbridge/include/dspbridge/drv.h | 13 -
.../tidspbridge/include/dspbridge/dsp_mmu.h | 33 +
.../tidspbridge/include/dspbridge/dspdefs.h | 44 -
.../tidspbridge/include/dspbridge/dspioctl.h | 7 -
.../staging/tidspbridge/include/dspbridge/proc.h | 46 -
drivers/staging/tidspbridge/pmgr/dev.c | 63 +--
drivers/staging/tidspbridge/pmgr/dmm.c | 533 ----------
drivers/staging/tidspbridge/pmgr/dspapi.c | 36 +-
drivers/staging/tidspbridge/rmgr/drv.c | 14 -
drivers/staging/tidspbridge/rmgr/drv_interface.c | 2 -
drivers/staging/tidspbridge/rmgr/node.c | 57 +-
drivers/staging/tidspbridge/rmgr/proc.c | 224 +---
31 files changed, 684 insertions(+), 3454 deletions(-)
create mode 100644 drivers/staging/tidspbridge/core/dsp_mmu.c
delete mode 100644 drivers/staging/tidspbridge/hw/EasiGlobal.h
delete mode 100644 drivers/staging/tidspbridge/hw/MMUAccInt.h
delete mode 100644 drivers/staging/tidspbridge/hw/MMURegAcM.h
delete mode 100644 drivers/staging/tidspbridge/hw/hw_defs.h
delete mode 100644 drivers/staging/tidspbridge/hw/hw_mmu.c
delete mode 100644 drivers/staging/tidspbridge/hw/hw_mmu.h
delete mode 100644 drivers/staging/tidspbridge/include/dspbridge/dmm.h
create mode 100644 drivers/staging/tidspbridge/include/dspbridge/dsp_mmu.h
delete mode 100644 drivers/staging/tidspbridge/pmgr/dmm.c


2011-04-28 15:43:25

by Ramirez Luna, Omar

[permalink] [raw]
Subject: [PATCH v4 5/6] staging: tidspbridge: remove dmm module

From: Fernando Guzman Lugo <[email protected]>

With iommu migration in place, there is no need to manage the
dsp va space with dmm module or proc_reserve/unreserve functions.

Deprecate reserve/un_reserve ioctls, given that there is a heavy
usage of these functions, print error message only if dynamic debug
is enabled.

Signed-off-by: Fernando Guzman Lugo <[email protected]>
Signed-off-by: Omar Ramirez Luna <[email protected]>
---
drivers/staging/tidspbridge/Makefile | 2 +-
drivers/staging/tidspbridge/core/tiomap3430.c | 1 -
.../staging/tidspbridge/include/dspbridge/dev.h | 24 -
.../staging/tidspbridge/include/dspbridge/dmm.h | 75 ---
.../staging/tidspbridge/include/dspbridge/drv.h | 10 -
.../staging/tidspbridge/include/dspbridge/proc.h | 46 --
drivers/staging/tidspbridge/pmgr/dev.c | 61 +---
drivers/staging/tidspbridge/pmgr/dmm.c | 533 --------------------
drivers/staging/tidspbridge/pmgr/dspapi.c | 36 +-
drivers/staging/tidspbridge/rmgr/drv.c | 10 -
drivers/staging/tidspbridge/rmgr/drv_interface.c | 2 -
drivers/staging/tidspbridge/rmgr/node.c | 57 +--
drivers/staging/tidspbridge/rmgr/proc.c | 90 ----
13 files changed, 18 insertions(+), 929 deletions(-)
delete mode 100644 drivers/staging/tidspbridge/include/dspbridge/dmm.h
delete mode 100644 drivers/staging/tidspbridge/pmgr/dmm.c

diff --git a/drivers/staging/tidspbridge/Makefile b/drivers/staging/tidspbridge/Makefile
index 9c7f974..0bab58b 100644
--- a/drivers/staging/tidspbridge/Makefile
+++ b/drivers/staging/tidspbridge/Makefile
@@ -5,7 +5,7 @@ libcore = core/chnl_sm.o core/msg_sm.o core/io_sm.o core/tiomap3430.o \
core/tiomap3430_pwr.o core/tiomap_io.o \
core/ue_deh.o core/wdt.o core/dsp-clock.o core/sync.o
libpmgr = pmgr/chnl.o pmgr/io.o pmgr/msg.o pmgr/cod.o pmgr/dev.o pmgr/dspapi.o \
- pmgr/dmm.o pmgr/cmm.o pmgr/dbll.o
+ pmgr/cmm.o pmgr/dbll.o
librmgr = rmgr/dbdcd.o rmgr/disp.o rmgr/drv.o rmgr/mgr.o rmgr/node.o \
rmgr/proc.o rmgr/pwr.o rmgr/rmm.o rmgr/strm.o rmgr/dspdrv.o \
rmgr/nldr.o rmgr/drv_interface.o
diff --git a/drivers/staging/tidspbridge/core/tiomap3430.c b/drivers/staging/tidspbridge/core/tiomap3430.c
index e9b2ce0..8b77837 100644
--- a/drivers/staging/tidspbridge/core/tiomap3430.c
+++ b/drivers/staging/tidspbridge/core/tiomap3430.c
@@ -47,7 +47,6 @@
/* ----------------------------------- Platform Manager */
#include <dspbridge/dev.h>
#include <dspbridge/dspapi.h>
-#include <dspbridge/dmm.h>
#include <dspbridge/wdt.h>

/* ----------------------------------- Local */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/dev.h b/drivers/staging/tidspbridge/include/dspbridge/dev.h
index f92b4be..232bcbc 100644
--- a/drivers/staging/tidspbridge/include/dspbridge/dev.h
+++ b/drivers/staging/tidspbridge/include/dspbridge/dev.h
@@ -27,7 +27,6 @@
#include <dspbridge/nodedefs.h>
#include <dspbridge/disp.h>
#include <dspbridge/dspdefs.h>
-#include <dspbridge/dmm.h>
#include <dspbridge/host_os.h>

/* ----------------------------------- This */
@@ -197,29 +196,6 @@ extern int dev_get_cmm_mgr(struct dev_object *hdev_obj,
struct cmm_object **mgr);

/*
- * ======== dev_get_dmm_mgr ========
- * Purpose:
- * Retrieve the handle to the dynamic memory manager created for this
- * device.
- * Parameters:
- * hdev_obj: Handle to device object created with
- * dev_create_device().
- * *mgr: Ptr to location to store handle.
- * Returns:
- * 0: Success.
- * -EFAULT: Invalid hdev_obj.
- * Requires:
- * mgr != NULL.
- * DEV Initialized.
- * Ensures:
- * 0: *mgr contains a handle to a channel manager object,
- * or NULL.
- * else: *mgr is NULL.
- */
-extern int dev_get_dmm_mgr(struct dev_object *hdev_obj,
- struct dmm_object **mgr);
-
-/*
* ======== dev_get_cod_mgr ========
* Purpose:
* Retrieve the COD manager create for this device.
diff --git a/drivers/staging/tidspbridge/include/dspbridge/dmm.h b/drivers/staging/tidspbridge/include/dspbridge/dmm.h
deleted file mode 100644
index 6c58335..0000000
--- a/drivers/staging/tidspbridge/include/dspbridge/dmm.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * dmm.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * The Dynamic Memory Mapping(DMM) module manages the DSP Virtual address
- * space that can be directly mapped to any MPU buffer or memory region.
- *
- * 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.
- */
-
-#ifndef DMM_
-#define DMM_
-
-#include <dspbridge/dbdefs.h>
-
-struct dmm_object;
-
-/* DMM attributes used in dmm_create() */
-struct dmm_mgrattrs {
- u32 reserved;
-};
-
-#define DMMPOOLSIZE 0x4000000
-
-/*
- * ======== dmm_get_handle ========
- * Purpose:
- * Return the dynamic memory manager object for this device.
- * This is typically called from the client process.
- */
-
-extern int dmm_get_handle(void *hprocessor,
- struct dmm_object **dmm_manager);
-
-extern int dmm_reserve_memory(struct dmm_object *dmm_mgr,
- u32 size, u32 *prsv_addr);
-
-extern int dmm_un_reserve_memory(struct dmm_object *dmm_mgr,
- u32 rsv_addr);
-
-extern int dmm_map_memory(struct dmm_object *dmm_mgr, u32 addr,
- u32 size);
-
-extern int dmm_un_map_memory(struct dmm_object *dmm_mgr,
- u32 addr, u32 *psize);
-
-extern int dmm_destroy(struct dmm_object *dmm_mgr);
-
-extern int dmm_delete_tables(struct dmm_object *dmm_mgr);
-
-extern int dmm_create(struct dmm_object **dmm_manager,
- struct dev_object *hdev_obj,
- const struct dmm_mgrattrs *mgr_attrts);
-
-extern bool dmm_init(void);
-
-extern void dmm_exit(void);
-
-extern int dmm_create_tables(struct dmm_object *dmm_mgr,
- u32 addr, u32 size);
-
-#ifdef DSP_DMM_DEBUG
-u32 dmm_mem_map_dump(struct dmm_object *dmm_mgr);
-#endif
-
-#endif /* DMM_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/drv.h b/drivers/staging/tidspbridge/include/dspbridge/drv.h
index ea74dda..5764073 100644
--- a/drivers/staging/tidspbridge/include/dspbridge/drv.h
+++ b/drivers/staging/tidspbridge/include/dspbridge/drv.h
@@ -89,12 +89,6 @@ struct dmm_map_object {
struct bridge_dma_map_info dma_info;
};

-/* Used for DMM reserved memory accounting */
-struct dmm_rsv_object {
- struct list_head link;
- u32 dsp_reserved_addr;
-};
-
/* New structure (member of process context) abstracts stream resource info */
struct strm_res_object {
s32 stream_allocated; /* Stream status */
@@ -135,10 +129,6 @@ struct process_context {
struct list_head dmm_map_list;
spinlock_t dmm_map_lock;

- /* DMM reserved memory resources */
- struct list_head dmm_rsv_list;
- spinlock_t dmm_rsv_lock;
-
/* Stream resources */
struct idr *stream_id;
};
diff --git a/drivers/staging/tidspbridge/include/dspbridge/proc.h b/drivers/staging/tidspbridge/include/dspbridge/proc.h
index f00dffd..692b73d 100644
--- a/drivers/staging/tidspbridge/include/dspbridge/proc.h
+++ b/drivers/staging/tidspbridge/include/dspbridge/proc.h
@@ -551,29 +551,6 @@ extern int proc_map(void *hprocessor,
struct process_context *pr_ctxt);

/*
- * ======== proc_reserve_memory ========
- * Purpose:
- * Reserve a virtually contiguous region of DSP address space.
- * Parameters:
- * hprocessor : The processor handle.
- * ul_size : Size of the address space to reserve.
- * pp_rsv_addr : Ptr to DSP side reserved u8 address.
- * Returns:
- * 0 : Success.
- * -EFAULT : Invalid processor handle.
- * -EPERM : General failure.
- * -ENOMEM : Cannot reserve chunk of this size.
- * Requires:
- * pp_rsv_addr is not NULL
- * PROC Initialized.
- * Ensures:
- * Details:
- */
-extern int proc_reserve_memory(void *hprocessor,
- u32 ul_size, void **pp_rsv_addr,
- struct process_context *pr_ctxt);
-
-/*
* ======== proc_un_map ========
* Purpose:
* Removes a MPU buffer mapping from the DSP address space.
@@ -595,27 +572,4 @@ extern int proc_reserve_memory(void *hprocessor,
extern int proc_un_map(void *hprocessor, void *map_addr,
struct process_context *pr_ctxt);

-/*
- * ======== proc_un_reserve_memory ========
- * Purpose:
- * Frees a previously reserved region of DSP address space.
- * Parameters:
- * hprocessor : The processor handle.
- * prsv_addr : Ptr to DSP side reservedBYTE address.
- * Returns:
- * 0 : Success.
- * -EFAULT : Invalid processor handle.
- * -EPERM : General failure.
- * -ENOENT : Cannot find a reserved region starting with this
- * : address.
- * Requires:
- * prsv_addr is not NULL
- * PROC Initialized.
- * Ensures:
- * Details:
- */
-extern int proc_un_reserve_memory(void *hprocessor,
- void *prsv_addr,
- struct process_context *pr_ctxt);
-
#endif /* PROC_ */
diff --git a/drivers/staging/tidspbridge/pmgr/dev.c b/drivers/staging/tidspbridge/pmgr/dev.c
index 522810b..d8f4079 100644
--- a/drivers/staging/tidspbridge/pmgr/dev.c
+++ b/drivers/staging/tidspbridge/pmgr/dev.c
@@ -31,7 +31,6 @@
#include <dspbridge/cod.h>
#include <dspbridge/drv.h>
#include <dspbridge/proc.h>
-#include <dspbridge/dmm.h>

/* ----------------------------------- Resource Manager */
#include <dspbridge/mgr.h>
@@ -71,7 +70,6 @@ struct dev_object {
struct msg_mgr *msg_mgr; /* Message manager. */
struct io_mgr *iomgr; /* IO manager (CHNL, msg_ctrl) */
struct cmm_object *cmm_mgr; /* SM memory manager. */
- struct dmm_object *dmm_mgr; /* Dynamic memory manager. */
u32 word_size; /* DSP word size: quick access. */
struct drv_object *drv_obj; /* Driver Object */
/* List of Processors attached to this device */
@@ -243,9 +241,6 @@ int dev_create_device(struct dev_object **device_obj,
/* Instantiate the DEH module */
status = bridge_deh_create(&dev_obj->deh_mgr, dev_obj);
}
- /* Create DMM mgr . */
- status = dmm_create(&dev_obj->dmm_mgr,
- (struct dev_object *)dev_obj, NULL);
}
/* Add the new DEV_Object to the global list: */
if (!status)
@@ -263,8 +258,6 @@ leave:
if (dev_obj) {
if (dev_obj->cod_mgr)
cod_delete(dev_obj->cod_mgr);
- if (dev_obj->dmm_mgr)
- dmm_destroy(dev_obj->dmm_mgr);
kfree(dev_obj);
}

@@ -374,11 +367,6 @@ int dev_destroy_device(struct dev_object *hdev_obj)
dev_obj->cmm_mgr = NULL;
}

- if (dev_obj->dmm_mgr) {
- dmm_destroy(dev_obj->dmm_mgr);
- dev_obj->dmm_mgr = NULL;
- }
-
/* Call the driver's bridge_dev_destroy() function: */
/* Require of DevDestroy */
if (dev_obj->bridge_context) {
@@ -456,32 +444,6 @@ int dev_get_cmm_mgr(struct dev_object *hdev_obj,
}

/*
- * ======== dev_get_dmm_mgr ========
- * Purpose:
- * Retrieve the handle to the dynamic memory manager created for this
- * device.
- */
-int dev_get_dmm_mgr(struct dev_object *hdev_obj,
- struct dmm_object **mgr)
-{
- int status = 0;
- struct dev_object *dev_obj = hdev_obj;
-
- DBC_REQUIRE(refs > 0);
- DBC_REQUIRE(mgr != NULL);
-
- if (hdev_obj) {
- *mgr = dev_obj->dmm_mgr;
- } else {
- *mgr = NULL;
- status = -EFAULT;
- }
-
- DBC_ENSURE(!status || (mgr != NULL && *mgr == NULL));
- return status;
-}
-
-/*
* ======== dev_get_cod_mgr ========
* Purpose:
* Retrieve the COD manager create for this device.
@@ -733,10 +695,8 @@ void dev_exit(void)

refs--;

- if (refs == 0) {
+ if (refs == 0)
cmm_exit();
- dmm_exit();
- }

DBC_ENSURE(refs >= 0);
}
@@ -748,25 +708,12 @@ void dev_exit(void)
*/
bool dev_init(void)
{
- bool cmm_ret, dmm_ret, ret = true;
+ bool ret = true;

DBC_REQUIRE(refs >= 0);

- if (refs == 0) {
- cmm_ret = cmm_init();
- dmm_ret = dmm_init();
-
- ret = cmm_ret && dmm_ret;
-
- if (!ret) {
- if (cmm_ret)
- cmm_exit();
-
- if (dmm_ret)
- dmm_exit();
-
- }
- }
+ if (refs == 0)
+ ret = cmm_init();

if (ret)
refs++;
diff --git a/drivers/staging/tidspbridge/pmgr/dmm.c b/drivers/staging/tidspbridge/pmgr/dmm.c
deleted file mode 100644
index 8685233..0000000
--- a/drivers/staging/tidspbridge/pmgr/dmm.c
+++ /dev/null
@@ -1,533 +0,0 @@
-/*
- * dmm.c
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * The Dynamic Memory Manager (DMM) module manages the DSP Virtual address
- * space that can be directly mapped to any MPU buffer or memory region
- *
- * Notes:
- * Region: Generic memory entitiy having a start address and a size
- * Chunk: Reserved region
- *
- * 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.
- */
-#include <linux/types.h>
-
-/* ----------------------------------- Host OS */
-#include <dspbridge/host_os.h>
-
-/* ----------------------------------- DSP/BIOS Bridge */
-#include <dspbridge/dbdefs.h>
-
-/* ----------------------------------- Trace & Debug */
-#include <dspbridge/dbc.h>
-
-/* ----------------------------------- OS Adaptation Layer */
-#include <dspbridge/sync.h>
-
-/* ----------------------------------- Platform Manager */
-#include <dspbridge/dev.h>
-#include <dspbridge/proc.h>
-
-/* ----------------------------------- This */
-#include <dspbridge/dmm.h>
-
-/* ----------------------------------- Defines, Data Structures, Typedefs */
-#define DMM_ADDR_VIRTUAL(a) \
- (((struct map_page *)(a) - virtual_mapping_table) * PG_SIZE4K +\
- dyn_mem_map_beg)
-#define DMM_ADDR_TO_INDEX(a) (((a) - dyn_mem_map_beg) / PG_SIZE4K)
-
-/* DMM Mgr */
-struct dmm_object {
- /* Dmm Lock is used to serialize access mem manager for
- * multi-threads. */
- spinlock_t dmm_lock; /* Lock to access dmm mgr */
-};
-
-/* ----------------------------------- Globals */
-static u32 refs; /* module reference count */
-struct map_page {
- u32 region_size:15;
- u32 mapped_size:15;
- u32 reserved:1;
- u32 mapped:1;
-};
-
-/* Create the free list */
-static struct map_page *virtual_mapping_table;
-static u32 free_region; /* The index of free region */
-static u32 free_size;
-static u32 dyn_mem_map_beg; /* The Beginning of dynamic memory mapping */
-static u32 table_size; /* The size of virt and phys pages tables */
-
-/* ----------------------------------- Function Prototypes */
-static struct map_page *get_region(u32 addr);
-static struct map_page *get_free_region(u32 len);
-static struct map_page *get_mapped_region(u32 addrs);
-
-/* ======== dmm_create_tables ========
- * Purpose:
- * Create table to hold the information of physical address
- * the buffer pages that is passed by the user, and the table
- * to hold the information of the virtual memory that is reserved
- * for DSP.
- */
-int dmm_create_tables(struct dmm_object *dmm_mgr, u32 addr, u32 size)
-{
- struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr;
- int status = 0;
-
- status = dmm_delete_tables(dmm_obj);
- if (!status) {
- dyn_mem_map_beg = addr;
- table_size = PG_ALIGN_HIGH(size, PG_SIZE4K) / PG_SIZE4K;
- /* Create the free list */
- virtual_mapping_table = __vmalloc(table_size *
- sizeof(struct map_page), GFP_KERNEL |
- __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL);
- if (virtual_mapping_table == NULL)
- status = -ENOMEM;
- else {
- /* On successful allocation,
- * all entries are zero ('free') */
- free_region = 0;
- free_size = table_size * PG_SIZE4K;
- virtual_mapping_table[0].region_size = table_size;
- }
- }
-
- if (status)
- pr_err("%s: failure, status 0x%x\n", __func__, status);
-
- return status;
-}
-
-/*
- * ======== dmm_create ========
- * Purpose:
- * Create a dynamic memory manager object.
- */
-int dmm_create(struct dmm_object **dmm_manager,
- struct dev_object *hdev_obj,
- const struct dmm_mgrattrs *mgr_attrts)
-{
- struct dmm_object *dmm_obj = NULL;
- int status = 0;
- DBC_REQUIRE(refs > 0);
- DBC_REQUIRE(dmm_manager != NULL);
-
- *dmm_manager = NULL;
- /* create, zero, and tag a cmm mgr object */
- dmm_obj = kzalloc(sizeof(struct dmm_object), GFP_KERNEL);
- if (dmm_obj != NULL) {
- spin_lock_init(&dmm_obj->dmm_lock);
- *dmm_manager = dmm_obj;
- } else {
- status = -ENOMEM;
- }
-
- return status;
-}
-
-/*
- * ======== dmm_destroy ========
- * Purpose:
- * Release the communication memory manager resources.
- */
-int dmm_destroy(struct dmm_object *dmm_mgr)
-{
- struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr;
- int status = 0;
-
- DBC_REQUIRE(refs > 0);
- if (dmm_mgr) {
- status = dmm_delete_tables(dmm_obj);
- if (!status)
- kfree(dmm_obj);
- } else
- status = -EFAULT;
-
- return status;
-}
-
-/*
- * ======== dmm_delete_tables ========
- * Purpose:
- * Delete DMM Tables.
- */
-int dmm_delete_tables(struct dmm_object *dmm_mgr)
-{
- int status = 0;
-
- DBC_REQUIRE(refs > 0);
- /* Delete all DMM tables */
- if (dmm_mgr)
- vfree(virtual_mapping_table);
- else
- status = -EFAULT;
- return status;
-}
-
-/*
- * ======== dmm_exit ========
- * Purpose:
- * Discontinue usage of module; free resources when reference count
- * reaches 0.
- */
-void dmm_exit(void)
-{
- DBC_REQUIRE(refs > 0);
-
- refs--;
-}
-
-/*
- * ======== dmm_get_handle ========
- * Purpose:
- * Return the dynamic memory manager object for this device.
- * This is typically called from the client process.
- */
-int dmm_get_handle(void *hprocessor, struct dmm_object **dmm_manager)
-{
- int status = 0;
- struct dev_object *hdev_obj;
-
- DBC_REQUIRE(refs > 0);
- DBC_REQUIRE(dmm_manager != NULL);
- if (hprocessor != NULL)
- status = proc_get_dev_object(hprocessor, &hdev_obj);
- else
- hdev_obj = dev_get_first(); /* default */
-
- if (!status)
- status = dev_get_dmm_mgr(hdev_obj, dmm_manager);
-
- return status;
-}
-
-/*
- * ======== dmm_init ========
- * Purpose:
- * Initializes private state of DMM module.
- */
-bool dmm_init(void)
-{
- bool ret = true;
-
- DBC_REQUIRE(refs >= 0);
-
- if (ret)
- refs++;
-
- DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs >= 0)));
-
- virtual_mapping_table = NULL;
- table_size = 0;
-
- return ret;
-}
-
-/*
- * ======== dmm_map_memory ========
- * Purpose:
- * Add a mapping block to the reserved chunk. DMM assumes that this block
- * will be mapped in the DSP/IVA's address space. DMM returns an error if a
- * mapping overlaps another one. This function stores the info that will be
- * required later while unmapping the block.
- */
-int dmm_map_memory(struct dmm_object *dmm_mgr, u32 addr, u32 size)
-{
- struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr;
- struct map_page *chunk;
- int status = 0;
-
- spin_lock(&dmm_obj->dmm_lock);
- /* Find the Reserved memory chunk containing the DSP block to
- * be mapped */
- chunk = (struct map_page *)get_region(addr);
- if (chunk != NULL) {
- /* Mark the region 'mapped', leave the 'reserved' info as-is */
- chunk->mapped = true;
- chunk->mapped_size = (size / PG_SIZE4K);
- } else
- status = -ENOENT;
- spin_unlock(&dmm_obj->dmm_lock);
-
- dev_dbg(bridge, "%s dmm_mgr %p, addr %x, size %x\n\tstatus %x, "
- "chunk %p", __func__, dmm_mgr, addr, size, status, chunk);
-
- return status;
-}
-
-/*
- * ======== dmm_reserve_memory ========
- * Purpose:
- * Reserve a chunk of virtually contiguous DSP/IVA address space.
- */
-int dmm_reserve_memory(struct dmm_object *dmm_mgr, u32 size,
- u32 *prsv_addr)
-{
- int status = 0;
- struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr;
- struct map_page *node;
- u32 rsv_addr = 0;
- u32 rsv_size = 0;
-
- spin_lock(&dmm_obj->dmm_lock);
-
- /* 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. */
- rsv_addr = DMM_ADDR_VIRTUAL(node);
- /* Calculate the number entries to use */
- rsv_size = size / PG_SIZE4K;
- if (rsv_size < node->region_size) {
- /* Mark remainder of free region */
- node[rsv_size].mapped = false;
- node[rsv_size].reserved = false;
- node[rsv_size].region_size =
- node->region_size - rsv_size;
- node[rsv_size].mapped_size = 0;
- }
- /* get_region will return first fit chunk. But we only use what
- is requested. */
- node->mapped = false;
- node->reserved = true;
- node->region_size = rsv_size;
- node->mapped_size = 0;
- /* Return the chunk's starting address */
- *prsv_addr = rsv_addr;
- } else
- /*dSP chunk of given size is not available */
- status = -ENOMEM;
-
- spin_unlock(&dmm_obj->dmm_lock);
-
- dev_dbg(bridge, "%s dmm_mgr %p, size %x, prsv_addr %p\n\tstatus %x, "
- "rsv_addr %x, rsv_size %x\n", __func__, dmm_mgr, size,
- prsv_addr, status, rsv_addr, rsv_size);
-
- return status;
-}
-
-/*
- * ======== dmm_un_map_memory ========
- * Purpose:
- * Remove the mapped block from the reserved chunk.
- */
-int dmm_un_map_memory(struct dmm_object *dmm_mgr, u32 addr, u32 *psize)
-{
- struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr;
- struct map_page *chunk;
- int status = 0;
-
- spin_lock(&dmm_obj->dmm_lock);
- chunk = get_mapped_region(addr);
- if (chunk == NULL)
- status = -ENOENT;
-
- if (!status) {
- /* Unmap the region */
- *psize = chunk->mapped_size * PG_SIZE4K;
- chunk->mapped = false;
- chunk->mapped_size = 0;
- }
- spin_unlock(&dmm_obj->dmm_lock);
-
- dev_dbg(bridge, "%s: dmm_mgr %p, addr %x, psize %p\n\tstatus %x, "
- "chunk %p\n", __func__, dmm_mgr, addr, psize, status, chunk);
-
- return status;
-}
-
-/*
- * ======== dmm_un_reserve_memory ========
- * Purpose:
- * Free a chunk of reserved DSP/IVA address space.
- */
-int dmm_un_reserve_memory(struct dmm_object *dmm_mgr, u32 rsv_addr)
-{
- struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr;
- struct map_page *chunk;
- u32 i;
- int status = 0;
- u32 chunk_size;
-
- spin_lock(&dmm_obj->dmm_lock);
-
- /* Find the chunk containing the reserved address */
- chunk = get_mapped_region(rsv_addr);
- if (chunk == NULL)
- status = -ENOENT;
-
- if (!status) {
- /* Free all the mapped pages for this reserved region */
- i = 0;
- while (i < chunk->region_size) {
- if (chunk[i].mapped) {
- /* Remove mapping from the page tables. */
- chunk_size = chunk[i].mapped_size;
- /* Clear the mapping flags */
- chunk[i].mapped = false;
- chunk[i].mapped_size = 0;
- i += chunk_size;
- } else
- i++;
- }
- /* Clear the flags (mark the region 'free') */
- chunk->reserved = false;
- /* NOTE: We do NOT coalesce free regions here.
- * Free regions are coalesced in get_region(), as it traverses
- *the whole mapping table
- */
- }
- spin_unlock(&dmm_obj->dmm_lock);
-
- dev_dbg(bridge, "%s: dmm_mgr %p, rsv_addr %x\n\tstatus %x chunk %p",
- __func__, dmm_mgr, rsv_addr, status, chunk);
-
- return status;
-}
-
-/*
- * ======== get_region ========
- * Purpose:
- * Returns a region containing the specified memory region
- */
-static struct map_page *get_region(u32 addr)
-{
- struct map_page *curr_region = NULL;
- u32 i = 0;
-
- if (virtual_mapping_table != NULL) {
- /* find page mapped by this address */
- i = DMM_ADDR_TO_INDEX(addr);
- if (i < table_size)
- curr_region = virtual_mapping_table + i;
- }
-
- dev_dbg(bridge, "%s: curr_region %p, free_region %d, free_size %d\n",
- __func__, curr_region, free_region, free_size);
- return curr_region;
-}
-
-/*
- * ======== get_free_region ========
- * Purpose:
- * Returns the requested free region
- */
-static struct map_page *get_free_region(u32 len)
-{
- struct map_page *curr_region = NULL;
- u32 i = 0;
- u32 region_size = 0;
- u32 next_i = 0;
-
- if (virtual_mapping_table == NULL)
- return curr_region;
- if (len > free_size) {
- /* Find the largest free region
- * (coalesce during the traversal) */
- while (i < table_size) {
- region_size = virtual_mapping_table[i].region_size;
- next_i = i + region_size;
- if (virtual_mapping_table[i].reserved == false) {
- /* Coalesce, if possible */
- if (next_i < table_size &&
- virtual_mapping_table[next_i].reserved
- == false) {
- virtual_mapping_table[i].region_size +=
- virtual_mapping_table
- [next_i].region_size;
- continue;
- }
- region_size *= PG_SIZE4K;
- if (region_size > free_size) {
- free_region = i;
- free_size = region_size;
- }
- }
- i = next_i;
- }
- }
- if (len <= free_size) {
- curr_region = virtual_mapping_table + free_region;
- free_region += (len / PG_SIZE4K);
- free_size -= len;
- }
- return curr_region;
-}
-
-/*
- * ======== get_mapped_region ========
- * Purpose:
- * Returns the requestedmapped region
- */
-static struct map_page *get_mapped_region(u32 addrs)
-{
- u32 i = 0;
- struct map_page *curr_region = NULL;
-
- if (virtual_mapping_table == NULL)
- return curr_region;
-
- i = DMM_ADDR_TO_INDEX(addrs);
- if (i < table_size && (virtual_mapping_table[i].mapped ||
- virtual_mapping_table[i].reserved))
- curr_region = virtual_mapping_table + i;
- return curr_region;
-}
-
-#ifdef DSP_DMM_DEBUG
-u32 dmm_mem_map_dump(struct dmm_object *dmm_mgr)
-{
- struct map_page *curr_node = NULL;
- u32 i;
- u32 freemem = 0;
- u32 bigsize = 0;
-
- spin_lock(&dmm_mgr->dmm_lock);
-
- if (virtual_mapping_table != NULL) {
- for (i = 0; i < table_size; i +=
- virtual_mapping_table[i].region_size) {
- curr_node = virtual_mapping_table + i;
- if (curr_node->reserved) {
- /*printk("RESERVED size = 0x%x, "
- "Map size = 0x%x\n",
- (curr_node->region_size * PG_SIZE4K),
- (curr_node->mapped == false) ? 0 :
- (curr_node->mapped_size * PG_SIZE4K));
- */
- } else {
-/* printk("UNRESERVED size = 0x%x\n",
- (curr_node->region_size * PG_SIZE4K));
- */
- freemem += (curr_node->region_size * PG_SIZE4K);
- if (curr_node->region_size > bigsize)
- bigsize = curr_node->region_size;
- }
- }
- }
- spin_unlock(&dmm_mgr->dmm_lock);
- 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 * PG_SIZE4K) - freemem)) / (1024 * 1024));
- printk(KERN_INFO "DSP VA - Biggest FREE block = %d Mbytes \n\n",
- (bigsize * PG_SIZE4K / (1024 * 1024)));
-
- return 0;
-}
-#endif
diff --git a/drivers/staging/tidspbridge/pmgr/dspapi.c b/drivers/staging/tidspbridge/pmgr/dspapi.c
index 767ffe2..377c41f 100644
--- a/drivers/staging/tidspbridge/pmgr/dspapi.c
+++ b/drivers/staging/tidspbridge/pmgr/dspapi.c
@@ -993,27 +993,11 @@ u32 procwrap_register_notify(union trapped_args *args, void *pr_ctxt)
/*
* ======== procwrap_reserve_memory ========
*/
-u32 procwrap_reserve_memory(union trapped_args *args, void *pr_ctxt)
+u32 __deprecated procwrap_reserve_memory(union trapped_args *args,
+ void *pr_ctxt)
{
- int status;
- void *prsv_addr;
- void *hprocessor = ((struct process_context *)pr_ctxt)->processor;
-
- if ((args->args_proc_rsvmem.size <= 0) ||
- (args->args_proc_rsvmem.size & (PG_SIZE4K - 1)) != 0)
- return -EINVAL;
-
- status = proc_reserve_memory(hprocessor,
- args->args_proc_rsvmem.size, &prsv_addr,
- pr_ctxt);
- if (!status) {
- if (put_user(prsv_addr, args->args_proc_rsvmem.rsv_addr)) {
- status = -EINVAL;
- proc_un_reserve_memory(args->args_proc_rsvmem.
- processor, prsv_addr, pr_ctxt);
- }
- }
- return status;
+ dev_dbg(bridge, "%s: deprecated dspbridge ioctl\n", __func__);
+ return 0;
}

/*
@@ -1042,15 +1026,11 @@ u32 procwrap_un_map(union trapped_args *args, void *pr_ctxt)
/*
* ======== procwrap_un_reserve_memory ========
*/
-u32 procwrap_un_reserve_memory(union trapped_args *args, void *pr_ctxt)
+u32 __deprecated procwrap_un_reserve_memory(union trapped_args *args,
+ void *pr_ctxt)
{
- int status;
- void *hprocessor = ((struct process_context *)pr_ctxt)->processor;
-
- status = proc_un_reserve_memory(hprocessor,
- args->args_proc_unrsvmem.rsv_addr,
- pr_ctxt);
- return status;
+ dev_dbg(bridge, "%s: deprecated dspbridge ioctl\n", __func__);
+ return 0;
}

/*
diff --git a/drivers/staging/tidspbridge/rmgr/drv.c b/drivers/staging/tidspbridge/rmgr/drv.c
index a7c93cf..3d031ba 100644
--- a/drivers/staging/tidspbridge/rmgr/drv.c
+++ b/drivers/staging/tidspbridge/rmgr/drv.c
@@ -144,7 +144,6 @@ int drv_remove_all_dmm_res_elements(void *process_ctxt)
struct process_context *ctxt = (struct process_context *)process_ctxt;
int status = 0;
struct dmm_map_object *temp_map, *map_obj;
- struct dmm_rsv_object *temp_rsv, *rsv_obj;

/* Free DMM mapped memory resources */
list_for_each_entry_safe(map_obj, temp_map, &ctxt->dmm_map_list, link) {
@@ -155,15 +154,6 @@ int drv_remove_all_dmm_res_elements(void *process_ctxt)
" status = 0x%xn", __func__, status);
}

- /* Free DMM reserved memory resources */
- list_for_each_entry_safe(rsv_obj, temp_rsv, &ctxt->dmm_rsv_list, link) {
- status = proc_un_reserve_memory(ctxt->processor, (void *)
- rsv_obj->dsp_reserved_addr,
- ctxt);
- if (status)
- pr_err("%s: proc_un_reserve_memory failed!"
- " status = 0x%xn", __func__, status);
- }
return status;
}

diff --git a/drivers/staging/tidspbridge/rmgr/drv_interface.c b/drivers/staging/tidspbridge/rmgr/drv_interface.c
index c43c7e3..1fb5369 100644
--- a/drivers/staging/tidspbridge/rmgr/drv_interface.c
+++ b/drivers/staging/tidspbridge/rmgr/drv_interface.c
@@ -508,8 +508,6 @@ static int bridge_open(struct inode *ip, struct file *filp)
pr_ctxt->res_state = PROC_RES_ALLOCATED;
spin_lock_init(&pr_ctxt->dmm_map_lock);
INIT_LIST_HEAD(&pr_ctxt->dmm_map_list);
- spin_lock_init(&pr_ctxt->dmm_rsv_lock);
- INIT_LIST_HEAD(&pr_ctxt->dmm_rsv_list);

pr_ctxt->node_id = kzalloc(sizeof(struct idr), GFP_KERNEL);
if (pr_ctxt->node_id) {
diff --git a/drivers/staging/tidspbridge/rmgr/node.c b/drivers/staging/tidspbridge/rmgr/node.c
index 5dadaa4..a6958fe 100644
--- a/drivers/staging/tidspbridge/rmgr/node.c
+++ b/drivers/staging/tidspbridge/rmgr/node.c
@@ -57,7 +57,6 @@
/* ----------------------------------- This */
#include <dspbridge/nodepriv.h>
#include <dspbridge/node.h>
-#include <dspbridge/dmm.h>

/* Static/Dynamic Loader includes */
#include <dspbridge/dbll.h>
@@ -319,11 +318,6 @@ int node_allocate(struct proc_object *hprocessor,
u32 mapped_addr = 0;
u32 map_attrs = 0x0;
struct dsp_processorstate proc_state;
-#ifdef DSP_DMM_DEBUG
- struct dmm_object *dmm_mgr;
- struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
-#endif
-
void *node_res;

DBC_REQUIRE(refs > 0);
@@ -432,35 +426,12 @@ int node_allocate(struct proc_object *hprocessor,
if (status)
goto func_cont;

- status = proc_reserve_memory(hprocessor,
- pnode->create_args.asa.task_arg_obj.
- heap_size + PAGE_SIZE,
- (void **)&(pnode->create_args.asa.
- task_arg_obj.dsp_heap_res_addr),
- pr_ctxt);
- if (status) {
- pr_err("%s: Failed to reserve memory for heap: 0x%x\n",
- __func__, status);
- goto func_cont;
- }
-#ifdef DSP_DMM_DEBUG
- status = dmm_get_handle(p_proc_object, &dmm_mgr);
- if (!dmm_mgr) {
- status = DSP_EHANDLE;
- goto func_cont;
- }
-
- dmm_mem_map_dump(dmm_mgr);
-#endif
-
map_attrs |= DSP_MAPLITTLEENDIAN;
map_attrs |= DSP_MAPELEMSIZE32;
map_attrs |= DSP_MAPVIRTUALADDR;
status = proc_map(hprocessor, (void *)attr_in->pgpp_virt_addr,
pnode->create_args.asa.task_arg_obj.heap_size,
- (void *)pnode->create_args.asa.task_arg_obj.
- dsp_heap_res_addr, (void **)&mapped_addr, map_attrs,
- pr_ctxt);
+ NULL, (void **)&mapped_addr, map_attrs, pr_ctxt);
if (status)
pr_err("%s: Failed to map memory for Heap: 0x%x\n",
__func__, status);
@@ -2457,12 +2428,8 @@ static void delete_node(struct node_object *hnode,
struct stream_chnl stream;
struct node_msgargs node_msg_args;
struct node_taskargs task_arg_obj;
-#ifdef DSP_DMM_DEBUG
- struct dmm_object *dmm_mgr;
- struct proc_object *p_proc_object =
- (struct proc_object *)hnode->processor;
-#endif
int status;
+
if (!hnode)
goto func_end;
hnode_mgr = hnode->node_mgr;
@@ -2518,24 +2485,10 @@ static void delete_node(struct node_object *hnode,
kfree(task_arg_obj.strm_out_def);
task_arg_obj.strm_out_def = NULL;
}
- if (task_arg_obj.dsp_heap_res_addr) {
- status = proc_un_map(hnode->processor, (void *)
- task_arg_obj.dsp_heap_addr,
+ if (task_arg_obj.dsp_heap_addr)
+ status = proc_un_map(hnode->processor,
+ (void *)task_arg_obj.dsp_heap_addr,
pr_ctxt);
-
- status = proc_un_reserve_memory(hnode->processor,
- (void *)
- task_arg_obj.
- dsp_heap_res_addr,
- pr_ctxt);
-#ifdef DSP_DMM_DEBUG
- status = dmm_get_handle(p_proc_object, &dmm_mgr);
- if (dmm_mgr)
- dmm_mem_map_dump(dmm_mgr);
- else
- status = DSP_EHANDLE;
-#endif
- }
}
if (node_type != NODE_MESSAGE) {
kfree(hnode->stream_connect);
diff --git a/drivers/staging/tidspbridge/rmgr/proc.c b/drivers/staging/tidspbridge/rmgr/proc.c
index ce57279..c53e60c 100644
--- a/drivers/staging/tidspbridge/rmgr/proc.c
+++ b/drivers/staging/tidspbridge/rmgr/proc.c
@@ -38,7 +38,6 @@
#include <dspbridge/cod.h>
#include <dspbridge/dev.h>
#include <dspbridge/procpriv.h>
-#include <dspbridge/dmm.h>

/* ----------------------------------- Resource Manager */
#include <dspbridge/mgr.h>
@@ -1126,9 +1125,6 @@ int proc_load(void *hprocessor, const s32 argc_index,
s32 cnew_envp; /* " " in new_envp[] */
s32 nproc_id = 0; /* Anticipate MP version. */
struct dcd_manager *hdcd_handle;
- struct dmm_object *dmm_mgr;
- u32 dw_ext_end;
- u32 proc_id;
int brd_state;
struct drv_data *drv_datap = dev_get_drvdata(bridge);

@@ -1309,35 +1305,6 @@ int proc_load(void *hprocessor, const s32 argc_index,
DSP_PROCESSORSTATECHANGE);
}
}
- if (!status) {
- status = proc_get_processor_id(hprocessor, &proc_id);
- if (proc_id == DSP_UNIT) {
- /* Use all available DSP address space after EXTMEM
- * for DMM */
- if (!status)
- status = cod_get_sym_value(cod_mgr, EXTEND,
- &dw_ext_end);
-
- /* Reset DMM structs and add an initial free chunk */
- if (!status) {
- status =
- dev_get_dmm_mgr(p_proc_object->dev_obj,
- &dmm_mgr);
- if (dmm_mgr) {
- /* Set dw_ext_end to DMM START u8
- * address */
- dw_ext_end =
- (dw_ext_end + 1) * DSPWORDSIZE;
- /* DMM memory is from EXT_END */
- status = dmm_create_tables(dmm_mgr,
- dw_ext_end,
- DMMPOOLSIZE);
- } else {
- status = -EFAULT;
- }
- }
- }
- }
/* Restore the original argv[0] */
kfree(new_envp);
user_args[0] = pargv0;
@@ -1388,7 +1355,6 @@ int proc_map(void *hprocessor, void *pmpu_addr, u32 ul_size,
{
u32 va_align;
u32 pa_align;
- struct dmm_object *dmm_mgr;
u32 size_align;
int status = 0;
struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
@@ -1417,9 +1383,6 @@ int proc_map(void *hprocessor, void *pmpu_addr, u32 ul_size,
}
/* Critical section */
mutex_lock(&proc_lock);
- dmm_get_handle(p_proc_object, &dmm_mgr);
- if (!dmm_mgr)
- status = -EFAULT;

/* Add mapping to the page tables. */
if (!status) {
@@ -1535,30 +1498,6 @@ func_end:
}

/*
- * ======== proc_reserve_memory ========
- * Purpose:
- * Reserve a virtually contiguous region of DSP address space.
- */
-int proc_reserve_memory(void *hprocessor, u32 ul_size,
- void **pp_rsv_addr,
- struct process_context *pr_ctxt)
-{
- int status = 0;
- struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
-
- if (!p_proc_object) {
- status = -EFAULT;
- goto func_end;
- }
-
-func_end:
- dev_dbg(bridge, "%s: hprocessor: 0x%p ul_size: 0x%x pp_rsv_addr: 0x%p "
- "status 0x%x\n", __func__, hprocessor,
- ul_size, pp_rsv_addr, status);
- return status;
-}
-
-/*
* ======== proc_start ========
* Purpose:
* Start a processor running.
@@ -1706,7 +1645,6 @@ int proc_un_map(void *hprocessor, void *map_addr,
{
int status = 0;
struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
- struct dmm_object *dmm_mgr;
struct dmm_map_object *dmo;
u32 va_align;

@@ -1716,12 +1654,6 @@ int proc_un_map(void *hprocessor, void *map_addr,
goto func_end;
}

- status = dmm_get_handle(hprocessor, &dmm_mgr);
- if (!dmm_mgr) {
- status = -EFAULT;
- goto func_end;
- }
-
/* Critical section */
mutex_lock(&proc_lock);

@@ -1753,28 +1685,6 @@ func_end:
}

/*
- * ======== proc_un_reserve_memory ========
- * Purpose:
- * Frees a previously reserved region of DSP address space.
- */
-int proc_un_reserve_memory(void *hprocessor, void *prsv_addr,
- struct process_context *pr_ctxt)
-{
- int status = 0;
- struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
-
- if (!p_proc_object) {
- status = -EFAULT;
- goto func_end;
- }
-
-func_end:
- dev_dbg(bridge, "%s: hprocessor: 0x%p prsv_addr: 0x%p status: 0x%x\n",
- __func__, hprocessor, prsv_addr, status);
- return status;
-}
-
-/*
* ======== = proc_monitor ======== ==
* Purpose:
* Place the Processor in Monitor State. This is an internal
--
1.7.1

2011-04-28 15:44:05

by Ramirez Luna, Omar

[permalink] [raw]
Subject: [PATCH v4 6/6] staging: tidspbridge: decouple mmu functions from regular code

From: Fernando Guzman Lugo <[email protected]>

Create a new dsp mmu file containing the functions needed to
interact with iommu block (map, unmap, mmufault handling, etc).

While at it, give meaningful names to map and unmap functions and
remove them from bridge's pointer-to-func structure.

Signed-off-by: Fernando Guzman Lugo <[email protected]>
Signed-off-by: Omar Ramirez Luna <[email protected]>
---
drivers/staging/tidspbridge/Makefile | 2 +-
drivers/staging/tidspbridge/core/_deh.h | 3 -
drivers/staging/tidspbridge/core/dsp_mmu.c | 396 ++++++++++++++++++++
drivers/staging/tidspbridge/core/tiomap3430.c | 271 +-------------
drivers/staging/tidspbridge/core/ue_deh.c | 87 +-----
.../tidspbridge/include/dspbridge/dsp_mmu.h | 33 ++
.../tidspbridge/include/dspbridge/dspdefs.h | 44 ---
drivers/staging/tidspbridge/pmgr/dev.c | 2 -
drivers/staging/tidspbridge/rmgr/proc.c | 13 +-
9 files changed, 442 insertions(+), 409 deletions(-)
create mode 100644 drivers/staging/tidspbridge/core/dsp_mmu.c
create mode 100644 drivers/staging/tidspbridge/include/dspbridge/dsp_mmu.h

diff --git a/drivers/staging/tidspbridge/Makefile b/drivers/staging/tidspbridge/Makefile
index 0bab58b..a12d9af 100644
--- a/drivers/staging/tidspbridge/Makefile
+++ b/drivers/staging/tidspbridge/Makefile
@@ -2,7 +2,7 @@ obj-$(CONFIG_TIDSPBRIDGE) += bridgedriver.o

libgen = gen/gh.o gen/uuidutil.o
libcore = core/chnl_sm.o core/msg_sm.o core/io_sm.o core/tiomap3430.o \
- core/tiomap3430_pwr.o core/tiomap_io.o \
+ core/tiomap3430_pwr.o core/tiomap_io.o core/dsp_mmu.o \
core/ue_deh.o core/wdt.o core/dsp-clock.o core/sync.o
libpmgr = pmgr/chnl.o pmgr/io.o pmgr/msg.o pmgr/cod.o pmgr/dev.o pmgr/dspapi.o \
pmgr/cmm.o pmgr/dbll.o
diff --git a/drivers/staging/tidspbridge/core/_deh.h b/drivers/staging/tidspbridge/core/_deh.h
index 85543cf..5cc720a 100644
--- a/drivers/staging/tidspbridge/core/_deh.h
+++ b/drivers/staging/tidspbridge/core/_deh.h
@@ -27,9 +27,6 @@
struct deh_mgr {
struct bridge_dev_context *bridge_context; /* Bridge context. */
struct ntfy_object *ntfy_obj; /* NTFY object */
-
- /* MMU Fault DPC */
- struct tasklet_struct dpc_tasklet;
};

int mmu_fault_isr(struct iommu *mmu, u32 da, u32 iommu_errs, void *priv);
diff --git a/drivers/staging/tidspbridge/core/dsp_mmu.c b/drivers/staging/tidspbridge/core/dsp_mmu.c
new file mode 100644
index 0000000..94bb29d
--- /dev/null
+++ b/drivers/staging/tidspbridge/core/dsp_mmu.c
@@ -0,0 +1,396 @@
+/*
+ * Copyright (C) 2011 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/errno.h>
+#include <dspbridge/dsp_mmu.h>
+#include <dspbridge/dev.h>
+#include <dspbridge/dspdeh.h>
+#include "_tiomap.h"
+#include "_tiomap_pwr.h"
+#include "_deh.h"
+
+#ifndef ARCH_HAS_SG_CHAIN
+static struct gen_pool *dmm_pool;
+
+static inline u32 dsptlb_init_entry(struct iotlb_entry *e, u32 da, u32 pa,
+ u32 pgsz)
+{
+ memset(e, 0, sizeof(*e));
+
+ e->da = da;
+ e->pa = pa;
+ e->valid = 1;
+ e->pgsz = MMU_CAM_PGSZ_4K;
+ e->pgsz = pgsz & MMU_CAM_PGSZ_MASK;
+ e->endian = MMU_RAM_ENDIAN_LITTLE;
+ e->elsz = MMU_RAM_ELSZ_32;
+ e->mixed = 0;
+
+ return iopgsz_to_bytes(e->pgsz);
+}
+#endif /* !ARCH_HAS_SG_CHAIN */
+
+/**
+ * user_va2_pa() - get physical address from userspace address.
+ * @mm: mm_struct pointer of the process.
+ * @address: User space virtual address.
+ */
+static u32 user_va2_pa(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;
+}
+
+/**
+ * get_io_pages() - pin and get pages of io user's buffer.
+ * @mm: mm_struct pointer of the process.
+ * @uva: Virtual user space address.
+ * @pages: Pages to be pined.
+ * @usr_pgs: struct page array pointer where the user pages will be stored
+ */
+static int get_io_pages(struct mm_struct *mm, u32 uva, unsigned pages,
+ struct page **usr_pgs)
+{
+ struct page *pg;
+ u32 pa;
+ int i;
+
+ for (i = 0; i < pages; i++) {
+ pa = user_va2_pa(mm, uva);
+
+ if (!pfn_valid(__phys_to_pfn(pa)))
+ break;
+
+ pg = phys_to_page(pa);
+ usr_pgs[i] = pg;
+ get_page(pg);
+ }
+ return i;
+}
+
+/**
+ * user_to_dsp_map() - maps user to dsp virtual address.
+ * @dev_ctx: Pointer to device context handle.
+ * @uva: User space virtual address.
+ * @da: DSP address.
+ * @size: Buffer size to map.
+ * @usr_pgs: Struct page array pointer where the user pages will be stored.
+ */
+u32 user_to_dsp_map(struct bridge_dev_context *dev_ctx, u32 uva, u32 da,
+ u32 size, struct page **usr_pgs)
+
+{
+ int res, w;
+ unsigned pages, i;
+ struct iommu *mmu = dev_ctx->dsp_mmu;
+ struct vm_area_struct *vma;
+ struct mm_struct *mm = current->mm;
+#ifndef ARCH_HAS_SG_CHAIN
+ u32 pa, addr;
+ struct iotlb_entry e;
+#else
+ struct sg_table *sgt;
+ struct scatterlist *sg;
+#endif
+
+ if (!size || !usr_pgs)
+ return -EINVAL;
+
+ pages = size / PG_SIZE4K;
+
+ down_read(&mm->mmap_sem);
+
+ vma = find_vma(mm, uva);
+ while (vma && (uva + size > vma->vm_end))
+ vma = find_vma(mm, vma->vm_end + 1);
+
+ if (!vma) {
+ pr_err("%s: Failed to get VMA region for 0x%x (%d)\n",
+ __func__, uva, size);
+ up_read(&mm->mmap_sem);
+ return -EINVAL;
+ }
+
+ if (vma->vm_flags & (VM_WRITE | VM_MAYWRITE))
+ w = 1;
+
+ if (vma->vm_flags & VM_IO)
+ i = get_io_pages(mm, uva, pages, usr_pgs);
+ else
+ i = get_user_pages(current, mm, uva, pages, w, 1,
+ usr_pgs, NULL);
+
+ up_read(&mm->mmap_sem);
+
+ if (i < 0)
+ return i;
+
+ if (i < pages) {
+ res = -EFAULT;
+ goto err_pages;
+ }
+
+#ifndef ARCH_HAS_SG_CHAIN
+ da = gen_pool_alloc(dmm_pool, size);
+ if (!da) {
+ res = -ENOMEM;
+ goto err_pages;
+ }
+
+ wake_dsp(dev_ctx, NULL);
+
+ for (i = 0, addr = da; i < pages; i++, addr += PAGE_SIZE) {
+ pa = page_to_phys(usr_pgs[i]);
+ dsptlb_init_entry(&e, addr, pa, MMU_CAM_PGSZ_4K);
+ iopgtable_store_entry(mmu, &e);
+ }
+
+ return da;
+#else
+ sgt = kzalloc(sizeof(*sgt), GFP_KERNEL);
+ if (!sgt) {
+ res = -ENOMEM;
+ goto err_pages;
+ }
+
+ res = sg_alloc_table(sgt, pages, GFP_KERNEL);
+
+ if (res < 0)
+ goto err_sg;
+
+ for_each_sg(sgt->sgl, sg, sgt->nents, i)
+ sg_set_page(sg, usr_pgs[i], PAGE_SIZE, 0);
+
+ wake_dsp(dev_ctx, NULL);
+
+ da = iommu_vmap(mmu, da, sgt, IOVMF_ENDIAN_LITTLE | IOVMF_ELSZ_32);
+
+ if (!IS_ERR_VALUE(da))
+ return da;
+ res = (int)da;
+
+ sg_free_table(sgt);
+err_sg:
+ kfree(sgt);
+ i = pages;
+#endif /* ARCH_HAS_SG_CHAIN */
+
+err_pages:
+ while (i--)
+ put_page(usr_pgs[i]);
+ return res;
+}
+
+/**
+ * user_to_dsp_unmap() - unmap DSP virtual buffer.
+ * @dev_ctx: Pointer to device context handle.
+ * @da: DSP address.
+ * @size: Buffer size to unmap.
+ * @usr_pgs: Struct page array pointer where the user pages are stored.
+ */
+int user_to_dsp_unmap(struct bridge_dev_context *dev_ctx, u32 da,
+ size_t size, struct page **usr_pgs)
+{
+ unsigned i = 0;
+
+#ifndef ARCH_HAS_SG_CHAIN
+ gen_pool_free(dmm_pool, da, size);
+
+ wake_dsp(dev_ctx, NULL);
+
+ while (size > 0) {
+ size_t bytes;
+ bytes = iopgtable_clear_entry(dev_ctx->dsp_mmu, da);
+ size -= bytes;
+ da += bytes;
+ put_page(usr_pgs[i++]);
+ }
+#else
+ struct sg_table *sgt;
+ struct scatterlist *sg;
+
+ wake_dsp(dev_ctx, NULL);
+
+ sgt = iommu_vunmap(dev_ctx->dsp_mmu, da);
+ if (!sgt)
+ return -EFAULT;
+
+ for_each_sg(sgt->sgl, sg, sgt->nents, i)
+ put_page(sg_page(sg));
+
+ sg_free_table(sgt);
+ kfree(sgt);
+#endif /* ARCH_HAS_SG_CHAIN */
+
+ return 0;
+}
+
+#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
+static void mmu_fault_print_stack(struct bridge_dev_context *dev_context)
+{
+ void *dummy_addr;
+ u32 fa, tmp;
+ struct iotlb_entry e;
+ struct iommu *mmu = dev_context->dsp_mmu;
+ dummy_addr = (void *)__get_free_page(GFP_ATOMIC);
+
+ /*
+ * Before acking the MMU fault, let's make sure MMU can only
+ * access entry #0. Then add a new entry so that the DSP OS
+ * can continue in order to dump the stack.
+ */
+ tmp = iommu_read_reg(mmu, MMU_CNTL);
+ tmp &= ~MMU_CNTL_TWL_EN;
+ iommu_write_reg(mmu, tmp, MMU_CNTL);
+ fa = iommu_read_reg(mmu, MMU_FAULT_AD);
+ e.da = fa & PAGE_MASK;
+ e.pa = virt_to_phys(dummy_addr);
+ e.valid = 1;
+ e.prsvd = 1;
+ e.pgsz = IOVMF_PGSZ_4K & MMU_CAM_PGSZ_MASK;
+ e.endian = MMU_RAM_ENDIAN_LITTLE;
+ e.elsz = MMU_RAM_ELSZ_32;
+ e.mixed = 0;
+
+ load_iotlb_entry(dev_context->dsp_mmu, &e);
+
+ dsp_clk_enable(DSP_CLK_GPT8);
+
+ dsp_gpt_wait_overflow(DSP_CLK_GPT8, 0xfffffffe);
+
+ /* Clear MMU interrupt */
+ tmp = iommu_read_reg(mmu, MMU_IRQSTATUS);
+ iommu_write_reg(mmu, tmp, MMU_IRQSTATUS);
+
+ dump_dsp_stack(dev_context);
+ dsp_clk_disable(DSP_CLK_GPT8);
+
+ iopgtable_clear_entry(mmu, fa);
+ free_page((unsigned long)dummy_addr);
+}
+#endif
+
+static void mmufault_tasklet(unsigned long data)
+{
+ struct iommu *mmu = (struct iommu *)data;
+ struct bridge_dev_context *dev_ctx;
+ struct deh_mgr *deh;
+ u32 fa;
+
+ dev_get_deh_mgr(dev_get_first(), &deh);
+ dev_get_bridge_context(dev_get_first(), &dev_ctx);
+
+ if (!deh || !dev_ctx)
+ return;
+
+ fa = iommu_read_reg(mmu, MMU_FAULT_AD);
+
+#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
+ print_dsp_trace_buffer(dev_ctx);
+ dump_dl_modules(dev_ctx);
+ mmu_fault_print_stack(dev_ctx);
+#endif
+
+ bridge_deh_notify(deh, DSP_MMUFAULT, fa);
+}
+
+static struct tasklet_struct mmufault_tsk;
+
+int mmufault_cb(struct iommu *mmu, u32 da, u32 iommu_errs, void *priv)
+{
+ iommu_write_reg(mmu, 0, MMU_IRQENABLE);
+ tasklet_schedule(&mmufault_tsk);
+
+ return 0;
+}
+
+/**
+ * dsp_mmu_init() - initialize iommu module
+ *
+ * This function initializes iommu module, it returns a struct iommu
+ * handle to be used for dsp maps.
+ */
+struct iommu *dsp_mmu_init()
+{
+ struct iommu *mmu;
+
+ mmu = iommu_get("iva2");
+ if (IS_ERR(mmu))
+ return mmu;
+
+ tasklet_init(&mmufault_tsk, mmufault_tasklet, (unsigned long)mmu);
+ mmu->isr = mmufault_cb;
+
+#ifndef ARCH_HAS_SG_CHAIN
+ if (dmm_pool) {
+ gen_pool_destroy(dmm_pool);
+ dmm_pool = NULL;
+ }
+
+ dmm_pool = gen_pool_create(PAGE_SHIFT, -1);
+ if (!dmm_pool) {
+ iommu_put(mmu);
+ return ERR_PTR(-ENOMEM);
+ } else {
+ struct bridge_dev_context *dev_ctx;
+ struct shm_segs *sm_sg;
+ u32 start;
+
+ dev_get_bridge_context(dev_get_first(), &dev_ctx);
+ if (!dev_ctx)
+ return ERR_PTR(-EFAULT);
+
+ sm_sg = &dev_ctx->sh_s;
+ start = sm_sg->seg1_da + sm_sg->seg1_size;
+ gen_pool_add(dmm_pool, start, CONFIG_TIDSPBRIDGE_DMM_SIZE, -1);
+ }
+#endif
+
+ return mmu;
+}
+
+/**
+ * dsp_mmu_exit() - destroy dsp mmu module
+ * @mmu: Pointer to iommu handle.
+ *
+ * This function destroys dsp mmu module.
+ *
+ */
+void dsp_mmu_exit(struct iommu *mmu)
+{
+ if (mmu)
+ iommu_put(mmu);
+ tasklet_kill(&mmufault_tsk);
+
+#ifndef ARCH_HAS_SG_CHAIN
+ if (dmm_pool) {
+ gen_pool_destroy(dmm_pool);
+ dmm_pool = NULL;
+ }
+#endif
+}
diff --git a/drivers/staging/tidspbridge/core/tiomap3430.c b/drivers/staging/tidspbridge/core/tiomap3430.c
index 8b77837..cc4bfbe 100644
--- a/drivers/staging/tidspbridge/core/tiomap3430.c
+++ b/drivers/staging/tidspbridge/core/tiomap3430.c
@@ -23,7 +23,7 @@
#include <dspbridge/host_os.h>
#include <linux/mm.h>
#include <linux/mmzone.h>
-#include <linux/genalloc.h>
+#include <dspbridge/dsp_mmu.h>

/* ----------------------------------- DSP/BIOS Bridge */
#include <dspbridge/dbdefs.h>
@@ -106,12 +106,6 @@ static int bridge_brd_mem_copy(struct bridge_dev_context *dev_ctxt,
static int bridge_brd_mem_write(struct bridge_dev_context *dev_ctxt,
u8 *host_buff, u32 dsp_addr,
u32 ul_num_bytes, u32 mem_type);
-static int bridge_brd_mem_map(struct bridge_dev_context *dev_ctxt,
- u32 ul_mpu_addr, u32 virt_addr,
- u32 ul_num_bytes, struct page **mapped_pages);
-static int bridge_brd_mem_un_map(struct bridge_dev_context *dev_ctxt,
- u32 da, size_t size,
- struct page **usr_pgs);
static int bridge_dev_create(struct bridge_dev_context
**dev_cntxt,
struct dev_object *hdev_obj,
@@ -119,9 +113,6 @@ static int bridge_dev_create(struct bridge_dev_context
static int bridge_dev_ctrl(struct bridge_dev_context *dev_context,
u32 dw_cmd, void *pargs);
static int bridge_dev_destroy(struct bridge_dev_context *dev_ctxt);
-static int get_io_pages(struct mm_struct *mm, u32 uva, unsigned pages,
- struct page **usr_pgs);
-static u32 user_va2_pa(struct mm_struct *mm, u32 address);
bool wait_for_start(struct bridge_dev_context *dev_context, u32 dw_sync_addr);

/* ----------------------------------- Globals */
@@ -145,8 +136,6 @@ static struct bridge_drv_interface drv_interface_fxns = {
bridge_brd_set_state,
bridge_brd_mem_copy,
bridge_brd_mem_write,
- bridge_brd_mem_map,
- bridge_brd_mem_un_map,
/* The following CHNL functions are provided by chnl_io.lib: */
bridge_chnl_create,
bridge_chnl_destroy,
@@ -180,27 +169,6 @@ static struct notifier_block dsp_mbox_notifier = {
.notifier_call = io_mbox_msg,
};

-#ifndef ARCH_HAS_SG_CHAIN
-static struct gen_pool *dmm_pool;
-
-static inline u32 dsptlb_init_entry(struct iotlb_entry *e, u32 da, u32 pa,
- u32 pgsz)
-{
- memset(e, 0, sizeof(*e));
-
- e->da = da;
- e->pa = pa;
- e->valid = 1;
- e->pgsz = MMU_CAM_PGSZ_4K;
- e->pgsz = pgsz & MMU_CAM_PGSZ_MASK;
- e->endian = MMU_RAM_ENDIAN_LITTLE;
- e->elsz = MMU_RAM_ELSZ_32;
- e->mixed = 0;
-
- return iopgsz_to_bytes(e->pgsz);
-}
-#endif /* !ARCH_HAS_SG_CHAIN */
-
/*
* ======== bridge_drv_entry ========
* purpose:
@@ -406,38 +374,16 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt,

mmu = dev_context->dsp_mmu;
if (mmu)
- iommu_put(mmu);
+ dsp_mmu_exit(mmu);

- mmu = iommu_get("iva2");
+ mmu = dsp_mmu_init();
if (IS_ERR(mmu)) {
dev_err(bridge, "iommu_get failed!\n");
dev_context->dsp_mmu = NULL;
return PTR_ERR(mmu);
}
-#ifndef ARCH_HAS_SG_CHAIN
- else {
- u32 start;
-
- if (dmm_pool) {
- gen_pool_destroy(dmm_pool);
- dmm_pool = NULL;
- }
-
- dmm_pool = gen_pool_create(PAGE_SHIFT, -1);
- if (!dmm_pool) {
- iommu_put(mmu);
- dev_context->dsp_mmu = NULL;
- return -ENOMEM;
- }
-
- sm_sg = &dev_context->sh_s;
- start = sm_sg->seg1_da + sm_sg->seg1_size;
- gen_pool_add(dmm_pool, start, CONFIG_TIDSPBRIDGE_DMM_SIZE, -1);
- }
-#endif

dev_context->dsp_mmu = mmu;
- mmu->isr = mmu_fault_isr;
sm_sg = &dev_context->sh_s;
/* Set valid range to map shared memory */
status = iommu_set_da_range(mmu, sm_sg->seg0_da,
@@ -702,14 +648,8 @@ static int bridge_brd_stop(struct bridge_dev_context *dev_ctxt)

iommu_kunmap(dev_context->dsp_mmu, dev_context->sh_s.seg1_da);
iommu_kunmap(dev_context->dsp_mmu, dev_context->sh_s.seg0_da);
- iommu_put(dev_context->dsp_mmu);
+ dsp_mmu_exit(dev_context->dsp_mmu);
dev_context->dsp_mmu = NULL;
-#ifndef ARCH_HAS_SG_CHAIN
- if (dmm_pool) {
- gen_pool_destroy(dmm_pool);
- dmm_pool = NULL;
- }
-#endif
}

/* Reset IVA IOMMU */
@@ -1018,209 +958,6 @@ static int bridge_brd_mem_write(struct bridge_dev_context *dev_ctxt,
}

/*
- * ======== bridge_brd_mem_map ========
- * 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)
- *
- * TODO: Disable MMU while updating the page tables (but that'll stall DSP)
- */
-static int bridge_brd_mem_map(struct bridge_dev_context *dev_ctx,
- u32 uva, u32 da, u32 size, struct page **usr_pgs)
-
-{
- int res, w;
- unsigned pages, i;
- struct iommu *mmu = dev_ctx->dsp_mmu;
- struct vm_area_struct *vma;
- struct mm_struct *mm = current->mm;
-#ifndef ARCH_HAS_SG_CHAIN
- u32 pa, addr;
- struct iotlb_entry e;
-#else
- struct sg_table *sgt;
- struct scatterlist *sg;
-#endif
-
- if (!size || !usr_pgs)
- return -EINVAL;
-
- pages = size / PG_SIZE4K;
-
- down_read(&mm->mmap_sem);
- vma = find_vma(mm, uva);
- while (vma && (uva + size > vma->vm_end))
- vma = find_vma(mm, vma->vm_end + 1);
-
- if (!vma) {
- pr_err("%s: Failed to get VMA region for 0x%x (%d)\n",
- __func__, uva, size);
- up_read(&mm->mmap_sem);
- return -EINVAL;
- }
- if (vma->vm_flags & (VM_WRITE | VM_MAYWRITE))
- w = 1;
-
- if (vma->vm_flags & VM_IO)
- i = get_io_pages(mm, uva, pages, usr_pgs);
- else
- i = get_user_pages(current, mm, uva, pages, w, 1,
- usr_pgs, NULL);
- up_read(&mm->mmap_sem);
-
- if (i < 0)
- return i;
-
- if (i < pages) {
- res = -EFAULT;
- goto err_pages;
- }
-
-#ifndef ARCH_HAS_SG_CHAIN
- da = gen_pool_alloc(dmm_pool, size);
- if (!da) {
- res = -ENOMEM;
- goto err_pages;
- }
-
- wake_dsp(dev_ctx, NULL);
-
- for (i = 0, addr = da; i < pages; i++, addr += PAGE_SIZE) {
- pa = page_to_phys(usr_pgs[i]);
- dsptlb_init_entry(&e, addr, pa, MMU_CAM_PGSZ_4K);
- iopgtable_store_entry(mmu, &e);
- }
-
- return da;
-#else
- sgt = kzalloc(sizeof(*sgt), GFP_KERNEL);
- if (!sgt) {
- res = -ENOMEM;
- goto err_pages;
- }
-
- res = sg_alloc_table(sgt, pages, GFP_KERNEL);
-
- if (res < 0)
- goto err_sg;
-
- for_each_sg(sgt->sgl, sg, sgt->nents, i)
- sg_set_page(sg, usr_pgs[i], PAGE_SIZE, 0);
-
- wake_dsp(dev_ctx, NULL);
-
- da = iommu_vmap(mmu, da, sgt, IOVMF_ENDIAN_LITTLE | IOVMF_ELSZ_32);
-
- if (!IS_ERR_VALUE(da))
- return da;
- res = (int)da;
-
- sg_free_table(sgt);
-err_sg:
- kfree(sgt);
- i = pages;
-#endif /* ARCH_HAS_SG_CHAIN */
-err_pages:
- while (i--)
- put_page(usr_pgs[i]);
- return res;
-}
-
-/*
- * ======== bridge_brd_mem_un_map ========
- * 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
- */
-static int bridge_brd_mem_un_map(struct bridge_dev_context *dev_ctx, u32 da,
- size_t size, struct page **usr_pgs)
-{
- unsigned i = 0;
-#ifndef ARCH_HAS_SG_CHAIN
- gen_pool_free(dmm_pool, da, size);
-
- wake_dsp(dev_ctx, NULL);
-
- while (size > 0) {
- size_t bytes;
- bytes = iopgtable_clear_entry(dev_ctx->dsp_mmu, da);
- size -= bytes;
- da += bytes;
- put_page(usr_pgs[i++]);
- }
-#else
- struct sg_table *sgt;
- struct scatterlist *sg;
-
- wake_dsp(dev_ctx, NULL);
-
- sgt = iommu_vunmap(dev_ctx->dsp_mmu, da);
- if (!sgt)
- return -EFAULT;
-
- for_each_sg(sgt->sgl, sg, sgt->nents, i)
- put_page(sg_page(sg));
-
- sg_free_table(sgt);
- kfree(sgt);
-#endif /* ARCH_HAS_SG_CHAIN */
-
- return 0;
-}
-
-
-static int get_io_pages(struct mm_struct *mm, u32 uva, unsigned pages,
- struct page **usr_pgs)
-{
- u32 pa;
- int i;
- struct page *pg;
-
- for (i = 0; i < pages; i++) {
- pa = user_va2_pa(mm, uva);
-
- if (!pfn_valid(__phys_to_pfn(pa)))
- break;
-
- pg = PHYS_TO_PAGE(pa);
- usr_pgs[i] = pg;
- get_page(pg);
- }
- return i;
-}
-
-/*
- * ======== user_va2_pa ========
- * Purpose:
- * This function walks through the page tables to convert a userland
- * virtual address to physical address
- */
-static u32 user_va2_pa(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;
-}
-
-/*
* ======== wait_for_start ========
* Wait for the singal from DSP that it has started, or time out.
*/
diff --git a/drivers/staging/tidspbridge/core/ue_deh.c b/drivers/staging/tidspbridge/core/ue_deh.c
index 317e7f6..1f1c084 100644
--- a/drivers/staging/tidspbridge/core/ue_deh.c
+++ b/drivers/staging/tidspbridge/core/ue_deh.c
@@ -31,33 +31,6 @@
#include <dspbridge/drv.h>
#include <dspbridge/wdt.h>

-#define MMU_CNTL_TWL_EN (1 << 2)
-
-static void mmu_fault_dpc(unsigned long data)
-{
- struct deh_mgr *deh = (void *)data;
-
- if (!deh)
- return;
-
- bridge_deh_notify(deh, DSP_MMUFAULT, 0);
-}
-
-int mmu_fault_isr(struct iommu *mmu, u32 da, u32 iommu_errs, void *priv)
-{
- struct deh_mgr *deh;
-
- dev_get_deh_mgr(dev_get_first(), &deh);
-
- if (!deh)
- return -EPERM;
-
- iommu_write_reg(mmu, 0, MMU_IRQENABLE);
- tasklet_schedule(&deh->dpc_tasklet);
-
- return 0;
-}
-
int bridge_deh_create(struct deh_mgr **ret_deh,
struct dev_object *hdev_obj)
{
@@ -85,9 +58,6 @@ int bridge_deh_create(struct deh_mgr **ret_deh,
}
ntfy_init(deh->ntfy_obj);

- /* Create a MMUfault DPC */
- tasklet_init(&deh->dpc_tasklet, mmu_fault_dpc, (u32) deh);
-
/* Fill in context structure */
deh->bridge_context = hbridge_context;

@@ -111,9 +81,6 @@ int bridge_deh_destroy(struct deh_mgr *deh)
kfree(deh->ntfy_obj);
}

- /* Free DPC object */
- tasklet_kill(&deh->dpc_tasklet);
-
/* Deallocate the DEH manager object */
kfree(deh);

@@ -134,51 +101,6 @@ int bridge_deh_register_notify(struct deh_mgr *deh, u32 event_mask,
return ntfy_unregister(deh->ntfy_obj, hnotification);
}

-#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
-static void mmu_fault_print_stack(struct bridge_dev_context *dev_context)
-{
- void *dummy_addr;
- u32 fa, tmp;
- struct iotlb_entry e;
- struct iommu *mmu = dev_context->dsp_mmu;
- dummy_addr = (void *)__get_free_page(GFP_ATOMIC);
-
- /*
- * Before acking the MMU fault, let's make sure MMU can only
- * access entry #0. Then add a new entry so that the DSP OS
- * can continue in order to dump the stack.
- */
- tmp = iommu_read_reg(mmu, MMU_CNTL);
- tmp &= ~MMU_CNTL_TWL_EN;
- iommu_write_reg(mmu, tmp, MMU_CNTL);
- fa = iommu_read_reg(mmu, MMU_FAULT_AD);
- e.da = fa & PAGE_MASK;
- e.pa = virt_to_phys(dummy_addr);
- e.valid = 1;
- e.prsvd = 1;
- e.pgsz = IOVMF_PGSZ_4K & MMU_CAM_PGSZ_MASK;
- e.endian = MMU_RAM_ENDIAN_LITTLE;
- e.elsz = MMU_RAM_ELSZ_32;
- e.mixed = 0;
-
- load_iotlb_entry(dev_context->dsp_mmu, &e);
-
- dsp_clk_enable(DSP_CLK_GPT8);
-
- dsp_gpt_wait_overflow(DSP_CLK_GPT8, 0xfffffffe);
-
- /* Clear MMU interrupt */
- tmp = iommu_read_reg(mmu, MMU_IRQSTATUS);
- iommu_write_reg(mmu, tmp, MMU_IRQSTATUS);
-
- dump_dsp_stack(dev_context);
- dsp_clk_disable(DSP_CLK_GPT8);
-
- iopgtable_clear_entry(mmu, fa);
- free_page((unsigned long)dummy_addr);
-}
-#endif
-
static inline const char *event_to_string(int event)
{
switch (event) {
@@ -194,7 +116,6 @@ void bridge_deh_notify(struct deh_mgr *deh, int event, int info)
{
struct bridge_dev_context *dev_context;
const char *str = event_to_string(event);
- u32 fa;

if (!deh)
return;
@@ -212,13 +133,7 @@ void bridge_deh_notify(struct deh_mgr *deh, int event, int info)
#endif
break;
case DSP_MMUFAULT:
- fa = iommu_read_reg(dev_context->dsp_mmu, MMU_FAULT_AD);
- dev_err(bridge, "%s: %s, addr=0x%x", __func__, str, fa);
-#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
- print_dsp_trace_buffer(dev_context);
- dump_dl_modules(dev_context);
- mmu_fault_print_stack(dev_context);
-#endif
+ dev_err(bridge, "%s: %s, addr=0x%x", __func__, str, info);
break;
default:
dev_err(bridge, "%s: %s", __func__, str);
diff --git a/drivers/staging/tidspbridge/include/dspbridge/dsp_mmu.h b/drivers/staging/tidspbridge/include/dspbridge/dsp_mmu.h
new file mode 100644
index 0000000..ff70c9d
--- /dev/null
+++ b/drivers/staging/tidspbridge/include/dspbridge/dsp_mmu.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2011 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 _DSP_MMU_
+#define _DSP_MMU_
+
+#include <linux/string.h>
+#include <linux/mutex.h>
+#include <linux/spinlock.h>
+#include <linux/genalloc.h>
+
+#include <plat/iommu.h>
+#include <plat/iovmm.h>
+
+struct bridge_dev_context;
+
+u32 user_to_dsp_map(struct bridge_dev_context *dev_ctx, u32 uva, u32 da,
+ u32 size, struct page **usr_pgs);
+int user_to_dsp_unmap(struct bridge_dev_context *dev_ctx, u32 da, size_t size,
+ struct page **usr_pgs);
+struct iommu *dsp_mmu_init(void);
+void dsp_mmu_exit(struct iommu *mmu);
+
+#endif /* _DSP_MMU_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h b/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h
index e052bba..fb1aa89 100644
--- a/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h
+++ b/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h
@@ -156,48 +156,6 @@ typedef int(*fxn_brd_memwrite) (struct bridge_dev_context
u32 mem_type);

/*
- * ======== bridge_brd_mem_map ========
- * Purpose:
- * Map a MPU memory region to a DSP/IVA memory space
- * Parameters:
- * dev_ctxt: Handle to Bridge driver defined device info.
- * ul_mpu_addr: MPU memory region start address.
- * virt_addr: DSP/IVA memory region u8 address.
- * ul_num_bytes: Number of bytes to map.
- * map_attrs: Mapping attributes (e.g. endianness).
- * Returns:
- * 0: Success.
- * -EPERM: Other, unspecified error.
- * Requires:
- * dev_ctxt != NULL;
- * Ensures:
- */
-typedef int(*fxn_brd_memmap) (struct bridge_dev_context
- * dev_ctxt, u32 ul_mpu_addr,
- u32 virt_addr, u32 ul_num_bytes,
- struct page **mapped_pages);
-
-/*
- * ======== bridge_brd_mem_un_map ========
- * Purpose:
- * UnMap an MPU memory region from DSP/IVA memory space
- * Parameters:
- * dev_ctxt: Handle to Bridge driver defined device info.
- * virt_addr: DSP/IVA memory region u8 address.
- * ul_num_bytes: Number of bytes to unmap.
- * Returns:
- * 0: Success.
- * -EPERM: Other, unspecified error.
- * Requires:
- * dev_ctxt != NULL;
- * Ensures:
- */
-typedef int(*fxn_brd_memunmap) (struct bridge_dev_context
- * dev_ctxt,
- u32 da, size_t size,
- struct page **usr_pgs);
-
-/*
* ======== bridge_brd_stop ========
* Purpose:
* Bring board to the BRD_STOPPED state.
@@ -987,8 +945,6 @@ struct bridge_drv_interface {
fxn_brd_setstate brd_set_state; /* Sets the Board State */
fxn_brd_memcopy brd_mem_copy; /* Copies DSP Memory */
fxn_brd_memwrite brd_mem_write; /* Write DSP Memory w/o halt */
- fxn_brd_memmap brd_mem_map; /* Maps MPU mem to DSP mem */
- fxn_brd_memunmap brd_mem_un_map; /* Unmaps MPU mem to DSP mem */
fxn_chnl_create chnl_create; /* Create channel manager. */
fxn_chnl_destroy chnl_destroy; /* Destroy channel manager. */
fxn_chnl_open chnl_open; /* Create a new channel. */
diff --git a/drivers/staging/tidspbridge/pmgr/dev.c b/drivers/staging/tidspbridge/pmgr/dev.c
index d8f4079..2cdfc92 100644
--- a/drivers/staging/tidspbridge/pmgr/dev.c
+++ b/drivers/staging/tidspbridge/pmgr/dev.c
@@ -1038,8 +1038,6 @@ static void store_interface_fxns(struct bridge_drv_interface *drv_fxns,
STORE_FXN(fxn_brd_setstate, brd_set_state);
STORE_FXN(fxn_brd_memcopy, brd_mem_copy);
STORE_FXN(fxn_brd_memwrite, brd_mem_write);
- STORE_FXN(fxn_brd_memmap, brd_mem_map);
- STORE_FXN(fxn_brd_memunmap, brd_mem_un_map);
STORE_FXN(fxn_chnl_create, chnl_create);
STORE_FXN(fxn_chnl_destroy, chnl_destroy);
STORE_FXN(fxn_chnl_open, chnl_open);
diff --git a/drivers/staging/tidspbridge/rmgr/proc.c b/drivers/staging/tidspbridge/rmgr/proc.c
index c53e60c..2623cdd 100644
--- a/drivers/staging/tidspbridge/rmgr/proc.c
+++ b/drivers/staging/tidspbridge/rmgr/proc.c
@@ -21,6 +21,7 @@
#include <linux/dma-mapping.h>
#include <linux/scatterlist.h>
#include <dspbridge/host_os.h>
+#include <dspbridge/dsp_mmu.h>

/* ----------------------------------- DSP/BIOS Bridge */
#include <dspbridge/dbdefs.h>
@@ -1392,9 +1393,10 @@ int proc_map(void *hprocessor, void *pmpu_addr, u32 ul_size,
if (!map_obj) {
status = -ENOMEM;
} else {
- va_align = (*p_proc_object->intf_fxns->brd_mem_map)
- (p_proc_object->bridge_context, pa_align, 0,
- size_align, map_obj->pages);
+ va_align =
+ user_to_dsp_map(p_proc_object->bridge_context,
+ pa_align, 0, size_align,
+ map_obj->pages);
if (IS_ERR_VALUE(va_align))
status = va_align;
}
@@ -1662,9 +1664,8 @@ int proc_un_map(void *hprocessor, void *map_addr,
goto unmap_failed;

/* Remove mapping from the page tables. */
- status = (*p_proc_object->intf_fxns->brd_mem_un_map)
- (p_proc_object->bridge_context, va_align, dmo->size,
- dmo->pages);
+ status = user_to_dsp_unmap(p_proc_object->bridge_context, va_align,
+ dmo->size, dmo->pages);
if (status)
goto unmap_failed;

--
1.7.1

2011-04-28 15:44:31

by Ramirez Luna, Omar

[permalink] [raw]
Subject: [PATCH v4 4/6] staging: tidspbridge: remove custom mmu code

From: Fernando Guzman Lugo <[email protected]>

This code is not needed anymore.

Signed-off-by: Fernando Guzman Lugo <[email protected]>
Signed-off-by: Omar Ramirez Luna <[email protected]>
---
drivers/staging/tidspbridge/Makefile | 3 +-
drivers/staging/tidspbridge/core/_tiomap.h | 3 -
drivers/staging/tidspbridge/core/io_sm.c | 4 -
drivers/staging/tidspbridge/core/tiomap3430.c | 427 ---------------
drivers/staging/tidspbridge/core/tiomap3430_pwr.c | 4 -
drivers/staging/tidspbridge/core/tiomap_io.c | 2 +-
drivers/staging/tidspbridge/hw/EasiGlobal.h | 41 --
drivers/staging/tidspbridge/hw/MMUAccInt.h | 76 ---
drivers/staging/tidspbridge/hw/MMURegAcM.h | 225 --------
drivers/staging/tidspbridge/hw/hw_defs.h | 58 --
drivers/staging/tidspbridge/hw/hw_mmu.c | 562 --------------------
drivers/staging/tidspbridge/hw/hw_mmu.h | 163 ------
.../tidspbridge/include/dspbridge/cfgdefs.h | 1 -
.../staging/tidspbridge/include/dspbridge/drv.h | 3 -
.../tidspbridge/include/dspbridge/dspioctl.h | 7 -
drivers/staging/tidspbridge/rmgr/drv.c | 4 -
16 files changed, 2 insertions(+), 1581 deletions(-)
delete mode 100644 drivers/staging/tidspbridge/hw/EasiGlobal.h
delete mode 100644 drivers/staging/tidspbridge/hw/MMUAccInt.h
delete mode 100644 drivers/staging/tidspbridge/hw/MMURegAcM.h
delete mode 100644 drivers/staging/tidspbridge/hw/hw_defs.h
delete mode 100644 drivers/staging/tidspbridge/hw/hw_mmu.c
delete mode 100644 drivers/staging/tidspbridge/hw/hw_mmu.h

diff --git a/drivers/staging/tidspbridge/Makefile b/drivers/staging/tidspbridge/Makefile
index fd6a276..9c7f974 100644
--- a/drivers/staging/tidspbridge/Makefile
+++ b/drivers/staging/tidspbridge/Makefile
@@ -11,10 +11,9 @@ librmgr = rmgr/dbdcd.o rmgr/disp.o rmgr/drv.o rmgr/mgr.o rmgr/node.o \
rmgr/nldr.o rmgr/drv_interface.o
libdload = dynload/cload.o dynload/getsection.o dynload/reloc.o \
dynload/tramp.o
-libhw = hw/hw_mmu.o

bridgedriver-y := $(libgen) $(libservices) $(libcore) $(libpmgr) $(librmgr) \
- $(libdload) $(libhw)
+ $(libdload)

#Machine dependent
ccflags-y += -D_TI_ -D_DB_TIOMAP -DTMS32060 \
diff --git a/drivers/staging/tidspbridge/core/_tiomap.h b/drivers/staging/tidspbridge/core/_tiomap.h
index d493e11..49a035a 100644
--- a/drivers/staging/tidspbridge/core/_tiomap.h
+++ b/drivers/staging/tidspbridge/core/_tiomap.h
@@ -37,7 +37,6 @@
#include <plat/iommu.h>
#include <plat/iovmm.h>
#include <dspbridge/devdefs.h>
-#include <hw_defs.h>
#include <dspbridge/dspioctl.h> /* for bridge_ioctl_extproc defn */
#include <dspbridge/sync.h>
#include <dspbridge/clk.h>
@@ -340,7 +339,6 @@ struct bridge_dev_context {
*/
u32 dsp_ext_base_addr; /* See the comment above */
u32 api_reg_base; /* API mem map'd registers */
- void __iomem *dsp_mmu_base; /* DSP MMU Mapped registers */
u32 api_clk_base; /* CLK Registers */
u32 dsp_clk_m2_base; /* DSP Clock Module m2 */
u32 public_rhea; /* Pub Rhea */
@@ -366,7 +364,6 @@ struct bridge_dev_context {

/* TC Settings */
bool tc_word_swap_on; /* Traffic Controller Word Swap */
- struct pg_table_attrs *pt_attrs;
u32 dsp_per_clks;
};

diff --git a/drivers/staging/tidspbridge/core/io_sm.c b/drivers/staging/tidspbridge/core/io_sm.c
index 3558658..8408d51 100644
--- a/drivers/staging/tidspbridge/core/io_sm.c
+++ b/drivers/staging/tidspbridge/core/io_sm.c
@@ -40,10 +40,6 @@
#include <dspbridge/ntfy.h>
#include <dspbridge/sync.h>

-/* Hardware Abstraction Layer */
-#include <hw_defs.h>
-#include <hw_mmu.h>
-
/* Bridge Driver */
#include <dspbridge/dspdeh.h>
#include <dspbridge/dspio.h>
diff --git a/drivers/staging/tidspbridge/core/tiomap3430.c b/drivers/staging/tidspbridge/core/tiomap3430.c
index 692a456..e9b2ce0 100644
--- a/drivers/staging/tidspbridge/core/tiomap3430.c
+++ b/drivers/staging/tidspbridge/core/tiomap3430.c
@@ -35,10 +35,6 @@
#include <dspbridge/drv.h>
#include <dspbridge/sync.h>

-/* ------------------------------------ Hardware Abstraction Layer */
-#include <hw_defs.h>
-#include <hw_mmu.h>
-
/* ----------------------------------- Link Driver */
#include <dspbridge/dspdefs.h>
#include <dspbridge/dspchnl.h>
@@ -127,56 +123,10 @@ static int bridge_dev_destroy(struct bridge_dev_context *dev_ctxt);
static int get_io_pages(struct mm_struct *mm, u32 uva, unsigned pages,
struct page **usr_pgs);
static u32 user_va2_pa(struct mm_struct *mm, u32 address);
-static int pte_update(struct bridge_dev_context *dev_ctxt, u32 pa,
- u32 va, u32 size,
- struct hw_mmu_map_attrs_t *map_attrs);
-static int pte_set(struct pg_table_attrs *pt, u32 pa, u32 va,
- u32 size, struct hw_mmu_map_attrs_t *attrs);
-static int mem_map_vmalloc(struct bridge_dev_context *dev_context,
- u32 ul_mpu_addr, u32 virt_addr,
- u32 ul_num_bytes,
- struct hw_mmu_map_attrs_t *hw_attrs);
-
bool wait_for_start(struct bridge_dev_context *dev_context, u32 dw_sync_addr);

/* ----------------------------------- Globals */

-/* Attributes of L2 page tables for DSP MMU */
-struct page_info {
- u32 num_entries; /* Number of valid PTEs in the L2 PT */
-};
-
-/* Attributes used to manage the DSP MMU page tables */
-struct pg_table_attrs {
- spinlock_t pg_lock; /* 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 l2_tbl_alloc_sz;
- /* Size of consistent memory allocated for L2 table.
- * May not be aligned */
-
- u32 l2_num_pages; /* Number of allocated L2 PT */
- /* Array [l2_num_pages] of L2 PT info structs */
- struct page_info *pg_info;
-};
-
/*
* This Bridge driver's function interface table.
*/
@@ -252,27 +202,6 @@ static inline u32 dsptlb_init_entry(struct iotlb_entry *e, u32 da, u32 pa,
}
#endif /* !ARCH_HAS_SG_CHAIN */

-static inline void flush_all(struct bridge_dev_context *dev_context)
-{
- if (dev_context->brd_state == BRD_DSP_HIBERNATION ||
- dev_context->brd_state == BRD_HIBERNATION)
- wake_dsp(dev_context, NULL);
-
- hw_mmu_tlb_flush_all(dev_context->dsp_mmu_base);
-}
-
-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"
- "page:%p flags:0x%0*lx mapping:%p mapcount:%d count:%d\n"
- "Backtrace:\n",
- current->comm, pg, (int)(2 * sizeof(unsigned long)),
- (unsigned long)pg->flags, pg->mapping,
- page_mapcount(pg), page_count(pg));
- dump_stack();
-}
-
/*
* ======== bridge_drv_entry ========
* purpose:
@@ -709,7 +638,6 @@ static int bridge_brd_stop(struct bridge_dev_context *dev_ctxt)
{
int status = 0;
struct bridge_dev_context *dev_context = dev_ctxt;
- struct pg_table_attrs *pt_attrs;
u32 dsp_pwr_state;
int i;
struct bridge_ioctl_extproc *tlb = dev_context->atlb_entry;
@@ -748,14 +676,6 @@ static int bridge_brd_stop(struct bridge_dev_context *dev_ctxt)

dsp_wdt_enable(false);

- /* This is a good place to clear the MMU page tables as well */
- if (dev_context->pt_attrs) {
- pt_attrs = dev_context->pt_attrs;
- memset((u8 *) pt_attrs->l1_base_va, 0x00, pt_attrs->l1_size);
- memset((u8 *) pt_attrs->l2_base_va, 0x00, pt_attrs->l2_size);
- memset((u8 *) pt_attrs->pg_info, 0x00,
- (pt_attrs->l2_num_pages * sizeof(struct page_info)));
- }
/* Reset DSP */
(*pdata->dsp_prm_rmw_bits)(OMAP3430_RST1_IVA2_MASK,
OMAP3430_RST1_IVA2_MASK, OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);
@@ -855,10 +775,6 @@ static int bridge_dev_create(struct bridge_dev_context
struct bridge_dev_context *dev_context = NULL;
s32 entry_ndx;
struct cfg_hostres *resources = config_param;
- struct pg_table_attrs *pt_attrs;
- u32 pg_tbl_pa;
- u32 pg_tbl_va;
- u32 align_size;
struct drv_data *drv_datap = dev_get_drvdata(bridge);

/* Allocate and initialize a data structure to contain the bridge driver
@@ -889,94 +805,8 @@ static int bridge_dev_create(struct bridge_dev_context
if (!dev_context->dsp_base_addr)
status = -EPERM;

- pt_attrs = kzalloc(sizeof(struct pg_table_attrs), GFP_KERNEL);
- if (pt_attrs != NULL) {
- pt_attrs->l1_size = SZ_16K; /* 4096 entries of 32 bits */
- align_size = 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) mem_alloc_phys_mem(pt_attrs->l1_size,
- align_size, &pg_tbl_pa);
-
- /* 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 */
- mem_free_phys_mem((void *)pg_tbl_va, pg_tbl_pa,
- pt_attrs->l1_size);
- /* we like to get aligned on L1 table size */
- pg_tbl_va =
- (u32) mem_alloc_phys_mem((pt_attrs->l1_size) * 2,
- align_size, &pg_tbl_pa);
- /* We should be able to get aligned table now */
- pt_attrs->l1_tbl_alloc_pa = pg_tbl_pa;
- pt_attrs->l1_tbl_alloc_va = pg_tbl_va;
- pt_attrs->l1_tbl_alloc_sz = pt_attrs->l1_size * 2;
- /* Align the PA to the next 'align' boundary */
- pt_attrs->l1_base_pa =
- ((pg_tbl_pa) +
- (align_size - 1)) & (~(align_size - 1));
- pt_attrs->l1_base_va =
- pg_tbl_va + (pt_attrs->l1_base_pa - pg_tbl_pa);
- } else {
- /* We got aligned PA, cool */
- pt_attrs->l1_tbl_alloc_pa = pg_tbl_pa;
- pt_attrs->l1_tbl_alloc_va = pg_tbl_va;
- pt_attrs->l1_tbl_alloc_sz = pt_attrs->l1_size;
- pt_attrs->l1_base_pa = pg_tbl_pa;
- pt_attrs->l1_base_va = pg_tbl_va;
- }
- if (pt_attrs->l1_base_va)
- memset((u8 *) pt_attrs->l1_base_va, 0x00,
- pt_attrs->l1_size);
-
- /* number of L2 page tables = DMM pool used + SHMMEM +EXTMEM +
- * L4 pages */
- pt_attrs->l2_num_pages = ((DMMPOOLSIZE >> 20) + 6);
- pt_attrs->l2_size = HW_MMU_COARSE_PAGE_SIZE *
- 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) mem_alloc_phys_mem(pt_attrs->l2_size,
- align_size, &pg_tbl_pa);
- pt_attrs->l2_tbl_alloc_pa = pg_tbl_pa;
- pt_attrs->l2_tbl_alloc_va = pg_tbl_va;
- pt_attrs->l2_tbl_alloc_sz = pt_attrs->l2_size;
- pt_attrs->l2_base_pa = pg_tbl_pa;
- pt_attrs->l2_base_va = pg_tbl_va;
-
- if (pt_attrs->l2_base_va)
- memset((u8 *) pt_attrs->l2_base_va, 0x00,
- pt_attrs->l2_size);
-
- pt_attrs->pg_info = kzalloc(pt_attrs->l2_num_pages *
- sizeof(struct page_info), GFP_KERNEL);
- dev_dbg(bridge,
- "L1 pa %x, va %x, size %x\n L2 pa %x, va "
- "%x, size %x\n", pt_attrs->l1_base_pa,
- pt_attrs->l1_base_va, pt_attrs->l1_size,
- pt_attrs->l2_base_pa, pt_attrs->l2_base_va,
- pt_attrs->l2_size);
- dev_dbg(bridge, "pt_attrs %p L2 NumPages %x pg_info %p\n",
- pt_attrs, pt_attrs->l2_num_pages, pt_attrs->pg_info);
- }
- if ((pt_attrs != NULL) && (pt_attrs->l1_base_va != 0) &&
- (pt_attrs->l2_base_va != 0) && (pt_attrs->pg_info != NULL))
- dev_context->pt_attrs = pt_attrs;
- else
- status = -ENOMEM;
-
if (!status) {
- spin_lock_init(&pt_attrs->pg_lock);
dev_context->tc_word_swap_on = drv_datap->tc_wordswapon;
-
- /* Set the Clock Divisor for the DSP module */
- udelay(5);
- /* MMU address is obtained from the host
- * resources struct */
- dev_context->dsp_mmu_base = resources->dmmu_base;
- }
- if (!status) {
dev_context->dev_obj = hdev_obj;
/* Store current board state. */
dev_context->brd_state = BRD_UNKNOWN;
@@ -986,23 +816,6 @@ static int bridge_dev_create(struct bridge_dev_context
/* Return ptr to our device state to the DSP API for storage */
*dev_cntxt = dev_context;
} else {
- if (pt_attrs != NULL) {
- kfree(pt_attrs->pg_info);
-
- if (pt_attrs->l2_tbl_alloc_va) {
- mem_free_phys_mem((void *)
- pt_attrs->l2_tbl_alloc_va,
- pt_attrs->l2_tbl_alloc_pa,
- pt_attrs->l2_tbl_alloc_sz);
- }
- if (pt_attrs->l1_tbl_alloc_va) {
- mem_free_phys_mem((void *)
- pt_attrs->l1_tbl_alloc_va,
- pt_attrs->l1_tbl_alloc_pa,
- pt_attrs->l1_tbl_alloc_sz);
- }
- }
- kfree(pt_attrs);
kfree(dev_context);
}
func_end:
@@ -1070,7 +883,6 @@ static int bridge_dev_ctrl(struct bridge_dev_context *dev_context,
*/
static int bridge_dev_destroy(struct bridge_dev_context *dev_ctxt)
{
- struct pg_table_attrs *pt_attrs;
int status = 0;
struct bridge_dev_context *dev_context = (struct bridge_dev_context *)
dev_ctxt;
@@ -1084,23 +896,6 @@ static int bridge_dev_destroy(struct bridge_dev_context *dev_ctxt)

/* first put the device to stop state */
bridge_brd_stop(dev_context);
- if (dev_context->pt_attrs) {
- pt_attrs = dev_context->pt_attrs;
- kfree(pt_attrs->pg_info);
-
- if (pt_attrs->l2_tbl_alloc_va) {
- mem_free_phys_mem((void *)pt_attrs->l2_tbl_alloc_va,
- pt_attrs->l2_tbl_alloc_pa,
- pt_attrs->l2_tbl_alloc_sz);
- }
- if (pt_attrs->l1_tbl_alloc_va) {
- mem_free_phys_mem((void *)pt_attrs->l1_tbl_alloc_va,
- pt_attrs->l1_tbl_alloc_pa,
- pt_attrs->l1_tbl_alloc_sz);
- }
- kfree(pt_attrs);
-
- }

if (dev_context->resources) {
host_res = dev_context->resources;
@@ -1131,8 +926,6 @@ static int bridge_dev_destroy(struct bridge_dev_context *dev_ctxt)
iounmap((void *)host_res->mem_base[3]);
if (host_res->mem_base[4])
iounmap((void *)host_res->mem_base[4]);
- if (host_res->dmmu_base)
- iounmap(host_res->dmmu_base);
if (host_res->per_base)
iounmap(host_res->per_base);
if (host_res->per_pm_base)
@@ -1144,7 +937,6 @@ static int bridge_dev_destroy(struct bridge_dev_context *dev_ctxt)
host_res->mem_base[2] = (u32) NULL;
host_res->mem_base[3] = (u32) NULL;
host_res->mem_base[4] = (u32) NULL;
- host_res->dmmu_base = NULL;

kfree(host_res);
}
@@ -1430,225 +1222,6 @@ static u32 user_va2_pa(struct mm_struct *mm, u32 address)
}

/*
- * ======== pte_update ========
- * This function calculates the optimum page-aligned addresses and sizes
- * Caller must pass page-aligned values
- */
-static int pte_update(struct bridge_dev_context *dev_ctxt, 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;
- struct bridge_dev_context *dev_context = dev_ctxt;
- int status = 0;
- u32 page_size[] = { HW_PAGE_SIZE16MB, HW_PAGE_SIZE1MB,
- HW_PAGE_SIZE64KB, HW_PAGE_SIZE4KB
- };
-
- while (num_bytes && !status) {
- /* To find the max. page size with which both PA & VA are
- * aligned */
- all_bits = pa_curr | va_curr;
-
- for (i = 0; i < 4; i++) {
- if ((num_bytes >= page_size[i]) && ((all_bits &
- (page_size[i] -
- 1)) == 0)) {
- status =
- pte_set(dev_context->pt_attrs, pa_curr,
- va_curr, page_size[i], map_attrs);
- pa_curr += page_size[i];
- va_curr += page_size[i];
- num_bytes -= page_size[i];
- /* Don't try smaller sizes. Hopefully we have
- * reached an address aligned to a bigger page
- * size */
- break;
- }
- }
- }
-
- return status;
-}
-
-/*
- * ======== pte_set ========
- * This function calculates PTE address (MPU virtual) to be updated
- * It also manages the L2 page tables
- */
-static int pte_set(struct pg_table_attrs *pt, 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;
- /* Base address of the PT that will be updated */
- u32 pg_tbl_va;
- 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;
- int status = 0;
-
- l1_base_va = pt->l1_base_va;
- pg_tbl_va = l1_base_va;
- if ((size == HW_PAGE_SIZE64KB) || (size == HW_PAGE_SIZE4KB)) {
- /* 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_size_l1(pte_val);
- } else {
- return -EPERM;
- }
- spin_lock(&pt->pg_lock);
- 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_coarse_l1(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 = -EPERM;
- }
- if (!status) {
- pg_tbl_va = l2_base_va;
- if (size == HW_PAGE_SIZE64KB)
- pt->pg_info[l2_page_num].num_entries += 16;
- else
- pt->pg_info[l2_page_num].num_entries++;
- dev_dbg(bridge, "PTE: 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);
- }
- spin_unlock(&pt->pg_lock);
- }
- if (!status) {
- dev_dbg(bridge, "PTE: pg_tbl_va %x, pa %x, va %x, size %x\n",
- pg_tbl_va, pa, va, size);
- dev_dbg(bridge, "PTE: endianism %x, element_size %x, "
- "mixed_size %x\n", attrs->endianism,
- attrs->element_size, attrs->mixed_size);
- status = hw_mmu_pte_set(pg_tbl_va, pa, va, size, attrs);
- }
-
- return status;
-}
-
-/* Memory map kernel VA -- memory allocated with vmalloc */
-static int mem_map_vmalloc(struct bridge_dev_context *dev_context,
- u32 ul_mpu_addr, u32 virt_addr,
- u32 ul_num_bytes,
- struct hw_mmu_map_attrs_t *hw_attrs)
-{
- int status = 0;
- struct page *page[1];
- u32 i;
- u32 pa_curr;
- u32 pa_next;
- u32 va_curr;
- u32 size_curr;
- u32 num_pages;
- u32 pa;
- u32 num_of4k_pages;
- u32 temp = 0;
-
- /*
- * Do Kernel va to pa translation.
- * Combine physically contiguous regions to reduce TLBs.
- * Pass the translated pa to pte_update.
- */
- num_pages = ul_num_bytes / PAGE_SIZE; /* PAGE_SIZE = OS page size */
- i = 0;
- va_curr = ul_mpu_addr;
- page[0] = vmalloc_to_page((void *)va_curr);
- pa_next = page_to_phys(page[0]);
- while (!status && (i < num_pages)) {
- /*
- * Reuse pa_next from the previous iteraion to avoid
- * an extra va2pa call
- */
- pa_curr = pa_next;
- size_curr = PAGE_SIZE;
- /*
- * If the next page is physically contiguous,
- * map it with the current one by increasing
- * the size of the region to be mapped
- */
- while (++i < num_pages) {
- page[0] =
- vmalloc_to_page((void *)(va_curr + size_curr));
- pa_next = page_to_phys(page[0]);
-
- if (pa_next == (pa_curr + size_curr))
- size_curr += PAGE_SIZE;
- else
- break;
-
- }
- if (pa_next == 0) {
- status = -ENOMEM;
- break;
- }
- pa = pa_curr;
- num_of4k_pages = size_curr / HW_PAGE_SIZE4KB;
- while (temp++ < num_of4k_pages) {
- get_page(PHYS_TO_PAGE(pa));
- pa += HW_PAGE_SIZE4KB;
- }
- status = pte_update(dev_context, pa_curr, virt_addr +
- (va_curr - ul_mpu_addr), size_curr,
- hw_attrs);
- va_curr += size_curr;
- }
- /*
- * 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
- */
- flush_all(dev_context);
- dev_dbg(bridge, "%s status %x\n", __func__, status);
- return status;
-}
-
-/*
* ======== wait_for_start ========
* Wait for the singal from DSP that it has started, or time out.
*/
diff --git a/drivers/staging/tidspbridge/core/tiomap3430_pwr.c b/drivers/staging/tidspbridge/core/tiomap3430_pwr.c
index 0d6bc4f..9aa6fd9 100644
--- a/drivers/staging/tidspbridge/core/tiomap3430_pwr.c
+++ b/drivers/staging/tidspbridge/core/tiomap3430_pwr.c
@@ -31,10 +31,6 @@
#include <dspbridge/dev.h>
#include <dspbridge/io.h>

-/* ------------------------------------ Hardware Abstraction Layer */
-#include <hw_defs.h>
-#include <hw_mmu.h>
-
#include <dspbridge/pwr.h>

/* ----------------------------------- Bridge Driver */
diff --git a/drivers/staging/tidspbridge/core/tiomap_io.c b/drivers/staging/tidspbridge/core/tiomap_io.c
index ab221f1..8c52041 100644
--- a/drivers/staging/tidspbridge/core/tiomap_io.c
+++ b/drivers/staging/tidspbridge/core/tiomap_io.c
@@ -143,7 +143,7 @@ int read_ext_dsp_data(struct bridge_dev_context *dev_ctxt,
ul_shm_base_virt - ul_tlb_base_virt;
ul_shm_offset_virt +=
PG_ALIGN_HIGH(ul_ext_end - ul_dyn_ext_base +
- 1, HW_PAGE_SIZE64KB);
+ 1, SZ_64K);
dw_ext_prog_virt_mem -= ul_shm_offset_virt;
dw_ext_prog_virt_mem +=
(ul_ext_base - ul_dyn_ext_base);
diff --git a/drivers/staging/tidspbridge/hw/EasiGlobal.h b/drivers/staging/tidspbridge/hw/EasiGlobal.h
deleted file mode 100644
index e48d7f6..0000000
--- a/drivers/staging/tidspbridge/hw/EasiGlobal.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * EasiGlobal.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Copyright (C) 2007 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 _EASIGLOBAL_H
-#define _EASIGLOBAL_H
-#include <linux/types.h>
-
-/*
- * DEFINE: READ_ONLY, WRITE_ONLY & READ_WRITE
- *
- * DESCRIPTION: Defines used to describe register types for EASI-checker tests.
- */
-
-#define READ_ONLY 1
-#define WRITE_ONLY 2
-#define READ_WRITE 3
-
-/*
- * MACRO: _DEBUG_LEVEL1_EASI
- *
- * DESCRIPTION: A MACRO which can be used to indicate that a particular beach
- * register access function was called.
- *
- * NOTE: We currently dont use this functionality.
- */
-#define _DEBUG_LEVEL1_EASI(easi_num) ((void)0)
-
-#endif /* _EASIGLOBAL_H */
diff --git a/drivers/staging/tidspbridge/hw/MMUAccInt.h b/drivers/staging/tidspbridge/hw/MMUAccInt.h
deleted file mode 100644
index 1cefca3..0000000
--- a/drivers/staging/tidspbridge/hw/MMUAccInt.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * MMUAccInt.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Copyright (C) 2007 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 _MMU_ACC_INT_H
-#define _MMU_ACC_INT_H
-
-/* Mappings of level 1 EASI function numbers to function names */
-
-#define EASIL1_MMUMMU_SYSCONFIG_READ_REGISTER32 (MMU_BASE_EASIL1 + 3)
-#define EASIL1_MMUMMU_SYSCONFIG_IDLE_MODE_WRITE32 (MMU_BASE_EASIL1 + 17)
-#define EASIL1_MMUMMU_SYSCONFIG_AUTO_IDLE_WRITE32 (MMU_BASE_EASIL1 + 39)
-#define EASIL1_MMUMMU_IRQSTATUS_WRITE_REGISTER32 (MMU_BASE_EASIL1 + 51)
-#define EASIL1_MMUMMU_IRQENABLE_READ_REGISTER32 (MMU_BASE_EASIL1 + 102)
-#define EASIL1_MMUMMU_IRQENABLE_WRITE_REGISTER32 (MMU_BASE_EASIL1 + 103)
-#define EASIL1_MMUMMU_WALKING_STTWL_RUNNING_READ32 (MMU_BASE_EASIL1 + 156)
-#define EASIL1_MMUMMU_CNTLTWL_ENABLE_READ32 (MMU_BASE_EASIL1 + 174)
-#define EASIL1_MMUMMU_CNTLTWL_ENABLE_WRITE32 (MMU_BASE_EASIL1 + 180)
-#define EASIL1_MMUMMU_CNTLMMU_ENABLE_WRITE32 (MMU_BASE_EASIL1 + 190)
-#define EASIL1_MMUMMU_FAULT_AD_READ_REGISTER32 (MMU_BASE_EASIL1 + 194)
-#define EASIL1_MMUMMU_TTB_WRITE_REGISTER32 (MMU_BASE_EASIL1 + 198)
-#define EASIL1_MMUMMU_LOCK_READ_REGISTER32 (MMU_BASE_EASIL1 + 203)
-#define EASIL1_MMUMMU_LOCK_WRITE_REGISTER32 (MMU_BASE_EASIL1 + 204)
-#define EASIL1_MMUMMU_LOCK_BASE_VALUE_READ32 (MMU_BASE_EASIL1 + 205)
-#define EASIL1_MMUMMU_LOCK_CURRENT_VICTIM_READ32 (MMU_BASE_EASIL1 + 209)
-#define EASIL1_MMUMMU_LOCK_CURRENT_VICTIM_WRITE32 (MMU_BASE_EASIL1 + 211)
-#define EASIL1_MMUMMU_LOCK_CURRENT_VICTIM_SET32 (MMU_BASE_EASIL1 + 212)
-#define EASIL1_MMUMMU_LD_TLB_READ_REGISTER32 (MMU_BASE_EASIL1 + 213)
-#define EASIL1_MMUMMU_LD_TLB_WRITE_REGISTER32 (MMU_BASE_EASIL1 + 214)
-#define EASIL1_MMUMMU_CAM_WRITE_REGISTER32 (MMU_BASE_EASIL1 + 226)
-#define EASIL1_MMUMMU_RAM_WRITE_REGISTER32 (MMU_BASE_EASIL1 + 268)
-#define EASIL1_MMUMMU_FLUSH_ENTRY_WRITE_REGISTER32 (MMU_BASE_EASIL1 + 322)
-
-/* Register offset address definitions */
-#define MMU_MMU_SYSCONFIG_OFFSET 0x10
-#define MMU_MMU_IRQSTATUS_OFFSET 0x18
-#define MMU_MMU_IRQENABLE_OFFSET 0x1c
-#define MMU_MMU_WALKING_ST_OFFSET 0x40
-#define MMU_MMU_CNTL_OFFSET 0x44
-#define MMU_MMU_FAULT_AD_OFFSET 0x48
-#define MMU_MMU_TTB_OFFSET 0x4c
-#define MMU_MMU_LOCK_OFFSET 0x50
-#define MMU_MMU_LD_TLB_OFFSET 0x54
-#define MMU_MMU_CAM_OFFSET 0x58
-#define MMU_MMU_RAM_OFFSET 0x5c
-#define MMU_MMU_GFLUSH_OFFSET 0x60
-#define MMU_MMU_FLUSH_ENTRY_OFFSET 0x64
-/* Bitfield mask and offset declarations */
-#define MMU_MMU_SYSCONFIG_IDLE_MODE_MASK 0x18
-#define MMU_MMU_SYSCONFIG_IDLE_MODE_OFFSET 3
-#define MMU_MMU_SYSCONFIG_AUTO_IDLE_MASK 0x1
-#define MMU_MMU_SYSCONFIG_AUTO_IDLE_OFFSET 0
-#define MMU_MMU_WALKING_ST_TWL_RUNNING_MASK 0x1
-#define MMU_MMU_WALKING_ST_TWL_RUNNING_OFFSET 0
-#define MMU_MMU_CNTL_TWL_ENABLE_MASK 0x4
-#define MMU_MMU_CNTL_TWL_ENABLE_OFFSET 2
-#define MMU_MMU_CNTL_MMU_ENABLE_MASK 0x2
-#define MMU_MMU_CNTL_MMU_ENABLE_OFFSET 1
-#define MMU_MMU_LOCK_BASE_VALUE_MASK 0xfc00
-#define MMU_MMU_LOCK_BASE_VALUE_OFFSET 10
-#define MMU_MMU_LOCK_CURRENT_VICTIM_MASK 0x3f0
-#define MMU_MMU_LOCK_CURRENT_VICTIM_OFFSET 4
-
-#endif /* _MMU_ACC_INT_H */
diff --git a/drivers/staging/tidspbridge/hw/MMURegAcM.h b/drivers/staging/tidspbridge/hw/MMURegAcM.h
deleted file mode 100644
index ab1a16d..0000000
--- a/drivers/staging/tidspbridge/hw/MMURegAcM.h
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * MMURegAcM.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Copyright (C) 2007 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 _MMU_REG_ACM_H
-#define _MMU_REG_ACM_H
-
-#include <linux/io.h>
-#include <EasiGlobal.h>
-
-#include "MMUAccInt.h"
-
-#if defined(USE_LEVEL_1_MACROS)
-
-#define MMUMMU_SYSCONFIG_READ_REGISTER32(base_address)\
- (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_SYSCONFIG_READ_REGISTER32),\
- __raw_readl((base_address)+MMU_MMU_SYSCONFIG_OFFSET))
-
-#define MMUMMU_SYSCONFIG_IDLE_MODE_WRITE32(base_address, value)\
-{\
- const u32 offset = MMU_MMU_SYSCONFIG_OFFSET;\
- register u32 data = __raw_readl((base_address)+offset);\
- register u32 new_value = (value);\
- _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_SYSCONFIG_IDLE_MODE_WRITE32);\
- data &= ~(MMU_MMU_SYSCONFIG_IDLE_MODE_MASK);\
- new_value <<= MMU_MMU_SYSCONFIG_IDLE_MODE_OFFSET;\
- new_value &= MMU_MMU_SYSCONFIG_IDLE_MODE_MASK;\
- new_value |= data;\
- __raw_writel(new_value, base_address+offset);\
-}
-
-#define MMUMMU_SYSCONFIG_AUTO_IDLE_WRITE32(base_address, value)\
-{\
- const u32 offset = MMU_MMU_SYSCONFIG_OFFSET;\
- register u32 data = __raw_readl((base_address)+offset);\
- register u32 new_value = (value);\
- _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_SYSCONFIG_AUTO_IDLE_WRITE32);\
- data &= ~(MMU_MMU_SYSCONFIG_AUTO_IDLE_MASK);\
- new_value <<= MMU_MMU_SYSCONFIG_AUTO_IDLE_OFFSET;\
- new_value &= MMU_MMU_SYSCONFIG_AUTO_IDLE_MASK;\
- new_value |= data;\
- __raw_writel(new_value, base_address+offset);\
-}
-
-#define MMUMMU_IRQSTATUS_READ_REGISTER32(base_address)\
- (_DEBUG_LEVEL1_EASI(easil1_mmummu_irqstatus_read_register32),\
- __raw_readl((base_address)+MMU_MMU_IRQSTATUS_OFFSET))
-
-#define MMUMMU_IRQSTATUS_WRITE_REGISTER32(base_address, value)\
-{\
- const u32 offset = MMU_MMU_IRQSTATUS_OFFSET;\
- register u32 new_value = (value);\
- _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_IRQSTATUS_WRITE_REGISTER32);\
- __raw_writel(new_value, (base_address)+offset);\
-}
-
-#define MMUMMU_IRQENABLE_READ_REGISTER32(base_address)\
- (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_IRQENABLE_READ_REGISTER32),\
- __raw_readl((base_address)+MMU_MMU_IRQENABLE_OFFSET))
-
-#define MMUMMU_IRQENABLE_WRITE_REGISTER32(base_address, value)\
-{\
- const u32 offset = MMU_MMU_IRQENABLE_OFFSET;\
- register u32 new_value = (value);\
- _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_IRQENABLE_WRITE_REGISTER32);\
- __raw_writel(new_value, (base_address)+offset);\
-}
-
-#define MMUMMU_WALKING_STTWL_RUNNING_READ32(base_address)\
- (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_WALKING_STTWL_RUNNING_READ32),\
- (((__raw_readl(((base_address)+(MMU_MMU_WALKING_ST_OFFSET))))\
- & MMU_MMU_WALKING_ST_TWL_RUNNING_MASK) >>\
- MMU_MMU_WALKING_ST_TWL_RUNNING_OFFSET))
-
-#define MMUMMU_CNTLTWL_ENABLE_READ32(base_address)\
- (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_CNTLTWL_ENABLE_READ32),\
- (((__raw_readl(((base_address)+(MMU_MMU_CNTL_OFFSET)))) &\
- MMU_MMU_CNTL_TWL_ENABLE_MASK) >>\
- MMU_MMU_CNTL_TWL_ENABLE_OFFSET))
-
-#define MMUMMU_CNTLTWL_ENABLE_WRITE32(base_address, value)\
-{\
- const u32 offset = MMU_MMU_CNTL_OFFSET;\
- register u32 data = __raw_readl((base_address)+offset);\
- register u32 new_value = (value);\
- _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_CNTLTWL_ENABLE_WRITE32);\
- data &= ~(MMU_MMU_CNTL_TWL_ENABLE_MASK);\
- new_value <<= MMU_MMU_CNTL_TWL_ENABLE_OFFSET;\
- new_value &= MMU_MMU_CNTL_TWL_ENABLE_MASK;\
- new_value |= data;\
- __raw_writel(new_value, base_address+offset);\
-}
-
-#define MMUMMU_CNTLMMU_ENABLE_WRITE32(base_address, value)\
-{\
- const u32 offset = MMU_MMU_CNTL_OFFSET;\
- register u32 data = __raw_readl((base_address)+offset);\
- register u32 new_value = (value);\
- _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_CNTLMMU_ENABLE_WRITE32);\
- data &= ~(MMU_MMU_CNTL_MMU_ENABLE_MASK);\
- new_value <<= MMU_MMU_CNTL_MMU_ENABLE_OFFSET;\
- new_value &= MMU_MMU_CNTL_MMU_ENABLE_MASK;\
- new_value |= data;\
- __raw_writel(new_value, base_address+offset);\
-}
-
-#define MMUMMU_FAULT_AD_READ_REGISTER32(base_address)\
- (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_FAULT_AD_READ_REGISTER32),\
- __raw_readl((base_address)+MMU_MMU_FAULT_AD_OFFSET))
-
-#define MMUMMU_TTB_WRITE_REGISTER32(base_address, value)\
-{\
- const u32 offset = MMU_MMU_TTB_OFFSET;\
- register u32 new_value = (value);\
- _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_TTB_WRITE_REGISTER32);\
- __raw_writel(new_value, (base_address)+offset);\
-}
-
-#define MMUMMU_LOCK_READ_REGISTER32(base_address)\
- (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LOCK_READ_REGISTER32),\
- __raw_readl((base_address)+MMU_MMU_LOCK_OFFSET))
-
-#define MMUMMU_LOCK_WRITE_REGISTER32(base_address, value)\
-{\
- const u32 offset = MMU_MMU_LOCK_OFFSET;\
- register u32 new_value = (value);\
- _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LOCK_WRITE_REGISTER32);\
- __raw_writel(new_value, (base_address)+offset);\
-}
-
-#define MMUMMU_LOCK_BASE_VALUE_READ32(base_address)\
- (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LOCK_BASE_VALUE_READ32),\
- (((__raw_readl(((base_address)+(MMU_MMU_LOCK_OFFSET)))) &\
- MMU_MMU_LOCK_BASE_VALUE_MASK) >>\
- MMU_MMU_LOCK_BASE_VALUE_OFFSET))
-
-#define MMUMMU_LOCK_BASE_VALUE_WRITE32(base_address, value)\
-{\
- const u32 offset = MMU_MMU_LOCK_OFFSET;\
- register u32 data = __raw_readl((base_address)+offset);\
- register u32 new_value = (value);\
- _DEBUG_LEVEL1_EASI(easil1_mmummu_lock_base_value_write32);\
- data &= ~(MMU_MMU_LOCK_BASE_VALUE_MASK);\
- new_value <<= MMU_MMU_LOCK_BASE_VALUE_OFFSET;\
- new_value &= MMU_MMU_LOCK_BASE_VALUE_MASK;\
- new_value |= data;\
- __raw_writel(new_value, base_address+offset);\
-}
-
-#define MMUMMU_LOCK_CURRENT_VICTIM_READ32(base_address)\
- (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LOCK_CURRENT_VICTIM_READ32),\
- (((__raw_readl(((base_address)+(MMU_MMU_LOCK_OFFSET)))) &\
- MMU_MMU_LOCK_CURRENT_VICTIM_MASK) >>\
- MMU_MMU_LOCK_CURRENT_VICTIM_OFFSET))
-
-#define MMUMMU_LOCK_CURRENT_VICTIM_WRITE32(base_address, value)\
-{\
- const u32 offset = MMU_MMU_LOCK_OFFSET;\
- register u32 data = __raw_readl((base_address)+offset);\
- register u32 new_value = (value);\
- _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LOCK_CURRENT_VICTIM_WRITE32);\
- data &= ~(MMU_MMU_LOCK_CURRENT_VICTIM_MASK);\
- new_value <<= MMU_MMU_LOCK_CURRENT_VICTIM_OFFSET;\
- new_value &= MMU_MMU_LOCK_CURRENT_VICTIM_MASK;\
- new_value |= data;\
- __raw_writel(new_value, base_address+offset);\
-}
-
-#define MMUMMU_LOCK_CURRENT_VICTIM_SET32(var, value)\
- (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LOCK_CURRENT_VICTIM_SET32),\
- (((var) & ~(MMU_MMU_LOCK_CURRENT_VICTIM_MASK)) |\
- (((value) << MMU_MMU_LOCK_CURRENT_VICTIM_OFFSET) &\
- MMU_MMU_LOCK_CURRENT_VICTIM_MASK)))
-
-#define MMUMMU_LD_TLB_READ_REGISTER32(base_address)\
- (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LD_TLB_READ_REGISTER32),\
- __raw_readl((base_address)+MMU_MMU_LD_TLB_OFFSET))
-
-#define MMUMMU_LD_TLB_WRITE_REGISTER32(base_address, value)\
-{\
- const u32 offset = MMU_MMU_LD_TLB_OFFSET;\
- register u32 new_value = (value);\
- _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LD_TLB_WRITE_REGISTER32);\
- __raw_writel(new_value, (base_address)+offset);\
-}
-
-#define MMUMMU_CAM_WRITE_REGISTER32(base_address, value)\
-{\
- const u32 offset = MMU_MMU_CAM_OFFSET;\
- register u32 new_value = (value);\
- _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_CAM_WRITE_REGISTER32);\
- __raw_writel(new_value, (base_address)+offset);\
-}
-
-#define MMUMMU_RAM_WRITE_REGISTER32(base_address, value)\
-{\
- const u32 offset = MMU_MMU_RAM_OFFSET;\
- register u32 new_value = (value);\
- _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_RAM_WRITE_REGISTER32);\
- __raw_writel(new_value, (base_address)+offset);\
-}
-
-#define MMUMMU_FLUSH_ENTRY_WRITE_REGISTER32(base_address, value)\
-{\
- const u32 offset = MMU_MMU_FLUSH_ENTRY_OFFSET;\
- register u32 new_value = (value);\
- _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_FLUSH_ENTRY_WRITE_REGISTER32);\
- __raw_writel(new_value, (base_address)+offset);\
-}
-
-#endif /* USE_LEVEL_1_MACROS */
-
-#endif /* _MMU_REG_ACM_H */
diff --git a/drivers/staging/tidspbridge/hw/hw_defs.h b/drivers/staging/tidspbridge/hw/hw_defs.h
deleted file mode 100644
index d5266d4..0000000
--- a/drivers/staging/tidspbridge/hw/hw_defs.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * hw_defs.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Global HW definitions
- *
- * Copyright (C) 2007 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 _HW_DEFS_H
-#define _HW_DEFS_H
-
-/* Page size */
-#define HW_PAGE_SIZE4KB 0x1000
-#define HW_PAGE_SIZE64KB 0x10000
-#define HW_PAGE_SIZE1MB 0x100000
-#define HW_PAGE_SIZE16MB 0x1000000
-
-/* hw_status: return type for HW API */
-typedef long hw_status;
-
-/* Macro used to set and clear any bit */
-#define HW_CLEAR 0
-#define HW_SET 1
-
-/* hw_endianism_t: Enumerated Type used to specify the endianism
- * Do NOT change these values. They are used as bit fields. */
-enum hw_endianism_t {
- HW_LITTLE_ENDIAN,
- HW_BIG_ENDIAN
-};
-
-/* hw_element_size_t: Enumerated Type used to specify the element size
- * Do NOT change these values. They are used as bit fields. */
-enum hw_element_size_t {
- HW_ELEM_SIZE8BIT,
- HW_ELEM_SIZE16BIT,
- HW_ELEM_SIZE32BIT,
- HW_ELEM_SIZE64BIT
-};
-
-/* hw_idle_mode_t: Enumerated Type used to specify Idle modes */
-enum hw_idle_mode_t {
- HW_FORCE_IDLE,
- HW_NO_IDLE,
- HW_SMART_IDLE
-};
-
-#endif /* _HW_DEFS_H */
diff --git a/drivers/staging/tidspbridge/hw/hw_mmu.c b/drivers/staging/tidspbridge/hw/hw_mmu.c
deleted file mode 100644
index c214df9..0000000
--- a/drivers/staging/tidspbridge/hw/hw_mmu.c
+++ /dev/null
@@ -1,562 +0,0 @@
-/*
- * hw_mmu.c
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * API definitions to setup MMU TLB and PTE
- *
- * Copyright (C) 2007 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/io.h>
-#include "MMURegAcM.h"
-#include <hw_defs.h>
-#include <hw_mmu.h>
-#include <linux/types.h>
-#include <linux/err.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 MMU_GFLUSH 0x60
-
-/*
- * hw_mmu_page_size_t: Enumerated Type used to specify the MMU Page Size(SLSS)
- */
-enum hw_mmu_page_size_t {
- HW_MMU_SECTION,
- HW_MMU_LARGE_PAGE,
- HW_MMU_SMALL_PAGE,
- HW_MMU_SUPERSECTION
-};
-
-/*
- * FUNCTION : mmu_flush_entry
- *
- * INPUTS:
- *
- * Identifier : base_address
- * Type : const u32
- * Description : Base Address of instance of MMU module
- *
- * RETURNS:
- *
- * Type : hw_status
- * Description : 0 -- No errors occurred
- * RET_BAD_NULL_PARAM -- A Pointer
- * Paramater was set to NULL
- *
- * PURPOSE: : Flush the TLB entry pointed by the
- * lock counter register
- * even if this entry is set protected
- *
- * METHOD: : Check the Input parameter and Flush a
- * single entry in the TLB.
- */
-static hw_status mmu_flush_entry(const void __iomem *base_address);
-
-/*
- * FUNCTION : mmu_set_cam_entry
- *
- * INPUTS:
- *
- * Identifier : base_address
- * TypE : const u32
- * Description : Base Address of instance of MMU module
- *
- * Identifier : page_sz
- * TypE : const u32
- * Description : It indicates the page size
- *
- * Identifier : preserved_bit
- * Type : const u32
- * Description : It indicates the TLB entry is preserved entry
- * or not
- *
- * Identifier : valid_bit
- * Type : const u32
- * Description : It indicates the TLB entry is valid entry or not
- *
- *
- * Identifier : virtual_addr_tag
- * Type : const u32
- * Description : virtual Address
- *
- * RETURNS:
- *
- * Type : hw_status
- * Description : 0 -- No errors occurred
- * RET_BAD_NULL_PARAM -- A Pointer Paramater
- * was set to NULL
- * RET_PARAM_OUT_OF_RANGE -- Input Parameter out
- * of Range
- *
- * PURPOSE: : Set MMU_CAM reg
- *
- * METHOD: : Check the Input parameters and set the CAM entry.
- */
-static hw_status mmu_set_cam_entry(const void __iomem *base_address,
- const u32 page_sz,
- const u32 preserved_bit,
- const u32 valid_bit,
- const u32 virtual_addr_tag);
-
-/*
- * FUNCTION : mmu_set_ram_entry
- *
- * INPUTS:
- *
- * Identifier : base_address
- * Type : const u32
- * Description : Base Address of instance of MMU module
- *
- * Identifier : physical_addr
- * Type : const u32
- * Description : Physical Address to which the corresponding
- * virtual Address shouldpoint
- *
- * Identifier : endianism
- * Type : hw_endianism_t
- * Description : endianism for the given page
- *
- * Identifier : element_size
- * Type : hw_element_size_t
- * Description : The element size ( 8,16, 32 or 64 bit)
- *
- * Identifier : mixed_size
- * Type : hw_mmu_mixed_size_t
- * Description : Element Size to follow CPU or TLB
- *
- * RETURNS:
- *
- * Type : hw_status
- * Description : 0 -- No errors occurred
- * RET_BAD_NULL_PARAM -- A Pointer Paramater
- * was set to NULL
- * RET_PARAM_OUT_OF_RANGE -- Input Parameter
- * out of Range
- *
- * PURPOSE: : Set MMU_CAM reg
- *
- * METHOD: : Check the Input parameters and set the RAM entry.
- */
-static hw_status mmu_set_ram_entry(const void __iomem *base_address,
- const u32 physical_addr,
- enum hw_endianism_t endianism,
- enum hw_element_size_t element_size,
- enum hw_mmu_mixed_size_t mixed_size);
-
-/* HW FUNCTIONS */
-
-hw_status hw_mmu_enable(const void __iomem *base_address)
-{
- hw_status status = 0;
-
- MMUMMU_CNTLMMU_ENABLE_WRITE32(base_address, HW_SET);
-
- return status;
-}
-
-hw_status hw_mmu_disable(const void __iomem *base_address)
-{
- hw_status status = 0;
-
- MMUMMU_CNTLMMU_ENABLE_WRITE32(base_address, HW_CLEAR);
-
- return status;
-}
-
-hw_status hw_mmu_num_locked_set(const void __iomem *base_address,
- u32 num_locked_entries)
-{
- hw_status status = 0;
-
- MMUMMU_LOCK_BASE_VALUE_WRITE32(base_address, num_locked_entries);
-
- return status;
-}
-
-hw_status hw_mmu_victim_num_set(const void __iomem *base_address,
- u32 victim_entry_num)
-{
- hw_status status = 0;
-
- MMUMMU_LOCK_CURRENT_VICTIM_WRITE32(base_address, victim_entry_num);
-
- return status;
-}
-
-hw_status hw_mmu_event_ack(const void __iomem *base_address, u32 irq_mask)
-{
- hw_status status = 0;
-
- MMUMMU_IRQSTATUS_WRITE_REGISTER32(base_address, irq_mask);
-
- return status;
-}
-
-hw_status hw_mmu_event_disable(const void __iomem *base_address, u32 irq_mask)
-{
- hw_status status = 0;
- u32 irq_reg;
-
- irq_reg = MMUMMU_IRQENABLE_READ_REGISTER32(base_address);
-
- MMUMMU_IRQENABLE_WRITE_REGISTER32(base_address, irq_reg & ~irq_mask);
-
- return status;
-}
-
-hw_status hw_mmu_event_enable(const void __iomem *base_address, u32 irq_mask)
-{
- hw_status status = 0;
- u32 irq_reg;
-
- irq_reg = MMUMMU_IRQENABLE_READ_REGISTER32(base_address);
-
- MMUMMU_IRQENABLE_WRITE_REGISTER32(base_address, irq_reg | irq_mask);
-
- return status;
-}
-
-hw_status hw_mmu_event_status(const void __iomem *base_address, u32 *irq_mask)
-{
- hw_status status = 0;
-
- *irq_mask = MMUMMU_IRQSTATUS_READ_REGISTER32(base_address);
-
- return status;
-}
-
-hw_status hw_mmu_fault_addr_read(const void __iomem *base_address, u32 *addr)
-{
- hw_status status = 0;
-
- /* read values from register */
- *addr = MMUMMU_FAULT_AD_READ_REGISTER32(base_address);
-
- return status;
-}
-
-hw_status hw_mmu_ttb_set(const void __iomem *base_address, u32 ttb_phys_addr)
-{
- hw_status status = 0;
- u32 load_ttb;
-
- load_ttb = ttb_phys_addr & ~0x7FUL;
- /* write values to register */
- MMUMMU_TTB_WRITE_REGISTER32(base_address, load_ttb);
-
- return status;
-}
-
-hw_status hw_mmu_twl_enable(const void __iomem *base_address)
-{
- hw_status status = 0;
-
- MMUMMU_CNTLTWL_ENABLE_WRITE32(base_address, HW_SET);
-
- return status;
-}
-
-hw_status hw_mmu_twl_disable(const void __iomem *base_address)
-{
- hw_status status = 0;
-
- MMUMMU_CNTLTWL_ENABLE_WRITE32(base_address, HW_CLEAR);
-
- return status;
-}
-
-hw_status hw_mmu_tlb_flush(const void __iomem *base_address, u32 virtual_addr,
- u32 page_sz)
-{
- hw_status status = 0;
- u32 virtual_addr_tag;
- enum hw_mmu_page_size_t pg_size_bits;
-
- switch (page_sz) {
- case HW_PAGE_SIZE4KB:
- pg_size_bits = HW_MMU_SMALL_PAGE;
- break;
-
- case HW_PAGE_SIZE64KB:
- pg_size_bits = HW_MMU_LARGE_PAGE;
- break;
-
- case HW_PAGE_SIZE1MB:
- pg_size_bits = HW_MMU_SECTION;
- break;
-
- case HW_PAGE_SIZE16MB:
- pg_size_bits = HW_MMU_SUPERSECTION;
- break;
-
- default:
- return -EINVAL;
- }
-
- /* Generate the 20-bit tag from virtual address */
- virtual_addr_tag = ((virtual_addr & MMU_ADDR_MASK) >> 12);
-
- mmu_set_cam_entry(base_address, pg_size_bits, 0, 0, virtual_addr_tag);
-
- mmu_flush_entry(base_address);
-
- return status;
-}
-
-hw_status hw_mmu_tlb_add(const void __iomem *base_address,
- u32 physical_addr,
- u32 virtual_addr,
- u32 page_sz,
- u32 entry_num,
- struct hw_mmu_map_attrs_t *map_attrs,
- s8 preserved_bit, s8 valid_bit)
-{
- hw_status status = 0;
- u32 lock_reg;
- u32 virtual_addr_tag;
- enum hw_mmu_page_size_t mmu_pg_size;
-
- /*Check the input Parameters */
- switch (page_sz) {
- case HW_PAGE_SIZE4KB:
- mmu_pg_size = HW_MMU_SMALL_PAGE;
- break;
-
- case HW_PAGE_SIZE64KB:
- mmu_pg_size = HW_MMU_LARGE_PAGE;
- break;
-
- case HW_PAGE_SIZE1MB:
- mmu_pg_size = HW_MMU_SECTION;
- break;
-
- case HW_PAGE_SIZE16MB:
- mmu_pg_size = HW_MMU_SUPERSECTION;
- break;
-
- default:
- return -EINVAL;
- }
-
- lock_reg = MMUMMU_LOCK_READ_REGISTER32(base_address);
-
- /* Generate the 20-bit tag from virtual address */
- virtual_addr_tag = ((virtual_addr & MMU_ADDR_MASK) >> 12);
-
- /* Write the fields in the CAM Entry Register */
- mmu_set_cam_entry(base_address, mmu_pg_size, preserved_bit, valid_bit,
- virtual_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->mixed_size);
-
- /* Update the MMU Lock Register */
- /* currentVictim between lockedBaseValue and (MMU_Entries_Number - 1) */
- MMUMMU_LOCK_CURRENT_VICTIM_WRITE32(base_address, entry_num);
-
- /* Enable loading of an entry in TLB by writing 1
- into LD_TLB_REG register */
- MMUMMU_LD_TLB_WRITE_REGISTER32(base_address, MMU_LOAD_TLB);
-
- MMUMMU_LOCK_WRITE_REGISTER32(base_address, lock_reg);
-
- return status;
-}
-
-hw_status hw_mmu_pte_set(const u32 pg_tbl_va,
- u32 physical_addr,
- u32 virtual_addr,
- u32 page_sz, struct hw_mmu_map_attrs_t *map_attrs)
-{
- hw_status status = 0;
- u32 pte_addr, pte_val;
- s32 num_entries = 1;
-
- switch (page_sz) {
- case HW_PAGE_SIZE4KB:
- 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->mixed_size << 11) | 2);
- break;
-
- case HW_PAGE_SIZE64KB:
- 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->mixed_size << 11) | 1);
- break;
-
- case HW_PAGE_SIZE1MB:
- 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->mixed_size << 17)) & ~0x40000) | 0x2);
- break;
-
- case HW_PAGE_SIZE16MB:
- 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->mixed_size << 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 -EINVAL;
- }
-
- while (--num_entries >= 0)
- ((u32 *) pte_addr)[num_entries] = pte_val;
-
- return status;
-}
-
-hw_status hw_mmu_pte_clear(const u32 pg_tbl_va, u32 virtual_addr, u32 page_size)
-{
- hw_status status = 0;
- u32 pte_addr;
- s32 num_entries = 1;
-
- switch (page_size) {
- case HW_PAGE_SIZE4KB:
- pte_addr = hw_mmu_pte_addr_l2(pg_tbl_va,
- virtual_addr &
- MMU_SMALL_PAGE_MASK);
- break;
-
- case HW_PAGE_SIZE64KB:
- num_entries = 16;
- pte_addr = hw_mmu_pte_addr_l2(pg_tbl_va,
- virtual_addr &
- MMU_LARGE_PAGE_MASK);
- break;
-
- case HW_PAGE_SIZE1MB:
- 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_SIZE16MB:
- num_entries = 16;
- pte_addr = hw_mmu_pte_addr_l1(pg_tbl_va,
- virtual_addr &
- MMU_SSECTION_ADDR_MASK);
- break;
-
- default:
- return -EINVAL;
- }
-
- while (--num_entries >= 0)
- ((u32 *) pte_addr)[num_entries] = 0;
-
- return status;
-}
-
-/* mmu_flush_entry */
-static hw_status mmu_flush_entry(const void __iomem *base_address)
-{
- hw_status status = 0;
- u32 flush_entry_data = 0x1;
-
- /* write values to register */
- MMUMMU_FLUSH_ENTRY_WRITE_REGISTER32(base_address, flush_entry_data);
-
- return status;
-}
-
-/* mmu_set_cam_entry */
-static hw_status mmu_set_cam_entry(const void __iomem *base_address,
- const u32 page_sz,
- const u32 preserved_bit,
- const u32 valid_bit,
- const u32 virtual_addr_tag)
-{
- hw_status status = 0;
- u32 mmu_cam_reg;
-
- mmu_cam_reg = (virtual_addr_tag << 12);
- mmu_cam_reg = (mmu_cam_reg) | (page_sz) | (valid_bit << 2) |
- (preserved_bit << 3);
-
- /* write values to register */
- MMUMMU_CAM_WRITE_REGISTER32(base_address, mmu_cam_reg);
-
- return status;
-}
-
-/* mmu_set_ram_entry */
-static hw_status mmu_set_ram_entry(const void __iomem *base_address,
- const u32 physical_addr,
- enum hw_endianism_t endianism,
- enum hw_element_size_t element_size,
- enum hw_mmu_mixed_size_t mixed_size)
-{
- hw_status status = 0;
- u32 mmu_ram_reg;
-
- mmu_ram_reg = (physical_addr & MMU_ADDR_MASK);
- mmu_ram_reg = (mmu_ram_reg) | ((endianism << 9) | (element_size << 7) |
- (mixed_size << 6));
-
- /* write values to register */
- MMUMMU_RAM_WRITE_REGISTER32(base_address, mmu_ram_reg);
-
- return status;
-
-}
-
-void hw_mmu_tlb_flush_all(const void __iomem *base)
-{
- __raw_writeb(1, base + MMU_GFLUSH);
-}
diff --git a/drivers/staging/tidspbridge/hw/hw_mmu.h b/drivers/staging/tidspbridge/hw/hw_mmu.h
deleted file mode 100644
index 1458a2c..0000000
--- a/drivers/staging/tidspbridge/hw/hw_mmu.h
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * hw_mmu.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * MMU types and API declarations
- *
- * Copyright (C) 2007 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 _HW_MMU_H
-#define _HW_MMU_H
-
-#include <linux/types.h>
-
-/* Bitmasks for interrupt sources */
-#define HW_MMU_TRANSLATION_FAULT 0x2
-#define HW_MMU_ALL_INTERRUPTS 0x1F
-
-#define HW_MMU_COARSE_PAGE_SIZE 0x400
-
-/* hw_mmu_mixed_size_t: Enumerated Type used to specify whether to follow
- CPU/TLB Element size */
-enum hw_mmu_mixed_size_t {
- HW_MMU_TLBES,
- HW_MMU_CPUES
-};
-
-/* hw_mmu_map_attrs_t: Struct containing MMU mapping attributes */
-struct hw_mmu_map_attrs_t {
- enum hw_endianism_t endianism;
- enum hw_element_size_t element_size;
- enum hw_mmu_mixed_size_t mixed_size;
- bool donotlockmpupage;
-};
-
-extern hw_status hw_mmu_enable(const void __iomem *base_address);
-
-extern hw_status hw_mmu_disable(const void __iomem *base_address);
-
-extern hw_status hw_mmu_num_locked_set(const void __iomem *base_address,
- u32 num_locked_entries);
-
-extern hw_status hw_mmu_victim_num_set(const void __iomem *base_address,
- u32 victim_entry_num);
-
-/* For MMU faults */
-extern hw_status hw_mmu_event_ack(const void __iomem *base_address,
- u32 irq_mask);
-
-extern hw_status hw_mmu_event_disable(const void __iomem *base_address,
- u32 irq_mask);
-
-extern hw_status hw_mmu_event_enable(const void __iomem *base_address,
- u32 irq_mask);
-
-extern hw_status hw_mmu_event_status(const void __iomem *base_address,
- u32 *irq_mask);
-
-extern hw_status hw_mmu_fault_addr_read(const void __iomem *base_address,
- u32 *addr);
-
-/* Set the TT base address */
-extern hw_status hw_mmu_ttb_set(const void __iomem *base_address,
- u32 ttb_phys_addr);
-
-extern hw_status hw_mmu_twl_enable(const void __iomem *base_address);
-
-extern hw_status hw_mmu_twl_disable(const void __iomem *base_address);
-
-extern hw_status hw_mmu_tlb_flush(const void __iomem *base_address,
- u32 virtual_addr, u32 page_sz);
-
-extern hw_status hw_mmu_tlb_add(const void __iomem *base_address,
- u32 physical_addr,
- u32 virtual_addr,
- u32 page_sz,
- u32 entry_num,
- struct hw_mmu_map_attrs_t *map_attrs,
- s8 preserved_bit, s8 valid_bit);
-
-/* For PTEs */
-extern hw_status hw_mmu_pte_set(const u32 pg_tbl_va,
- u32 physical_addr,
- u32 virtual_addr,
- u32 page_sz,
- struct hw_mmu_map_attrs_t *map_attrs);
-
-extern hw_status hw_mmu_pte_clear(const u32 pg_tbl_va,
- u32 virtual_addr, u32 page_size);
-
-void hw_mmu_tlb_flush_all(const void __iomem *base);
-
-static inline u32 hw_mmu_pte_addr_l1(u32 l1_base, u32 va)
-{
- u32 pte_addr;
- u32 va31_to20;
-
- va31_to20 = va >> (20 - 2); /* Left-shift by 2 here itself */
- va31_to20 &= 0xFFFFFFFCUL;
- pte_addr = l1_base + va31_to20;
-
- return pte_addr;
-}
-
-static inline u32 hw_mmu_pte_addr_l2(u32 l2_base, u32 va)
-{
- u32 pte_addr;
-
- pte_addr = (l2_base & 0xFFFFFC00) | ((va >> 10) & 0x3FC);
-
- return pte_addr;
-}
-
-static inline u32 hw_mmu_pte_coarse_l1(u32 pte_val)
-{
- u32 pte_coarse;
-
- pte_coarse = pte_val & 0xFFFFFC00;
-
- return pte_coarse;
-}
-
-static inline u32 hw_mmu_pte_size_l1(u32 pte_val)
-{
- u32 pte_size = 0;
-
- if ((pte_val & 0x3) == 0x1) {
- /* Points to L2 PT */
- pte_size = HW_MMU_COARSE_PAGE_SIZE;
- }
-
- if ((pte_val & 0x3) == 0x2) {
- if (pte_val & (1 << 18))
- pte_size = HW_PAGE_SIZE16MB;
- else
- pte_size = HW_PAGE_SIZE1MB;
- }
-
- return pte_size;
-}
-
-static inline u32 hw_mmu_pte_size_l2(u32 pte_val)
-{
- u32 pte_size = 0;
-
- if (pte_val & 0x2)
- pte_size = HW_PAGE_SIZE4KB;
- else if (pte_val & 0x1)
- pte_size = HW_PAGE_SIZE64KB;
-
- return pte_size;
-}
-
-#endif /* _HW_MMU_H */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h b/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h
index 60a2781..ed4b288 100644
--- a/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h
+++ b/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h
@@ -55,7 +55,6 @@ struct cfg_hostres {
void __iomem *per_base;
u32 per_pm_base;
u32 core_pm_base;
- void __iomem *dmmu_base;
};

#endif /* CFGDEFS_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/drv.h b/drivers/staging/tidspbridge/include/dspbridge/drv.h
index 9cdbd95..ea74dda 100644
--- a/drivers/staging/tidspbridge/include/dspbridge/drv.h
+++ b/drivers/staging/tidspbridge/include/dspbridge/drv.h
@@ -55,9 +55,6 @@ struct drv_object;
#define OMAP_CORE_PRM_BASE 0x48306A00
#define OMAP_CORE_PRM_SIZE 0x1000

-#define OMAP_DMMU_BASE 0x5D000000
-#define OMAP_DMMU_SIZE 0x1000
-
/* GPP PROCESS CLEANUP Data structures */

/* New structure (member of process context) abstracts NODE resource info */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspioctl.h b/drivers/staging/tidspbridge/include/dspbridge/dspioctl.h
index 0c7ec04..b589c1d 100644
--- a/drivers/staging/tidspbridge/include/dspbridge/dspioctl.h
+++ b/drivers/staging/tidspbridge/include/dspbridge/dspioctl.h
@@ -19,10 +19,6 @@
#ifndef DSPIOCTL_
#define DSPIOCTL_

-/* ------------------------------------ Hardware Abstraction Layer */
-#include <hw_defs.h>
-#include <hw_mmu.h>
-
/*
* Any IOCTLS at or above this value are reserved for standard Bridge driver
* interfaces.
@@ -60,9 +56,6 @@ struct bridge_ioctl_extproc {
/* GPP virtual address. __va does not work for ioremapped addresses */
u32 gpp_va;
u32 size; /* Size of the mapped memory in bytes */
- enum hw_endianism_t endianism;
- enum hw_mmu_mixed_size_t mixed_mode;
- enum hw_element_size_t elem_size;
};

#endif /* DSPIOCTL_ */
diff --git a/drivers/staging/tidspbridge/rmgr/drv.c b/drivers/staging/tidspbridge/rmgr/drv.c
index db8215f..a7c93cf 100644
--- a/drivers/staging/tidspbridge/rmgr/drv.c
+++ b/drivers/staging/tidspbridge/rmgr/drv.c
@@ -689,7 +689,6 @@ static int request_bridge_resources(struct cfg_hostres *res)
/* First window is for DSP internal memory */
dev_dbg(bridge, "mem_base[0] 0x%x\n", host_res->mem_base[0]);
dev_dbg(bridge, "mem_base[3] 0x%x\n", host_res->mem_base[3]);
- dev_dbg(bridge, "dmmu_base %p\n", host_res->dmmu_base);

/* for 24xx base port is not mapping the mamory for DSP
* internal memory TODO Do a ioremap here */
@@ -743,8 +742,6 @@ int drv_request_bridge_res_dsp(void **phost_resources)
OMAP_PER_PRM_SIZE);
host_res->core_pm_base = (u32) ioremap(OMAP_CORE_PRM_BASE,
OMAP_CORE_PRM_SIZE);
- host_res->dmmu_base = ioremap(OMAP_DMMU_BASE,
- OMAP_DMMU_SIZE);

dev_dbg(bridge, "mem_base[0] 0x%x\n",
host_res->mem_base[0]);
@@ -756,7 +753,6 @@ int drv_request_bridge_res_dsp(void **phost_resources)
host_res->mem_base[3]);
dev_dbg(bridge, "mem_base[4] 0x%x\n",
host_res->mem_base[4]);
- dev_dbg(bridge, "dmmu_base %p\n", host_res->dmmu_base);

shm_size = drv_datap->shm_size;
if (shm_size >= 0x10000) {
--
1.7.1

2011-04-28 15:43:17

by Ramirez Luna, Omar

[permalink] [raw]
Subject: [PATCH v4 1/6] staging: tidspbridge: introduce mapping search based on device address

Create function find_containing_mapping_da to search mapping objects
given the dsp va instead of the mpu va, in preparation to delete dmm
functions altogether.

Signed-off-by: Omar Ramirez Luna <[email protected]>
---
drivers/staging/tidspbridge/rmgr/proc.c | 41 +++++++++++++++++++++++++++++-
1 files changed, 39 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/tidspbridge/rmgr/proc.c b/drivers/staging/tidspbridge/rmgr/proc.c
index 242dd13..214dff8 100644
--- a/drivers/staging/tidspbridge/rmgr/proc.c
+++ b/drivers/staging/tidspbridge/rmgr/proc.c
@@ -231,6 +231,37 @@ out:
return map_obj;
}

+static struct dmm_map_object *find_containing_mapping_da(
+ struct process_context *pr_ctxt,
+ u32 dsp_addr)
+{
+ struct dmm_map_object *map_obj;
+
+ pr_debug("%s: looking for virt 0x%x\n", __func__, dsp_addr);
+
+ spin_lock(&pr_ctxt->dmm_map_lock);
+ list_for_each_entry(map_obj, &pr_ctxt->dmm_map_list, link) {
+ pr_debug("%s: candidate: mpu_addr 0x%x virt 0x%x size 0x%x\n",
+ __func__,
+ map_obj->mpu_addr,
+ map_obj->dsp_addr,
+ map_obj->size);
+
+ if (map_obj->dsp_addr == dsp_addr) {
+ pr_debug("%s: match!\n", __func__);
+ goto out;
+ }
+ pr_debug("%s: candidate didn't match\n", __func__);
+ }
+
+ map_obj = NULL;
+
+ pr_err("%s: failed to find given map info\n", __func__);
+out:
+ spin_unlock(&pr_ctxt->dmm_map_lock);
+ return map_obj;
+}
+
static int find_first_page_in_cache(struct dmm_map_object *map_obj,
unsigned long mpu_addr)
{
@@ -1703,6 +1734,7 @@ int proc_un_map(void *hprocessor, void *map_addr,
int status = 0;
struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
struct dmm_object *dmm_mgr;
+ struct dmm_map_object *dmo;
u32 va_align;
u32 size_align;

@@ -1725,10 +1757,15 @@ int proc_un_map(void *hprocessor, void *map_addr,
* This function returns error if the VA is not mapped
*/
status = dmm_un_map_memory(dmm_mgr, (u32) va_align, &size_align);
+
+ dmo = find_containing_mapping_da(pr_ctxt, (u32)map_addr);
+ if (!dmo)
+ goto unmap_failed;
+
/* Remove mapping from the page tables. */
if (!status) {
status = (*p_proc_object->intf_fxns->brd_mem_un_map)
- (p_proc_object->bridge_context, va_align, size_align);
+ (p_proc_object->bridge_context, va_align, dmo->size);
}

if (status)
@@ -1739,7 +1776,7 @@ int proc_un_map(void *hprocessor, void *map_addr,
* from dmm_map_list, so that mapped memory resource tracking
* remains uptodate
*/
- remove_mapping_information(pr_ctxt, (u32) map_addr, size_align);
+ remove_mapping_information(pr_ctxt, (u32) map_addr, dmo->size);

unmap_failed:
mutex_unlock(&proc_lock);
--
1.7.1

2011-04-28 15:45:22

by Ramirez Luna, Omar

[permalink] [raw]
Subject: [PATCH v4 3/6] staging: tidspbridge: mapping support when SG_CHAIN is not defined

If ARCH_HAS_SG_CHAIN is not defined a scatter-gather table can hold a
fixed number of entries, otherwise it results in a panic when
allocating bigger tables.

Use generic allocator to manage the mapped memory in such cases and
ignore iovmm functions.

Signed-off-by: Fernando Guzman Lugo <[email protected]>
Signed-off-by: Omar Ramirez Luna <[email protected]>
---
drivers/staging/tidspbridge/Kconfig | 1 +
drivers/staging/tidspbridge/core/tiomap3430.c | 94 +++++++++++++++++++-
.../tidspbridge/include/dspbridge/dspdefs.h | 3 +-
drivers/staging/tidspbridge/rmgr/proc.c | 3 +-
4 files changed, 96 insertions(+), 5 deletions(-)

diff --git a/drivers/staging/tidspbridge/Kconfig b/drivers/staging/tidspbridge/Kconfig
index 19b1b76..7a9d539 100644
--- a/drivers/staging/tidspbridge/Kconfig
+++ b/drivers/staging/tidspbridge/Kconfig
@@ -8,6 +8,7 @@ menuconfig TIDSPBRIDGE
select OMAP_MBOX_FWK
select OMAP_IOMMU
select OMAP_IOMMU_IVA2
+ select GENERIC_ALLOCATOR
help
DSP/BIOS Bridge is designed for platforms that contain a GPP and
one or more attached DSPs. The GPP is considered the master or
diff --git a/drivers/staging/tidspbridge/core/tiomap3430.c b/drivers/staging/tidspbridge/core/tiomap3430.c
index 1ca50d9..692a456 100644
--- a/drivers/staging/tidspbridge/core/tiomap3430.c
+++ b/drivers/staging/tidspbridge/core/tiomap3430.c
@@ -23,6 +23,7 @@
#include <dspbridge/host_os.h>
#include <linux/mm.h>
#include <linux/mmzone.h>
+#include <linux/genalloc.h>

/* ----------------------------------- DSP/BIOS Bridge */
#include <dspbridge/dbdefs.h>
@@ -114,7 +115,8 @@ static int bridge_brd_mem_map(struct bridge_dev_context *dev_ctxt,
u32 ul_mpu_addr, u32 virt_addr,
u32 ul_num_bytes, struct page **mapped_pages);
static int bridge_brd_mem_un_map(struct bridge_dev_context *dev_ctxt,
- u32 da);
+ u32 da, size_t size,
+ struct page **usr_pgs);
static int bridge_dev_create(struct bridge_dev_context
**dev_cntxt,
struct dev_object *hdev_obj,
@@ -229,6 +231,27 @@ static struct notifier_block dsp_mbox_notifier = {
.notifier_call = io_mbox_msg,
};

+#ifndef ARCH_HAS_SG_CHAIN
+static struct gen_pool *dmm_pool;
+
+static inline u32 dsptlb_init_entry(struct iotlb_entry *e, u32 da, u32 pa,
+ u32 pgsz)
+{
+ memset(e, 0, sizeof(*e));
+
+ e->da = da;
+ e->pa = pa;
+ e->valid = 1;
+ e->pgsz = MMU_CAM_PGSZ_4K;
+ e->pgsz = pgsz & MMU_CAM_PGSZ_MASK;
+ e->endian = MMU_RAM_ENDIAN_LITTLE;
+ e->elsz = MMU_RAM_ELSZ_32;
+ e->mixed = 0;
+
+ return iopgsz_to_bytes(e->pgsz);
+}
+#endif /* !ARCH_HAS_SG_CHAIN */
+
static inline void flush_all(struct bridge_dev_context *dev_context)
{
if (dev_context->brd_state == BRD_DSP_HIBERNATION ||
@@ -463,6 +486,27 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt,
dev_context->dsp_mmu = NULL;
return PTR_ERR(mmu);
}
+#ifndef ARCH_HAS_SG_CHAIN
+ else {
+ u32 start;
+
+ if (dmm_pool) {
+ gen_pool_destroy(dmm_pool);
+ dmm_pool = NULL;
+ }
+
+ dmm_pool = gen_pool_create(PAGE_SHIFT, -1);
+ if (!dmm_pool) {
+ iommu_put(mmu);
+ dev_context->dsp_mmu = NULL;
+ return -ENOMEM;
+ }
+
+ sm_sg = &dev_context->sh_s;
+ start = sm_sg->seg1_da + sm_sg->seg1_size;
+ gen_pool_add(dmm_pool, start, CONFIG_TIDSPBRIDGE_DMM_SIZE, -1);
+ }
+#endif

dev_context->dsp_mmu = mmu;
mmu->isr = mmu_fault_isr;
@@ -741,6 +785,12 @@ static int bridge_brd_stop(struct bridge_dev_context *dev_ctxt)
iommu_kunmap(dev_context->dsp_mmu, dev_context->sh_s.seg0_da);
iommu_put(dev_context->dsp_mmu);
dev_context->dsp_mmu = NULL;
+#ifndef ARCH_HAS_SG_CHAIN
+ if (dmm_pool) {
+ gen_pool_destroy(dmm_pool);
+ dmm_pool = NULL;
+ }
+#endif
}

/* Reset IVA IOMMU */
@@ -1194,8 +1244,13 @@ static int bridge_brd_mem_map(struct bridge_dev_context *dev_ctx,
struct iommu *mmu = dev_ctx->dsp_mmu;
struct vm_area_struct *vma;
struct mm_struct *mm = current->mm;
+#ifndef ARCH_HAS_SG_CHAIN
+ u32 pa, addr;
+ struct iotlb_entry e;
+#else
struct sg_table *sgt;
struct scatterlist *sg;
+#endif

if (!size || !usr_pgs)
return -EINVAL;
@@ -1231,6 +1286,23 @@ static int bridge_brd_mem_map(struct bridge_dev_context *dev_ctx,
goto err_pages;
}

+#ifndef ARCH_HAS_SG_CHAIN
+ da = gen_pool_alloc(dmm_pool, size);
+ if (!da) {
+ res = -ENOMEM;
+ goto err_pages;
+ }
+
+ wake_dsp(dev_ctx, NULL);
+
+ for (i = 0, addr = da; i < pages; i++, addr += PAGE_SIZE) {
+ pa = page_to_phys(usr_pgs[i]);
+ dsptlb_init_entry(&e, addr, pa, MMU_CAM_PGSZ_4K);
+ iopgtable_store_entry(mmu, &e);
+ }
+
+ return da;
+#else
sgt = kzalloc(sizeof(*sgt), GFP_KERNEL);
if (!sgt) {
res = -ENOMEM;
@@ -1257,6 +1329,7 @@ static int bridge_brd_mem_map(struct bridge_dev_context *dev_ctx,
err_sg:
kfree(sgt);
i = pages;
+#endif /* ARCH_HAS_SG_CHAIN */
err_pages:
while (i--)
put_page(usr_pgs[i]);
@@ -1271,9 +1344,23 @@ err_pages:
* So, instead of looking up the PTE address for every 4K block,
* we clear consecutive PTEs until we unmap all the bytes
*/
-static int bridge_brd_mem_un_map(struct bridge_dev_context *dev_ctx, u32 da)
+static int bridge_brd_mem_un_map(struct bridge_dev_context *dev_ctx, u32 da,
+ size_t size, struct page **usr_pgs)
{
- unsigned i;
+ unsigned i = 0;
+#ifndef ARCH_HAS_SG_CHAIN
+ gen_pool_free(dmm_pool, da, size);
+
+ wake_dsp(dev_ctx, NULL);
+
+ while (size > 0) {
+ size_t bytes;
+ bytes = iopgtable_clear_entry(dev_ctx->dsp_mmu, da);
+ size -= bytes;
+ da += bytes;
+ put_page(usr_pgs[i++]);
+ }
+#else
struct sg_table *sgt;
struct scatterlist *sg;

@@ -1288,6 +1375,7 @@ static int bridge_brd_mem_un_map(struct bridge_dev_context *dev_ctx, u32 da)

sg_free_table(sgt);
kfree(sgt);
+#endif /* ARCH_HAS_SG_CHAIN */

return 0;
}
diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h b/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h
index 48f91c9..e052bba 100644
--- a/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h
+++ b/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h
@@ -194,7 +194,8 @@ typedef int(*fxn_brd_memmap) (struct bridge_dev_context
*/
typedef int(*fxn_brd_memunmap) (struct bridge_dev_context
* dev_ctxt,
- u32 da);
+ u32 da, size_t size,
+ struct page **usr_pgs);

/*
* ======== bridge_brd_stop ========
diff --git a/drivers/staging/tidspbridge/rmgr/proc.c b/drivers/staging/tidspbridge/rmgr/proc.c
index 9049df8..ce57279 100644
--- a/drivers/staging/tidspbridge/rmgr/proc.c
+++ b/drivers/staging/tidspbridge/rmgr/proc.c
@@ -1731,7 +1731,8 @@ int proc_un_map(void *hprocessor, void *map_addr,

/* Remove mapping from the page tables. */
status = (*p_proc_object->intf_fxns->brd_mem_un_map)
- (p_proc_object->bridge_context, va_align);
+ (p_proc_object->bridge_context, va_align, dmo->size,
+ dmo->pages);
if (status)
goto unmap_failed;

--
1.7.1

2011-04-28 15:45:20

by Ramirez Luna, Omar

[permalink] [raw]
Subject: [PATCH v4 2/6] staging: tidspbridge: replace custom mmu for omap iommu framework

Use omap iommu framework to control IVA mmu and map/unmap buffers
to the dsp.

Changes to select IOMMU module and IVA IOMMU support are needed when
using tidspbridge, Kconfig has been updated for that.

Remove code from proc_reserve/un_reserve which is intended to manage
the available virtual address space, since iovmm does that.

BEWARE: Due to SG_CHAIN not being reviewed/fully-tested within the
ARM architecture, if not selected, sg_alloc_table can't allocate SG
tables representing large buffers (usually ~2MB+), this limitation
translates into a panic if attempted.

Signed-off-by: Fernando Guzman Lugo <[email protected]>
Signed-off-by: Omar Ramirez Luna <[email protected]>
---
drivers/staging/tidspbridge/Kconfig | 10 +
drivers/staging/tidspbridge/core/_deh.h | 2 +
drivers/staging/tidspbridge/core/_tiomap.h | 16 +-
drivers/staging/tidspbridge/core/io_sm.c | 177 +-----
drivers/staging/tidspbridge/core/tiomap3430.c | 676 +++++++-------------
drivers/staging/tidspbridge/core/tiomap3430_pwr.c | 2 +-
drivers/staging/tidspbridge/core/tiomap_io.c | 12 +-
drivers/staging/tidspbridge/core/ue_deh.c | 100 +--
.../tidspbridge/include/dspbridge/dspdefs.h | 3 +-
drivers/staging/tidspbridge/rmgr/proc.c | 95 +---
10 files changed, 326 insertions(+), 767 deletions(-)

diff --git a/drivers/staging/tidspbridge/Kconfig b/drivers/staging/tidspbridge/Kconfig
index 93de4f2..19b1b76 100644
--- a/drivers/staging/tidspbridge/Kconfig
+++ b/drivers/staging/tidspbridge/Kconfig
@@ -6,6 +6,8 @@ menuconfig TIDSPBRIDGE
tristate "DSP Bridge driver"
depends on ARCH_OMAP3
select OMAP_MBOX_FWK
+ select OMAP_IOMMU
+ select OMAP_IOMMU_IVA2
help
DSP/BIOS Bridge is designed for platforms that contain a GPP and
one or more attached DSPs. The GPP is considered the master or
@@ -31,6 +33,14 @@ config TIDSPBRIDGE_MEMPOOL_SIZE
Allocate specified size of memory at booting time to avoid allocation
failure under heavy memory fragmentation after some use time.

+config TIDSPBRIDGE_DMM_SIZE
+ hex "DMM capable memory size (Byte)"
+ depends on TIDSPBRIDGE
+ default "0x10000000"
+ help
+ Memory size of DSP virtual address for Dynamic Memory Mapping.
+ Please make sure the size is 4K aligned.
+
config TIDSPBRIDGE_DEBUG
bool "Debug Support"
depends on TIDSPBRIDGE
diff --git a/drivers/staging/tidspbridge/core/_deh.h b/drivers/staging/tidspbridge/core/_deh.h
index 025d343..85543cf 100644
--- a/drivers/staging/tidspbridge/core/_deh.h
+++ b/drivers/staging/tidspbridge/core/_deh.h
@@ -32,4 +32,6 @@ struct deh_mgr {
struct tasklet_struct dpc_tasklet;
};

+int mmu_fault_isr(struct iommu *mmu, u32 da, u32 iommu_errs, void *priv);
+
#endif /* _DEH_ */
diff --git a/drivers/staging/tidspbridge/core/_tiomap.h b/drivers/staging/tidspbridge/core/_tiomap.h
index 7cb5871..d493e11 100644
--- a/drivers/staging/tidspbridge/core/_tiomap.h
+++ b/drivers/staging/tidspbridge/core/_tiomap.h
@@ -34,6 +34,8 @@
#include <mach-omap2/cm2xxx_3xxx.h>
#include <mach-omap2/prm-regbits-34xx.h>
#include <mach-omap2/cm-regbits-34xx.h>
+#include <plat/iommu.h>
+#include <plat/iovmm.h>
#include <dspbridge/devdefs.h>
#include <hw_defs.h>
#include <dspbridge/dspioctl.h> /* for bridge_ioctl_extproc defn */
@@ -317,6 +319,17 @@ static const struct bpwr_clk_t bpwr_clks[] = {

#define CLEAR_BIT_INDEX(reg, index) (reg &= ~(1 << (index)))

+struct shm_segs {
+ u32 seg0_da;
+ u32 seg0_pa;
+ u32 seg0_va;
+ u32 seg0_size;
+ u32 seg1_da;
+ u32 seg1_pa;
+ u32 seg1_va;
+ u32 seg1_size;
+};
+
/* This Bridge driver's device context: */
struct bridge_dev_context {
struct dev_object *dev_obj; /* Handle to Bridge device object. */
@@ -339,7 +352,8 @@ struct bridge_dev_context {
u32 internal_size; /* Internal memory size */

struct omap_mbox *mbox; /* Mail box handle */
-
+ struct iommu *dsp_mmu; /* iommu for iva2 handler */
+ struct shm_segs sh_s;
struct cfg_hostres *resources; /* Host Resources */

/*
diff --git a/drivers/staging/tidspbridge/core/io_sm.c b/drivers/staging/tidspbridge/core/io_sm.c
index 694c0e5..3558658 100644
--- a/drivers/staging/tidspbridge/core/io_sm.c
+++ b/drivers/staging/tidspbridge/core/io_sm.c
@@ -271,6 +271,7 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr)
struct cod_manager *cod_man;
struct chnl_mgr *hchnl_mgr;
struct msg_mgr *hmsg_mgr;
+ struct shm_segs *sm_sg;
u32 ul_shm_base;
u32 ul_shm_base_offset;
u32 ul_shm_limit;
@@ -293,18 +294,9 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr)
struct bridge_ioctl_extproc ae_proc[BRDIOCTL_NUMOFMMUTLB];
struct cfg_hostres *host_res;
struct bridge_dev_context *pbridge_context;
- u32 map_attrs;
u32 shm0_end;
u32 ul_dyn_ext_base;
u32 ul_seg1_size = 0;
- u32 pa_curr = 0;
- u32 va_curr = 0;
- u32 gpp_va_curr = 0;
- u32 num_bytes = 0;
- u32 all_bits = 0;
- u32 page_size[] = { HW_PAGE_SIZE16MB, HW_PAGE_SIZE1MB,
- HW_PAGE_SIZE64KB, HW_PAGE_SIZE4KB
- };

status = dev_get_bridge_context(hio_mgr->dev_obj, &pbridge_context);
if (!pbridge_context) {
@@ -317,6 +309,9 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr)
status = -EFAULT;
goto func_end;
}
+
+ sm_sg = &pbridge_context->sh_s;
+
status = dev_get_cod_mgr(hio_mgr->dev_obj, &cod_man);
if (!cod_man) {
status = -EFAULT;
@@ -451,129 +446,14 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr)
if (status)
goto func_end;

- pa_curr = ul_gpp_pa;
- va_curr = ul_dyn_ext_base * hio_mgr->word_size;
- gpp_va_curr = ul_gpp_va;
- num_bytes = ul_seg1_size;
-
- /*
- * Try to fit into TLB entries. If not possible, push them to page
- * tables. It is quite possible that if sections are not on
- * bigger page boundary, we may end up making several small pages.
- * So, push them onto page tables, if that is the case.
- */
- map_attrs = 0x00000000;
- map_attrs = DSP_MAPLITTLEENDIAN;
- map_attrs |= DSP_MAPPHYSICALADDR;
- map_attrs |= DSP_MAPELEMSIZE32;
- map_attrs |= DSP_MAPDONOTLOCK;
-
- while (num_bytes) {
- /*
- * To find the max. page size with which both PA & VA are
- * aligned.
- */
- all_bits = pa_curr | va_curr;
- dev_dbg(bridge, "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 >= page_size[i]) && ((all_bits &
- (page_size[i] -
- 1)) == 0)) {
- status =
- hio_mgr->intf_fxns->
- brd_mem_map(hio_mgr->bridge_context,
- pa_curr, va_curr,
- page_size[i], map_attrs,
- NULL);
- if (status)
- goto func_end;
- pa_curr += page_size[i];
- va_curr += page_size[i];
- gpp_va_curr += page_size[i];
- num_bytes -= page_size[i];
- /*
- * Don't try smaller sizes. Hopefully we have
- * reached an address aligned to a bigger page
- * size.
- */
- break;
- }
- }
- }
- pa_curr += ul_pad_size;
- va_curr += ul_pad_size;
- gpp_va_curr += ul_pad_size;
-
- /* Configure the TLB entries for the next cacheable segment */
- num_bytes = ul_seg_size;
- va_curr = ul_dsp_va * hio_mgr->word_size;
- while (num_bytes) {
- /*
- * To find the max. page size with which both PA & VA are
- * aligned.
- */
- all_bits = pa_curr | va_curr;
- dev_dbg(bridge, "all_bits for Seg1 %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 >= page_size[i]) ||
- !((all_bits & (page_size[i] - 1)) == 0))
- continue;
- if (ndx < MAX_LOCK_TLB_ENTRIES) {
- /*
- * This is the physical address written to
- * DSP MMU.
- */
- ae_proc[ndx].gpp_pa = pa_curr;
- /*
- * This is the virtual uncached ioremapped
- * address!!!
- */
- ae_proc[ndx].gpp_va = gpp_va_curr;
- ae_proc[ndx].dsp_va =
- va_curr / hio_mgr->word_size;
- ae_proc[ndx].size = page_size[i];
- ae_proc[ndx].endianism = HW_LITTLE_ENDIAN;
- ae_proc[ndx].elem_size = HW_ELEM_SIZE16BIT;
- ae_proc[ndx].mixed_mode = HW_MMU_CPUES;
- dev_dbg(bridge, "shm MMU TLB entry PA %x"
- " VA %x DSP_VA %x Size %x\n",
- ae_proc[ndx].gpp_pa,
- ae_proc[ndx].gpp_va,
- ae_proc[ndx].dsp_va *
- hio_mgr->word_size, page_size[i]);
- ndx++;
- } else {
- status =
- hio_mgr->intf_fxns->
- brd_mem_map(hio_mgr->bridge_context,
- pa_curr, va_curr,
- page_size[i], map_attrs,
- NULL);
- dev_dbg(bridge,
- "shm MMU PTE entry PA %x"
- " VA %x DSP_VA %x Size %x\n",
- ae_proc[ndx].gpp_pa,
- ae_proc[ndx].gpp_va,
- ae_proc[ndx].dsp_va *
- hio_mgr->word_size, page_size[i]);
- if (status)
- goto func_end;
- }
- pa_curr += page_size[i];
- va_curr += page_size[i];
- gpp_va_curr += page_size[i];
- num_bytes -= page_size[i];
- /*
- * Don't try smaller sizes. Hopefully we have reached
- * an address aligned to a bigger page size.
- */
- break;
- }
- }
+ sm_sg->seg1_pa = ul_gpp_pa;
+ sm_sg->seg1_da = ul_dyn_ext_base;
+ sm_sg->seg1_va = ul_gpp_va;
+ sm_sg->seg1_size = ul_seg1_size;
+ sm_sg->seg0_pa = ul_gpp_pa + ul_pad_size + ul_seg1_size;
+ sm_sg->seg0_da = ul_dsp_va;
+ sm_sg->seg0_va = ul_gpp_va + ul_pad_size + ul_seg1_size;
+ sm_sg->seg0_size = ul_seg_size;

/*
* Copy remaining entries from CDB. All entries are 1 MB and
@@ -614,38 +494,12 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr)
"DSP_VA 0x%x\n", ae_proc[ndx].gpp_pa,
ae_proc[ndx].dsp_va);
ndx++;
- } else {
- status = hio_mgr->intf_fxns->brd_mem_map
- (hio_mgr->bridge_context,
- hio_mgr->ext_proc_info.ty_tlb[i].
- gpp_phys,
- hio_mgr->ext_proc_info.ty_tlb[i].
- dsp_virt, 0x100000, map_attrs,
- NULL);
}
}
if (status)
goto func_end;
}

- map_attrs = 0x00000000;
- map_attrs = DSP_MAPLITTLEENDIAN;
- map_attrs |= DSP_MAPPHYSICALADDR;
- map_attrs |= DSP_MAPELEMSIZE32;
- map_attrs |= DSP_MAPDONOTLOCK;
-
- /* Map the L4 peripherals */
- i = 0;
- while (l4_peripheral_table[i].phys_addr) {
- status = hio_mgr->intf_fxns->brd_mem_map
- (hio_mgr->bridge_context, l4_peripheral_table[i].phys_addr,
- l4_peripheral_table[i].dsp_virt_addr, HW_PAGE_SIZE4KB,
- map_attrs, NULL);
- if (status)
- goto func_end;
- i++;
- }
-
for (i = ndx; i < BRDIOCTL_NUMOFMMUTLB; i++) {
ae_proc[i].dsp_va = 0;
ae_proc[i].gpp_pa = 0;
@@ -668,12 +522,12 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr)
status = -EFAULT;
goto func_end;
} else {
- if (ae_proc[0].dsp_va > ul_shm_base) {
+ if (sm_sg->seg0_da > ul_shm_base) {
status = -EPERM;
goto func_end;
}
/* ul_shm_base may not be at ul_dsp_va address */
- ul_shm_base_offset = (ul_shm_base - ae_proc[0].dsp_va) *
+ ul_shm_base_offset = (ul_shm_base - sm_sg->seg0_da) *
hio_mgr->word_size;
/*
* bridge_dev_ctrl() will set dev context dsp-mmu info. In
@@ -697,8 +551,7 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr)
goto func_end;
}
/* Register SM */
- status =
- register_shm_segs(hio_mgr, cod_man, ae_proc[0].gpp_pa);
+ status = register_shm_segs(hio_mgr, cod_man, sm_sg->seg0_pa);
}

hio_mgr->shared_mem = (struct shm *)ul_shm_base;
diff --git a/drivers/staging/tidspbridge/core/tiomap3430.c b/drivers/staging/tidspbridge/core/tiomap3430.c
index e1c4492..1ca50d9 100644
--- a/drivers/staging/tidspbridge/core/tiomap3430.c
+++ b/drivers/staging/tidspbridge/core/tiomap3430.c
@@ -57,6 +57,7 @@
#include "_tiomap.h"
#include "_tiomap_pwr.h"
#include "tiomap_io.h"
+#include "_deh.h"

/* Offset in shared mem to write to in order to synchronize start with DSP */
#define SHMSYNCOFFSET 4 /* GPP byte offset */
@@ -111,10 +112,9 @@ static int bridge_brd_mem_write(struct bridge_dev_context *dev_ctxt,
u32 ul_num_bytes, u32 mem_type);
static int bridge_brd_mem_map(struct bridge_dev_context *dev_ctxt,
u32 ul_mpu_addr, u32 virt_addr,
- u32 ul_num_bytes, u32 ul_map_attr,
- struct page **mapped_pages);
+ u32 ul_num_bytes, struct page **mapped_pages);
static int bridge_brd_mem_un_map(struct bridge_dev_context *dev_ctxt,
- u32 virt_addr, u32 ul_num_bytes);
+ u32 da);
static int bridge_dev_create(struct bridge_dev_context
**dev_cntxt,
struct dev_object *hdev_obj,
@@ -122,6 +122,8 @@ static int bridge_dev_create(struct bridge_dev_context
static int bridge_dev_ctrl(struct bridge_dev_context *dev_context,
u32 dw_cmd, void *pargs);
static int bridge_dev_destroy(struct bridge_dev_context *dev_ctxt);
+static int get_io_pages(struct mm_struct *mm, u32 uva, unsigned pages,
+ struct page **usr_pgs);
static u32 user_va2_pa(struct mm_struct *mm, u32 address);
static int pte_update(struct bridge_dev_context *dev_ctxt, u32 pa,
u32 va, u32 size,
@@ -301,8 +303,7 @@ static int bridge_brd_monitor(struct bridge_dev_context *dev_ctxt)
(*pdata->dsp_cm_write)(OMAP34XX_CLKSTCTRL_DISABLE_AUTO,
OMAP3430_IVA2_MOD, OMAP2_CM_CLKSTCTRL);
}
- (*pdata->dsp_prm_rmw_bits)(OMAP3430_RST2_IVA2_MASK, 0,
- OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);
+
dsp_clk_enable(DSP_CLK_IVA2);

/* set the device state to IDLE */
@@ -373,14 +374,18 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt,
{
int status = 0;
struct bridge_dev_context *dev_context = dev_ctxt;
+ struct iommu *mmu = NULL;
+ struct shm_segs *sm_sg;
+ int l4_i, tlb_i;
+ u32 sg0_da, sg1_da, da;
+ u32 flags = IOVMF_ENDIAN_LITTLE | IOVMF_ELSZ_32 | IOVMF_DA_FIXED;
+ struct bridge_ioctl_extproc *tlb = dev_context->atlb_entry;
u32 dw_sync_addr = 0;
u32 ul_shm_base; /* Gpp Phys SM base addr(byte) */
u32 ul_shm_base_virt; /* Dsp Virt SM base addr */
u32 ul_tlb_base_virt; /* Base of MMU TLB entry */
/* Offset of shm_base_virt from tlb_base_virt */
u32 ul_shm_offset_virt;
- s32 entry_ndx;
- s32 itmp_entry_ndx = 0; /* DSP-MMU TLB entry base address */
struct cfg_hostres *resources = NULL;
u32 temp;
u32 ul_dsp_clk_rate;
@@ -401,12 +406,12 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt,
ul_shm_base_virt *= DSPWORDSIZE;
DBC_ASSERT(ul_shm_base_virt != 0);
/* DSP Virtual address */
- ul_tlb_base_virt = dev_context->atlb_entry[0].dsp_va;
+ ul_tlb_base_virt = dev_context->sh_s.seg0_da;
DBC_ASSERT(ul_tlb_base_virt <= ul_shm_base_virt);
ul_shm_offset_virt =
ul_shm_base_virt - (ul_tlb_base_virt * DSPWORDSIZE);
/* Kernel logical address */
- ul_shm_base = dev_context->atlb_entry[0].gpp_va + ul_shm_offset_virt;
+ ul_shm_base = dev_context->sh_s.seg0_va + ul_shm_offset_virt;

DBC_ASSERT(ul_shm_base != 0);
/* 2nd wd is used as sync field */
@@ -441,78 +446,91 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt,
OMAP343X_CONTROL_IVA2_BOOTMOD));
}
}
- if (!status) {
- /* Reset and Unreset the RST2, so that BOOTADDR is copied to
- * IVA2 SYSC register */
- (*pdata->dsp_prm_rmw_bits)(OMAP3430_RST2_IVA2_MASK,
- OMAP3430_RST2_IVA2_MASK, OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);
- udelay(100);
- (*pdata->dsp_prm_rmw_bits)(OMAP3430_RST2_IVA2_MASK, 0,
+
+ if (status)
+ return status;
+
+ (*pdata->dsp_prm_rmw_bits)(OMAP3430_RST2_IVA2_MASK, 0,
OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);
- udelay(100);
-
- /* Disbale the DSP MMU */
- hw_mmu_disable(resources->dmmu_base);
- /* Disable TWL */
- hw_mmu_twl_disable(resources->dmmu_base);
-
- /* Only make TLB entry if both addresses are non-zero */
- for (entry_ndx = 0; entry_ndx < BRDIOCTL_NUMOFMMUTLB;
- entry_ndx++) {
- struct bridge_ioctl_extproc *e = &dev_context->atlb_entry[entry_ndx];
- struct hw_mmu_map_attrs_t map_attrs = {
- .endianism = e->endianism,
- .element_size = e->elem_size,
- .mixed_size = e->mixed_mode,
- };
-
- if (!e->gpp_pa || !e->dsp_va)
- continue;

- dev_dbg(bridge,
- "MMU %d, pa: 0x%x, va: 0x%x, size: 0x%x",
- itmp_entry_ndx,
- e->gpp_pa,
- e->dsp_va,
- e->size);
-
- hw_mmu_tlb_add(dev_context->dsp_mmu_base,
- e->gpp_pa,
- e->dsp_va,
- e->size,
- itmp_entry_ndx,
- &map_attrs, 1, 1);
-
- itmp_entry_ndx++;
+ mmu = dev_context->dsp_mmu;
+ if (mmu)
+ iommu_put(mmu);
+
+ mmu = iommu_get("iva2");
+ if (IS_ERR(mmu)) {
+ dev_err(bridge, "iommu_get failed!\n");
+ dev_context->dsp_mmu = NULL;
+ return PTR_ERR(mmu);
+ }
+
+ dev_context->dsp_mmu = mmu;
+ mmu->isr = mmu_fault_isr;
+ sm_sg = &dev_context->sh_s;
+ /* Set valid range to map shared memory */
+ status = iommu_set_da_range(mmu, sm_sg->seg0_da,
+ sm_sg->seg1_da + sm_sg->seg1_size);
+ if (status)
+ return status;
+
+ sg0_da = iommu_kmap(mmu, sm_sg->seg0_da, sm_sg->seg0_pa,
+ sm_sg->seg0_size, flags);
+ if (IS_ERR_VALUE(sg0_da))
+ return (int)sg0_da;
+
+ sg1_da = iommu_kmap(mmu, sm_sg->seg1_da, sm_sg->seg1_pa,
+ sm_sg->seg1_size, flags);
+ if (IS_ERR_VALUE(sg1_da)) {
+ status = (int)sg1_da;
+ goto err1;
+ }
+
+ for (tlb_i = 0; tlb_i < BRDIOCTL_NUMOFMMUTLB; tlb_i++) {
+ if (!tlb[tlb_i].gpp_pa)
+ continue;
+
+ da = iommu_kmap(mmu, tlb[tlb_i].dsp_va, tlb[tlb_i].gpp_pa,
+ PAGE_SIZE, flags);
+ if (IS_ERR_VALUE(da)) {
+ status = (int)da;
+ goto err2;
}
}

+ l4_i = 0;
+ while (l4_peripheral_table[l4_i].phys_addr) {
+ da = iommu_kmap(mmu, l4_peripheral_table[l4_i].dsp_virt_addr,
+ l4_peripheral_table[l4_i].phys_addr, PAGE_SIZE,
+ flags);
+ if (IS_ERR_VALUE(da)) {
+ status = (int)da;
+ goto err3;
+ }
+ l4_i++;
+ }
+
+ /* Set valid range for DMM mappings */
+ if (0xFFFFF000 - CONFIG_TIDSPBRIDGE_DMM_SIZE <
+ sm_sg->seg1_da + sm_sg->seg1_size) {
+ dev_err(bridge, "DMM size too big!\n");
+ status = -ENOMEM;
+ } else {
+ status = iommu_set_da_range(mmu,
+ sm_sg->seg1_da + sm_sg->seg1_size,
+ sm_sg->seg1_da + sm_sg->seg1_size +
+ CONFIG_TIDSPBRIDGE_DMM_SIZE);
+ }
+
/* Lock the above TLB entries and get the BIOS and load monitor timer
* information */
if (!status) {
- hw_mmu_num_locked_set(resources->dmmu_base, itmp_entry_ndx);
- hw_mmu_victim_num_set(resources->dmmu_base, itmp_entry_ndx);
- hw_mmu_ttb_set(resources->dmmu_base,
- dev_context->pt_attrs->l1_base_pa);
- hw_mmu_twl_enable(resources->dmmu_base);
- /* Enable the SmartIdle and AutoIdle bit for MMU_SYSCONFIG */
-
- temp = __raw_readl((resources->dmmu_base) + 0x10);
- temp = (temp & 0xFFFFFFEF) | 0x11;
- __raw_writel(temp, (resources->dmmu_base) + 0x10);
-
- /* Let the DSP MMU run */
- hw_mmu_enable(resources->dmmu_base);
-
/* Enable the BIOS clock */
(void)dev_get_symbol(dev_context->dev_obj,
BRIDGEINIT_BIOSGPTIMER, &ul_bios_gp_timer);
(void)dev_get_symbol(dev_context->dev_obj,
BRIDGEINIT_LOADMON_GPTIMER,
&ul_load_monitor_timer);
- }

- if (!status) {
if (ul_load_monitor_timer != 0xFFFF) {
clk_cmd = (BPWR_ENABLE_CLOCK << MBX_PM_CLK_CMDSHIFT) |
ul_load_monitor_timer;
@@ -521,9 +539,7 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt,
dev_dbg(bridge, "Not able to get the symbol for Load "
"Monitor Timer\n");
}
- }

- if (!status) {
if (ul_bios_gp_timer != 0xFFFF) {
clk_cmd = (BPWR_ENABLE_CLOCK << MBX_PM_CLK_CMDSHIFT) |
ul_bios_gp_timer;
@@ -532,9 +548,7 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt,
dev_dbg(bridge,
"Not able to get the symbol for BIOS Timer\n");
}
- }

- if (!status) {
/* Set the DSP clock rate */
(void)dev_get_symbol(dev_context->dev_obj,
"_BRIDGEINIT_DSP_FREQ", &ul_dsp_clk_addr);
@@ -585,9 +599,6 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt,

/* Let DSP go */
dev_dbg(bridge, "%s Unreset\n", __func__);
- /* Enable DSP MMU Interrupts */
- hw_mmu_event_enable(resources->dmmu_base,
- HW_MMU_ALL_INTERRUPTS);
/* release the RST1, DSP starts executing now .. */
(*pdata->dsp_prm_rmw_bits)(OMAP3430_RST1_IVA2_MASK, 0,
OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);
@@ -617,11 +628,28 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt,

/* update board state */
dev_context->brd_state = BRD_RUNNING;
- /* (void)chnlsm_enable_interrupt(dev_context); */
+ return 0;
} else {
dev_context->brd_state = BRD_UNKNOWN;
}
}
+
+err3:
+ while (l4_i--)
+ iommu_kunmap(mmu, l4_peripheral_table[l4_i].dsp_virt_addr);
+err2:
+ while (tlb_i--) {
+ if (!tlb[tlb_i].gpp_pa)
+ continue;
+ iommu_kunmap(mmu, tlb[tlb_i].gpp_va);
+ }
+
+ if (sg1_da)
+ iommu_kunmap(mmu, sg1_da);
+err1:
+ if (sg0_da)
+ iommu_kunmap(mmu, sg0_da);
+
return status;
}

@@ -639,6 +667,8 @@ static int bridge_brd_stop(struct bridge_dev_context *dev_ctxt)
struct bridge_dev_context *dev_context = dev_ctxt;
struct pg_table_attrs *pt_attrs;
u32 dsp_pwr_state;
+ int i;
+ struct bridge_ioctl_extproc *tlb = dev_context->atlb_entry;
struct omap_dsp_platform_data *pdata =
omap_dspbridge_dev->dev.platform_data;

@@ -682,15 +712,40 @@ static int bridge_brd_stop(struct bridge_dev_context *dev_ctxt)
memset((u8 *) pt_attrs->pg_info, 0x00,
(pt_attrs->l2_num_pages * sizeof(struct page_info)));
}
+ /* Reset DSP */
+ (*pdata->dsp_prm_rmw_bits)(OMAP3430_RST1_IVA2_MASK,
+ OMAP3430_RST1_IVA2_MASK, OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);
+
/* Disable the mailbox interrupts */
if (dev_context->mbox) {
omap_mbox_disable_irq(dev_context->mbox, IRQ_RX);
omap_mbox_put(dev_context->mbox, &dsp_mbox_notifier);
dev_context->mbox = NULL;
}
- /* Reset IVA2 clocks*/
- (*pdata->dsp_prm_write)(OMAP3430_RST1_IVA2_MASK | OMAP3430_RST2_IVA2_MASK |
- OMAP3430_RST3_IVA2_MASK, OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);
+
+ if (dev_context->dsp_mmu) {
+ i = 0;
+ while (l4_peripheral_table[i].phys_addr) {
+ iommu_kunmap(dev_context->dsp_mmu,
+ l4_peripheral_table[i].dsp_virt_addr);
+ i++;
+ }
+
+ for (i = 0; i < BRDIOCTL_NUMOFMMUTLB; i++) {
+ if (!tlb[i].gpp_pa)
+ continue;
+ iommu_kunmap(dev_context->dsp_mmu, tlb[i].gpp_va);
+ }
+
+ iommu_kunmap(dev_context->dsp_mmu, dev_context->sh_s.seg1_da);
+ iommu_kunmap(dev_context->dsp_mmu, dev_context->sh_s.seg0_da);
+ iommu_put(dev_context->dsp_mmu);
+ dev_context->dsp_mmu = NULL;
+ }
+
+ /* Reset IVA IOMMU */
+ (*pdata->dsp_prm_rmw_bits)(OMAP3430_RST2_IVA2_MASK,
+ OMAP3430_RST2_IVA2_MASK, OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);

dsp_clock_disable_all(dev_context->dsp_per_clks);
dsp_clk_disable(DSP_CLK_IVA2);
@@ -1130,217 +1185,82 @@ static int bridge_brd_mem_write(struct bridge_dev_context *dev_ctxt,
*
* TODO: Disable MMU while updating the page tables (but that'll stall DSP)
*/
-static int bridge_brd_mem_map(struct bridge_dev_context *dev_ctxt,
- u32 ul_mpu_addr, u32 virt_addr,
- u32 ul_num_bytes, u32 ul_map_attr,
- struct page **mapped_pages)
+static int bridge_brd_mem_map(struct bridge_dev_context *dev_ctx,
+ u32 uva, u32 da, u32 size, struct page **usr_pgs)
+
{
- u32 attrs;
- int status = 0;
- struct bridge_dev_context *dev_context = dev_ctxt;
- struct hw_mmu_map_attrs_t hw_attrs;
+ int res, w;
+ unsigned pages, i;
+ struct iommu *mmu = dev_ctx->dsp_mmu;
struct vm_area_struct *vma;
struct mm_struct *mm = current->mm;
- u32 write = 0;
- u32 num_usr_pgs = 0;
- struct page *mapped_page, *pg;
- s32 pg_num;
- u32 va = virt_addr;
- struct task_struct *curr_task = current;
- u32 pg_i = 0;
- u32 mpu_addr, pa;
-
- dev_dbg(bridge,
- "%s hDevCtxt %p, pa %x, va %x, size %x, ul_map_attr %x\n",
- __func__, dev_ctxt, ul_mpu_addr, virt_addr, ul_num_bytes,
- ul_map_attr);
- if (ul_num_bytes == 0)
- return -EINVAL;
+ struct sg_table *sgt;
+ struct scatterlist *sg;

- if (ul_map_attr & DSP_MAP_DIR_MASK) {
- attrs = ul_map_attr;
- } else {
- /* Assign default attributes */
- attrs = ul_map_attr | (DSP_MAPVIRTUALADDR | DSP_MAPELEMSIZE16);
- }
- /* Take mapping properties */
- if (attrs & DSP_MAPBIGENDIAN)
- hw_attrs.endianism = HW_BIG_ENDIAN;
- else
- hw_attrs.endianism = HW_LITTLE_ENDIAN;
-
- hw_attrs.mixed_size = (enum hw_mmu_mixed_size_t)
- ((attrs & DSP_MAPMIXEDELEMSIZE) >> 2);
- /* Ignore element_size if mixed_size is enabled */
- if (hw_attrs.mixed_size == 0) {
- if (attrs & DSP_MAPELEMSIZE8) {
- /* Size is 8 bit */
- hw_attrs.element_size = HW_ELEM_SIZE8BIT;
- } else if (attrs & DSP_MAPELEMSIZE16) {
- /* Size is 16 bit */
- hw_attrs.element_size = HW_ELEM_SIZE16BIT;
- } else if (attrs & DSP_MAPELEMSIZE32) {
- /* Size is 32 bit */
- hw_attrs.element_size = HW_ELEM_SIZE32BIT;
- } else if (attrs & DSP_MAPELEMSIZE64) {
- /* Size is 64 bit */
- hw_attrs.element_size = HW_ELEM_SIZE64BIT;
- } else {
- /*
- * Mixedsize isn't enabled, so size can't be
- * zero here
- */
- return -EINVAL;
- }
- }
- if (attrs & DSP_MAPDONOTLOCK)
- hw_attrs.donotlockmpupage = 1;
- else
- hw_attrs.donotlockmpupage = 0;
+ if (!size || !usr_pgs)
+ return -EINVAL;

- if (attrs & DSP_MAPVMALLOCADDR) {
- return mem_map_vmalloc(dev_ctxt, ul_mpu_addr, virt_addr,
- ul_num_bytes, &hw_attrs);
- }
- /*
- * Do OS-specific user-va to pa translation.
- * Combine physically contiguous regions to reduce TLBs.
- * Pass the translated pa to pte_update.
- */
- if ((attrs & DSP_MAPPHYSICALADDR)) {
- status = pte_update(dev_context, ul_mpu_addr, virt_addr,
- ul_num_bytes, &hw_attrs);
- goto func_cont;
- }
+ pages = size / PG_SIZE4K;

- /*
- * Important Note: ul_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, ul_mpu_addr);
- if (vma)
- dev_dbg(bridge,
- "VMAfor UserBuf: ul_mpu_addr=%x, ul_num_bytes=%x, "
- "vm_start=%lx, vm_end=%lx, vm_flags=%lx\n", ul_mpu_addr,
- ul_num_bytes, vma->vm_start, vma->vm_end,
- vma->vm_flags);
-
- /*
- * 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) && (ul_mpu_addr + ul_num_bytes > vma->vm_end)) {
- /* jump to the next VMA region */
+ vma = find_vma(mm, uva);
+ while (vma && (uva + size > vma->vm_end))
vma = find_vma(mm, vma->vm_end + 1);
- dev_dbg(bridge,
- "VMA for UserBuf ul_mpu_addr=%x ul_num_bytes=%x, "
- "vm_start=%lx, vm_end=%lx, vm_flags=%lx\n", ul_mpu_addr,
- ul_num_bytes, vma->vm_start, vma->vm_end,
- vma->vm_flags);
- }
+
if (!vma) {
pr_err("%s: Failed to get VMA region for 0x%x (%d)\n",
- __func__, ul_mpu_addr, ul_num_bytes);
- status = -EINVAL;
+ __func__, uva, size);
up_read(&mm->mmap_sem);
- goto func_cont;
+ return -EINVAL;
}
+ if (vma->vm_flags & (VM_WRITE | VM_MAYWRITE))
+ w = 1;

- if (vma->vm_flags & VM_IO) {
- num_usr_pgs = ul_num_bytes / PG_SIZE4K;
- mpu_addr = ul_mpu_addr;
-
- /* Get the physical addresses for user buffer */
- for (pg_i = 0; pg_i < num_usr_pgs; pg_i++) {
- pa = user_va2_pa(mm, mpu_addr);
- if (!pa) {
- status = -EPERM;
- 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(dev_context->pt_attrs, pa,
- va, HW_PAGE_SIZE4KB, &hw_attrs);
- if (status)
- break;
+ if (vma->vm_flags & VM_IO)
+ i = get_io_pages(mm, uva, pages, usr_pgs);
+ else
+ i = get_user_pages(current, mm, uva, pages, w, 1,
+ usr_pgs, NULL);
+ up_read(&mm->mmap_sem);

- va += HW_PAGE_SIZE4KB;
- mpu_addr += HW_PAGE_SIZE4KB;
- pa += HW_PAGE_SIZE4KB;
- }
- } else {
- num_usr_pgs = ul_num_bytes / PG_SIZE4K;
- if (vma->vm_flags & (VM_WRITE | VM_MAYWRITE))
- write = 1;
-
- for (pg_i = 0; pg_i < num_usr_pgs; pg_i++) {
- pg_num = get_user_pages(curr_task, mm, ul_mpu_addr, 1,
- write, 1, &mapped_page, NULL);
- if (pg_num > 0) {
- if (page_count(mapped_page) < 1) {
- pr_err("Bad page count after doing"
- "get_user_pages on"
- "user buffer\n");
- bad_page_dump(page_to_phys(mapped_page),
- mapped_page);
- }
- status = pte_set(dev_context->pt_attrs,
- page_to_phys(mapped_page), va,
- HW_PAGE_SIZE4KB, &hw_attrs);
- if (status)
- break;
-
- if (mapped_pages)
- mapped_pages[pg_i] = mapped_page;
-
- va += HW_PAGE_SIZE4KB;
- ul_mpu_addr += HW_PAGE_SIZE4KB;
- } 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", ul_mpu_addr,
- vma->vm_flags, pg_num, ul_num_bytes);
- status = -EPERM;
- break;
- }
- }
+ if (i < 0)
+ return i;
+
+ if (i < pages) {
+ res = -EFAULT;
+ goto err_pages;
}
- up_read(&mm->mmap_sem);
-func_cont:
- if (status) {
- /*
- * Roll out the mapped pages incase it failed in middle of
- * mapping
- */
- if (pg_i) {
- bridge_brd_mem_un_map(dev_context, virt_addr,
- (pg_i * PG_SIZE4K));
- }
- status = -EPERM;
+
+ sgt = kzalloc(sizeof(*sgt), GFP_KERNEL);
+ if (!sgt) {
+ res = -ENOMEM;
+ goto err_pages;
}
- /*
- * 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
- */
- flush_all(dev_context);
- dev_dbg(bridge, "%s status %x\n", __func__, status);
- return status;
+
+ res = sg_alloc_table(sgt, pages, GFP_KERNEL);
+
+ if (res < 0)
+ goto err_sg;
+
+ for_each_sg(sgt->sgl, sg, sgt->nents, i)
+ sg_set_page(sg, usr_pgs[i], PAGE_SIZE, 0);
+
+ wake_dsp(dev_ctx, NULL);
+
+ da = iommu_vmap(mmu, da, sgt, IOVMF_ENDIAN_LITTLE | IOVMF_ELSZ_32);
+
+ if (!IS_ERR_VALUE(da))
+ return da;
+ res = (int)da;
+
+ sg_free_table(sgt);
+err_sg:
+ kfree(sgt);
+ i = pages;
+err_pages:
+ while (i--)
+ put_page(usr_pgs[i]);
+ return res;
}

/*
@@ -1351,194 +1271,46 @@ func_cont:
* So, instead of looking up the PTE address for every 4K block,
* we clear consecutive PTEs until we unmap all the bytes
*/
-static int bridge_brd_mem_un_map(struct bridge_dev_context *dev_ctxt,
- u32 virt_addr, u32 ul_num_bytes)
+static int bridge_brd_mem_un_map(struct bridge_dev_context *dev_ctx, u32 da)
{
- 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 va_curr;
- struct page *pg = NULL;
- int status = 0;
- struct bridge_dev_context *dev_context = dev_ctxt;
- struct pg_table_attrs *pt = dev_context->pt_attrs;
- u32 temp;
- u32 paddr;
- u32 numof4k_pages = 0;
+ unsigned i;
+ struct sg_table *sgt;
+ struct scatterlist *sg;

- va_curr = virt_addr;
- rem_bytes = ul_num_bytes;
- rem_bytes_l2 = 0;
- l1_base_va = pt->l1_base_va;
- pte_addr_l1 = hw_mmu_pte_addr_l1(l1_base_va, va_curr);
- dev_dbg(bridge, "%s dev_ctxt %p, va %x, NumBytes %x l1_base_va %x, "
- "pte_addr_l1 %x\n", __func__, dev_ctxt, virt_addr,
- ul_num_bytes, l1_base_va, pte_addr_l1);
+ wake_dsp(dev_ctx, NULL);

- while (rem_bytes && !status) {
- u32 va_curr_orig = va_curr;
- /* Find whether the L1 PTE points to a valid L2 PT */
- pte_addr_l1 = hw_mmu_pte_addr_l1(l1_base_va, va_curr);
- pte_val = *(u32 *) pte_addr_l1;
- pte_size = hw_mmu_pte_size_l1(pte_val);
+ sgt = iommu_vunmap(dev_ctx->dsp_mmu, da);
+ if (!sgt)
+ return -EFAULT;

- if (pte_size != HW_MMU_COARSE_PAGE_SIZE)
- goto skip_coarse_page;
+ for_each_sg(sgt->sgl, sg, sgt->nents, i)
+ put_page(sg_page(sg));

- /*
- * Get the L2 PA from the L1 PTE, and find
- * corresponding L2 VA
- */
- l2_base_pa = hw_mmu_pte_coarse_l1(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;
- /*
- * 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, va_curr);
- 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 * PG_SIZE4K))
- pte_count = rem_bytes / PG_SIZE4K;
- rem_bytes_l2 = pte_count * PG_SIZE4K;
+ sg_free_table(sgt);
+ kfree(sgt);

- /*
- * 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 && !status) {
- pte_val = *(u32 *) pte_addr_l2;
- pte_size = hw_mmu_pte_size_l2(pte_val);
- /* va_curr aligned to pte_size? */
- if (pte_size == 0 || rem_bytes_l2 < pte_size ||
- va_curr & (pte_size - 1)) {
- status = -EPERM;
- break;
- }
+ return 0;
+}

- /* Collect Physical addresses from VA */
- paddr = (pte_val & ~(pte_size - 1));
- if (pte_size == HW_PAGE_SIZE64KB)
- numof4k_pages = 16;
- else
- numof4k_pages = 1;
- temp = 0;
- while (temp++ < numof4k_pages) {
- if (!pfn_valid(__phys_to_pfn(paddr))) {
- paddr += HW_PAGE_SIZE4KB;
- continue;
- }
- pg = PHYS_TO_PAGE(paddr);
- if (page_count(pg) < 1) {
- pr_info("DSPBRIDGE: UNMAP function: "
- "COUNT 0 FOR PA 0x%x, size = "
- "0x%x\n", paddr, ul_num_bytes);
- bad_page_dump(paddr, pg);
- } else {
- set_page_dirty(pg);
- page_cache_release(pg);
- }
- paddr += HW_PAGE_SIZE4KB;
- }
- if (hw_mmu_pte_clear(pte_addr_l2, va_curr, pte_size)) {
- status = -EPERM;
- goto EXIT_LOOP;
- }

- status = 0;
- rem_bytes_l2 -= pte_size;
- va_curr += pte_size;
- pte_addr_l2 += (pte_size >> 12) * sizeof(u32);
- }
- spin_lock(&pt->pg_lock);
- if (rem_bytes_l2 == 0) {
- pt->pg_info[l2_page_num].num_entries -= pte_count;
- if (pt->pg_info[l2_page_num].num_entries == 0) {
- /*
- * Clear the L1 PTE pointing to the L2 PT
- */
- if (!hw_mmu_pte_clear(l1_base_va, va_curr_orig,
- HW_MMU_COARSE_PAGE_SIZE))
- status = 0;
- else {
- status = -EPERM;
- spin_unlock(&pt->pg_lock);
- goto EXIT_LOOP;
- }
- }
- rem_bytes -= pte_count * PG_SIZE4K;
- } else
- status = -EPERM;
+static int get_io_pages(struct mm_struct *mm, u32 uva, unsigned pages,
+ struct page **usr_pgs)
+{
+ u32 pa;
+ int i;
+ struct page *pg;

- spin_unlock(&pt->pg_lock);
- continue;
-skip_coarse_page:
- /* va_curr aligned to pte_size? */
- /* pte_size = 1 MB or 16 MB */
- if (pte_size == 0 || rem_bytes < pte_size ||
- va_curr & (pte_size - 1)) {
- status = -EPERM;
+ for (i = 0; i < pages; i++) {
+ pa = user_va2_pa(mm, uva);
+
+ if (!pfn_valid(__phys_to_pfn(pa)))
break;
- }

- if (pte_size == HW_PAGE_SIZE1MB)
- numof4k_pages = 256;
- else
- numof4k_pages = 4096;
- temp = 0;
- /* Collect Physical addresses from VA */
- paddr = (pte_val & ~(pte_size - 1));
- while (temp++ < numof4k_pages) {
- if (pfn_valid(__phys_to_pfn(paddr))) {
- pg = PHYS_TO_PAGE(paddr);
- if (page_count(pg) < 1) {
- pr_info("DSPBRIDGE: UNMAP function: "
- "COUNT 0 FOR PA 0x%x, size = "
- "0x%x\n", paddr, ul_num_bytes);
- bad_page_dump(paddr, pg);
- } else {
- set_page_dirty(pg);
- page_cache_release(pg);
- }
- }
- paddr += HW_PAGE_SIZE4KB;
- }
- if (!hw_mmu_pte_clear(l1_base_va, va_curr, pte_size)) {
- status = 0;
- rem_bytes -= pte_size;
- va_curr += pte_size;
- } else {
- status = -EPERM;
- goto EXIT_LOOP;
- }
+ pg = PHYS_TO_PAGE(pa);
+ usr_pgs[i] = pg;
+ get_page(pg);
}
- /*
- * It is better to flush the TLB here, so that any stale old entries
- * get flushed
- */
-EXIT_LOOP:
- flush_all(dev_context);
- dev_dbg(bridge,
- "%s: va_curr %x, pte_addr_l1 %x pte_addr_l2 %x rem_bytes %x,"
- " rem_bytes_l2 %x status %x\n", __func__, va_curr, pte_addr_l1,
- pte_addr_l2, rem_bytes, rem_bytes_l2, status);
- return status;
+ return i;
}

/*
diff --git a/drivers/staging/tidspbridge/core/tiomap3430_pwr.c b/drivers/staging/tidspbridge/core/tiomap3430_pwr.c
index fdbf4eb..0d6bc4f 100644
--- a/drivers/staging/tidspbridge/core/tiomap3430_pwr.c
+++ b/drivers/staging/tidspbridge/core/tiomap3430_pwr.c
@@ -333,7 +333,7 @@ int wake_dsp(struct bridge_dev_context *dev_context, void *pargs)
omap_mbox_restore_ctx(dev_context->mbox);

/* Access MMU SYS CONFIG register to generate a short wakeup */
- readl(resources->dmmu_base + 0x10);
+ iommu_read_reg(dev_context->dsp_mmu, MMU_SYSCONFIG);

dev_context->brd_state = BRD_RUNNING;

diff --git a/drivers/staging/tidspbridge/core/tiomap_io.c b/drivers/staging/tidspbridge/core/tiomap_io.c
index ff350e5..ab221f1 100644
--- a/drivers/staging/tidspbridge/core/tiomap_io.c
+++ b/drivers/staging/tidspbridge/core/tiomap_io.c
@@ -134,10 +134,9 @@ int read_ext_dsp_data(struct bridge_dev_context *dev_ctxt,

if (!status) {
ul_tlb_base_virt =
- dev_context->atlb_entry[0].dsp_va * DSPWORDSIZE;
+ dev_context->sh_s.seg0_da * DSPWORDSIZE;
DBC_ASSERT(ul_tlb_base_virt <= ul_shm_base_virt);
- dw_ext_prog_virt_mem =
- dev_context->atlb_entry[0].gpp_va;
+ dw_ext_prog_virt_mem = dev_context->sh_s.seg0_va;

if (!trace_read) {
ul_shm_offset_virt =
@@ -318,8 +317,9 @@ int write_ext_dsp_data(struct bridge_dev_context *dev_context,
ret = -EPERM;

if (!ret) {
- ul_tlb_base_virt =
- dev_context->atlb_entry[0].dsp_va * DSPWORDSIZE;
+ ul_tlb_base_virt = dev_context->sh_s.seg0_da *
+ DSPWORDSIZE;
+
DBC_ASSERT(ul_tlb_base_virt <= ul_shm_base_virt);

if (symbols_reloaded) {
@@ -337,7 +337,7 @@ int write_ext_dsp_data(struct bridge_dev_context *dev_context,
ul_shm_base_virt - ul_tlb_base_virt;
if (trace_load) {
dw_ext_prog_virt_mem =
- dev_context->atlb_entry[0].gpp_va;
+ dev_context->sh_s.seg0_va;
} else {
dw_ext_prog_virt_mem = host_res->mem_base[1];
dw_ext_prog_virt_mem +=
diff --git a/drivers/staging/tidspbridge/core/ue_deh.c b/drivers/staging/tidspbridge/core/ue_deh.c
index 006ffd7..317e7f6 100644
--- a/drivers/staging/tidspbridge/core/ue_deh.c
+++ b/drivers/staging/tidspbridge/core/ue_deh.c
@@ -31,7 +31,7 @@
#include <dspbridge/drv.h>
#include <dspbridge/wdt.h>

-static u32 fault_addr;
+#define MMU_CNTL_TWL_EN (1 << 2)

static void mmu_fault_dpc(unsigned long data)
{
@@ -43,43 +43,19 @@ static void mmu_fault_dpc(unsigned long data)
bridge_deh_notify(deh, DSP_MMUFAULT, 0);
}

-static irqreturn_t mmu_fault_isr(int irq, void *data)
+int mmu_fault_isr(struct iommu *mmu, u32 da, u32 iommu_errs, void *priv)
{
- struct deh_mgr *deh = data;
- struct cfg_hostres *resources;
- u32 event;
+ struct deh_mgr *deh;
+
+ dev_get_deh_mgr(dev_get_first(), &deh);

if (!deh)
- return IRQ_HANDLED;
+ return -EPERM;

- resources = deh->bridge_context->resources;
- if (!resources) {
- dev_dbg(bridge, "%s: Failed to get Host Resources\n",
- __func__);
- return IRQ_HANDLED;
- }
+ iommu_write_reg(mmu, 0, MMU_IRQENABLE);
+ tasklet_schedule(&deh->dpc_tasklet);

- hw_mmu_event_status(resources->dmmu_base, &event);
- if (event == HW_MMU_TRANSLATION_FAULT) {
- hw_mmu_fault_addr_read(resources->dmmu_base, &fault_addr);
- dev_dbg(bridge, "%s: event=0x%x, fault_addr=0x%x\n", __func__,
- event, fault_addr);
- /*
- * Schedule a DPC directly. In the future, it may be
- * necessary to check if DSP MMU fault is intended for
- * Bridge.
- */
- tasklet_schedule(&deh->dpc_tasklet);
-
- /* Disable the MMU events, else once we clear it will
- * start to raise INTs again */
- hw_mmu_event_disable(resources->dmmu_base,
- HW_MMU_TRANSLATION_FAULT);
- } else {
- hw_mmu_event_disable(resources->dmmu_base,
- HW_MMU_ALL_INTERRUPTS);
- }
- return IRQ_HANDLED;
+ return 0;
}

int bridge_deh_create(struct deh_mgr **ret_deh,
@@ -115,12 +91,6 @@ int bridge_deh_create(struct deh_mgr **ret_deh,
/* Fill in context structure */
deh->bridge_context = hbridge_context;

- /* Install ISR function for DSP MMU fault */
- status = request_irq(INT_DSP_MMU_IRQ, mmu_fault_isr, 0,
- "DspBridge\tiommu fault", deh);
- if (status < 0)
- goto err;
-
*ret_deh = deh;
return 0;

@@ -140,8 +110,6 @@ int bridge_deh_destroy(struct deh_mgr *deh)
ntfy_delete(deh->ntfy_obj);
kfree(deh->ntfy_obj);
}
- /* Disable DSP MMU fault */
- free_irq(INT_DSP_MMU_IRQ, deh);

/* Free DPC object */
tasklet_kill(&deh->dpc_tasklet);
@@ -169,42 +137,45 @@ int bridge_deh_register_notify(struct deh_mgr *deh, u32 event_mask,
#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
static void mmu_fault_print_stack(struct bridge_dev_context *dev_context)
{
- struct cfg_hostres *resources;
- struct hw_mmu_map_attrs_t map_attrs = {
- .endianism = HW_LITTLE_ENDIAN,
- .element_size = HW_ELEM_SIZE16BIT,
- .mixed_size = HW_MMU_CPUES,
- };
- void *dummy_va_addr;
-
- resources = dev_context->resources;
- dummy_va_addr = (void*)__get_free_page(GFP_ATOMIC);
+ void *dummy_addr;
+ u32 fa, tmp;
+ struct iotlb_entry e;
+ struct iommu *mmu = dev_context->dsp_mmu;
+ dummy_addr = (void *)__get_free_page(GFP_ATOMIC);

/*
* Before acking the MMU fault, let's make sure MMU can only
* access entry #0. Then add a new entry so that the DSP OS
* can continue in order to dump the stack.
*/
- hw_mmu_twl_disable(resources->dmmu_base);
- hw_mmu_tlb_flush_all(resources->dmmu_base);
-
- hw_mmu_tlb_add(resources->dmmu_base,
- virt_to_phys(dummy_va_addr), fault_addr,
- HW_PAGE_SIZE4KB, 1,
- &map_attrs, HW_SET, HW_SET);
+ tmp = iommu_read_reg(mmu, MMU_CNTL);
+ tmp &= ~MMU_CNTL_TWL_EN;
+ iommu_write_reg(mmu, tmp, MMU_CNTL);
+ fa = iommu_read_reg(mmu, MMU_FAULT_AD);
+ e.da = fa & PAGE_MASK;
+ e.pa = virt_to_phys(dummy_addr);
+ e.valid = 1;
+ e.prsvd = 1;
+ e.pgsz = IOVMF_PGSZ_4K & MMU_CAM_PGSZ_MASK;
+ e.endian = MMU_RAM_ENDIAN_LITTLE;
+ e.elsz = MMU_RAM_ELSZ_32;
+ e.mixed = 0;
+
+ load_iotlb_entry(dev_context->dsp_mmu, &e);

dsp_clk_enable(DSP_CLK_GPT8);

dsp_gpt_wait_overflow(DSP_CLK_GPT8, 0xfffffffe);

/* Clear MMU interrupt */
- hw_mmu_event_ack(resources->dmmu_base,
- HW_MMU_TRANSLATION_FAULT);
+ tmp = iommu_read_reg(mmu, MMU_IRQSTATUS);
+ iommu_write_reg(mmu, tmp, MMU_IRQSTATUS);
+
dump_dsp_stack(dev_context);
dsp_clk_disable(DSP_CLK_GPT8);

- hw_mmu_disable(resources->dmmu_base);
- free_page((unsigned long)dummy_va_addr);
+ iopgtable_clear_entry(mmu, fa);
+ free_page((unsigned long)dummy_addr);
}
#endif

@@ -223,6 +194,7 @@ void bridge_deh_notify(struct deh_mgr *deh, int event, int info)
{
struct bridge_dev_context *dev_context;
const char *str = event_to_string(event);
+ u32 fa;

if (!deh)
return;
@@ -240,8 +212,8 @@ void bridge_deh_notify(struct deh_mgr *deh, int event, int info)
#endif
break;
case DSP_MMUFAULT:
- dev_err(bridge, "%s: %s, addr=0x%x", __func__,
- str, fault_addr);
+ fa = iommu_read_reg(dev_context->dsp_mmu, MMU_FAULT_AD);
+ dev_err(bridge, "%s: %s, addr=0x%x", __func__, str, fa);
#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
print_dsp_trace_buffer(dev_context);
dump_dl_modules(dev_context);
diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h b/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h
index ed32bf3..48f91c9 100644
--- a/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h
+++ b/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h
@@ -175,7 +175,6 @@ typedef int(*fxn_brd_memwrite) (struct bridge_dev_context
typedef int(*fxn_brd_memmap) (struct bridge_dev_context
* dev_ctxt, u32 ul_mpu_addr,
u32 virt_addr, u32 ul_num_bytes,
- u32 map_attr,
struct page **mapped_pages);

/*
@@ -195,7 +194,7 @@ typedef int(*fxn_brd_memmap) (struct bridge_dev_context
*/
typedef int(*fxn_brd_memunmap) (struct bridge_dev_context
* dev_ctxt,
- u32 virt_addr, u32 ul_num_bytes);
+ u32 da);

/*
* ======== bridge_brd_stop ========
diff --git a/drivers/staging/tidspbridge/rmgr/proc.c b/drivers/staging/tidspbridge/rmgr/proc.c
index 214dff8..9049df8 100644
--- a/drivers/staging/tidspbridge/rmgr/proc.c
+++ b/drivers/staging/tidspbridge/rmgr/proc.c
@@ -1393,7 +1393,6 @@ int proc_map(void *hprocessor, void *pmpu_addr, u32 ul_size,
int status = 0;
struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
struct dmm_map_object *map_obj;
- u32 tmp_addr = 0;

#ifdef CONFIG_TIDSPBRIDGE_CACHE_LINE_CHECK
if ((ul_map_attr & BUFMODE_MASK) != RBUF) {
@@ -1419,32 +1418,31 @@ int proc_map(void *hprocessor, void *pmpu_addr, u32 ul_size,
/* Critical section */
mutex_lock(&proc_lock);
dmm_get_handle(p_proc_object, &dmm_mgr);
- if (dmm_mgr)
- status = dmm_map_memory(dmm_mgr, va_align, size_align);
- else
+ if (!dmm_mgr)
status = -EFAULT;

/* Add mapping to the page tables. */
if (!status) {
-
- /* Mapped address = MSB of VA | LSB of PA */
- tmp_addr = (va_align | ((u32) pmpu_addr & (PG_SIZE4K - 1)));
/* mapped memory resource tracking */
- map_obj = add_mapping_info(pr_ctxt, pa_align, tmp_addr,
+ map_obj = add_mapping_info(pr_ctxt, pa_align, va_align,
size_align);
- if (!map_obj)
+ if (!map_obj) {
status = -ENOMEM;
- else
- status = (*p_proc_object->intf_fxns->brd_mem_map)
- (p_proc_object->bridge_context, pa_align, va_align,
- size_align, ul_map_attr, map_obj->pages);
+ } else {
+ va_align = (*p_proc_object->intf_fxns->brd_mem_map)
+ (p_proc_object->bridge_context, pa_align, 0,
+ size_align, map_obj->pages);
+ if (IS_ERR_VALUE(va_align))
+ status = va_align;
+ }
}
if (!status) {
/* Mapped address = MSB of VA | LSB of PA */
- *pp_map_addr = (void *) tmp_addr;
+ map_obj->dsp_addr =
+ (va_align | ((u32)pmpu_addr & (PG_SIZE4K - 1)));
+ *pp_map_addr = (void *)map_obj->dsp_addr;
} else {
- remove_mapping_information(pr_ctxt, tmp_addr, size_align);
- dmm_un_map_memory(dmm_mgr, va_align, &size_align);
+ remove_mapping_information(pr_ctxt, va_align, size_align);
}
mutex_unlock(&proc_lock);

@@ -1545,39 +1543,14 @@ int proc_reserve_memory(void *hprocessor, u32 ul_size,
void **pp_rsv_addr,
struct process_context *pr_ctxt)
{
- struct dmm_object *dmm_mgr;
int status = 0;
struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
- struct dmm_rsv_object *rsv_obj;

if (!p_proc_object) {
status = -EFAULT;
goto func_end;
}

- status = dmm_get_handle(p_proc_object, &dmm_mgr);
- if (!dmm_mgr) {
- status = -EFAULT;
- goto func_end;
- }
-
- status = dmm_reserve_memory(dmm_mgr, ul_size, (u32 *) pp_rsv_addr);
- if (status != 0)
- goto func_end;
-
- /*
- * A successful reserve should be followed by insertion of rsv_obj
- * into dmm_rsv_list, so that reserved memory resource tracking
- * remains uptodate
- */
- rsv_obj = kmalloc(sizeof(struct dmm_rsv_object), GFP_KERNEL);
- if (rsv_obj) {
- rsv_obj->dsp_reserved_addr = (u32) *pp_rsv_addr;
- spin_lock(&pr_ctxt->dmm_rsv_lock);
- list_add(&rsv_obj->link, &pr_ctxt->dmm_rsv_list);
- spin_unlock(&pr_ctxt->dmm_rsv_lock);
- }
-
func_end:
dev_dbg(bridge, "%s: hprocessor: 0x%p ul_size: 0x%x pp_rsv_addr: 0x%p "
"status 0x%x\n", __func__, hprocessor,
@@ -1736,7 +1709,6 @@ int proc_un_map(void *hprocessor, void *map_addr,
struct dmm_object *dmm_mgr;
struct dmm_map_object *dmo;
u32 va_align;
- u32 size_align;

va_align = PG_ALIGN_LOW((u32) map_addr, PG_SIZE4K);
if (!p_proc_object) {
@@ -1752,22 +1724,14 @@ int proc_un_map(void *hprocessor, void *map_addr,

/* Critical section */
mutex_lock(&proc_lock);
- /*
- * Update DMM structures. Get the size to unmap.
- * This function returns error if the VA is not mapped
- */
- status = dmm_un_map_memory(dmm_mgr, (u32) va_align, &size_align);

dmo = find_containing_mapping_da(pr_ctxt, (u32)map_addr);
if (!dmo)
goto unmap_failed;

/* Remove mapping from the page tables. */
- if (!status) {
- status = (*p_proc_object->intf_fxns->brd_mem_un_map)
- (p_proc_object->bridge_context, va_align, dmo->size);
- }
-
+ status = (*p_proc_object->intf_fxns->brd_mem_un_map)
+ (p_proc_object->bridge_context, va_align);
if (status)
goto unmap_failed;

@@ -1795,41 +1759,14 @@ func_end:
int proc_un_reserve_memory(void *hprocessor, void *prsv_addr,
struct process_context *pr_ctxt)
{
- struct dmm_object *dmm_mgr;
int status = 0;
struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
- struct dmm_rsv_object *rsv_obj;

if (!p_proc_object) {
status = -EFAULT;
goto func_end;
}

- status = dmm_get_handle(p_proc_object, &dmm_mgr);
- if (!dmm_mgr) {
- status = -EFAULT;
- goto func_end;
- }
-
- status = dmm_un_reserve_memory(dmm_mgr, (u32) prsv_addr);
- if (status != 0)
- goto func_end;
-
- /*
- * A successful unreserve should be followed by removal of rsv_obj
- * from dmm_rsv_list, so that reserved memory resource tracking
- * remains uptodate
- */
- spin_lock(&pr_ctxt->dmm_rsv_lock);
- list_for_each_entry(rsv_obj, &pr_ctxt->dmm_rsv_list, link) {
- if (rsv_obj->dsp_reserved_addr == (u32) prsv_addr) {
- list_del(&rsv_obj->link);
- kfree(rsv_obj);
- break;
- }
- }
- spin_unlock(&pr_ctxt->dmm_rsv_lock);
-
func_end:
dev_dbg(bridge, "%s: hprocessor: 0x%p prsv_addr: 0x%p status: 0x%x\n",
__func__, hprocessor, prsv_addr, status);
--
1.7.1

2011-05-03 17:58:07

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH v4 0/6] staging tidspbridge: iommu migration

On Thu, Apr 28, 2011 at 10:31:46AM -0500, Omar Ramirez Luna wrote:
> DO-NOT-APPLY to staging yet.

Then don't send them to me :)

Seriously, why are you sending this with me as the "To:" if you don't
want me to do something with them? If you want others to review them,
fine, but put their names in the "To:" line, not me.

I really don't care about this driver at all, sorry.

greg k-h

2011-05-03 20:18:44

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH v4 0/6] staging tidspbridge: iommu migration

On Thursday 28 April 2011 17:31:46 Omar Ramirez Luna wrote:
> Rework and rebase of the previous set of patches for iommu migration[1].
>
> Reorganized the patches to avoid several iterations to change the same code.
>
> Patches were tested with an OMAP3630 board, with both, basic samples and
> gst-dsp; these are dependant on patch:
> "OMAP: iovmm: fix SW flags passed by user"[2].

The code removal in this series looks good, but the move from
one proprietary iommu API to another proprietary iommu API
seems pointless.

It would be much more helpful if you could convert the tidspbridge
code to the dma-mapping API, or to the generic iommu API
and provide these interfaces from the omap code.

Arnd

2011-05-03 20:34:32

by Ramirez Luna, Omar

[permalink] [raw]
Subject: Re: [PATCH v4 0/6] staging tidspbridge: iommu migration

On Tue, May 3, 2011 at 12:55 PM, Greg KH <[email protected]> wrote:
> On Thu, Apr 28, 2011 at 10:31:46AM -0500, Omar Ramirez Luna wrote:
>> DO-NOT-APPLY to staging yet.
>
> Then don't send them to me :)

Not a problem.

Thanks,

Omar

2011-05-03 20:48:12

by Ramirez Luna, Omar

[permalink] [raw]
Subject: Re: [PATCH v4 0/6] staging tidspbridge: iommu migration

Hi Arnd,

On Tue, May 3, 2011 at 3:18 PM, Arnd Bergmann <[email protected]> wrote:
> On Thursday 28 April 2011 17:31:46 Omar Ramirez Luna wrote:
>> Rework and rebase of the previous set of patches for iommu migration[1].
>>
>> Reorganized the patches to avoid several iterations to change the same code.
>>
>> Patches were tested with an OMAP3630 board, with both, basic samples and
>> gst-dsp; these are dependant on patch:
>> ? ? ? ? "OMAP: iovmm: fix SW flags passed by user"[2].
>
> The code removal in this series looks good, but the move from
> one proprietary iommu API to another proprietary iommu API
> seems pointless.
>
> It would be much more helpful if you could convert the tidspbridge
> code to the dma-mapping API, or to the generic iommu API
> and provide these interfaces from the omap code.

Yes, I thought removing a bunch of lines from staging might be good.
I'll check what can be done to use generic iommu or dma-mapping.

Thanks,

Omar

2011-05-04 13:01:25

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH v4 0/6] staging tidspbridge: iommu migration

On Tuesday 03 May 2011, Ramirez Luna, Omar wrote:
> >
> > The code removal in this series looks good, but the move from
> > one proprietary iommu API to another proprietary iommu API
> > seems pointless.
> >
> > It would be much more helpful if you could convert the tidspbridge
> > code to the dma-mapping API, or to the generic iommu API
> > and provide these interfaces from the omap code.
>
> Yes, I thought removing a bunch of lines from staging might be good.
> I'll check what can be done to use generic iommu or dma-mapping.

Ok, excellent. Have you seen the recent discussions on the
[email protected] mailing lists? We've been
thinking about how it should be done there, and will continue
the discussions in the upcoming Linaro@UDS meeting in Budapest
next week.

Arnd