aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/tiler/dmm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/tiler/dmm.c')
-rw-r--r--drivers/media/video/tiler/dmm.c211
1 files changed, 54 insertions, 157 deletions
diff --git a/drivers/media/video/tiler/dmm.c b/drivers/media/video/tiler/dmm.c
index 8663b36a5e7..685a1935a7f 100644
--- a/drivers/media/video/tiler/dmm.c
+++ b/drivers/media/video/tiler/dmm.c
@@ -3,6 +3,9 @@
3 * 3 *
4 * DMM driver support functions for TI OMAP processors. 4 * DMM driver support functions for TI OMAP processors.
5 * 5 *
6 * Authors: David Sin <davidsin@ti.com>
7 * Lajos Molnar <molnar@ti.com>
8 *
6 * Copyright (C) 2009-2010 Texas Instruments, Inc. 9 * Copyright (C) 2009-2010 Texas Instruments, Inc.
7 * 10 *
8 * This package is free software; you can redistribute it and/or modify 11 * This package is free software; you can redistribute it and/or modify
@@ -16,10 +19,6 @@
16 19
17#include <linux/init.h> 20#include <linux/init.h>
18#include <linux/module.h> 21#include <linux/module.h>
19#include <linux/cdev.h> /* struct cdev */
20#include <linux/kdev_t.h> /* MKDEV() */
21#include <linux/fs.h> /* register_chrdev_region() */
22#include <linux/device.h> /* struct class */
23#include <linux/platform_device.h> /* platform_device() */ 22#include <linux/platform_device.h> /* platform_device() */
24#include <linux/err.h> /* IS_ERR() */ 23#include <linux/err.h> /* IS_ERR() */
25#include <linux/io.h> /* ioremap() */ 24#include <linux/io.h> /* ioremap() */
@@ -29,10 +28,10 @@
29#include <mach/dmm.h> 28#include <mach/dmm.h>
30 29
31#undef __DEBUG__ 30#undef __DEBUG__
32#define BITS_32(in_NbBits) ((((u32)1 << in_NbBits) - 1) | ((u32)1 << in_NbBits)) 31
33#define BITFIELD_32(in_UpBit, in_LowBit)\ 32#define MASK(msb, lsb) (((1 << ((msb) + 1 - (lsb))) - 1) << (lsb))
34 (BITS_32(in_UpBit) & ~((BITS_32(in_LowBit)) >> 1)) 33#define SET_FLD(reg, msb, lsb, val) \
35#define BF BITFIELD_32 34(((reg) & ~MASK((msb), (lsb))) | (((val) << (lsb)) & MASK((msb), (lsb))))
36 35
37#ifdef __DEBUG__ 36#ifdef __DEBUG__
38#define DEBUG(x, y) printk(KERN_NOTICE "%s()::%d:%s=(0x%08x)\n", \ 37#define DEBUG(x, y) printk(KERN_NOTICE "%s()::%d:%s=(0x%08x)\n", \
@@ -41,16 +40,6 @@
41#define DEBUG(x, y) 40#define DEBUG(x, y)
42#endif 41#endif
43 42
44static s32 dmm_major;
45static s32 dmm_minor;
46
47struct dmm_dev {
48 struct cdev cdev;
49};
50
51static struct dmm_dev *dmm_device;
52static struct class *dmmdev_class;
53
54static struct platform_driver dmm_driver_ldm = { 43static struct platform_driver dmm_driver_ldm = {
55 .driver = { 44 .driver = {
56 .owner = THIS_MODULE, 45 .owner = THIS_MODULE,
@@ -63,18 +52,15 @@ static struct platform_driver dmm_driver_ldm = {
63 52
64s32 dmm_pat_refill(struct dmm *dmm, struct pat *pd, enum pat_mode mode) 53s32 dmm_pat_refill(struct dmm *dmm, struct pat *pd, enum pat_mode mode)
65{ 54{
66 void __iomem *r = NULL; 55 void __iomem *r;
67 u32 v = -1, w = -1; 56 u32 v;
68 57
69 /* Only manual refill supported */ 58 /* Only manual refill supported */
70 if (mode != MANUAL) 59 if (mode != MANUAL)
71 return -EFAULT; 60 return -EFAULT;
72 61
73 /* 62 /* Check that the DMM_PAT_STATUS register has not reported an error */
74 * Check that the DMM_PAT_STATUS register 63 r = dmm->base + DMM_PAT_STATUS__0;
75 * has not reported an error.
76 */
77 r = (void __iomem *)((u32)dmm->base | DMM_PAT_STATUS__0);
78 v = __raw_readl(r); 64 v = __raw_readl(r);
79 if ((v & 0xFC00) != 0) { 65 if ((v & 0xFC00) != 0) {
80 while (1) 66 while (1)
@@ -82,28 +68,19 @@ s32 dmm_pat_refill(struct dmm *dmm, struct pat *pd, enum pat_mode mode)
82 } 68 }
83 69
84 /* Set "next" register to NULL */ 70 /* Set "next" register to NULL */
85 r = (void __iomem *)((u32)dmm->base | DMM_PAT_DESCR__0); 71 r = dmm->base + DMM_PAT_DESCR__0;
86 v = __raw_readl(r); 72 v = __raw_readl(r);
87 w = (v & (~(BF(31, 4)))) | ((((u32)NULL) << 4) & BF(31, 4)); 73 v = SET_FLD(v, 31, 4, (u32) NULL);
88 __raw_writel(w, r); 74 __raw_writel(v, r);
89 75
90 /* Set area to be refilled */ 76 /* Set area to be refilled */
91 r = (void __iomem *)((u32)dmm->base | DMM_PAT_AREA__0); 77 r = dmm->base + DMM_PAT_AREA__0;
92 v = __raw_readl(r);
93 w = (v & (~(BF(30, 24)))) | ((((s8)pd->area.y1) << 24) & BF(30, 24));
94 __raw_writel(w, r);
95
96 v = __raw_readl(r);
97 w = (v & (~(BF(23, 16)))) | ((((s8)pd->area.x1) << 16) & BF(23, 16));
98 __raw_writel(w, r);
99
100 v = __raw_readl(r);
101 w = (v & (~(BF(14, 8)))) | ((((s8)pd->area.y0) << 8) & BF(14, 8));
102 __raw_writel(w, r);
103
104 v = __raw_readl(r); 78 v = __raw_readl(r);
105 w = (v & (~(BF(7, 0)))) | ((((s8)pd->area.x0) << 0) & BF(7, 0)); 79 v = SET_FLD(v, 30, 24, pd->area.y1);
106 __raw_writel(w, r); 80 v = SET_FLD(v, 23, 16, pd->area.x1);
81 v = SET_FLD(v, 14, 8, pd->area.y0);
82 v = SET_FLD(v, 7, 0, pd->area.x0);
83 __raw_writel(v, r);
107 wmb(); 84 wmb();
108 85
109#ifdef __DEBUG__ 86#ifdef __DEBUG__
@@ -115,92 +92,71 @@ s32 dmm_pat_refill(struct dmm *dmm, struct pat *pd, enum pat_mode mode)
115#endif 92#endif
116 93
117 /* First, clear the DMM_PAT_IRQSTATUS register */ 94 /* First, clear the DMM_PAT_IRQSTATUS register */
118 r = (void __iomem *)((u32)dmm->base | (u32)DMM_PAT_IRQSTATUS); 95 r = dmm->base + DMM_PAT_IRQSTATUS;
119 __raw_writel(0xFFFFFFFF, r); 96 __raw_writel(0xFFFFFFFF, r);
120 wmb(); 97 wmb();
121 98
122 r = (void __iomem *)((u32)dmm->base | (u32)DMM_PAT_IRQSTATUS_RAW); 99 r = dmm->base + DMM_PAT_IRQSTATUS_RAW;
123 v = 0xFFFFFFFF; 100 do {
124
125 while (v != 0x0) {
126 v = __raw_readl(r); 101 v = __raw_readl(r);
127 DEBUG("DMM_PAT_IRQSTATUS_RAW", v); 102 DEBUG("DMM_PAT_IRQSTATUS_RAW", v);
128 } 103 } while (v != 0x0);
129 104
130 /* Fill data register */ 105 /* Fill data register */
131 r = (void __iomem *)((u32)dmm->base | DMM_PAT_DATA__0); 106 r = dmm->base + DMM_PAT_DATA__0;
132 v = __raw_readl(r); 107 v = __raw_readl(r);
133 108
134 /* Apply 4 bit left shft to counter the 4 bit right shift */ 109 /* pd->data must be 16 aligned */
135 w = (v & (~(BF(31, 4)))) | ((((u32)(pd->data >> 4)) << 4) & BF(31, 4)); 110 BUG_ON(pd->data & 15);
136 __raw_writel(w, r); 111 v = SET_FLD(v, 31, 4, pd->data >> 4);
112 __raw_writel(v, r);
137 wmb(); 113 wmb();
138 114
139 /* Read back PAT_DATA__0 to see if write was successful */ 115 /* Read back PAT_DATA__0 to see if write was successful */
140 v = 0x0; 116 do {
141 while (v != pd->data) {
142 v = __raw_readl(r); 117 v = __raw_readl(r);
143 DEBUG("DMM_PAT_DATA__0", v); 118 DEBUG("DMM_PAT_DATA__0", v);
144 } 119 } while (v != pd->data);
145
146 r = (void __iomem *)((u32)dmm->base | (u32)DMM_PAT_CTRL__0);
147 v = __raw_readl(r);
148
149 w = (v & (~(BF(31, 28)))) | ((((u32)pd->ctrl.ini) << 28) & BF(31, 28));
150 __raw_writel(w, r);
151
152 v = __raw_readl(r);
153 w = (v & (~(BF(16, 16)))) | ((((u32)pd->ctrl.sync) << 16) & BF(16, 16));
154 __raw_writel(w, r);
155
156 v = __raw_readl(r);
157 w = (v & (~(BF(9, 8)))) | ((((u32)pd->ctrl.lut_id) << 8) & BF(9, 8));
158 __raw_writel(w, r);
159
160 v = __raw_readl(r);
161 w = (v & (~(BF(6, 4)))) | ((((u32)pd->ctrl.dir) << 4) & BF(6, 4));
162 __raw_writel(w, r);
163 120
121 r = dmm->base + DMM_PAT_CTRL__0;
164 v = __raw_readl(r); 122 v = __raw_readl(r);
165 w = (v & (~(BF(0, 0)))) | ((((u32)pd->ctrl.start) << 0) & BF(0, 0)); 123 v = SET_FLD(v, 31, 28, pd->ctrl.ini);
166 __raw_writel(w, r); 124 v = SET_FLD(v, 16, 16, pd->ctrl.sync);
125 v = SET_FLD(v, 9, 8, pd->ctrl.lut_id);
126 v = SET_FLD(v, 6, 4, pd->ctrl.dir);
127 v = SET_FLD(v, 0, 0, pd->ctrl.start);
128 __raw_writel(v, r);
167 wmb(); 129 wmb();
168 130
169 /* 131 /* Check if PAT_IRQSTATUS_RAW is set after the PAT has been refilled */
170 * Now, check if PAT_IRQSTATUS_RAW has been 132 r = dmm->base + DMM_PAT_IRQSTATUS_RAW;
171 * set after the PAT has been refilled 133 do {
172 */
173 r = (void __iomem *)((u32)dmm->base | (u32)DMM_PAT_IRQSTATUS_RAW);
174 v = 0x0;
175 while ((v & 0x3) != 0x3) {
176 v = __raw_readl(r); 134 v = __raw_readl(r);
177 DEBUG("DMM_PAT_IRQSTATUS_RAW", v); 135 DEBUG("DMM_PAT_IRQSTATUS_RAW", v);
178 } 136 } while ((v & 0x3) != 0x3);
179 137
180 /* Again, clear the DMM_PAT_IRQSTATUS register */ 138 /* Again, clear the DMM_PAT_IRQSTATUS register */
181 r = (void __iomem *)((u32)dmm->base | (u32)DMM_PAT_IRQSTATUS); 139 r = dmm->base + DMM_PAT_IRQSTATUS;
182 __raw_writel(0xFFFFFFFF, r); 140 __raw_writel(0xFFFFFFFF, r);
183 wmb(); 141 wmb();
184 142
185 r = (void __iomem *)((u32)dmm->base | (u32)DMM_PAT_IRQSTATUS_RAW); 143 r = dmm->base + DMM_PAT_IRQSTATUS_RAW;
186 v = 0xFFFFFFFF; 144 do {
187
188 while (v != 0x0) {
189 v = __raw_readl(r); 145 v = __raw_readl(r);
190 DEBUG("DMM_PAT_IRQSTATUS_RAW", v); 146 DEBUG("DMM_PAT_IRQSTATUS_RAW", v);
191 } 147 } while (v != 0x0);
192 148
193 /* Again, set "next" register to NULL to clear any PAT STATUS errors */ 149 /* Again, set "next" register to NULL to clear any PAT STATUS errors */
194 r = (void __iomem *)((u32)dmm->base | DMM_PAT_DESCR__0); 150 r = dmm->base + DMM_PAT_DESCR__0;
195 v = __raw_readl(r); 151 v = __raw_readl(r);
196 w = (v & (~(BF(31, 4)))) | ((((u32)NULL) << 4) & BF(31, 4)); 152 v = SET_FLD(v, 31, 4, (u32) NULL);
197 __raw_writel(w, r); 153 __raw_writel(v, r);
198 154
199 /* 155 /*
200 * Now, check that the DMM_PAT_STATUS register 156 * Now, check that the DMM_PAT_STATUS register
201 * has not reported an error before exiting. 157 * has not reported an error before exiting.
202 */ 158 */
203 r = (void __iomem *)((u32)dmm->base | DMM_PAT_STATUS__0); 159 r = dmm->base + DMM_PAT_STATUS__0;
204 v = __raw_readl(r); 160 v = __raw_readl(r);
205 if ((v & 0xFC00) != 0) { 161 if ((v & 0xFC00) != 0) {
206 while (1) 162 while (1)
@@ -211,25 +167,10 @@ s32 dmm_pat_refill(struct dmm *dmm, struct pat *pd, enum pat_mode mode)
211} 167}
212EXPORT_SYMBOL(dmm_pat_refill); 168EXPORT_SYMBOL(dmm_pat_refill);
213 169
214static s32 dmm_open(struct inode *ip, struct file *filp)
215{
216 return 0;
217}
218
219static s32 dmm_release(struct inode *ip, struct file *filp)
220{
221 return 0;
222}
223
224static const struct file_operations dmm_fops = {
225 .open = dmm_open,
226 .release = dmm_release,
227};
228
229struct dmm *dmm_pat_init(u32 id) 170struct dmm *dmm_pat_init(u32 id)
230{ 171{
231 u32 base = 0; 172 u32 base;
232 struct dmm *dmm = NULL; 173 struct dmm *dmm;
233 switch (id) { 174 switch (id) {
234 case 0: 175 case 0:
235 /* only support id 0 for now */ 176 /* only support id 0 for now */
@@ -276,60 +217,16 @@ EXPORT_SYMBOL(dmm_pat_release);
276 217
277static s32 __init dmm_init(void) 218static s32 __init dmm_init(void)
278{ 219{
279 dev_t dev = 0; 220 return platform_driver_register(&dmm_driver_ldm);
280 s32 r = -1;
281 struct device *device = NULL;
282
283 if (dmm_major) {
284 dev = MKDEV(dmm_major, dmm_minor);
285 r = register_chrdev_region(dev, 1, "dmm");
286 } else {
287 r = alloc_chrdev_region(&dev, dmm_minor, 1, "dmm");
288 dmm_major = MAJOR(dev);
289 }
290
291 dmm_device = kmalloc(sizeof(*dmm_device), GFP_KERNEL);
292 if (!dmm_device) {
293 unregister_chrdev_region(dev, 1);
294 return -ENOMEM;
295 }
296 memset(dmm_device, 0x0, sizeof(struct dmm_dev));
297
298 cdev_init(&dmm_device->cdev, &dmm_fops);
299 dmm_device->cdev.owner = THIS_MODULE;
300 dmm_device->cdev.ops = &dmm_fops;
301
302 r = cdev_add(&dmm_device->cdev, dev, 1);
303 if (r)
304 printk(KERN_ERR "cdev_add():failed\n");
305
306 dmmdev_class = class_create(THIS_MODULE, "dmm");
307
308 if (IS_ERR(dmmdev_class)) {
309 printk(KERN_ERR "class_create():failed\n");
310 goto EXIT;
311 }
312
313 device = device_create(dmmdev_class, NULL, dev, NULL, "dmm");
314 if (device == NULL)
315 printk(KERN_ERR "device_create() fail\n");
316
317 r = platform_driver_register(&dmm_driver_ldm);
318
319EXIT:
320 return r;
321} 221}
322 222
323static void __exit dmm_exit(void) 223static void __exit dmm_exit(void)
324{ 224{
325 platform_driver_unregister(&dmm_driver_ldm); 225 platform_driver_unregister(&dmm_driver_ldm);
326 cdev_del(&dmm_device->cdev);
327 kfree(dmm_device);
328 device_destroy(dmmdev_class, MKDEV(dmm_major, dmm_minor));
329 class_destroy(dmmdev_class);
330} 226}
331 227
332MODULE_LICENSE("GPL v2"); 228MODULE_LICENSE("GPL v2");
333MODULE_AUTHOR("davidsin@ti.com"); 229MODULE_AUTHOR("davidsin@ti.com");
230MODULE_AUTHOR("molnar@ti.com");
334module_init(dmm_init); 231module_init(dmm_init);
335module_exit(dmm_exit); 232module_exit(dmm_exit);