diff options
author | Subramaniam C.A <subramaniam.ca@ti.com> | 2012-04-13 11:38:41 -0500 |
---|---|---|
committer | Dmytro Kedrovskyi <x0169235@ti.com> | 2012-04-18 19:25:00 +0300 |
commit | 2423ae215b246a08d83d7e78038e7f78d60d31a7 (patch) | |
tree | a116fdf7ddb84917811da6c5a8d2b392ef1ca9f9 /arch | |
parent | c64178afc3f69498b04896fe6d3b811245f474c8 (diff) | |
download | kernel_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.c | 6 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/iommu.h | 2 | ||||
-rw-r--r-- | arch/arm/plat-omap/iommu.c | 32 |
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); |