summaryrefslogtreecommitdiff
path: root/drivers/video
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/Kconfig4
-rw-r--r--drivers/video/aty/radeon_base.c5
-rw-r--r--drivers/video/console/fbcon.c3
-rw-r--r--drivers/video/fbcmap.c96
-rw-r--r--drivers/video/fbmem.c7
-rw-r--r--drivers/video/fbmon.c2
-rw-r--r--drivers/video/fbsysfs.c82
-rw-r--r--drivers/video/imxfb.c14
-rw-r--r--drivers/video/imxfb.h1
-rw-r--r--drivers/video/pm2fb.c16
-rw-r--r--drivers/video/riva/fbdev.c2
-rw-r--r--drivers/video/vesafb.c47
12 files changed, 177 insertions, 102 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 04d3120..cde0ed0 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -1399,8 +1399,8 @@ config FB_TX3912
Say Y here to enable kernel support for the on-board framebuffer.
config FB_G364
- bool
- depends on MIPS_MAGNUM_4000 || OLIVETTI_M700
+ bool "G364 frame buffer support"
+ depends on (FB = y) && (MIPS_MAGNUM_4000 || OLIVETTI_M700)
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c
index 47a6b12..e7e8b52 100644
--- a/drivers/video/aty/radeon_base.c
+++ b/drivers/video/aty/radeon_base.c
@@ -2521,6 +2521,11 @@ static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev)
radeonfb_pm_exit(rinfo);
+ if (rinfo->mon1_EDID)
+ sysfs_remove_bin_file(&rinfo->pdev->dev.kobj, &edid1_attr);
+ if (rinfo->mon2_EDID)
+ sysfs_remove_bin_file(&rinfo->pdev->dev.kobj, &edid2_attr);
+
#if 0
/* restore original state
*
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 9dd0fbc..35c88bd 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -275,7 +275,8 @@ static void fb_flashcursor(void *private)
if (!vc || !CON_IS_VISIBLE(vc) ||
fbcon_is_inactive(vc, info) ||
- registered_fb[con2fb_map[vc->vc_num]] != info)
+ registered_fb[con2fb_map[vc->vc_num]] != info ||
+ vc_cons[ops->currcon].d->vc_deccm != 1)
return;
acquire_console_sem();
p = &fb_display[vc->vc_num];
diff --git a/drivers/video/fbcmap.c b/drivers/video/fbcmap.c
index 4e5ce8f..c32a2a5 100644
--- a/drivers/video/fbcmap.c
+++ b/drivers/video/fbcmap.c
@@ -212,7 +212,7 @@ int fb_cmap_to_user(struct fb_cmap *from, struct fb_cmap_user *to)
int fb_set_cmap(struct fb_cmap *cmap, struct fb_info *info)
{
- int i, start;
+ int i, start, rc = 0;
u16 *red, *green, *blue, *transp;
u_int hred, hgreen, hblue, htransp = 0xffff;
@@ -225,75 +225,51 @@ int fb_set_cmap(struct fb_cmap *cmap, struct fb_info *info)
if (start < 0 || (!info->fbops->fb_setcolreg &&
!info->fbops->fb_setcmap))
return -EINVAL;
- if (info->fbops->fb_setcmap)
- return info->fbops->fb_setcmap(cmap, info);
- for (i = 0; i < cmap->len; i++) {
- hred = *red++;
- hgreen = *green++;
- hblue = *blue++;
- if (transp)
- htransp = *transp++;
- if (info->fbops->fb_setcolreg(start++,
- hred, hgreen, hblue, htransp,
- info))
- break;
+ if (info->fbops->fb_setcmap) {
+ rc = info->fbops->fb_setcmap(cmap, info);
+ } else {
+ for (i = 0; i < cmap->len; i++) {
+ hred = *red++;
+ hgreen = *green++;
+ hblue = *blue++;
+ if (transp)
+ htransp = *transp++;
+ if (info->fbops->fb_setcolreg(start++,
+ hred, hgreen, hblue,
+ htransp, info))
+ break;
+ }
}
- return 0;
+ if (rc == 0)
+ fb_copy_cmap(cmap, &info->cmap);
+
+ return rc;
}
int fb_set_user_cmap(struct fb_cmap_user *cmap, struct fb_info *info)
{
- int i, start;
- u16 __user *red, *green, *blue, *transp;
- u_int hred, hgreen, hblue, htransp = 0xffff;
-
- red = cmap->red;
- green = cmap->green;
- blue = cmap->blue;
- transp = cmap->transp;
- start = cmap->start;
+ int rc, size = cmap->len * sizeof(u16);
+ struct fb_cmap umap;
- if (start < 0 || (!info->fbops->fb_setcolreg &&
- !info->fbops->fb_setcmap))
+ if (cmap->start < 0 || (!info->fbops->fb_setcolreg &&
+ !info->fbops->fb_setcmap))
return -EINVAL;
- /* If we can batch, do it */
- if (info->fbops->fb_setcmap && cmap->len > 1) {
- struct fb_cmap umap;
- int size = cmap->len * sizeof(u16);
- int rc;
-
- memset(&umap, 0, sizeof(struct fb_cmap));
- rc = fb_alloc_cmap(&umap, cmap->len, transp != NULL);
- if (rc)
- return rc;
- if (copy_from_user(umap.red, red, size) ||
- copy_from_user(umap.green, green, size) ||
- copy_from_user(umap.blue, blue, size) ||
- (transp && copy_from_user(umap.transp, transp, size))) {
- rc = -EFAULT;
- }
- umap.start = start;
- if (rc == 0)
- rc = info->fbops->fb_setcmap(&umap, info);
- fb_dealloc_cmap(&umap);
+ memset(&umap, 0, sizeof(struct fb_cmap));
+ rc = fb_alloc_cmap(&umap, cmap->len, cmap->transp != NULL);
+ if (rc)
return rc;
+ if (copy_from_user(umap.red, cmap->red, size) ||
+ copy_from_user(umap.green, cmap->green, size) ||
+ copy_from_user(umap.blue, cmap->blue, size) ||
+ (cmap->transp && copy_from_user(umap.transp, cmap->transp, size))) {
+ fb_dealloc_cmap(&umap);
+ return -EFAULT;
}
-
- for (i = 0; i < cmap->len; i++, red++, blue++, green++) {
- if (get_user(hred, red) ||
- get_user(hgreen, green) ||
- get_user(hblue, blue) ||
- (transp && get_user(htransp, transp)))
- return -EFAULT;
- if (info->fbops->fb_setcolreg(start++,
- hred, hgreen, hblue, htransp,
- info))
- return 0;
- if (transp)
- transp++;
- }
- return 0;
+ umap.start = cmap->start;
+ rc = fb_set_cmap(&umap, info);
+ fb_dealloc_cmap(&umap);
+ return rc;
}
/**
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 2222de6..d2e19f6 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -80,10 +80,12 @@ EXPORT_SYMBOL(fb_get_color_depth);
*/
void fb_pad_aligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch, u32 height)
{
- int i;
+ int i, j;
for (i = height; i--; ) {
- memcpy(dst, src, s_pitch);
+ /* s_pitch is a few bytes at the most, memcpy is suboptimal */
+ for (j = 0; j < s_pitch; j++)
+ dst[j] = src[j];
src += s_pitch;
dst += d_pitch;
}
@@ -1164,6 +1166,7 @@ static void __exit
fbmem_exit(void)
{
class_destroy(fb_class);
+ unregister_chrdev(FB_MAJOR, "fb");
}
module_exit(fbmem_exit);
diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c
index 6cd1976..c2718bb 100644
--- a/drivers/video/fbmon.c
+++ b/drivers/video/fbmon.c
@@ -1241,6 +1241,8 @@ int fb_validate_mode(const struct fb_var_screeninfo *var, struct fb_info *info)
vtotal *= 2;
hfreq = pixclock/htotal;
+ hfreq = (hfreq + 500) / 1000 * 1000;
+
vfreq = hfreq/vtotal;
return (vfreq < vfmin || vfreq > vfmax ||
diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c
index ddc9443..ed1d4d1 100644
--- a/drivers/video/fbsysfs.c
+++ b/drivers/video/fbsysfs.c
@@ -242,10 +242,68 @@ static ssize_t show_virtual(struct class_device *class_device, char *buf)
fb_info->var.yres_virtual);
}
-static ssize_t store_cmap(struct class_device *class_device, const char * buf,
+/* Format for cmap is "%02x%c%4x%4x%4x\n" */
+/* %02x entry %c transp %4x red %4x blue %4x green \n */
+/* 256 rows at 16 chars equals 4096, the normal page size */
+/* the code will automatically adjust for different page sizes */
+static ssize_t store_cmap(struct class_device *class_device, const char *buf,
size_t count)
{
-// struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device);
+ struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device);
+ int rc, i, start, length, transp = 0;
+
+ if ((count > PAGE_SIZE) || ((count % 16) != 0))
+ return -EINVAL;
+
+ if (!fb_info->fbops->fb_setcolreg && !fb_info->fbops->fb_setcmap)
+ return -EINVAL;
+
+ sscanf(buf, "%02x", &start);
+ length = count / 16;
+
+ for (i = 0; i < length; i++)
+ if (buf[i * 16 + 2] != ' ')
+ transp = 1;
+
+ /* If we can batch, do it */
+ if (fb_info->fbops->fb_setcmap && length > 1) {
+ struct fb_cmap umap;
+
+ memset(&umap, 0, sizeof(umap));
+ if ((rc = fb_alloc_cmap(&umap, length, transp)))
+ return rc;
+
+ umap.start = start;
+ for (i = 0; i < length; i++) {
+ sscanf(&buf[i * 16 + 3], "%4hx", &umap.red[i]);
+ sscanf(&buf[i * 16 + 7], "%4hx", &umap.blue[i]);
+ sscanf(&buf[i * 16 + 11], "%4hx", &umap.green[i]);
+ if (transp)
+ umap.transp[i] = (buf[i * 16 + 2] != ' ');
+ }
+ rc = fb_info->fbops->fb_setcmap(&umap, fb_info);
+ fb_copy_cmap(&umap, &fb_info->cmap);
+ fb_dealloc_cmap(&umap);
+
+ return rc;
+ }
+ for (i = 0; i < length; i++) {
+ u16 red, blue, green, tsp;
+
+ sscanf(&buf[i * 16 + 3], "%4hx", &red);
+ sscanf(&buf[i * 16 + 7], "%4hx", &blue);
+ sscanf(&buf[i * 16 + 11], "%4hx", &green);
+ tsp = (buf[i * 16 + 2] != ' ');
+ if ((rc = fb_info->fbops->fb_setcolreg(start++,
+ red, green, blue, tsp, fb_info)))
+ return rc;
+
+ fb_info->cmap.red[i] = red;
+ fb_info->cmap.blue[i] = blue;
+ fb_info->cmap.green[i] = green;
+ if (transp)
+ fb_info->cmap.transp[i] = tsp;
+ }
return 0;
}
@@ -253,20 +311,24 @@ static ssize_t show_cmap(struct class_device *class_device, char *buf)
{
struct fb_info *fb_info =
(struct fb_info *)class_get_devdata(class_device);
- unsigned int offset = 0, i;
+ unsigned int i;
if (!fb_info->cmap.red || !fb_info->cmap.blue ||
- !fb_info->cmap.green || !fb_info->cmap.transp)
+ !fb_info->cmap.green)
+ return -EINVAL;
+
+ if (fb_info->cmap.len > PAGE_SIZE / 16)
return -EINVAL;
+ /* don't mess with the format, the buffer is PAGE_SIZE */
+ /* 256 entries at 16 chars per line equals 4096 = PAGE_SIZE */
for (i = 0; i < fb_info->cmap.len; i++) {
- offset += snprintf(buf, PAGE_SIZE - offset,
- "%d,%d,%d,%d,%d\n", i + fb_info->cmap.start,
- fb_info->cmap.red[i], fb_info->cmap.blue[i],
- fb_info->cmap.green[i],
- fb_info->cmap.transp[i]);
+ snprintf(&buf[ i * 16], PAGE_SIZE - i * 16, "%02x%c%4x%4x%4x\n", i + fb_info->cmap.start,
+ ((fb_info->cmap.transp && fb_info->cmap.transp[i]) ? '*' : ' '),
+ fb_info->cmap.red[i], fb_info->cmap.blue[i],
+ fb_info->cmap.green[i]);
}
- return offset;
+ return 16 * fb_info->cmap.len;
}
static ssize_t store_blank(struct class_device *class_device, const char * buf,
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
index 8fe1c12..cabd53c 100644
--- a/drivers/video/imxfb.c
+++ b/drivers/video/imxfb.c
@@ -249,9 +249,6 @@ static void imxfb_enable_controller(struct imxfb_info *fbi)
/* disable hardware cursor */
LCDC_CPOS &= ~(CPOS_CC0 | CPOS_CC1);
- /* fixed burst length (see erratum 11) */
- LCDC_DMACR = DMACR_BURST | DMACR_HM(8) | DMACR_TM(2);
-
LCDC_RMCR = RMCR_LCDC_EN;
if(fbi->backlight_power)
@@ -359,6 +356,7 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf
LCDC_PCR = fbi->pcr;
LCDC_PWMR = fbi->pwmr;
LCDC_LSCR1 = fbi->lscr1;
+ LCDC_DMACR = fbi->dmacr;
return 0;
}
@@ -509,6 +507,7 @@ static int __init imxfb_init_fbinfo(struct device *dev)
fbi->cmap_inverse = inf->cmap_inverse;
fbi->pcr = inf->pcr;
fbi->lscr1 = inf->lscr1;
+ fbi->dmacr = inf->dmacr;
fbi->pwmr = inf->pwmr;
fbi->lcd_power = inf->lcd_power;
fbi->backlight_power = inf->backlight_power;
@@ -642,12 +641,12 @@ static int imxfb_remove(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct fb_info *info = dev_get_drvdata(dev);
+ struct imxfb_info *fbi = info->par;
struct resource *res;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- /* disable LCD controller */
- LCDC_RMCR &= ~RMCR_LCDC_EN;
+ imxfb_disable_controller(fbi);
unregister_framebuffer(info);
@@ -663,8 +662,9 @@ static int imxfb_remove(struct device *dev)
void imxfb_shutdown(struct device * dev)
{
- /* disable LCD Controller */
- LCDC_RMCR &= ~RMCR_LCDC_EN;
+ struct fb_info *info = dev_get_drvdata(dev);
+ struct imxfb_info *fbi = info->par;
+ imxfb_disable_controller(fbi);
}
static struct device_driver imxfb_driver = {
diff --git a/drivers/video/imxfb.h b/drivers/video/imxfb.h
index 128c3ee..e837a8b 100644
--- a/drivers/video/imxfb.h
+++ b/drivers/video/imxfb.h
@@ -54,6 +54,7 @@ struct imxfb_info {
u_int pcr;
u_int pwmr;
u_int lscr1;
+ u_int dmacr;
u_int cmap_inverse:1,
cmap_static:1,
unused:30;
diff --git a/drivers/video/pm2fb.c b/drivers/video/pm2fb.c
index 5dcedde..42c17ef 100644
--- a/drivers/video/pm2fb.c
+++ b/drivers/video/pm2fb.c
@@ -138,27 +138,27 @@ static struct fb_var_screeninfo pm2fb_var __devinitdata = {
* Utility functions
*/
-inline static u32 RD32(unsigned char __iomem *base, s32 off)
+static inline u32 RD32(unsigned char __iomem *base, s32 off)
{
return fb_readl(base + off);
}
-inline static void WR32(unsigned char __iomem *base, s32 off, u32 v)
+static inline void WR32(unsigned char __iomem *base, s32 off, u32 v)
{
fb_writel(v, base + off);
}
-inline static u32 pm2_RD(struct pm2fb_par* p, s32 off)
+static inline u32 pm2_RD(struct pm2fb_par* p, s32 off)
{
return RD32(p->v_regs, off);
}
-inline static void pm2_WR(struct pm2fb_par* p, s32 off, u32 v)
+static inline void pm2_WR(struct pm2fb_par* p, s32 off, u32 v)
{
WR32(p->v_regs, off, v);
}
-inline static u32 pm2_RDAC_RD(struct pm2fb_par* p, s32 idx)
+static inline u32 pm2_RDAC_RD(struct pm2fb_par* p, s32 idx)
{
int index = PM2R_RD_INDEXED_DATA;
switch (p->type) {
@@ -174,7 +174,7 @@ inline static u32 pm2_RDAC_RD(struct pm2fb_par* p, s32 idx)
return pm2_RD(p, index);
}
-inline static void pm2_RDAC_WR(struct pm2fb_par* p, s32 idx, u32 v)
+static inline void pm2_RDAC_WR(struct pm2fb_par* p, s32 idx, u32 v)
{
int index = PM2R_RD_INDEXED_DATA;
switch (p->type) {
@@ -190,7 +190,7 @@ inline static void pm2_RDAC_WR(struct pm2fb_par* p, s32 idx, u32 v)
pm2_WR(p, index, v);
}
-inline static void pm2v_RDAC_WR(struct pm2fb_par* p, s32 idx, u32 v)
+static inline void pm2v_RDAC_WR(struct pm2fb_par* p, s32 idx, u32 v)
{
pm2_WR(p, PM2VR_RD_INDEX_LOW, idx & 0xff);
mb();
@@ -200,7 +200,7 @@ inline static void pm2v_RDAC_WR(struct pm2fb_par* p, s32 idx, u32 v)
#ifdef CONFIG_FB_PM2_FIFO_DISCONNECT
#define WAIT_FIFO(p,a)
#else
-inline static void WAIT_FIFO(struct pm2fb_par* p, u32 a)
+static inline void WAIT_FIFO(struct pm2fb_par* p, u32 a)
{
while( pm2_RD(p, PM2R_IN_FIFO_SPACE) < a );
mb();
diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c
index 6a9e183..ae297e2 100644
--- a/drivers/video/riva/fbdev.c
+++ b/drivers/video/riva/fbdev.c
@@ -1826,7 +1826,7 @@ static void __devinit riva_get_EDID(struct fb_info *info, struct pci_dev *pdev)
#ifdef CONFIG_PPC_OF
if (!riva_get_EDID_OF(info, pdev))
printk(PFX "could not retrieve EDID from OF\n");
-#elif CONFIG_FB_RIVA_I2C
+#elif defined(CONFIG_FB_RIVA_I2C)
if (!riva_get_EDID_i2c(info))
printk(PFX "could not retrieve EDID from DDC/I2C\n");
#endif
diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c
index 9ed1a93..a272592 100644
--- a/drivers/video/vesafb.c
+++ b/drivers/video/vesafb.c
@@ -45,7 +45,7 @@ static struct fb_fix_screeninfo vesafb_fix __initdata = {
};
static int inverse = 0;
-static int mtrr = 1;
+static int mtrr = 3; /* default to write-combining */
static int vram_remap __initdata = 0; /* Set amount of memory to be used */
static int vram_total __initdata = 0; /* Set total amount of memory */
static int pmi_setpal = 0; /* pmi for palette changes ??? */
@@ -204,8 +204,8 @@ static int __init vesafb_setup(char *options)
pmi_setpal=0;
else if (! strcmp(this_opt, "pmipal"))
pmi_setpal=1;
- else if (! strcmp(this_opt, "mtrr"))
- mtrr=1;
+ else if (! strncmp(this_opt, "mtrr:", 5))
+ mtrr = simple_strtoul(this_opt+5, NULL, 0);
else if (! strcmp(this_opt, "nomtrr"))
mtrr=0;
else if (! strncmp(this_opt, "vtotal:", 7))
@@ -387,14 +387,39 @@ static int __init vesafb_probe(struct device *device)
if (mtrr) {
unsigned int temp_size = size_total;
- /* Find the largest power-of-two */
- while (temp_size & (temp_size - 1))
- temp_size &= (temp_size - 1);
-
- /* Try and find a power of two to add */
- while (temp_size > PAGE_SIZE &&
- mtrr_add(vesafb_fix.smem_start, temp_size, MTRR_TYPE_WRCOMB, 1)==-EINVAL) {
- temp_size >>= 1;
+ unsigned int type = 0;
+
+ switch (mtrr) {
+ case 1:
+ type = MTRR_TYPE_UNCACHABLE;
+ break;
+ case 2:
+ type = MTRR_TYPE_WRBACK;
+ break;
+ case 3:
+ type = MTRR_TYPE_WRCOMB;
+ break;
+ case 4:
+ type = MTRR_TYPE_WRTHROUGH;
+ break;
+ default:
+ type = 0;
+ break;
+ }
+
+ if (type) {
+ int rc;
+
+ /* Find the largest power-of-two */
+ while (temp_size & (temp_size - 1))
+ temp_size &= (temp_size - 1);
+
+ /* Try and find a power of two to add */
+ do {
+ rc = mtrr_add(vesafb_fix.smem_start, temp_size,
+ type, 1);
+ temp_size >>= 1;
+ } while (temp_size >= PAGE_SIZE && rc == -EINVAL);
}
}