glamo_fb: Implement screen blanking
[kernel.git] / drivers / mfd / glamo / glamo-core.c
1 /* Smedia Glamo 336x/337x driver
2  *
3  * (C) 2007 by Openmoko, Inc.
4  * Author: Harald Welte <laforge@openmoko.org>
5  * All rights reserved.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License as
9  * published by the Free Software Foundation; either version 2 of
10  * the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20  * MA 02111-1307 USA
21  */
22
23 #include <linux/module.h>
24 #include <linux/kernel.h>
25 #include <linux/errno.h>
26 #include <linux/string.h>
27 #include <linux/mm.h>
28 #include <linux/tty.h>
29 #include <linux/slab.h>
30 #include <linux/delay.h>
31 #include <linux/fb.h>
32 #include <linux/init.h>
33 #include <linux/irq.h>
34 #include <linux/interrupt.h>
35 #include <linux/workqueue.h>
36 #include <linux/wait.h>
37 #include <linux/platform_device.h>
38 #include <linux/kernel_stat.h>
39 #include <linux/spinlock.h>
40 #include <linux/glamofb.h>
41 #include <linux/mmc/mmc.h>
42 #include <linux/mmc/host.h>
43
44 #include <asm/io.h>
45 #include <asm/uaccess.h>
46 #include <asm/div64.h>
47
48 //#include <mach/regs-irq.h>
49
50 #ifdef CONFIG_PM
51 #include <linux/pm.h>
52 #endif
53
54 #include "glamo-regs.h"
55 #include "glamo-core.h"
56
57 #define RESSIZE(ressource) (((ressource)->end - (ressource)->start)+1)
58
59 #define GLAMO_MEM_REFRESH_COUNT 0x100
60
61 static struct glamo_core *glamo_handle;
62
63 static inline void __reg_write(struct glamo_core *glamo,
64                                 u_int16_t reg, u_int16_t val)
65 {
66         writew(val, glamo->base + reg);
67 }
68
69 static inline u_int16_t __reg_read(struct glamo_core *glamo,
70                                    u_int16_t reg)
71 {
72         return readw(glamo->base + reg);
73 }
74
75 static void __reg_set_bit_mask(struct glamo_core *glamo,
76                                 u_int16_t reg, u_int16_t mask,
77                                 u_int16_t val)
78 {
79         u_int16_t tmp;
80
81         val &= mask;
82
83         tmp = __reg_read(glamo, reg);
84         tmp &= ~mask;
85         tmp |= val;
86         __reg_write(glamo, reg, tmp);
87 }
88
89 static void reg_set_bit_mask(struct glamo_core *glamo,
90                                 u_int16_t reg, u_int16_t mask,
91                                 u_int16_t val)
92 {
93         spin_lock(&glamo->lock);
94         __reg_set_bit_mask(glamo, reg, mask, val);
95         spin_unlock(&glamo->lock);
96 }
97
98 static inline void __reg_set_bit(struct glamo_core *glamo,
99                                  u_int16_t reg, u_int16_t bit)
100 {
101         __reg_set_bit_mask(glamo, reg, bit, 0xffff);
102 }
103
104 static inline void __reg_clear_bit(struct glamo_core *glamo,
105                                    u_int16_t reg, u_int16_t bit)
106 {
107         __reg_set_bit_mask(glamo, reg, bit, 0);
108 }
109
110 static inline void glamo_vmem_write(struct glamo_core *glamo, u_int32_t addr,
111                                     u_int16_t *src, int len)
112 {
113         if (addr & 0x0001 || (unsigned long)src & 0x0001 || len & 0x0001) {
114                 dev_err(&glamo->pdev->dev, "unaligned write(0x%08x, 0x%p, "
115                         "0x%x)!!\n", addr, src, len);
116         }
117
118 }
119
120 static inline void glamo_vmem_read(struct glamo_core *glamo, u_int16_t *buf,
121                                    u_int32_t addr, int len)
122 {
123         if (addr & 0x0001 || (unsigned long) buf & 0x0001 || len & 0x0001) {
124                 dev_err(&glamo->pdev->dev, "unaligned read(0x%p, 0x08%x, "
125                         "0x%x)!!\n", buf, addr, len);
126         }
127
128
129 }
130
131 /***********************************************************************
132  * resources of sibling devices
133  ***********************************************************************/
134
135 #if 0
136 static struct resource glamo_core_resources[] = {
137         {
138                 .start  = GLAMO_REGOFS_GENERIC,
139                 .end    = GLAMO_REGOFS_GENERIC + 0x400,
140                 .flags  = IORESOURCE_MEM,
141         }, {
142                 .start  = 0,
143                 .end    = 0,
144                 .flags  = IORESOURCE_IRQ,
145         },
146 };
147
148 static struct platform_device glamo_core_dev = {
149         .name           = "glamo-core",
150         .resource       = &glamo_core_resources,
151         .num_resources  = ARRAY_SIZE(glamo_core_resources),
152 };
153 #endif
154
155 static struct resource glamo_jpeg_resources[] = {
156         {
157                 .start  = GLAMO_REGOFS_JPEG,
158                 .end    = GLAMO_REGOFS_MPEG - 1,
159                 .flags  = IORESOURCE_MEM,
160         }, {
161                 .start  = IRQ_GLAMO_JPEG,
162                 .end    = IRQ_GLAMO_JPEG,
163                 .flags  = IORESOURCE_IRQ,
164         },
165 };
166
167 static struct platform_device glamo_jpeg_dev = {
168         .name           = "glamo-jpeg",
169         .resource       = glamo_jpeg_resources,
170         .num_resources  = ARRAY_SIZE(glamo_jpeg_resources),
171 };
172
173 static struct resource glamo_mpeg_resources[] = {
174         {
175                 .start  = GLAMO_REGOFS_MPEG,
176                 .end    = GLAMO_REGOFS_LCD - 1,
177                 .flags  = IORESOURCE_MEM,
178         }, {
179                 .start  = IRQ_GLAMO_MPEG,
180                 .end    = IRQ_GLAMO_MPEG,
181                 .flags  = IORESOURCE_IRQ,
182         },
183 };
184
185 static struct platform_device glamo_mpeg_dev = {
186         .name           = "glamo-mpeg",
187         .resource       = glamo_mpeg_resources,
188         .num_resources  = ARRAY_SIZE(glamo_mpeg_resources),
189 };
190
191 static struct resource glamo_2d_resources[] = {
192         {
193                 .start  = GLAMO_REGOFS_2D,
194                 .end    = GLAMO_REGOFS_3D - 1,
195                 .flags  = IORESOURCE_MEM,
196         }, {
197                 .start  = IRQ_GLAMO_2D,
198                 .end    = IRQ_GLAMO_2D,
199                 .flags  = IORESOURCE_IRQ,
200         },
201 };
202
203 static struct platform_device glamo_2d_dev = {
204         .name           = "glamo-2d",
205         .resource       = glamo_2d_resources,
206         .num_resources  = ARRAY_SIZE(glamo_2d_resources),
207 };
208
209 static struct resource glamo_3d_resources[] = {
210         {
211                 .start  = GLAMO_REGOFS_3D,
212                 .end    = GLAMO_REGOFS_END - 1,
213                 .flags  = IORESOURCE_MEM,
214         },
215 };
216
217 static struct platform_device glamo_3d_dev = {
218         .name           = "glamo-3d",
219         .resource       = glamo_3d_resources,
220         .num_resources  = ARRAY_SIZE(glamo_3d_resources),
221 };
222
223 static struct platform_device glamo_spigpio_dev = {
224         .name           = "glamo-spi-gpio",
225 };
226
227 static struct resource glamo_fb_resources[] = {
228         /* FIXME: those need to be incremented by parent base */
229         {
230                 .name   = "glamo-fb-regs",
231                 .start  = GLAMO_REGOFS_LCD,
232                 .end    = GLAMO_REGOFS_MMC - 1,
233                 .flags  = IORESOURCE_MEM,
234         }, {
235                 .name   = "glamo-fb-mem",
236                 .start  = GLAMO_OFFSET_FB,
237                 .end    = GLAMO_OFFSET_FB + GLAMO_FB_SIZE - 1,
238                 .flags  = IORESOURCE_MEM,
239         },
240 };
241
242 static struct platform_device glamo_fb_dev = {
243         .name           = "glamo-fb",
244         .resource       = glamo_fb_resources,
245         .num_resources  = ARRAY_SIZE(glamo_fb_resources),
246 };
247
248 static struct resource glamo_mmc_resources[] = {
249         {
250                 /* FIXME: those need to be incremented by parent base */
251                 .start  = GLAMO_REGOFS_MMC,
252                 .end    = GLAMO_REGOFS_MPROC0 - 1,
253                 .flags  = IORESOURCE_MEM
254         }, {
255                 .start  = IRQ_GLAMO_MMC,
256                 .end    = IRQ_GLAMO_MMC,
257                 .flags  = IORESOURCE_IRQ,
258         }, { /* our data buffer for MMC transfers */
259                 .start  = GLAMO_OFFSET_FB + GLAMO_FB_SIZE,
260                 .end    = GLAMO_OFFSET_FB + GLAMO_FB_SIZE +
261                                   GLAMO_MMC_BUFFER_SIZE - 1,
262                 .flags  = IORESOURCE_MEM
263         },
264 };
265
266 static struct platform_device glamo_mmc_dev = {
267         .name           = "glamo-mci",
268         .resource       = glamo_mmc_resources,
269         .num_resources  = ARRAY_SIZE(glamo_mmc_resources),
270 };
271
272 struct glamo_mci_pdata glamo_mci_def_pdata = {
273         .gpio_detect            = 0,
274         .glamo_set_mci_power    = NULL, /* filled in from MFD platform data */
275         .ocr_avail      = MMC_VDD_20_21 |
276                           MMC_VDD_21_22 |
277                           MMC_VDD_22_23 |
278                           MMC_VDD_23_24 |
279                           MMC_VDD_24_25 |
280                           MMC_VDD_25_26 |
281                           MMC_VDD_26_27 |
282                           MMC_VDD_27_28 |
283                           MMC_VDD_28_29 |
284                           MMC_VDD_29_30 |
285                           MMC_VDD_30_31 |
286                           MMC_VDD_32_33,
287         .glamo_irq_is_wired     = NULL, /* filled in from MFD platform data */
288         .mci_suspending = NULL, /* filled in from MFD platform data */
289         .mci_all_dependencies_resumed = NULL, /* filled in from MFD platform data */
290 };
291 EXPORT_SYMBOL_GPL(glamo_mci_def_pdata);
292
293
294
295 static void mangle_mem_resources(struct resource *res, int num_res,
296                                  struct resource *parent)
297 {
298         int i;
299
300         for (i = 0; i < num_res; i++) {
301                 if (res[i].flags != IORESOURCE_MEM)
302                         continue;
303                 res[i].start += parent->start;
304                 res[i].end += parent->start;
305                 res[i].parent = parent;
306         }
307 }
308
309 /***********************************************************************
310  * IRQ demultiplexer
311  ***********************************************************************/
312 #define irq2glamo(x)    (x - IRQ_GLAMO(0))
313
314 static void glamo_ack_irq(unsigned int irq)
315 {
316         /* clear interrupt source */
317         __reg_write(glamo_handle, GLAMO_REG_IRQ_CLEAR,
318                     1 << irq2glamo(irq));
319 }
320
321 static void glamo_mask_irq(unsigned int irq)
322 {
323         u_int16_t tmp;
324
325         /* clear bit in enable register */
326         tmp = __reg_read(glamo_handle, GLAMO_REG_IRQ_ENABLE);
327         tmp &= ~(1 << irq2glamo(irq));
328         __reg_write(glamo_handle, GLAMO_REG_IRQ_ENABLE, tmp);
329 }
330
331 static void glamo_unmask_irq(unsigned int irq)
332 {
333         u_int16_t tmp;
334
335         /* set bit in enable register */
336         tmp = __reg_read(glamo_handle, GLAMO_REG_IRQ_ENABLE);
337         tmp |= (1 << irq2glamo(irq));
338         __reg_write(glamo_handle, GLAMO_REG_IRQ_ENABLE, tmp);
339 }
340
341 static struct irq_chip glamo_irq_chip = {
342         .ack    = glamo_ack_irq,
343         .mask   = glamo_mask_irq,
344         .unmask = glamo_unmask_irq,
345 };
346
347 static void glamo_irq_demux_handler(unsigned int irq, struct irq_desc *desc)
348 {
349         const unsigned int cpu = smp_processor_id();
350
351         spin_lock(&desc->lock);
352
353         desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
354
355         if (unlikely(desc->status & IRQ_INPROGRESS)) {
356                 desc->status |= (IRQ_PENDING | IRQ_MASKED);
357                 desc->chip->mask(irq);
358                 desc->chip->ack(irq);
359                 goto out_unlock;
360         }
361
362         kstat_cpu(cpu).irqs[irq]++;
363         desc->chip->ack(irq);
364         desc->status |= IRQ_INPROGRESS;
365
366         do {
367                 u_int16_t irqstatus;
368                 int i;
369
370                 if (unlikely((desc->status &
371                                 (IRQ_PENDING | IRQ_MASKED | IRQ_DISABLED)) ==
372                                 (IRQ_PENDING | IRQ_MASKED))) {
373                         /* dealing with pending IRQ, unmasking */
374                         desc->chip->unmask(irq);
375                         desc->status &= ~IRQ_MASKED;
376                 }
377
378                 desc->status &= ~IRQ_PENDING;
379
380                 /* read IRQ status register */
381                 irqstatus = __reg_read(glamo_handle, GLAMO_REG_IRQ_STATUS);
382                 for (i = 0; i < 9; i++)
383                         if (irqstatus & (1 << i))
384                                 desc_handle_irq(IRQ_GLAMO(i),
385                                     irq_desc+IRQ_GLAMO(i));
386
387         } while ((desc->status & (IRQ_PENDING | IRQ_DISABLED)) == IRQ_PENDING);
388
389         desc->status &= ~IRQ_INPROGRESS;
390
391 out_unlock:
392         spin_unlock(&desc->lock);
393 }
394
395 /***********************************************************************
396  * 'engine' support
397  ***********************************************************************/
398
399 int __glamo_engine_enable(struct glamo_core *glamo, enum glamo_engine engine)
400 {
401         switch (engine) {
402         case GLAMO_ENGINE_LCD:
403                 __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_LCD,
404                             GLAMO_CLOCK_LCD_EN_M5CLK |
405                             GLAMO_CLOCK_LCD_EN_DHCLK |
406                             GLAMO_CLOCK_LCD_EN_DMCLK |
407                             GLAMO_CLOCK_LCD_EN_DCLK |
408                             GLAMO_CLOCK_LCD_DG_M5CLK |
409                             GLAMO_CLOCK_LCD_DG_DMCLK, 0xffff);
410                 __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_GEN5_1,
411                             GLAMO_CLOCK_GEN51_EN_DIV_DHCLK |
412                             GLAMO_CLOCK_GEN51_EN_DIV_DMCLK |
413                             GLAMO_CLOCK_GEN51_EN_DIV_DCLK, 0xffff);
414                 __reg_set_bit_mask(glamo, GLAMO_REG_HOSTBUS(2),
415                             GLAMO_HOSTBUS2_MMIO_EN_LCD,
416                             0xffff);
417                 break;
418         case GLAMO_ENGINE_MMC:
419                 __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_MMC,
420                                    GLAMO_CLOCK_MMC_EN_M9CLK |
421                                    GLAMO_CLOCK_MMC_EN_TCLK |
422                                    GLAMO_CLOCK_MMC_DG_M9CLK |
423                                    GLAMO_CLOCK_MMC_DG_TCLK, 0xffff);
424                 __reg_set_bit_mask(glamo, GLAMO_REG_HOSTBUS(2),
425                                    GLAMO_HOSTBUS2_MMIO_EN_MMC,
426                                    GLAMO_HOSTBUS2_MMIO_EN_MMC);
427                 break;
428         case GLAMO_ENGINE_2D:
429                 __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_2D,
430                                    GLAMO_CLOCK_2D_EN_M7CLK |
431                                    GLAMO_CLOCK_2D_EN_GCLK |
432                                    GLAMO_CLOCK_2D_DG_M7CLK |
433                                    GLAMO_CLOCK_2D_DG_GCLK, 0xffff);
434                 __reg_set_bit_mask(glamo, GLAMO_REG_HOSTBUS(2),
435                                    GLAMO_HOSTBUS2_MMIO_EN_2D,
436                                    GLAMO_HOSTBUS2_MMIO_EN_2D);
437                 break;
438         case GLAMO_ENGINE_CMDQ:
439                 __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_2D,
440                                    GLAMO_CLOCK_2D_EN_M6CLK, 0xffff);
441                 __reg_set_bit_mask(glamo, GLAMO_REG_HOSTBUS(2),
442                                    GLAMO_HOSTBUS2_MMIO_EN_CQ,
443                                    GLAMO_HOSTBUS2_MMIO_EN_CQ);
444                 break;
445         /* FIXME: Implementation */
446         default:
447                 break;
448         }
449
450         glamo->engine_enabled_bitfield |= 1 << engine;
451
452         return 0;
453 }
454
455 int glamo_engine_enable(struct glamo_core *glamo, enum glamo_engine engine)
456 {
457         int ret;
458
459         spin_lock(&glamo->lock);
460
461         ret = __glamo_engine_enable(glamo, engine);
462
463         spin_unlock(&glamo->lock);
464
465         return ret;
466 }
467 EXPORT_SYMBOL_GPL(glamo_engine_enable);
468
469 int __glamo_engine_disable(struct glamo_core *glamo, enum glamo_engine engine)
470 {
471         switch (engine) {
472         case GLAMO_ENGINE_LCD:
473                 /* remove pixel clock to LCM */
474                 __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_LCD,
475                             GLAMO_CLOCK_LCD_EN_DCLK, 0);
476                 __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_LCD,
477                             GLAMO_CLOCK_LCD_EN_DHCLK |
478                             GLAMO_CLOCK_LCD_EN_DMCLK, 0);
479                 /* kill memory clock */
480                 __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_LCD,
481                             GLAMO_CLOCK_LCD_EN_M5CLK, 0);
482                 /* stop dividing the clocks */
483                 __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_GEN5_1,
484                             GLAMO_CLOCK_GEN51_EN_DIV_DHCLK |
485                             GLAMO_CLOCK_GEN51_EN_DIV_DMCLK |
486                             GLAMO_CLOCK_GEN51_EN_DIV_DCLK, 0);
487                 __reg_set_bit_mask(glamo, GLAMO_REG_HOSTBUS(2),
488                             GLAMO_HOSTBUS2_MMIO_EN_LCD, 0);
489                 break;
490
491         case GLAMO_ENGINE_MMC:
492                 __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_MMC, 0,
493                                                    GLAMO_CLOCK_MMC_EN_M9CLK |
494                                                    GLAMO_CLOCK_MMC_EN_TCLK |
495                                                    GLAMO_CLOCK_MMC_DG_M9CLK |
496                                                    GLAMO_CLOCK_MMC_DG_TCLK);
497                 /* disable the TCLK divider clk input */
498                 __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_GEN5_1, 0,
499                                                 GLAMO_CLOCK_GEN51_EN_DIV_TCLK);
500                 __reg_set_bit_mask(glamo, GLAMO_REG_HOSTBUS(2), 0,
501                                                    GLAMO_HOSTBUS2_MMIO_EN_MMC);
502                 /* good idea to hold the thing in reset when we power it off? */
503 /*              writew(readw(glamo->base + GLAMO_REG_CLOCK_MMC) |
504                       GLAMO_CLOCK_MMC_RESET, glamo->base + GLAMO_REG_CLOCK_MMC);
505 */
506                 break;
507         default:
508                 break;
509         }
510
511         glamo->engine_enabled_bitfield &= ~(1 << engine);
512
513         return 0;
514 }
515 int glamo_engine_disable(struct glamo_core *glamo, enum glamo_engine engine)
516 {
517         int ret;
518
519         spin_lock(&glamo->lock);
520
521         ret = __glamo_engine_disable(glamo, engine);
522
523         spin_unlock(&glamo->lock);
524
525         return ret;
526 }
527 EXPORT_SYMBOL_GPL(glamo_engine_disable);
528
529 static const u_int16_t engine_clock_regs[__NUM_GLAMO_ENGINES] = {
530         [GLAMO_ENGINE_LCD]      = GLAMO_REG_CLOCK_LCD,
531         [GLAMO_ENGINE_MMC]      = GLAMO_REG_CLOCK_MMC,
532         [GLAMO_ENGINE_ISP]      = GLAMO_REG_CLOCK_ISP,
533         [GLAMO_ENGINE_JPEG]     = GLAMO_REG_CLOCK_JPEG,
534         [GLAMO_ENGINE_3D]       = GLAMO_REG_CLOCK_3D,
535         [GLAMO_ENGINE_2D]       = GLAMO_REG_CLOCK_2D,
536         [GLAMO_ENGINE_MPEG_ENC] = GLAMO_REG_CLOCK_MPEG,
537         [GLAMO_ENGINE_MPEG_DEC] = GLAMO_REG_CLOCK_MPEG,
538 };
539
540 void glamo_engine_clkreg_set(struct glamo_core *glamo,
541                              enum glamo_engine engine,
542                              u_int16_t mask, u_int16_t val)
543 {
544         reg_set_bit_mask(glamo, engine_clock_regs[engine], mask, val);
545 }
546 EXPORT_SYMBOL_GPL(glamo_engine_clkreg_set);
547
548 u_int16_t glamo_engine_clkreg_get(struct glamo_core *glamo,
549                                   enum glamo_engine engine)
550 {
551         u_int16_t val;
552
553         spin_lock(&glamo->lock);
554         val = __reg_read(glamo, engine_clock_regs[engine]);
555         spin_unlock(&glamo->lock);
556
557         return val;
558 }
559 EXPORT_SYMBOL_GPL(glamo_engine_clkreg_get);
560
561 struct glamo_script reset_regs[] = {
562         [GLAMO_ENGINE_LCD] = {
563                 GLAMO_REG_CLOCK_LCD, GLAMO_CLOCK_LCD_RESET
564         },
565 #if 0
566         [GLAMO_ENGINE_HOST] = {
567                 GLAMO_REG_CLOCK_HOST, GLAMO_CLOCK_HOST_RESET
568         },
569         [GLAMO_ENGINE_MEM] = {
570                 GLAMO_REG_CLOCK_MEM, GLAMO_CLOCK_MEM_RESET
571         },
572 #endif
573         [GLAMO_ENGINE_MMC] = {
574                 GLAMO_REG_CLOCK_MMC, GLAMO_CLOCK_MMC_RESET
575         },
576         [GLAMO_ENGINE_2D] = {
577                 GLAMO_REG_CLOCK_2D, GLAMO_CLOCK_2D_RESET
578         },
579         [GLAMO_ENGINE_JPEG] = {
580                 GLAMO_REG_CLOCK_JPEG, GLAMO_CLOCK_JPEG_RESET
581         },
582 };
583
584 void glamo_engine_reset(struct glamo_core *glamo, enum glamo_engine engine)
585 {
586         struct glamo_script *rst;
587
588         if (engine >= ARRAY_SIZE(reset_regs)) {
589                 dev_warn(&glamo->pdev->dev, "unknown engine %u ", engine);
590                 return;
591         }
592
593         rst = &reset_regs[engine];
594
595         spin_lock(&glamo->lock);
596         __reg_set_bit(glamo, rst->reg, rst->val);
597         spin_unlock(&glamo->lock);
598
599         msleep(1);
600
601         spin_lock(&glamo->lock);
602         __reg_clear_bit(glamo, rst->reg, rst->val);
603         spin_unlock(&glamo->lock);
604
605         msleep(1);
606 }
607 EXPORT_SYMBOL_GPL(glamo_engine_reset);
608
609 void glamo_lcm_reset(int level)
610 {
611         if (!glamo_handle)
612                 return;
613
614         glamo_gpio_setpin(glamo_handle, GLAMO_GPIO4, level);
615         glamo_gpio_cfgpin(glamo_handle, GLAMO_GPIO4_OUTPUT);
616
617 }
618 EXPORT_SYMBOL_GPL(glamo_lcm_reset);
619
620 enum glamo_pll {
621         GLAMO_PLL1,
622         GLAMO_PLL2,
623 };
624
625 static int glamo_pll_rate(struct glamo_core *glamo,
626                           enum glamo_pll pll)
627 {
628         u_int16_t reg;
629         unsigned int div = 512;
630         /* FIXME: move osci into platform_data */
631         unsigned int osci = 32768;
632
633         if (osci == 32768)
634                 div = 1;
635
636         switch (pll) {
637         case GLAMO_PLL1:
638                 reg = __reg_read(glamo, GLAMO_REG_PLL_GEN1);
639                 break;
640         case GLAMO_PLL2:
641                 reg = __reg_read(glamo, GLAMO_REG_PLL_GEN3);
642                 break;
643         default:
644                 return -EINVAL;
645         }
646         return (osci/div)*reg;
647 }
648
649 int glamo_engine_reclock(struct glamo_core *glamo,
650                          enum glamo_engine engine,
651                          int ps)
652 {
653         int pll, khz;
654         u_int16_t reg, mask, val = 0;
655
656         if (!ps)
657                 return 0;
658
659         switch (engine) {
660         case GLAMO_ENGINE_LCD:
661                 pll = GLAMO_PLL1;
662                 reg = GLAMO_REG_CLOCK_GEN7;
663                 mask = 0xff;
664                 break;
665         default:
666                 dev_warn(&glamo->pdev->dev,
667                          "reclock of engine 0x%x not supported\n", engine);
668                 return -EINVAL;
669                 break;
670         }
671
672         pll = glamo_pll_rate(glamo, pll);
673         khz = 1000000000UL / ps;
674
675         if (khz)
676                 val = (pll / khz) / 1000;
677
678         dev_dbg(&glamo->pdev->dev,
679                         "PLL %d, kHZ %d, div %d\n", pll, khz, val);
680
681         if (val) {
682                 val--;
683                 reg_set_bit_mask(glamo, reg, mask, val);
684                 mdelay(5); /* wait some time to stabilize */
685
686                 return 0;
687         } else {
688                 return -EINVAL;
689         }
690 }
691 EXPORT_SYMBOL_GPL(glamo_engine_reclock);
692
693 /***********************************************************************
694  * script support
695  ***********************************************************************/
696
697 int glamo_run_script(struct glamo_core *glamo, struct glamo_script *script,
698                      int len, int may_sleep)
699 {
700         int i;
701
702         for (i = 0; i < len; i++) {
703                 struct glamo_script *line = &script[i];
704
705                 switch (line->reg) {
706                 case 0xffff:
707                         return 0;
708                 case 0xfffe:
709                         if (may_sleep)
710                                 msleep(line->val);
711                         else
712                                 mdelay(line->val * 4);
713                         break;
714                 case 0xfffd:
715                         /* spin until PLLs lock */
716                         while ((__reg_read(glamo, GLAMO_REG_PLL_GEN5) & 3) != 3)
717                                 ;
718                         break;
719                 default:
720                         __reg_write(glamo, script[i].reg, script[i].val);
721                         break;
722                 }
723         }
724
725         return 0;
726 }
727 EXPORT_SYMBOL(glamo_run_script);
728
729 static struct glamo_script glamo_init_script[] = {
730         { GLAMO_REG_CLOCK_HOST,         0x1000 },
731                 { 0xfffe, 2 },
732         { GLAMO_REG_CLOCK_MEMORY,       0x1000 },
733         { GLAMO_REG_CLOCK_MEMORY,       0x2000 },
734         { GLAMO_REG_CLOCK_LCD,          0x1000 },
735         { GLAMO_REG_CLOCK_MMC,          0x1000 },
736         { GLAMO_REG_CLOCK_ISP,          0x1000 },
737         { GLAMO_REG_CLOCK_ISP,          0x3000 },
738         { GLAMO_REG_CLOCK_JPEG,         0x1000 },
739         { GLAMO_REG_CLOCK_3D,           0x1000 },
740         { GLAMO_REG_CLOCK_3D,           0x3000 },
741         { GLAMO_REG_CLOCK_2D,           0x1000 },
742         { GLAMO_REG_CLOCK_2D,           0x3000 },
743         { GLAMO_REG_CLOCK_RISC1,        0x1000 },
744         { GLAMO_REG_CLOCK_MPEG,         0x3000 },
745         { GLAMO_REG_CLOCK_MPEG,         0x3000 },
746         { GLAMO_REG_CLOCK_MPROC,        0x1000 /*0x100f*/ },
747                 { 0xfffe, 2 },
748         { GLAMO_REG_CLOCK_HOST,         0x0000 },
749         { GLAMO_REG_CLOCK_MEMORY,       0x0000 },
750         { GLAMO_REG_CLOCK_LCD,          0x0000 },
751         { GLAMO_REG_CLOCK_MMC,          0x0000 },
752 #if 0
753 /* unused engines must be left in reset to stop MMC block read "blackouts" */
754         { GLAMO_REG_CLOCK_ISP,          0x0000 },
755         { GLAMO_REG_CLOCK_ISP,          0x0000 },
756         { GLAMO_REG_CLOCK_JPEG,         0x0000 },
757         { GLAMO_REG_CLOCK_3D,           0x0000 },
758         { GLAMO_REG_CLOCK_3D,           0x0000 },
759         { GLAMO_REG_CLOCK_2D,           0x0000 },
760         { GLAMO_REG_CLOCK_2D,           0x0000 },
761         { GLAMO_REG_CLOCK_RISC1,        0x0000 },
762         { GLAMO_REG_CLOCK_MPEG,         0x0000 },
763         { GLAMO_REG_CLOCK_MPEG,         0x0000 },
764 #endif
765         { GLAMO_REG_PLL_GEN1,           0x05db },       /* 48MHz */
766         { GLAMO_REG_PLL_GEN3,           0x0aba },       /* 90MHz */
767         { 0xfffd, 0 },
768         /*
769          * b9 of this register MUST be zero to get any interrupts on INT#
770          * the other set bits enable all the engine interrupt sources
771          */
772         { GLAMO_REG_IRQ_ENABLE,         0x01ff },
773         { GLAMO_REG_CLOCK_GEN6,         0x2000 },
774         { GLAMO_REG_CLOCK_GEN7,         0x0101 },
775         { GLAMO_REG_CLOCK_GEN8,         0x0100 },
776         { GLAMO_REG_CLOCK_HOST,         0x000d },
777         /*
778          * b7..b4 = 0 = no wait states on read or write
779          * b0 = 1 select PLL2 for Host interface, b1 = enable it
780          */
781         { 0x200,        0x0e03 },
782         { 0x202,        0x07ff },
783         { 0x212,        0x0000 },
784         { 0x214,        0x4000 },
785         { 0x216,        0xf00e },
786
787         /* S-Media recommended "set tiling mode to 512 mode for memory access
788          * more efficiency when 640x480" */
789         { GLAMO_REG_MEM_TYPE,           0x0c74 }, /* 8MB, 16 word pg wr+rd */
790         { GLAMO_REG_MEM_GEN,            0xafaf }, /* 63 grants min + max */
791
792         { GLAMO_REG_MEM_TIMING1,        0x0108 },
793         { GLAMO_REG_MEM_TIMING2,        0x0010 }, /* Taa = 3 MCLK */
794         { GLAMO_REG_MEM_TIMING3,        0x0000 },
795         { GLAMO_REG_MEM_TIMING4,        0x0000 }, /* CE1# delay fall/rise */
796         { GLAMO_REG_MEM_TIMING5,        0x0000 }, /* UB# LB# */
797         { GLAMO_REG_MEM_TIMING6,        0x0000 }, /* OE# */
798         { GLAMO_REG_MEM_TIMING7,        0x0000 }, /* WE# */
799         { GLAMO_REG_MEM_TIMING8,        0x1002 }, /* MCLK delay, was 0x1000 */
800         { GLAMO_REG_MEM_TIMING9,        0x6006 },
801         { GLAMO_REG_MEM_TIMING10,       0x00ff },
802         { GLAMO_REG_MEM_TIMING11,       0x0001 },
803         { GLAMO_REG_MEM_POWER1,         0x0020 },
804         { GLAMO_REG_MEM_POWER2,         0x0000 },
805         { GLAMO_REG_MEM_DRAM1,          0x0000 },
806                 { 0xfffe, 1 },
807         { GLAMO_REG_MEM_DRAM1,          0xc100 },
808                 { 0xfffe, 1 },
809         { GLAMO_REG_MEM_DRAM1,          0xe100 },
810         { GLAMO_REG_MEM_DRAM2,          0x01d6 },
811         { GLAMO_REG_CLOCK_MEMORY,       0x000b },
812 };
813
814
815 enum glamo_power {
816         GLAMO_POWER_ON,
817         GLAMO_POWER_SUSPEND,
818 };
819
820 static void glamo_power(struct glamo_core *glamo,
821                         enum glamo_power new_state)
822 {
823         int n;
824
825         spin_lock(&glamo->lock);
826
827         dev_dbg(&glamo->pdev->dev, "***** glamo_power -> %d\n", new_state);
828
829         switch (new_state) {
830         case GLAMO_POWER_ON:
831                 /* power up PLL1 and PLL2 */
832                 __reg_set_bit_mask(glamo, GLAMO_REG_DFT_GEN6, 0x0001, 0xffff);
833                 __reg_set_bit_mask(glamo, GLAMO_REG_PLL_GEN3, 0x2000, 0x0000);
834
835                 /* spin until PLL1 and PLL2 lock */
836                 while ((__reg_read(glamo, GLAMO_REG_PLL_GEN5) & 3) != 3)
837                         ;
838
839                 /* Get memory out of deep powerdown */
840
841                 __reg_write(glamo, GLAMO_REG_MEM_DRAM2,
842                                         (7 << 6) | /* tRC */
843                                         (1 << 4) | /* tRP */
844                                         (1 << 2) | /* tRCD */
845                                         2); /* CAS latency */
846
847                 /* Stop self-refresh */
848
849                 __reg_write(glamo, GLAMO_REG_MEM_DRAM1,
850                                         GLAMO_MEM_DRAM1_EN_DRAM_REFRESH |
851                                         GLAMO_MEM_DRAM1_EN_GATE_CKE |
852                                         GLAMO_MEM_REFRESH_COUNT);
853                 __reg_write(glamo, GLAMO_REG_MEM_DRAM1,
854                                         GLAMO_MEM_DRAM1_EN_MODEREG_SET |
855                                         GLAMO_MEM_DRAM1_EN_DRAM_REFRESH |
856                                         GLAMO_MEM_DRAM1_EN_GATE_CKE |
857                                         GLAMO_MEM_REFRESH_COUNT);
858
859                 /* re-enable clocks to memory */
860
861                 __reg_write(glamo, GLAMO_REG_CLOCK_MEMORY,
862                                         GLAMO_CLOCK_MEM_EN_MOCACLK |
863                                         GLAMO_CLOCK_MEM_EN_M1CLK |
864                                         GLAMO_CLOCK_MEM_DG_M1CLK);
865
866                 /* restore each engine that was up before suspend */
867                 for (n = 0; n < __NUM_GLAMO_ENGINES; n++)
868                         if (glamo->engine_enabled_bitfield_suspend & (1 << n))
869                                 __glamo_engine_enable(glamo, n);
870                 break;
871
872         case GLAMO_POWER_SUSPEND:
873                 /* stash a copy of which engines were running */
874                 glamo->engine_enabled_bitfield_suspend =
875                                                  glamo->engine_enabled_bitfield;
876
877                 /* take down each engine before we kill mem and pll */
878                 for (n = 0; n < __NUM_GLAMO_ENGINES; n++)
879                         if (glamo->engine_enabled_bitfield & (1 << n))
880                                 __glamo_engine_disable(glamo, n);
881
882                 /* enable self-refresh */
883
884                 __reg_write(glamo, GLAMO_REG_MEM_DRAM1,
885                                         GLAMO_MEM_DRAM1_EN_DRAM_REFRESH |
886                                         GLAMO_MEM_DRAM1_EN_GATE_CKE |
887                                         GLAMO_MEM_DRAM1_SELF_REFRESH |
888                                         GLAMO_MEM_REFRESH_COUNT);
889                 __reg_write(glamo, GLAMO_REG_MEM_DRAM1,
890                                         GLAMO_MEM_DRAM1_EN_MODEREG_SET |
891                                         GLAMO_MEM_DRAM1_EN_DRAM_REFRESH |
892                                         GLAMO_MEM_DRAM1_EN_GATE_CKE |
893                                         GLAMO_MEM_DRAM1_SELF_REFRESH |
894                                         GLAMO_MEM_REFRESH_COUNT);
895
896                 /* force RAM into deep powerdown */
897
898                 __reg_write(glamo, GLAMO_REG_MEM_DRAM2,
899                                         GLAMO_MEM_DRAM2_DEEP_PWRDOWN |
900                                         (7 << 6) | /* tRC */
901                                         (1 << 4) | /* tRP */
902                                         (1 << 2) | /* tRCD */
903                                         2); /* CAS latency */
904
905                 /* kill clocks to memory */
906
907                 __reg_write(glamo, GLAMO_REG_CLOCK_MEMORY, 0);
908
909                 /* power down PLL2 and then PLL1 */
910                 __reg_set_bit_mask(glamo, GLAMO_REG_PLL_GEN3, 0x2000, 0xffff);
911                 __reg_set_bit_mask(glamo, GLAMO_REG_DFT_GEN5, 0x0001, 0xffff);
912                 break;
913         }
914
915         spin_unlock(&glamo->lock);
916 }
917
918 #if 0
919 #define MEMDETECT_RETRY 6
920 static unsigned int detect_memsize(struct glamo_core *glamo)
921 {
922         int i;
923
924         /*static const u_int16_t pattern[] = {
925                 0x1111, 0x8a8a, 0x2222, 0x7a7a,
926                 0x3333, 0x6a6a, 0x4444, 0x5a5a,
927                 0x5555, 0x4a4a, 0x6666, 0x3a3a,
928                 0x7777, 0x2a2a, 0x8888, 0x1a1a
929         }; */
930
931         for (i = 0; i < MEMDETECT_RETRY; i++) {
932                 switch (glamo->type) {
933                 case 3600:
934                         __reg_write(glamo, GLAMO_REG_MEM_TYPE, 0x0072);
935                         __reg_write(glamo, GLAMO_REG_MEM_DRAM1, 0xc100);
936                         break;
937                 case 3650:
938                         switch (glamo->revision) {
939                         case GLAMO_CORE_REV_A0:
940                                 if (i & 1)
941                                         __reg_write(glamo, GLAMO_REG_MEM_TYPE,
942                                                     0x097a);
943                                 else
944                                         __reg_write(glamo, GLAMO_REG_MEM_TYPE,
945                                                     0x0173);
946
947                                 __reg_write(glamo, GLAMO_REG_MEM_DRAM1, 0x0000);
948                                 msleep(1);
949                                 __reg_write(glamo, GLAMO_REG_MEM_DRAM1, 0xc100);
950                                 break;
951                         default:
952                                 if (i & 1)
953                                         __reg_write(glamo, GLAMO_REG_MEM_TYPE,
954                                                     0x0972);
955                                 else
956                                         __reg_write(glamo, GLAMO_REG_MEM_TYPE,
957                                                     0x0872);
958
959                                 __reg_write(glamo, GLAMO_REG_MEM_DRAM1, 0x0000);
960                                 msleep(1);
961                                 __reg_write(glamo, GLAMO_REG_MEM_DRAM1, 0xe100);
962                                 break;
963                         }
964                         break;
965                 case 3700:
966                         /* FIXME */
967                 default:
968                         break;
969                 }
970
971 #if 0
972                 /* FIXME: finish implementation */
973                 for (j = 0; j < 8; j++) {
974                         __
975 #endif
976         }
977
978         return 0;
979 }
980 #endif
981
982 /* Find out if we can support this version of the Glamo chip */
983 static int glamo_supported(struct glamo_core *glamo)
984 {
985         u_int16_t dev_id, rev_id; /*, memsize; */
986
987         dev_id = __reg_read(glamo, GLAMO_REG_DEVICE_ID);
988         rev_id = __reg_read(glamo, GLAMO_REG_REVISION_ID);
989
990         switch (dev_id) {
991         case 0x3650:
992                 switch (rev_id) {
993                 case GLAMO_CORE_REV_A2:
994                         break;
995                 case GLAMO_CORE_REV_A0:
996                 case GLAMO_CORE_REV_A1:
997                 case GLAMO_CORE_REV_A3:
998                         dev_warn(&glamo->pdev->dev, "untested core revision "
999                                  "%04x, your mileage may vary\n", rev_id);
1000                         break;
1001                 default:
1002                         dev_warn(&glamo->pdev->dev, "unknown glamo revision "
1003                                  "%04x, your mileage may vary\n", rev_id);
1004                         /* maybe should abort ? */
1005                 }
1006                 break;
1007         case 0x3600:
1008         case 0x3700:
1009         default:
1010                 dev_err(&glamo->pdev->dev, "unsupported Glamo device %04x\n",
1011                         dev_id);
1012                 return 0;
1013         }
1014
1015         dev_info(&glamo->pdev->dev, "Detected Glamo core %04x Revision %04x "
1016                  "(%uHz CPU / %uHz Memory)\n", dev_id, rev_id,
1017                  glamo_pll_rate(glamo, GLAMO_PLL1),
1018                  glamo_pll_rate(glamo, GLAMO_PLL2));
1019
1020         return 1;
1021 }
1022
1023 static ssize_t regs_write(struct device *dev, struct device_attribute *attr,
1024                            const char *buf, size_t count)
1025 {
1026         unsigned long reg = simple_strtoul(buf, NULL, 10);
1027         struct glamo_core *glamo = dev_get_drvdata(dev);
1028
1029         while (*buf && (*buf != ' '))
1030                 buf++;
1031         if (*buf != ' ')
1032                 return -EINVAL;
1033         while (*buf && (*buf == ' '))
1034                 buf++;
1035         if (!*buf)
1036                 return -EINVAL;
1037
1038         printk(KERN_INFO"reg 0x%02lX <-- 0x%04lX\n",
1039                reg, simple_strtoul(buf, NULL, 10));
1040
1041         __reg_write(glamo, reg, simple_strtoul(buf, NULL, 10));
1042
1043         return count;
1044 }
1045
1046 static ssize_t regs_read(struct device *dev, struct device_attribute *attr,
1047                         char *buf)
1048 {
1049         struct glamo_core *glamo = dev_get_drvdata(dev);
1050         int n, n1 = 0, r;
1051         char * end = buf;
1052         struct reg_range {
1053                 int start;
1054                 int count;
1055                 char * name;
1056         };
1057         struct reg_range reg_range[] = {
1058                 { 0x0000, 0x76, "General" },
1059 /*              { 0x0200, 0x100, "Host Bus" },
1060 */              { 0x0300, 0x38, "Memory" },
1061 /*              { 0x0400, 0x100, "Sensor" },
1062                 { 0x0500, 0x300, "ISP" },
1063                 { 0x0800, 0x400, "JPEG" },
1064                 { 0x0c00, 0x500, "MPEG" },
1065 */
1066                 { 0x1100, 0x88, "LCD" },
1067 /*
1068                 { 0x1500, 0x080, "MPU 0" },
1069                 { 0x1580, 0x080, "MPU 1" },
1070                 { 0x1600, 0x080, "Command Queue" },
1071                 { 0x1680, 0x080, "RISC CPU" },
1072                 { 0x1700, 0x400, "2D Unit" },
1073                 { 0x1b00, 0x900, "3D Unit" },
1074 */
1075         };
1076
1077         spin_lock(&glamo->lock);
1078
1079         for (r = 0; r < ARRAY_SIZE(reg_range); r++) {
1080                 n1 = 0;
1081                 end += sprintf(end, "\n%s\n", reg_range[r].name);
1082                 for (n = reg_range[r].start;
1083                      n < reg_range[r].start + reg_range[r].count; n += 2) {
1084                         if (((n1++) & 7) == 0)
1085                                 end += sprintf(end, "\n%04X:  ", n);
1086                         end += sprintf(end, "%04x ", __reg_read(glamo, n));
1087                 }
1088                 end += sprintf(end, "\n");
1089         }
1090         spin_unlock(&glamo->lock);
1091
1092         return end - buf;
1093 }
1094
1095 static DEVICE_ATTR(regs, 0644, regs_read, regs_write);
1096 static struct attribute *glamo_sysfs_entries[] = {
1097         &dev_attr_regs.attr,
1098         NULL
1099 };
1100 static struct attribute_group glamo_attr_group = {
1101         .name   = NULL,
1102         .attrs  = glamo_sysfs_entries,
1103 };
1104
1105
1106
1107 static int __init glamo_probe(struct platform_device *pdev)
1108 {
1109         int rc = 0, irq;
1110         struct glamo_core *glamo;
1111
1112         if (glamo_handle) {
1113                 dev_err(&pdev->dev,
1114                         "This driver supports only one instance\n");
1115                 return -EBUSY;
1116         }
1117
1118         glamo = kmalloc(GFP_KERNEL, sizeof(*glamo));
1119         if (!glamo)
1120                 return -ENOMEM;
1121
1122         spin_lock_init(&glamo->lock);
1123         glamo_handle = glamo;
1124         glamo->pdev = pdev;
1125         glamo->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1126         glamo->irq = platform_get_irq(pdev, 0);
1127         glamo->pdata = pdev->dev.platform_data;
1128         if (!glamo->mem || !glamo->pdata) {
1129                 dev_err(&pdev->dev, "platform device with no MEM/PDATA ?\n");
1130                 rc = -ENOENT;
1131                 goto out_free;
1132         }
1133
1134         init_resume_dependency_list(&glamo->resume_dependency);
1135
1136         /* register a number of sibling devices whoise IOMEM resources
1137          * are siblings of pdev's IOMEM resource */
1138 #if 0
1139         glamo_core_dev.dev.parent = &pdev.dev;
1140         mangle_mem_resources(glamo_core_dev.resources,
1141                              glamo_core_dev.num_resources, glamo->mem);
1142         glamo_core_dev.resources[1].start = glamo->irq;
1143         glamo_core_dev.resources[1].end = glamo->irq;
1144         platform_device_register(&glamo_core_dev);
1145 #endif
1146         /* only remap the generic, hostbus and memory controller registers */
1147         glamo->base = ioremap(glamo->mem->start, 0x4000 /*GLAMO_REGOFS_VIDCAP*/);
1148         if (!glamo->base) {
1149                 dev_err(&pdev->dev, "failed to ioremap() memory region\n");
1150                 goto out_free;
1151         }
1152
1153         /* bring MCI specific stuff over from our MFD platform data */
1154         glamo_mci_def_pdata.glamo_set_mci_power =
1155                                         glamo->pdata->glamo_set_mci_power;
1156         glamo_mci_def_pdata.glamo_mci_use_slow =
1157                                         glamo->pdata->glamo_mci_use_slow;
1158         glamo_mci_def_pdata.glamo_irq_is_wired =
1159                                         glamo->pdata->glamo_irq_is_wired;
1160         glamo_mci_def_pdata.mci_suspending =
1161                                         glamo->pdata->mci_suspending;
1162         glamo_mci_def_pdata.mci_all_dependencies_resumed =
1163                                 glamo->pdata->mci_all_dependencies_resumed;
1164
1165         glamo_2d_dev.dev.parent = &pdev->dev;
1166         mangle_mem_resources(glamo_2d_dev.resource,
1167                              glamo_2d_dev.num_resources, glamo->mem);
1168         platform_device_register(&glamo_2d_dev);
1169
1170         glamo_3d_dev.dev.parent = &pdev->dev;
1171         mangle_mem_resources(glamo_3d_dev.resource,
1172                              glamo_3d_dev.num_resources, glamo->mem);
1173         platform_device_register(&glamo_3d_dev);
1174
1175         glamo_jpeg_dev.dev.parent = &pdev->dev;
1176         mangle_mem_resources(glamo_jpeg_dev.resource,
1177                              glamo_jpeg_dev.num_resources, glamo->mem);
1178         platform_device_register(&glamo_jpeg_dev);
1179
1180         glamo_mpeg_dev.dev.parent = &pdev->dev;
1181         mangle_mem_resources(glamo_mpeg_dev.resource,
1182                              glamo_mpeg_dev.num_resources, glamo->mem);
1183         platform_device_register(&glamo_mpeg_dev);
1184
1185         glamo->pdata->glamo = glamo;
1186         glamo_fb_dev.dev.parent = &pdev->dev;
1187         glamo_fb_dev.dev.platform_data = glamo->pdata;
1188         mangle_mem_resources(glamo_fb_dev.resource,
1189                              glamo_fb_dev.num_resources, glamo->mem);
1190         platform_device_register(&glamo_fb_dev);
1191
1192         glamo->pdata->spigpio_info->glamo = glamo;
1193         glamo_spigpio_dev.dev.parent = &pdev->dev;
1194         glamo_spigpio_dev.dev.platform_data = glamo->pdata->spigpio_info;
1195         platform_device_register(&glamo_spigpio_dev);
1196
1197         glamo_mmc_dev.dev.parent = &pdev->dev;
1198         /* we need it later to give to the engine enable and disable */
1199         glamo_mci_def_pdata.pglamo = glamo;
1200         mangle_mem_resources(glamo_mmc_dev.resource,
1201                              glamo_mmc_dev.num_resources, glamo->mem);
1202         platform_device_register(&glamo_mmc_dev);
1203
1204         /* only request the generic, hostbus and memory controller MMIO */
1205         glamo->mem = request_mem_region(glamo->mem->start,
1206                                         GLAMO_REGOFS_VIDCAP, "glamo-core");
1207         if (!glamo->mem) {
1208                 dev_err(&pdev->dev, "failed to request memory region\n");
1209                 goto out_free;
1210         }
1211
1212         if (!glamo_supported(glamo)) {
1213                 dev_err(&pdev->dev, "This Glamo is not supported\n");
1214                 goto out_free;
1215         }
1216
1217         rc = sysfs_create_group(&pdev->dev.kobj, &glamo_attr_group);
1218         if (rc < 0) {
1219                 dev_err(&pdev->dev, "cannot create sysfs group\n");
1220                 goto out_free;
1221         }
1222
1223         platform_set_drvdata(pdev, glamo);
1224
1225         dev_dbg(&glamo->pdev->dev, "running init script\n");
1226         glamo_run_script(glamo, glamo_init_script,
1227                          ARRAY_SIZE(glamo_init_script), 1);
1228
1229         dev_info(&glamo->pdev->dev, "Glamo core now %uHz CPU / %uHz Memory)\n",
1230                  glamo_pll_rate(glamo, GLAMO_PLL1),
1231                  glamo_pll_rate(glamo, GLAMO_PLL2));
1232
1233         glamo_lcm_reset(1);
1234
1235         for (irq = IRQ_GLAMO(0); irq <= IRQ_GLAMO(8); irq++) {
1236                 set_irq_chip(irq, &glamo_irq_chip);
1237                 set_irq_handler(irq, handle_level_irq);
1238                 set_irq_flags(irq, IRQF_VALID);
1239         }
1240
1241         if (glamo->pdata->glamo_irq_is_wired &&
1242             !glamo->pdata->glamo_irq_is_wired()) {
1243                 set_irq_chained_handler(glamo->irq, glamo_irq_demux_handler);
1244                 set_irq_type(glamo->irq, IRQ_TYPE_EDGE_FALLING);
1245                 glamo->irq_works = 1;
1246         } else
1247                 glamo->irq_works = 0;
1248
1249         return 0;
1250
1251 out_free:
1252         glamo_handle = NULL;
1253         kfree(glamo);
1254         return rc;
1255 }
1256
1257 static int glamo_remove(struct platform_device *pdev)
1258 {
1259         struct glamo_core *glamo = platform_get_drvdata(pdev);
1260         int irq;
1261
1262         disable_irq(glamo->irq);
1263         set_irq_chained_handler(glamo->irq, NULL);
1264
1265         for (irq = IRQ_GLAMO(0); irq <= IRQ_GLAMO(8); irq++) {
1266                 set_irq_flags(irq, 0);
1267                 set_irq_chip(irq, NULL);
1268         }
1269
1270         platform_set_drvdata(pdev, NULL);
1271         platform_device_unregister(&glamo_fb_dev);
1272         platform_device_unregister(&glamo_mmc_dev);
1273         iounmap(glamo->base);
1274         release_mem_region(glamo->mem->start, GLAMO_REGOFS_VIDCAP);
1275         glamo_handle = NULL;
1276         kfree(glamo);
1277
1278         return 0;
1279 }
1280
1281 #ifdef CONFIG_PM
1282
1283 /* have to export this because struct glamo_core is opaque */
1284
1285 void glamo_register_resume_dependency(struct resume_dependency *
1286                                                               resume_dependency)
1287 {
1288         register_resume_dependency(&glamo_handle->resume_dependency,
1289                                                              resume_dependency);
1290         if (glamo_handle->is_suspended)
1291                 activate_all_resume_dependencies(&glamo_handle->resume_dependency);
1292 }
1293 EXPORT_SYMBOL_GPL(glamo_register_resume_dependency);
1294
1295
1296 static int glamo_suspend(struct platform_device *pdev, pm_message_t state)
1297 {
1298         glamo_power(glamo_handle, GLAMO_POWER_SUSPEND);
1299         glamo_handle->is_suspended = 1;
1300         activate_all_resume_dependencies(&glamo_handle->resume_dependency);
1301         return 0;
1302 }
1303
1304 static int glamo_resume(struct platform_device *pdev)
1305 {
1306         glamo_power(glamo_handle, GLAMO_POWER_ON);
1307         glamo_handle->is_suspended = 0;
1308         callback_all_resume_dependencies(&glamo_handle->resume_dependency);
1309
1310         return 0;
1311 }
1312 #else
1313 #define glamo_suspend NULL
1314 #define glamo_resume  NULL
1315 #endif
1316
1317 static struct platform_driver glamo_driver = {
1318         .probe          = glamo_probe,
1319         .remove         = glamo_remove,
1320         .suspend_late   = glamo_suspend,
1321         .resume_early   = glamo_resume,
1322         .driver         = {
1323                 .name   = "glamo3362",
1324                 .owner  = THIS_MODULE,
1325         },
1326 };
1327
1328 static int __devinit glamo_init(void)
1329 {
1330         return platform_driver_register(&glamo_driver);
1331 }
1332
1333 static void __exit glamo_cleanup(void)
1334 {
1335         platform_driver_unregister(&glamo_driver);
1336 }
1337
1338 module_init(glamo_init);
1339 module_exit(glamo_cleanup);
1340
1341 MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>");
1342 MODULE_DESCRIPTION("Smedia Glamo 336x/337x core/resource driver");
1343 MODULE_LICENSE("GPL");