changed Makefile and profiles, added patches for kernel 2.6.24
[openwrt.git] / target / linux / s3c24xx / patches-2.6.24 / 1033-smedia-glamo.patch.patch
1 From f9fc3f480aeb1fdfcdefdd3c560d06c8297c758b Mon Sep 17 00:00:00 2001
2 From: mokopatches <mokopatches@openmoko.org>
3 Date: Fri, 4 Apr 2008 11:34:54 +0100
4 Subject: [PATCH] smedia-glamo.patch
5  [ FIXME:
6   include/asm-arm/arch-s3c2410/irqs.h shouldn't contain device-specific
7   changes. ]
8
9 This is a Linux kernel driver for the Smedia Glamo336x / Glamo337x
10 multi-function peripheral device.
11
12 Signed-off-by: Harald Welte <laforge@openmoko.org>
13 ---
14  drivers/mfd/Kconfig                 |    2 +
15  drivers/mfd/Makefile                |    1 +
16  drivers/mfd/glamo/Kconfig           |   35 ++
17  drivers/mfd/glamo/Makefile          |   11 +
18  drivers/mfd/glamo/glamo-core.c      | 1151 +++++++++++++++++++++++++++++++++++
19  drivers/mfd/glamo/glamo-core.h      |   91 +++
20  drivers/mfd/glamo/glamo-fb.c        |  822 +++++++++++++++++++++++++
21  drivers/mfd/glamo/glamo-gpio.c      |   62 ++
22  drivers/mfd/glamo/glamo-lcm-spi.c   |  241 ++++++++
23  drivers/mfd/glamo/glamo-regs.h      |  477 +++++++++++++++
24  drivers/mfd/glamo/glamo-spi-gpio.c  |  256 ++++++++
25  include/asm-arm/arch-s3c2410/irqs.h |   32 +-
26  include/linux/glamo-gpio.h          |   99 +++
27  include/linux/glamofb.h             |   39 ++
28  include/linux/spi/glamo.h           |   28 +
29  15 files changed, 3345 insertions(+), 2 deletions(-)
30  create mode 100644 drivers/mfd/glamo/Kconfig
31  create mode 100644 drivers/mfd/glamo/Makefile
32  create mode 100644 drivers/mfd/glamo/glamo-core.c
33  create mode 100644 drivers/mfd/glamo/glamo-core.h
34  create mode 100644 drivers/mfd/glamo/glamo-fb.c
35  create mode 100644 drivers/mfd/glamo/glamo-gpio.c
36  create mode 100644 drivers/mfd/glamo/glamo-lcm-spi.c
37  create mode 100644 drivers/mfd/glamo/glamo-regs.h
38  create mode 100644 drivers/mfd/glamo/glamo-spi-gpio.c
39  create mode 100644 include/linux/glamo-gpio.h
40  create mode 100644 include/linux/glamofb.h
41  create mode 100644 include/linux/spi/glamo.h
42
43 diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
44 index 2571619..fe06f8e 100644
45 --- a/drivers/mfd/Kconfig
46 +++ b/drivers/mfd/Kconfig
47 @@ -15,6 +15,8 @@ config MFD_SM501
48           interface. The device may be connected by PCI or local bus with
49           varying functions enabled.
50  
51 +source "drivers/mfd/glamo/Kconfig"
52 +
53  endmenu
54  
55  menu "Multimedia Capabilities Port drivers"
56 diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
57 index 5143209..a2da091 100644
58 --- a/drivers/mfd/Makefile
59 +++ b/drivers/mfd/Makefile
60 @@ -3,6 +3,7 @@
61  #
62  
63  obj-$(CONFIG_MFD_SM501)                += sm501.o
64 +obj-$(CONFIG_MFD_GLAMO)                += glamo/
65  
66  obj-$(CONFIG_MCP)              += mcp-core.o
67  obj-$(CONFIG_MCP_SA11X0)       += mcp-sa11x0.o
68 diff --git a/drivers/mfd/glamo/Kconfig b/drivers/mfd/glamo/Kconfig
69 new file mode 100644
70 index 0000000..b99f2b2
71 --- /dev/null
72 +++ b/drivers/mfd/glamo/Kconfig
73 @@ -0,0 +1,35 @@
74 +config MFD_GLAMO
75 +       bool "Smedia Glamo 336x/337x support"
76 +       help
77 +         This enables the core driver for the Smedia Glamo 336x/337x
78 +         multi-function device.  It includes irq_chip demultiplex as
79 +         well as clock / power management and GPIO support.
80 +
81 +config MFD_GLAMO_FB
82 +       tristate "Smedia Glamo 336x/337x framebuffer support"
83 +       depends on FB && MFD_GLAMO
84 +       help
85 +         Frame buffer driver for the LCD controller in the Smedia Glamo
86 +         336x/337x.
87 +
88 +         This driver is also available as a module ( = code which can be
89 +         inserted and removed from the running kernel whenever you want). The
90 +         module will be called glamofb. If you want to compile it as a module,
91 +         say M here and read <file:Documentation/modules.txt>.
92 +
93 +         If unsure, say N.
94 +
95 +config MFD_GLAMO_SPI_GPIO
96 +       tristate "Glamo GPIO SPI bitbang support"
97 +       depends on MFD_GLAMO
98 +       help
99 +         Enable a bitbanging SPI adapter driver for the Smedia Glamo.
100 +
101 +config MFD_GLAMO_SPI_FB
102 +       tristate "Glamo LCM control channel SPI support"
103 +       depends on MFD_GLAMO_FB
104 +       help
105 +         Enable a bitbanging SPI adapter driver for the Smedia Glamo LCM
106 +        control channel.  This SPI interface is frequently used to
107 +        interconnect the LCM control interface.
108 +
109 diff --git a/drivers/mfd/glamo/Makefile b/drivers/mfd/glamo/Makefile
110 new file mode 100644
111 index 0000000..fb53982
112 --- /dev/null
113 +++ b/drivers/mfd/glamo/Makefile
114 @@ -0,0 +1,11 @@
115 +#
116 +# Makefile for the Smedia Glamo framebuffer driver
117 +#
118 +
119 +obj-$(CONFIG_MFD_GLAMO)                        += glamo-core.o glamo-gpio.o
120 +obj-$(CONFIG_MFD_GLAMO_SPI)            += glamo-spi.o
121 +obj-$(CONFIG_MFD_GLAMO_SPI_GPIO)       += glamo-spi-gpio.o
122 +
123 +obj-$(CONFIG_MFD_GLAMO_FB)             += glamo-fb.o
124 +obj-$(CONFIG_MFD_GLAMO_SPI_FB)         += glamo-lcm-spi.o
125 +
126 diff --git a/drivers/mfd/glamo/glamo-core.c b/drivers/mfd/glamo/glamo-core.c
127 new file mode 100644
128 index 0000000..acf545f
129 --- /dev/null
130 +++ b/drivers/mfd/glamo/glamo-core.c
131 @@ -0,0 +1,1151 @@
132 +/* Smedia Glamo 336x/337x driver
133 + *
134 + * (C) 2007 by OpenMoko, Inc.
135 + * Author: Harald Welte <laforge@openmoko.org>
136 + * All rights reserved.
137 + *
138 + * This program is free software; you can redistribute it and/or
139 + * modify it under the terms of the GNU General Public License as
140 + * published by the Free Software Foundation; either version 2 of
141 + * the License, or (at your option) any later version.
142 + *
143 + * This program is distributed in the hope that it will be useful,
144 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
145 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
146 + * GNU General Public License for more details.
147 + *
148 + * You should have received a copy of the GNU General Public License
149 + * along with this program; if not, write to the Free Software
150 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
151 + * MA 02111-1307 USA
152 + */
153 +
154 +#include <linux/module.h>
155 +#include <linux/kernel.h>
156 +#include <linux/errno.h>
157 +#include <linux/string.h>
158 +#include <linux/mm.h>
159 +#include <linux/tty.h>
160 +#include <linux/slab.h>
161 +#include <linux/delay.h>
162 +#include <linux/fb.h>
163 +#include <linux/init.h>
164 +#include <linux/irq.h>
165 +#include <linux/interrupt.h>
166 +#include <linux/workqueue.h>
167 +#include <linux/wait.h>
168 +#include <linux/platform_device.h>
169 +#include <linux/kernel_stat.h>
170 +#include <linux/spinlock.h>
171 +#include <linux/glamofb.h>
172 +#include <linux/mmc/mmc.h>
173 +#include <linux/mmc/host.h>
174 +
175 +#include <asm/io.h>
176 +#include <asm/uaccess.h>
177 +#include <asm/div64.h>
178 +
179 +#ifdef CONFIG_PM
180 +#include <linux/pm.h>
181 +#endif
182 +
183 +#include "glamo-regs.h"
184 +#include "glamo-core.h"
185 +
186 +#define RESSIZE(ressource) (((ressource)->end - (ressource)->start)+1)
187 +
188 +static struct glamo_core *glamo_handle;
189 +
190 +static inline void __reg_write(struct glamo_core *glamo,
191 +                               u_int16_t reg, u_int16_t val)
192 +{
193 +       writew(val, glamo->base + reg);
194 +}
195 +
196 +static inline u_int16_t __reg_read(struct glamo_core *glamo,
197 +                                  u_int16_t reg)
198 +{
199 +       return readw(glamo->base + reg);
200 +}
201 +
202 +static void __reg_set_bit_mask(struct glamo_core *glamo,
203 +                               u_int16_t reg, u_int16_t mask,
204 +                               u_int16_t val)
205 +{
206 +       u_int16_t tmp;
207 +
208 +       val &= mask;
209 +
210 +       tmp = __reg_read(glamo, reg);
211 +       tmp &= ~mask;
212 +       tmp |= val;
213 +       __reg_write(glamo, reg, tmp);
214 +}
215 +
216 +static void reg_set_bit_mask(struct glamo_core *glamo,
217 +                               u_int16_t reg, u_int16_t mask,
218 +                               u_int16_t val)
219 +{
220 +       spin_lock(&glamo->lock);
221 +       __reg_set_bit_mask(glamo, reg, mask, val);
222 +       spin_unlock(&glamo->lock);
223 +}
224 +
225 +static inline void __reg_set_bit(struct glamo_core *glamo,
226 +                                u_int16_t reg, u_int16_t bit)
227 +{
228 +       __reg_set_bit_mask(glamo, reg, bit, 0xffff);
229 +}
230 +
231 +static inline void __reg_clear_bit(struct glamo_core *glamo,
232 +                                  u_int16_t reg, u_int16_t bit)
233 +{
234 +       __reg_set_bit_mask(glamo, reg, bit, 0);
235 +}
236 +
237 +static inline void glamo_vmem_write(struct glamo_core *glamo, u_int32_t addr,
238 +                                   u_int16_t *src, int len)
239 +{
240 +       if (addr & 0x0001 || (unsigned long)src & 0x0001 || len & 0x0001) {
241 +               dev_err(&glamo->pdev->dev, "unaligned write(0x%08x, 0x%p, "
242 +                       "0x%x)!!\n", addr, src, len);
243 +       }
244 +
245 +}
246 +
247 +static inline void glamo_vmem_read(struct glamo_core *glamo, u_int16_t *buf,
248 +                                  u_int32_t addr, int len)
249 +{
250 +       if (addr & 0x0001 || (unsigned long) buf & 0x0001 || len & 0x0001) {
251 +               dev_err(&glamo->pdev->dev, "unaligned read(0x%p, 0x08%x, "
252 +                       "0x%x)!!\n", buf, addr, len);
253 +       }
254 +
255 +
256 +}
257 +
258 +/***********************************************************************
259 + * resources of sibling devices
260 + ***********************************************************************/
261 +
262 +#if 0
263 +static struct resource glamo_core_resources[] = {
264 +       {
265 +               .start  = GLAMO_REGOFS_GENERIC,
266 +               .end    = GLAMO_REGOFS_GENERIC + 0x400,
267 +               .flags  = IORESOURCE_MEM,
268 +       }, {
269 +               .start  = 0,
270 +               .end    = 0,
271 +               .flags  = IORESOURCE_IRQ,
272 +       },
273 +};
274 +
275 +static struct platform_device glamo_core_dev = {
276 +       .name           = "glamo-core",
277 +       .resource       = &glamo_core_resources,
278 +       .num_resources  = ARRAY_SIZE(glamo_core_resources),
279 +};
280 +#endif
281 +
282 +static struct resource glamo_jpeg_resources[] = {
283 +       {
284 +               .start  = GLAMO_REGOFS_JPEG,
285 +               .end    = GLAMO_REGOFS_MPEG - 1,
286 +               .flags  = IORESOURCE_MEM,
287 +       }, {
288 +               .start  = IRQ_GLAMO_JPEG,
289 +               .end    = IRQ_GLAMO_JPEG,
290 +               .flags  = IORESOURCE_IRQ,
291 +       },
292 +};
293 +
294 +static struct platform_device glamo_jpeg_dev = {
295 +       .name           = "glamo-jpeg",
296 +       .resource       = glamo_jpeg_resources,
297 +       .num_resources  = ARRAY_SIZE(glamo_jpeg_resources),
298 +};
299 +
300 +static struct resource glamo_mpeg_resources[] = {
301 +       {
302 +               .start  = GLAMO_REGOFS_MPEG,
303 +               .end    = GLAMO_REGOFS_LCD - 1,
304 +               .flags  = IORESOURCE_MEM,
305 +       }, {
306 +               .start  = IRQ_GLAMO_MPEG,
307 +               .end    = IRQ_GLAMO_MPEG,
308 +               .flags  = IORESOURCE_IRQ,
309 +       },
310 +};
311 +
312 +static struct platform_device glamo_mpeg_dev = {
313 +       .name           = "glamo-mpeg",
314 +       .resource       = glamo_mpeg_resources,
315 +       .num_resources  = ARRAY_SIZE(glamo_mpeg_resources),
316 +};
317 +
318 +static struct resource glamo_2d_resources[] = {
319 +       {
320 +               .start  = GLAMO_REGOFS_2D,
321 +               .end    = GLAMO_REGOFS_3D - 1,
322 +               .flags  = IORESOURCE_MEM,
323 +       }, {
324 +               .start  = IRQ_GLAMO_2D,
325 +               .end    = IRQ_GLAMO_2D,
326 +               .flags  = IORESOURCE_IRQ,
327 +       },
328 +};
329 +
330 +static struct platform_device glamo_2d_dev = {
331 +       .name           = "glamo-2d",
332 +       .resource       = glamo_2d_resources,
333 +       .num_resources  = ARRAY_SIZE(glamo_2d_resources),
334 +};
335 +
336 +static struct resource glamo_3d_resources[] = {
337 +       {
338 +               .start  = GLAMO_REGOFS_3D,
339 +               .end    = GLAMO_REGOFS_END - 1,
340 +               .flags  = IORESOURCE_MEM,
341 +       },
342 +};
343 +
344 +static struct platform_device glamo_3d_dev = {
345 +       .name           = "glamo-3d",
346 +       .resource       = glamo_3d_resources,
347 +       .num_resources  = ARRAY_SIZE(glamo_3d_resources),
348 +};
349 +
350 +static struct platform_device glamo_spigpio_dev = {
351 +       .name           = "glamo-spi-gpio",
352 +};
353 +
354 +static struct resource glamo_fb_resources[] = {
355 +       /* FIXME: those need to be incremented by parent base */
356 +       {
357 +               .name   = "glamo-fb-regs",
358 +               .start  = GLAMO_REGOFS_LCD,
359 +               .end    = GLAMO_REGOFS_MMC - 1,
360 +               .flags  = IORESOURCE_MEM,
361 +       }, {
362 +               .name   = "glamo-fb-mem",
363 +               .start  = GLAMO_OFFSET_FB,
364 +               .end    = GLAMO_OFFSET_FB + GLAMO_FB_SIZE - 1,
365 +               .flags  = IORESOURCE_MEM,
366 +       },
367 +};
368 +
369 +static struct platform_device glamo_fb_dev = {
370 +       .name           = "glamo-fb",
371 +       .resource       = glamo_fb_resources,
372 +       .num_resources  = ARRAY_SIZE(glamo_fb_resources),
373 +};
374 +
375 +static struct resource glamo_mmc_resources[] = {
376 +       {
377 +               /* FIXME: those need to be incremented by parent base */
378 +               .start  = GLAMO_REGOFS_MMC,
379 +               .end    = GLAMO_REGOFS_MPROC0 - 1,
380 +               .flags  = IORESOURCE_MEM
381 +       }, {
382 +               .start  = IRQ_GLAMO_MMC,
383 +               .end    = IRQ_GLAMO_MMC,
384 +               .flags  = IORESOURCE_IRQ,
385 +       }, { /* our data buffer for MMC transfers */
386 +               .start  = GLAMO_OFFSET_FB + GLAMO_FB_SIZE,
387 +               .end    = GLAMO_OFFSET_FB + GLAMO_FB_SIZE +
388 +                                 GLAMO_MMC_BUFFER_SIZE - 1,
389 +               .flags  = IORESOURCE_MEM
390 +       },
391 +};
392 +
393 +static struct platform_device glamo_mmc_dev = {
394 +       .name           = "glamo-mci",
395 +       .resource       = glamo_mmc_resources,
396 +       .num_resources  = ARRAY_SIZE(glamo_mmc_resources),
397 +};
398 +
399 +struct glamo_mci_pdata glamo_mci_def_pdata = {
400 +       .gpio_detect            = 0,
401 +       .glamo_set_mci_power    = NULL, /* filled in from MFD platform data */
402 +       .ocr_avail              = MMC_VDD_32_33,
403 +       .glamo_irq_is_wired     = NULL, /* filled in from MFD platform data */
404 +};
405 +EXPORT_SYMBOL_GPL(glamo_mci_def_pdata);
406 +
407 +
408 +
409 +static void mangle_mem_resources(struct resource *res, int num_res,
410 +                                struct resource *parent)
411 +{
412 +       int i;
413 +
414 +       for (i = 0; i < num_res; i++) {
415 +               if (res[i].flags != IORESOURCE_MEM)
416 +                       continue;
417 +               res[i].start += parent->start;
418 +               res[i].end += parent->start;
419 +               res[i].parent = parent;
420 +       }
421 +}
422 +
423 +/***********************************************************************
424 + * IRQ demultiplexer
425 + ***********************************************************************/
426 +#define irq2glamo(x)   (x - IRQ_GLAMO(0))
427 +
428 +static void glamo_ack_irq(unsigned int irq)
429 +{
430 +       /* clear interrupt source */
431 +       __reg_write(glamo_handle, GLAMO_REG_IRQ_CLEAR,
432 +                   1 << irq2glamo(irq));
433 +}
434 +
435 +static void glamo_mask_irq(unsigned int irq)
436 +{
437 +       u_int16_t tmp;
438 +
439 +       /* clear bit in enable register */
440 +       tmp = __reg_read(glamo_handle, GLAMO_REG_IRQ_ENABLE);
441 +       tmp &= ~(1 << irq2glamo(irq));
442 +       __reg_write(glamo_handle, GLAMO_REG_IRQ_ENABLE, tmp);
443 +}
444 +
445 +static void glamo_unmask_irq(unsigned int irq)
446 +{
447 +       u_int16_t tmp;
448 +
449 +       /* set bit in enable register */
450 +       tmp = __reg_read(glamo_handle, GLAMO_REG_IRQ_ENABLE);
451 +       tmp |= (1 << irq2glamo(irq));
452 +       __reg_write(glamo_handle, GLAMO_REG_IRQ_ENABLE, tmp);
453 +}
454 +
455 +static struct irq_chip glamo_irq_chip = {
456 +       .ack    = glamo_ack_irq,
457 +       .mask   = glamo_mask_irq,
458 +       .unmask = glamo_unmask_irq,
459 +};
460 +
461 +static void glamo_irq_demux_handler(unsigned int irq, struct irq_desc *desc)
462 +{
463 +       const unsigned int cpu = smp_processor_id();
464 +
465 +       spin_lock(&desc->lock);
466 +
467 +       desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
468 +
469 +       if (unlikely(desc->status & IRQ_INPROGRESS)) {
470 +               desc->status |= (IRQ_PENDING | IRQ_MASKED);
471 +               desc->chip->mask(irq);
472 +               desc->chip->ack(irq);
473 +               goto out_unlock;
474 +       }
475 +
476 +       kstat_cpu(cpu).irqs[irq]++;
477 +       desc->chip->ack(irq);
478 +       desc->status |= IRQ_INPROGRESS;
479 +
480 +       do {
481 +               u_int16_t irqstatus;
482 +               int i;
483 +
484 +               if (unlikely((desc->status &
485 +                               (IRQ_PENDING | IRQ_MASKED | IRQ_DISABLED)) ==
486 +                               (IRQ_PENDING | IRQ_MASKED))) {
487 +                       /* dealing with pending IRQ, unmasking */
488 +                       desc->chip->unmask(irq);
489 +                       desc->status &= ~IRQ_MASKED;
490 +               }
491 +
492 +               desc->status &= ~IRQ_PENDING;
493 +
494 +               /* read IRQ status register */
495 +               irqstatus = __reg_read(glamo_handle, GLAMO_REG_IRQ_STATUS);
496 +               for (i = 0; i < 9; i++)
497 +                       if (irqstatus & (1 << i))
498 +                               desc_handle_irq(IRQ_GLAMO(i),
499 +                                   irq_desc+IRQ_GLAMO(i));
500 +
501 +       } while ((desc->status & (IRQ_PENDING | IRQ_DISABLED)) == IRQ_PENDING);
502 +
503 +       desc->status &= ~IRQ_INPROGRESS;
504 +
505 +out_unlock:
506 +       spin_unlock(&desc->lock);
507 +}
508 +
509 +/***********************************************************************
510 + * 'engine' support
511 + ***********************************************************************/
512 +
513 +int glamo_engine_enable(struct glamo_core *glamo, enum glamo_engine engine)
514 +{
515 +       spin_lock(&glamo->lock);
516 +       switch (engine) {
517 +       case GLAMO_ENGINE_LCD:
518 +               __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_LCD,
519 +                           GLAMO_CLOCK_LCD_EN_M5CLK |
520 +                           GLAMO_CLOCK_LCD_EN_DHCLK |
521 +                           GLAMO_CLOCK_LCD_EN_DMCLK |
522 +                           GLAMO_CLOCK_LCD_EN_DCLK |
523 +                           GLAMO_CLOCK_LCD_DG_M5CLK |
524 +                           GLAMO_CLOCK_LCD_DG_DMCLK, 0xffff);
525 +               __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_GEN5_1,
526 +                           GLAMO_CLOCK_GEN51_EN_DIV_DHCLK |
527 +                           GLAMO_CLOCK_GEN51_EN_DIV_DMCLK |
528 +                           GLAMO_CLOCK_GEN51_EN_DIV_DCLK, 0xffff);
529 +               __reg_set_bit_mask(glamo, GLAMO_REG_HOSTBUS(2),
530 +                           GLAMO_HOSTBUS2_MMIO_EN_LCD,
531 +                           0xffff);
532 +               break;
533 +       case GLAMO_ENGINE_MMC:
534 +               __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_MMC,
535 +                                  GLAMO_CLOCK_MMC_EN_M9CLK |
536 +                                  GLAMO_CLOCK_MMC_EN_TCLK |
537 +                                  GLAMO_CLOCK_MMC_DG_M9CLK |
538 +                                  GLAMO_CLOCK_MMC_DG_TCLK, 0xffff);
539 +               __reg_set_bit_mask(glamo, GLAMO_REG_HOSTBUS(2),
540 +                                  GLAMO_HOSTBUS2_MMIO_EN_MMC,
541 +                                  GLAMO_HOSTBUS2_MMIO_EN_MMC);
542 +               break;
543 +       case GLAMO_ENGINE_2D:
544 +               __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_2D,
545 +                                  GLAMO_CLOCK_2D_EN_M7CLK |
546 +                                  GLAMO_CLOCK_2D_EN_GCLK |
547 +                                  GLAMO_CLOCK_2D_DG_M7CLK |
548 +                                  GLAMO_CLOCK_2D_DG_GCLK, 0xffff);
549 +               __reg_set_bit_mask(glamo, GLAMO_REG_HOSTBUS(2),
550 +                                  GLAMO_HOSTBUS2_MMIO_EN_2D,
551 +                                  GLAMO_HOSTBUS2_MMIO_EN_2D);
552 +               break;
553 +       case GLAMO_ENGINE_CMDQ:
554 +               __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_2D,
555 +                                  GLAMO_CLOCK_2D_EN_M6CLK, 0xffff);
556 +               __reg_set_bit_mask(glamo, GLAMO_REG_HOSTBUS(2),
557 +                                  GLAMO_HOSTBUS2_MMIO_EN_CQ,
558 +                                  GLAMO_HOSTBUS2_MMIO_EN_CQ);
559 +               break;
560 +       /* FIXME: Implementation */
561 +       default:
562 +               break;
563 +       }
564 +       spin_unlock(&glamo->lock);
565 +
566 +       return 0;
567 +}
568 +EXPORT_SYMBOL_GPL(glamo_engine_enable);
569 +
570 +int glamo_engine_disable(struct glamo_core *glamo, enum glamo_engine engine)
571 +{
572 +       spin_lock(&glamo->lock);
573 +       switch (engine) {
574 +       /* FIXME: Implementation */
575 +       default:
576 +               break;
577 +       }
578 +       spin_unlock(&glamo->lock);
579 +
580 +       return 0;
581 +}
582 +EXPORT_SYMBOL_GPL(glamo_engine_disable);
583 +
584 +struct glamo_script reset_regs[] = {
585 +       [GLAMO_ENGINE_LCD] = {
586 +               GLAMO_REG_CLOCK_LCD, GLAMO_CLOCK_LCD_RESET
587 +       },
588 +#if 0
589 +       [GLAMO_ENGINE_HOST] = {
590 +               GLAMO_REG_CLOCK_HOST, GLAMO_CLOCK_HOST_RESET
591 +       },
592 +       [GLAMO_ENGINE_MEM] = {
593 +               GLAMO_REG_CLOCK_MEM, GLAMO_CLOCK_MEM_RESET
594 +       },
595 +#endif
596 +       [GLAMO_ENGINE_MMC] = {
597 +               GLAMO_REG_CLOCK_MMC, GLAMO_CLOCK_MMC_RESET
598 +       },
599 +       [GLAMO_ENGINE_2D] = {
600 +               GLAMO_REG_CLOCK_2D, GLAMO_CLOCK_2D_RESET
601 +       },
602 +       [GLAMO_ENGINE_JPEG] = {
603 +               GLAMO_REG_CLOCK_JPEG, GLAMO_CLOCK_JPEG_RESET
604 +       },
605 +};
606 +
607 +void glamo_engine_reset(struct glamo_core *glamo, enum glamo_engine engine)
608 +{
609 +       struct glamo_script *rst;
610 +
611 +       if (engine >= ARRAY_SIZE(reset_regs)) {
612 +               dev_warn(&glamo->pdev->dev, "unknown engine %u ", engine);
613 +               return;
614 +       }
615 +
616 +       rst = &reset_regs[engine];
617 +
618 +       spin_lock(&glamo->lock);
619 +       __reg_set_bit(glamo, rst->reg, rst->val);
620 +       spin_unlock(&glamo->lock);
621 +
622 +       msleep(1);
623 +
624 +       spin_lock(&glamo->lock);
625 +       __reg_clear_bit(glamo, rst->reg, rst->val);
626 +       spin_unlock(&glamo->lock);
627 +
628 +       msleep(1);
629 +}
630 +EXPORT_SYMBOL_GPL(glamo_engine_reset);
631 +
632 +enum glamo_pll {
633 +       GLAMO_PLL1,
634 +       GLAMO_PLL2,
635 +};
636 +
637 +static int glamo_pll_rate(struct glamo_core *glamo,
638 +                         enum glamo_pll pll)
639 +{
640 +       u_int16_t reg;
641 +       unsigned int div = 512;
642 +       /* FIXME: move osci into platform_data */
643 +       unsigned int osci = 32768;
644 +
645 +       if (osci == 32768)
646 +               div = 1;
647 +
648 +       switch (pll) {
649 +       case GLAMO_PLL1:
650 +               reg = __reg_read(glamo, GLAMO_REG_PLL_GEN1);
651 +               break;
652 +       case GLAMO_PLL2:
653 +               reg = __reg_read(glamo, GLAMO_REG_PLL_GEN3);
654 +               break;
655 +       default:
656 +               return -EINVAL;
657 +       }
658 +       return (osci/div)*reg;
659 +}
660 +
661 +int glamo_engine_reclock(struct glamo_core *glamo,
662 +                        enum glamo_engine engine,
663 +                        int ps)
664 +{
665 +       int pll, khz;
666 +       u_int16_t reg, mask, val = 0;
667 +
668 +       if (!ps)
669 +               return 0;
670 +
671 +       switch (engine) {
672 +       case GLAMO_ENGINE_LCD:
673 +               pll = GLAMO_PLL1;
674 +               reg = GLAMO_REG_CLOCK_GEN7;
675 +               mask = 0xff;
676 +               break;
677 +       default:
678 +               dev_warn(&glamo->pdev->dev,
679 +                        "reclock of engine 0x%x not supported\n", engine);
680 +               return -EINVAL;
681 +               break;
682 +       }
683 +
684 +       pll = glamo_pll_rate(glamo, pll);
685 +       khz = 1000000000UL / ps;
686 +
687 +       if (khz)
688 +               val = (pll / khz) / 1000;
689 +
690 +       dev_dbg(&glamo->pdev->dev,
691 +                       "PLL %d, kHZ %d, div %d\n", pll, khz, val);
692 +
693 +       if (val) {
694 +               val--;
695 +               reg_set_bit_mask(glamo, reg, mask, val);
696 +               msleep(5); /* wait some time to stabilize */
697 +
698 +               return 0;
699 +       } else {
700 +               return -EINVAL;
701 +       }
702 +}
703 +EXPORT_SYMBOL_GPL(glamo_engine_reclock);
704 +
705 +/***********************************************************************
706 + * script support
707 + ***********************************************************************/
708 +
709 +int glamo_run_script(struct glamo_core *glamo, struct glamo_script *script,
710 +                    int len, int may_sleep)
711 +{
712 +       int i;
713 +
714 +       for (i = 0; i < len; i++) {
715 +               struct glamo_script *line = &script[i];
716 +
717 +               switch (line->reg) {
718 +               case 0xffff:
719 +                       return 0;
720 +               case 0xfffe:
721 +                       if (may_sleep)
722 +                               msleep(line->val);
723 +                       else
724 +                               mdelay(line->val);
725 +                       break;
726 +               case 0xfffd:
727 +                       /* spin until PLLs lock */
728 +                       while ((__reg_read(glamo, GLAMO_REG_PLL_GEN5) & 3) != 3)
729 +                               ;
730 +                       break;
731 +               default:
732 +                       __reg_write(glamo, script[i].reg, script[i].val);
733 +                       break;
734 +               }
735 +       }
736 +
737 +       return 0;
738 +}
739 +EXPORT_SYMBOL(glamo_run_script);
740 +
741 +static struct glamo_script glamo_init_script[] = {
742 +       { GLAMO_REG_CLOCK_HOST,         0x1000 },
743 +               { 0xfffe, 2 },
744 +       { GLAMO_REG_CLOCK_MEMORY,       0x1000 },
745 +       { GLAMO_REG_CLOCK_MEMORY,       0x2000 },
746 +       { GLAMO_REG_CLOCK_LCD,          0x1000 },
747 +       { GLAMO_REG_CLOCK_MMC,          0x1000 },
748 +       { GLAMO_REG_CLOCK_ISP,          0x1000 },
749 +       { GLAMO_REG_CLOCK_ISP,          0x3000 },
750 +       { GLAMO_REG_CLOCK_JPEG,         0x1000 },
751 +       { GLAMO_REG_CLOCK_3D,           0x1000 },
752 +       { GLAMO_REG_CLOCK_3D,           0x3000 },
753 +       { GLAMO_REG_CLOCK_2D,           0x1000 },
754 +       { GLAMO_REG_CLOCK_2D,           0x3000 },
755 +       { GLAMO_REG_CLOCK_RISC1,        0x1000 },
756 +       { GLAMO_REG_CLOCK_MPEG,         0x3000 },
757 +       { GLAMO_REG_CLOCK_MPEG,         0x3000 },
758 +       { GLAMO_REG_CLOCK_MPROC,        0x1000 /*0x100f*/ },
759 +               { 0xfffe, 2 },
760 +       { GLAMO_REG_CLOCK_HOST,         0x0000 },
761 +       { GLAMO_REG_CLOCK_MEMORY,       0x0000 },
762 +       { GLAMO_REG_CLOCK_LCD,          0x0000 },
763 +       { GLAMO_REG_CLOCK_MMC,          0x0000 },
764 +#if 0
765 +/* unused engines must be left in reset to stop MMC block read "blackouts" */
766 +       { GLAMO_REG_CLOCK_ISP,          0x0000 },
767 +       { GLAMO_REG_CLOCK_ISP,          0x0000 },
768 +       { GLAMO_REG_CLOCK_JPEG,         0x0000 },
769 +       { GLAMO_REG_CLOCK_3D,           0x0000 },
770 +       { GLAMO_REG_CLOCK_3D,           0x0000 },
771 +       { GLAMO_REG_CLOCK_2D,           0x0000 },
772 +       { GLAMO_REG_CLOCK_2D,           0x0000 },
773 +       { GLAMO_REG_CLOCK_RISC1,        0x0000 },
774 +       { GLAMO_REG_CLOCK_MPEG,         0x0000 },
775 +       { GLAMO_REG_CLOCK_MPEG,         0x0000 },
776 +#endif
777 +       { GLAMO_REG_PLL_GEN1,           0x05db },       /* 48MHz */
778 +       { GLAMO_REG_PLL_GEN3,           0x09c3 },       /* 80MHz */
779 +               { 0xfffd, 0 },
780 +       /*
781 +        * b9 of this register MUST be zero to get any interrupts on INT#
782 +        * the other set bits enable all the engine interrupt sources
783 +        */
784 +       { GLAMO_REG_IRQ_ENABLE,         0x01ff },
785 +       { GLAMO_REG_CLOCK_GEN6,         0x2000 },
786 +       { GLAMO_REG_CLOCK_GEN7,         0x0101 },
787 +       { GLAMO_REG_CLOCK_GEN8,         0x0100 },
788 +       { GLAMO_REG_CLOCK_HOST,         0x000d },
789 +       { 0x200,        0x0ef0 },
790 +       { 0x202,        0x07ff },
791 +       { 0x212,        0x0000 },
792 +       { 0x214,        0x4000 },
793 +       { 0x216,        0xf00e },
794 +       { GLAMO_REG_MEM_TYPE,           0x0874 }, /* 8MB, 16 word pg wr+rd */
795 +       { GLAMO_REG_MEM_GEN,            0xafaf }, /* 63 grants min + max */
796 +       /*
797 +        * the register below originally 0x0108 makes unreliable Glamo MMC
798 +        * write operations.  Cranked to 0x05ad to add a wait state, the
799 +        * unreliability is not seen after 4GB of write / read testing
800 +        */
801 +       { GLAMO_REG_MEM_TIMING1,        0x0108 },
802 +       { GLAMO_REG_MEM_TIMING2,        0x0010 }, /* Taa = 3 MCLK */
803 +       { GLAMO_REG_MEM_TIMING3,        0x0000 },
804 +       { GLAMO_REG_MEM_TIMING4,        0x0000 }, /* CE1# delay fall/rise */
805 +       { GLAMO_REG_MEM_TIMING5,        0x0000 }, /* UB# LB# */
806 +       { GLAMO_REG_MEM_TIMING6,        0x0000 }, /* OE# */
807 +       { GLAMO_REG_MEM_TIMING7,        0x0000 }, /* WE# */
808 +       { GLAMO_REG_MEM_TIMING8,        0x1002 }, /* MCLK delay, was 0x1000 */
809 +       { GLAMO_REG_MEM_TIMING9,        0x6006 },
810 +       { GLAMO_REG_MEM_TIMING10,       0x00ff },
811 +       { GLAMO_REG_MEM_TIMING11,       0x0001 },
812 +       { GLAMO_REG_MEM_POWER1,         0x0020 },
813 +       { GLAMO_REG_MEM_POWER2,         0x0000 },
814 +       { GLAMO_REG_MEM_DRAM1,          0x0000 },
815 +               { 0xfffe, 1 },
816 +       { GLAMO_REG_MEM_DRAM1,          0xc100 },
817 +               { 0xfffe, 1 },
818 +       { GLAMO_REG_MEM_DRAM1,          0xe100 },
819 +       { GLAMO_REG_MEM_DRAM2,          0x01d6 },
820 +       { GLAMO_REG_CLOCK_MEMORY,       0x000b },
821 +};
822 +
823 +static struct glamo_script glamo_resume_script[] = {
824 +       { GLAMO_REG_IRQ_ENABLE,         0x01ff },
825 +       { GLAMO_REG_CLOCK_GEN6,         0x2000 },
826 +       { GLAMO_REG_CLOCK_GEN7,         0x0001 }, /* 0101 */
827 +       { GLAMO_REG_CLOCK_GEN8,         0x0100 },
828 +       { GLAMO_REG_CLOCK_HOST,         0x000d },
829 +       { 0x200,        0x0ef0 },
830 +       { 0x202,        0x07ff },
831 +       { 0x212,        0x0000 },
832 +       { 0x214,        0x4000 },
833 +       { 0x216,        0xf00e },
834 +       { GLAMO_REG_MEM_TYPE,           0x0874 }, /* 8MB, 16 word pg wr+rd */
835 +       { GLAMO_REG_MEM_GEN,            0xafaf }, /* 63 grants min + max */
836 +
837 +       { GLAMO_REG_MEM_TIMING1,        0x0108 },
838 +       { GLAMO_REG_MEM_TIMING2,        0x0010 }, /* Taa = 3 MCLK */
839 +       { GLAMO_REG_MEM_TIMING3,        0x0000 },
840 +       { GLAMO_REG_MEM_TIMING4,        0x0000 }, /* CE1# delay fall/rise */
841 +       { GLAMO_REG_MEM_TIMING5,        0x0000 }, /* UB# LB# */
842 +       { GLAMO_REG_MEM_TIMING6,        0x0000 }, /* OE# */
843 +       { GLAMO_REG_MEM_TIMING7,        0x0000 }, /* WE# */
844 +       { GLAMO_REG_MEM_TIMING8,        0x1002 }, /* MCLK delay, was 0x1000 */
845 +       { GLAMO_REG_MEM_TIMING9,        0x6006 },
846 +       { GLAMO_REG_MEM_TIMING10,       0x00ff },
847 +       { GLAMO_REG_MEM_TIMING11,       0x0001 },
848 +       { GLAMO_REG_MEM_POWER1,         0x0020 },
849 +       { GLAMO_REG_MEM_POWER2,         0x0000 },
850 +       { GLAMO_REG_MEM_DRAM1,          0x0000 },
851 +               { 0xfffe, 1 },
852 +       { GLAMO_REG_MEM_DRAM1,          0xc100 },
853 +               { 0xfffe, 1 },
854 +       { GLAMO_REG_MEM_DRAM1,          0xe100 },
855 +       { GLAMO_REG_MEM_DRAM2,          0x01d6 },
856 +       { GLAMO_REG_CLOCK_MEMORY,       0x000b },
857 +};
858 +
859 +#if 0 /* MM370 */
860 +static const struct glamo_script regs_vram_2mb = {
861 +       { GLAMO_REG_CLOCK_MEMORY,       0x3aaa },
862 +               { 0xfffe, 50 },
863 +       { GLAMO_REG_CLOCK_MEMORY,       0x0aaa },
864 +               { 0xfffe, 3 },
865 +       { GLAMO_REG_MEM_POWER1,         0x0020 },
866 +       { 0x033a,                       0x0000 },
867 +       { 0x033c,                       0x0000 },
868 +       { 0x033e,                       0x0000 },
869 +       { 0x0340,                       0x0000 },
870 +       { 0x0342,                       0x0000 },
871 +       { 0x0344,                       0x0000 },
872 +       { 0x0346,                       0x0240 },
873 +       { GLAMO_REG_MEM_TIMING8,        0x1016 },
874 +       { GLAMO_REG_MEM_TIMING9,        0x6067 },
875 +       { GLAMO_REG_MEM_TIMING10,       0x00ff },
876 +       { GLAMO_REG_MEM_TIMING11,       0x0030 },
877 +       { GLAMO_REG_MEM_GEN,            0x3fff },
878 +       { GLAMO_REG_MEM_GEN,            0xafaf },
879 +       { GLAMO_REG_MEM_TIMING1,        0x0108 },
880 +       { GLAMO_REG_MEM_TIMING2,        0x0010 },
881 +       { GLAMO_REG_MEM_DRAM1,          0x0a00 },
882 +               { 0xfffe, 3 },
883 +       { GLAMO_REG_MEM_DRAM1,          0xe200 },
884 +               { 0xfffe, 1 },
885 +};
886 +
887 +static const struct glamo_script regs_vram_8mb = {
888 +       { GLAMO_REG_CLOCK_MEMORY,       0x3aaa },
889 +               { 0xfffe, 50 },
890 +       { GLAMO_REG_CLOCK_MEMORY,       0x0aaa },
891 +               { 0xfffe, 3 },
892 +       { GLAMO_REG_MEM_POWER1,         0x0020 },
893 +       { 0x033a,                       0x45cf },
894 +       { 0x033c,                       0x4240 },
895 +       { 0x033e,                       0x53e0 },
896 +       { 0x0340,                       0x1401 },
897 +       { 0x0342,                       0x0c44 },
898 +       { 0x0344,                       0x1d0b },
899 +       { 0x0346,                       0x25ac },
900 +       { 0x0348,                       0x1953 },
901 +               { 0xfffe, 1 },
902 +       { GLAMO_REG_MEM_TYPE,           0x087a },
903 +       { GLAMO_REG_MEM_DRAM2,          0x01d6 },
904 +       { GLAMO_REG_MEM_TIMING8,        0x1060 },
905 +       { GLAMO_REG_MEM_TIMING9,        0x6067 },
906 +       { GLAMO_REG_MEM_TIMING10,       0x00ff },
907 +       { GLAMO_REG_MEM_TIMING11,       0x0030 },
908 +       { GLAMO_REG_MEM_GEN,            0x3fff },
909 +       { GLAMO_REG_MEM_GEN,            0xafaf },
910 +       { GLAMO_REG_MEM_TIMING1,        0x3108 },
911 +       { GLAMO_REG_MEM_TIMING2,        0x0010 },
912 +       { GLAMO_REG_MEM_DRAM1,          0x0a00 },
913 +               { 0xfffe, 3 },
914 +       { GLAMO_REG_MEM_DRAM1,          0xe200 },
915 +               { 0xfffe, 1 },
916 +};
917 +#endif
918 +
919 +enum glamo_power {
920 +       GLAMO_POWER_ON,
921 +       GLAMO_POWER_STANDBY,
922 +       GLAMO_POWER_SUSPEND,
923 +};
924 +
925 +static void glamo_power(struct glamo_core *glamo,
926 +                       enum glamo_power new_state)
927 +{
928 +       spin_lock(&glamo->lock);
929 +
930 +       switch (new_state) {
931 +       case GLAMO_POWER_ON:
932 +               /* power up PLL1 and PLL2 */
933 +               __reg_set_bit_mask(glamo, GLAMO_REG_DFT_GEN6, 0x0001, 0xffff);
934 +               __reg_set_bit_mask(glamo, GLAMO_REG_PLL_GEN3, 0x2000, 0x0000);
935 +
936 +               /* spin until PLL1 and PLL2 lock */
937 +               while ((__reg_read(glamo, GLAMO_REG_PLL_GEN5) & 3) != 3)
938 +                       ;
939 +
940 +               /* enable memory clock and get it out of deep pwrdown */
941 +               __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_MEMORY,
942 +                                  GLAMO_CLOCK_MEM_EN_MOCACLK, 0xffff);
943 +               __reg_set_bit_mask(glamo, GLAMO_REG_MEM_DRAM2,
944 +                                  GLAMO_MEM_DRAM2_DEEP_PWRDOWN, 0x0000);
945 +               __reg_set_bit_mask(glamo, GLAMO_REG_MEM_DRAM1,
946 +                                  GLAMO_MEM_DRAM1_SELF_REFRESH, 0x0000);
947 +
948 +               glamo_run_script(glamo, glamo_resume_script,
949 +                                ARRAY_SIZE(glamo_resume_script), 0);
950 +
951 +               break;
952 +       case GLAMO_POWER_STANDBY:
953 +               /* enable memory self-refresh */
954 +               __reg_set_bit_mask(glamo, GLAMO_REG_MEM_DRAM1,
955 +                                  GLAMO_MEM_DRAM1_SELF_REFRESH, 0xffff);
956 +               /* stop memory clock */
957 +               __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_MEMORY,
958 +                                  GLAMO_CLOCK_MEM_EN_MOCACLK, 0x0000);
959 +               /* power down PLL2 and then PLL1 */
960 +               __reg_set_bit_mask(glamo, GLAMO_REG_PLL_GEN3, 0x2000, 0xffff);
961 +               __reg_set_bit_mask(glamo, GLAMO_REG_DFT_GEN5, 0x0001, 0xffff);
962 +               break;
963 +       case GLAMO_POWER_SUSPEND:
964 +               __reg_set_bit_mask(glamo, GLAMO_REG_MEM_DRAM2,
965 +                                  GLAMO_MEM_DRAM2_DEEP_PWRDOWN, 0xffff);
966 +               /* stop memory clock */
967 +               __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_MEMORY,
968 +                                  GLAMO_CLOCK_MEM_EN_MOCACLK, 0x0000);
969 +               /* power down PLL2 and then PLL1 */
970 +               __reg_set_bit_mask(glamo, GLAMO_REG_PLL_GEN3, 0x2000, 0xffff);
971 +               __reg_set_bit_mask(glamo, GLAMO_REG_DFT_GEN5, 0x0001, 0xffff);
972 +               break;
973 +       }
974 +
975 +       spin_unlock(&glamo->lock);
976 +}
977 +
978 +#if 0
979 +#define MEMDETECT_RETRY        6
980 +static unsigned int detect_memsize(struct glamo_core *glamo)
981 +{
982 +       int i;
983 +
984 +       /*static const u_int16_t pattern[] = {
985 +               0x1111, 0x8a8a, 0x2222, 0x7a7a,
986 +               0x3333, 0x6a6a, 0x4444, 0x5a5a,
987 +               0x5555, 0x4a4a, 0x6666, 0x3a3a,
988 +               0x7777, 0x2a2a, 0x8888, 0x1a1a
989 +       }; */
990 +
991 +       for (i = 0; i < MEMDETECT_RETRY; i++) {
992 +               switch (glamo->type) {
993 +               case 3600:
994 +                       __reg_write(glamo, GLAMO_REG_MEM_TYPE, 0x0072);
995 +                       __reg_write(glamo, GLAMO_REG_MEM_DRAM1, 0xc100);
996 +                       break;
997 +               case 3650:
998 +                       switch (glamo->revision) {
999 +                       case GLAMO_CORE_REV_A0:
1000 +                               if (i & 1)
1001 +                                       __reg_write(glamo, GLAMO_REG_MEM_TYPE,
1002 +                                                   0x097a);
1003 +                               else
1004 +                                       __reg_write(glamo, GLAMO_REG_MEM_TYPE,
1005 +                                                   0x0173);
1006 +
1007 +                               __reg_write(glamo, GLAMO_REG_MEM_DRAM1, 0x0000);
1008 +                               msleep(1);
1009 +                               __reg_write(glamo, GLAMO_REG_MEM_DRAM1, 0xc100);
1010 +                               break;
1011 +                       default:
1012 +                               if (i & 1)
1013 +                                       __reg_write(glamo, GLAMO_REG_MEM_TYPE,
1014 +                                                   0x0972);
1015 +                               else
1016 +                                       __reg_write(glamo, GLAMO_REG_MEM_TYPE,
1017 +                                                   0x0872);
1018 +
1019 +                               __reg_write(glamo, GLAMO_REG_MEM_DRAM1, 0x0000);
1020 +                               msleep(1);
1021 +                               __reg_write(glamo, GLAMO_REG_MEM_DRAM1, 0xe100);
1022 +                               break;
1023 +                       }
1024 +                       break;
1025 +               case 3700:
1026 +                       /* FIXME */
1027 +               default:
1028 +                       break;
1029 +               }
1030 +
1031 +#if 0
1032 +               /* FIXME: finish implementation */
1033 +               for (j = 0; j < 8; j++) {
1034 +                       __
1035 +#endif
1036 +       }
1037 +
1038 +       return 0;
1039 +}
1040 +#endif
1041 +
1042 +/* Find out if we can support this version of the Glamo chip */
1043 +static int glamo_supported(struct glamo_core *glamo)
1044 +{
1045 +       u_int16_t dev_id, rev_id; /*, memsize; */
1046 +
1047 +       dev_id = __reg_read(glamo, GLAMO_REG_DEVICE_ID);
1048 +       rev_id = __reg_read(glamo, GLAMO_REG_REVISION_ID);
1049 +
1050 +       switch (dev_id) {
1051 +       case 0x3650:
1052 +               switch (rev_id) {
1053 +               case GLAMO_CORE_REV_A2:
1054 +                       break;
1055 +               case GLAMO_CORE_REV_A0:
1056 +               case GLAMO_CORE_REV_A1:
1057 +               case GLAMO_CORE_REV_A3:
1058 +                       dev_warn(&glamo->pdev->dev, "untested core revision "
1059 +                                "%04x, your mileage may vary\n", rev_id);
1060 +                       break;
1061 +               default:
1062 +                       dev_warn(&glamo->pdev->dev, "unknown glamo revision "
1063 +                                "%04x, your mileage may vary\n", rev_id);
1064 +                       /* maybe should abort ? */
1065 +               }
1066 +               break;
1067 +       case 0x3600:
1068 +       case 0x3700:
1069 +       default:
1070 +               dev_err(&glamo->pdev->dev, "unsupported Glamo device %04x\n",
1071 +                       dev_id);
1072 +               return 0;
1073 +       }
1074 +
1075 +       dev_info(&glamo->pdev->dev, "Detected Glamo core %04x Revision %04x "
1076 +                "(%uHz CPU / %uHz Memory)\n", dev_id, rev_id,
1077 +                glamo_pll_rate(glamo, GLAMO_PLL1),
1078 +                glamo_pll_rate(glamo, GLAMO_PLL2));
1079 +
1080 +       return 1;
1081 +}
1082 +
1083 +
1084 +static int __init glamo_probe(struct platform_device *pdev)
1085 +{
1086 +       int rc, irq;
1087 +       struct glamo_core *glamo;
1088 +
1089 +       if (glamo_handle) {
1090 +               dev_err(&pdev->dev,
1091 +                       "This driver supports only one instance\n");
1092 +               return -EBUSY;
1093 +       }
1094 +
1095 +       glamo = kmalloc(GFP_KERNEL, sizeof(*glamo));
1096 +       if (!glamo)
1097 +               return -ENOMEM;
1098 +
1099 +       spin_lock_init(&glamo->lock);
1100 +       glamo_handle = glamo;
1101 +       glamo->pdev = pdev;
1102 +       glamo->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1103 +       glamo->irq = platform_get_irq(pdev, 0);
1104 +       glamo->pdata = pdev->dev.platform_data;
1105 +       if (!glamo->mem || !glamo->pdata) {
1106 +               dev_err(&pdev->dev, "platform device with no MEM/PDATA ?\n");
1107 +               rc = -ENOENT;
1108 +               goto out_free;
1109 +       }
1110 +
1111 +       /* register a number of sibling devices whoise IOMEM resources
1112 +        * are siblings of pdev's IOMEM resource */
1113 +#if 0
1114 +       glamo_core_dev.dev.parent = &pdev.dev;
1115 +       mangle_mem_resources(glamo_core_dev.resources,
1116 +                            glamo_core_dev.num_resources, glamo->mem);
1117 +       glamo_core_dev.resources[1].start = glamo->irq;
1118 +       glamo_core_dev.resources[1].end = glamo->irq;
1119 +       platform_device_register(&glamo_core_dev);
1120 +#endif
1121 +       /* only remap the generic, hostbus and memory controller registers */
1122 +       glamo->base = ioremap(glamo->mem->start, GLAMO_REGOFS_VIDCAP);
1123 +       if (!glamo->base) {
1124 +               dev_err(&pdev->dev, "failed to ioremap() memory region\n");
1125 +               goto out_free;
1126 +       }
1127 +
1128 +       /* bring MCI specific stuff over from our MFD platform data */
1129 +       glamo_mci_def_pdata.glamo_set_mci_power =
1130 +                                       glamo->pdata->glamo_set_mci_power;
1131 +       glamo_mci_def_pdata.glamo_irq_is_wired =
1132 +                                       glamo->pdata->glamo_irq_is_wired;
1133 +
1134 +       glamo_mmc_dev.dev.parent = &pdev->dev;
1135 +       /* we need it later to give to the engine enable and disable */
1136 +       glamo_mci_def_pdata.pglamo = glamo;
1137 +       mangle_mem_resources(glamo_mmc_dev.resource,
1138 +                            glamo_mmc_dev.num_resources, glamo->mem);
1139 +       platform_device_register(&glamo_mmc_dev);
1140 +
1141 +       glamo_2d_dev.dev.parent = &pdev->dev;
1142 +       mangle_mem_resources(glamo_2d_dev.resource,
1143 +                            glamo_2d_dev.num_resources, glamo->mem);
1144 +       platform_device_register(&glamo_2d_dev);
1145 +
1146 +       glamo_3d_dev.dev.parent = &pdev->dev;
1147 +       mangle_mem_resources(glamo_3d_dev.resource,
1148 +                            glamo_3d_dev.num_resources, glamo->mem);
1149 +       platform_device_register(&glamo_3d_dev);
1150 +
1151 +       glamo_jpeg_dev.dev.parent = &pdev->dev;
1152 +       mangle_mem_resources(glamo_jpeg_dev.resource,
1153 +                            glamo_jpeg_dev.num_resources, glamo->mem);
1154 +       platform_device_register(&glamo_jpeg_dev);
1155 +
1156 +       glamo_mpeg_dev.dev.parent = &pdev->dev;
1157 +       mangle_mem_resources(glamo_mpeg_dev.resource,
1158 +                            glamo_mpeg_dev.num_resources, glamo->mem);
1159 +       platform_device_register(&glamo_mpeg_dev);
1160 +
1161 +       glamo->pdata->glamo = glamo;
1162 +       glamo_fb_dev.dev.parent = &pdev->dev;
1163 +       glamo_fb_dev.dev.platform_data = glamo->pdata;
1164 +       mangle_mem_resources(glamo_fb_dev.resource,
1165 +                            glamo_fb_dev.num_resources, glamo->mem);
1166 +       platform_device_register(&glamo_fb_dev);
1167 +
1168 +       glamo->pdata->spigpio_info->glamo = glamo;
1169 +       glamo_spigpio_dev.dev.parent = &pdev->dev;
1170 +       glamo_spigpio_dev.dev.platform_data = glamo->pdata->spigpio_info;
1171 +       platform_device_register(&glamo_spigpio_dev);
1172 +
1173 +       /* only request the generic, hostbus and memory controller MMIO */
1174 +       glamo->mem = request_mem_region(glamo->mem->start,
1175 +                                       GLAMO_REGOFS_VIDCAP, "glamo-core");
1176 +       if (!glamo->mem) {
1177 +               dev_err(&pdev->dev, "failed to request memory region\n");
1178 +               goto out_free;
1179 +       }
1180 +
1181 +       if (!glamo_supported(glamo)) {
1182 +               dev_err(&pdev->dev, "This Glamo is not supported\n");
1183 +               goto out_free;
1184 +       }
1185 +
1186 +       platform_set_drvdata(pdev, glamo);
1187 +
1188 +       dev_dbg(&glamo->pdev->dev, "running init script\n");
1189 +       glamo_run_script(glamo, glamo_init_script,
1190 +                        ARRAY_SIZE(glamo_init_script), 1);
1191 +
1192 +       dev_info(&glamo->pdev->dev, "Glamo core now %uHz CPU / %uHz Memory)\n",
1193 +                glamo_pll_rate(glamo, GLAMO_PLL1),
1194 +                glamo_pll_rate(glamo, GLAMO_PLL2));
1195 +
1196 +       for (irq = IRQ_GLAMO(0); irq <= IRQ_GLAMO(8); irq++) {
1197 +               set_irq_chip(irq, &glamo_irq_chip);
1198 +               set_irq_handler(irq, handle_level_irq);
1199 +               set_irq_flags(irq, IRQF_VALID);
1200 +       }
1201 +
1202 +       if (glamo->pdata->glamo_irq_is_wired &&
1203 +           !glamo->pdata->glamo_irq_is_wired()) {
1204 +               set_irq_chained_handler(glamo->irq, glamo_irq_demux_handler);
1205 +               set_irq_type(glamo->irq, IRQT_FALLING);
1206 +               glamo->irq_works = 1;
1207 +       } else
1208 +               glamo->irq_works = 0;
1209 +       return 0;
1210 +
1211 +out_free:
1212 +       glamo_handle = NULL;
1213 +       kfree(glamo);
1214 +       return rc;
1215 +}
1216 +
1217 +static int glamo_remove(struct platform_device *pdev)
1218 +{
1219 +       struct glamo_core *glamo = platform_get_drvdata(pdev);
1220 +       int irq;
1221 +
1222 +       disable_irq(glamo->irq);
1223 +       set_irq_chained_handler(glamo->irq, NULL);
1224 +
1225 +       for (irq = IRQ_GLAMO(0); irq <= IRQ_GLAMO(8); irq++) {
1226 +               set_irq_flags(irq, 0);
1227 +               set_irq_chip(irq, NULL);
1228 +       }
1229 +
1230 +       platform_set_drvdata(pdev, NULL);
1231 +       platform_device_unregister(&glamo_fb_dev);
1232 +       platform_device_unregister(&glamo_mmc_dev);
1233 +       iounmap(glamo->base);
1234 +       release_mem_region(glamo->mem->start, GLAMO_REGOFS_VIDCAP);
1235 +       glamo_handle = NULL;
1236 +       kfree(glamo);
1237 +
1238 +       return 0;
1239 +}
1240 +
1241 +#ifdef CONFIG_PM
1242 +static int glamo_suspend(struct platform_device *pdev, pm_message_t state)
1243 +{
1244 +       return 0;
1245 +}
1246 +
1247 +static int glamo_resume(struct platform_device *pdev)
1248 +{
1249 +       return 0;
1250 +}
1251 +#else
1252 +#define glamo_suspend NULL
1253 +#define glamo_resume  NULL
1254 +#endif
1255 +
1256 +static struct platform_driver glamo_driver = {
1257 +       .probe          = glamo_probe,
1258 +       .remove         = glamo_remove,
1259 +       .suspend        = glamo_suspend,
1260 +       .resume         = glamo_resume,
1261 +       .driver         = {
1262 +               .name   = "glamo3362",
1263 +               .owner  = THIS_MODULE,
1264 +       },
1265 +};
1266 +
1267 +static int __devinit glamo_init(void)
1268 +{
1269 +       return platform_driver_register(&glamo_driver);
1270 +}
1271 +
1272 +static void __exit glamo_cleanup(void)
1273 +{
1274 +       platform_driver_unregister(&glamo_driver);
1275 +}
1276 +
1277 +module_init(glamo_init);
1278 +module_exit(glamo_cleanup);
1279 +
1280 +MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>");
1281 +MODULE_DESCRIPTION("Smedia Glamo 336x/337x core/resource driver");
1282 +MODULE_LICENSE("GPL");
1283 diff --git a/drivers/mfd/glamo/glamo-core.h b/drivers/mfd/glamo/glamo-core.h
1284 new file mode 100644
1285 index 0000000..cf89f03
1286 --- /dev/null
1287 +++ b/drivers/mfd/glamo/glamo-core.h
1288 @@ -0,0 +1,91 @@
1289 +#ifndef __GLAMO_CORE_H
1290 +#define __GLAMO_CORE_H
1291 +
1292 +#include <asm/system.h>
1293 +
1294 +
1295 +/* for the time being, we put the on-screen framebuffer into the lowest
1296 + * VRAM space.  This should make the code easily compatible with the various
1297 + * 2MB/4MB/8MB variants of the Smedia chips */
1298 +#define GLAMO_OFFSET_VRAM      0x800000
1299 +#define GLAMO_OFFSET_FB        (GLAMO_OFFSET_VRAM)
1300 +
1301 +/* we only allocate the minimum possible size for the framebuffer to make
1302 + * sure we have sufficient memory for other functions of the chip */
1303 +//#define GLAMO_FB_SIZE        (640*480*4)     /* == 0x12c000 */
1304 +#define GLAMO_INTERNAL_RAM_SIZE 0x800000
1305 +#define GLAMO_MMC_BUFFER_SIZE (64 * 1024)
1306 +#define GLAMO_FB_SIZE  (GLAMO_INTERNAL_RAM_SIZE - GLAMO_MMC_BUFFER_SIZE)
1307 +
1308 +
1309 +struct glamo_core {
1310 +       int irq;
1311 +       int irq_works; /* 0 means PCB does not support Glamo IRQ */
1312 +       struct resource *mem;
1313 +       struct resource *mem_core;
1314 +       void __iomem *base;
1315 +       struct platform_device *pdev;
1316 +       struct glamofb_platform_data *pdata;
1317 +       u_int16_t type;
1318 +       u_int16_t revision;
1319 +       spinlock_t lock;
1320 +};
1321 +
1322 +struct glamo_script {
1323 +       u_int16_t reg;
1324 +       u_int16_t val;
1325 +};
1326 +
1327 +int glamo_run_script(struct glamo_core *glamo,
1328 +                    struct glamo_script *script, int len, int may_sleep);
1329 +
1330 +enum glamo_engine {
1331 +       GLAMO_ENGINE_CAPTURE,
1332 +       GLAMO_ENGINE_ISP,
1333 +       GLAMO_ENGINE_JPEG,
1334 +       GLAMO_ENGINE_MPEG_ENC,
1335 +       GLAMO_ENGINE_MPEG_DEC,
1336 +       GLAMO_ENGINE_LCD,
1337 +       GLAMO_ENGINE_CMDQ,
1338 +       GLAMO_ENGINE_2D,
1339 +       GLAMO_ENGINE_3D,
1340 +       GLAMO_ENGINE_MMC,
1341 +       GLAMO_ENGINE_MICROP0,
1342 +       GLAMO_ENGINE_RISC,
1343 +       GLAMO_ENGINE_MICROP1_MPEG_ENC,
1344 +       GLAMO_ENGINE_MICROP1_MPEG_DEC,
1345 +#if 0
1346 +       GLAMO_ENGINE_H264_DEC,
1347 +       GLAMO_ENGINE_RISC1,
1348 +       GLAMO_ENGINE_SPI,
1349 +#endif
1350 +       __NUM_GLAMO_ENGINES
1351 +};
1352 +
1353 +struct glamo_mci_pdata {
1354 +       struct glamo_core * pglamo;
1355 +       unsigned int    gpio_detect;
1356 +       unsigned int    gpio_wprotect;
1357 +       unsigned long   ocr_avail;
1358 +       void            (*glamo_set_mci_power)(unsigned char power_mode,
1359 +                                    unsigned short vdd);
1360 +       int             (*glamo_irq_is_wired)(void);
1361 +};
1362 +
1363 +
1364 +static inline void glamo_reg_access_delay(void)
1365 +{
1366 +       int n;
1367 +
1368 +       for (n = 0; n != 2; n++)
1369 +               nop();
1370 +}
1371 +
1372 +
1373 +int glamo_engine_enable(struct glamo_core *glamo, enum glamo_engine engine);
1374 +int glamo_engine_disable(struct glamo_core *glamo, enum glamo_engine engine);
1375 +void glamo_engine_reset(struct glamo_core *glamo, enum glamo_engine engine);
1376 +int glamo_engine_reclock(struct glamo_core *glamo,
1377 +                        enum glamo_engine engine, int ps);
1378 +
1379 +#endif /* __GLAMO_CORE_H */
1380 diff --git a/drivers/mfd/glamo/glamo-fb.c b/drivers/mfd/glamo/glamo-fb.c
1381 new file mode 100644
1382 index 0000000..394a0ad
1383 --- /dev/null
1384 +++ b/drivers/mfd/glamo/glamo-fb.c
1385 @@ -0,0 +1,822 @@
1386 +/* Smedia Glamo 336x/337x driver
1387 + *
1388 + * (C) 2007 by OpenMoko, Inc.
1389 + * Author: Harald Welte <laforge@openmoko.org>
1390 + * All rights reserved.
1391 + *
1392 + * This program is free software; you can redistribute it and/or
1393 + * modify it under the terms of the GNU General Public License as
1394 + * published by the Free Software Foundation; either version 2 of
1395 + * the License, or (at your option) any later version.
1396 + *
1397 + * This program is distributed in the hope that it will be useful,
1398 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1399 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1400 + * GNU General Public License for more details.
1401 + *
1402 + * You should have received a copy of the GNU General Public License
1403 + * along with this program; if not, write to the Free Software
1404 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
1405 + * MA 02111-1307 USA
1406 + */
1407 +
1408 +#include <linux/module.h>
1409 +#include <linux/kernel.h>
1410 +#include <linux/errno.h>
1411 +#include <linux/string.h>
1412 +#include <linux/mm.h>
1413 +#include <linux/slab.h>
1414 +#include <linux/delay.h>
1415 +#include <linux/fb.h>
1416 +#include <linux/init.h>
1417 +#include <linux/vmalloc.h>
1418 +#include <linux/dma-mapping.h>
1419 +#include <linux/interrupt.h>
1420 +#include <linux/workqueue.h>
1421 +#include <linux/wait.h>
1422 +#include <linux/platform_device.h>
1423 +#include <linux/clk.h>
1424 +
1425 +#include <asm/io.h>
1426 +#include <asm/uaccess.h>
1427 +#include <asm/div64.h>
1428 +
1429 +#ifdef CONFIG_PM
1430 +#include <linux/pm.h>
1431 +#endif
1432 +
1433 +#include <linux/glamofb.h>
1434 +
1435 +#include "glamo-regs.h"
1436 +#include "glamo-core.h"
1437 +
1438 +#ifdef DEBUG
1439 +#define GLAMO_LOG(...)
1440 +#else
1441 +#define GLAMO_LOG(...) \
1442 +do { \
1443 +       printk(KERN_DEBUG "in %s:%s:%d", __FILE__, __func__, __LINE__); \
1444 +       printk(KERN_DEBUG __VA_ARGS__); \
1445 +} while (0);
1446 +#endif
1447 +
1448 +
1449 +#define RESSIZE(ressource) (((ressource)->end - (ressource)->start)+1)
1450 +
1451 +struct glamofb_handle {
1452 +       struct fb_info *fb;
1453 +       struct device *dev;
1454 +       struct resource *reg;
1455 +       struct resource *fb_res;
1456 +       char __iomem *base;
1457 +       struct glamofb_platform_data *mach_info;
1458 +       char __iomem *cursor_addr;
1459 +       u_int32_t pseudo_pal[16];
1460 +};
1461 +
1462 +/* 'sibling' spi device for lcm init */
1463 +static struct platform_device glamo_spi_dev = {
1464 +       .name           = "glamo-lcm-spi",
1465 +};
1466 +
1467 +
1468 +static int reg_read(struct glamofb_handle *glamo,
1469 +                          u_int16_t reg)
1470 +{
1471 +       glamo_reg_access_delay();
1472 +       return readw(glamo->base + reg);
1473 +}
1474 +
1475 +static void reg_write(struct glamofb_handle *glamo,
1476 +                            u_int16_t reg, u_int16_t val)
1477 +{
1478 +       glamo_reg_access_delay();
1479 +       writew(val, glamo->base + reg);
1480 +}
1481 +
1482 +static struct glamo_script glamo_regs[] = {
1483 +       { GLAMO_REG_LCD_MODE1, 0x0020 },
1484 +       /* no display rotation, no hardware cursor, no dither, no gamma,
1485 +        * no retrace flip, vsync low-active, hsync low active,
1486 +        * no TVCLK, no partial display, hw dest color from fb,
1487 +        * no partial display mode, LCD1, software flip,  */
1488 +       { GLAMO_REG_LCD_MODE2, 0x1020 },
1489 +         /* no video flip, no ptr, no ptr, dhclk,
1490 +          * normal mode,  no cpuif,
1491 +          * res, serial msb first, single fb, no fr ctrl,
1492 +          * cpu if bits all zero, no crc
1493 +          * 0000 0000 0010  0000 */
1494 +       { GLAMO_REG_LCD_MODE3, 0x0b40 },
1495 +         /* src data rgb565, res, 18bit rgb666
1496 +          * 000 01 011 0100 0000 */
1497 +       { GLAMO_REG_LCD_POLARITY, 0x440c },
1498 +         /* DE high active, no cpu/lcd if, cs0 force low, a0 low active,
1499 +          * np cpu if, 9bit serial data, sclk rising edge latch data
1500 +          * 01 00 0 100 0 000 01 0 0 */
1501 +       { GLAMO_REG_LCD_A_BASE1, 0x0000 }, /* display A base address 15:0 */
1502 +       { GLAMO_REG_LCD_A_BASE2, 0x0000 }, /* display A base address 22:16 */
1503 +};
1504 +
1505 +static int glamofb_run_script(struct glamofb_handle *glamo,
1506 +                               struct glamo_script *script, int len)
1507 +{
1508 +       int i;
1509 +
1510 +       for (i = 0; i < len; i++) {
1511 +               struct glamo_script *line = &script[i];
1512 +
1513 +               if (line->reg == 0xffff)
1514 +                       return 0;
1515 +               else if (line->reg == 0xfffe)
1516 +                       msleep(line->val);
1517 +               else
1518 +                       reg_write(glamo, script[i].reg, script[i].val);
1519 +       }
1520 +
1521 +       return 0;
1522 +}
1523 +
1524 +static int glamofb_check_var(struct fb_var_screeninfo *var,
1525 +                            struct fb_info *info)
1526 +{
1527 +       struct glamofb_handle *glamo = info->par;
1528 +
1529 +       if (var->yres > glamo->mach_info->yres.max)
1530 +               var->yres = glamo->mach_info->yres.max;
1531 +       else if (var->yres < glamo->mach_info->yres.min)
1532 +               var->yres = glamo->mach_info->yres.min;
1533 +
1534 +       if (var->xres > glamo->mach_info->xres.max)
1535 +               var->xres = glamo->mach_info->xres.max;
1536 +       else if (var->xres < glamo->mach_info->xres.min)
1537 +               var->xres = glamo->mach_info->xres.min;
1538 +
1539 +       if (var->bits_per_pixel > glamo->mach_info->bpp.max)
1540 +               var->bits_per_pixel = glamo->mach_info->bpp.max;
1541 +       else if (var->bits_per_pixel < glamo->mach_info->bpp.min)
1542 +               var->bits_per_pixel = glamo->mach_info->bpp.min;
1543 +
1544 +       /* FIXME: set rgb positions */
1545 +       switch (var->bits_per_pixel) {
1546 +       case 16:
1547 +               switch (reg_read(glamo, GLAMO_REG_LCD_MODE3) & 0xc000) {
1548 +               case GLAMO_LCD_SRC_RGB565:
1549 +                       var->red.offset         = 11;
1550 +                       var->green.offset       = 5;
1551 +                       var->blue.offset        = 0;
1552 +                       var->red.length         = 5;
1553 +                       var->green.length       = 6;
1554 +                       var->blue.length        = 5;
1555 +                       var->transp.length      = 0;
1556 +                       break;
1557 +               case GLAMO_LCD_SRC_ARGB1555:
1558 +                       var->transp.offset      = 15;
1559 +                       var->red.offset         = 10;
1560 +                       var->green.offset       = 5;
1561 +                       var->blue.offset        = 0;
1562 +                       var->transp.length      = 1;
1563 +                       var->red.length         = 5;
1564 +                       var->green.length       = 5;
1565 +                       var->blue.length        = 5;
1566 +                       break;
1567 +               case GLAMO_LCD_SRC_ARGB4444:
1568 +                       var->transp.offset      = 12;
1569 +                       var->red.offset         = 8;
1570 +                       var->green.offset       = 4;
1571 +                       var->blue.offset        = 0;
1572 +                       var->transp.length      = 4;
1573 +                       var->red.length         = 4;
1574 +                       var->green.length       = 4;
1575 +                       var->blue.length        = 4;
1576 +                       break;
1577 +               }
1578 +               break;
1579 +       case 24:
1580 +       case 32:
1581 +       default:
1582 +               /* The Smedia Glamo doesn't support anything but 16bit color */
1583 +               printk(KERN_ERR
1584 +                      "Smedia driver does not [yet?] support 24/32bpp\n");
1585 +               return -EINVAL;
1586 +               break;
1587 +       }
1588 +
1589 +       return 0;
1590 +}
1591 +
1592 +static void reg_set_bit_mask(struct glamofb_handle *glamo,
1593 +                            u_int16_t reg, u_int16_t mask,
1594 +                            u_int16_t val)
1595 +{
1596 +       u_int16_t tmp;
1597 +
1598 +       val &= mask;
1599 +
1600 +       tmp = reg_read(glamo, reg);
1601 +       tmp &= ~mask;
1602 +       tmp |= val;
1603 +       reg_write(glamo, reg, tmp);
1604 +}
1605 +
1606 +#define GLAMO_LCD_WIDTH_MASK 0x03FF
1607 +#define GLAMO_LCD_HEIGHT_MASK 0x03FF
1608 +#define GLAMO_LCD_PITCH_MASK 0x07FE
1609 +#define GLAMO_LCD_HV_TOTAL_MASK 0x03FF
1610 +#define GLAMO_LCD_HV_RETR_START_MASK 0x03FF
1611 +#define GLAMO_LCD_HV_RETR_END_MASK 0x03FF
1612 +#define GLAMO_LCD_HV_RETR_DISP_START_MASK 0x03FF
1613 +#define GLAMO_LCD_HV_RETR_DISP_END_MASK 0x03FF
1614 +
1615 +enum orientation {
1616 +    ORIENTATION_PORTRAIT,
1617 +    ORIENTATION_LANDSCAPE
1618 +};
1619 +
1620 +
1621 +static void rotate_lcd(struct glamofb_handle *glamo,
1622 +                       __u32 rotation)
1623 +{
1624 +       int glamo_rot;
1625 +
1626 +       switch (rotation) {
1627 +               case FB_ROTATE_UR:
1628 +                       glamo_rot = GLAMO_LCD_ROT_MODE_0;
1629 +                       break;
1630 +               case FB_ROTATE_CW:
1631 +                       glamo_rot = GLAMO_LCD_ROT_MODE_90;
1632 +                       break;
1633 +               case FB_ROTATE_UD:
1634 +                       glamo_rot = GLAMO_LCD_ROT_MODE_180;
1635 +                       break;
1636 +               case FB_ROTATE_CCW:
1637 +                       glamo_rot = GLAMO_LCD_ROT_MODE_270;
1638 +                       break;
1639 +               default:
1640 +                       glamo_rot = GLAMO_LCD_ROT_MODE_0;
1641 +                       break;
1642 +       }
1643 +       glamofb_cmd_mode(glamo, 1);
1644 +       reg_set_bit_mask(glamo,
1645 +                        GLAMO_REG_LCD_WIDTH,
1646 +                        GLAMO_LCD_ROT_MODE_MASK,
1647 +                        glamo_rot);
1648 +       reg_set_bit_mask(glamo,
1649 +                        GLAMO_REG_LCD_MODE1,
1650 +                        GLAMO_LCD_MODE1_ROTATE_EN,
1651 +                        (glamo_rot != GLAMO_LCD_ROT_MODE_0)?
1652 +                                GLAMO_LCD_MODE1_ROTATE_EN : 0);
1653 +       glamofb_cmd_mode(glamo, 0);
1654 +}
1655 +
1656 +static enum orientation get_orientation(struct fb_var_screeninfo *var)
1657 +{
1658 +       GLAMO_LOG("mark\n")
1659 +       if (var->xres <= var->yres) {
1660 +               GLAMO_LOG("portrait\n")
1661 +               return ORIENTATION_PORTRAIT;
1662 +       }
1663 +       GLAMO_LOG("landscape\n")
1664 +       return ORIENTATION_LANDSCAPE;
1665 +}
1666 +
1667 +static int will_orientation_change(struct fb_var_screeninfo *var)
1668 +{
1669 +       enum  orientation orient = get_orientation(var);
1670 +       switch (orient) {
1671 +               case ORIENTATION_LANDSCAPE:
1672 +                       if (var->rotate == FB_ROTATE_UR || var->rotate == FB_ROTATE_UD)
1673 +                               return 1;
1674 +                       break;
1675 +               case ORIENTATION_PORTRAIT:
1676 +                       if (var->rotate == FB_ROTATE_CW || var->rotate == FB_ROTATE_CCW)
1677 +                               return 1;
1678 +                       break;
1679 +       }
1680 +       return 0;
1681 +}
1682 +
1683 +static void glamofb_update_lcd_controller(struct glamofb_handle *glamo,
1684 +                                         struct fb_var_screeninfo *var)
1685 +{
1686 +       int sync, bp, disp, fp, total, xres, yres, pitch, orientation_changing;
1687 +
1688 +       GLAMO_LOG("enter: glamo:%#x, var:%#x\n", (unsigned)glamo, (unsigned)var);
1689 +       if (!glamo || !var)
1690 +               return;
1691 +
1692 +       glamofb_cmd_mode(glamo, 1);
1693 +
1694 +       if (var->pixclock)
1695 +               glamo_engine_reclock(glamo->mach_info->glamo,
1696 +                                    GLAMO_ENGINE_LCD,
1697 +                                    var->pixclock);
1698 +
1699 +       xres = var->xres;
1700 +       yres = var->yres;
1701 +       GLAMO_LOG("xres:%d, yres:%d, rotate:%d\n", xres, yres, var->rotate);
1702 +
1703 +       /*
1704 +        * figure out if orientation is going to change
1705 +        */
1706 +       orientation_changing = will_orientation_change(var);
1707 +       GLAMO_LOG("orientation_changing:%d\n", orientation_changing);
1708 +
1709 +        /*
1710 +         * adjust the pitch according to new orientation to come
1711 +         */
1712 +        if (orientation_changing) {
1713 +               pitch = var->yres * var->bits_per_pixel / 8;
1714 +        } else {
1715 +               pitch = var->xres * var->bits_per_pixel / 8;
1716 +        }
1717 +       GLAMO_LOG("pitch:%d\n", pitch);
1718 +
1719 +       /*
1720 +        * set the awaiten LCD geometry
1721 +        */
1722 +       reg_set_bit_mask(glamo,
1723 +                        GLAMO_REG_LCD_WIDTH,
1724 +                        GLAMO_LCD_WIDTH_MASK,
1725 +                        xres);
1726 +       reg_set_bit_mask(glamo,
1727 +                        GLAMO_REG_LCD_HEIGHT,
1728 +                        GLAMO_LCD_HEIGHT_MASK,
1729 +                        yres);
1730 +       reg_set_bit_mask(glamo,
1731 +                        GLAMO_REG_LCD_PITCH,
1732 +                        GLAMO_LCD_PITCH_MASK,
1733 +                        pitch);
1734 +
1735 +       GLAMO_LOG("mark:\n");
1736 +       /*
1737 +        * honour the rotation request
1738 +        */
1739 +       rotate_lcd(glamo, var->rotate);
1740 +
1741 +       /*
1742 +        * update the reported geometry
1743 +        * of the framebuffer.
1744 +        */
1745 +       if (orientation_changing) {
1746 +               var->xres_virtual = var->xres = yres;
1747 +               var->yres_virtual = var->yres = xres;
1748 +       } else {
1749 +               var->xres_virtual = var->xres = xres;
1750 +               var->yres_virtual = var->yres = yres;
1751 +       }
1752 +
1753 +       GLAMO_LOG("reported res:(%d,%d)\n", var->xres, var->yres);
1754 +       /*
1755 +        * update scannout timings
1756 +        */
1757 +       sync = 0;
1758 +       bp = sync + var->hsync_len;
1759 +       disp = bp + var->left_margin;
1760 +       fp = disp + xres;
1761 +       total = fp + var->right_margin;
1762 +
1763 +       reg_set_bit_mask(glamo, GLAMO_REG_LCD_HORIZ_TOTAL,
1764 +                        GLAMO_LCD_HV_TOTAL_MASK, total);
1765 +       reg_set_bit_mask(glamo, GLAMO_REG_LCD_HORIZ_RETR_START,
1766 +                        GLAMO_LCD_HV_RETR_START_MASK, sync);
1767 +       reg_set_bit_mask(glamo, GLAMO_REG_LCD_HORIZ_RETR_END,
1768 +                        GLAMO_LCD_HV_RETR_END_MASK, bp);
1769 +       reg_set_bit_mask(glamo, GLAMO_REG_LCD_HORIZ_DISP_START,
1770 +                         GLAMO_LCD_HV_RETR_DISP_START_MASK, disp);
1771 +       reg_set_bit_mask(glamo, GLAMO_REG_LCD_HORIZ_DISP_END,
1772 +                        GLAMO_LCD_HV_RETR_DISP_END_MASK, fp);
1773 +
1774 +       GLAMO_LOG("mark:\n");
1775 +
1776 +       sync = 0;
1777 +       bp = sync + var->vsync_len;
1778 +       disp = bp + var->upper_margin;
1779 +       fp = disp + yres;
1780 +       total = fp + var->lower_margin;
1781 +
1782 +       reg_set_bit_mask(glamo, GLAMO_REG_LCD_VERT_TOTAL,
1783 +                        GLAMO_LCD_HV_TOTAL_MASK, total);
1784 +       reg_set_bit_mask(glamo, GLAMO_REG_LCD_VERT_RETR_START,
1785 +                         GLAMO_LCD_HV_RETR_START_MASK, sync);
1786 +       reg_set_bit_mask(glamo, GLAMO_REG_LCD_VERT_RETR_END,
1787 +                        GLAMO_LCD_HV_RETR_END_MASK, bp);
1788 +       reg_set_bit_mask(glamo, GLAMO_REG_LCD_VERT_DISP_START,
1789 +                        GLAMO_LCD_HV_RETR_DISP_START_MASK, disp);
1790 +       reg_set_bit_mask(glamo, GLAMO_REG_LCD_VERT_DISP_END,
1791 +                        GLAMO_LCD_HV_RETR_DISP_END_MASK, fp);
1792 +
1793 +       GLAMO_LOG("mark:\n");
1794 +       glamofb_cmd_mode(glamo, 0);
1795 +
1796 +       GLAMO_LOG("leave:\n");
1797 +}
1798 +
1799 +static int glamofb_set_par(struct fb_info *info)
1800 +{
1801 +       struct glamofb_handle *glamo = info->par;
1802 +       struct fb_var_screeninfo *var = &info->var;
1803 +
1804 +       switch (var->bits_per_pixel) {
1805 +       case 16:
1806 +               info->fix.visual = FB_VISUAL_TRUECOLOR;
1807 +               break;
1808 +       default:
1809 +               printk("Smedia driver doesn't support != 16bpp\n");
1810 +               return -EINVAL;
1811 +       }
1812 +
1813 +       info->fix.line_length = (var->xres * var->bits_per_pixel) / 8;
1814 +
1815 +       glamofb_update_lcd_controller(glamo, var);
1816 +
1817 +       return 0;
1818 +}
1819 +
1820 +static int glamofb_blank(int blank_mode, struct fb_info *info)
1821 +{
1822 +       /* FIXME */
1823 +       return 0;
1824 +}
1825 +
1826 +static inline unsigned int chan_to_field(unsigned int chan, struct fb_bitfield *bf)
1827 +{
1828 +       chan &= 0xffff;
1829 +       chan >>= 16 - bf->length;
1830 +       return chan << bf->offset;
1831 +}
1832 +
1833 +static int glamofb_setcolreg(unsigned regno,
1834 +                            unsigned red, unsigned green, unsigned blue,
1835 +                            unsigned transp, struct fb_info *info)
1836 +{
1837 +       struct glamofb_handle *glamo = info->par;
1838 +       unsigned int val;
1839 +
1840 +       switch (glamo->fb->fix.visual) {
1841 +       case FB_VISUAL_TRUECOLOR:
1842 +       case FB_VISUAL_DIRECTCOLOR:
1843 +               /* true-colour, use pseuo-palette */
1844 +
1845 +               if (regno < 16) {
1846 +                       u32 *pal = glamo->fb->pseudo_palette;
1847 +
1848 +                       val  = chan_to_field(red, &glamo->fb->var.red);
1849 +                       val |= chan_to_field(green, &glamo->fb->var.green);
1850 +                       val |= chan_to_field(blue, &glamo->fb->var.blue);
1851 +
1852 +                       pal[regno] = val;
1853 +               };
1854 +               break;
1855 +       default:
1856 +               return 1; /* unknown type */
1857 +       }
1858 +
1859 +       return 0;
1860 +}
1861 +
1862 +static int glamofb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1863 +{
1864 +       struct glamofb_handle *glamo = info->par;
1865 +       u_int16_t reg;
1866 +
1867 +       if (cursor->image.depth > 2)
1868 +               return -EINVAL;
1869 +
1870 +       reg = reg_read(glamo, GLAMO_REG_LCD_MODE1);
1871 +
1872 +       if (cursor->enable)
1873 +               reg_write(glamo, GLAMO_REG_LCD_MODE1,
1874 +                         reg | GLAMO_LCD_MODE1_CURSOR_EN);
1875 +       else
1876 +               reg_write(glamo, GLAMO_REG_LCD_MODE1,
1877 +                         reg & ~GLAMO_LCD_MODE1_CURSOR_EN);
1878 +
1879 +       if (cursor->set & FB_CUR_SETPOS) {
1880 +               reg_write(glamo, GLAMO_REG_LCD_CURSOR_X_POS,
1881 +                         cursor->image.dx);
1882 +               reg_write(glamo, GLAMO_REG_LCD_CURSOR_Y_POS,
1883 +                         cursor->image.dy);
1884 +       }
1885 +
1886 +       if (cursor->set & FB_CUR_SETCMAP) {
1887 +               /* FIXME */
1888 +       }
1889 +
1890 +       if (cursor->set & FB_CUR_SETSIZE ||
1891 +           cursor->set & (FB_CUR_SETIMAGE | FB_CUR_SETSHAPE)) {
1892 +               int x, y, op;
1893 +               const unsigned char *pcol = cursor->image.data;
1894 +               const unsigned char *pmsk = cursor->mask;
1895 +               void __iomem *dst = glamo->cursor_addr;
1896 +               unsigned char dcol = 0;
1897 +               unsigned char dmsk = 0;
1898 +
1899 +               reg_write(glamo, GLAMO_REG_LCD_CURSOR_X_SIZE,
1900 +                         cursor->image.width);
1901 +               reg_write(glamo, GLAMO_REG_LCD_CURSOR_PITCH,
1902 +                         cursor->image.width * 2);
1903 +               reg_write(glamo, GLAMO_REG_LCD_CURSOR_Y_SIZE,
1904 +                         cursor->image.height);
1905 +
1906 +               for (op = 0; op < (cursor->image.width *
1907 +                                  cursor->image.height * 2)/8; op += 4)
1908 +                       writel(0x0, dst + op);
1909 +
1910 +               for (y = 0; y < cursor->image.height; y++) {
1911 +                       for (x = 0; x < cursor->image.width; x++) {
1912 +                               if ((x % 8) == 0) {
1913 +                                       dcol = *pcol++;
1914 +                                       dmsk = *pmsk++;
1915 +                               } else {
1916 +                                       dcol >>= 1;
1917 +                                       dmsk >>= 1;
1918 +                               }
1919 +
1920 +                               if (dmsk & 1) {
1921 +                                       unsigned int op;
1922 +
1923 +                                       op = (dcol & 1) ? 1 : 3;
1924 +                                       op <<= ((x % 4) * 2);
1925 +
1926 +                                       op |= readb(dst + (x / 4));
1927 +                                       writeb(op, dst + (x / 4));
1928 +                               }
1929 +                       }
1930 +               }
1931 +       }
1932 +}
1933 +
1934 +static inline int glamofb_cmdq_empty(struct glamofb_handle *gfb)
1935 +{
1936 +       return reg_read(gfb, GLAMO_REG_LCD_STATUS1) & (1 << 15);
1937 +}
1938 +
1939 +void glamofb_cmd_mode(struct glamofb_handle *gfb, int on)
1940 +{
1941 +       dev_dbg(gfb->dev, "glamofb_cmd_mode(gfb=%p, on=%d)\n", gfb, on);
1942 +       if (on) {
1943 +               dev_dbg(gfb->dev, "%s: waiting for cmdq empty: ",
1944 +                       __FUNCTION__);
1945 +               while (!glamofb_cmdq_empty(gfb))
1946 +                       yield();
1947 +               dev_dbg(gfb->dev, "empty!\n");
1948 +
1949 +               /* display the entire frame then switch to command */
1950 +               reg_write(gfb, GLAMO_REG_LCD_COMMAND1,
1951 +                         GLAMO_LCD_CMD_TYPE_DISP |
1952 +                         GLAMO_LCD_CMD_DATA_FIRE_VSYNC);
1953 +
1954 +               /* wait until LCD is idle */
1955 +               dev_dbg(gfb->dev, "waiting for LCD idle: ");
1956 +               while (!reg_read(gfb, GLAMO_REG_LCD_STATUS2) & (1 << 12))
1957 +                       yield();
1958 +               dev_dbg(gfb->dev, "idle!\n");
1959 +
1960 +               msleep(90);
1961 +       } else {
1962 +               /* RGB interface needs vsync/hsync */
1963 +               if (reg_read(gfb, GLAMO_REG_LCD_MODE3) & GLAMO_LCD_MODE3_RGB)
1964 +                       reg_write(gfb, GLAMO_REG_LCD_COMMAND1,
1965 +                                 GLAMO_LCD_CMD_TYPE_DISP |
1966 +                                 GLAMO_LCD_CMD_DATA_DISP_SYNC);
1967 +
1968 +               reg_write(gfb, GLAMO_REG_LCD_COMMAND1,
1969 +                         GLAMO_LCD_CMD_TYPE_DISP |
1970 +                         GLAMO_LCD_CMD_DATA_DISP_FIRE);
1971 +       }
1972 +}
1973 +EXPORT_SYMBOL_GPL(glamofb_cmd_mode);
1974 +
1975 +int glamofb_cmd_write(struct glamofb_handle *gfb, u_int16_t val)
1976 +{
1977 +       dev_dbg(gfb->dev, "%s: waiting for cmdq empty\n",
1978 +               __FUNCTION__);
1979 +       while (!glamofb_cmdq_empty(gfb))
1980 +               yield();
1981 +       dev_dbg(gfb->dev, "idle, writing 0x%04x\n", val);
1982 +
1983 +       reg_write(gfb, GLAMO_REG_LCD_COMMAND1, val);
1984 +
1985 +       return 0;
1986 +}
1987 +EXPORT_SYMBOL_GPL(glamofb_cmd_write);
1988 +
1989 +static struct fb_ops glamofb_ops = {
1990 +       .owner          = THIS_MODULE,
1991 +       .fb_check_var   = glamofb_check_var,
1992 +       .fb_set_par     = glamofb_set_par,
1993 +       .fb_blank       = glamofb_blank,
1994 +       .fb_setcolreg   = glamofb_setcolreg,
1995 +       //.fb_cursor    = glamofb_cursor,
1996 +       .fb_fillrect    = cfb_fillrect,
1997 +       .fb_copyarea    = cfb_copyarea,
1998 +       .fb_imageblit   = cfb_imageblit,
1999 +};
2000 +
2001 +static int glamofb_init_regs(struct glamofb_handle *glamo)
2002 +{
2003 +       struct fb_info *info = glamo->fb;
2004 +
2005 +       glamofb_check_var(&info->var, info);
2006 +       glamofb_run_script(glamo, glamo_regs, ARRAY_SIZE(glamo_regs));
2007 +       glamofb_set_par(info);
2008 +
2009 +       return 0;
2010 +}
2011 +
2012 +static int __init glamofb_probe(struct platform_device *pdev)
2013 +{
2014 +       int rc = -EIO;
2015 +       struct fb_info *fbinfo;
2016 +       struct glamofb_handle *glamofb;
2017 +       struct glamofb_platform_data *mach_info = pdev->dev.platform_data;
2018 +
2019 +       printk(KERN_INFO "SMEDIA Glamo frame buffer driver (C) 2007 "
2020 +               "OpenMoko, Inc.\n");
2021 +
2022 +       fbinfo = framebuffer_alloc(sizeof(struct glamofb_handle), &pdev->dev);
2023 +       if (!fbinfo)
2024 +               return -ENOMEM;
2025 +
2026 +       glamofb = fbinfo->par;
2027 +       glamofb->fb = fbinfo;
2028 +       glamofb->dev = &pdev->dev;
2029 +
2030 +       strcpy(fbinfo->fix.id, "SMedia Glamo");
2031 +
2032 +       glamofb->reg = platform_get_resource_byname(pdev, IORESOURCE_MEM,
2033 +                                                   "glamo-fb-regs");
2034 +       if (!glamofb->reg) {
2035 +               dev_err(&pdev->dev, "platform device with no registers?\n");
2036 +               rc = -ENOENT;
2037 +               goto out_free;
2038 +       }
2039 +
2040 +       glamofb->fb_res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
2041 +                                                       "glamo-fb-mem");
2042 +       if (!glamofb->fb_res) {
2043 +               dev_err(&pdev->dev, "platform device with no memory ?\n");
2044 +               rc = -ENOENT;
2045 +               goto out_free;
2046 +       }
2047 +
2048 +       glamofb->reg = request_mem_region(glamofb->reg->start,
2049 +                                         RESSIZE(glamofb->reg), pdev->name);
2050 +       if (!glamofb->reg) {
2051 +               dev_err(&pdev->dev, "failed to request mmio region\n");
2052 +               goto out_free;
2053 +       }
2054 +
2055 +       glamofb->fb_res = request_mem_region(glamofb->fb_res->start,
2056 +                                            mach_info->fb_mem_size,
2057 +                                            pdev->name);
2058 +       if (!glamofb->fb_res) {
2059 +               dev_err(&pdev->dev, "failed to request vram region\n");
2060 +               goto out_release_reg;
2061 +       }
2062 +
2063 +       /* we want to remap only the registers required for this core
2064 +        * driver. */
2065 +       glamofb->base = ioremap(glamofb->reg->start, RESSIZE(glamofb->reg));
2066 +       if (!glamofb->base) {
2067 +               dev_err(&pdev->dev, "failed to ioremap() mmio memory\n");
2068 +               goto out_release_fb;
2069 +       }
2070 +       fbinfo->fix.smem_start = (unsigned long) glamofb->fb_res->start;
2071 +       fbinfo->fix.smem_len = mach_info->fb_mem_size;
2072 +
2073 +       fbinfo->screen_base = ioremap(glamofb->fb_res->start,
2074 +                                      RESSIZE(glamofb->fb_res));
2075 +       if (!fbinfo->screen_base) {
2076 +               dev_err(&pdev->dev, "failed to ioremap() vram memory\n");
2077 +               goto out_release_fb;
2078 +       }
2079 +
2080 +       platform_set_drvdata(pdev, fbinfo);
2081 +
2082 +       glamofb->mach_info = pdev->dev.platform_data;
2083 +
2084 +       fbinfo->fix.visual = FB_VISUAL_TRUECOLOR;
2085 +       fbinfo->fix.type = FB_TYPE_PACKED_PIXELS;
2086 +       fbinfo->fix.type_aux = 0;
2087 +       fbinfo->fix.xpanstep = 0;
2088 +       fbinfo->fix.ypanstep = 0;
2089 +       fbinfo->fix.ywrapstep = 0;
2090 +       fbinfo->fix.accel = FB_ACCEL_NONE; /* FIXME */
2091 +
2092 +       fbinfo->var.nonstd = 0;
2093 +       fbinfo->var.activate = FB_ACTIVATE_NOW;
2094 +       fbinfo->var.height = mach_info->height;
2095 +       fbinfo->var.width = mach_info->width;
2096 +       fbinfo->var.accel_flags = 0;
2097 +       fbinfo->var.vmode = FB_VMODE_NONINTERLACED;
2098 +
2099 +       fbinfo->fbops = &glamofb_ops;
2100 +       fbinfo->flags = FBINFO_FLAG_DEFAULT;
2101 +       fbinfo->pseudo_palette = &glamofb->pseudo_pal;
2102 +
2103 +       fbinfo->var.xres = mach_info->xres.defval;
2104 +       fbinfo->var.xres_virtual = mach_info->xres.defval;
2105 +       fbinfo->var.yres = mach_info->yres.defval;
2106 +       fbinfo->var.yres_virtual = mach_info->yres.defval;
2107 +       fbinfo->var.bits_per_pixel = mach_info->bpp.defval;
2108 +
2109 +       fbinfo->var.pixclock = mach_info->pixclock;
2110 +       fbinfo->var.left_margin = mach_info->left_margin;
2111 +       fbinfo->var.right_margin = mach_info->right_margin;
2112 +       fbinfo->var.upper_margin = mach_info->upper_margin;
2113 +       fbinfo->var.lower_margin = mach_info->lower_margin;
2114 +       fbinfo->var.hsync_len = mach_info->hsync_len;
2115 +       fbinfo->var.vsync_len = mach_info->vsync_len;
2116 +
2117 +       memset(fbinfo->screen_base, 0, fbinfo->fix.smem_len);
2118 +
2119 +       glamo_engine_enable(mach_info->glamo, GLAMO_ENGINE_LCD);
2120 +       glamo_engine_reset(mach_info->glamo, GLAMO_ENGINE_LCD);
2121 +       glamofb_init_regs(glamofb);
2122 +
2123 +       rc = register_framebuffer(fbinfo);
2124 +       if (rc < 0) {
2125 +               dev_err(&pdev->dev, "failed to register framebuffer\n");
2126 +               goto out_unmap_fb;
2127 +       }
2128 +
2129 +       if (mach_info->spi_info) {
2130 +               /* register the sibling spi device */
2131 +               mach_info->spi_info->glamofb_handle = glamofb;
2132 +               glamo_spi_dev.dev.parent = &pdev->dev;
2133 +               glamo_spi_dev.dev.platform_data = mach_info->spi_info;
2134 +               platform_device_register(&glamo_spi_dev);
2135 +       }
2136 +
2137 +       printk(KERN_INFO "fb%d: %s frame buffer device\n",
2138 +               fbinfo->node, fbinfo->fix.id);
2139 +
2140 +       return 0;
2141 +
2142 +out_unmap_fb:
2143 +       iounmap(fbinfo->screen_base);
2144 +       iounmap(glamofb->base);
2145 +out_release_fb:
2146 +       release_mem_region(glamofb->fb_res->start, RESSIZE(glamofb->fb_res));
2147 +out_release_reg:
2148 +       release_mem_region(glamofb->reg->start, RESSIZE(glamofb->reg));
2149 +out_free:
2150 +       framebuffer_release(fbinfo);
2151 +       return rc;
2152 +}
2153 +
2154 +static int glamofb_remove(struct platform_device *pdev)
2155 +{
2156 +       struct glamofb_handle *glamofb = platform_get_drvdata(pdev);
2157 +
2158 +       platform_set_drvdata(pdev, NULL);
2159 +       iounmap(glamofb->base);
2160 +       release_mem_region(glamofb->reg->start, RESSIZE(glamofb->reg));
2161 +       kfree(glamofb);
2162 +
2163 +       return 0;
2164 +}
2165 +
2166 +#ifdef CONFIG_PM
2167 +static int glamofb_suspend(struct platform_device *pdev, pm_message_t state)
2168 +{
2169 +       return 0;
2170 +}
2171 +
2172 +static int glamofb_resume(struct platform_device *pdev)
2173 +{
2174 +       return 0;
2175 +}
2176 +#else
2177 +#define glamofb_suspend NULL
2178 +#define glamofb_resume  NULL
2179 +#endif
2180 +
2181 +static struct platform_driver glamofb_driver = {
2182 +       .probe          = glamofb_probe,
2183 +       .remove         = glamofb_remove,
2184 +       .suspend        = glamofb_suspend,
2185 +       .resume         = glamofb_resume,
2186 +       .driver         = {
2187 +               .name   = "glamo-fb",
2188 +               .owner  = THIS_MODULE,
2189 +       },
2190 +};
2191 +
2192 +static int __devinit glamofb_init(void)
2193 +{
2194 +       return platform_driver_register(&glamofb_driver);
2195 +}
2196 +
2197 +static void __exit glamofb_cleanup(void)
2198 +{
2199 +       platform_driver_unregister(&glamofb_driver);
2200 +}
2201 +
2202 +module_init(glamofb_init);
2203 +module_exit(glamofb_cleanup);
2204 +
2205 +MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>");
2206 +MODULE_DESCRIPTION("Smedia Glamo 336x/337x framebuffer driver");
2207 +MODULE_LICENSE("GPL");
2208 diff --git a/drivers/mfd/glamo/glamo-gpio.c b/drivers/mfd/glamo/glamo-gpio.c
2209 new file mode 100644
2210 index 0000000..45d0bf9
2211 --- /dev/null
2212 +++ b/drivers/mfd/glamo/glamo-gpio.c
2213 @@ -0,0 +1,62 @@
2214 +
2215 +#include <linux/kernel.h>
2216 +#include <linux/module.h>
2217 +#include <linux/spinlock.h>
2218 +#include <linux/io.h>
2219 +
2220 +#include <linux/glamo-gpio.h>
2221 +
2222 +#include "glamo-core.h"
2223 +#include "glamo-regs.h"
2224 +
2225 +void glamo_gpio_setpin(struct glamo_core *glamo, unsigned int pin,
2226 +                      unsigned int value)
2227 +{
2228 +       unsigned int reg = REG_OF_GPIO(pin);
2229 +       u_int16_t tmp;
2230 +
2231 +       spin_lock(&glamo->lock);
2232 +       tmp = readw(glamo->base + reg);
2233 +       if (value)
2234 +               tmp |= OUTPUT_BIT(pin);
2235 +       else
2236 +               tmp &= ~OUTPUT_BIT(pin);
2237 +       writew(tmp, glamo->base + reg);
2238 +       spin_unlock(&glamo->lock);
2239 +}
2240 +EXPORT_SYMBOL(glamo_gpio_setpin);
2241 +
2242 +int glamo_gpio_getpin(struct glamo_core *glamo, unsigned int pin)
2243 +{
2244 +       return readw(REG_OF_GPIO(pin)) & INPUT_BIT(pin) ? 1 : 0;
2245 +}
2246 +EXPORT_SYMBOL(glamo_gpio_getpin);
2247 +
2248 +void glamo_gpio_cfgpin(struct glamo_core *glamo, unsigned int pinfunc)
2249 +{
2250 +       unsigned int reg = REG_OF_GPIO(pinfunc);
2251 +       u_int16_t tmp;
2252 +
2253 +       spin_lock(&glamo->lock);
2254 +       tmp = readw(glamo->base + reg);
2255 +
2256 +       if ((pinfunc & 0x00f0) == GLAMO_GPIO_F_FUNC) {
2257 +               /* pin is a function pin: clear gpio bit */
2258 +               tmp &= ~FUNC_BIT(pinfunc);
2259 +       } else {
2260 +               /* pin is gpio: set gpio bit */
2261 +               tmp |= FUNC_BIT(pinfunc);
2262 +
2263 +               if (pinfunc & GLAMO_GPIO_F_IN) {
2264 +                       /* gpio input: set bit to disable output mode */
2265 +                       tmp |= GPIO_OUT_BIT(pinfunc);
2266 +               } else if (pinfunc & GLAMO_GPIO_F_OUT) {
2267 +                       /* gpio output: clear bit to enable output mode */
2268 +                       tmp &= ~GPIO_OUT_BIT(pinfunc);
2269 +               }
2270 +       }
2271 +       writew(tmp, glamo->base + reg);
2272 +       spin_unlock(&glamo->lock);
2273 +}
2274 +EXPORT_SYMBOL(glamo_gpio_cfgpin);
2275 +
2276 diff --git a/drivers/mfd/glamo/glamo-lcm-spi.c b/drivers/mfd/glamo/glamo-lcm-spi.c
2277 new file mode 100644
2278 index 0000000..92cabe4
2279 --- /dev/null
2280 +++ b/drivers/mfd/glamo/glamo-lcm-spi.c
2281 @@ -0,0 +1,241 @@
2282 +/*
2283 + * Copyright (C) 2007 OpenMoko, Inc.
2284 + * Author: Harald Welte <laforge@openmoko.org>
2285 + *
2286 + * Smedia Glamo GPIO based SPI driver
2287 + *
2288 + * This program is free software; you can redistribute it and/or modify
2289 + * it under the terms of the GNU General Public License version 2 as
2290 + * published by the Free Software Foundation.
2291 + *
2292 + * This driver currently only implements a minimum subset of the hardware
2293 + * features, esp. those features that are required to drive the jbt6k74
2294 + * LCM controller asic in the TD028TTEC1 LCM.
2295 + *
2296 +*/
2297 +
2298 +#define DEBUG
2299 +
2300 +#include <linux/kernel.h>
2301 +#include <linux/init.h>
2302 +#include <linux/delay.h>
2303 +#include <linux/device.h>
2304 +#include <linux/spinlock.h>
2305 +#include <linux/workqueue.h>
2306 +#include <linux/platform_device.h>
2307 +
2308 +#include <linux/spi/spi.h>
2309 +#include <linux/spi/spi_bitbang.h>
2310 +#include <linux/spi/glamo.h>
2311 +
2312 +#include <linux/glamofb.h>
2313 +
2314 +#include <asm/hardware.h>
2315 +
2316 +#include "glamo-core.h"
2317 +#include "glamo-regs.h"
2318 +
2319 +struct glamo_spi {
2320 +       struct spi_bitbang      bitbang;
2321 +       struct spi_master       *master;
2322 +       struct glamo_spi_info   *info;
2323 +       struct device           *dev;
2324 +};
2325 +
2326 +static inline struct glamo_spi *to_gs(struct spi_device *spi)
2327 +{
2328 +       return spi->controller_data;
2329 +}
2330 +
2331 +static int glamo_spi_setupxfer(struct spi_device *spi, struct spi_transfer *t)
2332 +{
2333 +       struct glamo_spi *gs = to_gs(spi);
2334 +       unsigned int bpw;
2335 +
2336 +       bpw = t ? t->bits_per_word : spi->bits_per_word;
2337 +
2338 +       if (bpw != 9 && bpw != 8) {
2339 +               dev_err(&spi->dev, "invalid bits-per-word (%d)\n", bpw);
2340 +               return -EINVAL;
2341 +       }
2342 +
2343 +       return 0;
2344 +}
2345 +
2346 +static void glamo_spi_chipsel(struct spi_device *spi, int value)
2347 +{
2348 +#if 0
2349 +       struct glamo_spi *gs = to_gs(spi);
2350 +
2351 +       dev_dbg(&spi->dev, "chipsel %d: spi=%p, gs=%p, info=%p, handle=%p\n",
2352 +               value, spi, gs, gs->info, gs->info->glamofb_handle);
2353 +
2354 +       glamofb_cmd_mode(gs->info->glamofb_handle, value);
2355 +#endif
2356 +}
2357 +
2358 +static int glamo_spi_txrx(struct spi_device *spi, struct spi_transfer *t)
2359 +{
2360 +       struct glamo_spi *gs = to_gs(spi);
2361 +       const u_int16_t *ui16 = (const u_int16_t *) t->tx_buf;
2362 +       u_int16_t nine_bits;
2363 +       int i;
2364 +
2365 +       dev_dbg(&spi->dev, "txrx: tx %p, rx %p, bpw %d, len %d\n",
2366 +               t->tx_buf, t->rx_buf, t->bits_per_word, t->len);
2367 +
2368 +       if (spi->bits_per_word == 9)
2369 +               nine_bits = (1 << 9);
2370 +       else
2371 +               nine_bits = 0;
2372 +
2373 +       if (t->len > 3 * sizeof(u_int16_t)) {
2374 +               dev_err(&spi->dev, "this driver doesn't support "
2375 +                       "%u sized xfers\n", t->len);
2376 +               return -EINVAL;
2377 +       }
2378 +
2379 +       for (i = 0; i < t->len/sizeof(u_int16_t); i++) {
2380 +               /* actually transfer the data */
2381 +#if 1
2382 +               glamofb_cmd_write(gs->info->glamofb_handle,
2383 +                                 GLAMO_LCD_CMD_TYPE_SERIAL | nine_bits |
2384 +                                 (1 << 10) | (1 << 11) | (ui16[i] & 0x1ff));
2385 +#endif
2386 +               /* FIXME: fire ?!? */
2387 +               if (i == 0 && (ui16[i] & 0x1ff) == 0x29) {
2388 +                       dev_dbg(&spi->dev, "leaving command mode\n");
2389 +                       glamofb_cmd_mode(gs->info->glamofb_handle, 0);
2390 +               }
2391 +       }
2392 +
2393 +       return t->len;
2394 +}
2395 +
2396 +static int glamo_spi_setup(struct spi_device *spi)
2397 +{
2398 +       int ret;
2399 +
2400 +       if (!spi->bits_per_word)
2401 +               spi->bits_per_word = 9;
2402 +
2403 +       /* FIXME: hardware can do this */
2404 +       if (spi->mode & SPI_LSB_FIRST)
2405 +               return -EINVAL;
2406 +
2407 +       ret = glamo_spi_setupxfer(spi, NULL);
2408 +       if (ret < 0) {
2409 +               dev_err(&spi->dev, "setupxfer returned %d\n", ret);
2410 +               return ret;
2411 +       }
2412 +
2413 +       dev_dbg(&spi->dev, "%s: mode %d, %u bpw\n",
2414 +               __FUNCTION__, spi->mode, spi->bits_per_word);
2415 +
2416 +       return 0;
2417 +}
2418 +
2419 +static int glamo_spi_probe(struct platform_device *pdev)
2420 +{
2421 +       struct spi_master *master;
2422 +       struct glamo_spi *sp;
2423 +       int ret;
2424 +       int i;
2425 +
2426 +       master = spi_alloc_master(&pdev->dev, sizeof(struct glamo_spi));
2427 +       if (master == NULL) {
2428 +               dev_err(&pdev->dev, "failed to allocate spi master\n");
2429 +               ret = -ENOMEM;
2430 +               goto err;
2431 +       }
2432 +
2433 +       sp = spi_master_get_devdata(master);
2434 +       memset(sp, 0, sizeof(struct glamo_spi));
2435 +
2436 +       sp->master = spi_master_get(master);
2437 +       sp->info = pdev->dev.platform_data;
2438 +       if (!sp->info) {
2439 +               dev_err(&pdev->dev, "can't operate without platform data\n");
2440 +               ret = -EIO;
2441 +               goto err_no_pdev;
2442 +       }
2443 +       dev_dbg(&pdev->dev, "sp->info(pdata) = %p\n", sp->info);
2444 +
2445 +       sp->dev = &pdev->dev;
2446 +
2447 +       platform_set_drvdata(pdev, sp);
2448 +
2449 +       sp->bitbang.master = sp->master;
2450 +       sp->bitbang.setup_transfer = glamo_spi_setupxfer;
2451 +       sp->bitbang.chipselect = glamo_spi_chipsel;
2452 +       sp->bitbang.txrx_bufs = glamo_spi_txrx;
2453 +       sp->bitbang.master->setup = glamo_spi_setup;
2454 +
2455 +       ret = spi_bitbang_start(&sp->bitbang);
2456 +       if (ret)
2457 +               goto err_no_bitbang;
2458 +
2459 +       /* register the chips to go with the board */
2460 +
2461 +       glamofb_cmd_mode(sp->info->glamofb_handle, 1);
2462 +
2463 +       for (i = 0; i < sp->info->board_size; i++) {
2464 +               dev_info(&pdev->dev, "registering %p: %s\n",
2465 +                        &sp->info->board_info[i],
2466 +                        sp->info->board_info[i].modalias);
2467 +
2468 +               sp->info->board_info[i].controller_data = sp;
2469 +               spi_new_device(master, sp->info->board_info + i);
2470 +       }
2471 +
2472 +       return 0;
2473 +
2474 +err_no_bitbang:
2475 +       platform_set_drvdata(pdev, NULL);
2476 +err_no_pdev:
2477 +       spi_master_put(sp->bitbang.master);
2478 +err:
2479 +       return ret;
2480 +
2481 +}
2482 +
2483 +static int glamo_spi_remove(struct platform_device *pdev)
2484 +{
2485 +       struct glamo_spi *sp = platform_get_drvdata(pdev);
2486 +
2487 +       spi_bitbang_stop(&sp->bitbang);
2488 +       spi_master_put(sp->bitbang.master);
2489 +
2490 +       return 0;
2491 +}
2492 +
2493 +#define glamo_spi_suspend NULL
2494 +#define glamo_spi_resume NULL
2495 +
2496 +static struct platform_driver glamo_spi_drv = {
2497 +       .probe          = glamo_spi_probe,
2498 +       .remove         = glamo_spi_remove,
2499 +       .suspend        = glamo_spi_suspend,
2500 +       .resume         = glamo_spi_resume,
2501 +       .driver         = {
2502 +               .name   = "glamo-lcm-spi",
2503 +               .owner  = THIS_MODULE,
2504 +       },
2505 +};
2506 +
2507 +static int __init glamo_spi_init(void)
2508 +{
2509 +       return platform_driver_register(&glamo_spi_drv);
2510 +}
2511 +
2512 +static void __exit glamo_spi_exit(void)
2513 +{
2514 +       platform_driver_unregister(&glamo_spi_drv);
2515 +}
2516 +
2517 +module_init(glamo_spi_init);
2518 +module_exit(glamo_spi_exit);
2519 +
2520 +MODULE_DESCRIPTION("Smedia Glamo 336x/337x LCM serial command SPI Driver");
2521 +MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>")
2522 +MODULE_LICENSE("GPL");
2523 diff --git a/drivers/mfd/glamo/glamo-regs.h b/drivers/mfd/glamo/glamo-regs.h
2524 new file mode 100644
2525 index 0000000..151cd66
2526 --- /dev/null
2527 +++ b/drivers/mfd/glamo/glamo-regs.h
2528 @@ -0,0 +1,477 @@
2529 +#ifndef _GLAMO_REGS_H
2530 +#define _GLAMO_REGS_H
2531 +
2532 +/* Smedia Glamo 336x/337x driver
2533 + *
2534 + * (C) 2007 by OpenMoko, Inc.
2535 + * Author: Harald Welte <laforge@openmoko.org>
2536 + * All rights reserved.
2537 + *
2538 + * This program is free software; you can redistribute it and/or
2539 + * modify it under the terms of the GNU General Public License as
2540 + * published by the Free Software Foundation; either version 2 of
2541 + * the License, or (at your option) any later version.
2542 + *
2543 + * This program is distributed in the hope that it will be useful,
2544 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2545 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
2546 + * GNU General Public License for more details.
2547 + *
2548 + * You should have received a copy of the GNU General Public License
2549 + * along with this program; if not, write to the Free Software
2550 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
2551 + * MA 02111-1307 USA
2552 + */
2553 +
2554 +enum glamo_regster_offsets {
2555 +       GLAMO_REGOFS_GENERIC    = 0x0000,
2556 +       GLAMO_REGOFS_HOSTBUS    = 0x0200,
2557 +       GLAMO_REGOFS_MEMORY     = 0x0300,
2558 +       GLAMO_REGOFS_VIDCAP     = 0x0400,
2559 +       GLAMO_REGOFS_ISP        = 0x0500,
2560 +       GLAMO_REGOFS_JPEG       = 0x0800,
2561 +       GLAMO_REGOFS_MPEG       = 0x0c00,
2562 +       GLAMO_REGOFS_LCD        = 0x1100,
2563 +       GLAMO_REGOFS_MMC        = 0x1400,
2564 +       GLAMO_REGOFS_MPROC0     = 0x1500,
2565 +       GLAMO_REGOFS_MPROC1     = 0x1580,
2566 +       GLAMO_REGOFS_CMDQUEUE   = 0x1600,
2567 +       GLAMO_REGOFS_RISC       = 0x1680,
2568 +       GLAMO_REGOFS_2D         = 0x1700,
2569 +       GLAMO_REGOFS_3D         = 0x1b00,
2570 +       GLAMO_REGOFS_END        = 0x2400,
2571 +};
2572 +
2573 +
2574 +enum glamo_register_generic {
2575 +       GLAMO_REG_GCONF1        = 0x0000,
2576 +       GLAMO_REG_GCONF2        = 0x0002,
2577 +#define        GLAMO_REG_DEVICE_ID     GLAMO_REG_GCONF2
2578 +       GLAMO_REG_GCONF3        = 0x0004,
2579 +#define        GLAMO_REG_REVISION_ID   GLAMO_REG_GCONF3
2580 +       GLAMO_REG_IRQ_GEN1      = 0x0006,
2581 +#define GLAMO_REG_IRQ_ENABLE   GLAMO_REG_IRQ_GEN1
2582 +       GLAMO_REG_IRQ_GEN2      = 0x0008,
2583 +#define GLAMO_REG_IRQ_SET      GLAMO_REG_IRQ_GEN2
2584 +       GLAMO_REG_IRQ_GEN3      = 0x000a,
2585 +#define GLAMO_REG_IRQ_CLEAR    GLAMO_REG_IRQ_GEN3
2586 +       GLAMO_REG_IRQ_GEN4      = 0x000c,
2587 +#define GLAMO_REG_IRQ_STATUS   GLAMO_REG_IRQ_GEN4
2588 +       GLAMO_REG_CLOCK_HOST    = 0x0010,
2589 +       GLAMO_REG_CLOCK_MEMORY  = 0x0012,
2590 +       GLAMO_REG_CLOCK_LCD     = 0x0014,
2591 +       GLAMO_REG_CLOCK_MMC     = 0x0016,
2592 +       GLAMO_REG_CLOCK_ISP     = 0x0018,
2593 +       GLAMO_REG_CLOCK_JPEG    = 0x001a,
2594 +       GLAMO_REG_CLOCK_3D      = 0x001c,
2595 +       GLAMO_REG_CLOCK_2D      = 0x001e,
2596 +       GLAMO_REG_CLOCK_RISC1   = 0x0020,       /* 3365 only? */
2597 +       GLAMO_REG_CLOCK_RISC2   = 0x0022,       /* 3365 only? */
2598 +       GLAMO_REG_CLOCK_MPEG    = 0x0024,
2599 +       GLAMO_REG_CLOCK_MPROC   = 0x0026,
2600 +
2601 +       GLAMO_REG_CLOCK_GEN5_1  = 0x0030,
2602 +       GLAMO_REG_CLOCK_GEN5_2  = 0x0032,
2603 +       GLAMO_REG_CLOCK_GEN6    = 0x0034,
2604 +       GLAMO_REG_CLOCK_GEN7    = 0x0036,
2605 +       GLAMO_REG_CLOCK_GEN8    = 0x0038,
2606 +       GLAMO_REG_CLOCK_GEN9    = 0x003a,
2607 +       GLAMO_REG_CLOCK_GEN10   = 0x003c,
2608 +       GLAMO_REG_CLOCK_GEN11   = 0x003e,
2609 +       GLAMO_REG_PLL_GEN1      = 0x0040,
2610 +       GLAMO_REG_PLL_GEN2      = 0x0042,
2611 +       GLAMO_REG_PLL_GEN3      = 0x0044,
2612 +       GLAMO_REG_PLL_GEN4      = 0x0046,
2613 +       GLAMO_REG_PLL_GEN5      = 0x0048,
2614 +       GLAMO_REG_GPIO_GEN1     = 0x0050,
2615 +       GLAMO_REG_GPIO_GEN2     = 0x0052,
2616 +       GLAMO_REG_GPIO_GEN3     = 0x0054,
2617 +       GLAMO_REG_GPIO_GEN4     = 0x0056,
2618 +       GLAMO_REG_GPIO_GEN5     = 0x0058,
2619 +       GLAMO_REG_GPIO_GEN6     = 0x005a,
2620 +       GLAMO_REG_GPIO_GEN7     = 0x005c,
2621 +       GLAMO_REG_GPIO_GEN8     = 0x005e,
2622 +       GLAMO_REG_GPIO_GEN9     = 0x0060,
2623 +       GLAMO_REG_GPIO_GEN10    = 0x0062,
2624 +       GLAMO_REG_DFT_GEN1      = 0x0070,
2625 +       GLAMO_REG_DFT_GEN2      = 0x0072,
2626 +       GLAMO_REG_DFT_GEN3      = 0x0074,
2627 +       GLAMO_REG_DFT_GEN4      = 0x0076,
2628 +
2629 +       GLAMO_REG_DFT_GEN5      = 0x01e0,
2630 +       GLAMO_REG_DFT_GEN6      = 0x01f0,
2631 +};
2632 +
2633 +#define GLAMO_REG_HOSTBUS(x)   (GLAMO_REGOFS_HOSTBUS-2+(x*2))
2634 +
2635 +#define REG_MEM(x)             (GLAMO_REGOFS_MEMORY+(x))
2636 +#define GLAMO_REG_MEM_TIMING(x)        (GLAMO_REG_MEM_TIMING1-2+(x*2))
2637 +
2638 +enum glamo_register_mem {
2639 +       GLAMO_REG_MEM_TYPE      = REG_MEM(0x00),
2640 +       GLAMO_REG_MEM_GEN       = REG_MEM(0x02),
2641 +       GLAMO_REG_MEM_TIMING1   = REG_MEM(0x04),
2642 +       GLAMO_REG_MEM_TIMING2   = REG_MEM(0x06),
2643 +       GLAMO_REG_MEM_TIMING3   = REG_MEM(0x08),
2644 +       GLAMO_REG_MEM_TIMING4   = REG_MEM(0x0a),
2645 +       GLAMO_REG_MEM_TIMING5   = REG_MEM(0x0c),
2646 +       GLAMO_REG_MEM_TIMING6   = REG_MEM(0x0e),
2647 +       GLAMO_REG_MEM_TIMING7   = REG_MEM(0x10),
2648 +       GLAMO_REG_MEM_TIMING8   = REG_MEM(0x12),
2649 +       GLAMO_REG_MEM_TIMING9   = REG_MEM(0x14),
2650 +       GLAMO_REG_MEM_TIMING10  = REG_MEM(0x16),
2651 +       GLAMO_REG_MEM_TIMING11  = REG_MEM(0x18),
2652 +       GLAMO_REG_MEM_POWER1    = REG_MEM(0x1a),
2653 +       GLAMO_REG_MEM_POWER2    = REG_MEM(0x1c),
2654 +       GLAMO_REG_MEM_LCD_BUF1  = REG_MEM(0x1e),
2655 +       GLAMO_REG_MEM_LCD_BUF2  = REG_MEM(0x20),
2656 +       GLAMO_REG_MEM_LCD_BUF3  = REG_MEM(0x22),
2657 +       GLAMO_REG_MEM_LCD_BUF4  = REG_MEM(0x24),
2658 +       GLAMO_REG_MEM_BIST1     = REG_MEM(0x26),
2659 +       GLAMO_REG_MEM_BIST2     = REG_MEM(0x28),
2660 +       GLAMO_REG_MEM_BIST3     = REG_MEM(0x2a),
2661 +       GLAMO_REG_MEM_BIST4     = REG_MEM(0x2c),
2662 +       GLAMO_REG_MEM_BIST5     = REG_MEM(0x2e),
2663 +       GLAMO_REG_MEM_MAH1      = REG_MEM(0x30),
2664 +       GLAMO_REG_MEM_MAH2      = REG_MEM(0x32),
2665 +       GLAMO_REG_MEM_DRAM1     = REG_MEM(0x34),
2666 +       GLAMO_REG_MEM_DRAM2     = REG_MEM(0x36),
2667 +       GLAMO_REG_MEM_CRC       = REG_MEM(0x38),
2668 +};
2669 +
2670 +#define GLAMO_MEM_TYPE_MASK    0x03
2671 +
2672 +enum glamo_reg_mem_dram1 {
2673 +       GLAMO_MEM_DRAM1_EN_SDRAM_CLK    = (1 << 11),
2674 +       GLAMO_MEM_DRAM1_SELF_REFRESH    = (1 << 12),
2675 +};
2676 +
2677 +enum glamo_reg_mem_dram2 {
2678 +       GLAMO_MEM_DRAM2_DEEP_PWRDOWN    = (1 << 12),
2679 +};
2680 +
2681 +enum glamo_irq {
2682 +       GLAMO_IRQ_HOSTBUS       = 0x0001,
2683 +       GLAMO_IRQ_JPEG          = 0x0002,
2684 +       GLAMO_IRQ_MPEG          = 0x0004,
2685 +       GLAMO_IRQ_MPROC1        = 0x0008,
2686 +       GLAMO_IRQ_MPROC0        = 0x0010,
2687 +       GLAMO_IRQ_CMDQUEUE      = 0x0020,
2688 +       GLAMO_IRQ_2D            = 0x0040,
2689 +       GLAMO_IRQ_MMC           = 0x0080,
2690 +       GLAMO_IRQ_RISC          = 0x0100,
2691 +};
2692 +
2693 +enum glamo_reg_clock_host {
2694 +       GLAMO_CLOCK_HOST_DG_BCLK        = 0x0001,
2695 +       GLAMO_CLOCK_HOST_DG_M0CLK       = 0x0004,
2696 +       GLAMO_CLOCK_HOST_RESET          = 0x1000,
2697 +};
2698 +
2699 +enum glamo_reg_clock_mem {
2700 +       GLAMO_CLOCK_MEM_DG_M1CLK        = 0x0001,
2701 +       GLAMO_CLOCK_MEM_EN_M1CLK        = 0x0002,
2702 +       GLAMO_CLOCK_MEM_DG_MOCACLK      = 0x0004,
2703 +       GLAMO_CLOCK_MEM_EN_MOCACLK      = 0x0008,
2704 +       GLAMO_CLOCK_MEM_RESET           = 0x1000,
2705 +       GLAMO_CLOCK_MOCA_RESET          = 0x2000,
2706 +};
2707 +
2708 +enum glamo_reg_clock_lcd {
2709 +       GLAMO_CLOCK_LCD_DG_DCLK         = 0x0001,
2710 +       GLAMO_CLOCK_LCD_EN_DCLK         = 0x0002,
2711 +       GLAMO_CLOCK_LCD_DG_DMCLK        = 0x0004,
2712 +       GLAMO_CLOCK_LCD_EN_DMCLK        = 0x0008,
2713 +       //
2714 +       GLAMO_CLOCK_LCD_EN_DHCLK        = 0x0020,
2715 +       GLAMO_CLOCK_LCD_DG_M5CLK        = 0x0040,
2716 +       GLAMO_CLOCK_LCD_EN_M5CLK        = 0x0080,
2717 +       GLAMO_CLOCK_LCD_RESET           = 0x1000,
2718 +};
2719 +
2720 +enum glamo_reg_clock_mmc {
2721 +       GLAMO_CLOCK_MMC_DG_TCLK         = 0x0001,
2722 +       GLAMO_CLOCK_MMC_EN_TCLK         = 0x0002,
2723 +       GLAMO_CLOCK_MMC_DG_M9CLK        = 0x0004,
2724 +       GLAMO_CLOCK_MMC_EN_M9CLK        = 0x0008,
2725 +       GLAMO_CLOCK_MMC_RESET           = 0x1000,
2726 +};
2727 +
2728 +enum glamo_reg_clock_isp {
2729 +       GLAMO_CLOCK_ISP_DG_I1CLK        = 0x0001,
2730 +       GLAMO_CLOCK_ISP_EN_I1CLK        = 0x0002,
2731 +       GLAMO_CLOCK_ISP_DG_CCLK         = 0x0004,
2732 +       GLAMO_CLOCK_ISP_EN_CCLK         = 0x0008,
2733 +       //
2734 +       GLAMO_CLOCK_ISP_EN_SCLK         = 0x0020,
2735 +       GLAMO_CLOCK_ISP_DG_M2CLK        = 0x0040,
2736 +       GLAMO_CLOCK_ISP_EN_M2CLK        = 0x0080,
2737 +       GLAMO_CLOCK_ISP_DG_M15CLK       = 0x0100,
2738 +       GLAMO_CLOCK_ISP_EN_M15CLK       = 0x0200,
2739 +       GLAMO_CLOCK_ISP1_RESET          = 0x1000,
2740 +       GLAMO_CLOCK_ISP2_RESET          = 0x2000,
2741 +};
2742 +
2743 +enum glamo_reg_clock_jpeg {
2744 +       GLAMO_CLOCK_JPEG_DG_JCLK        = 0x0001,
2745 +       GLAMO_CLOCK_JPEG_EN_JCLK        = 0x0002,
2746 +       GLAMO_CLOCK_JPEG_DG_M3CLK       = 0x0004,
2747 +       GLAMO_CLOCK_JPEG_EN_M3CLK       = 0x0008,
2748 +       GLAMO_CLOCK_JPEG_RESET          = 0x1000,
2749 +};
2750 +
2751 +enum glamo_reg_clock_2d {
2752 +       GLAMO_CLOCK_2D_DG_GCLK          = 0x0001,
2753 +       GLAMO_CLOCK_2D_EN_GCLK          = 0x0002,
2754 +       GLAMO_CLOCK_2D_DG_M7CLK         = 0x0004,
2755 +       GLAMO_CLOCK_2D_EN_M7CLK         = 0x0008,
2756 +       GLAMO_CLOCK_2D_DG_M6CLK         = 0x0010,
2757 +       GLAMO_CLOCK_2D_EN_M6CLK         = 0x0020,
2758 +       GLAMO_CLOCK_2D_RESET            = 0x1000,
2759 +       GLAMO_CLOCK_2D_CQ_RESET         = 0x2000,
2760 +};
2761 +
2762 +enum glamo_reg_clock_3d {
2763 +       GLAMO_CLOCK_3D_DG_ECLK          = 0x0001,
2764 +       GLAMO_CLOCK_3D_EN_ECLK          = 0x0002,
2765 +       GLAMO_CLOCK_3D_DG_RCLK          = 0x0004,
2766 +       GLAMO_CLOCK_3D_EN_RCLK          = 0x0008,
2767 +       GLAMO_CLOCK_3D_DG_M8CLK         = 0x0010,
2768 +       GLAMO_CLOCK_3D_EN_M8CLK         = 0x0020,
2769 +       GLAMO_CLOCK_3D_BACK_RESET       = 0x1000,
2770 +       GLAMO_CLOCK_3D_FRONT_RESET      = 0x2000,
2771 +};
2772 +
2773 +enum glamo_reg_clock_mpeg {
2774 +       GLAMO_CLOCK_MPEG_DG_X0CLK       = 0x0001,
2775 +       GLAMO_CLOCK_MPEG_EN_X0CLK       = 0x0002,
2776 +       GLAMO_CLOCK_MPEG_DG_X1CLK       = 0x0004,
2777 +       GLAMO_CLOCK_MPEG_EN_X1CLK       = 0x0008,
2778 +       GLAMO_CLOCK_MPEG_DG_X2CLK       = 0x0010,
2779 +       GLAMO_CLOCK_MPEG_EN_X2CLK       = 0x0020,
2780 +       GLAMO_CLOCK_MPEG_DG_X3CLK       = 0x0040,
2781 +       GLAMO_CLOCK_MPEG_EN_X3CLK       = 0x0080,
2782 +       GLAMO_CLOCK_MPEG_DG_X4CLK       = 0x0100,
2783 +       GLAMO_CLOCK_MPEG_EN_X4CLK       = 0x0200,
2784 +       GLAMO_CLOCK_MPEG_DG_X6CLK       = 0x0400,
2785 +       GLAMO_CLOCK_MPEG_EN_X6CLK       = 0x0800,
2786 +       GLAMO_CLOCK_MPEG_ENC_RESET      = 0x1000,
2787 +       GLAMO_CLOCK_MPEG_DEC_RESET      = 0x2000,
2788 +};
2789 +
2790 +enum glamo_reg_clock51 {
2791 +       GLAMO_CLOCK_GEN51_EN_DIV_MCLK   = 0x0001,
2792 +       GLAMO_CLOCK_GEN51_EN_DIV_SCLK   = 0x0002,
2793 +       GLAMO_CLOCK_GEN51_EN_DIV_JCLK   = 0x0004,
2794 +       GLAMO_CLOCK_GEN51_EN_DIV_DCLK   = 0x0008,
2795 +       GLAMO_CLOCK_GEN51_EN_DIV_DMCLK  = 0x0010,
2796 +       GLAMO_CLOCK_GEN51_EN_DIV_DHCLK  = 0x0020,
2797 +       GLAMO_CLOCK_GEN51_EN_DIV_GCLK   = 0x0040,
2798 +       GLAMO_CLOCK_GEN51_EN_DIV_TCLK   = 0x0080,
2799 +       /* FIXME: higher bits */
2800 +};
2801 +
2802 +enum glamo_reg_hostbus2 {
2803 +       GLAMO_HOSTBUS2_MMIO_EN_ISP      = 0x0001,
2804 +       GLAMO_HOSTBUS2_MMIO_EN_JPEG     = 0x0002,
2805 +       GLAMO_HOSTBUS2_MMIO_EN_MPEG     = 0x0004,
2806 +       GLAMO_HOSTBUS2_MMIO_EN_LCD      = 0x0008,
2807 +       GLAMO_HOSTBUS2_MMIO_EN_MMC      = 0x0010,
2808 +       GLAMO_HOSTBUS2_MMIO_EN_MICROP0  = 0x0020,
2809 +       GLAMO_HOSTBUS2_MMIO_EN_MICROP1  = 0x0040,
2810 +       GLAMO_HOSTBUS2_MMIO_EN_CQ       = 0x0080,
2811 +       GLAMO_HOSTBUS2_MMIO_EN_RISC     = 0x0100,
2812 +       GLAMO_HOSTBUS2_MMIO_EN_2D       = 0x0200,
2813 +       GLAMO_HOSTBUS2_MMIO_EN_3D       = 0x0400,
2814 +};
2815 +
2816 +/* LCD Controller */
2817 +
2818 +#define REG_LCD(x)     (x)
2819 +enum glamo_reg_lcd {
2820 +       GLAMO_REG_LCD_MODE1             = REG_LCD(0x00),
2821 +       GLAMO_REG_LCD_MODE2             = REG_LCD(0x02),
2822 +       GLAMO_REG_LCD_MODE3             = REG_LCD(0x04),
2823 +       GLAMO_REG_LCD_WIDTH             = REG_LCD(0x06),
2824 +       GLAMO_REG_LCD_HEIGHT            = REG_LCD(0x08),
2825 +       GLAMO_REG_LCD_POLARITY          = REG_LCD(0x0a),
2826 +       GLAMO_REG_LCD_A_BASE1           = REG_LCD(0x0c),
2827 +       GLAMO_REG_LCD_A_BASE2           = REG_LCD(0x0e),
2828 +       GLAMO_REG_LCD_B_BASE1           = REG_LCD(0x10),
2829 +       GLAMO_REG_LCD_B_BASE2           = REG_LCD(0x12),
2830 +       GLAMO_REG_LCD_C_BASE1           = REG_LCD(0x14),
2831 +       GLAMO_REG_LCD_C_BASE2           = REG_LCD(0x16),
2832 +       GLAMO_REG_LCD_PITCH             = REG_LCD(0x18),
2833 +       /* RES */
2834 +       GLAMO_REG_LCD_HORIZ_TOTAL       = REG_LCD(0x1c),
2835 +       /* RES */
2836 +       GLAMO_REG_LCD_HORIZ_RETR_START  = REG_LCD(0x20),
2837 +       /* RES */
2838 +       GLAMO_REG_LCD_HORIZ_RETR_END    = REG_LCD(0x24),
2839 +       /* RES */
2840 +       GLAMO_REG_LCD_HORIZ_DISP_START  = REG_LCD(0x28),
2841 +       /* RES */
2842 +       GLAMO_REG_LCD_HORIZ_DISP_END    = REG_LCD(0x2c),
2843 +       /* RES */
2844 +       GLAMO_REG_LCD_VERT_TOTAL        = REG_LCD(0x30),
2845 +       /* RES */
2846 +       GLAMO_REG_LCD_VERT_RETR_START   = REG_LCD(0x34),
2847 +       /* RES */
2848 +       GLAMO_REG_LCD_VERT_RETR_END     = REG_LCD(0x38),
2849 +       /* RES */
2850 +       GLAMO_REG_LCD_VERT_DISP_START   = REG_LCD(0x3c),
2851 +       /* RES */
2852 +       GLAMO_REG_LCD_VERT_DISP_END     = REG_LCD(0x40),
2853 +       /* RES */
2854 +       GLAMO_REG_LCD_POL               = REG_LCD(0x44),
2855 +       GLAMO_REG_LCD_DATA_START        = REG_LCD(0x46),
2856 +       GLAMO_REG_LCD_FRATE_CONTRO      = REG_LCD(0x48),
2857 +       GLAMO_REG_LCD_DATA_CMD_HDR      = REG_LCD(0x4a),
2858 +       GLAMO_REG_LCD_SP_START          = REG_LCD(0x4c),
2859 +       GLAMO_REG_LCD_SP_END            = REG_LCD(0x4e),
2860 +       GLAMO_REG_LCD_CURSOR_BASE1      = REG_LCD(0x50),
2861 +       GLAMO_REG_LCD_CURSOR_BASE2      = REG_LCD(0x52),
2862 +       GLAMO_REG_LCD_CURSOR_PITCH      = REG_LCD(0x54),
2863 +       GLAMO_REG_LCD_CURSOR_X_SIZE     = REG_LCD(0x56),
2864 +       GLAMO_REG_LCD_CURSOR_Y_SIZE     = REG_LCD(0x58),
2865 +       GLAMO_REG_LCD_CURSOR_X_POS      = REG_LCD(0x5a),
2866 +       GLAMO_REG_LCD_CURSOR_Y_POS      = REG_LCD(0x5c),
2867 +       GLAMO_REG_LCD_CURSOR_PRESET     = REG_LCD(0x5e),
2868 +       GLAMO_REG_LCD_CURSOR_FG_COLOR   = REG_LCD(0x60),
2869 +       /* RES */
2870 +       GLAMO_REG_LCD_CURSOR_BG_COLOR   = REG_LCD(0x64),
2871 +       /* RES */
2872 +       GLAMO_REG_LCD_CURSOR_DST_COLOR  = REG_LCD(0x68),
2873 +       /* RES */
2874 +       GLAMO_REG_LCD_STATUS1           = REG_LCD(0x80),
2875 +       GLAMO_REG_LCD_STATUS2           = REG_LCD(0x82),
2876 +       GLAMO_REG_LCD_STATUS3           = REG_LCD(0x84),
2877 +       GLAMO_REG_LCD_STATUS4           = REG_LCD(0x86),
2878 +       /* RES */
2879 +       GLAMO_REG_LCD_COMMAND1          = REG_LCD(0xa0),
2880 +       GLAMO_REG_LCD_COMMAND2          = REG_LCD(0xa2),
2881 +       /* RES */
2882 +       GLAMO_REG_LCD_WFORM_DELAY1      = REG_LCD(0xb0),
2883 +       GLAMO_REG_LCD_WFORM_DELAY2      = REG_LCD(0xb2),
2884 +       /* RES */
2885 +       GLAMO_REG_LCD_GAMMA_CORR        = REG_LCD(0x100),
2886 +       /* RES */
2887 +       GLAMO_REG_LCD_GAMMA_R_ENTRY01   = REG_LCD(0x110),
2888 +       GLAMO_REG_LCD_GAMMA_R_ENTRY23   = REG_LCD(0x112),
2889 +       GLAMO_REG_LCD_GAMMA_R_ENTRY45   = REG_LCD(0x114),
2890 +       GLAMO_REG_LCD_GAMMA_R_ENTRY67   = REG_LCD(0x116),
2891 +       GLAMO_REG_LCD_GAMMA_R_ENTRY8    = REG_LCD(0x118),
2892 +       /* RES */
2893 +       GLAMO_REG_LCD_GAMMA_G_ENTRY01   = REG_LCD(0x130),
2894 +       GLAMO_REG_LCD_GAMMA_G_ENTRY23   = REG_LCD(0x132),
2895 +       GLAMO_REG_LCD_GAMMA_G_ENTRY45   = REG_LCD(0x134),
2896 +       GLAMO_REG_LCD_GAMMA_G_ENTRY67   = REG_LCD(0x136),
2897 +       GLAMO_REG_LCD_GAMMA_G_ENTRY8    = REG_LCD(0x138),
2898 +       /* RES */
2899 +       GLAMO_REG_LCD_GAMMA_B_ENTRY01   = REG_LCD(0x150),
2900 +       GLAMO_REG_LCD_GAMMA_B_ENTRY23   = REG_LCD(0x152),
2901 +       GLAMO_REG_LCD_GAMMA_B_ENTRY45   = REG_LCD(0x154),
2902 +       GLAMO_REG_LCD_GAMMA_B_ENTRY67   = REG_LCD(0x156),
2903 +       GLAMO_REG_LCD_GAMMA_B_ENTRY8    = REG_LCD(0x158),
2904 +       /* RES */
2905 +       GLAMO_REG_LCD_SRAM_DRIVING1     = REG_LCD(0x160),
2906 +       GLAMO_REG_LCD_SRAM_DRIVING2     = REG_LCD(0x162),
2907 +       GLAMO_REG_LCD_SRAM_DRIVING3     = REG_LCD(0x164),
2908 +};
2909 +
2910 +enum glamo_reg_lcd_mode1 {
2911 +       GLAMO_LCD_MODE1_PWRSAVE         = 0x0001,
2912 +       GLAMO_LCD_MODE1_PARTIAL_PRT     = 0x0002,
2913 +       GLAMO_LCD_MODE1_HWFLIP          = 0x0004,
2914 +       GLAMO_LCD_MODE1_LCD2            = 0x0008,
2915 +       /* RES */
2916 +       GLAMO_LCD_MODE1_PARTIAL_MODE    = 0x0020,
2917 +       GLAMO_LCD_MODE1_CURSOR_DSTCOLOR = 0x0040,
2918 +       GLAMO_LCD_MODE1_PARTIAL_ENABLE  = 0x0080,
2919 +       GLAMO_LCD_MODE1_TVCLK_IN_ENABLE = 0x0100,
2920 +       GLAMO_LCD_MODE1_HSYNC_HIGH_ACT  = 0x0200,
2921 +       GLAMO_LCD_MODE1_VSYNC_HIGH_ACT  = 0x0400,
2922 +       GLAMO_LCD_MODE1_HSYNC_FLIP      = 0x0800,
2923 +       GLAMO_LCD_MODE1_GAMMA_COR_EN    = 0x1000,
2924 +       GLAMO_LCD_MODE1_DITHER_EN       = 0x2000,
2925 +       GLAMO_LCD_MODE1_CURSOR_EN       = 0x4000,
2926 +       GLAMO_LCD_MODE1_ROTATE_EN       = 0x8000,
2927 +};
2928 +
2929 +enum glamo_reg_lcd_mode2 {
2930 +       GLAMO_LCD_MODE2_CRC_CHECK_EN    = 0x0001,
2931 +       GLAMO_LCD_MODE2_DCMD_PER_LINE   = 0x0002,
2932 +       GLAMO_LCD_MODE2_NOUSE_BDEF      = 0x0004,
2933 +       GLAMO_LCD_MODE2_OUT_POS_MODE    = 0x0008,
2934 +       GLAMO_LCD_MODE2_FRATE_CTRL_EN   = 0x0010,
2935 +       GLAMO_LCD_MODE2_SINGLE_BUFFER   = 0x0020,
2936 +       GLAMO_LCD_MODE2_SER_LSB_TO_MSB  = 0x0040,
2937 +       /* FIXME */
2938 +};
2939 +
2940 +enum glamo_reg_lcd_mode3 {
2941 +       /* LCD color source data format */
2942 +       GLAMO_LCD_SRC_RGB565            = 0x0000,
2943 +       GLAMO_LCD_SRC_ARGB1555          = 0x4000,
2944 +       GLAMO_LCD_SRC_ARGB4444          = 0x8000,
2945 +       /* interface type */
2946 +       GLAMO_LCD_MODE3_LCD             = 0x1000,
2947 +       GLAMO_LCD_MODE3_RGB             = 0x0800,
2948 +       GLAMO_LCD_MODE3_CPU             = 0x0000,
2949 +       /* mode */
2950 +       GLAMO_LCD_MODE3_RGB332          = 0x0000,
2951 +       GLAMO_LCD_MODE3_RGB444          = 0x0100,
2952 +       GLAMO_LCD_MODE3_RGB565          = 0x0200,
2953 +       GLAMO_LCD_MODE3_RGB666          = 0x0300,
2954 +       /* depth */
2955 +       GLAMO_LCD_MODE3_6BITS           = 0x0000,
2956 +       GLAMO_LCD_MODE3_8BITS           = 0x0010,
2957 +       GLAMO_LCD_MODE3_9BITS           = 0x0020,
2958 +       GLAMO_LCD_MODE3_16BITS          = 0x0030,
2959 +       GLAMO_LCD_MODE3_18BITS          = 0x0040,
2960 +};
2961 +
2962 +enum glamo_lcd_rot_mode {
2963 +        GLAMO_LCD_ROT_MODE_0            = 0x0000,
2964 +        GLAMO_LCD_ROT_MODE_180          = 0x2000,
2965 +        GLAMO_LCD_ROT_MODE_MIRROR       = 0x4000,
2966 +        GLAMO_LCD_ROT_MODE_FLIP         = 0x6000,
2967 +        GLAMO_LCD_ROT_MODE_90           = 0x8000,
2968 +        GLAMO_LCD_ROT_MODE_270          = 0xa000,
2969 +};
2970 +#define GLAMO_LCD_ROT_MODE_MASK         0xe000
2971 +
2972 +enum glamo_lcd_cmd_type {
2973 +       GLAMO_LCD_CMD_TYPE_DISP         = 0x0000,
2974 +       GLAMO_LCD_CMD_TYPE_PARALLEL     = 0x4000,
2975 +       GLAMO_LCD_CMD_TYPE_SERIAL       = 0x8000,
2976 +       GLAMO_LCD_CMD_TYPE_SERIAL_DIRECT= 0xc000,
2977 +};
2978 +#define GLAMO_LCD_CMD_TYPE_MASK                0xc000
2979 +
2980 +enum glamo_lcd_cmds {
2981 +       GLAMO_LCD_CMD_DATA_DISP_FIRE    = 0x00,
2982 +       GLAMO_LCD_CMD_DATA_DISP_SYNC    = 0x01,         /* RGB only */
2983 +       /* switch to command mode, no display */
2984 +       GLAMO_LCD_CMD_DATA_FIRE_NO_DISP = 0x02,
2985 +       /* display until VSYNC, switch to command */
2986 +       GLAMO_LCD_CMD_DATA_FIRE_VSYNC   = 0x11,
2987 +       /* display until HSYNC, switch to command */
2988 +       GLAMO_LCD_CMD_DATA_FIRE_HSYNC   = 0x12,
2989 +       /* display until VSYNC, 1 black frame, VSYNC, switch to command */
2990 +       GLAMO_LCD_CMD_DATA_FIRE_VSYNC_B = 0x13,
2991 +       /* don't care about display and switch to command */
2992 +       GLAMO_LCD_CMD_DATA_FIRE_FREE    = 0x14,         /* RGB only */
2993 +       /* don't care about display, keep data display but disable data,
2994 +        * and switch to command */
2995 +       GLAMO_LCD_CMD_DATA_FIRE_FREE_D  = 0x15,         /* RGB only */
2996 +};
2997 +
2998 +enum glamo_core_revisions {
2999 +       GLAMO_CORE_REV_A0               = 0x0000,
3000 +       GLAMO_CORE_REV_A1               = 0x0001,
3001 +       GLAMO_CORE_REV_A2               = 0x0002,
3002 +       GLAMO_CORE_REV_A3               = 0x0003,
3003 +};
3004 +
3005 +#endif /* _GLAMO_REGS_H */
3006 diff --git a/drivers/mfd/glamo/glamo-spi-gpio.c b/drivers/mfd/glamo/glamo-spi-gpio.c
3007 new file mode 100644
3008 index 0000000..73926bd
3009 --- /dev/null
3010 +++ b/drivers/mfd/glamo/glamo-spi-gpio.c
3011 @@ -0,0 +1,256 @@
3012 +/*
3013 + * Copyright (C) 2007 OpenMoko, Inc.
3014 + * Author: Harald Welte <laforge@openmoko.org>
3015 + *
3016 + * Smedia Glamo GPIO based SPI driver
3017 + *
3018 + * This program is free software; you can redistribute it and/or modify
3019 + * it under the terms of the GNU General Public License version 2 as
3020 + * published by the Free Software Foundation.
3021 + *
3022 + * This driver currently only implements a minimum subset of the hardware
3023 + * features, esp. those features that are required to drive the jbt6k74
3024 + * LCM controller asic in the TD028TTEC1 LCM.
3025 + *
3026 +*/
3027 +
3028 +#define DEBUG
3029 +
3030 +#include <linux/kernel.h>
3031 +#include <linux/init.h>
3032 +#include <linux/delay.h>
3033 +#include <linux/device.h>
3034 +#include <linux/spinlock.h>
3035 +#include <linux/workqueue.h>
3036 +#include <linux/platform_device.h>
3037 +
3038 +#include <linux/spi/spi.h>
3039 +#include <linux/spi/spi_bitbang.h>
3040 +#include <linux/spi/glamo.h>
3041 +
3042 +#include <linux/glamofb.h>
3043 +
3044 +#include <asm/hardware.h>
3045 +
3046 +#include "glamo-core.h"
3047 +#include "glamo-regs.h"
3048 +
3049 +struct glamo_spigpio {
3050 +       struct spi_bitbang              bitbang;
3051 +       struct spi_master               *master;
3052 +       struct glamo_spigpio_info       *info;
3053 +       struct glamo_core               *glamo;
3054 +};
3055 +
3056 +static inline struct glamo_spigpio *to_sg(struct spi_device *spi)
3057 +{
3058 +       return spi->controller_data;
3059 +}
3060 +
3061 +static inline void setsck(struct spi_device *dev, int on)
3062 +{
3063 +       struct glamo_spigpio *sg = to_sg(dev);
3064 +       glamo_gpio_setpin(sg->glamo, sg->info->pin_clk, on ? 1 : 0);
3065 +}
3066 +
3067 +static inline void setmosi(struct spi_device *dev, int on)
3068 +{
3069 +       struct glamo_spigpio *sg = to_sg(dev);
3070 +       glamo_gpio_setpin(sg->glamo, sg->info->pin_mosi, on ? 1 : 0);
3071 +}
3072 +
3073 +static inline u32 getmiso(struct spi_device *dev)
3074 +{
3075 +       struct glamo_spigpio *sg = to_sg(dev);
3076 +       if (sg->info->pin_miso)
3077 +               return glamo_gpio_getpin(sg->glamo, sg->info->pin_miso) ? 1 : 0;
3078 +       else
3079 +               return 0;
3080 +}
3081 +
3082 +#define spidelay(x) ndelay(x)
3083 +
3084 +#define EXPAND_BITBANG_TXRX
3085 +#include <linux/spi/spi_bitbang.h>
3086 +
3087 +static u32 glamo_spigpio_txrx_mode0(struct spi_device *spi,
3088 +                                   unsigned nsecs, u32 word, u8 bits)
3089 +{
3090 +       return bitbang_txrx_be_cpha0(spi, nsecs, 0, word, bits);
3091 +}
3092 +
3093 +static u32 glamo_spigpio_txrx_mode1(struct spi_device *spi,
3094 +                                   unsigned nsecs, u32 word, u8 bits)
3095 +{
3096 +       return bitbang_txrx_be_cpha1(spi, nsecs, 0, word, bits);
3097 +}
3098 +
3099 +static u32 glamo_spigpio_txrx_mode2(struct spi_device *spi,
3100 +                                   unsigned nsecs, u32 word, u8 bits)
3101 +{
3102 +       return bitbang_txrx_be_cpha0(spi, nsecs, 1, word, bits);
3103 +}
3104 +
3105 +static u32 glamo_spigpio_txrx_mode3(struct spi_device *spi,
3106 +                                   unsigned nsecs, u32 word, u8 bits)
3107 +{
3108 +       return bitbang_txrx_be_cpha1(spi, nsecs, 1, word, bits);
3109 +}
3110 +
3111 +
3112 +#if 0
3113 +static int glamo_spigpio_setupxfer(struct spi_device *spi,
3114 +                                  struct spi_transfer *t)
3115 +{
3116 +       struct glamo_spi *gs = to_sg(spi);
3117 +       unsigned int bpw;
3118 +
3119 +       bpw = t ? t->bits_per_word : spi->bits_per_word;
3120 +
3121 +       if (bpw != 9 && bpw != 8) {
3122 +               dev_err(&spi->dev, "invalid bits-per-word (%d)\n", bpw);
3123 +               return -EINVAL;
3124 +       }
3125 +
3126 +       return 0;
3127 +}
3128 +#endif
3129 +
3130 +static void glamo_spigpio_chipsel(struct spi_device *spi, int value)
3131 +{
3132 +       struct glamo_spigpio *gs = to_sg(spi);
3133 +#if 0
3134 +       dev_dbg(&spi->dev, "chipsel %d: spi=%p, gs=%p, info=%p, handle=%p\n",
3135 +               value, spi, gs, gs->info, gs->info->glamo);
3136 +#endif
3137 +       glamo_gpio_setpin(gs->glamo, gs->info->pin_cs, value ? 0 : 1);
3138 +}
3139 +
3140 +
3141 +static int glamo_spigpio_probe(struct platform_device *pdev)
3142 +{
3143 +       struct spi_master *master;
3144 +       struct glamo_spigpio *sp;
3145 +       int ret;
3146 +       int i;
3147 +
3148 +       master = spi_alloc_master(&pdev->dev, sizeof(struct glamo_spigpio));
3149 +       if (master == NULL) {
3150 +               dev_err(&pdev->dev, "failed to allocate spi master\n");
3151 +               ret = -ENOMEM;
3152 +               goto err;
3153 +       }
3154 +
3155 +       sp = spi_master_get_devdata(master);
3156 +       platform_set_drvdata(pdev, sp);
3157 +       sp->info = pdev->dev.platform_data;
3158 +       if (!sp->info) {
3159 +               dev_err(&pdev->dev, "can't operate without platform data\n");
3160 +               ret = -EIO;
3161 +               goto err_no_pdev;
3162 +       }
3163 +
3164 +       master->num_chipselect = 1;
3165 +       master->bus_num = 2; /* FIXME: use dynamic number */
3166 +
3167 +       sp->master = spi_master_get(master);
3168 +       sp->glamo = sp->info->glamo;
3169 +
3170 +       sp->bitbang.master = sp->master;
3171 +       sp->bitbang.chipselect = glamo_spigpio_chipsel;
3172 +       sp->bitbang.txrx_word[SPI_MODE_0] = glamo_spigpio_txrx_mode0;
3173 +       sp->bitbang.txrx_word[SPI_MODE_1] = glamo_spigpio_txrx_mode1;
3174 +       sp->bitbang.txrx_word[SPI_MODE_2] = glamo_spigpio_txrx_mode2;
3175 +       sp->bitbang.txrx_word[SPI_MODE_3] = glamo_spigpio_txrx_mode3;
3176 +
3177 +       /* set state of spi pins */
3178 +       glamo_gpio_setpin(sp->glamo, sp->info->pin_clk, 0);
3179 +       glamo_gpio_setpin(sp->glamo, sp->info->pin_mosi, 0);
3180 +       glamo_gpio_setpin(sp->glamo, sp->info->pin_cs, 1);
3181 +
3182 +       glamo_gpio_cfgpin(sp->glamo, sp->info->pin_clk);
3183 +       glamo_gpio_cfgpin(sp->glamo, sp->info->pin_mosi);
3184 +       glamo_gpio_cfgpin(sp->glamo, sp->info->pin_cs);
3185 +       if (sp->info->pin_miso)
3186 +               glamo_gpio_cfgpin(sp->glamo, sp->info->pin_miso);
3187 +
3188 +       /* bring the LCM panel out of reset if it isn't already */
3189 +
3190 +       glamo_gpio_setpin(sp->glamo, GLAMO_GPIO4, 1);
3191 +       glamo_gpio_cfgpin(sp->glamo, GLAMO_GPIO4_OUTPUT);
3192 +       msleep(90);
3193 +
3194 +#if 0
3195 +       sp->dev = &pdev->dev;
3196 +
3197 +       sp->bitbang.setup_transfer = glamo_spi_setupxfer;
3198 +       sp->bitbang.txrx_bufs = glamo_spi_txrx;
3199 +       sp->bitbang.master->setup = glamo_spi_setup;
3200 +#endif
3201 +
3202 +       ret = spi_bitbang_start(&sp->bitbang);
3203 +       if (ret)
3204 +               goto err_no_bitbang;
3205 +
3206 +       /* register the chips to go with the board */
3207 +
3208 +       for (i = 0; i < sp->info->board_size; i++) {
3209 +               dev_info(&pdev->dev, "registering %p: %s\n",
3210 +                        &sp->info->board_info[i],
3211 +                        sp->info->board_info[i].modalias);
3212 +
3213 +               sp->info->board_info[i].controller_data = sp;
3214 +               spi_new_device(master, sp->info->board_info + i);
3215 +       }
3216 +
3217 +       return 0;
3218 +
3219 +err_no_bitbang:
3220 +       platform_set_drvdata(pdev, NULL);
3221 +err_no_pdev:
3222 +       spi_master_put(sp->bitbang.master);
3223 +err:
3224 +       return ret;
3225 +
3226 +}
3227 +
3228 +static int glamo_spigpio_remove(struct platform_device *pdev)
3229 +{
3230 +       struct glamo_spigpio *sp = platform_get_drvdata(pdev);
3231 +
3232 +       spi_bitbang_stop(&sp->bitbang);
3233 +       spi_master_put(sp->bitbang.master);
3234 +
3235 +       return 0;
3236 +}
3237 +
3238 +#define glamo_spigpio_suspend NULL
3239 +#define glamo_spigpio_resume NULL
3240 +
3241 +static struct platform_driver glamo_spi_drv = {
3242 +       .probe          = glamo_spigpio_probe,
3243 +       .remove         = glamo_spigpio_remove,
3244 +       .suspend        = glamo_spigpio_suspend,
3245 +       .resume         = glamo_spigpio_resume,
3246 +       .driver         = {
3247 +               .name   = "glamo-spi-gpio",
3248 +               .owner  = THIS_MODULE,
3249 +       },
3250 +};
3251 +
3252 +static int __init glamo_spi_init(void)
3253 +{
3254 +       return platform_driver_register(&glamo_spi_drv);
3255 +}
3256 +
3257 +static void __exit glamo_spi_exit(void)
3258 +{
3259 +       platform_driver_unregister(&glamo_spi_drv);
3260 +}
3261 +
3262 +module_init(glamo_spi_init);
3263 +module_exit(glamo_spi_exit);
3264 +
3265 +MODULE_DESCRIPTION("Smedia Glamo 336x/337x LCM serial command SPI Driver");
3266 +MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>")
3267 +MODULE_LICENSE("GPL");
3268 diff --git a/include/asm-arm/arch-s3c2410/irqs.h b/include/asm-arm/arch-s3c2410/irqs.h
3269 index 996f654..9522cd1 100644
3270 --- a/include/asm-arm/arch-s3c2410/irqs.h
3271 +++ b/include/asm-arm/arch-s3c2410/irqs.h
3272 @@ -155,9 +155,37 @@
3273  #define IRQ_S3C2443_AC97       S3C2410_IRQSUB(28)
3274  
3275  #ifdef CONFIG_CPU_S3C2443
3276 -#define NR_IRQS (IRQ_S3C2443_AC97+1)
3277 +#define _NR_IRQS (IRQ_S3C2443_AC97+1)
3278  #else
3279 -#define NR_IRQS (IRQ_S3C2440_AC97+1)
3280 +#define _NR_IRQS (IRQ_S3C2440_AC97+1)
3281  #endif
3282  
3283 +/*
3284 + * The next 16 interrupts are for board specific purposes.  Since
3285 + * the kernel can only run on one machine at a time, we can re-use
3286 + * these.  If you need more, increase IRQ_BOARD_END, but keep it
3287 + * within sensible limits.
3288 + */
3289 +#define IRQ_BOARD_START                _NR_IRQS
3290 +#define IRQ_BOARD_END          (_NR_IRQS + 10)
3291 +
3292 +#if defined(CONFIG_MACH_NEO1973_GTA02)
3293 +#define NR_IRQS                        (IRQ_BOARD_END)
3294 +#else
3295 +#define NR_IRQS                        (IRQ_BOARD_START)
3296 +#endif
3297 +
3298 +/* Neo1973 GTA02 interrupts */
3299 +#define NEO1973_GTA02_IRQ(x)   (IRQ_BOARD_START + (x))
3300 +#define IRQ_GLAMO(x)           NEO1973_GTA02_IRQ(x)
3301 +#define IRQ_GLAMO_HOSTBUS      IRQ_GLAMO(0)
3302 +#define IRQ_GLAMO_JPEG         IRQ_GLAMO(1)
3303 +#define IRQ_GLAMO_MPEG         IRQ_GLAMO(2)
3304 +#define IRQ_GLAMO_MPROC1       IRQ_GLAMO(3)
3305 +#define IRQ_GLAMO_MPROC0       IRQ_GLAMO(4)
3306 +#define IRQ_GLAMO_CMDQUEUE     IRQ_GLAMO(5)
3307 +#define IRQ_GLAMO_2D           IRQ_GLAMO(6)
3308 +#define IRQ_GLAMO_MMC          IRQ_GLAMO(7)
3309 +#define IRQ_GLAMO_RISC         IRQ_GLAMO(8)
3310 +
3311  #endif /* __ASM_ARCH_IRQ_H */
3312 diff --git a/include/linux/glamo-gpio.h b/include/linux/glamo-gpio.h
3313 new file mode 100644
3314 index 0000000..d00f7e9
3315 --- /dev/null
3316 +++ b/include/linux/glamo-gpio.h
3317 @@ -0,0 +1,99 @@
3318 +#ifndef __GLAMO_GPIO_H
3319 +#define __GLAMO_GPIO_H
3320 +
3321 +struct glamo_core;
3322 +
3323 +#define GLAMO_GPIO_BANKA       0x0000
3324 +#define GLAMO_GPIO_BANKB       0x1000
3325 +#define GLAMO_GPIO_BANKC       0x2000
3326 +#define GLAMO_GPIO_BANKD       0x3000
3327 +
3328 +#define GLAMO_GPIONO(bank, pin)        ((bank & 0xf000) | ((pin & 0xf) << 8))
3329 +
3330 +#define GLAMO_GPIO_F_IN                0x0010
3331 +#define GLAMO_GPIO_F_OUT       0x0020
3332 +#define GLAMO_GPIO_F_FUNC      0x0030
3333 +
3334 +#define GLAMO_GPIO0            GLAMO_GPIONO(GLAMO_GPIO_BANKA, 0)
3335 +#define GLAMO_GPIO0_INPUT      (GLAMO_GPIO0 | GLAMO_GPIO_F_IN)
3336 +#define GLAMO_GPIO0_OUTPUT     (GLAMO_GPIO0 | GLAMO_GPIO_F_OUT)
3337 +#define GLAMO_GPIO0_HA20       (GLAMO_GPIO0 | GLAMO_GPIO_F_FUNC)
3338 +
3339 +#define GLAMO_GPIO1            GLAMO_GPIONO(GLAMO_GPIO_BANKA, 1)
3340 +#define GLAMO_GPIO1_INPUT      (GLAMO_GPIO1 | GLAMO_GPIO_F_IN)
3341 +#define GLAMO_GPIO1_OUTPUT     (GLAMO_GPIO1 | GLAMO_GPIO_F_OUT)
3342 +#define GLAMO_GPIO1_HA21       (GLAMO_GPIO1 | GLAMO_GPIO_F_FUNC)
3343 +
3344 +#define GLAMO_GPIO2            GLAMO_GPIONO(GLAMO_GPIO_BANKA, 2)
3345 +#define GLAMO_GPIO2_INPUT      (GLAMO_GPIO2 | GLAMO_GPIO_F_IN)
3346 +#define GLAMO_GPIO2_OUTPUT     (GLAMO_GPIO2 | GLAMO_GPIO_F_OUT)
3347 +#define GLAMO_GPIO2_HA22       (GLAMO_GPIO2 | GLAMO_GPIO_F_FUNC)
3348 +
3349 +#define GLAMO_GPIO3            GLAMO_GPIONO(GLAMO_GPIO_BANKA, 3)
3350 +#define GLAMO_GPIO3_INPUT      (GLAMO_GPIO3 | GLAMO_GPIO_F_IN)
3351 +#define GLAMO_GPIO3_OUTPUT     (GLAMO_GPIO3 | GLAMO_GPIO_F_OUT)
3352 +#define        GLAMO_GPIO3_HA23        (GLAMO_GPIO3 | GLAMO_GPIO_F_FUNC)
3353 +
3354 +#define GLAMO_GPIO4            GLAMO_GPIONO(GLAMO_GPIO_BANKB, 0)
3355 +#define GLAMO_GPIO4_INPUT      (GLAMO_GPIO4 | GLAMO_GPIO_F_IN)
3356 +#define GLAMO_GPIO4_OUTPUT     (GLAMO_GPIO4 | GLAMO_GPIO_F_OUT)
3357 +#define GLAMO_GPIO4_nLCS0      (GLAMO_GPIO4 | GLAMO_GPIO_F_FUNC)
3358 +
3359 +#define GLAMO_GPIO5            GLAMO_GPIONO(GLAMO_GPIO_BANKB, 1)
3360 +#define GLAMO_GPIO5_INPUT      (GLAMO_GPIO5 | GLAMO_GPIO_F_IN)
3361 +#define GLAMO_GPIO5_OUTPUT     (GLAMO_GPIO5 | GLAMO_GPIO_F_OUT)
3362 +#define GLAMO_GPIO5_nLCS1      (GLAMO_GPIO5 | GLAMO_GPIO_F_FUNC)
3363 +
3364 +#define GLAMO_GPIO6            GLAMO_GPIONO(GLAMO_GPIO_BANKB, 2)
3365 +#define GLAMO_GPIO6_INPUT      (GLAMO_GPIO6 | GLAMO_GPIO_F_IN)
3366 +#define GLAMO_GPIO6_OUTPUT     (GLAMO_GPIO6 | GLAMO_GPIO_F_OUT)
3367 +#define GLAMO_GPIO6_LDCLK      (GLAMO_GPIO6 | GLAMO_GPIO_F_FUNC)
3368 +
3369 +#define GLAMO_GPIO7            GLAMO_GPIONO(GLAMO_GPIO_BANKB, 3)
3370 +#define GLAMO_GPIO7_INPUT      (GLAMO_GPIO7 | GLAMO_GPIO_F_IN)
3371 +#define GLAMO_GPIO7_OUTPUT     (GLAMO_GPIO7 | GLAMO_GPIO_F_OUT)
3372 +#define GLAMO_GPIO7_nLDE       (GLAMO_GPIO7 | GLAMO_GPIO_F_FUNC)
3373 +
3374 +#define GLAMO_GPIO8            GLAMO_GPIONO(GLAMO_GPIO_BANKC, 0)
3375 +#define GLAMO_GPIO8_INPUT      (GLAMO_GPIO8 | GLAMO_GPIO_F_IN)
3376 +#define GLAMO_GPIO8_OUTPUT     (GLAMO_GPIO8 | GLAMO_GPIO_F_OUT)
3377 +#define GLAMO_GPIO8_LD16       (GLAMO_GPIO8 | GLAMO_GPIO_F_FUNC)
3378 +
3379 +#define GLAMO_GPIO9            GLAMO_GPIONO(GLAMO_GPIO_BANKC, 1)
3380 +#define GLAMO_GPIO9_INPUT      (GLAMO_GPIO9 | GLAMO_GPIO_F_IN)
3381 +#define GLAMO_GPIO9_OUTPUT     (GLAMO_GPIO9 | GLAMO_GPIO_F_OUT)
3382 +#define GLAMO_GPIO9_LD17       (GLAMO_GPIO9 | GLAMO_GPIO_F_FUNC)
3383 +
3384 +#define GLAMO_GPIO10           GLAMO_GPIONO(GLAMO_GPIO_BANKC, 2)
3385 +#define GLAMO_GPIO10_INPUT     (GLAMO_GPIO10 | GLAMO_GPIO_F_IN)
3386 +#define GLAMO_GPIO10_OUTPUT    (GLAMO_GPIO10 | GLAMO_GPIO_F_OUT)
3387 +#define GLAMO_GPIO10_LSCK      (GLAMO_GPIO10 | GLAMO_GPIO_F_FUNC)
3388 +
3389 +#define GLAMO_GPIO11           GLAMO_GPIONO(GLAMO_GPIO_BANKC, 3)
3390 +#define GLAMO_GPIO11_INPUT     (GLAMO_GPIO11 | GLAMO_GPIO_F_IN)
3391 +#define GLAMO_GPIO11_OUTPUT    (GLAMO_GPIO11 | GLAMO_GPIO_F_OUT)
3392 +#define GLAMO_GPIO11_LSDA      (GLAMO_GPIO11 | GLAMO_GPIO_F_FUNC)
3393 +
3394 +#define GLAMO_GPIO12           GLAMO_GPIONO(GLAMO_GPIO_BANKD, 0)
3395 +#define GLAMO_GPIO12_INPUT     (GLAMO_GPIO12 | GLAMO_GPIO_F_IN)
3396 +#define GLAMO_GPIO12_OUTPUT    (GLAMO_GPIO12 | GLAMO_GPIO_F_OUT)
3397 +#define GLAMO_GPIO12_LSA0      (GLAMO_GPIO12 | GLAMO_GPIO_F_FUNC)
3398 +
3399 +
3400 +#define REG_OF_GPIO(gpio)      (((gpio & 0xf000) >> 12)*2 \
3401 +                                               + GLAMO_REG_GPIO_GEN1)
3402 +#define NUM_OF_GPIO(gpio)      ((gpio & 0x0f00) >> 8)
3403 +#define GPIO_OUT_BIT(gpio)     (1 << (NUM_OF_GPIO(gpio) + 0))
3404 +#define OUTPUT_BIT(gpio)       (1 << (NUM_OF_GPIO(gpio) + 4))
3405 +#define INPUT_BIT(gpio)                (1 << (NUM_OF_GPIO(gpio) + 8))
3406 +#define FUNC_BIT(gpio)         (1 << (NUM_OF_GPIO(gpio) + 12))
3407 +
3408 +void glamo_gpio_setpin(struct glamo_core *glamo, unsigned int pin,
3409 +                      unsigned int value);
3410 +
3411 +int glamo_gpio_getpin(struct glamo_core *glamo, unsigned int pin);
3412 +
3413 +void glamo_gpio_cfgpin(struct glamo_core *glamo, unsigned int pinfunc);
3414 +
3415 +
3416 +#endif /* _GLAMO_GPIO */
3417 diff --git a/include/linux/glamofb.h b/include/linux/glamofb.h
3418 new file mode 100644
3419 index 0000000..24742a2
3420 --- /dev/null
3421 +++ b/include/linux/glamofb.h
3422 @@ -0,0 +1,39 @@
3423 +#ifndef _LINUX_GLAMOFB_H
3424 +#define _LINUX_GLAMOFB_H
3425 +
3426 +#include <linux/spi/glamo.h>
3427 +
3428 +struct glamofb_val {
3429 +       unsigned int defval;
3430 +       unsigned int min;
3431 +       unsigned int max;
3432 +};
3433 +
3434 +struct glamo_core;
3435 +
3436 +struct glamofb_platform_data {
3437 +       int width, height;
3438 +       int pixclock;
3439 +       int left_margin, right_margin;
3440 +       int upper_margin, lower_margin;
3441 +       int hsync_len, vsync_len;
3442 +       int fb_mem_size;
3443 +
3444 +       struct glamofb_val xres;
3445 +       struct glamofb_val yres;
3446 +       struct glamofb_val bpp;
3447 +
3448 +       struct glamo_spi_info *spi_info;
3449 +       struct glamo_spigpio_info *spigpio_info;
3450 +       struct glamo_core *glamo;
3451 +
3452 +       /* glamo mmc platform specific info */
3453 +       void            (*glamo_set_mci_power)(unsigned char power_mode,
3454 +                                    unsigned short vdd);
3455 +       int             (*glamo_irq_is_wired)(void);
3456 +};
3457 +
3458 +void glamofb_cmd_mode(struct glamofb_handle *gfb, int on);
3459 +int glamofb_cmd_write(struct glamofb_handle *gfb, u_int16_t val);
3460 +
3461 +#endif
3462 diff --git a/include/linux/spi/glamo.h b/include/linux/spi/glamo.h
3463 new file mode 100644
3464 index 0000000..86419ea
3465 --- /dev/null
3466 +++ b/include/linux/spi/glamo.h
3467 @@ -0,0 +1,28 @@
3468 +#ifndef __GLAMO_SPI_H
3469 +#define __GLAMO_SPI_H
3470 +
3471 +#include <linux/glamo-gpio.h>
3472 +
3473 +struct spi_board_info;
3474 +struct glamofb_handle;
3475 +struct glamo_core;
3476 +
3477 +struct glamo_spi_info {
3478 +       unsigned long           board_size;
3479 +       struct spi_board_info   *board_info;
3480 +       struct glamofb_handle   *glamofb_handle;
3481 +};
3482 +
3483 +struct glamo_spigpio_info {
3484 +       unsigned int            pin_clk;
3485 +       unsigned int            pin_mosi;
3486 +       unsigned int            pin_miso;
3487 +       unsigned int            pin_cs;
3488 +
3489 +       unsigned int            board_size;
3490 +       struct spi_board_info   *board_info;
3491 +       struct glamo_core       *glamo;
3492 +};
3493 +
3494 +
3495 +#endif
3496 -- 
3497 1.5.6.5
3498