aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorSubramaniam C.A <subramaniam.ca@ti.com>2012-04-13 11:38:41 -0500
committerDmytro Kedrovskyi <x0169235@ti.com>2012-04-18 19:25:00 +0300
commit2423ae215b246a08d83d7e78038e7f78d60d31a7 (patch)
treea116fdf7ddb84917811da6c5a8d2b392ef1ca9f9 /arch
parentc64178afc3f69498b04896fe6d3b811245f474c8 (diff)
downloadkernel_samsung_espresso10-2423ae215b246a08d83d7e78038e7f78d60d31a7.zip
kernel_samsung_espresso10-2423ae215b246a08d83d7e78038e7f78d60d31a7.tar.gz
kernel_samsung_espresso10-2423ae215b246a08d83d7e78038e7f78d60d31a7.tar.bz2
omap: iommu: program constraints based on platform data
IOMMU driver requests and releases constraints in iommu_get and iommu_put respectively. These constraints are actually needed only on OMAP4 and beyond for sub-systems that have an AMMU. The current driver code has these values hard-coded for all the chips. A new platform data field has been added now for the constraints values, and this allows the values to be programmed based on the OMAP chip and also allow a unique value if needed for each iommu instance. The logic in IOMMU driver code is adjusted to request the constraints only if the relevant platform data field is set. Change-Id: Iab18cbdde1d7fa7507dbff0b9512c8577b42fefd Signed-off-by: Subramaniam C.A <subramaniam.ca@ti.com> Signed-off-by: Suman Anna <s-anna@ti.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-omap2/omap-iommu.c6
-rw-r--r--arch/arm/plat-omap/include/plat/iommu.h2
-rw-r--r--arch/arm/plat-omap/iommu.c32
3 files changed, 25 insertions, 15 deletions
diff --git a/arch/arm/mach-omap2/omap-iommu.c b/arch/arm/mach-omap2/omap-iommu.c
index 6965b4d..cbab709 100644
--- a/arch/arm/mach-omap2/omap-iommu.c
+++ b/arch/arm/mach-omap2/omap-iommu.c
@@ -53,6 +53,10 @@ static struct iommu_platform_data omap3_devices_data[] = {
#endif
#ifdef CONFIG_ARCH_OMAP4
+
+#define SET_DSP_CONSTRAINT 10
+#define SET_MPU_CORE_CONSTRAINT 10
+
static struct iommu_platform_data omap4_devices_data[] = {
{
.name = "ducati",
@@ -60,6 +64,7 @@ static struct iommu_platform_data omap4_devices_data[] = {
.nr_tlb_entries = 32,
.da_start = 0x0,
.da_end = 0xFFFFF000,
+ .pm_constraint = SET_MPU_CORE_CONSTRAINT,
},
{
.name = "tesla",
@@ -67,6 +72,7 @@ static struct iommu_platform_data omap4_devices_data[] = {
.nr_tlb_entries = 32,
.da_start = 0x0,
.da_end = 0xFFFFF000,
+ .pm_constraint = SET_DSP_CONSTRAINT,
},
};
#define NR_OMAP4_IOMMU_DEVICES ARRAY_SIZE(omap4_devices_data)
diff --git a/arch/arm/plat-omap/include/plat/iommu.h b/arch/arm/plat-omap/include/plat/iommu.h
index ed33ddf..59bc69c 100644
--- a/arch/arm/plat-omap/include/plat/iommu.h
+++ b/arch/arm/plat-omap/include/plat/iommu.h
@@ -56,6 +56,7 @@ struct iommu {
u32 da_end;
struct platform_device *pdev;
struct pm_qos_request_list *qos_request;
+ unsigned int pm_constraint;
void *secure_ttb;
bool secure_mode;
};
@@ -114,6 +115,7 @@ struct iommu_platform_data {
u32 da_start;
u32 da_end;
int irq;
+ unsigned int pm_constraint;
void __iomem *io_base;
};
diff --git a/arch/arm/plat-omap/iommu.c b/arch/arm/plat-omap/iommu.c
index f82db49..b3c575c 100644
--- a/arch/arm/plat-omap/iommu.c
+++ b/arch/arm/plat-omap/iommu.c
@@ -31,10 +31,6 @@
(__i < (n)) && (cr = __iotlb_read_cr((obj), __i), true); \
__i++)
-#define SET_MPU_CORE_CONSTRAINT 10
-#define SET_DSP_CONSTRAINT 10
-#define CLEAR_CONSTRAINT -1
-
/* accommodate the difference between omap1 and omap2/3 */
static const struct iommu_functions *arch_iommu;
@@ -857,13 +853,13 @@ static void _set_latency_cstr(struct iommu *obj, bool set)
{
int val;
- if (!strcmp(obj->name, "ducati")) {
- val = set ? SET_MPU_CORE_CONSTRAINT : CLEAR_CONSTRAINT;
+ val = set ? obj->pm_constraint : PM_QOS_DEFAULT_VALUE;
+ if (!strcmp(obj->name, "ducati"))
pm_qos_update_request(obj->qos_request, val);
- } else if (!strcmp(obj->name, "tesla")) {
- val = set ? SET_DSP_CONSTRAINT : CLEAR_CONSTRAINT;
- omap_pm_set_max_dev_wakeup_lat(obj->dev, obj->dev, val);
- }
+ else if (!strcmp(obj->name, "tesla"))
+ omap_pm_set_max_dev_wakeup_lat(obj->dev,
+ obj->dev, val);
+
return;
}
@@ -887,12 +883,13 @@ struct iommu *iommu_get(const char *name)
mutex_lock(&obj->iommu_lock);
if (obj->refcount++ == 0) {
- _set_latency_cstr(obj, true);
+ if (obj->pm_constraint)
+ _set_latency_cstr(obj, true);
+
err = iommu_enable(obj);
- if (err) {
- _set_latency_cstr(obj, false);
+ if (err)
goto err_enable;
- }
+
flush_iotlb_all(obj);
}
@@ -908,6 +905,9 @@ err_module:
if (obj->refcount == 1)
iommu_disable(obj);
err_enable:
+ if (obj->pm_constraint)
+ _set_latency_cstr(obj, false);
+
obj->refcount--;
mutex_unlock(&obj->iommu_lock);
return ERR_PTR(err);
@@ -933,7 +933,8 @@ void iommu_put(struct iommu *obj)
if (--obj->refcount == 0) {
iommu_disable(obj);
- _set_latency_cstr(obj, false);
+ if (obj->pm_constraint)
+ _set_latency_cstr(obj, false);
}
module_put(obj->owner);
@@ -1016,6 +1017,7 @@ static int __devinit omap_iommu_probe(struct platform_device *pdev)
obj->ctx = (void *)obj + sizeof(*obj);
obj->da_start = pdata->da_start;
obj->da_end = pdata->da_end;
+ obj->pm_constraint = pdata->pm_constraint;
mutex_init(&obj->iommu_lock);
mutex_init(&obj->mmap_lock);