/*
* drivers/mb862xx/mb862xxfb.c
*
* Fujitsu Carmine/Coral-P(A)/Lime framebuffer driver
*
* (C) 2008 Anatolij Gustschin <agust@denx.de>
* DENX Software Engineering
*
* 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.
*
*/
#undef DEBUG
#include <linux/fb.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
#if defined(CONFIG_PPC_OF)
#include <linux/of_platform.h>
#endif
#include "mb862xxfb.h"
#include "mb862xx_reg.h"
#define NR_PALETTE 256
#define MB862XX_MEM_SIZE 0x1000000
#define CORALP_MEM_SIZE 0x4000000
#define CARMINE_MEM_SIZE 0x8000000
#define DRV_NAME "mb862xxfb"
#if defined(CONFIG_LWMON5)
static struct mb862xx_gc_mode lwmon5_gc_mode = {
/* Mode for Sharp LQ104V1DG61 TFT LCD Panel */
{ "640x480", 60, 640, 480, 40000, 48, 16, 32, 11, 96, 2, 0, 0, 0 },
/* 16 bits/pixel, 32MB, 100MHz, SDRAM memory mode value */
16, 0x2000000, GC_CCF_COT_100, 0x414fb7f2
};
#endif
#if defined(CONFIG_SOCRATES)
static struct mb862xx_gc_mode socrates_gc_mode = {
/* Mode for Prime View PM070WL4 TFT LCD Panel */
{ "800x480", 45, 800, 480, 40000, 86, 42, 33, 10, 128, 2, 0, 0, 0 },
/* 16 bits/pixel, 16MB, 133MHz, SDRAM memory mode value */
16, 0x1000000, GC_CCF_COT_133, 0x4157ba63
};
#endif
/* Helpers */
static inline int h_total(struct fb_var_screeninfo *var)
{
return var->xres + var->left_margin +
var->right_margin + var->hsync_len;
}
static inline int v_total(struct fb_var_screeninfo *var)
{
return var->yres + var->upper_margin +
var->lower_margin + var->vsync_len;
}
static inline int hsp(struct fb_var_screeninfo *var)
{
return var->xres + var->right_margin - 1;
}
static inline int vsp(struct fb_var_screeninfo *var)
{
return var->yres + var->lower_margin - 1;
}
static inline int d_pitch(struct fb_var_screeninfo *var)
{
return var->xres * var->bits_per_pixel / 8;
}
static inline unsigned int chan_to_field(unsigned int chan,
struct fb_bitfield *bf)
{
chan &= 0xffff;
chan >>= 16 - bf->length;
return chan << bf->offset;
}
static int mb862xxfb_setcolreg(unsigned regno,
unsigned red, unsigned green, unsigned blue,
unsigned transp, struct fb_info *info)
{
struct mb862xxfb_par *par = info->par;
unsigned int val;
switch (info->fix.visual) {
case FB_VISUAL_TRUECOLOR:
if (regno < 16) {
val = chan_to_field(red, &info->var.red);
val |= chan_to_field(green, &info->var.green);
val |= chan_to_field(blue, &info->var.blue);
par->pseudo_palette[regno] = val;
}
break;
case FB_VISUAL_PSEUDOCOLOR:
if (regno < 256) {
val = (red >> 8) << 16;
val |= (green >> 8) << 8;
val |= blue >> 8;
outreg(disp, GC_L0PAL0 + (regno * 4), val);
}
break;
default:
return 1; /* unsupported type */
}
return 0;
}
static int mb862xxfb_check_var(struct fb_var_screeninfo *var,
struct fb_info *fbi)
{
unsigned long tmp;
if (fbi->dev)
dev_dbg(fbi->dev, "%s\n", __func__);
/* check if these values fit i