Logo Search packages:      
Sourcecode: linux version File versions  Download package

clcd.c

/*
 *  arch/arm/mach-lh7a40x/clcd.c
 *
 *  Copyright (C) 2004 Marc Singer
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License
 *  version 2 as published by the Free Software Foundation.
 *
 */

#include <linux/init.h>
#include <linux/gfp.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/sysdev.h>
#include <linux/interrupt.h>

//#include <linux/module.h>
//#include <linux/time.h>

//#include <asm/mach/time.h>
#include <asm/irq.h>
#include <asm/mach/irq.h>

#include <asm/system.h>
#include <mach/hardware.h>
#include <linux/amba/bus.h>
#include <linux/amba/clcd.h>

#define HRTFTC_HRSETUP        __REG(HRTFTC_PHYS + 0x00)
#define HRTFTC_HRCON          __REG(HRTFTC_PHYS + 0x04)
#define HRTFTC_HRTIMING1      __REG(HRTFTC_PHYS + 0x08)
#define HRTFTC_HRTIMING2      __REG(HRTFTC_PHYS + 0x0c)

#define ALI_SETUP       __REG(ALI_PHYS + 0x00)
#define ALI_CONTROL           __REG(ALI_PHYS + 0x04)
#define ALI_TIMING1           __REG(ALI_PHYS + 0x08)
#define ALI_TIMING2           __REG(ALI_PHYS + 0x0c)

#include "lcd-panel.h"

static void lh7a40x_clcd_disable (struct clcd_fb *fb)
{
#if defined (CONFIG_MACH_LPD7A400)
      CPLD_CONTROL &= ~(1<<1);      /* Disable LCD Vee */
#endif

#if defined (CONFIG_MACH_LPD7A404)
      GPIO_PCD  &= ~(1<<3);         /* Disable LCD Vee */
#endif

#if defined (CONFIG_ARCH_LH7A400)
      HRTFTC_HRSETUP &= ~(1<<13);   /* Disable HRTFT controller */
#endif

#if defined (CONFIG_ARCH_LH7A404)
      ALI_SETUP &= ~(1<<13);        /* Disable ALI */
#endif
}

static void lh7a40x_clcd_enable (struct clcd_fb *fb)
{
      struct clcd_panel_extra* extra
            = (struct clcd_panel_extra*) fb->board_data;

#if defined (CONFIG_MACH_LPD7A400)
      CPLD_CONTROL |= (1<<1);       /* Enable LCD Vee */
#endif

#if defined (CONFIG_MACH_LPD7A404)
      GPIO_PCDD &= ~(1<<3);         /* Enable LCD Vee */
      GPIO_PCD  |=  (1<<3);
#endif

#if defined (CONFIG_ARCH_LH7A400)

      if (extra) {
            HRTFTC_HRSETUP
                  = (1 << 13)
                  | ((fb->fb.var.xres - 1) << 4)
                  | 0xc
                  | (extra->hrmode ? 1 : 0);
            HRTFTC_HRCON
                  = ((extra->clsen ? 1 : 0) << 1)
                  | ((extra->spsen ? 1 : 0) << 0);
            HRTFTC_HRTIMING1
                  = (extra->pcdel << 8)
                  | (extra->revdel << 4)
                  | (extra->lpdel << 0);
            HRTFTC_HRTIMING2
                  = (extra->spldel << 9)
                  | (extra->pc2del << 0);
      }
      else
            HRTFTC_HRSETUP
                  = (1 << 13)
                  | 0xc;
#endif

#if defined (CONFIG_ARCH_LH7A404)

      if (extra) {
            ALI_SETUP
                  = (1 << 13)
                  | ((fb->fb.var.xres - 1) << 4)
                  | 0xc
                  | (extra->hrmode ? 1 : 0);
            ALI_CONTROL
                  = ((extra->clsen ? 1 : 0) << 1)
                  | ((extra->spsen ? 1 : 0) << 0);
            ALI_TIMING1
                  = (extra->pcdel << 8)
                  | (extra->revdel << 4)
                  | (extra->lpdel << 0);
            ALI_TIMING2
                  = (extra->spldel << 9)
                  | (extra->pc2del << 0);
      }
      else
            ALI_SETUP
                  = (1 << 13)
                  | 0xc;
#endif

}

#define FRAMESIZE(s) (((s) + PAGE_SIZE - 1)&PAGE_MASK)

static int lh7a40x_clcd_setup (struct clcd_fb *fb)
{
      dma_addr_t dma;
      u32 len = FRAMESIZE (lcd_panel.mode.xres*lcd_panel.mode.yres
                       *(lcd_panel.bpp/8));

      fb->panel = &lcd_panel;

            /* Enforce the sync polarity defaults */
      if (!(fb->panel->tim2 & TIM2_IHS))
            fb->fb.var.sync |= FB_SYNC_HOR_HIGH_ACT;
      if (!(fb->panel->tim2 & TIM2_IVS))
            fb->fb.var.sync |= FB_SYNC_VERT_HIGH_ACT;

#if defined (HAS_LCD_PANEL_EXTRA)
      fb->board_data = &lcd_panel_extra;
#endif

      fb->fb.screen_base
            = dma_alloc_writecombine (&fb->dev->dev, len,
                                &dma, GFP_KERNEL);
      printk ("CLCD: LCD setup fb virt 0x%p phys 0x%p l %x io 0x%p \n",
            fb->fb.screen_base, (void*) dma, len,
            (void*) io_p2v (CLCDC_PHYS));
      printk ("CLCD: pixclock %d\n", lcd_panel.mode.pixclock);

      if (!fb->fb.screen_base) {
            printk(KERN_ERR "CLCD: unable to map framebuffer\n");
            return -ENOMEM;
      }

#if defined (USE_RGB555)
      fb->fb.var.green.length = 5; /* Panel uses RGB 5:5:5 */
#endif

      fb->fb.fix.smem_start = dma;
      fb->fb.fix.smem_len = len;

            /* Drive PE4 high to prevent CPLD crash */
      GPIO_PEDD |= (1<<4);
      GPIO_PED  |= (1<<4);

      GPIO_PINMUX |= (1<<1) | (1<<0); /* LCDVD[15:4] */

//    fb->fb.fbops->fb_check_var (&fb->fb.var, &fb->fb);
//    fb->fb.fbops->fb_set_par (&fb->fb);

      return 0;
}

static int lh7a40x_clcd_mmap (struct clcd_fb *fb, struct vm_area_struct *vma)
{
      return dma_mmap_writecombine(&fb->dev->dev, vma,
                             fb->fb.screen_base,
                             fb->fb.fix.smem_start,
                             fb->fb.fix.smem_len);
}

static void lh7a40x_clcd_remove (struct clcd_fb *fb)
{
      dma_free_writecombine (&fb->dev->dev, fb->fb.fix.smem_len,
                         fb->fb.screen_base, fb->fb.fix.smem_start);
}

static struct clcd_board clcd_platform_data = {
      .name       = "lh7a40x FB",
      .check            = clcdfb_check,
      .decode           = clcdfb_decode,
      .enable           = lh7a40x_clcd_enable,
      .setup            = lh7a40x_clcd_setup,
      .mmap       = lh7a40x_clcd_mmap,
      .remove           = lh7a40x_clcd_remove,
      .disable    = lh7a40x_clcd_disable,
};

#define IRQ_CLCDC (IRQ_LCDINTR)

#define AMBA_DEVICE(name,busid,base,plat,pid)               \
static struct amba_device name##_device = {                 \
      .dev = {                                  \
            .coherent_dma_mask = ~0,                  \
            .init_name = busid,                       \
            .platform_data = plat,                    \
            },                                  \
      .res = {                                  \
            .start      = base##_PHYS,                      \
            .end  = (base##_PHYS) + (4*1024) - 1,           \
            .flags      = IORESOURCE_MEM,             \
            },                                  \
      .dma_mask   = ~0,                         \
      .irq        = { IRQ_##base, },                  \
      /* .dma           = base##_DMA,*/                     \
      .periphid = pid,                          \
}

AMBA_DEVICE(clcd,  "cldc-lh7a40x",  CLCDC,     &clcd_platform_data, 0x41110);

static struct amba_device *amba_devs[] __initdata = {
      &clcd_device,
};

void __init lh7a40x_clcd_init (void)
{
      int i;
      int result;
      printk ("CLCD: registering amba devices\n");
      for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
            struct amba_device *d = amba_devs[i];
            result = amba_device_register(d, &iomem_resource);
            printk ("  %d -> %d\n", i ,result);
      }
}

Generated by  Doxygen 1.6.0   Back to index