omap-iommu.c 3.7 KB
Newer Older
1
/*
2
 * omap iommu: omap device registration
3 4 5 6 7 8 9 10 11 12
 *
 * Copyright (C) 2008-2009 Nokia Corporation
 *
 * Written by Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
 *
 * 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.
 */

13
#include <linux/module.h>
14 15
#include <linux/platform_device.h>

16
#include <linux/platform_data/iommu-omap.h>
17 18 19

#include "soc.h"
#include "common.h"
20

21 22 23 24 25
struct iommu_device {
	resource_size_t base;
	int irq;
	struct iommu_platform_data pdata;
	struct resource res[2];
26
};
27 28
static struct iommu_device *devices;
static int num_iommu_devices;
29

30
#ifdef CONFIG_ARCH_OMAP3
31
static struct iommu_device omap3_devices[] = {
32
	{
33
		.base = 0x480bd400,
34
		.irq = 24 + OMAP_INTC_START,
35 36 37 38
		.pdata = {
			.name = "isp",
			.nr_tlb_entries = 8,
			.clk_name = "cam_ick",
39 40
			.da_start = 0x0,
			.da_end = 0xFFFFF000,
41
		},
42
	},
43
#if defined(CONFIG_OMAP_IOMMU_IVA2)
44
	{
45
		.base = 0x5d000000,
46
		.irq = 28 + OMAP_INTC_START,
47 48 49 50
		.pdata = {
			.name = "iva2",
			.nr_tlb_entries = 32,
			.clk_name = "iva2_ck",
51 52
			.da_start = 0x11000000,
			.da_end = 0xFFFFF000,
53
		},
54
	},
55
#endif
56
};
57 58 59 60 61 62
#define NR_OMAP3_IOMMU_DEVICES ARRAY_SIZE(omap3_devices)
static struct platform_device *omap3_iommu_pdev[NR_OMAP3_IOMMU_DEVICES];
#else
#define omap3_devices		NULL
#define NR_OMAP3_IOMMU_DEVICES	0
#define omap3_iommu_pdev	NULL
63 64
#endif

65 66 67 68
#ifdef CONFIG_ARCH_OMAP4
static struct iommu_device omap4_devices[] = {
	{
		.base = OMAP4_MMU1_BASE,
69
		.irq = 100 + OMAP44XX_IRQ_GIC_START,
70 71 72
		.pdata = {
			.name = "ducati",
			.nr_tlb_entries = 32,
73
			.clk_name = "ipu_fck",
74 75
			.da_start = 0x0,
			.da_end = 0xFFFFF000,
76 77 78 79
		},
	},
	{
		.base = OMAP4_MMU2_BASE,
80
		.irq = 28 + OMAP44XX_IRQ_GIC_START,
81 82 83
		.pdata = {
			.name = "tesla",
			.nr_tlb_entries = 32,
84
			.clk_name = "dsp_fck",
85 86
			.da_start = 0x0,
			.da_end = 0xFFFFF000,
87 88 89 90 91 92 93 94 95 96
		},
	},
};
#define NR_OMAP4_IOMMU_DEVICES ARRAY_SIZE(omap4_devices)
static struct platform_device *omap4_iommu_pdev[NR_OMAP4_IOMMU_DEVICES];
#else
#define omap4_devices		NULL
#define NR_OMAP4_IOMMU_DEVICES	0
#define omap4_iommu_pdev	NULL
#endif
97

98
static struct platform_device **omap_iommu_pdev;
99

100
static int __init omap_iommu_init(void)
101 102
{
	int i, err;
103 104 105 106
	struct resource res[] = {
		{ .flags = IORESOURCE_MEM },
		{ .flags = IORESOURCE_IRQ },
	};
107

108 109 110 111 112 113 114 115 116 117 118 119
	if (cpu_is_omap34xx()) {
		devices = omap3_devices;
		omap_iommu_pdev = omap3_iommu_pdev;
		num_iommu_devices = NR_OMAP3_IOMMU_DEVICES;
	} else if (cpu_is_omap44xx()) {
		devices = omap4_devices;
		omap_iommu_pdev = omap4_iommu_pdev;
		num_iommu_devices = NR_OMAP4_IOMMU_DEVICES;
	} else
		return -ENODEV;

	for (i = 0; i < num_iommu_devices; i++) {
120
		struct platform_device *pdev;
121
		const struct iommu_device *d = &devices[i];
122 123 124 125 126 127 128

		pdev = platform_device_alloc("omap-iommu", i);
		if (!pdev) {
			err = -ENOMEM;
			goto err_out;
		}

129 130 131
		res[0].start = d->base;
		res[0].end = d->base + MMU_REG_SIZE - 1;
		res[1].start = res[1].end = d->irq;
132 133 134 135 136

		err = platform_device_add_resources(pdev, res,
						    ARRAY_SIZE(res));
		if (err)
			goto err_out;
137 138
		err = platform_device_add_data(pdev, &d->pdata,
					       sizeof(d->pdata));
139 140 141 142 143
		if (err)
			goto err_out;
		err = platform_device_add(pdev);
		if (err)
			goto err_out;
144
		omap_iommu_pdev[i] = pdev;
145 146 147 148 149
	}
	return 0;

err_out:
	while (i--)
150
		platform_device_put(omap_iommu_pdev[i]);
151 152
	return err;
}
153 154
/* must be ready before omap3isp is probed */
subsys_initcall(omap_iommu_init);
155

156
static void __exit omap_iommu_exit(void)
157 158 159
{
	int i;

160
	for (i = 0; i < num_iommu_devices; i++)
161
		platform_device_unregister(omap_iommu_pdev[i]);
162
}
163
module_exit(omap_iommu_exit);
164 165

MODULE_AUTHOR("Hiroshi DOYU");
166
MODULE_DESCRIPTION("omap iommu: omap device registration");
167
MODULE_LICENSE("GPL v2");