a54106b1913cd70d78fd70a76bd42fdeb0fd3110
[kernel.git] / drivers / mfd / glamo / glamo-core.c
1 /* Smedia Glamo 3362 driver
2  *
3  * (C) 2007 by Openmoko, Inc.
4  * Author: Harald Welte <laforge@openmoko.org>
5  * (C) 2009, Lars-Peter Clausen <lars@metafoo.de>
6  * All rights reserved.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  */
23
24 #include <linux/module.h>
25 #include <linux/kernel.h>
26 #include <linux/errno.h>
27 #include <linux/string.h>
28 #include <linux/mm.h>
29 #include <linux/delay.h>
30 #include <linux/init.h>
31 #include <linux/irq.h>
32 #include <linux/interrupt.h>
33 #include <linux/workqueue.h>
34 #include <linux/platform_device.h>
35 #include <linux/kernel_stat.h>
36 #include <linux/spinlock.h>
37 #include <linux/mfd/core.h>
38 #include <linux/mfd/glamo.h>
39 #include <linux/io.h>
40 #include <linux/slab.h>
41
42 #include <linux/pm.h>
43
44 #include "glamo-regs.h"
45 #include "glamo-core.h"
46
47 #define GLAMO_MEM_REFRESH_COUNT 0x100
48
49 #define GLAMO_NR_IRQS 9
50
51 #define GLAMO_IRQ_HOSTBUS       0
52 #define GLAMO_IRQ_JPEG          1
53 #define GLAMO_IRQ_MPEG          2
54 #define GLAMO_IRQ_MPROC1        3
55 #define GLAMO_IRQ_MPROC0        4
56 #define GLAMO_IRQ_CMDQUEUE      5
57 #define GLAMO_IRQ_2D            6
58 #define GLAMO_IRQ_MMC           7
59 #define GLAMO_IRQ_RISC          8
60
61 /*
62  * Glamo internal settings
63  *
64  * We run the memory interface from the faster PLLB on 2.6.28 kernels and
65  * above.  Couple of GTA02 users report trouble with memory bus when they
66  * upgraded from 2.6.24.  So this parameter allows reversion to 2.6.24
67  * scheme if their Glamo chip needs it.
68  *
69  * you can override the faster default on kernel commandline using
70  *
71  *   glamo3362.slow_memory=1
72  *
73  * for example
74  */
75
76 static int slow_memory;
77 module_param(slow_memory, int, 0644);
78
79 struct reg_range {
80         int start;
81         int count;
82         char *name;
83         unsigned dump:1;
84 };
85
86 static const struct reg_range reg_range[] = {
87         { 0x0000, 0x76,         "General",      1 },
88         { 0x0200, 0x18,         "Host Bus",     1 },
89         { 0x0300, 0x38,         "Memory",       1 },
90 /*      { 0x0400, 0x100,        "Sensor",       0 }, */
91 /*      { 0x0500, 0x300,        "ISP",          0 }, */
92 /*      { 0x0800, 0x400,        "JPEG",         0 }, */
93 /*      { 0x0c00, 0xcc,         "MPEG",         0 }, */
94         { 0x1100, 0xb2,         "LCD 1",        0 },
95         { 0x1200, 0x64,         "LCD 2",        0 },
96         { 0x1400, 0x42,         "MMC",          0 },
97 /*      { 0x1500, 0x080,        "MPU 0",        0 },
98         { 0x1580, 0x080,        "MPU 1",        0 },
99         { 0x1600, 0x080,        "Cmd Queue",    0 },
100         { 0x1680, 0x080,        "RISC CPU",     0 },*/
101         { 0x1700, 0x400,        "2D Unit",      0 },
102 /*      { 0x1b00, 0x900,        "3D Unit",      0 }, */
103 };
104
105 static inline void __reg_write(struct glamo_core *glamo,
106                                 uint16_t reg, uint16_t val)
107 {
108         writew(val, glamo->base + reg);
109 }
110
111 void glamo_reg_write(struct glamo_core *glamo,
112                                 uint16_t reg, uint16_t val)
113 {
114         spin_lock(&glamo->lock);
115         __reg_write(glamo, reg, val);
116         spin_unlock(&glamo->lock);
117 }
118 EXPORT_SYMBOL_GPL(glamo_reg_write);
119
120
121 static inline uint16_t __reg_read(struct glamo_core *glamo,
122                                         uint16_t reg)
123 {
124         return readw(glamo->base + reg);
125 }
126
127 uint16_t glamo_reg_read(struct glamo_core *glamo, uint16_t reg)
128 {
129         uint16_t val;
130         spin_lock(&glamo->lock);
131         val = __reg_read(glamo, reg);
132         spin_unlock(&glamo->lock);
133
134         return val;
135 }
136 EXPORT_SYMBOL_GPL(glamo_reg_read);
137
138 static void __reg_set_bit_mask(struct glamo_core *glamo,
139                                 uint16_t reg, uint16_t mask,
140                                 uint16_t val)
141 {
142         uint16_t tmp;
143
144         val &= mask;
145
146         tmp = __reg_read(glamo, reg);
147         tmp &= ~mask;
148         tmp |= val;
149         __reg_write(glamo, reg, tmp);
150 }
151
152 static void reg_set_bit_mask(struct glamo_core *glamo,
153                                 uint16_t reg, uint16_t mask,
154                                 uint16_t val)
155 {
156         spin_lock(&glamo->lock);
157         __reg_set_bit_mask(glamo, reg, mask, val);
158         spin_unlock(&glamo->lock);
159 }
160
161 static inline void __reg_set_bit(struct glamo_core *glamo,
162                                  uint16_t reg, uint16_t bit)
163 {
164         uint16_t tmp;
165         tmp = __reg_read(glamo, reg);
166         tmp |= bit;
167         __reg_write(glamo, reg, tmp);
168 }
169
170 static inline void __reg_clear_bit(struct glamo_core *glamo,
171                                         uint16_t reg, uint16_t bit)
172 {
173         uint16_t tmp;
174         tmp = __reg_read(glamo, reg);
175         tmp &= ~bit;
176         __reg_write(glamo, reg, tmp);
177 }
178
179 static void __reg_write_batch(struct glamo_core *glamo, uint16_t reg,
180                                 uint16_t count, uint16_t *values)
181 {
182         uint16_t end;
183         for (end = reg + count * 2; reg < end; reg += 2, ++values)
184                 __reg_write(glamo, reg, *values);
185 }
186
187 static void __reg_read_batch(struct glamo_core *glamo, uint16_t reg,
188                                 uint16_t count, uint16_t *values)
189 {
190         uint16_t end;
191         for (end = reg + count * 2; reg < end; reg += 2, ++values)
192                 *values = __reg_read(glamo, reg);
193 }
194
195 void glamo_reg_write_batch(struct glamo_core *glamo, uint16_t reg,
196                                 uint16_t count, uint16_t *values)
197 {
198         spin_lock(&glamo->lock);
199         __reg_write_batch(glamo, reg, count, values);
200         spin_unlock(&glamo->lock);
201 }
202 EXPORT_SYMBOL(glamo_reg_write_batch);
203
204 void glamo_reg_read_batch(struct glamo_core *glamo, uint16_t reg,
205                                 uint16_t count, uint16_t *values)
206 {
207         spin_lock(&glamo->lock);
208         __reg_read_batch(glamo, reg, count, values);
209         spin_unlock(&glamo->lock);
210 }
211 EXPORT_SYMBOL(glamo_reg_read_batch);
212
213 /***********************************************************************
214  * resources of sibling devices
215  ***********************************************************************/
216
217 static struct resource glamo_fb_resources[] = {
218         {
219                 .name   = "glamo-fb-regs",
220                 .start  = GLAMO_REGOFS_LCD,
221                 .end    = GLAMO_REGOFS_MMC - 1,
222                 .flags  = IORESOURCE_MEM,
223         }, {
224                 .name   = "glamo-fb-mem",
225                 .start  = GLAMO_MEM_BASE + GLAMO_OFFSET_FB,
226                 .end    = GLAMO_MEM_BASE + GLAMO_OFFSET_FB + GLAMO_FB_SIZE - 1,
227                 .flags  = IORESOURCE_MEM,
228         }, {
229                 .name   = "glamo-cmdq-regs",
230                 .start  = GLAMO_REGOFS_CMDQUEUE,
231                 .end    = GLAMO_REGOFS_RISC - 1,
232                 .flags  = IORESOURCE_MEM,
233         }, {
234                 .name   = "glamo-2d-regs",
235                 .start  = GLAMO_REGOFS_2D,
236                 .end    = GLAMO_REGOFS_3D- 1,
237                 .flags  = IORESOURCE_MEM,
238         }, {
239                 .name   = "glamo-2d-irq",
240                 .start  = GLAMO_IRQ_2D,
241                 .end    = GLAMO_IRQ_2D,
242                 .flags  = IORESOURCE_IRQ,
243         }
244 };
245
246 static struct resource glamo_mmc_resources[] = {
247         {
248                 .name   = "glamo-mmc-regs",
249                 .start  = GLAMO_REGOFS_MMC,
250                 .end    = GLAMO_REGOFS_MPROC0 - 1,
251                 .flags  = IORESOURCE_MEM
252         }, {
253                 .name   = "glamo-mmc-mem",
254                 .start  = GLAMO_MEM_BASE + GLAMO_OFFSET_MMC,
255                 .end    = GLAMO_MEM_BASE + GLAMO_OFFSET_MMC
256                                          + GLAMO_MMC_BUFFER_SIZE - 1,
257                 .flags  = IORESOURCE_MEM
258         }, {
259                 .start  = GLAMO_IRQ_MMC,
260                 .end    = GLAMO_IRQ_MMC,
261                 .flags  = IORESOURCE_IRQ,
262         },
263 };
264
265 enum glamo_cells {
266         GLAMO_CELL_FB,
267         GLAMO_CELL_MMC,
268         GLAMO_CELL_GPIO,
269 };
270
271 static const struct mfd_cell glamo_cells[] = {
272         [GLAMO_CELL_FB] = {
273                 .name = "glamo-fb",
274                 .num_resources = ARRAY_SIZE(glamo_fb_resources),
275                 .resources = glamo_fb_resources,
276         },
277         [GLAMO_CELL_MMC] = {
278                 .name = "glamo-mci",
279                 .num_resources = ARRAY_SIZE(glamo_mmc_resources),
280                 .resources = glamo_mmc_resources,
281         },
282         [GLAMO_CELL_GPIO] = {
283                 .name = "glamo-gpio",
284         },
285 };
286
287 /***********************************************************************
288  * IRQ demultiplexer
289  ***********************************************************************/
290 #define glamo_irq_bit(glamo, x) BIT(x - glamo->irq_base)
291
292 static inline struct glamo_core *irq_to_glamo(unsigned int irq)
293 {
294         return (struct glamo_core *)get_irq_chip_data(irq);
295 }
296
297 static void glamo_ack_irq(unsigned int irq)
298 {
299         struct glamo_core *glamo = irq_to_glamo(irq);
300         /* clear interrupt source */
301         __reg_write(glamo, GLAMO_REG_IRQ_CLEAR, glamo_irq_bit(glamo, irq));
302 }
303
304 static void glamo_mask_irq(unsigned int irq)
305 {
306         struct glamo_core *glamo = irq_to_glamo(irq);
307
308         /* clear bit in enable register */
309         __reg_clear_bit(glamo, GLAMO_REG_IRQ_ENABLE, glamo_irq_bit(glamo, irq));
310 }
311
312 static void glamo_unmask_irq(unsigned int irq)
313 {
314         struct glamo_core *glamo = irq_to_glamo(irq);
315
316         /* set bit in enable register */
317         __reg_set_bit(glamo, GLAMO_REG_IRQ_ENABLE, glamo_irq_bit(glamo, irq));
318 }
319
320 static struct irq_chip glamo_irq_chip = {
321         .name   = "glamo",
322         .ack    = glamo_ack_irq,
323         .mask   = glamo_mask_irq,
324         .unmask = glamo_unmask_irq,
325 };
326
327 static void glamo_irq_demux_handler(unsigned int irq, struct irq_desc *desc)
328 {
329         struct glamo_core *glamo = get_irq_desc_data(desc);
330         desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
331
332         if (unlikely(desc->status & IRQ_INPROGRESS)) {
333                 desc->status |= (IRQ_PENDING | IRQ_MASKED);
334                 desc->chip->mask(irq);
335                 desc->chip->ack(irq);
336                 return;
337         }
338         kstat_incr_irqs_this_cpu(irq, desc);
339
340         desc->chip->ack(irq);
341         desc->status |= IRQ_INPROGRESS;
342
343         do {
344                 uint16_t irqstatus;
345                 int i;
346
347                 if (unlikely((desc->status &
348                                 (IRQ_PENDING | IRQ_MASKED | IRQ_DISABLED)) ==
349                                 (IRQ_PENDING | IRQ_MASKED))) {
350                         /* dealing with pending IRQ, unmasking */
351                         desc->chip->unmask(irq);
352                         desc->status &= ~IRQ_MASKED;
353                 }
354
355                 desc->status &= ~IRQ_PENDING;
356
357                 /* read IRQ status register */
358                 irqstatus = __reg_read(glamo, GLAMO_REG_IRQ_STATUS);
359                 for (i = 0; i < 9; ++i) {
360                         if (irqstatus & BIT(i))
361                                 generic_handle_irq(glamo->irq_base + i);
362                 }
363
364         } while ((desc->status & (IRQ_PENDING | IRQ_DISABLED)) == IRQ_PENDING);
365
366         desc->status &= ~IRQ_INPROGRESS;
367 }
368
369 /*
370 sysfs
371 */
372
373 static ssize_t regs_write(struct device *dev, struct device_attribute *attr,
374                                 const char *buf, size_t count)
375 {
376         struct glamo_core *glamo = dev_get_drvdata(dev);
377         unsigned int reg;
378         unsigned int val;
379
380         sscanf(buf, "%u %u", &reg, &val);
381         printk(KERN_INFO"reg 0x%02x <-- 0x%04x\n",
382                 reg, val);
383
384         glamo_reg_write(glamo, reg, val);
385
386         return count;
387 }
388
389 static ssize_t regs_read(struct device *dev, struct device_attribute *attr,
390                         char *buf)
391 {
392         struct glamo_core *glamo = dev_get_drvdata(dev);
393         int i, n;
394         char *end = buf;
395         const struct reg_range *rr = reg_range;
396
397         spin_lock(&glamo->lock);
398
399         for (i = 0; i < ARRAY_SIZE(reg_range); ++i, ++rr) {
400                 if (!rr->dump)
401                         continue;
402                 end += sprintf(end, "\n%s\n", rr->name);
403                 for (n = rr->start; n < rr->start + rr->count; n += 2) {
404                         if ((n & 15) == 0)
405                                 end += sprintf(end, "\n%04X:  ", n);
406                         end += sprintf(end, "%04x ", __reg_read(glamo, n));
407                 }
408                 end += sprintf(end, "\n");
409         }
410         spin_unlock(&glamo->lock);
411
412         return end - buf;
413 }
414
415 static DEVICE_ATTR(regs, 0644, regs_read, regs_write);
416
417 struct glamo_engine_reg_set {
418         uint16_t reg;
419         uint16_t mask_suspended;
420         uint16_t mask_enabled;
421 };
422
423 struct glamo_engine_desc {
424         const char *name;
425         uint16_t hostbus;
426         const struct glamo_engine_reg_set *regs;
427         int num_regs;
428 };
429
430 static const struct glamo_engine_reg_set glamo_lcd_regs[] = {
431         { GLAMO_REG_CLOCK_LCD,
432         GLAMO_CLOCK_LCD_EN_M5CLK |
433         GLAMO_CLOCK_LCD_DG_M5CLK |
434         GLAMO_CLOCK_LCD_EN_DMCLK,
435
436         GLAMO_CLOCK_LCD_EN_DHCLK |
437         GLAMO_CLOCK_LCD_EN_DCLK
438         },
439         { GLAMO_REG_CLOCK_GEN5_1,
440         GLAMO_CLOCK_GEN51_EN_DIV_DMCLK,
441
442         GLAMO_CLOCK_GEN51_EN_DIV_DHCLK |
443         GLAMO_CLOCK_GEN51_EN_DIV_DCLK
444         }
445 };
446
447 static const struct glamo_engine_reg_set glamo_mmc_regs[] = {
448         { GLAMO_REG_CLOCK_MMC,
449         GLAMO_CLOCK_MMC_EN_M9CLK |
450         GLAMO_CLOCK_MMC_DG_M9CLK,
451
452         GLAMO_CLOCK_MMC_EN_TCLK |
453         GLAMO_CLOCK_MMC_DG_TCLK
454         },
455         { GLAMO_REG_CLOCK_GEN5_1,
456         0,
457         GLAMO_CLOCK_GEN51_EN_DIV_TCLK
458         }
459 };
460
461 static const struct glamo_engine_reg_set glamo_2d_regs[] = {
462         { GLAMO_REG_CLOCK_2D,
463         GLAMO_CLOCK_2D_EN_M7CLK |
464         GLAMO_CLOCK_2D_DG_M7CLK,
465
466         GLAMO_CLOCK_2D_EN_GCLK |
467         GLAMO_CLOCK_2D_DG_GCLK
468         },
469         { GLAMO_REG_CLOCK_GEN5_1,
470         0,
471         GLAMO_CLOCK_GEN51_EN_DIV_GCLK,
472         }
473 };
474
475 static const struct glamo_engine_reg_set glamo_cmdq_regs[] = {
476         { GLAMO_REG_CLOCK_2D,
477         GLAMO_CLOCK_2D_EN_M6CLK,
478         0
479         },
480 };
481
482 #define GLAMO_ENGINE(xname, xhostbus, xregs) { \
483         .name = xname, \
484         .hostbus = xhostbus, \
485         .num_regs = ARRAY_SIZE(xregs), \
486         .regs = xregs, \
487 }
488
489 static const struct glamo_engine_desc glamo_engines[] = {
490         [GLAMO_ENGINE_LCD] = GLAMO_ENGINE("LCD", GLAMO_HOSTBUS2_MMIO_EN_LCD,
491                                         glamo_lcd_regs),
492         [GLAMO_ENGINE_MMC] = GLAMO_ENGINE("MMC", GLAMO_HOSTBUS2_MMIO_EN_MMC,
493                                         glamo_mmc_regs),
494         [GLAMO_ENGINE_2D] = GLAMO_ENGINE("2D", GLAMO_HOSTBUS2_MMIO_EN_2D,
495                                         glamo_2d_regs),
496         [GLAMO_ENGINE_CMDQ] = GLAMO_ENGINE("CMDQ", GLAMO_HOSTBUS2_MMIO_EN_CQ,
497                                         glamo_cmdq_regs),
498 };
499
500 static inline const char *glamo_engine_name(enum glamo_engine engine)
501 {
502         return glamo_engines[engine].name;
503 }
504
505 /***********************************************************************
506  * 'engine' support
507  ***********************************************************************/
508
509 int __glamo_engine_enable(struct glamo_core *glamo, enum glamo_engine engine)
510 {
511         int i;
512         const struct glamo_engine_desc *engine_desc = &glamo_engines[engine];
513         const struct glamo_engine_reg_set *reg;
514
515         switch (engine) {
516         case GLAMO_ENGINE_LCD:
517         case GLAMO_ENGINE_MMC:
518         case GLAMO_ENGINE_2D:
519         case GLAMO_ENGINE_CMDQ:
520                 break;
521         default:
522                 return -EINVAL;
523         }
524
525         reg = engine_desc->regs;
526
527         __reg_set_bit(glamo, GLAMO_REG_HOSTBUS(2),
528                         engine_desc->hostbus);
529         for (i = engine_desc->num_regs; i; --i, ++reg)
530                 __reg_set_bit(glamo, reg->reg,
531                                 reg->mask_suspended | reg->mask_enabled);
532
533         return 0;
534 }
535
536 int glamo_engine_enable(struct glamo_core *glamo, enum glamo_engine engine)
537 {
538         int ret = 0;
539
540         spin_lock(&glamo->lock);
541
542         if (glamo->engine_state[engine] != GLAMO_ENGINE_ENABLED) {
543                 ret = __glamo_engine_enable(glamo, engine);
544                 if (!ret)
545                         glamo->engine_state[engine] = GLAMO_ENGINE_ENABLED;
546         }
547
548         spin_unlock(&glamo->lock);
549
550         return ret;
551 }
552 EXPORT_SYMBOL_GPL(glamo_engine_enable);
553
554 int __glamo_engine_disable(struct glamo_core *glamo, enum glamo_engine engine)
555 {
556         int i;
557         const struct glamo_engine_desc *engine_desc = &glamo_engines[engine];
558         const struct glamo_engine_reg_set *reg;
559
560         switch (engine) {
561         case GLAMO_ENGINE_LCD:
562         case GLAMO_ENGINE_MMC:
563         case GLAMO_ENGINE_2D:
564         case GLAMO_ENGINE_CMDQ:
565                 break;
566         default:
567                 return -EINVAL;
568         }
569
570         reg = engine_desc->regs;
571
572         __reg_clear_bit(glamo, GLAMO_REG_HOSTBUS(2),
573                         engine_desc->hostbus);
574         for (i = engine_desc->num_regs; i; --i, ++reg)
575                 __reg_clear_bit(glamo, reg->reg,
576                                 reg->mask_suspended | reg->mask_enabled);
577
578         return 0;
579 }
580 int glamo_engine_disable(struct glamo_core *glamo, enum glamo_engine engine)
581 {
582         int ret = 0;
583
584         spin_lock(&glamo->lock);
585
586         if (glamo->engine_state[engine] != GLAMO_ENGINE_DISABLED) {
587                 ret = __glamo_engine_disable(glamo, engine);
588                 if (!ret)
589                         glamo->engine_state[engine] = GLAMO_ENGINE_DISABLED;
590         }
591
592         spin_unlock(&glamo->lock);
593
594         return ret;
595 }
596 EXPORT_SYMBOL_GPL(glamo_engine_disable);
597
598 int __glamo_engine_suspend(struct glamo_core *glamo, enum glamo_engine engine)
599 {
600         int i;
601         const struct glamo_engine_desc *engine_desc = &glamo_engines[engine];
602         const struct glamo_engine_reg_set *reg;
603
604         switch (engine) {
605         case GLAMO_ENGINE_LCD:
606         case GLAMO_ENGINE_MMC:
607         case GLAMO_ENGINE_2D:
608         case GLAMO_ENGINE_CMDQ:
609                 break;
610         default:
611                 return -EINVAL;
612         }
613
614         reg = engine_desc->regs;
615
616         __reg_set_bit(glamo, GLAMO_REG_HOSTBUS(2),
617                         engine_desc->hostbus);
618         for (i = engine_desc->num_regs; i; --i, ++reg) {
619                 __reg_set_bit(glamo, reg->reg, reg->mask_suspended);
620                 __reg_clear_bit(glamo, reg->reg, reg->mask_enabled);
621         }
622
623         return 0;
624 }
625
626 int glamo_engine_suspend(struct glamo_core *glamo, enum glamo_engine engine)
627 {
628         int ret = 0;
629
630         spin_lock(&glamo->lock);
631
632         if (glamo->engine_state[engine] != GLAMO_ENGINE_SUSPENDED) {
633                 ret = __glamo_engine_suspend(glamo, engine);
634                 if (!ret)
635                         glamo->engine_state[engine] = GLAMO_ENGINE_SUSPENDED;
636         }
637
638         spin_unlock(&glamo->lock);
639
640         return ret;
641 }
642 EXPORT_SYMBOL_GPL(glamo_engine_suspend);
643
644 static const struct glamo_script reset_regs[] = {
645         [GLAMO_ENGINE_LCD] = {
646                 GLAMO_REG_CLOCK_LCD, GLAMO_CLOCK_LCD_RESET
647         },
648         [GLAMO_ENGINE_MMC] = {
649                 GLAMO_REG_CLOCK_MMC, GLAMO_CLOCK_MMC_RESET
650         },
651         [GLAMO_ENGINE_CMDQ] = {
652                 GLAMO_REG_CLOCK_2D, GLAMO_CLOCK_2D_CQ_RESET
653         },
654         [GLAMO_ENGINE_2D] = {
655                 GLAMO_REG_CLOCK_2D, GLAMO_CLOCK_2D_RESET
656         },
657         [GLAMO_ENGINE_JPEG] = {
658                 GLAMO_REG_CLOCK_JPEG, GLAMO_CLOCK_JPEG_RESET
659         },
660 };
661
662 void glamo_engine_reset(struct glamo_core *glamo, enum glamo_engine engine)
663 {
664         uint16_t reg = reset_regs[engine].reg;
665         uint16_t val = reset_regs[engine].val;
666
667         if (engine >= ARRAY_SIZE(reset_regs)) {
668                 dev_warn(&glamo->pdev->dev, "unknown engine %u ", engine);
669                 return;
670         }
671
672         spin_lock(&glamo->lock);
673         __reg_set_bit(glamo, reg, val);
674         __reg_clear_bit(glamo, reg, val);
675         spin_unlock(&glamo->lock);
676 }
677 EXPORT_SYMBOL_GPL(glamo_engine_reset);
678
679 int glamo_pll_rate(struct glamo_core *glamo,
680                           enum glamo_pll pll)
681 {
682         uint16_t reg;
683         unsigned int osci = glamo->pdata->osci_clock_rate;
684
685         switch (pll) {
686         case GLAMO_PLL1:
687                 reg = __reg_read(glamo, GLAMO_REG_PLL_GEN1);
688                 break;
689         case GLAMO_PLL2:
690                 reg = __reg_read(glamo, GLAMO_REG_PLL_GEN3);
691                 break;
692         default:
693                 return -EINVAL;
694         }
695
696         return (int)osci * (int)reg;
697 }
698 EXPORT_SYMBOL_GPL(glamo_pll_rate);
699
700 int glamo_engine_reclock(struct glamo_core *glamo,
701                          enum glamo_engine engine,
702                          int hz)
703 {
704         int pll;
705         uint16_t reg, mask, div;
706
707         if (!hz)
708                 return -EINVAL;
709
710         switch (engine) {
711         case GLAMO_ENGINE_LCD:
712                 pll = GLAMO_PLL1;
713                 reg = GLAMO_REG_CLOCK_GEN7;
714                 mask = 0xff;
715                 break;
716         case GLAMO_ENGINE_MMC:
717                 pll = GLAMO_PLL1;
718                 reg = GLAMO_REG_CLOCK_GEN8;
719                 mask = 0xff;
720                 break;
721         default:
722                 dev_warn(&glamo->pdev->dev,
723                          "reclock of engine 0x%x not supported\n", engine);
724                 return -EINVAL;
725                 break;
726         }
727
728         pll = glamo_pll_rate(glamo, pll);
729
730         div = pll / hz;
731
732         if (div != 0 && pll / div <= hz)
733                 --div;
734
735         if (div > mask)
736                 div = mask;
737
738         dev_dbg(&glamo->pdev->dev,
739                         "PLL %d, kHZ %d, div %d\n", pll, hz / 1000, div);
740
741         reg_set_bit_mask(glamo, reg, mask, div);
742         mdelay(5); /* wait some time to stabilize */
743
744         return pll / (div + 1);
745 }
746 EXPORT_SYMBOL_GPL(glamo_engine_reclock);
747
748 /***********************************************************************
749  * script support
750  ***********************************************************************/
751
752 #define GLAMO_SCRIPT_END        0xffff
753 #define GLAMO_SCRIPT_WAIT       0xfffe
754 #define GLAMO_SCRIPT_LOCK_PLL   0xfffd
755
756 /*
757  * couple of people reported artefacts with 2.6.28 changes, this
758  * allows reversion to 2.6.24 settings
759 */
760 static const uint16_t reg_0x200[] = {
761 0xe03, /* 0 waits on Async BB R & W, Use PLL 2 for mem bus */
762 0xef0, /* 3 waits on Async BB R & W, Use PLL 1 for mem bus */
763 0xea0, /* 2 waits on Async BB R & W, Use PLL 1 for mem bus */
764 0xe50, /* 1 waits on Async BB R & W, Use PLL 1 for mem bus */
765 0xe00, /* 0 waits on Async BB R & W, Use PLL 1 for mem bus */
766 0xef3, /* 3 waits on Async BB R & W, Use PLL 2 for mem bus */
767 0xea3, /* 2 waits on Async BB R & W, Use PLL 2 for mem bus */
768 0xe53, /* 1 waits on Async BB R & W, Use PLL 2 for mem bus */
769 };
770
771 static int glamo_run_script(struct glamo_core *glamo,
772                                 const struct glamo_script *script, int len,
773                                 int may_sleep)
774 {
775         int i;
776         uint16_t status;
777         const struct glamo_script *line = script;
778
779         for (i = 0; i < len; ++i, ++line) {
780                 switch (line->reg) {
781                 case GLAMO_SCRIPT_END:
782                         return 0;
783                 case GLAMO_SCRIPT_WAIT:
784                         if (may_sleep)
785                                 msleep(line->val);
786                         else
787                                 mdelay(line->val * 4);
788                         break;
789                 case GLAMO_SCRIPT_LOCK_PLL:
790                         /* spin until PLLs lock */
791                         do {
792                                 status = __reg_read(glamo, GLAMO_REG_PLL_GEN5);
793                         } while ((status & 3) != 3);
794                         break;
795                 case 0x200:
796                         __reg_write(glamo, line->reg,
797                                         reg_0x200[slow_memory & 0x8]);
798                         break;
799                 default:
800                         __reg_write(glamo, line->reg, line->val);
801                         break;
802                 }
803         }
804
805         return 0;
806 }
807
808 static const struct glamo_script glamo_init_script[] = {
809         { GLAMO_REG_CLOCK_HOST,         0x1000 },
810         { GLAMO_SCRIPT_WAIT,                 2 },
811         { GLAMO_REG_CLOCK_MEMORY,       0x1000 },
812         { GLAMO_REG_CLOCK_MEMORY,       0x2000 },
813         { GLAMO_REG_CLOCK_LCD,          0x1000 },
814         { GLAMO_REG_CLOCK_MMC,          0x1000 },
815         { GLAMO_REG_CLOCK_ISP,          0x1000 },
816         { GLAMO_REG_CLOCK_ISP,          0x3000 },
817         { GLAMO_REG_CLOCK_JPEG,         0x1000 },
818         { GLAMO_REG_CLOCK_3D,           0x1000 },
819         { GLAMO_REG_CLOCK_3D,           0x3000 },
820         { GLAMO_REG_CLOCK_2D,           0x1000 },
821         { GLAMO_REG_CLOCK_2D,           0x3000 },
822         { GLAMO_REG_CLOCK_RISC1,        0x1000 },
823         { GLAMO_REG_CLOCK_MPEG,         0x1000 },
824         { GLAMO_REG_CLOCK_MPEG,         0x3000 },
825         { GLAMO_REG_CLOCK_MPROC,        0x1000 /*0x100f*/ },
826         { GLAMO_SCRIPT_WAIT,                 2 },
827         { GLAMO_REG_CLOCK_HOST,         0x0000 },
828         { GLAMO_REG_CLOCK_MEMORY,       0x0000 },
829         { GLAMO_REG_CLOCK_LCD,          0x0000 },
830         { GLAMO_REG_CLOCK_MMC,          0x0000 },
831         { GLAMO_REG_PLL_GEN1,           0x05db },       /* 48MHz */
832         { GLAMO_REG_PLL_GEN3,           0x0aba },       /* 90MHz */
833         { GLAMO_SCRIPT_LOCK_PLL, 0 },
834         /*
835          * b9 of this register MUST be zero to get any interrupts on INT#
836          * the other set bits enable all the engine interrupt sources
837          */
838         { GLAMO_REG_IRQ_ENABLE,         0x0100 },
839         { GLAMO_REG_CLOCK_GEN6,         0x2000 },
840         { GLAMO_REG_CLOCK_GEN7,         0x0101 },
841         { GLAMO_REG_CLOCK_GEN8,         0x0100 },
842         { GLAMO_REG_CLOCK_HOST,         0x000d },
843         /*
844          * b7..b4 = 0 = no wait states on read or write
845          * b0 = 1 select PLL2 for Host interface, b1 = enable it
846          */
847         { GLAMO_REG_HOSTBUS(0),         0x0e03 /* this is replaced by script parser */ },
848         { GLAMO_REG_HOSTBUS(1),         0x07ff }, /* TODO: Disable all */
849         { GLAMO_REG_HOSTBUS(10),        0x0000 },
850         { GLAMO_REG_HOSTBUS(11),        0x4000 },
851         { GLAMO_REG_HOSTBUS(12),        0xf00e },
852
853         /* S-Media recommended "set tiling mode to 512 mode for memory access
854          * more efficiency when 640x480" */
855         { GLAMO_REG_MEM_TYPE,           0x0c74 }, /* 8MB, 16 word pg wr+rd */
856         { GLAMO_REG_MEM_GEN,            0xafaf }, /* 63 grants min + max */
857
858         { GLAMO_REG_MEM_TIMING1,        0x0108 },
859         { GLAMO_REG_MEM_TIMING2,        0x0010 }, /* Taa = 3 MCLK */
860         { GLAMO_REG_MEM_TIMING3,        0x0000 },
861         { GLAMO_REG_MEM_TIMING4,        0x0000 }, /* CE1# delay fall/rise */
862         { GLAMO_REG_MEM_TIMING5,        0x0000 }, /* UB# LB# */
863         { GLAMO_REG_MEM_TIMING6,        0x0000 }, /* OE# */
864         { GLAMO_REG_MEM_TIMING7,        0x0000 }, /* WE# */
865         { GLAMO_REG_MEM_TIMING8,        0x1002 }, /* MCLK delay, was 0x1000 */
866         { GLAMO_REG_MEM_TIMING9,        0x6006 },
867         { GLAMO_REG_MEM_TIMING10,       0x00ff },
868         { GLAMO_REG_MEM_TIMING11,       0x0001 },
869         { GLAMO_REG_MEM_POWER1,         0x0020 },
870         { GLAMO_REG_MEM_POWER2,         0x0000 },
871         { GLAMO_REG_MEM_DRAM1,          0x0000 },
872         { GLAMO_SCRIPT_WAIT,                 1 },
873         { GLAMO_REG_MEM_DRAM1,          0xc100 },
874         { GLAMO_SCRIPT_WAIT,                 1 },
875         { GLAMO_REG_MEM_DRAM1,          0xe100 },
876         { GLAMO_REG_MEM_DRAM2,          0x01d6 },
877         { GLAMO_REG_CLOCK_MEMORY,       0x000b },
878 };
879
880 /* Find out if we can support this version of the Glamo chip */
881 static int __devinit glamo_supported(struct glamo_core *glamo)
882 {
883         uint16_t dev_id, rev_id;
884
885         dev_id = __reg_read(glamo, GLAMO_REG_DEVICE_ID);
886         rev_id = __reg_read(glamo, GLAMO_REG_REVISION_ID);
887
888         switch (dev_id) {
889         case 0x3650:
890                 switch (rev_id) {
891                 case GLAMO_CORE_REV_A2:
892                         break;
893                 case GLAMO_CORE_REV_A0:
894                 case GLAMO_CORE_REV_A1:
895                 case GLAMO_CORE_REV_A3:
896                         dev_warn(&glamo->pdev->dev, "untested core revision "
897                                  "%04x, your mileage may vary\n", rev_id);
898                         break;
899                 default:
900                         dev_warn(&glamo->pdev->dev, "unknown glamo revision "
901                                  "%04x, your mileage may vary\n", rev_id);
902                 }
903                 break;
904         default:
905                 dev_err(&glamo->pdev->dev, "unsupported Glamo device %04x\n",
906                         dev_id);
907                 return 0;
908         }
909
910         dev_dbg(&glamo->pdev->dev, "Detected Glamo core %04x Revision %04x "
911                  "(%uHz CPU / %uHz Memory)\n", dev_id, rev_id,
912                  glamo_pll_rate(glamo, GLAMO_PLL1),
913                  glamo_pll_rate(glamo, GLAMO_PLL2));
914
915         return 1;
916 }
917
918 static int __devinit glamo_probe(struct platform_device *pdev)
919 {
920         int ret = 0, irq, irq_base;
921         struct glamo_core *glamo;
922         struct resource *mem;
923
924         glamo = kmalloc(GFP_KERNEL, sizeof(*glamo));
925         if (!glamo)
926                 return -ENOMEM;
927
928         spin_lock_init(&glamo->lock);
929
930         glamo->pdev = pdev;
931         mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
932         glamo->irq = platform_get_irq(pdev, 0);
933         glamo->irq_base = irq_base = platform_get_irq(pdev, 1);
934         glamo->pdata = pdev->dev.platform_data;
935
936         if (glamo->irq < 0) {
937                 ret = glamo->irq;
938                 dev_err(&pdev->dev, "Failed to get platform irq: %d\n", ret);
939                 goto err_free;
940         }
941
942         if (irq_base < 0) {
943                 ret = glamo->irq;
944                 dev_err(&pdev->dev, "Failed to get glamo irq base: %d\n", ret);
945                 goto err_free;
946         }
947
948         if (!mem) {
949                 dev_err(&pdev->dev, "Failed to get platform memory\n");
950                 ret = -ENOENT;
951                 goto err_free;
952         }
953
954         if (!glamo->pdata) {
955                 dev_err(&pdev->dev, "Missing platform data\n");
956                 ret = -ENOENT;
957                 goto err_free;
958         }
959
960         /* only request the generic, hostbus and memory controller registers */
961         glamo->mem = request_mem_region(mem->start, GLAMO_REGOFS_VIDCAP,
962                                         pdev->name);
963
964         if (!glamo->mem) {
965                 dev_err(&pdev->dev, "Failed to request io memory region\n");
966                 ret = -ENOENT;
967                 goto err_free;
968         }
969
970         glamo->base = ioremap(glamo->mem->start, resource_size(glamo->mem));
971         if (!glamo->base) {
972                 dev_err(&pdev->dev, "Failed to ioremap() memory region\n");
973                 goto err_release_mem_region;
974         }
975
976         /* confirm it isn't insane version */
977         if (!glamo_supported(glamo)) {
978                 dev_err(&pdev->dev,
979                         "This version of the Glamo is not supported\n");
980                 goto err_iounmap;
981         }
982
983         platform_set_drvdata(pdev, glamo);
984
985         /* sysfs */
986         ret = device_create_file(&pdev->dev, &dev_attr_regs);
987         if (ret < 0) {
988                 dev_err(&pdev->dev, "Failed to create sysfs file\n");
989                 goto err_iounmap;
990         }
991
992         /* init the chip with canned register set */
993         glamo_run_script(glamo, glamo_init_script,
994                          ARRAY_SIZE(glamo_init_script), 1);
995
996         /*
997          * finally set the mfd interrupts up
998          */
999         for (irq = irq_base; irq < irq_base + GLAMO_NR_IRQS; ++irq) {
1000 #ifdef CONFIG_ARM
1001                 set_irq_flags(irq, IRQF_VALID);
1002 #else
1003                 set_irq_noprobe(irq);
1004 #endif
1005                 set_irq_chip_data(irq, glamo);
1006                 set_irq_chip_and_handler(irq, &glamo_irq_chip,
1007                                         handle_level_irq);
1008         }
1009
1010         set_irq_type(glamo->irq, IRQ_TYPE_EDGE_FALLING);
1011         set_irq_data(glamo->irq, glamo);
1012         set_irq_chained_handler(glamo->irq, glamo_irq_demux_handler);
1013         glamo->irq_works = 1;
1014
1015         ret = mfd_add_devices(&pdev->dev, pdev->id, glamo_cells,
1016                                 ARRAY_SIZE(glamo_cells), mem, glamo->irq_base);
1017
1018         if (ret) {
1019                 dev_err(&pdev->dev, "Failed to add child devices: %d\n", ret);
1020                 goto err_free_irqs;
1021         }
1022
1023         dev_info(&glamo->pdev->dev, "Glamo core PLL1: %uHz, PLL2: %uHz\n",
1024                  glamo_pll_rate(glamo, GLAMO_PLL1),
1025                  glamo_pll_rate(glamo, GLAMO_PLL2));
1026
1027         return 0;
1028
1029 err_free_irqs:
1030         disable_irq(glamo->irq);
1031         set_irq_chained_handler(glamo->irq, NULL);
1032         set_irq_chip_data(glamo->irq, NULL);
1033
1034         for (irq = irq_base; irq < irq_base + GLAMO_NR_IRQS; ++irq) {
1035                 set_irq_chip(irq, NULL);
1036 #ifdef CONFIG_ARM
1037                 set_irq_flags(irq, 0);
1038 #else
1039                 set_irq_probe(irq);
1040 #endif
1041                 set_irq_chip_data(irq, NULL);
1042         }
1043 err_iounmap:
1044         iounmap(glamo->base);
1045 err_release_mem_region:
1046         release_mem_region(glamo->mem->start, resource_size(glamo->mem));
1047 err_free:
1048         platform_set_drvdata(pdev, NULL);
1049         kfree(glamo);
1050
1051         return ret;
1052 }
1053
1054 static int __devexit glamo_remove(struct platform_device *pdev)
1055 {
1056         struct glamo_core *glamo = platform_get_drvdata(pdev);
1057         int irq;
1058         int irq_base = glamo->irq_base;
1059
1060         mfd_remove_devices(&pdev->dev);
1061
1062         disable_irq(glamo->irq);
1063         set_irq_chained_handler(glamo->irq, NULL);
1064         set_irq_chip_data(glamo->irq, NULL);
1065
1066         for (irq = irq_base; irq < irq_base + GLAMO_NR_IRQS; ++irq) {
1067 #ifdef CONFIG_ARM
1068                 set_irq_flags(irq, 0);
1069 #else
1070                 set_irq_noprobe();
1071 #endif
1072                 set_irq_chip(irq, NULL);
1073                 set_irq_chip_data(irq, NULL);
1074         }
1075
1076         platform_set_drvdata(pdev, NULL);
1077         iounmap(glamo->base);
1078         release_mem_region(glamo->mem->start, resource_size(glamo->mem));
1079         kfree(glamo);
1080
1081         return 0;
1082 }
1083
1084 #ifdef CONFIG_PM
1085 #if 0
1086 static struct glamo_script glamo_resume_script[] = {
1087
1088         { GLAMO_REG_PLL_GEN1,           0x05db },       /* 48MHz */
1089         { GLAMO_REG_PLL_GEN3,           0x0aba },       /* 90MHz */
1090         { GLAMO_REG_DFT_GEN6, 1 },
1091                 { 0xfffe, 100 },
1092                 { 0xfffd, 0 },
1093         { 0x200,        0x0e03 },
1094
1095         /*
1096          * b9 of this register MUST be zero to get any interrupts on INT#
1097          * the other set bits enable all the engine interrupt sources
1098          */
1099         { GLAMO_REG_IRQ_ENABLE,         0x01ff },
1100         { GLAMO_REG_CLOCK_HOST,         0x0018 },
1101         { GLAMO_REG_CLOCK_GEN5_1, 0x18b1 },
1102
1103         { GLAMO_REG_MEM_DRAM1,          0x0000 },
1104                 { 0xfffe, 1 },
1105         { GLAMO_REG_MEM_DRAM1,          0xc100 },
1106                 { 0xfffe, 1 },
1107         { GLAMO_REG_MEM_DRAM1,          0xe100 },
1108         { GLAMO_REG_MEM_DRAM2,          0x01d6 },
1109         { GLAMO_REG_CLOCK_MEMORY,       0x000b },
1110 };
1111 #endif
1112
1113 #if 0
1114 static void glamo_power(struct glamo_core *glamo)
1115 {
1116         unsigned long flags;
1117
1118         spin_lock_irqsave(&glamo->lock, flags);
1119
1120         /*
1121 Power management
1122 static const REG_VALUE_MASK_TYPE reg_powerOn[] =
1123 {
1124         { REG_GEN_DFT6,     REG_BIT_ALL,    REG_DATA(1u << 0)           },
1125         { REG_GEN_PLL3,     0u,             REG_DATA(1u << 13)          },
1126         { REG_GEN_MEM_CLK,  REG_BIT_ALL,    REG_BIT_EN_MOCACLK          },
1127         { REG_MEM_DRAM2,    0u,             REG_BIT_EN_DEEP_POWER_DOWN  },
1128         { REG_MEM_DRAM1,    0u,             REG_BIT_SELF_REFRESH        }
1129 };
1130
1131 static const REG_VALUE_MASK_TYPE reg_powerStandby[] =
1132 {
1133         { REG_MEM_DRAM1,    REG_BIT_ALL,    REG_BIT_SELF_REFRESH    },
1134         { REG_GEN_MEM_CLK,  0u,             REG_BIT_EN_MOCACLK      },
1135         { REG_GEN_PLL3,     REG_BIT_ALL,    REG_DATA(1u << 13)      },
1136         { REG_GEN_DFT5,     REG_BIT_ALL,    REG_DATA(1u << 0)       }
1137 };
1138
1139 static const REG_VALUE_MASK_TYPE reg_powerSuspend[] =
1140 {
1141         { REG_MEM_DRAM2,    REG_BIT_ALL,    REG_BIT_EN_DEEP_POWER_DOWN  },
1142         { REG_GEN_MEM_CLK,  0u,             REG_BIT_EN_MOCACLK          },
1143         { REG_GEN_PLL3,     REG_BIT_ALL,    REG_DATA(1u << 13)          },
1144         { REG_GEN_DFT5,     REG_BIT_ALL,    REG_DATA(1u << 0)           }
1145 };
1146 */
1147         switch (new_state) {
1148         case GLAMO_POWER_ON:
1149
1150                 /*
1151                  * glamo state on resume is nondeterministic in some
1152                  * fundamental way, it has also been observed that the
1153                  * Glamo reset pin can get asserted by, eg, touching it with
1154                  * a scope probe.  So the only answer is to roll with it and
1155                  * force an external reset on the Glamo during resume.
1156                  */
1157
1158
1159                 break;
1160
1161         case GLAMO_POWER_SUSPEND:
1162
1163                 break;
1164         }
1165         spin_unlock_irqrestore(&glamo->lock, flags);
1166 }
1167 #endif
1168
1169 static int glamo_suspend(struct device *dev)
1170 {
1171         struct glamo_core *glamo = dev_get_drvdata(dev);
1172         int n;
1173
1174         spin_lock(&glamo->lock);
1175
1176         glamo->saved_irq_mask = __reg_read(glamo, GLAMO_REG_IRQ_ENABLE);
1177
1178         /* nuke interrupts */
1179         __reg_write(glamo, GLAMO_REG_IRQ_ENABLE, 0x200);
1180
1181         /* take down each engine before we kill mem and pll */
1182         for (n = 0; n < __NUM_GLAMO_ENGINES; n++) {
1183                 if (glamo->engine_state != GLAMO_ENGINE_DISABLED)
1184                         __glamo_engine_disable(glamo, n);
1185         }
1186
1187         /* enable self-refresh */
1188
1189         __reg_write(glamo, GLAMO_REG_MEM_DRAM1,
1190                                 GLAMO_MEM_DRAM1_EN_DRAM_REFRESH |
1191                                 GLAMO_MEM_DRAM1_EN_GATE_CKE |
1192                                 GLAMO_MEM_DRAM1_SELF_REFRESH |
1193                                 GLAMO_MEM_REFRESH_COUNT);
1194         __reg_write(glamo, GLAMO_REG_MEM_DRAM1,
1195                                 GLAMO_MEM_DRAM1_EN_MODEREG_SET |
1196                                 GLAMO_MEM_DRAM1_EN_DRAM_REFRESH |
1197                                 GLAMO_MEM_DRAM1_EN_GATE_CKE |
1198                                 GLAMO_MEM_DRAM1_SELF_REFRESH |
1199                                 GLAMO_MEM_REFRESH_COUNT);
1200
1201         /* force RAM into deep powerdown */
1202         __reg_write(glamo, GLAMO_REG_MEM_DRAM2,
1203                                 GLAMO_MEM_DRAM2_DEEP_PWRDOWN |
1204                                 (7 << 6) | /* tRC */
1205                                 (1 << 4) | /* tRP */
1206                                 (1 << 2) | /* tRCD */
1207                                 2); /* CAS latency */
1208
1209         /* disable clocks to memory */
1210         __reg_write(glamo, GLAMO_REG_CLOCK_MEMORY, 0);
1211
1212         /* all dividers from OSCI */
1213         __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_GEN5_1, 0x400, 0x400);
1214
1215         /* PLL2 into bypass */
1216         __reg_set_bit_mask(glamo, GLAMO_REG_PLL_GEN3, 1 << 12, 1 << 12);
1217
1218         __reg_write(glamo, GLAMO_BASIC_MMC_EN_TCLK_DLYA1, 0x0e00);
1219
1220         /* kill PLLS 1 then 2 */
1221         __reg_write(glamo, GLAMO_REG_DFT_GEN5, 0x0001);
1222         __reg_set_bit_mask(glamo, GLAMO_REG_PLL_GEN3, 1 << 13, 1 << 13);
1223
1224         spin_unlock(&glamo->lock);
1225
1226         return 0;
1227 }
1228
1229 static int glamo_resume(struct device *dev)
1230 {
1231         struct glamo_core *glamo = dev_get_drvdata(dev);
1232         int n;
1233
1234         (glamo->pdata->glamo_external_reset)(0);
1235         udelay(10);
1236         (glamo->pdata->glamo_external_reset)(1);
1237         mdelay(5);
1238
1239         spin_lock(&glamo->lock);
1240
1241         glamo_run_script(glamo, glamo_init_script,
1242                          ARRAY_SIZE(glamo_init_script), 0);
1243
1244
1245         for (n = 0; n < __NUM_GLAMO_ENGINES; n++) {
1246                 switch (glamo->engine_state[n]) {
1247                 case GLAMO_ENGINE_SUSPENDED:
1248                         __glamo_engine_suspend(glamo, n);
1249                         break;
1250                 case GLAMO_ENGINE_ENABLED:
1251                         __glamo_engine_enable(glamo, n);
1252                         break;
1253                 default:
1254                         break;
1255                 }
1256         }
1257
1258         __reg_write(glamo, GLAMO_REG_IRQ_ENABLE, glamo->saved_irq_mask);
1259
1260         spin_unlock(&glamo->lock);
1261
1262         return 0;
1263 }
1264
1265 static struct dev_pm_ops glamo_pm_ops = {
1266         .suspend    = glamo_suspend,
1267         .resume     = glamo_resume,
1268         .poweroff   = glamo_suspend,
1269         .restore    = glamo_resume,
1270 };
1271
1272 #define GLAMO_PM_OPS (&glamo_pm_ops)
1273
1274 #else
1275 #define GLAMO_PM_OPS NULL
1276 #endif
1277
1278 static struct platform_driver glamo_driver = {
1279         .probe          = glamo_probe,
1280         .remove         = __devexit_p(glamo_remove),
1281         .driver         = {
1282                 .name   = "glamo3362",
1283                 .owner  = THIS_MODULE,
1284                 .pm     = GLAMO_PM_OPS,
1285         },
1286 };
1287
1288 static int __devinit glamo_init(void)
1289 {
1290         return platform_driver_register(&glamo_driver);
1291 }
1292 module_init(glamo_init);
1293
1294 static void __exit glamo_exit(void)
1295 {
1296         platform_driver_unregister(&glamo_driver);
1297 }
1298 module_exit(glamo_exit);
1299
1300 MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>");
1301 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
1302 MODULE_DESCRIPTION("Smedia Glamo 3362 core/resource driver");
1303 MODULE_LICENSE("GPL");
1304 MODULE_ALIAS("platform:glamo3362");