linux/arch/arm/mach-lh7a40x/clcd.c
<<
>>
Prefs
   1/*
   2 *  arch/arm/mach-lh7a40x/clcd.c
   3 *
   4 *  Copyright (C) 2004 Marc Singer
   5 *
   6 *  This program is free software; you can redistribute it and/or
   7 *  modify it under the terms of the GNU General Public License
   8 *  version 2 as published by the Free Software Foundation.
   9 *
  10 */
  11
  12#include <linux/init.h>
  13#include <linux/device.h>
  14#include <linux/dma-mapping.h>
  15#include <linux/sysdev.h>
  16#include <linux/interrupt.h>
  17
  18//#include <linux/module.h>
  19//#include <linux/time.h>
  20
  21//#include <asm/mach/time.h>
  22#include <asm/irq.h>
  23#include <asm/mach/irq.h>
  24
  25#include <asm/system.h>
  26#include <mach/hardware.h>
  27#include <linux/amba/bus.h>
  28#include <linux/amba/clcd.h>
  29
  30#define HRTFTC_HRSETUP          __REG(HRTFTC_PHYS + 0x00)
  31#define HRTFTC_HRCON            __REG(HRTFTC_PHYS + 0x04)
  32#define HRTFTC_HRTIMING1        __REG(HRTFTC_PHYS + 0x08)
  33#define HRTFTC_HRTIMING2        __REG(HRTFTC_PHYS + 0x0c)
  34
  35#define ALI_SETUP               __REG(ALI_PHYS + 0x00)
  36#define ALI_CONTROL             __REG(ALI_PHYS + 0x04)
  37#define ALI_TIMING1             __REG(ALI_PHYS + 0x08)
  38#define ALI_TIMING2             __REG(ALI_PHYS + 0x0c)
  39
  40#include "lcd-panel.h"
  41
  42static void lh7a40x_clcd_disable (struct clcd_fb *fb)
  43{
  44#if defined (CONFIG_MACH_LPD7A400)
  45        CPLD_CONTROL &= ~(1<<1);        /* Disable LCD Vee */
  46#endif
  47
  48#if defined (CONFIG_MACH_LPD7A404)
  49        GPIO_PCD  &= ~(1<<3);           /* Disable LCD Vee */
  50#endif
  51
  52#if defined (CONFIG_ARCH_LH7A400)
  53        HRTFTC_HRSETUP &= ~(1<<13);     /* Disable HRTFT controller */
  54#endif
  55
  56#if defined (CONFIG_ARCH_LH7A404)
  57        ALI_SETUP &= ~(1<<13);          /* Disable ALI */
  58#endif
  59}
  60
  61static void lh7a40x_clcd_enable (struct clcd_fb *fb)
  62{
  63        struct clcd_panel_extra* extra
  64                = (struct clcd_panel_extra*) fb->board_data;
  65
  66#if defined (CONFIG_MACH_LPD7A400)
  67        CPLD_CONTROL |= (1<<1);         /* Enable LCD Vee */
  68#endif
  69
  70#if defined (CONFIG_MACH_LPD7A404)
  71        GPIO_PCDD &= ~(1<<3);           /* Enable LCD Vee */
  72        GPIO_PCD  |=  (1<<3);
  73#endif
  74
  75#if defined (CONFIG_ARCH_LH7A400)
  76
  77        if (extra) {
  78                HRTFTC_HRSETUP
  79                        = (1 << 13)
  80                        | ((fb->fb.var.xres - 1) << 4)
  81                        | 0xc
  82                        | (extra->hrmode ? 1 : 0);
  83                HRTFTC_HRCON
  84                        = ((extra->clsen ? 1 : 0) << 1)
  85                        | ((extra->spsen ? 1 : 0) << 0);
  86                HRTFTC_HRTIMING1
  87                        = (extra->pcdel << 8)
  88                        | (extra->revdel << 4)
  89                        | (extra->lpdel << 0);
  90                HRTFTC_HRTIMING2
  91                        = (extra->spldel << 9)
  92                        | (extra->pc2del << 0);
  93        }
  94        else
  95                HRTFTC_HRSETUP
  96                        = (1 << 13)
  97                        | 0xc;
  98#endif
  99
 100#if defined (CONFIG_ARCH_LH7A404)
 101
 102        if (extra) {
 103                ALI_SETUP
 104                        = (1 << 13)
 105                        | ((fb->fb.var.xres - 1) << 4)
 106                        | 0xc
 107                        | (extra->hrmode ? 1 : 0);
 108                ALI_CONTROL
 109                        = ((extra->clsen ? 1 : 0) << 1)
 110                        | ((extra->spsen ? 1 : 0) << 0);
 111                ALI_TIMING1
 112                        = (extra->pcdel << 8)
 113                        | (extra->revdel << 4)
 114                        | (extra->lpdel << 0);
 115                ALI_TIMING2
 116                        = (extra->spldel << 9)
 117                        | (extra->pc2del << 0);
 118        }
 119        else
 120                ALI_SETUP
 121                        = (1 << 13)
 122                        | 0xc;
 123#endif
 124
 125}
 126
 127#define FRAMESIZE(s) (((s) + PAGE_SIZE - 1)&PAGE_MASK)
 128
 129static int lh7a40x_clcd_setup (struct clcd_fb *fb)
 130{
 131        dma_addr_t dma;
 132        u32 len = FRAMESIZE (lcd_panel.mode.xres*lcd_panel.mode.yres
 133                             *(lcd_panel.bpp/8));
 134
 135        fb->panel = &lcd_panel;
 136
 137                /* Enforce the sync polarity defaults */
 138        if (!(fb->panel->tim2 & TIM2_IHS))
 139                fb->fb.var.sync |= FB_SYNC_HOR_HIGH_ACT;
 140        if (!(fb->panel->tim2 & TIM2_IVS))
 141                fb->fb.var.sync |= FB_SYNC_VERT_HIGH_ACT;
 142
 143#if defined (HAS_LCD_PANEL_EXTRA)
 144        fb->board_data = &lcd_panel_extra;
 145#endif
 146
 147        fb->fb.screen_base
 148                = dma_alloc_writecombine (&fb->dev->dev, len,
 149                                          &dma, GFP_KERNEL);
 150        printk ("CLCD: LCD setup fb virt 0x%p phys 0x%p l %x io 0x%p \n",
 151                fb->fb.screen_base, (void*) dma, len,
 152                (void*) io_p2v (CLCDC_PHYS));
 153        printk ("CLCD: pixclock %d\n", lcd_panel.mode.pixclock);
 154
 155        if (!fb->fb.screen_base) {
 156                printk(KERN_ERR "CLCD: unable to map framebuffer\n");
 157                return -ENOMEM;
 158        }
 159
 160#if defined (USE_RGB555)
 161        fb->fb.var.green.length = 5; /* Panel uses RGB 5:5:5 */
 162#endif
 163
 164        fb->fb.fix.smem_start = dma;
 165        fb->fb.fix.smem_len = len;
 166
 167                /* Drive PE4 high to prevent CPLD crash */
 168        GPIO_PEDD |= (1<<4);
 169        GPIO_PED  |= (1<<4);
 170
 171        GPIO_PINMUX |= (1<<1) | (1<<0); /* LCDVD[15:4] */
 172
 173//      fb->fb.fbops->fb_check_var (&fb->fb.var, &fb->fb);
 174//      fb->fb.fbops->fb_set_par (&fb->fb);
 175
 176        return 0;
 177}
 178
 179static int lh7a40x_clcd_mmap (struct clcd_fb *fb, struct vm_area_struct *vma)
 180{
 181        return dma_mmap_writecombine(&fb->dev->dev, vma,
 182                                     fb->fb.screen_base,
 183                                     fb->fb.fix.smem_start,
 184                                     fb->fb.fix.smem_len);
 185}
 186
 187static void lh7a40x_clcd_remove (struct clcd_fb *fb)
 188{
 189        dma_free_writecombine (&fb->dev->dev, fb->fb.fix.smem_len,
 190                               fb->fb.screen_base, fb->fb.fix.smem_start);
 191}
 192
 193static struct clcd_board clcd_platform_data = {
 194        .name           = "lh7a40x FB",
 195        .check          = clcdfb_check,
 196        .decode         = clcdfb_decode,
 197        .enable         = lh7a40x_clcd_enable,
 198        .setup          = lh7a40x_clcd_setup,
 199        .mmap           = lh7a40x_clcd_mmap,
 200        .remove         = lh7a40x_clcd_remove,
 201        .disable        = lh7a40x_clcd_disable,
 202};
 203
 204#define IRQ_CLCDC (IRQ_LCDINTR)
 205
 206#define AMBA_DEVICE(name,busid,base,plat,pid)                   \
 207static struct amba_device name##_device = {                     \
 208        .dev = {                                                \
 209                .coherent_dma_mask = ~0,                        \
 210                .bus_id = busid,                                \
 211                .platform_data = plat,                          \
 212                },                                              \
 213        .res = {                                                \
 214                .start  = base##_PHYS,                          \
 215                .end    = (base##_PHYS) + (4*1024) - 1,         \
 216                .flags  = IORESOURCE_MEM,                       \
 217                },                                              \
 218        .dma_mask       = ~0,                                   \
 219        .irq            = { IRQ_##base, },                      \
 220        /* .dma         = base##_DMA,*/                         \
 221        .periphid = pid,                                        \
 222}
 223
 224AMBA_DEVICE(clcd,  "cldc-lh7a40x",  CLCDC,     &clcd_platform_data, 0x41110);
 225
 226static struct amba_device *amba_devs[] __initdata = {
 227        &clcd_device,
 228};
 229
 230void __init lh7a40x_clcd_init (void)
 231{
 232        int i;
 233        int result;
 234        printk ("CLCD: registering amba devices\n");
 235        for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
 236                struct amba_device *d = amba_devs[i];
 237                result = amba_device_register(d, &iomem_resource);
 238                printk ("  %d -> %d\n", i ,result);
 239        }
 240}
 241