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