Commit 18bbff9f authored by Russell King's avatar Russell King

Merge branch 'sa11x0-lcd' into sa11x0

Conflicts:
	arch/arm/mach-sa1100/assabet.c
parents e7d863d0 7cb66dcc
...@@ -20,6 +20,8 @@ ...@@ -20,6 +20,8 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <video/sa1100fb.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/irq.h> #include <asm/irq.h>
...@@ -69,33 +71,6 @@ void ASSABET_BCR_frob(unsigned int mask, unsigned int val) ...@@ -69,33 +71,6 @@ void ASSABET_BCR_frob(unsigned int mask, unsigned int val)
EXPORT_SYMBOL(ASSABET_BCR_frob); EXPORT_SYMBOL(ASSABET_BCR_frob);
static void assabet_backlight_power(int on)
{
#ifndef ASSABET_PAL_VIDEO
if (on)
ASSABET_BCR_set(ASSABET_BCR_LIGHT_ON);
else
#endif
ASSABET_BCR_clear(ASSABET_BCR_LIGHT_ON);
}
/*
* Turn on/off the backlight. When turning the backlight on,
* we wait 500us after turning it on so we don't cause the
* supplies to droop when we enable the LCD controller (and
* cause a hard reset.)
*/
static void assabet_lcd_power(int on)
{
#ifndef ASSABET_PAL_VIDEO
if (on) {
ASSABET_BCR_set(ASSABET_BCR_LCD_ON);
udelay(500);
} else
#endif
ASSABET_BCR_clear(ASSABET_BCR_LCD_ON);
}
/* /*
* Assabet flash support code. * Assabet flash support code.
...@@ -197,6 +172,99 @@ static struct mcp_plat_data assabet_mcp_data = { ...@@ -197,6 +172,99 @@ static struct mcp_plat_data assabet_mcp_data = {
.sclk_rate = 11981000, .sclk_rate = 11981000,
}; };
static void assabet_lcd_set_visual(u32 visual)
{
u_int is_true_color = visual == FB_VISUAL_TRUECOLOR;
if (machine_is_assabet()) {
#if 1 // phase 4 or newer Assabet's
if (is_true_color)
ASSABET_BCR_set(ASSABET_BCR_LCD_12RGB);
else
ASSABET_BCR_clear(ASSABET_BCR_LCD_12RGB);
#else
// older Assabet's
if (is_true_color)
ASSABET_BCR_clear(ASSABET_BCR_LCD_12RGB);
else
ASSABET_BCR_set(ASSABET_BCR_LCD_12RGB);
#endif
}
}
#ifndef ASSABET_PAL_VIDEO
static void assabet_lcd_backlight_power(int on)
{
if (on)
ASSABET_BCR_set(ASSABET_BCR_LIGHT_ON);
else
ASSABET_BCR_clear(ASSABET_BCR_LIGHT_ON);
}
/*
* Turn on/off the backlight. When turning the backlight on, we wait
* 500us after turning it on so we don't cause the supplies to droop
* when we enable the LCD controller (and cause a hard reset.)
*/
static void assabet_lcd_power(int on)
{
if (on) {
ASSABET_BCR_set(ASSABET_BCR_LCD_ON);
udelay(500);
} else
ASSABET_BCR_clear(ASSABET_BCR_LCD_ON);
}
/*
* The assabet uses a sharp LQ039Q2DS54 LCD module. It is actually
* takes an RGB666 signal, but we provide it with an RGB565 signal
* instead (def_rgb_16).
*/
static struct sa1100fb_mach_info lq039q2ds54_info = {
.pixclock = 171521, .bpp = 16,
.xres = 320, .yres = 240,
.hsync_len = 5, .vsync_len = 1,
.left_margin = 61, .upper_margin = 3,
.right_margin = 9, .lower_margin = 0,
.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
.lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
.lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
.backlight_power = assabet_lcd_backlight_power,
.lcd_power = assabet_lcd_power,
.set_visual = assabet_lcd_set_visual,
};
#else
static void assabet_pal_backlight_power(int on)
{
ASSABET_BCR_clear(ASSABET_BCR_LIGHT_ON);
}
static void assabet_pal_power(int on)
{
ASSABET_BCR_clear(ASSABET_BCR_LCD_ON);
}
static struct sa1100fb_mach_info pal_info = {
.pixclock = 67797, .bpp = 16,
.xres = 640, .yres = 512,
.hsync_len = 64, .vsync_len = 6,
.left_margin = 125, .upper_margin = 70,
.right_margin = 115, .lower_margin = 36,
.lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
.lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(512),
.backlight_power = assabet_pal_backlight_power,
.lcd_power = assabet_pal_power,
.set_visual = assabet_lcd_set_visual,
};
#endif
#ifdef CONFIG_ASSABET_NEPONSET #ifdef CONFIG_ASSABET_NEPONSET
static struct resource neponset_resources[] = { static struct resource neponset_resources[] = {
DEFINE_RES_MEM(0x10000000, 0x08000000), DEFINE_RES_MEM(0x10000000, 0x08000000),
...@@ -241,9 +309,6 @@ static void __init assabet_init(void) ...@@ -241,9 +309,6 @@ static void __init assabet_init(void)
PPDR |= PPC_TXD3 | PPC_TXD1; PPDR |= PPC_TXD3 | PPC_TXD1;
PPSR |= PPC_TXD3 | PPC_TXD1; PPSR |= PPC_TXD3 | PPC_TXD1;
sa1100fb_lcd_power = assabet_lcd_power;
sa1100fb_backlight_power = assabet_backlight_power;
if (machine_has_neponset()) { if (machine_has_neponset()) {
/* /*
* Angel sets this, but other bootloaders may not. * Angel sets this, but other bootloaders may not.
...@@ -262,6 +327,11 @@ static void __init assabet_init(void) ...@@ -262,6 +327,11 @@ static void __init assabet_init(void)
#endif #endif
} }
#ifndef ASSABET_PAL_VIDEO
sa11x0_register_lcd(&lq039q2ds54_info);
#else
sa11x0_register_lcd(&pal_video);
#endif
sa11x0_register_mtd(&assabet_flash_data, assabet_flash_resources, sa11x0_register_mtd(&assabet_flash_data, assabet_flash_resources,
ARRAY_SIZE(assabet_flash_resources)); ARRAY_SIZE(assabet_flash_resources));
sa11x0_register_irda(&assabet_irda_data); sa11x0_register_irda(&assabet_irda_data);
......
...@@ -28,6 +28,8 @@ ...@@ -28,6 +28,8 @@
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/pda_power.h> #include <linux/pda_power.h>
#include <video/sa1100fb.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/irq.h> #include <asm/irq.h>
...@@ -294,6 +296,20 @@ static struct resource collie_flash_resources[] = { ...@@ -294,6 +296,20 @@ static struct resource collie_flash_resources[] = {
DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M), DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M),
}; };
static struct sa1100fb_mach_info collie_lcd_info = {
.pixclock = 171521, .bpp = 16,
.xres = 320, .yres = 240,
.hsync_len = 5, .vsync_len = 1,
.left_margin = 11, .upper_margin = 2,
.right_margin = 30, .lower_margin = 0,
.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
.lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
.lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
};
static void __init collie_init(void) static void __init collie_init(void)
{ {
int ret = 0; int ret = 0;
...@@ -332,6 +348,7 @@ static void __init collie_init(void) ...@@ -332,6 +348,7 @@ static void __init collie_init(void)
printk(KERN_WARNING "collie: Unable to register LoCoMo device\n"); printk(KERN_WARNING "collie: Unable to register LoCoMo device\n");
} }
sa11x0_register_lcd(&collie_lcd_info);
sa11x0_register_mtd(&collie_flash_data, collie_flash_resources, sa11x0_register_mtd(&collie_flash_data, collie_flash_resources,
ARRAY_SIZE(collie_flash_resources)); ARRAY_SIZE(collie_flash_resources));
sa11x0_register_mcp(&collie_mcp_data); sa11x0_register_mcp(&collie_mcp_data);
......
...@@ -20,6 +20,8 @@ ...@@ -20,6 +20,8 @@
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <video/sa1100fb.h>
#include <asm/div64.h> #include <asm/div64.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <asm/system.h> #include <asm/system.h>
...@@ -247,6 +249,11 @@ static struct platform_device sa11x0fb_device = { ...@@ -247,6 +249,11 @@ static struct platform_device sa11x0fb_device = {
.resource = sa11x0fb_resources, .resource = sa11x0fb_resources,
}; };
void sa11x0_register_lcd(struct sa1100fb_mach_info *inf)
{
sa11x0_register_device(&sa11x0fb_device, inf);
}
static struct platform_device sa11x0pcmcia_device = { static struct platform_device sa11x0pcmcia_device = {
.name = "sa11x0-pcmcia", .name = "sa11x0-pcmcia",
.id = -1, .id = -1,
...@@ -319,7 +326,6 @@ static struct platform_device *sa11x0_devices[] __initdata = { ...@@ -319,7 +326,6 @@ static struct platform_device *sa11x0_devices[] __initdata = {
&sa11x0uart3_device, &sa11x0uart3_device,
&sa11x0ssp_device, &sa11x0ssp_device,
&sa11x0pcmcia_device, &sa11x0pcmcia_device,
&sa11x0fb_device,
&sa11x0rtc_device, &sa11x0rtc_device,
&sa11x0dma_device, &sa11x0dma_device,
}; };
...@@ -332,12 +338,6 @@ static int __init sa1100_init(void) ...@@ -332,12 +338,6 @@ static int __init sa1100_init(void)
arch_initcall(sa1100_init); arch_initcall(sa1100_init);
void (*sa1100fb_backlight_power)(int on);
void (*sa1100fb_lcd_power)(int on);
EXPORT_SYMBOL(sa1100fb_backlight_power);
EXPORT_SYMBOL(sa1100fb_lcd_power);
/* /*
* Common I/O mapping: * Common I/O mapping:
......
...@@ -16,9 +16,6 @@ extern void sa11x0_restart(char, const char *); ...@@ -16,9 +16,6 @@ extern void sa11x0_restart(char, const char *);
mi->bank[__nr].start = (__start), \ mi->bank[__nr].start = (__start), \
mi->bank[__nr].size = (__size) mi->bank[__nr].size = (__size)
extern void (*sa1100fb_backlight_power)(int on);
extern void (*sa1100fb_lcd_power)(int on);
extern void sa1110_mb_enable(void); extern void sa1110_mb_enable(void);
extern void sa1110_mb_disable(void); extern void sa1110_mb_disable(void);
...@@ -40,3 +37,6 @@ void sa11x0_register_irda(struct irda_platform_data *irda); ...@@ -40,3 +37,6 @@ void sa11x0_register_irda(struct irda_platform_data *irda);
struct mcp_plat_data; struct mcp_plat_data;
void sa11x0_register_mcp(struct mcp_plat_data *data); void sa11x0_register_mcp(struct mcp_plat_data *data);
struct sa1100fb_mach_info;
void sa11x0_register_lcd(struct sa1100fb_mach_info *inf);
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <video/sa1100fb.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
#include <asm/mach/irda.h> #include <asm/mach/irda.h>
...@@ -36,13 +38,28 @@ static void h3100_lcd_power(int enable) ...@@ -36,13 +38,28 @@ static void h3100_lcd_power(int enable)
} }
} }
static struct sa1100fb_mach_info h3100_lcd_info = {
.pixclock = 406977, .bpp = 4,
.xres = 320, .yres = 240,
.hsync_len = 26, .vsync_len = 41,
.left_margin = 4, .upper_margin = 0,
.right_margin = 4, .lower_margin = 0,
.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
.cmap_greyscale = 1,
.cmap_inverse = 1,
.lccr0 = LCCR0_Mono | LCCR0_4PixMono | LCCR0_Sngl | LCCR0_Pas,
.lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
.lcd_power = h3100_lcd_power,
};
static void __init h3100_map_io(void) static void __init h3100_map_io(void)
{ {
h3xxx_map_io(); h3xxx_map_io();
sa1100fb_lcd_power = h3100_lcd_power;
/* Older bootldrs put GPIO2-9 in alternate mode on the /* Older bootldrs put GPIO2-9 in alternate mode on the
assumption that they are used for video */ assumption that they are used for video */
GAFR &= ~0x000001fb; GAFR &= ~0x000001fb;
...@@ -80,6 +97,8 @@ static void __init h3100_mach_init(void) ...@@ -80,6 +97,8 @@ static void __init h3100_mach_init(void)
{ {
h3xxx_init_gpio(h3100_default_gpio, ARRAY_SIZE(h3100_default_gpio)); h3xxx_init_gpio(h3100_default_gpio, ARRAY_SIZE(h3100_default_gpio));
h3xxx_mach_init(); h3xxx_mach_init();
sa11x0_register_lcd(&h3100_lcd_info);
sa11x0_register_irda(&h3100_irda_data); sa11x0_register_irda(&h3100_irda_data);
} }
......
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <video/sa1100fb.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
#include <asm/mach/irda.h> #include <asm/mach/irda.h>
...@@ -56,11 +58,35 @@ err2: gpio_free(H3XXX_EGPIO_LCD_ON); ...@@ -56,11 +58,35 @@ err2: gpio_free(H3XXX_EGPIO_LCD_ON);
err1: return; err1: return;
} }
static const struct sa1100fb_rgb h3600_rgb_16 = {
.red = { .offset = 12, .length = 4, },
.green = { .offset = 7, .length = 4, },
.blue = { .offset = 1, .length = 4, },
.transp = { .offset = 0, .length = 0, },
};
static struct sa1100fb_mach_info h3600_lcd_info = {
.pixclock = 174757, .bpp = 16,
.xres = 320, .yres = 240,
.hsync_len = 3, .vsync_len = 3,
.left_margin = 12, .upper_margin = 10,
.right_margin = 17, .lower_margin = 1,
.cmap_static = 1,
.lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
.lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
.rgb[RGB_16] = &h3600_rgb_16,
.lcd_power = h3600_lcd_power,
};
static void __init h3600_map_io(void) static void __init h3600_map_io(void)
{ {
h3xxx_map_io(); h3xxx_map_io();
sa1100fb_lcd_power = h3600_lcd_power;
} }
/* /*
...@@ -121,6 +147,8 @@ static void __init h3600_mach_init(void) ...@@ -121,6 +147,8 @@ static void __init h3600_mach_init(void)
{ {
h3xxx_init_gpio(h3600_default_gpio, ARRAY_SIZE(h3600_default_gpio)); h3xxx_init_gpio(h3600_default_gpio, ARRAY_SIZE(h3600_default_gpio));
h3xxx_mach_init(); h3xxx_mach_init();
sa11x0_register_lcd(&h3600_lcd_info);
sa11x0_register_irda(&h3600_irda_data); sa11x0_register_irda(&h3600_irda_data);
} }
......
...@@ -1688,16 +1688,6 @@ ...@@ -1688,16 +1688,6 @@
#define LCD_Int100_0A 0xF /* LCD Intensity = 100.0% = 1 */ #define LCD_Int100_0A 0xF /* LCD Intensity = 100.0% = 1 */
/* (Alternative) */ /* (Alternative) */
#define LCCR0 __REG(0xB0100000) /* LCD Control Reg. 0 */
#define LCSR __REG(0xB0100004) /* LCD Status Reg. */
#define DBAR1 __REG(0xB0100010) /* LCD DMA Base Address Reg. channel 1 */
#define DCAR1 __REG(0xB0100014) /* LCD DMA Current Address Reg. channel 1 */
#define DBAR2 __REG(0xB0100018) /* LCD DMA Base Address Reg. channel 2 */
#define DCAR2 __REG(0xB010001C) /* LCD DMA Current Address Reg. channel 2 */
#define LCCR1 __REG(0xB0100020) /* LCD Control Reg. 1 */
#define LCCR2 __REG(0xB0100024) /* LCD Control Reg. 2 */
#define LCCR3 __REG(0xB0100028) /* LCD Control Reg. 3 */
#define LCCR0_LEN 0x00000001 /* LCD ENable */ #define LCCR0_LEN 0x00000001 /* LCD ENable */
#define LCCR0_CMS 0x00000002 /* Color/Monochrome display Select */ #define LCCR0_CMS 0x00000002 /* Color/Monochrome display Select */
#define LCCR0_Color (LCCR0_CMS*0) /* Color display */ #define LCCR0_Color (LCCR0_CMS*0) /* Color display */
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
#define SHANNON_GPIO_U3_RTS GPIO_GPIO (19) /* ?? */ #define SHANNON_GPIO_U3_RTS GPIO_GPIO (19) /* ?? */
#define SHANNON_GPIO_U3_CTS GPIO_GPIO (20) /* ?? */ #define SHANNON_GPIO_U3_CTS GPIO_GPIO (20) /* ?? */
#define SHANNON_GPIO_SENSE_12V GPIO_GPIO (21) /* Input, 12v flash unprotect detected */ #define SHANNON_GPIO_SENSE_12V GPIO_GPIO (21) /* Input, 12v flash unprotect detected */
#define SHANNON_GPIO_DISP_EN GPIO_GPIO (22) /* out */ #define SHANNON_GPIO_DISP_EN 22 /* out */
/* XXX GPIO 23 unaccounted for */ /* XXX GPIO 23 unaccounted for */
#define SHANNON_GPIO_EJECT_0 GPIO_GPIO (24) /* in */ #define SHANNON_GPIO_EJECT_0 GPIO_GPIO (24) /* in */
#define SHANNON_IRQ_GPIO_EJECT_0 IRQ_GPIO24 #define SHANNON_IRQ_GPIO_EJECT_0 IRQ_GPIO24
......
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/tty.h> #include <linux/tty.h>
#include <video/sa1100fb.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
...@@ -26,8 +28,85 @@ static struct mcp_plat_data lart_mcp_data = { ...@@ -26,8 +28,85 @@ static struct mcp_plat_data lart_mcp_data = {
.sclk_rate = 11981000, .sclk_rate = 11981000,
}; };
#ifdef LART_GREY_LCD
static struct sa1100fb_mach_info lart_grey_info = {
.pixclock = 150000, .bpp = 4,
.xres = 320, .yres = 240,
.hsync_len = 1, .vsync_len = 1,
.left_margin = 4, .upper_margin = 0,
.right_margin = 2, .lower_margin = 0,
.cmap_greyscale = 1,
.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
.lccr0 = LCCR0_Mono | LCCR0_Sngl | LCCR0_Pas | LCCR0_4PixMono,
.lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(512),
};
#endif
#ifdef LART_COLOR_LCD
static struct sa1100fb_mach_info lart_color_info = {
.pixclock = 150000, .bpp = 16,
.xres = 320, .yres = 240,
.hsync_len = 2, .vsync_len = 3,
.left_margin = 69, .upper_margin = 14,
.right_margin = 8, .lower_margin = 4,
.lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
.lccr3 = LCCR3_OutEnH | LCCR3_PixFlEdg | LCCR3_ACBsDiv(512),
};
#endif
#ifdef LART_VIDEO_OUT
static struct sa1100fb_mach_info lart_video_info = {
.pixclock = 39721, .bpp = 16,
.xres = 640, .yres = 480,
.hsync_len = 95, .vsync_len = 2,
.left_margin = 40, .upper_margin = 32,
.right_margin = 24, .lower_margin = 11,
.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
.lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
.lccr3 = LCCR3_OutEnL | LCCR3_PixFlEdg | LCCR3_ACBsDiv(512),
};
#endif
#ifdef LART_KIT01_LCD
static struct sa1100fb_mach_info lart_kit01_info = {
.pixclock = 63291, .bpp = 16,
.xres = 640, .yres = 480,
.hsync_len = 64, .vsync_len = 3,
.left_margin = 122, .upper_margin = 45,
.right_margin = 10, .lower_margin = 10,
.lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
.lccr3 = LCCR3_OutEnH | LCCR3_PixFlEdg
};
#endif
static void __init lart_init(void) static void __init lart_init(void)
{ {
struct sa1100fb_mach_info *inf = NULL;
#ifdef LART_GREY_LCD
inf = &lart_grey_info;
#endif
#ifdef LART_COLOR_LCD
inf = &lart_color_info;
#endif
#ifdef LART_VIDEO_OUT
inf = &lart_video_info;
#endif
#ifdef LART_KIT01_LCD
inf = &lart_kit01_info;
#endif
if (inf)
sa11x0_register_lcd(inf);
sa11x0_register_mcp(&lart_mcp_data); sa11x0_register_mcp(&lart_mcp_data);
} }
......
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h> #include <linux/mtd/partitions.h>
#include <video/sa1100fb.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/setup.h> #include <asm/setup.h>
...@@ -54,8 +56,23 @@ static struct mcp_plat_data shannon_mcp_data = { ...@@ -54,8 +56,23 @@ static struct mcp_plat_data shannon_mcp_data = {
.sclk_rate = 11981000, .sclk_rate = 11981000,
}; };
static struct sa1100fb_mach_info shannon_lcd_info = {
.pixclock = 152500, .bpp = 8,
.xres = 640, .yres = 480,
.hsync_len = 4, .vsync_len = 3,
.left_margin = 2, .upper_margin = 0,
.right_margin = 1, .lower_margin = 0,
.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
.lccr0 = LCCR0_Color | LCCR0_Dual | LCCR0_Pas,
.lccr3 = LCCR3_ACBsDiv(512),
};
static void __init shannon_init(void) static void __init shannon_init(void)
{ {
sa11x0_register_lcd(&shannon_lcd_info);
sa11x0_register_mtd(&shannon_flash_data, &shannon_flash_resource, 1); sa11x0_register_mtd(&shannon_flash_data, &shannon_flash_resource, 1);
sa11x0_register_mcp(&shannon_mcp_data); sa11x0_register_mcp(&shannon_mcp_data);
} }
......
...@@ -173,282 +173,48 @@ ...@@ -173,282 +173,48 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/cpufreq.h> #include <linux/cpufreq.h>
#include <linux/gpio.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/io.h> #include <linux/io.h>
#include <video/sa1100fb.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <mach/assabet.h>
#include <mach/shannon.h> #include <mach/shannon.h>
/*
* debugging?
*/
#define DEBUG 0
/* /*
* Complain if VAR is out of range. * Complain if VAR is out of range.
*/ */
#define DEBUG_VAR 1 #define DEBUG_VAR 1
#undef ASSABET_PAL_VIDEO
#include "sa1100fb.h" #include "sa1100fb.h"
extern void (*sa1100fb_backlight_power)(int on); static const struct sa1100fb_rgb rgb_4 = {
extern void (*sa1100fb_lcd_power)(int on);
static struct sa1100fb_rgb rgb_4 = {
.red = { .offset = 0, .length = 4, }, .red = { .offset = 0, .length = 4, },
.green = { .offset = 0, .length = 4, }, .green = { .offset = 0, .length = 4, },
.blue = { .offset = 0, .length = 4, }, .blue = { .offset = 0, .length = 4, },
.transp = { .offset = 0, .length = 0, }, .transp = { .offset = 0, .length = 0, },
}; };
static struct sa1100fb_rgb rgb_8 = { static const struct sa1100fb_rgb rgb_8 = {
.red = { .offset = 0, .length = 8, }, .red = { .offset = 0, .length = 8, },
.green = { .offset = 0, .length = 8, }, .green = { .offset = 0, .length = 8, },
.blue = { .offset = 0, .length = 8, }, .blue = { .offset = 0, .length = 8, },
.transp = { .offset = 0, .length = 0, }, .transp = { .offset = 0, .length = 0, },
}; };
static struct sa1100fb_rgb def_rgb_16 = { static const struct sa1100fb_rgb def_rgb_16 = {
.red = { .offset = 11, .length = 5, }, .red = { .offset = 11, .length = 5, },
.green = { .offset = 5, .length = 6, }, .green = { .offset = 5, .length = 6, },
.blue = { .offset = 0, .length = 5, }, .blue = { .offset = 0, .length = 5, },
.transp = { .offset = 0, .length = 0, }, .transp = { .offset = 0, .length = 0, },
}; };
#ifdef CONFIG_SA1100_ASSABET
#ifndef ASSABET_PAL_VIDEO
/*
* The assabet uses a sharp LQ039Q2DS54 LCD module. It is actually
* takes an RGB666 signal, but we provide it with an RGB565 signal
* instead (def_rgb_16).
*/
static struct sa1100fb_mach_info lq039q2ds54_info __initdata = {
.pixclock = 171521, .bpp = 16,
.xres = 320, .yres = 240,
.hsync_len = 5, .vsync_len = 1,
.left_margin = 61, .upper_margin = 3,
.right_margin = 9, .lower_margin = 0,
.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
.lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
.lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
};
#else
static struct sa1100fb_mach_info pal_info __initdata = {
.pixclock = 67797, .bpp = 16,
.xres = 640, .yres = 512,
.hsync_len = 64, .vsync_len = 6,
.left_margin = 125, .upper_margin = 70,
.right_margin = 115, .lower_margin = 36,
.lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
.lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(512),
};
#endif
#endif
#ifdef CONFIG_SA1100_H3600
static struct sa1100fb_mach_info h3600_info __initdata = {
.pixclock = 174757, .bpp = 16,
.xres = 320, .yres = 240,
.hsync_len = 3, .vsync_len = 3,
.left_margin = 12, .upper_margin = 10,
.right_margin = 17, .lower_margin = 1,
.cmap_static = 1,
.lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
.lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
};
static struct sa1100fb_rgb h3600_rgb_16 = {
.red = { .offset = 12, .length = 4, },
.green = { .offset = 7, .length = 4, },
.blue = { .offset = 1, .length = 4, },
.transp = { .offset = 0, .length = 0, },
};
#endif
#ifdef CONFIG_SA1100_H3100
static struct sa1100fb_mach_info h3100_info __initdata = {
.pixclock = 406977, .bpp = 4,
.xres = 320, .yres = 240,
.hsync_len = 26, .vsync_len = 41,
.left_margin = 4, .upper_margin = 0,
.right_margin = 4, .lower_margin = 0,
.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
.cmap_greyscale = 1,
.cmap_inverse = 1,
.lccr0 = LCCR0_Mono | LCCR0_4PixMono | LCCR0_Sngl | LCCR0_Pas,
.lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
};
#endif
#ifdef CONFIG_SA1100_COLLIE
static struct sa1100fb_mach_info collie_info __initdata = {
.pixclock = 171521, .bpp = 16,
.xres = 320, .yres = 240,
.hsync_len = 5, .vsync_len = 1,
.left_margin = 11, .upper_margin = 2,
.right_margin = 30, .lower_margin = 0,
.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
.lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
.lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
};
#endif
#ifdef LART_GREY_LCD
static struct sa1100fb_mach_info lart_grey_info __initdata = {
.pixclock = 150000, .bpp = 4,
.xres = 320, .yres = 240,
.hsync_len = 1, .vsync_len = 1,
.left_margin = 4, .upper_margin = 0,
.right_margin = 2, .lower_margin = 0,
.cmap_greyscale = 1,
.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
.lccr0 = LCCR0_Mono | LCCR0_Sngl | LCCR0_Pas | LCCR0_4PixMono,
.lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(512),
};
#endif
#ifdef LART_COLOR_LCD
static struct sa1100fb_mach_info lart_color_info __initdata = {
.pixclock = 150000, .bpp = 16,
.xres = 320, .yres = 240,
.hsync_len = 2, .vsync_len = 3,
.left_margin = 69, .upper_margin = 14,
.right_margin = 8, .lower_margin = 4,
.lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
.lccr3 = LCCR3_OutEnH | LCCR3_PixFlEdg | LCCR3_ACBsDiv(512),
};
#endif
#ifdef LART_VIDEO_OUT
static struct sa1100fb_mach_info lart_video_info __initdata = {
.pixclock = 39721, .bpp = 16,
.xres = 640, .yres = 480,
.hsync_len = 95, .vsync_len = 2,
.left_margin = 40, .upper_margin = 32,
.right_margin = 24, .lower_margin = 11,
.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
.lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
.lccr3 = LCCR3_OutEnL | LCCR3_PixFlEdg | LCCR3_ACBsDiv(512),
};
#endif
#ifdef LART_KIT01_LCD
static struct sa1100fb_mach_info lart_kit01_info __initdata = {
.pixclock = 63291, .bpp = 16,
.xres = 640, .yres = 480,
.hsync_len = 64, .vsync_len = 3,
.left_margin = 122, .upper_margin = 45,
.right_margin = 10, .lower_margin = 10,
.lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
.lccr3 = LCCR3_OutEnH | LCCR3_PixFlEdg
};
#endif
#ifdef CONFIG_SA1100_SHANNON
static struct sa1100fb_mach_info shannon_info __initdata = {
.pixclock = 152500, .bpp = 8,
.xres = 640, .yres = 480,
.hsync_len = 4, .vsync_len = 3,
.left_margin = 2, .upper_margin = 0,
.right_margin = 1, .lower_margin = 0,
.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
.lccr0 = LCCR0_Color | LCCR0_Dual | LCCR0_Pas,
.lccr3 = LCCR3_ACBsDiv(512),
};
#endif
static struct sa1100fb_mach_info * __init
sa1100fb_get_machine_info(struct sa1100fb_info *fbi)
{
struct sa1100fb_mach_info *inf = NULL;
/*
* R G B T
* default {11,5}, { 5,6}, { 0,5}, { 0,0}
* h3600 {12,4}, { 7,4}, { 1,4}, { 0,0}
* freebird { 8,4}, { 4,4}, { 0,4}, {12,4}
*/
#ifdef CONFIG_SA1100_ASSABET
if (machine_is_assabet()) {
#ifndef ASSABET_PAL_VIDEO
inf = &lq039q2ds54_info;
#else
inf = &pal_info;
#endif
}
#endif
#ifdef CONFIG_SA1100_H3100
if (machine_is_h3100()) {
inf = &h3100_info;
}
#endif
#ifdef CONFIG_SA1100_H3600
if (machine_is_h3600()) {
inf = &h3600_info;
fbi->rgb[RGB_16] = &h3600_rgb_16;
}
#endif
#ifdef CONFIG_SA1100_COLLIE
if (machine_is_collie()) {
inf = &collie_info;
}
#endif
#ifdef CONFIG_SA1100_LART
if (machine_is_lart()) {
#ifdef LART_GREY_LCD
inf = &lart_grey_info;
#endif
#ifdef LART_COLOR_LCD
inf = &lart_color_info;
#endif
#ifdef LART_VIDEO_OUT
inf = &lart_video_info;
#endif
#ifdef LART_KIT01_LCD
inf = &lart_kit01_info;
#endif
}
#endif
#ifdef CONFIG_SA1100_SHANNON
if (machine_is_shannon()) {
inf = &shannon_info;
}
#endif
return inf;
}
static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct sa1100fb_info *); static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct sa1100fb_info *);
static void set_ctrlr_state(struct sa1100fb_info *fbi, u_int state); static void set_ctrlr_state(struct sa1100fb_info *fbi, u_int state);
...@@ -533,7 +299,7 @@ sa1100fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, ...@@ -533,7 +299,7 @@ sa1100fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
* is what you poke into the framebuffer to produce the * is what you poke into the framebuffer to produce the
* colour you requested. * colour you requested.
*/ */
if (fbi->cmap_inverse) { if (fbi->inf->cmap_inverse) {
red = 0xffff - red; red = 0xffff - red;
green = 0xffff - green; green = 0xffff - green;
blue = 0xffff - blue; blue = 0xffff - blue;
...@@ -607,14 +373,14 @@ sa1100fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) ...@@ -607,14 +373,14 @@ sa1100fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
var->xres = MIN_XRES; var->xres = MIN_XRES;
if (var->yres < MIN_YRES) if (var->yres < MIN_YRES)
var->yres = MIN_YRES; var->yres = MIN_YRES;
if (var->xres > fbi->max_xres) if (var->xres > fbi->inf->xres)
var->xres = fbi->max_xres; var->xres = fbi->inf->xres;
if (var->yres > fbi->max_yres) if (var->yres > fbi->inf->yres)
var->yres = fbi->max_yres; var->yres = fbi->inf->yres;
var->xres_virtual = max(var->xres_virtual, var->xres); var->xres_virtual = max(var->xres_virtual, var->xres);
var->yres_virtual = max(var->yres_virtual, var->yres); var->yres_virtual = max(var->yres_virtual, var->yres);
DPRINTK("var->bits_per_pixel=%d\n", var->bits_per_pixel); dev_dbg(fbi->dev, "var->bits_per_pixel=%d\n", var->bits_per_pixel);
switch (var->bits_per_pixel) { switch (var->bits_per_pixel) {
case 4: case 4:
rgbidx = RGB_4; rgbidx = RGB_4;
...@@ -638,16 +404,16 @@ sa1100fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) ...@@ -638,16 +404,16 @@ sa1100fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
var->blue = fbi->rgb[rgbidx]->blue; var->blue = fbi->rgb[rgbidx]->blue;
var->transp = fbi->rgb[rgbidx]->transp; var->transp = fbi->rgb[rgbidx]->transp;
DPRINTK("RGBT length = %d:%d:%d:%d\n", dev_dbg(fbi->dev, "RGBT length = %d:%d:%d:%d\n",
var->red.length, var->green.length, var->blue.length, var->red.length, var->green.length, var->blue.length,
var->transp.length); var->transp.length);
DPRINTK("RGBT offset = %d:%d:%d:%d\n", dev_dbg(fbi->dev, "RGBT offset = %d:%d:%d:%d\n",
var->red.offset, var->green.offset, var->blue.offset, var->red.offset, var->green.offset, var->blue.offset,
var->transp.offset); var->transp.offset);
#ifdef CONFIG_CPU_FREQ #ifdef CONFIG_CPU_FREQ
printk(KERN_DEBUG "dma period = %d ps, clock = %d kHz\n", dev_dbg(fbi->dev, "dma period = %d ps, clock = %d kHz\n",
sa1100fb_display_dma_period(var), sa1100fb_display_dma_period(var),
cpufreq_get(smp_processor_id())); cpufreq_get(smp_processor_id()));
#endif #endif
...@@ -655,22 +421,10 @@ sa1100fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) ...@@ -655,22 +421,10 @@ sa1100fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
return 0; return 0;
} }
static inline void sa1100fb_set_truecolor(u_int is_true_color) static void sa1100fb_set_visual(struct sa1100fb_info *fbi, u32 visual)
{ {
if (machine_is_assabet()) { if (fbi->inf->set_visual)
#if 1 // phase 4 or newer Assabet's fbi->inf->set_visual(visual);
if (is_true_color)
ASSABET_BCR_set(ASSABET_BCR_LCD_12RGB);
else
ASSABET_BCR_clear(ASSABET_BCR_LCD_12RGB);
#else
// older Assabet's
if (is_true_color)
ASSABET_BCR_clear(ASSABET_BCR_LCD_12RGB);
else
ASSABET_BCR_set(ASSABET_BCR_LCD_12RGB);
#endif
}
} }
/* /*
...@@ -683,11 +437,11 @@ static int sa1100fb_set_par(struct fb_info *info) ...@@ -683,11 +437,11 @@ static int sa1100fb_set_par(struct fb_info *info)
struct fb_var_screeninfo *var = &info->var; struct fb_var_screeninfo *var = &info->var;
unsigned long palette_mem_size; unsigned long palette_mem_size;
DPRINTK("set_par\n"); dev_dbg(fbi->dev, "set_par\n");
if (var->bits_per_pixel == 16) if (var->bits_per_pixel == 16)
fbi->fb.fix.visual = FB_VISUAL_TRUECOLOR; fbi->fb.fix.visual = FB_VISUAL_TRUECOLOR;
else if (!fbi->cmap_static) else if (!fbi->inf->cmap_static)
fbi->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR; fbi->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR;
else { else {
/* /*
...@@ -704,7 +458,7 @@ static int sa1100fb_set_par(struct fb_info *info) ...@@ -704,7 +458,7 @@ static int sa1100fb_set_par(struct fb_info *info)
palette_mem_size = fbi->palette_size * sizeof(u16); palette_mem_size = fbi->palette_size * sizeof(u16);
DPRINTK("palette_mem_size = 0x%08lx\n", (u_long) palette_mem_size); dev_dbg(fbi->dev, "palette_mem_size = 0x%08lx\n", palette_mem_size);
fbi->palette_cpu = (u16 *)(fbi->map_cpu + PAGE_SIZE - palette_mem_size); fbi->palette_cpu = (u16 *)(fbi->map_cpu + PAGE_SIZE - palette_mem_size);
fbi->palette_dma = fbi->map_dma + PAGE_SIZE - palette_mem_size; fbi->palette_dma = fbi->map_dma + PAGE_SIZE - palette_mem_size;
...@@ -712,7 +466,7 @@ static int sa1100fb_set_par(struct fb_info *info) ...@@ -712,7 +466,7 @@ static int sa1100fb_set_par(struct fb_info *info)
/* /*
* Set (any) board control register to handle new color depth * Set (any) board control register to handle new color depth
*/ */
sa1100fb_set_truecolor(fbi->fb.fix.visual == FB_VISUAL_TRUECOLOR); sa1100fb_set_visual(fbi, fbi->fb.fix.visual);
sa1100fb_activate_var(var, fbi); sa1100fb_activate_var(var, fbi);
return 0; return 0;
...@@ -728,7 +482,7 @@ sa1100fb_set_cmap(struct fb_cmap *cmap, int kspc, int con, ...@@ -728,7 +482,7 @@ sa1100fb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
/* /*
* Make sure the user isn't doing something stupid. * Make sure the user isn't doing something stupid.
*/ */
if (!kspc && (fbi->fb.var.bits_per_pixel == 16 || fbi->cmap_static)) if (!kspc && (fbi->fb.var.bits_per_pixel == 16 || fbi->inf->cmap_static))
return -EINVAL; return -EINVAL;
return gen_set_cmap(cmap, kspc, con, info); return gen_set_cmap(cmap, kspc, con, info);
...@@ -775,7 +529,7 @@ static int sa1100fb_blank(int blank, struct fb_info *info) ...@@ -775,7 +529,7 @@ static int sa1100fb_blank(int blank, struct fb_info *info)
struct sa1100fb_info *fbi = (struct sa1100fb_info *)info; struct sa1100fb_info *fbi = (struct sa1100fb_info *)info;
int i; int i;
DPRINTK("sa1100fb_blank: blank=%d\n", blank); dev_dbg(fbi->dev, "sa1100fb_blank: blank=%d\n", blank);
switch (blank) { switch (blank) {
case FB_BLANK_POWERDOWN: case FB_BLANK_POWERDOWN:
...@@ -863,43 +617,43 @@ static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct sa1100fb_ ...@@ -863,43 +617,43 @@ static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct sa1100fb_
u_int half_screen_size, yres, pcd; u_int half_screen_size, yres, pcd;
u_long flags; u_long flags;
DPRINTK("Configuring SA1100 LCD\n"); dev_dbg(fbi->dev, "Configuring SA1100 LCD\n");
DPRINTK("var: xres=%d hslen=%d lm=%d rm=%d\n", dev_dbg(fbi->dev, "var: xres=%d hslen=%d lm=%d rm=%d\n",
var->xres, var->hsync_len, var->xres, var->hsync_len,
var->left_margin, var->right_margin); var->left_margin, var->right_margin);
DPRINTK("var: yres=%d vslen=%d um=%d bm=%d\n", dev_dbg(fbi->dev, "var: yres=%d vslen=%d um=%d bm=%d\n",
var->yres, var->vsync_len, var->yres, var->vsync_len,
var->upper_margin, var->lower_margin); var->upper_margin, var->lower_margin);
#if DEBUG_VAR #if DEBUG_VAR
if (var->xres < 16 || var->xres > 1024) if (var->xres < 16 || var->xres > 1024)
printk(KERN_ERR "%s: invalid xres %d\n", dev_err(fbi->dev, "%s: invalid xres %d\n",
fbi->fb.fix.id, var->xres); fbi->fb.fix.id, var->xres);
if (var->hsync_len < 1 || var->hsync_len > 64) if (var->hsync_len < 1 || var->hsync_len > 64)
printk(KERN_ERR "%s: invalid hsync_len %d\n", dev_err(fbi->dev, "%s: invalid hsync_len %d\n",
fbi->fb.fix.id, var->hsync_len); fbi->fb.fix.id, var->hsync_len);
if (var->left_margin < 1 || var->left_margin > 255) if (var->left_margin < 1 || var->left_margin > 255)
printk(KERN_ERR "%s: invalid left_margin %d\n", dev_err(fbi->dev, "%s: invalid left_margin %d\n",
fbi->fb.fix.id, var->left_margin); fbi->fb.fix.id, var->left_margin);
if (var->right_margin < 1 || var->right_margin > 255) if (var->right_margin < 1 || var->right_margin > 255)
printk(KERN_ERR "%s: invalid right_margin %d\n", dev_err(fbi->dev, "%s: invalid right_margin %d\n",
fbi->fb.fix.id, var->right_margin); fbi->fb.fix.id, var->right_margin);
if (var->yres < 1 || var->yres > 1024) if (var->yres < 1 || var->yres > 1024)
printk(KERN_ERR "%s: invalid yres %d\n", dev_err(fbi->dev, "%s: invalid yres %d\n",
fbi->fb.fix.id, var->yres); fbi->fb.fix.id, var->yres);
if (var->vsync_len < 1 || var->vsync_len > 64) if (var->vsync_len < 1 || var->vsync_len > 64)
printk(KERN_ERR "%s: invalid vsync_len %d\n", dev_err(fbi->dev, "%s: invalid vsync_len %d\n",
fbi->fb.fix.id, var->vsync_len); fbi->fb.fix.id, var->vsync_len);
if (var->upper_margin < 0 || var->upper_margin > 255) if (var->upper_margin < 0 || var->upper_margin > 255)
printk(KERN_ERR "%s: invalid upper_margin %d\n", dev_err(fbi->dev, "%s: invalid upper_margin %d\n",
fbi->fb.fix.id, var->upper_margin); fbi->fb.fix.id, var->upper_margin);
if (var->lower_margin < 0 || var->lower_margin > 255) if (var->lower_margin < 0 || var->lower_margin > 255)
printk(KERN_ERR "%s: invalid lower_margin %d\n", dev_err(fbi->dev, "%s: invalid lower_margin %d\n",
fbi->fb.fix.id, var->lower_margin); fbi->fb.fix.id, var->lower_margin);
#endif #endif
new_regs.lccr0 = fbi->lccr0 | new_regs.lccr0 = fbi->inf->lccr0 |
LCCR0_LEN | LCCR0_LDM | LCCR0_BAM | LCCR0_LEN | LCCR0_LDM | LCCR0_BAM |
LCCR0_ERM | LCCR0_LtlEnd | LCCR0_DMADel(0); LCCR0_ERM | LCCR0_LtlEnd | LCCR0_DMADel(0);
...@@ -914,7 +668,7 @@ static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct sa1100fb_ ...@@ -914,7 +668,7 @@ static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct sa1100fb_
* the YRES parameter. * the YRES parameter.
*/ */
yres = var->yres; yres = var->yres;
if (fbi->lccr0 & LCCR0_Dual) if (fbi->inf->lccr0 & LCCR0_Dual)
yres /= 2; yres /= 2;
new_regs.lccr2 = new_regs.lccr2 =
...@@ -924,14 +678,14 @@ static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct sa1100fb_ ...@@ -924,14 +678,14 @@ static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct sa1100fb_
LCCR2_EndFrmDel(var->lower_margin); LCCR2_EndFrmDel(var->lower_margin);
pcd = get_pcd(var->pixclock, cpufreq_get(0)); pcd = get_pcd(var->pixclock, cpufreq_get(0));
new_regs.lccr3 = LCCR3_PixClkDiv(pcd) | fbi->lccr3 | new_regs.lccr3 = LCCR3_PixClkDiv(pcd) | fbi->inf->lccr3 |
(var->sync & FB_SYNC_HOR_HIGH_ACT ? LCCR3_HorSnchH : LCCR3_HorSnchL) | (var->sync & FB_SYNC_HOR_HIGH_ACT ? LCCR3_HorSnchH : LCCR3_HorSnchL) |
(var->sync & FB_SYNC_VERT_HIGH_ACT ? LCCR3_VrtSnchH : LCCR3_VrtSnchL); (var->sync & FB_SYNC_VERT_HIGH_ACT ? LCCR3_VrtSnchH : LCCR3_VrtSnchL);
DPRINTK("nlccr0 = 0x%08lx\n", new_regs.lccr0); dev_dbg(fbi->dev, "nlccr0 = 0x%08lx\n", new_regs.lccr0);
DPRINTK("nlccr1 = 0x%08lx\n", new_regs.lccr1); dev_dbg(fbi->dev, "nlccr1 = 0x%08lx\n", new_regs.lccr1);
DPRINTK("nlccr2 = 0x%08lx\n", new_regs.lccr2); dev_dbg(fbi->dev, "nlccr2 = 0x%08lx\n", new_regs.lccr2);
DPRINTK("nlccr3 = 0x%08lx\n", new_regs.lccr3); dev_dbg(fbi->dev, "nlccr3 = 0x%08lx\n", new_regs.lccr3);
half_screen_size = var->bits_per_pixel; half_screen_size = var->bits_per_pixel;
half_screen_size = half_screen_size * var->xres * var->yres / 16; half_screen_size = half_screen_size * var->xres * var->yres / 16;
...@@ -951,9 +705,12 @@ static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct sa1100fb_ ...@@ -951,9 +705,12 @@ static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct sa1100fb_
* Only update the registers if the controller is enabled * Only update the registers if the controller is enabled
* and something has changed. * and something has changed.
*/ */
if ((LCCR0 != fbi->reg_lccr0) || (LCCR1 != fbi->reg_lccr1) || if (readl_relaxed(fbi->base + LCCR0) != fbi->reg_lccr0 ||
(LCCR2 != fbi->reg_lccr2) || (LCCR3 != fbi->reg_lccr3) || readl_relaxed(fbi->base + LCCR1) != fbi->reg_lccr1 ||
(DBAR1 != fbi->dbar1) || (DBAR2 != fbi->dbar2)) readl_relaxed(fbi->base + LCCR2) != fbi->reg_lccr2 ||
readl_relaxed(fbi->base + LCCR3) != fbi->reg_lccr3 ||
readl_relaxed(fbi->base + DBAR1) != fbi->dbar1 ||
readl_relaxed(fbi->base + DBAR2) != fbi->dbar2)
sa1100fb_schedule_work(fbi, C_REENABLE); sa1100fb_schedule_work(fbi, C_REENABLE);
return 0; return 0;
...@@ -967,18 +724,18 @@ static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct sa1100fb_ ...@@ -967,18 +724,18 @@ static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct sa1100fb_
*/ */
static inline void __sa1100fb_backlight_power(struct sa1100fb_info *fbi, int on) static inline void __sa1100fb_backlight_power(struct sa1100fb_info *fbi, int on)
{ {
DPRINTK("backlight o%s\n", on ? "n" : "ff"); dev_dbg(fbi->dev, "backlight o%s\n", on ? "n" : "ff");
if (sa1100fb_backlight_power) if (fbi->inf->backlight_power)
sa1100fb_backlight_power(on); fbi->inf->backlight_power(on);
} }
static inline void __sa1100fb_lcd_power(struct sa1100fb_info *fbi, int on) static inline void __sa1100fb_lcd_power(struct sa1100fb_info *fbi, int on)
{ {
DPRINTK("LCD power o%s\n", on ? "n" : "ff"); dev_dbg(fbi->dev, "LCD power o%s\n", on ? "n" : "ff");
if (sa1100fb_lcd_power) if (fbi->inf->lcd_power)
sa1100fb_lcd_power(on); fbi->inf->lcd_power(on);
} }
static void sa1100fb_setup_gpio(struct sa1100fb_info *fbi) static void sa1100fb_setup_gpio(struct sa1100fb_info *fbi)
...@@ -1008,14 +765,25 @@ static void sa1100fb_setup_gpio(struct sa1100fb_info *fbi) ...@@ -1008,14 +765,25 @@ static void sa1100fb_setup_gpio(struct sa1100fb_info *fbi)
} }
if (mask) { if (mask) {
unsigned long flags;
/*
* SA-1100 requires the GPIO direction register set
* appropriately for the alternate function. Hence
* we set it here via bitmask rather than excessive
* fiddling via the GPIO subsystem - and even then
* we'll still have to deal with GAFR.
*/
local_irq_save(flags);
GPDR |= mask; GPDR |= mask;
GAFR |= mask; GAFR |= mask;
local_irq_restore(flags);
} }
} }
static void sa1100fb_enable_controller(struct sa1100fb_info *fbi) static void sa1100fb_enable_controller(struct sa1100fb_info *fbi)
{ {
DPRINTK("Enabling LCD controller\n"); dev_dbg(fbi->dev, "Enabling LCD controller\n");
/* /*
* Make sure the mode bits are present in the first palette entry * Make sure the mode bits are present in the first palette entry
...@@ -1024,43 +792,46 @@ static void sa1100fb_enable_controller(struct sa1100fb_info *fbi) ...@@ -1024,43 +792,46 @@ static void sa1100fb_enable_controller(struct sa1100fb_info *fbi)
fbi->palette_cpu[0] |= palette_pbs(&fbi->fb.var); fbi->palette_cpu[0] |= palette_pbs(&fbi->fb.var);
/* Sequence from 11.7.10 */ /* Sequence from 11.7.10 */
LCCR3 = fbi->reg_lccr3; writel_relaxed(fbi->reg_lccr3, fbi->base + LCCR3);
LCCR2 = fbi->reg_lccr2; writel_relaxed(fbi->reg_lccr2, fbi->base + LCCR2);
LCCR1 = fbi->reg_lccr1; writel_relaxed(fbi->reg_lccr1, fbi->base + LCCR1);
LCCR0 = fbi->reg_lccr0 & ~LCCR0_LEN; writel_relaxed(fbi->reg_lccr0 & ~LCCR0_LEN, fbi->base + LCCR0);
DBAR1 = fbi->dbar1; writel_relaxed(fbi->dbar1, fbi->base + DBAR1);
DBAR2 = fbi->dbar2; writel_relaxed(fbi->dbar2, fbi->base + DBAR2);
LCCR0 |= LCCR0_LEN; writel_relaxed(fbi->reg_lccr0 | LCCR0_LEN, fbi->base + LCCR0);
if (machine_is_shannon()) { if (machine_is_shannon())
GPDR |= SHANNON_GPIO_DISP_EN; gpio_set_value(SHANNON_GPIO_DISP_EN, 1);
GPSR |= SHANNON_GPIO_DISP_EN;
} dev_dbg(fbi->dev, "DBAR1: 0x%08x\n", readl_relaxed(fbi->base + DBAR1));
dev_dbg(fbi->dev, "DBAR2: 0x%08x\n", readl_relaxed(fbi->base + DBAR2));
DPRINTK("DBAR1 = 0x%08x\n", DBAR1); dev_dbg(fbi->dev, "LCCR0: 0x%08x\n", readl_relaxed(fbi->base + LCCR0));
DPRINTK("DBAR2 = 0x%08x\n", DBAR2); dev_dbg(fbi->dev, "LCCR1: 0x%08x\n", readl_relaxed(fbi->base + LCCR1));
DPRINTK("LCCR0 = 0x%08x\n", LCCR0); dev_dbg(fbi->dev, "LCCR2: 0x%08x\n", readl_relaxed(fbi->base + LCCR2));
DPRINTK("LCCR1 = 0x%08x\n", LCCR1); dev_dbg(fbi->dev, "LCCR3: 0x%08x\n", readl_relaxed(fbi->base + LCCR3));
DPRINTK("LCCR2 = 0x%08x\n", LCCR2);
DPRINTK("LCCR3 = 0x%08x\n", LCCR3);
} }
static void sa1100fb_disable_controller(struct sa1100fb_info *fbi) static void sa1100fb_disable_controller(struct sa1100fb_info *fbi)
{ {
DECLARE_WAITQUEUE(wait, current); DECLARE_WAITQUEUE(wait, current);
u32 lccr0;
DPRINTK("Disabling LCD controller\n"); dev_dbg(fbi->dev, "Disabling LCD controller\n");
if (machine_is_shannon()) { if (machine_is_shannon())
GPCR |= SHANNON_GPIO_DISP_EN; gpio_set_value(SHANNON_GPIO_DISP_EN, 0);
}
set_current_state(TASK_UNINTERRUPTIBLE); set_current_state(TASK_UNINTERRUPTIBLE);
add_wait_queue(&fbi->ctrlr_wait, &wait); add_wait_queue(&fbi->ctrlr_wait, &wait);
LCSR = 0xffffffff; /* Clear LCD Status Register */ /* Clear LCD Status Register */
LCCR0 &= ~LCCR0_LDM; /* Enable LCD Disable Done Interrupt */ writel_relaxed(~0, fbi->base + LCSR);
LCCR0 &= ~LCCR0_LEN; /* Disable LCD Controller */
lccr0 = readl_relaxed(fbi->base + LCCR0);
lccr0 &= ~LCCR0_LDM; /* Enable LCD Disable Done Interrupt */
writel_relaxed(lccr0, fbi->base + LCCR0);
lccr0 &= ~LCCR0_LEN; /* Disable LCD Controller */
writel_relaxed(lccr0, fbi->base + LCCR0);
schedule_timeout(20 * HZ / 1000); schedule_timeout(20 * HZ / 1000);
remove_wait_queue(&fbi->ctrlr_wait, &wait); remove_wait_queue(&fbi->ctrlr_wait, &wait);
...@@ -1072,14 +843,15 @@ static void sa1100fb_disable_controller(struct sa1100fb_info *fbi) ...@@ -1072,14 +843,15 @@ static void sa1100fb_disable_controller(struct sa1100fb_info *fbi)
static irqreturn_t sa1100fb_handle_irq(int irq, void *dev_id) static irqreturn_t sa1100fb_handle_irq(int irq, void *dev_id)
{ {
struct sa1100fb_info *fbi = dev_id; struct sa1100fb_info *fbi = dev_id;
unsigned int lcsr = LCSR; unsigned int lcsr = readl_relaxed(fbi->base + LCSR);
if (lcsr & LCSR_LDD) { if (lcsr & LCSR_LDD) {
LCCR0 |= LCCR0_LDM; u32 lccr0 = readl_relaxed(fbi->base + LCCR0) | LCCR0_LDM;
writel_relaxed(lccr0, fbi->base + LCCR0);
wake_up(&fbi->ctrlr_wait); wake_up(&fbi->ctrlr_wait);
} }
LCSR = lcsr; writel_relaxed(lcsr, fbi->base + LCSR);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
...@@ -1268,7 +1040,7 @@ sa1100fb_freq_policy(struct notifier_block *nb, unsigned long val, ...@@ -1268,7 +1040,7 @@ sa1100fb_freq_policy(struct notifier_block *nb, unsigned long val,
switch (val) { switch (val) {
case CPUFREQ_ADJUST: case CPUFREQ_ADJUST:
case CPUFREQ_INCOMPATIBLE: case CPUFREQ_INCOMPATIBLE:
printk(KERN_DEBUG "min dma period: %d ps, " dev_dbg(fbi->dev, "min dma period: %d ps, "
"new clock %d kHz\n", sa1100fb_min_dma_period(fbi), "new clock %d kHz\n", sa1100fb_min_dma_period(fbi),
policy->max); policy->max);
/* todo: fill in min/max values */ /* todo: fill in min/max values */
...@@ -1318,7 +1090,7 @@ static int sa1100fb_resume(struct platform_device *dev) ...@@ -1318,7 +1090,7 @@ static int sa1100fb_resume(struct platform_device *dev)
* cache. Once this area is remapped, all virtual memory * cache. Once this area is remapped, all virtual memory
* access to the video memory should occur at the new region. * access to the video memory should occur at the new region.
*/ */
static int __init sa1100fb_map_video_memory(struct sa1100fb_info *fbi) static int __devinit sa1100fb_map_video_memory(struct sa1100fb_info *fbi)
{ {
/* /*
* We reserve one page for the palette, plus the size * We reserve one page for the palette, plus the size
...@@ -1344,7 +1116,7 @@ static int __init sa1100fb_map_video_memory(struct sa1100fb_info *fbi) ...@@ -1344,7 +1116,7 @@ static int __init sa1100fb_map_video_memory(struct sa1100fb_info *fbi)
} }
/* Fake monspecs to fill in fbinfo structure */ /* Fake monspecs to fill in fbinfo structure */
static struct fb_monspecs monspecs __initdata = { static struct fb_monspecs monspecs __devinitdata = {
.hfmin = 30000, .hfmin = 30000,
.hfmax = 70000, .hfmax = 70000,
.vfmin = 50, .vfmin = 50,
...@@ -1352,10 +1124,11 @@ static struct fb_monspecs monspecs __initdata = { ...@@ -1352,10 +1124,11 @@ static struct fb_monspecs monspecs __initdata = {
}; };
static struct sa1100fb_info * __init sa1100fb_init_fbinfo(struct device *dev) static struct sa1100fb_info * __devinit sa1100fb_init_fbinfo(struct device *dev)
{ {
struct sa1100fb_mach_info *inf; struct sa1100fb_mach_info *inf = dev->platform_data;
struct sa1100fb_info *fbi; struct sa1100fb_info *fbi;
unsigned i;
fbi = kmalloc(sizeof(struct sa1100fb_info) + sizeof(u32) * 16, fbi = kmalloc(sizeof(struct sa1100fb_info) + sizeof(u32) * 16,
GFP_KERNEL); GFP_KERNEL);
...@@ -1390,8 +1163,6 @@ static struct sa1100fb_info * __init sa1100fb_init_fbinfo(struct device *dev) ...@@ -1390,8 +1163,6 @@ static struct sa1100fb_info * __init sa1100fb_init_fbinfo(struct device *dev)
fbi->rgb[RGB_8] = &rgb_8; fbi->rgb[RGB_8] = &rgb_8;
fbi->rgb[RGB_16] = &def_rgb_16; fbi->rgb[RGB_16] = &def_rgb_16;
inf = sa1100fb_get_machine_info(fbi);
/* /*
* People just don't seem to get this. We don't support * People just don't seem to get this. We don't support
* anything but correct entries now, so panic if someone * anything but correct entries now, so panic if someone
...@@ -1402,13 +1173,10 @@ static struct sa1100fb_info * __init sa1100fb_init_fbinfo(struct device *dev) ...@@ -1402,13 +1173,10 @@ static struct sa1100fb_info * __init sa1100fb_init_fbinfo(struct device *dev)
panic("sa1100fb error: invalid LCCR3 fields set or zero " panic("sa1100fb error: invalid LCCR3 fields set or zero "
"pixclock."); "pixclock.");
fbi->max_xres = inf->xres;
fbi->fb.var.xres = inf->xres; fbi->fb.var.xres = inf->xres;
fbi->fb.var.xres_virtual = inf->xres; fbi->fb.var.xres_virtual = inf->xres;
fbi->max_yres = inf->yres;
fbi->fb.var.yres = inf->yres; fbi->fb.var.yres = inf->yres;
fbi->fb.var.yres_virtual = inf->yres; fbi->fb.var.yres_virtual = inf->yres;
fbi->max_bpp = inf->bpp;
fbi->fb.var.bits_per_pixel = inf->bpp; fbi->fb.var.bits_per_pixel = inf->bpp;
fbi->fb.var.pixclock = inf->pixclock; fbi->fb.var.pixclock = inf->pixclock;
fbi->fb.var.hsync_len = inf->hsync_len; fbi->fb.var.hsync_len = inf->hsync_len;
...@@ -1419,14 +1187,16 @@ static struct sa1100fb_info * __init sa1100fb_init_fbinfo(struct device *dev) ...@@ -1419,14 +1187,16 @@ static struct sa1100fb_info * __init sa1100fb_init_fbinfo(struct device *dev)
fbi->fb.var.lower_margin = inf->lower_margin; fbi->fb.var.lower_margin = inf->lower_margin;
fbi->fb.var.sync = inf->sync; fbi->fb.var.sync = inf->sync;
fbi->fb.var.grayscale = inf->cmap_greyscale; fbi->fb.var.grayscale = inf->cmap_greyscale;
fbi->cmap_inverse = inf->cmap_inverse;
fbi->cmap_static = inf->cmap_static;
fbi->lccr0 = inf->lccr0;
fbi->lccr3 = inf->lccr3;
fbi->state = C_STARTUP; fbi->state = C_STARTUP;
fbi->task_state = (u_char)-1; fbi->task_state = (u_char)-1;
fbi->fb.fix.smem_len = fbi->max_xres * fbi->max_yres * fbi->fb.fix.smem_len = inf->xres * inf->yres *
fbi->max_bpp / 8; inf->bpp / 8;
fbi->inf = inf;
/* Copy the RGB bitfield overrides */
for (i = 0; i < NR_RGB; i++)
if (inf->rgb[i])
fbi->rgb[i] = inf->rgb[i];
init_waitqueue_head(&fbi->ctrlr_wait); init_waitqueue_head(&fbi->ctrlr_wait);
INIT_WORK(&fbi->task, sa1100fb_task); INIT_WORK(&fbi->task, sa1100fb_task);
...@@ -1438,13 +1208,20 @@ static struct sa1100fb_info * __init sa1100fb_init_fbinfo(struct device *dev) ...@@ -1438,13 +1208,20 @@ static struct sa1100fb_info * __init sa1100fb_init_fbinfo(struct device *dev)
static int __devinit sa1100fb_probe(struct platform_device *pdev) static int __devinit sa1100fb_probe(struct platform_device *pdev)
{ {
struct sa1100fb_info *fbi; struct sa1100fb_info *fbi;
struct resource *res;
int ret, irq; int ret, irq;
if (!pdev->dev.platform_data) {
dev_err(&pdev->dev, "no platform LCD data\n");
return -EINVAL;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
irq = platform_get_irq(pdev, 0); irq = platform_get_irq(pdev, 0);
if (irq < 0) if (irq < 0 || !res)
return -EINVAL; return -EINVAL;
if (!request_mem_region(0xb0100000, 0x10000, "LCD")) if (!request_mem_region(res->start, resource_size(res), "LCD"))
return -EBUSY; return -EBUSY;
fbi = sa1100fb_init_fbinfo(&pdev->dev); fbi = sa1100fb_init_fbinfo(&pdev->dev);
...@@ -1452,6 +1229,10 @@ static int __devinit sa1100fb_probe(struct platform_device *pdev) ...@@ -1452,6 +1229,10 @@ static int __devinit sa1100fb_probe(struct platform_device *pdev)
if (!fbi) if (!fbi)
goto failed; goto failed;
fbi->base = ioremap(res->start, resource_size(res));
if (!fbi->base)
goto failed;
/* Initialize video memory */ /* Initialize video memory */
ret = sa1100fb_map_video_memory(fbi); ret = sa1100fb_map_video_memory(fbi);
if (ret) if (ret)
...@@ -1459,14 +1240,16 @@ static int __devinit sa1100fb_probe(struct platform_device *pdev) ...@@ -1459,14 +1240,16 @@ static int __devinit sa1100fb_probe(struct platform_device *pdev)
ret = request_irq(irq, sa1100fb_handle_irq, 0, "LCD", fbi); ret = request_irq(irq, sa1100fb_handle_irq, 0, "LCD", fbi);
if (ret) { if (ret) {
printk(KERN_ERR "sa1100fb: request_irq failed: %d\n", ret); dev_err(&pdev->dev, "request_irq failed: %d\n", ret);
goto failed; goto failed;
} }
#ifdef ASSABET_PAL_VIDEO if (machine_is_shannon()) {
if (machine_is_assabet()) ret = gpio_request_one(SHANNON_GPIO_DISP_EN,
ASSABET_BCR_clear(ASSABET_BCR_LCD_ON); GPIOF_OUT_INIT_LOW, "display enable");
#endif if (ret)
goto err_free_irq;
}
/* /*
* This makes sure that our colour bitfield * This makes sure that our colour bitfield
...@@ -1478,7 +1261,7 @@ static int __devinit sa1100fb_probe(struct platform_device *pdev) ...@@ -1478,7 +1261,7 @@ static int __devinit sa1100fb_probe(struct platform_device *pdev)
ret = register_framebuffer(&fbi->fb); ret = register_framebuffer(&fbi->fb);
if (ret < 0) if (ret < 0)
goto err_free_irq; goto err_reg_fb;
#ifdef CONFIG_CPU_FREQ #ifdef CONFIG_CPU_FREQ
fbi->freq_transition.notifier_call = sa1100fb_freq_transition; fbi->freq_transition.notifier_call = sa1100fb_freq_transition;
...@@ -1490,12 +1273,17 @@ static int __devinit sa1100fb_probe(struct platform_device *pdev) ...@@ -1490,12 +1273,17 @@ static int __devinit sa1100fb_probe(struct platform_device *pdev)
/* This driver cannot be unloaded at the moment */ /* This driver cannot be unloaded at the moment */
return 0; return 0;
err_reg_fb:
if (machine_is_shannon())
gpio_free(SHANNON_GPIO_DISP_EN);
err_free_irq: err_free_irq:
free_irq(irq, fbi); free_irq(irq, fbi);
failed: failed:
if (fbi)
iounmap(fbi->base);
platform_set_drvdata(pdev, NULL); platform_set_drvdata(pdev, NULL);
kfree(fbi); kfree(fbi);
release_mem_region(0xb0100000, 0x10000); release_mem_region(res->start, resource_size(res));
return ret; return ret;
} }
...@@ -1505,6 +1293,7 @@ static struct platform_driver sa1100fb_driver = { ...@@ -1505,6 +1293,7 @@ static struct platform_driver sa1100fb_driver = {
.resume = sa1100fb_resume, .resume = sa1100fb_resume,
.driver = { .driver = {
.name = "sa11x0-fb", .name = "sa11x0-fb",
.owner = THIS_MODULE,
}, },
}; };
......
...@@ -10,44 +10,15 @@ ...@@ -10,44 +10,15 @@
* for more details. * for more details.
*/ */
/* #define LCCR0 0x0000 /* LCD Control Reg. 0 */
* These are the bitfields for each #define LCSR 0x0004 /* LCD Status Reg. */
* display depth that we support. #define DBAR1 0x0010 /* LCD DMA Base Address Reg. channel 1 */
*/ #define DCAR1 0x0014 /* LCD DMA Current Address Reg. channel 1 */
struct sa1100fb_rgb { #define DBAR2 0x0018 /* LCD DMA Base Address Reg. channel 2 */
struct fb_bitfield red; #define DCAR2 0x001C /* LCD DMA Current Address Reg. channel 2 */
struct fb_bitfield green; #define LCCR1 0x0020 /* LCD Control Reg. 1 */
struct fb_bitfield blue; #define LCCR2 0x0024 /* LCD Control Reg. 2 */
struct fb_bitfield transp; #define LCCR3 0x0028 /* LCD Control Reg. 3 */
};
/*
* This structure describes the machine which we are running on.
*/
struct sa1100fb_mach_info {
u_long pixclock;
u_short xres;
u_short yres;
u_char bpp;
u_char hsync_len;
u_char left_margin;
u_char right_margin;
u_char vsync_len;
u_char upper_margin;
u_char lower_margin;
u_char sync;
u_int cmap_greyscale:1,
cmap_inverse:1,
cmap_static:1,
unused:29;
u_int lccr0;
u_int lccr3;
};
/* Shadows for LCD controller registers */ /* Shadows for LCD controller registers */
struct sa1100fb_lcd_reg { struct sa1100fb_lcd_reg {
...@@ -57,19 +28,11 @@ struct sa1100fb_lcd_reg { ...@@ -57,19 +28,11 @@ struct sa1100fb_lcd_reg {
unsigned long lccr3; unsigned long lccr3;
}; };
#define RGB_4 (0)
#define RGB_8 (1)
#define RGB_16 (2)
#define NR_RGB 3
struct sa1100fb_info { struct sa1100fb_info {
struct fb_info fb; struct fb_info fb;
struct device *dev; struct device *dev;
struct sa1100fb_rgb *rgb[NR_RGB]; const struct sa1100fb_rgb *rgb[NR_RGB];
void __iomem *base;
u_int max_bpp;
u_int max_xres;
u_int max_yres;
/* /*
* These are the addresses we mapped * These are the addresses we mapped
...@@ -88,12 +51,6 @@ struct sa1100fb_info { ...@@ -88,12 +51,6 @@ struct sa1100fb_info {
dma_addr_t dbar1; dma_addr_t dbar1;
dma_addr_t dbar2; dma_addr_t dbar2;
u_int lccr0;
u_int lccr3;
u_int cmap_inverse:1,
cmap_static:1,
unused:30;
u_int reg_lccr0; u_int reg_lccr0;
u_int reg_lccr1; u_int reg_lccr1;
u_int reg_lccr2; u_int reg_lccr2;
...@@ -109,6 +66,8 @@ struct sa1100fb_info { ...@@ -109,6 +66,8 @@ struct sa1100fb_info {
struct notifier_block freq_transition; struct notifier_block freq_transition;
struct notifier_block freq_policy; struct notifier_block freq_policy;
#endif #endif
const struct sa1100fb_mach_info *inf;
}; };
#define TO_INF(ptr,member) container_of(ptr,struct sa1100fb_info,member) #define TO_INF(ptr,member) container_of(ptr,struct sa1100fb_info,member)
...@@ -129,15 +88,6 @@ struct sa1100fb_info { ...@@ -129,15 +88,6 @@ struct sa1100fb_info {
#define SA1100_NAME "SA1100" #define SA1100_NAME "SA1100"
/*
* Debug macros
*/
#if DEBUG
# define DPRINTK(fmt, args...) printk("%s: " fmt, __func__ , ## args)
#else
# define DPRINTK(fmt, args...)
#endif
/* /*
* Minimum X and Y resolutions * Minimum X and Y resolutions
*/ */
......
/*
* StrongARM 1100 LCD Controller Frame Buffer Device
*
* Copyright (C) 1999 Eric A. Thomas
* Based on acornfb.c Copyright (C) Russell King.
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive
* for more details.
*/
#ifndef _VIDEO_SA1100FB_H
#define _VIDEO_SA1100FB_H
#include <linux/fb.h>
#include <linux/types.h>
#define RGB_4 0
#define RGB_8 1
#define RGB_16 2
#define NR_RGB 3
/* These are the bitfields for each display depth that we support. */
struct sa1100fb_rgb {
struct fb_bitfield red;
struct fb_bitfield green;
struct fb_bitfield blue;
struct fb_bitfield transp;
};
/* This structure describes the machine which we are running on. */
struct sa1100fb_mach_info {
u_long pixclock;
u_short xres;
u_short yres;
u_char bpp;
u_char hsync_len;
u_char left_margin;
u_char right_margin;
u_char vsync_len;
u_char upper_margin;
u_char lower_margin;
u_char sync;
u_int cmap_greyscale:1,
cmap_inverse:1,
cmap_static:1,
unused:29;
u_int lccr0;
u_int lccr3;
/* Overrides for the default RGB maps */
const struct sa1100fb_rgb *rgb[NR_RGB];
void (*backlight_power)(int);
void (*lcd_power)(int);
void (*set_visual)(u32);
};
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment