blob: 6965b4da6c0a3b47a40e35040375931a336cb08c [file] [log] [blame] [edit]
/*
* omap iommu: omap device registration
*
* Copyright (C) 2008-2009 Nokia Corporation
*
* Written by Hiroshi DOYU <[email protected]>
*
* This program 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.
*/
#include <linux/platform_device.h>
#include <linux/err.h>
#include <plat/iommu.h>
#include <plat/omap_device.h>
#include <plat/omap_hwmod.h>
struct iommu_device {
resource_size_t base;
int irq;
struct iommu_platform_data pdata;
struct resource res[2];
};
static struct iommu_platform_data *devices_data;
static int num_iommu_devices;
#ifdef CONFIG_ARCH_OMAP3
static struct iommu_platform_data omap3_devices_data[] = {
{
.name = "isp",
.oh_name = "isp",
.nr_tlb_entries = 8,
.da_start = 0x0,
.da_end = 0xFFFFF000,
},
#if defined(CONFIG_OMAP_IOMMU_IVA2)
{
.name = "iva2",
.oh_name = "dsp",
.nr_tlb_entries = 32,
.da_start = 0x11000000,
.da_end = 0xFFFFF000,
},
#endif
};
#define NR_OMAP3_IOMMU_DEVICES ARRAY_SIZE(omap3_devices_data)
#else
#define omap3_devices_data NULL
#define NR_OMAP3_IOMMU_DEVICES 0
#endif
#ifdef CONFIG_ARCH_OMAP4
static struct iommu_platform_data omap4_devices_data[] = {
{
.name = "ducati",
.oh_name = "ipu",
.nr_tlb_entries = 32,
.da_start = 0x0,
.da_end = 0xFFFFF000,
},
{
.name = "tesla",
.oh_name = "dsp",
.nr_tlb_entries = 32,
.da_start = 0x0,
.da_end = 0xFFFFF000,
},
};
#define NR_OMAP4_IOMMU_DEVICES ARRAY_SIZE(omap4_devices_data)
#else
#define omap4_devices_data NULL
#define NR_OMAP4_IOMMU_DEVICES 0
#endif
static struct omap_device_pm_latency omap_iommu_latency[] = {
[0] = {
.deactivate_func = omap_device_idle_hwmods,
.activate_func = omap_device_enable_hwmods,
.flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
},
};
int iommu_get_plat_data_size(void)
{
return num_iommu_devices;
}
EXPORT_SYMBOL(iommu_get_plat_data_size);
struct iommu_platform_data *iommu_get_device_data(void)
{
return devices_data;
}
static int __init omap_iommu_init(void)
{
int i, ohl_cnt;
struct omap_hwmod *oh;
struct omap_device *od;
struct omap_device_pm_latency *ohl;
if (cpu_is_omap34xx()) {
devices_data = omap3_devices_data;
num_iommu_devices = NR_OMAP3_IOMMU_DEVICES;
} else if (cpu_is_omap44xx()) {
devices_data = omap4_devices_data;
num_iommu_devices = NR_OMAP4_IOMMU_DEVICES;
} else
return -ENODEV;
ohl = omap_iommu_latency;
ohl_cnt = ARRAY_SIZE(omap_iommu_latency);
for (i = 0; i < num_iommu_devices; i++) {
struct iommu_platform_data *data = &devices_data[i];
oh = omap_hwmod_lookup(data->oh_name);
data->io_base = oh->_mpu_rt_va;
data->irq = oh->mpu_irqs[0].irq;
if (!oh) {
pr_err("%s: could not look up %s\n", __func__,
data->oh_name);
continue;
}
od = omap_device_build("omap-iommu", i, oh,
data, sizeof(*data),
ohl, ohl_cnt, false);
WARN(IS_ERR(od), "Could not build omap_device"
"for %s %s\n", "omap-iommu", data->oh_name);
}
return 0;
}
module_init(omap_iommu_init);
MODULE_AUTHOR("Hiroshi DOYU");
MODULE_AUTHOR("Hari Kanigeri");
MODULE_DESCRIPTION("omap iommu: omap device registration");
MODULE_LICENSE("GPL v2");