Commit cccd559e authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'fbdev-v5.2' of git://github.com/bzolnier/linux

Pull fbdev updates from Bartlomiej Zolnierkiewicz:
 "Four small fixes for fb core, updates for udlfb, sm712fb, macfb and
  atafb drivers. Redundant code removals from amba-clcd and atmel_lcdfb
  drivers. Minor fixes/cleanups for other fb drivers

  Detailed summary:

   - fix regression in fbcon logo handling on 'quiet' boots (Andreas
     Schwab)

   - fix divide-by-zero error in fb_var_to_videomode() (Shile Zhang)

   - fix 'WARNING in __alloc_pages_nodemask' bug (Jiufei Xue)

   - list all PCI memory BARs as conflicting apertures (Gerd Hoffmann)

   - update udlfb driver: fix sleeping inside spinlock, add mutex around
     rendering calls and remove redundant code (Mikulas Patocka)

   - update sm712fb driver: fix SM720 support related issues (Yifeng Li)

   - update macfb driver: fix DAFB colour table pointer initialization
     and remove redundant code (Finn Thain)

   - update atafb driver: fix kexec support, use dev_*() calls instead
     of printk() and remove obsolete module support (Geert Uytterhoeven)

   - add support to mxsfb driver for skipping display initialization for
     flicker-free display takeover from bootloader (Melchior Franz)

   - remove Versatile and Nomadik board families support from amba-clcd
     driver as they are handled by DRM driver nowadays (Linus Walleij)

   - remove no longer needed AVR and platform_data support from
     atmel_lcdfb driver (Alexandre Belloni)

   - misc fixes (Colin Ian King, Julia Lawall, Gustavo A. R. Silva,
     Aditya Pakki, Kangjie Lu, YueHaibing)

   - misc cleanups (Enrico Weigelt, Kefeng Wang)"

* tag 'fbdev-v5.2' of git://github.com/bzolnier/linux: (38 commits)
  video: fbdev: Use dev_get_drvdata()
  fbcon: Don't reset logo_shown when logo is currently shown
  video: fbdev: atmel_lcdfb: remove set but not used variable 'pdata'
  video: fbdev: mxsfb: remove set but not used variable 'line_count'
  video: fbdev: pvr2fb: remove set but not used variable 'size'
  fbdev: fix WARNING in __alloc_pages_nodemask bug
  video: amba-clcd: Decomission Versatile and Nomadik
  fbdev: sm712fb: fix memory frequency by avoiding a switch/case fallthrough
  fbdev: fix divide error in fb_var_to_videomode
  fbdev: sm712fb: use 1024x768 by default on non-MIPS, fix garbled display
  fbdev: sm712fb: fix support for 1024x768-16 mode
  fbdev: sm712fb: fix crashes and garbled display during DPMS modesetting
  fbdev: sm712fb: fix crashes during framebuffer writes by correctly mapping VRAM
  fbdev: sm712fb: fix boot screen glitch when sm712fb replaces VGA
  fbdev: sm712fb: fix VRAM detection, don't set SR70/71/74/75
  fbdev: sm712fb: fix brightness control on reboot, don't set SR30
  fbdev: sm712fb: fix white screen of death on reboot, don't set CR3B-CR3F
  video: imsttfb: fix potential NULL pointer dereferences
  video: hgafb: fix potential NULL pointer dereference
  fbdev: list all pci memory bars as conflicting apertures
  ...
parents cece6460 d4a56117
...@@ -293,14 +293,6 @@ config FB_ARMCLCD ...@@ -293,14 +293,6 @@ config FB_ARMCLCD
here and read <file:Documentation/kbuild/modules.txt>. The module here and read <file:Documentation/kbuild/modules.txt>. The module
will be called amba-clcd. will be called amba-clcd.
# Helper logic selected only by the ARM Versatile platform family.
config PLAT_VERSATILE_CLCD
def_bool ARCH_VERSATILE || ARCH_REALVIEW || ARCH_VEXPRESS || ARCH_INTEGRATOR
depends on ARM
depends on FB_ARMCLCD && FB=y
select REGMAP
select MFD_SYSCON
config FB_ACORN config FB_ACORN
bool "Acorn VIDC support" bool "Acorn VIDC support"
depends on (FB = y) && ARM && ARCH_ACORN depends on (FB = y) && ARM && ARCH_ACORN
...@@ -866,8 +858,8 @@ config FB_S1D13XXX ...@@ -866,8 +858,8 @@ config FB_S1D13XXX
<http://vdc.epson.com/> <http://vdc.epson.com/>
config FB_ATMEL config FB_ATMEL
tristate "AT91/AT32 LCD Controller support" tristate "AT91 LCD Controller support"
depends on FB && HAVE_FB_ATMEL depends on FB && OF && HAVE_FB_ATMEL
select FB_BACKLIGHT select FB_BACKLIGHT
select FB_CFB_FILLRECT select FB_CFB_FILLRECT
select FB_CFB_COPYAREA select FB_CFB_COPYAREA
...@@ -875,7 +867,7 @@ config FB_ATMEL ...@@ -875,7 +867,7 @@ config FB_ATMEL
select FB_MODE_HELPERS select FB_MODE_HELPERS
select VIDEOMODE_HELPERS select VIDEOMODE_HELPERS
help help
This enables support for the AT91/AT32 LCD Controller. This enables support for the AT91 LCD Controller.
config FB_NVIDIA config FB_NVIDIA
tristate "nVidia Framebuffer Support" tristate "nVidia Framebuffer Support"
...@@ -2183,7 +2175,7 @@ config FB_EP93XX ...@@ -2183,7 +2175,7 @@ config FB_EP93XX
config FB_PRE_INIT_FB config FB_PRE_INIT_FB
bool "Don't reinitialize, use bootloader's GDC/Display configuration" bool "Don't reinitialize, use bootloader's GDC/Display configuration"
depends on FB && FB_MB862XX_LIME depends on FB && (FB_MB862XX_LIME || FB_MXS)
---help--- ---help---
Select this option if display contents should be inherited as set by Select this option if display contents should be inherited as set by
the bootloader. the bootloader.
......
...@@ -76,8 +76,6 @@ obj-$(CONFIG_FB_ATMEL) += atmel_lcdfb.o ...@@ -76,8 +76,6 @@ obj-$(CONFIG_FB_ATMEL) += atmel_lcdfb.o
obj-$(CONFIG_FB_PVR2) += pvr2fb.o obj-$(CONFIG_FB_PVR2) += pvr2fb.o
obj-$(CONFIG_FB_VOODOO1) += sstfb.o obj-$(CONFIG_FB_VOODOO1) += sstfb.o
obj-$(CONFIG_FB_ARMCLCD) += amba-clcd.o obj-$(CONFIG_FB_ARMCLCD) += amba-clcd.o
obj-$(CONFIG_ARCH_NOMADIK) += amba-clcd-nomadik.o
obj-$(CONFIG_PLAT_VERSATILE_CLCD) += amba-clcd-versatile.o
obj-$(CONFIG_FB_GOLDFISH) += goldfishfb.o obj-$(CONFIG_FB_GOLDFISH) += goldfishfb.o
obj-$(CONFIG_FB_68328) += 68328fb.o obj-$(CONFIG_FB_68328) += 68328fb.o
obj-$(CONFIG_FB_GBE) += gbefb.o obj-$(CONFIG_FB_GBE) += gbefb.o
......
#include <linux/amba/bus.h>
#include <linux/amba/clcd.h>
#include <linux/gpio/consumer.h>
#include <linux/of.h>
#include <linux/of_graph.h>
#include <linux/delay.h>
#include <linux/bitops.h>
#include <linux/mfd/syscon.h>
#include <linux/regmap.h>
#include "amba-clcd-nomadik.h"
static struct gpio_desc *grestb;
static struct gpio_desc *scen;
static struct gpio_desc *scl;
static struct gpio_desc *sda;
static u8 tpg110_readwrite_reg(bool write, u8 address, u8 outval)
{
int i;
u8 inval = 0;
/* Assert SCEN */
gpiod_set_value_cansleep(scen, 1);
ndelay(150);
/* Hammer out the address */
for (i = 5; i >= 0; i--) {
if (address & BIT(i))
gpiod_set_value_cansleep(sda, 1);
else
gpiod_set_value_cansleep(sda, 0);
ndelay(150);
/* Send an SCL pulse */
gpiod_set_value_cansleep(scl, 1);
ndelay(160);
gpiod_set_value_cansleep(scl, 0);
ndelay(160);
}
if (write) {
/* WRITE */
gpiod_set_value_cansleep(sda, 0);
} else {
/* READ */
gpiod_set_value_cansleep(sda, 1);
}
ndelay(150);
/* Send an SCL pulse */
gpiod_set_value_cansleep(scl, 1);
ndelay(160);
gpiod_set_value_cansleep(scl, 0);
ndelay(160);
if (!write)
/* HiZ turn-around cycle */
gpiod_direction_input(sda);
ndelay(150);
/* Send an SCL pulse */
gpiod_set_value_cansleep(scl, 1);
ndelay(160);
gpiod_set_value_cansleep(scl, 0);
ndelay(160);
/* Hammer in/out the data */
for (i = 7; i >= 0; i--) {
int value;
if (write) {
value = !!(outval & BIT(i));
gpiod_set_value_cansleep(sda, value);
} else {
value = gpiod_get_value(sda);
if (value)
inval |= BIT(i);
}
ndelay(150);
/* Send an SCL pulse */
gpiod_set_value_cansleep(scl, 1);
ndelay(160);
gpiod_set_value_cansleep(scl, 0);
ndelay(160);
}
gpiod_direction_output(sda, 0);
/* Deassert SCEN */
gpiod_set_value_cansleep(scen, 0);
/* Satisfies SCEN pulse width */
udelay(1);
return inval;
}
static u8 tpg110_read_reg(u8 address)
{
return tpg110_readwrite_reg(false, address, 0);
}
static void tpg110_write_reg(u8 address, u8 outval)
{
tpg110_readwrite_reg(true, address, outval);
}
static void tpg110_startup(struct device *dev)
{
u8 val;
dev_info(dev, "TPG110 display enable\n");
/* De-assert the reset signal */
gpiod_set_value_cansleep(grestb, 0);
mdelay(1);
dev_info(dev, "de-asserted GRESTB\n");
/* Test display communication */
tpg110_write_reg(0x00, 0x55);
val = tpg110_read_reg(0x00);
if (val == 0x55)
dev_info(dev, "passed communication test\n");
val = tpg110_read_reg(0x01);
dev_info(dev, "TPG110 chip ID: %d version: %d\n",
val>>4, val&0x0f);
/* Show display resolution */
val = tpg110_read_reg(0x02);
val &= 7;
switch (val) {
case 0x0:
dev_info(dev, "IN 400x240 RGB -> OUT 800x480 RGB (dual scan)");
break;
case 0x1:
dev_info(dev, "IN 480x272 RGB -> OUT 800x480 RGB (dual scan)");
break;
case 0x4:
dev_info(dev, "480x640 RGB");
break;
case 0x5:
dev_info(dev, "480x272 RGB");
break;
case 0x6:
dev_info(dev, "640x480 RGB");
break;
case 0x7:
dev_info(dev, "800x480 RGB");
break;
default:
dev_info(dev, "ILLEGAL RESOLUTION");
break;
}
val = tpg110_read_reg(0x03);
dev_info(dev, "resolution is controlled by %s\n",
(val & BIT(7)) ? "software" : "hardware");
}
static void tpg110_enable(struct clcd_fb *fb)
{
struct device *dev = &fb->dev->dev;
static bool startup;
u8 val;
if (!startup) {
tpg110_startup(dev);
startup = true;
}
/* Take chip out of standby */
val = tpg110_read_reg(0x03);
val |= BIT(0);
tpg110_write_reg(0x03, val);
}
static void tpg110_disable(struct clcd_fb *fb)
{
u8 val;
dev_info(&fb->dev->dev, "TPG110 display disable\n");
val = tpg110_read_reg(0x03);
/* Put into standby */
val &= ~BIT(0);
tpg110_write_reg(0x03, val);
}
static void tpg110_init(struct device *dev, struct device_node *np,
struct clcd_board *board)
{
dev_info(dev, "TPG110 display init\n");
/* This asserts the GRESTB signal, putting the display into reset */
grestb = devm_fwnode_get_gpiod_from_child(dev, "grestb", &np->fwnode,
GPIOD_OUT_HIGH, "grestb");
if (IS_ERR(grestb)) {
dev_err(dev, "no GRESTB GPIO\n");
return;
}
scen = devm_fwnode_get_gpiod_from_child(dev, "scen", &np->fwnode,
GPIOD_OUT_LOW, "scen");
if (IS_ERR(scen)) {
dev_err(dev, "no SCEN GPIO\n");
return;
}
scl = devm_fwnode_get_gpiod_from_child(dev, "scl", &np->fwnode,
GPIOD_OUT_LOW, "scl");
if (IS_ERR(scl)) {
dev_err(dev, "no SCL GPIO\n");
return;
}
sda = devm_fwnode_get_gpiod_from_child(dev, "sda", &np->fwnode,
GPIOD_OUT_LOW, "sda");
if (IS_ERR(sda)) {
dev_err(dev, "no SDA GPIO\n");
return;
}
board->enable = tpg110_enable;
board->disable = tpg110_disable;
}
int nomadik_clcd_init_panel(struct clcd_fb *fb, struct device_node *panel)
{
if (of_device_is_compatible(panel, "tpo,tpg110"))
tpg110_init(&fb->dev->dev, panel, fb->board);
else
dev_info(&fb->dev->dev, "unknown panel\n");
/* Unknown panel, fall through */
return 0;
}
EXPORT_SYMBOL_GPL(nomadik_clcd_init_panel);
#define PMU_CTRL_OFFSET 0x0000
#define PMU_CTRL_LCDNDIF BIT(26)
int nomadik_clcd_init_board(struct amba_device *adev,
struct clcd_board *board)
{
struct regmap *pmu_regmap;
dev_info(&adev->dev, "Nomadik CLCD board init\n");
pmu_regmap =
syscon_regmap_lookup_by_compatible("stericsson,nomadik-pmu");
if (IS_ERR(pmu_regmap)) {
dev_err(&adev->dev, "could not find PMU syscon regmap\n");
return PTR_ERR(pmu_regmap);
}
regmap_update_bits(pmu_regmap,
PMU_CTRL_OFFSET,
PMU_CTRL_LCDNDIF,
0);
dev_info(&adev->dev, "set PMU mux to CLCD mode\n");
return 0;
}
EXPORT_SYMBOL_GPL(nomadik_clcd_init_board);
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _AMBA_CLCD_NOMADIK_H
#define _AMBA_CLCD_NOMADIK_H
#include <linux/amba/bus.h>
#ifdef CONFIG_ARCH_NOMADIK
int nomadik_clcd_init_board(struct amba_device *adev,
struct clcd_board *board);
int nomadik_clcd_init_panel(struct clcd_fb *fb, struct device_node *panel);
#else
static inline int nomadik_clcd_init_board(struct amba_device *adev,
struct clcd_board *board)
{
return 0;
}
static inline int nomadik_clcd_init_panel(struct clcd_fb *fb,
struct device_node *panel)
{
return 0;
}
#endif
#endif /* inclusion guard */
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Special local versatile callbacks
*/
#include <linux/of.h>
#include <linux/amba/bus.h>
#include <linux/platform_data/video-clcd-versatile.h>
#if defined(CONFIG_PLAT_VERSATILE_CLCD) && defined(CONFIG_OF)
int versatile_clcd_init_panel(struct clcd_fb *fb, struct device_node *panel);
#else
static inline int versatile_clcd_init_panel(struct clcd_fb *fb,
struct device_node *panel)
{
return 0;
}
#endif
...@@ -30,9 +30,6 @@ ...@@ -30,9 +30,6 @@
#include <video/of_display_timing.h> #include <video/of_display_timing.h>
#include <video/videomode.h> #include <video/videomode.h>
#include "amba-clcd-nomadik.h"
#include "amba-clcd-versatile.h"
#define to_clcd(info) container_of(info, struct clcd_fb, fb) #define to_clcd(info) container_of(info, struct clcd_fb, fb)
/* This is limited to 16 characters when displayed by X startup */ /* This is limited to 16 characters when displayed by X startup */
...@@ -223,15 +220,6 @@ clcdfb_set_bitfields(struct clcd_fb *fb, struct fb_var_screeninfo *var) ...@@ -223,15 +220,6 @@ clcdfb_set_bitfields(struct clcd_fb *fb, struct fb_var_screeninfo *var)
var->blue.length = 4; var->blue.length = 4;
} }
break; break;
case 24:
if (fb->vendor->packed_24_bit_pixels) {
var->red.length = 8;
var->green.length = 8;
var->blue.length = 8;
} else {
ret = -EINVAL;
}
break;
case 32: case 32:
/* If we can't do 888, reject */ /* If we can't do 888, reject */
caps &= CLCD_CAP_888; caps &= CLCD_CAP_888;
...@@ -318,12 +306,6 @@ static int clcdfb_set_par(struct fb_info *info) ...@@ -318,12 +306,6 @@ static int clcdfb_set_par(struct fb_info *info)
clcdfb_disable(fb); clcdfb_disable(fb);
/* Some variants must be clocked here */
if (fb->vendor->clock_timregs && !fb->clk_enabled) {
fb->clk_enabled = true;
clk_enable(fb->clk);
}
writel(regs.tim0, fb->regs + CLCD_TIM0); writel(regs.tim0, fb->regs + CLCD_TIM0);
writel(regs.tim1, fb->regs + CLCD_TIM1); writel(regs.tim1, fb->regs + CLCD_TIM1);
writel(regs.tim2, fb->regs + CLCD_TIM2); writel(regs.tim2, fb->regs + CLCD_TIM2);
...@@ -464,16 +446,10 @@ static int clcdfb_register(struct clcd_fb *fb) ...@@ -464,16 +446,10 @@ static int clcdfb_register(struct clcd_fb *fb)
if (amba_manf(fb->dev) == 0x41 && amba_part(fb->dev) == 0x111) { if (amba_manf(fb->dev) == 0x41 && amba_part(fb->dev) == 0x111) {
fb->off_ienb = CLCD_PL111_IENB; fb->off_ienb = CLCD_PL111_IENB;
fb->off_cntl = CLCD_PL111_CNTL; fb->off_cntl = CLCD_PL111_CNTL;
} else {
if (of_machine_is_compatible("arm,versatile-ab") ||
of_machine_is_compatible("arm,versatile-pb")) {
fb->off_ienb = CLCD_PL111_IENB;
fb->off_cntl = CLCD_PL111_CNTL;
} else { } else {
fb->off_ienb = CLCD_PL110_IENB; fb->off_ienb = CLCD_PL110_IENB;
fb->off_cntl = CLCD_PL110_CNTL; fb->off_cntl = CLCD_PL110_CNTL;
} }
}
fb->clk = clk_get(&fb->dev->dev, NULL); fb->clk = clk_get(&fb->dev->dev, NULL);
if (IS_ERR(fb->clk)) { if (IS_ERR(fb->clk)) {
...@@ -713,42 +689,6 @@ static int clcdfb_of_init_tft_panel(struct clcd_fb *fb, u32 r0, u32 g0, u32 b0) ...@@ -713,42 +689,6 @@ static int clcdfb_of_init_tft_panel(struct clcd_fb *fb, u32 r0, u32 g0, u32 b0)
if (r0 != 0 && b0 == 0) if (r0 != 0 && b0 == 0)
fb->panel->bgr_connection = true; fb->panel->bgr_connection = true;
if (fb->panel->caps && fb->vendor->st_bitmux_control) {
/*
* Set up the special bits for the Nomadik control register
* (other platforms tend to do this through an external
* register).
*/
/* Offset of the highest used color */
int maxoff = max3(r0, g0, b0);
/* Most significant bit out, highest used bit */
int msb = 0;
if (fb->panel->caps & CLCD_CAP_888) {
msb = maxoff + 8 - 1;
} else if (fb->panel->caps & CLCD_CAP_565) {
msb = maxoff + 5 - 1;
fb->panel->cntl |= CNTL_ST_1XBPP_565;
} else if (fb->panel->caps & CLCD_CAP_5551) {
msb = maxoff + 5 - 1;
fb->panel->cntl |= CNTL_ST_1XBPP_5551;
} else if (fb->panel->caps & CLCD_CAP_444) {
msb = maxoff + 4 - 1;
fb->panel->cntl |= CNTL_ST_1XBPP_444;
}
/* Send out as many bits as we need */
if (msb > 17)
fb->panel->cntl |= CNTL_ST_CDWID_24;
else if (msb > 15)
fb->panel->cntl |= CNTL_ST_CDWID_18;
else if (msb > 11)
fb->panel->cntl |= CNTL_ST_CDWID_16;
else
fb->panel->cntl |= CNTL_ST_CDWID_12;
}
return fb->panel->caps ? 0 : -EINVAL; return fb->panel->caps ? 0 : -EINVAL;
} }
...@@ -775,12 +715,6 @@ static int clcdfb_of_init_display(struct clcd_fb *fb) ...@@ -775,12 +715,6 @@ static int clcdfb_of_init_display(struct clcd_fb *fb)
if (!panel) if (!panel)
return -ENODEV; return -ENODEV;
if (fb->vendor->init_panel) {
err = fb->vendor->init_panel(fb, panel);
if (err)
return err;
}
err = clcdfb_of_get_backlight(panel, fb->panel); err = clcdfb_of_get_backlight(panel, fb->panel);
if (err) if (err)
return err; return err;
...@@ -941,7 +875,6 @@ static struct clcd_board *clcdfb_of_get_board(struct amba_device *dev) ...@@ -941,7 +875,6 @@ static struct clcd_board *clcdfb_of_get_board(struct amba_device *dev)
static int clcdfb_probe(struct amba_device *dev, const struct amba_id *id) static int clcdfb_probe(struct amba_device *dev, const struct amba_id *id)
{ {
struct clcd_board *board = dev_get_platdata(&dev->dev); struct clcd_board *board = dev_get_platdata(&dev->dev);
struct clcd_vendor_data *vendor = id->data;
struct clcd_fb *fb; struct clcd_fb *fb;
int ret; int ret;
...@@ -951,12 +884,6 @@ static int clcdfb_probe(struct amba_device *dev, const struct amba_id *id) ...@@ -951,12 +884,6 @@ static int clcdfb_probe(struct amba_device *dev, const struct amba_id *id)
if (!board) if (!board)
return -EINVAL; return -EINVAL;
if (vendor->init_board) {
ret = vendor->init_board(dev, board);
if (ret)
return ret;
}
ret = dma_set_mask_and_coherent(&dev->dev, DMA_BIT_MASK(32)); ret = dma_set_mask_and_coherent(&dev->dev, DMA_BIT_MASK(32));
if (ret) if (ret)
goto out; goto out;
...@@ -974,7 +901,6 @@ static int clcdfb_probe(struct amba_device *dev, const struct amba_id *id) ...@@ -974,7 +901,6 @@ static int clcdfb_probe(struct amba_device *dev, const struct amba_id *id)
} }
fb->dev = dev; fb->dev = dev;
fb->vendor = vendor;
fb->board = board; fb->board = board;
dev_info(&fb->dev->dev, "PL%03x designer %02x rev%u at 0x%08llx\n", dev_info(&fb->dev->dev, "PL%03x designer %02x rev%u at 0x%08llx\n",
...@@ -1021,30 +947,10 @@ static int clcdfb_remove(struct amba_device *dev) ...@@ -1021,30 +947,10 @@ static int clcdfb_remove(struct amba_device *dev)
return 0; return 0;
} }
static struct clcd_vendor_data vendor_arm = {
/* Sets up the versatile board displays */
.init_panel = versatile_clcd_init_panel,
};
static struct clcd_vendor_data vendor_nomadik = {
.clock_timregs = true,
.packed_24_bit_pixels = true,
.st_bitmux_control = true,
.init_board = nomadik_clcd_init_board,
.init_panel = nomadik_clcd_init_panel,
};
static const struct amba_id clcdfb_id_table[] = { static const struct amba_id clcdfb_id_table[] = {
{ {
.id = 0x00041110, .id = 0x00041110,
.mask = 0x000ffffe, .mask = 0x000ffffe,
.data = &vendor_arm,
},
/* ST Electronics Nomadik variant */
{
.id = 0x00180110,
.mask = 0x00fffffe,
.data = &vendor_nomadik,
}, },
{ 0, 0 }, { 0, 0 },
}; };
......
...@@ -47,7 +47,6 @@ ...@@ -47,7 +47,6 @@
#define ATAFB_EXT #define ATAFB_EXT
#define ATAFB_FALCON #define ATAFB_FALCON
#include <linux/module.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/string.h> #include <linux/string.h>
...@@ -55,6 +54,7 @@ ...@@ -55,6 +54,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
...@@ -3073,28 +3073,22 @@ int __init atafb_setup(char *options) ...@@ -3073,28 +3073,22 @@ int __init atafb_setup(char *options)
return 0; return 0;
} }
int __init atafb_init(void) static int __init atafb_probe(struct platform_device *pdev)
{ {
int pad, detected_mode, error; int pad, detected_mode, error;
unsigned int defmode = 0; unsigned int defmode = 0;
unsigned long mem_req; unsigned long mem_req;
#ifndef MODULE
char *option = NULL; char *option = NULL;
if (fb_get_options("atafb", &option)) if (fb_get_options("atafb", &option))
return -ENODEV; return -ENODEV;
atafb_setup(option); atafb_setup(option);
#endif dev_dbg(&pdev->dev, "%s: start\n", __func__);
printk("atafb_init: start\n");
if (!MACH_IS_ATARI)
return -ENODEV;
do { do {
#ifdef ATAFB_EXT #ifdef ATAFB_EXT
if (external_addr) { if (external_addr) {
printk("atafb_init: initializing external hw\n"); dev_dbg(&pdev->dev, "initializing external hw\n");
fbhw = &ext_switch; fbhw = &ext_switch;
atafb_ops.fb_setcolreg = &ext_setcolreg; atafb_ops.fb_setcolreg = &ext_setcolreg;
defmode = DEFMODE_EXT; defmode = DEFMODE_EXT;
...@@ -3103,7 +3097,7 @@ int __init atafb_init(void) ...@@ -3103,7 +3097,7 @@ int __init atafb_init(void)
#endif #endif
#ifdef ATAFB_TT #ifdef ATAFB_TT
if (ATARIHW_PRESENT(TT_SHIFTER)) { if (ATARIHW_PRESENT(TT_SHIFTER)) {
printk("atafb_init: initializing TT hw\n"); dev_dbg(&pdev->dev, "initializing TT hw\n");
fbhw = &tt_switch; fbhw = &tt_switch;
atafb_ops.fb_setcolreg = &tt_setcolreg; atafb_ops.fb_setcolreg = &tt_setcolreg;
defmode = DEFMODE_TT; defmode = DEFMODE_TT;
...@@ -3112,7 +3106,7 @@ int __init atafb_init(void) ...@@ -3112,7 +3106,7 @@ int __init atafb_init(void)
#endif #endif
#ifdef ATAFB_FALCON #ifdef ATAFB_FALCON
if (ATARIHW_PRESENT(VIDEL_SHIFTER)) { if (ATARIHW_PRESENT(VIDEL_SHIFTER)) {
printk("atafb_init: initializing Falcon hw\n"); dev_dbg(&pdev->dev, "initializing Falcon hw\n");
fbhw = &falcon_switch; fbhw = &falcon_switch;
atafb_ops.fb_setcolreg = &falcon_setcolreg; atafb_ops.fb_setcolreg = &falcon_setcolreg;
error = request_irq(IRQ_AUTO_4, falcon_vbl_switcher, 0, error = request_irq(IRQ_AUTO_4, falcon_vbl_switcher, 0,
...@@ -3127,7 +3121,7 @@ int __init atafb_init(void) ...@@ -3127,7 +3121,7 @@ int __init atafb_init(void)
#ifdef ATAFB_STE #ifdef ATAFB_STE
if (ATARIHW_PRESENT(STND_SHIFTER) || if (ATARIHW_PRESENT(STND_SHIFTER) ||
ATARIHW_PRESENT(EXTD_SHIFTER)) { ATARIHW_PRESENT(EXTD_SHIFTER)) {
printk("atafb_init: initializing ST/E hw\n"); dev_dbg(&pdev->dev, "initializing ST/E hw\n");
fbhw = &st_switch; fbhw = &st_switch;
atafb_ops.fb_setcolreg = &stste_setcolreg; atafb_ops.fb_setcolreg = &stste_setcolreg;
defmode = DEFMODE_STE; defmode = DEFMODE_STE;
...@@ -3135,7 +3129,8 @@ int __init atafb_init(void) ...@@ -3135,7 +3129,8 @@ int __init atafb_init(void)
} }
fbhw = &st_switch; fbhw = &st_switch;
atafb_ops.fb_setcolreg = &stste_setcolreg; atafb_ops.fb_setcolreg = &stste_setcolreg;
printk("Cannot determine video hardware; defaulting to ST(e)\n"); dev_warn(&pdev->dev,
"Cannot determine video hardware; defaulting to ST(e)\n");
#else /* ATAFB_STE */ #else /* ATAFB_STE */
/* no default driver included */ /* no default driver included */
/* Nobody will ever see this message :-) */ /* Nobody will ever see this message :-) */
...@@ -3175,8 +3170,8 @@ int __init atafb_init(void) ...@@ -3175,8 +3170,8 @@ int __init atafb_init(void)
kernel_set_cachemode(screen_base, screen_len, kernel_set_cachemode(screen_base, screen_len,
IOMAP_WRITETHROUGH); IOMAP_WRITETHROUGH);
} }
printk("atafb: screen_base %p phys_screen_base %lx screen_len %d\n", dev_info(&pdev->dev, "phys_screen_base %lx screen_len %d\n",
screen_base, phys_screen_base, screen_len); phys_screen_base, screen_len);
#ifdef ATAFB_EXT #ifdef ATAFB_EXT
} else { } else {
/* Map the video memory (physical address given) to somewhere /* Map the video memory (physical address given) to somewhere
...@@ -3223,12 +3218,12 @@ int __init atafb_init(void) ...@@ -3223,12 +3218,12 @@ int __init atafb_init(void)
fb_alloc_cmap(&(fb_info.cmap), 1 << fb_info.var.bits_per_pixel, 0); fb_alloc_cmap(&(fb_info.cmap), 1 << fb_info.var.bits_per_pixel, 0);
printk("Determined %dx%d, depth %d\n", dev_info(&pdev->dev, "Determined %dx%d, depth %d\n", fb_info.var.xres,
fb_info.var.xres, fb_info.var.yres, fb_info.var.bits_per_pixel); fb_info.var.yres, fb_info.var.bits_per_pixel);
if ((fb_info.var.xres != fb_info.var.xres_virtual) || if ((fb_info.var.xres != fb_info.var.xres_virtual) ||
(fb_info.var.yres != fb_info.var.yres_virtual)) (fb_info.var.yres != fb_info.var.yres_virtual))
printk(" virtual %dx%d\n", fb_info.var.xres_virtual, dev_info(&pdev->dev, " virtual %dx%d\n",
fb_info.var.yres_virtual); fb_info.var.xres_virtual, fb_info.var.yres_virtual);
if (register_framebuffer(&fb_info) < 0) { if (register_framebuffer(&fb_info) < 0) {
#ifdef ATAFB_EXT #ifdef ATAFB_EXT
...@@ -3251,14 +3246,32 @@ int __init atafb_init(void) ...@@ -3251,14 +3246,32 @@ int __init atafb_init(void)
return 0; return 0;
} }
module_init(atafb_init); static void atafb_shutdown(struct platform_device *pdev)
{
/* Unblank before kexec */
if (fbhw->blank)
fbhw->blank(0);
}
#ifdef MODULE static struct platform_driver atafb_driver = {
MODULE_LICENSE("GPL"); .shutdown = atafb_shutdown,
.driver = {
.name = "atafb",
},
};
int cleanup_module(void) static int __init atafb_init(void)
{ {
unregister_framebuffer(&fb_info); struct platform_device *pdev;
return atafb_deinit();
if (!MACH_IS_ATARI)
return -ENODEV;
pdev = platform_device_register_simple("atafb", -1, NULL, 0);
if (IS_ERR(pdev))
return PTR_ERR(pdev);
return platform_driver_probe(&atafb_driver, atafb_probe);
} }
#endif /* MODULE */
device_initcall(atafb_init);
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
* more details. * more details.
*/ */
#include <linux/module.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/fb.h> #include <linux/fb.h>
...@@ -269,25 +268,3 @@ void atafb_iplan2p2_linefill(struct fb_info *info, u_long next_line, ...@@ -269,25 +268,3 @@ void atafb_iplan2p2_linefill(struct fb_info *info, u_long next_line,
if (width) if (width)
fill8_2col((u8 *)dest, fgcolor, bgcolor, *data); fill8_2col((u8 *)dest, fgcolor, bgcolor, *data);
} }
#ifdef MODULE
MODULE_LICENSE("GPL");
int init_module(void)
{
return 0;
}
void cleanup_module(void)
{
}
#endif /* MODULE */
/*
* Visible symbols for modules
*/
EXPORT_SYMBOL(atafb_iplan2p2_copyarea);
EXPORT_SYMBOL(atafb_iplan2p2_fillrect);
EXPORT_SYMBOL(atafb_iplan2p2_linefill);
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
* more details. * more details.
*/ */
#include <linux/module.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/fb.h> #include <linux/fb.h>
...@@ -284,25 +283,3 @@ void atafb_iplan2p4_linefill(struct fb_info *info, u_long next_line, ...@@ -284,25 +283,3 @@ void atafb_iplan2p4_linefill(struct fb_info *info, u_long next_line,
if (width) if (width)
fill8_2col((u8 *)dest, fgcolor, bgcolor, *data); fill8_2col((u8 *)dest, fgcolor, bgcolor, *data);
} }
#ifdef MODULE
MODULE_LICENSE("GPL");
int init_module(void)
{
return 0;
}
void cleanup_module(void)
{
}
#endif /* MODULE */
/*
* Visible symbols for modules
*/
EXPORT_SYMBOL(atafb_iplan2p4_copyarea);
EXPORT_SYMBOL(atafb_iplan2p4_fillrect);
EXPORT_SYMBOL(atafb_iplan2p4_linefill);
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
* more details. * more details.
*/ */
#include <linux/module.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/fb.h> #include <linux/fb.h>
...@@ -321,25 +320,3 @@ void atafb_iplan2p8_linefill(struct fb_info *info, u_long next_line, ...@@ -321,25 +320,3 @@ void atafb_iplan2p8_linefill(struct fb_info *info, u_long next_line,
if (width) if (width)
fill8_2col((u8 *)dest, fgcolor, bgcolor, *data); fill8_2col((u8 *)dest, fgcolor, bgcolor, *data);
} }
#ifdef MODULE
MODULE_LICENSE("GPL");
int init_module(void)
{
return 0;
}
void cleanup_module(void)
{
}
#endif /* MODULE */
/*
* Visible symbols for modules
*/
EXPORT_SYMBOL(atafb_iplan2p8_copyarea);
EXPORT_SYMBOL(atafb_iplan2p8_fillrect);
EXPORT_SYMBOL(atafb_iplan2p8_linefill);
...@@ -9,7 +9,6 @@ ...@@ -9,7 +9,6 @@
* more details. * more details.
*/ */
#include <linux/module.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/fb.h> #include <linux/fb.h>
...@@ -88,25 +87,3 @@ void atafb_mfb_linefill(struct fb_info *info, u_long next_line, ...@@ -88,25 +87,3 @@ void atafb_mfb_linefill(struct fb_info *info, u_long next_line,
*dest++ = *data++; *dest++ = *data++;
} }
} }
#ifdef MODULE
MODULE_LICENSE("GPL");
int init_module(void)
{
return 0;
}
void cleanup_module(void)
{
}
#endif /* MODULE */
/*
* Visible symbols for modules
*/
EXPORT_SYMBOL(atafb_mfb_copyarea);
EXPORT_SYMBOL(atafb_mfb_fillrect);
EXPORT_SYMBOL(atafb_mfb_linefill);
/* /*
* Driver for AT91/AT32 LCD Controller * Driver for AT91 LCD Controller
* *
* Copyright (C) 2007 Atmel Corporation * Copyright (C) 2007 Atmel Corporation
* *
...@@ -99,86 +99,6 @@ static struct atmel_lcdfb_config at91sam9rl_config = { ...@@ -99,86 +99,6 @@ static struct atmel_lcdfb_config at91sam9rl_config = {
.have_intensity_bit = true, .have_intensity_bit = true,
}; };
static struct atmel_lcdfb_config at32ap_config = {
.have_hozval = true,
};
static const struct platform_device_id atmel_lcdfb_devtypes[] = {
{
.name = "at91sam9261-lcdfb",
.driver_data = (unsigned long)&at91sam9261_config,
}, {
.name = "at91sam9263-lcdfb",
.driver_data = (unsigned long)&at91sam9263_config,
}, {
.name = "at91sam9g10-lcdfb",
.driver_data = (unsigned long)&at91sam9g10_config,
}, {
.name = "at91sam9g45-lcdfb",
.driver_data = (unsigned long)&at91sam9g45_config,
}, {
.name = "at91sam9g45es-lcdfb",
.driver_data = (unsigned long)&at91sam9g45es_config,
}, {
.name = "at91sam9rl-lcdfb",
.driver_data = (unsigned long)&at91sam9rl_config,
}, {
.name = "at32ap-lcdfb",
.driver_data = (unsigned long)&at32ap_config,
}, {
/* terminator */
}
};
MODULE_DEVICE_TABLE(platform, atmel_lcdfb_devtypes);
static struct atmel_lcdfb_config *
atmel_lcdfb_get_config(struct platform_device *pdev)
{
unsigned long data;
data = platform_get_device_id(pdev)->driver_data;
return (struct atmel_lcdfb_config *)data;
}
#if defined(CONFIG_ARCH_AT91)
#define ATMEL_LCDFB_FBINFO_DEFAULT (FBINFO_DEFAULT \
| FBINFO_PARTIAL_PAN_OK \
| FBINFO_HWACCEL_YPAN)
static inline void atmel_lcdfb_update_dma2d(struct atmel_lcdfb_info *sinfo,
struct fb_var_screeninfo *var,
struct fb_info *info)
{
}
#elif defined(CONFIG_AVR32)
#define ATMEL_LCDFB_FBINFO_DEFAULT (FBINFO_DEFAULT \
| FBINFO_PARTIAL_PAN_OK \
| FBINFO_HWACCEL_XPAN \
| FBINFO_HWACCEL_YPAN)
static void atmel_lcdfb_update_dma2d(struct atmel_lcdfb_info *sinfo,
struct fb_var_screeninfo *var,
struct fb_info *info)
{
u32 dma2dcfg;
u32 pixeloff;
pixeloff = (var->xoffset * info->var.bits_per_pixel) & 0x1f;
dma2dcfg = (info->var.xres_virtual - info->var.xres)
* info->var.bits_per_pixel / 8;
dma2dcfg |= pixeloff << ATMEL_LCDC_PIXELOFF_OFFSET;
lcdc_writel(sinfo, ATMEL_LCDC_DMA2DCFG, dma2dcfg);
/* Update configuration */
lcdc_writel(sinfo, ATMEL_LCDC_DMACON,
lcdc_readl(sinfo, ATMEL_LCDC_DMACON)
| ATMEL_LCDC_DMAUPDT);
}
#endif
static u32 contrast_ctr = ATMEL_LCDC_PS_DIV8 static u32 contrast_ctr = ATMEL_LCDC_PS_DIV8
| ATMEL_LCDC_POL_POSITIVE | ATMEL_LCDC_POL_POSITIVE
| ATMEL_LCDC_ENA_PWMENABLE; | ATMEL_LCDC_ENA_PWMENABLE;
...@@ -404,8 +324,6 @@ static void atmel_lcdfb_update_dma(struct fb_info *info, ...@@ -404,8 +324,6 @@ static void atmel_lcdfb_update_dma(struct fb_info *info,
/* Set framebuffer DMA base address and pixel offset */ /* Set framebuffer DMA base address and pixel offset */
lcdc_writel(sinfo, ATMEL_LCDC_DMABADDR1, dma_addr); lcdc_writel(sinfo, ATMEL_LCDC_DMABADDR1, dma_addr);
atmel_lcdfb_update_dma2d(sinfo, var, info);
} }
static inline void atmel_lcdfb_free_video_memory(struct atmel_lcdfb_info *sinfo) static inline void atmel_lcdfb_free_video_memory(struct atmel_lcdfb_info *sinfo)
...@@ -978,7 +896,6 @@ static void atmel_lcdfb_stop_clock(struct atmel_lcdfb_info *sinfo) ...@@ -978,7 +896,6 @@ static void atmel_lcdfb_stop_clock(struct atmel_lcdfb_info *sinfo)
clk_disable_unprepare(sinfo->lcdc_clk); clk_disable_unprepare(sinfo->lcdc_clk);
} }
#ifdef CONFIG_OF
static const struct of_device_id atmel_lcdfb_dt_ids[] = { static const struct of_device_id atmel_lcdfb_dt_ids[] = {
{ .compatible = "atmel,at91sam9261-lcdc" , .data = &at91sam9261_config, }, { .compatible = "atmel,at91sam9261-lcdc" , .data = &at91sam9261_config, },
{ .compatible = "atmel,at91sam9263-lcdc" , .data = &at91sam9263_config, }, { .compatible = "atmel,at91sam9263-lcdc" , .data = &at91sam9263_config, },
...@@ -986,7 +903,6 @@ static const struct of_device_id atmel_lcdfb_dt_ids[] = { ...@@ -986,7 +903,6 @@ static const struct of_device_id atmel_lcdfb_dt_ids[] = {
{ .compatible = "atmel,at91sam9g45-lcdc" , .data = &at91sam9g45_config, }, { .compatible = "atmel,at91sam9g45-lcdc" , .data = &at91sam9g45_config, },
{ .compatible = "atmel,at91sam9g45es-lcdc" , .data = &at91sam9g45es_config, }, { .compatible = "atmel,at91sam9g45es-lcdc" , .data = &at91sam9g45es_config, },
{ .compatible = "atmel,at91sam9rl-lcdc" , .data = &at91sam9rl_config, }, { .compatible = "atmel,at91sam9rl-lcdc" , .data = &at91sam9rl_config, },
{ .compatible = "atmel,at32ap-lcdc" , .data = &at32ap_config, },
{ /* sentinel */ } { /* sentinel */ }
}; };
...@@ -1122,19 +1038,12 @@ static int atmel_lcdfb_of_init(struct atmel_lcdfb_info *sinfo) ...@@ -1122,19 +1038,12 @@ static int atmel_lcdfb_of_init(struct atmel_lcdfb_info *sinfo)
of_node_put(display_np); of_node_put(display_np);
return ret; return ret;
} }
#else
static int atmel_lcdfb_of_init(struct atmel_lcdfb_info *sinfo)
{
return 0;
}
#endif
static int __init atmel_lcdfb_probe(struct platform_device *pdev) static int __init atmel_lcdfb_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct fb_info *info; struct fb_info *info;
struct atmel_lcdfb_info *sinfo; struct atmel_lcdfb_info *sinfo;
struct atmel_lcdfb_pdata *pdata = NULL;
struct resource *regs = NULL; struct resource *regs = NULL;
struct resource *map = NULL; struct resource *map = NULL;
struct fb_modelist *modelist; struct fb_modelist *modelist;
...@@ -1159,21 +1068,6 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev) ...@@ -1159,21 +1068,6 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)
ret = atmel_lcdfb_of_init(sinfo); ret = atmel_lcdfb_of_init(sinfo);
if (ret) if (ret)
goto free_info; goto free_info;
} else if (dev_get_platdata(dev)) {
struct fb_monspecs *monspecs;
int i;
pdata = dev_get_platdata(dev);
monspecs = pdata->default_monspecs;
sinfo->pdata = *pdata;
for (i = 0; i < monspecs->modedb_len; i++)
fb_add_videomode(&monspecs->modedb[i], &info->modelist);
sinfo->config = atmel_lcdfb_get_config(pdev);
info->var.bits_per_pixel = pdata->default_bpp ? pdata->default_bpp : 16;
memcpy(&info->monspecs, pdata->default_monspecs, sizeof(info->monspecs));
} else { } else {
dev_err(dev, "cannot get default configuration\n"); dev_err(dev, "cannot get default configuration\n");
goto free_info; goto free_info;
...@@ -1186,7 +1080,8 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev) ...@@ -1186,7 +1080,8 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)
if (IS_ERR(sinfo->reg_lcd)) if (IS_ERR(sinfo->reg_lcd))
sinfo->reg_lcd = NULL; sinfo->reg_lcd = NULL;
info->flags = ATMEL_LCDFB_FBINFO_DEFAULT; info->flags = FBINFO_DEFAULT | FBINFO_PARTIAL_PAN_OK |
FBINFO_HWACCEL_YPAN;
info->pseudo_palette = sinfo->pseudo_palette; info->pseudo_palette = sinfo->pseudo_palette;
info->fbops = &atmel_lcdfb_ops; info->fbops = &atmel_lcdfb_ops;
...@@ -1357,12 +1252,10 @@ static int __exit atmel_lcdfb_remove(struct platform_device *pdev) ...@@ -1357,12 +1252,10 @@ static int __exit atmel_lcdfb_remove(struct platform_device *pdev)
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct fb_info *info = dev_get_drvdata(dev); struct fb_info *info = dev_get_drvdata(dev);
struct atmel_lcdfb_info *sinfo; struct atmel_lcdfb_info *sinfo;
struct atmel_lcdfb_pdata *pdata;
if (!info || !info->par) if (!info || !info->par)
return 0; return 0;
sinfo = info->par; sinfo = info->par;
pdata = &sinfo->pdata;
cancel_work_sync(&sinfo->task); cancel_work_sync(&sinfo->task);
exit_backlight(sinfo); exit_backlight(sinfo);
...@@ -1435,7 +1328,6 @@ static struct platform_driver atmel_lcdfb_driver = { ...@@ -1435,7 +1328,6 @@ static struct platform_driver atmel_lcdfb_driver = {
.remove = __exit_p(atmel_lcdfb_remove), .remove = __exit_p(atmel_lcdfb_remove),
.suspend = atmel_lcdfb_suspend, .suspend = atmel_lcdfb_suspend,
.resume = atmel_lcdfb_resume, .resume = atmel_lcdfb_resume,
.id_table = atmel_lcdfb_devtypes,
.driver = { .driver = {
.name = "atmel_lcdfb", .name = "atmel_lcdfb",
.of_match_table = of_match_ptr(atmel_lcdfb_dt_ids), .of_match_table = of_match_ptr(atmel_lcdfb_dt_ids),
...@@ -1444,6 +1336,6 @@ static struct platform_driver atmel_lcdfb_driver = { ...@@ -1444,6 +1336,6 @@ static struct platform_driver atmel_lcdfb_driver = {
module_platform_driver_probe(atmel_lcdfb_driver, atmel_lcdfb_probe); module_platform_driver_probe(atmel_lcdfb_driver, atmel_lcdfb_probe);
MODULE_DESCRIPTION("AT91/AT32 LCD Controller framebuffer driver"); MODULE_DESCRIPTION("AT91 LCD Controller framebuffer driver");
MODULE_AUTHOR("Nicolas Ferre <nicolas.ferre@atmel.com>"); MODULE_AUTHOR("Nicolas Ferre <nicolas.ferre@atmel.com>");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -94,6 +94,8 @@ int fb_alloc_cmap_gfp(struct fb_cmap *cmap, int len, int transp, gfp_t flags) ...@@ -94,6 +94,8 @@ int fb_alloc_cmap_gfp(struct fb_cmap *cmap, int len, int transp, gfp_t flags)
int size = len * sizeof(u16); int size = len * sizeof(u16);
int ret = -ENOMEM; int ret = -ENOMEM;
flags |= __GFP_NOWARN;
if (cmap->len != len) { if (cmap->len != len) {
fb_dealloc_cmap(cmap); fb_dealloc_cmap(cmap);
if (!len) if (!len)
......
...@@ -1069,7 +1069,7 @@ static void fbcon_init(struct vc_data *vc, int init) ...@@ -1069,7 +1069,7 @@ static void fbcon_init(struct vc_data *vc, int init)
cap = info->flags; cap = info->flags;
if (console_loglevel <= CONSOLE_LOGLEVEL_QUIET) if (logo_shown < 0 && console_loglevel <= CONSOLE_LOGLEVEL_QUIET)
logo_shown = FBCON_LOGO_DONTSHOW; logo_shown = FBCON_LOGO_DONTSHOW;
if (vc != svc || logo_shown == FBCON_LOGO_DONTSHOW || if (vc != svc || logo_shown == FBCON_LOGO_DONTSHOW ||
......
...@@ -1882,14 +1882,35 @@ int remove_conflicting_pci_framebuffers(struct pci_dev *pdev, int res_id, const ...@@ -1882,14 +1882,35 @@ int remove_conflicting_pci_framebuffers(struct pci_dev *pdev, int res_id, const
{ {
struct apertures_struct *ap; struct apertures_struct *ap;
bool primary = false; bool primary = false;
int err; int err, idx, bar;
bool res_id_found = false;
for (idx = 0, bar = 0; bar < PCI_ROM_RESOURCE; bar++) {
if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM))
continue;
idx++;
}
ap = alloc_apertures(1); ap = alloc_apertures(idx);
if (!ap) if (!ap)
return -ENOMEM; return -ENOMEM;
ap->ranges[0].base = pci_resource_start(pdev, res_id); for (idx = 0, bar = 0; bar < PCI_ROM_RESOURCE; bar++) {
ap->ranges[0].size = pci_resource_len(pdev, res_id); if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM))
continue;
ap->ranges[idx].base = pci_resource_start(pdev, bar);
ap->ranges[idx].size = pci_resource_len(pdev, bar);
pci_info(pdev, "%s: bar %d: 0x%lx -> 0x%lx\n", __func__, bar,
(unsigned long)pci_resource_start(pdev, bar),
(unsigned long)pci_resource_end(pdev, bar));
idx++;
if (res_id == bar)
res_id_found = true;
}
if (!res_id_found)
pci_warn(pdev, "%s: passed res_id (%d) is not a memory bar\n",
__func__, res_id);
#ifdef CONFIG_X86 #ifdef CONFIG_X86
primary = pdev->resource[PCI_ROM_RESOURCE].flags & primary = pdev->resource[PCI_ROM_RESOURCE].flags &
IORESOURCE_ROM_SHADOW; IORESOURCE_ROM_SHADOW;
......
...@@ -935,6 +935,9 @@ void fb_var_to_videomode(struct fb_videomode *mode, ...@@ -935,6 +935,9 @@ void fb_var_to_videomode(struct fb_videomode *mode,
if (var->vmode & FB_VMODE_DOUBLE) if (var->vmode & FB_VMODE_DOUBLE)
vtotal *= 2; vtotal *= 2;
if (!htotal || !vtotal)
return;
hfreq = pixclock/htotal; hfreq = pixclock/htotal;
mode->refresh = hfreq/vtotal; mode->refresh = hfreq/vtotal;
} }
......
...@@ -285,6 +285,8 @@ static int hga_card_detect(void) ...@@ -285,6 +285,8 @@ static int hga_card_detect(void)
hga_vram_len = 0x08000; hga_vram_len = 0x08000;
hga_vram = ioremap(0xb0000, hga_vram_len); hga_vram = ioremap(0xb0000, hga_vram_len);
if (!hga_vram)
goto error;
if (request_region(0x3b0, 12, "hgafb")) if (request_region(0x3b0, 12, "hgafb"))
release_io_ports = 1; release_io_ports = 1;
......
...@@ -1515,6 +1515,11 @@ static int imsttfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1515,6 +1515,11 @@ static int imsttfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
info->fix.smem_start = addr; info->fix.smem_start = addr;
info->screen_base = (__u8 *)ioremap(addr, par->ramdac == IBM ? info->screen_base = (__u8 *)ioremap(addr, par->ramdac == IBM ?
0x400000 : 0x800000); 0x400000 : 0x800000);
if (!info->screen_base) {
release_mem_region(addr, size);
framebuffer_release(info);
return -ENOMEM;
}
info->fix.mmio_start = addr + 0x800000; info->fix.mmio_start = addr + 0x800000;
par->dc_regs = ioremap(addr + 0x800000, 0x1000); par->dc_regs = ioremap(addr + 0x800000, 0x1000);
par->cmap_regs_phys = addr + 0x840000; par->cmap_regs_phys = addr + 0x840000;
......
...@@ -120,10 +120,7 @@ struct jet_cmap_regs { ...@@ -120,10 +120,7 @@ struct jet_cmap_regs {
#define PIXEL_TO_MM(a) (((a)*10)/28) /* width in mm at 72 dpi */ #define PIXEL_TO_MM(a) (((a)*10)/28) /* width in mm at 72 dpi */
static struct fb_var_screeninfo macfb_defined = { static struct fb_var_screeninfo macfb_defined = {
.bits_per_pixel = 8,
.activate = FB_ACTIVATE_NOW, .activate = FB_ACTIVATE_NOW,
.width = -1,
.height = -1,
.right_margin = 32, .right_margin = 32,
.upper_margin = 16, .upper_margin = 16,
.lower_margin = 4, .lower_margin = 4,
...@@ -139,7 +136,6 @@ static struct fb_fix_screeninfo macfb_fix = { ...@@ -139,7 +136,6 @@ static struct fb_fix_screeninfo macfb_fix = {
static void *slot_addr; static void *slot_addr;
static struct fb_info fb_info; static struct fb_info fb_info;
static u32 pseudo_palette[16]; static u32 pseudo_palette[16];
static int inverse;
static int vidtest; static int vidtest;
/* /*
...@@ -152,7 +148,7 @@ static int dafb_setpalette(unsigned int regno, unsigned int red, ...@@ -152,7 +148,7 @@ static int dafb_setpalette(unsigned int regno, unsigned int red,
unsigned int green, unsigned int blue, unsigned int green, unsigned int blue,
struct fb_info *info) struct fb_info *info)
{ {
static int lastreg = -1; static int lastreg = -2;
unsigned long flags; unsigned long flags;
local_irq_save(flags); local_irq_save(flags);
...@@ -201,9 +197,6 @@ static int v8_brazil_setpalette(unsigned int regno, unsigned int red, ...@@ -201,9 +197,6 @@ static int v8_brazil_setpalette(unsigned int regno, unsigned int red,
unsigned int bpp = info->var.bits_per_pixel; unsigned int bpp = info->var.bits_per_pixel;
unsigned long flags; unsigned long flags;
if (bpp > 8)
return 1; /* failsafe */
local_irq_save(flags); local_irq_save(flags);
/* On these chips, the CLUT register numbers are spread out /* On these chips, the CLUT register numbers are spread out
...@@ -234,9 +227,6 @@ static int rbv_setpalette(unsigned int regno, unsigned int red, ...@@ -234,9 +227,6 @@ static int rbv_setpalette(unsigned int regno, unsigned int red,
{ {
unsigned long flags; unsigned long flags;
if (info->var.bits_per_pixel > 8)
return 1; /* failsafe */
local_irq_save(flags); local_irq_save(flags);
/* From the VideoToolbox driver. Seems to be saying that /* From the VideoToolbox driver. Seems to be saying that
...@@ -353,9 +343,6 @@ static int civic_setpalette(unsigned int regno, unsigned int red, ...@@ -353,9 +343,6 @@ static int civic_setpalette(unsigned int regno, unsigned int red,
unsigned long flags; unsigned long flags;
int clut_status; int clut_status;
if (info->var.bits_per_pixel > 8)
return 1; /* failsafe */
local_irq_save(flags); local_irq_save(flags);
/* Set the register address */ /* Set the register address */
...@@ -532,7 +519,7 @@ static void __init macfb_setup(char *options) ...@@ -532,7 +519,7 @@ static void __init macfb_setup(char *options)
continue; continue;
if (!strcmp(this_opt, "inverse")) if (!strcmp(this_opt, "inverse"))
inverse = 1; fb_invert_cmaps();
else else
if (!strcmp(this_opt, "vidtest")) if (!strcmp(this_opt, "vidtest"))
vidtest = 1; /* enable experimental CLUT code */ vidtest = 1; /* enable experimental CLUT code */
...@@ -688,17 +675,14 @@ static int __init macfb_init(void) ...@@ -688,17 +675,14 @@ static int __init macfb_init(void)
case NUBUS_DRHW_APPLE_MDC: case NUBUS_DRHW_APPLE_MDC:
strcpy(macfb_fix.id, "Mac Disp. Card"); strcpy(macfb_fix.id, "Mac Disp. Card");
macfb_setpalette = mdc_setpalette; macfb_setpalette = mdc_setpalette;
macfb_defined.activate = FB_ACTIVATE_NOW;
break; break;
case NUBUS_DRHW_APPLE_TFB: case NUBUS_DRHW_APPLE_TFB:
strcpy(macfb_fix.id, "Toby"); strcpy(macfb_fix.id, "Toby");
macfb_setpalette = toby_setpalette; macfb_setpalette = toby_setpalette;
macfb_defined.activate = FB_ACTIVATE_NOW;
break; break;
case NUBUS_DRHW_APPLE_JET: case NUBUS_DRHW_APPLE_JET:
strcpy(macfb_fix.id, "Jet"); strcpy(macfb_fix.id, "Jet");
macfb_setpalette = jet_setpalette; macfb_setpalette = jet_setpalette;
macfb_defined.activate = FB_ACTIVATE_NOW;
break; break;
default: default:
strcpy(macfb_fix.id, "Generic NuBus"); strcpy(macfb_fix.id, "Generic NuBus");
...@@ -731,7 +715,6 @@ static int __init macfb_init(void) ...@@ -731,7 +715,6 @@ static int __init macfb_init(void)
strcpy(macfb_fix.id, "DAFB"); strcpy(macfb_fix.id, "DAFB");
macfb_setpalette = dafb_setpalette; macfb_setpalette = dafb_setpalette;
dafb_cmap_regs = ioremap(DAFB_BASE, 0x1000); dafb_cmap_regs = ioremap(DAFB_BASE, 0x1000);
macfb_defined.activate = FB_ACTIVATE_NOW;
break; break;
/* /*
...@@ -741,7 +724,6 @@ static int __init macfb_init(void) ...@@ -741,7 +724,6 @@ static int __init macfb_init(void)
strcpy(macfb_fix.id, "V8"); strcpy(macfb_fix.id, "V8");
macfb_setpalette = v8_brazil_setpalette; macfb_setpalette = v8_brazil_setpalette;
v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000); v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
macfb_defined.activate = FB_ACTIVATE_NOW;
break; break;
/* /*
...@@ -755,7 +737,6 @@ static int __init macfb_init(void) ...@@ -755,7 +737,6 @@ static int __init macfb_init(void)
strcpy(macfb_fix.id, "Brazil"); strcpy(macfb_fix.id, "Brazil");
macfb_setpalette = v8_brazil_setpalette; macfb_setpalette = v8_brazil_setpalette;
v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000); v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
macfb_defined.activate = FB_ACTIVATE_NOW;
break; break;
/* /*
...@@ -772,7 +753,6 @@ static int __init macfb_init(void) ...@@ -772,7 +753,6 @@ static int __init macfb_init(void)
strcpy(macfb_fix.id, "Sonora"); strcpy(macfb_fix.id, "Sonora");
macfb_setpalette = v8_brazil_setpalette; macfb_setpalette = v8_brazil_setpalette;
v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000); v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
macfb_defined.activate = FB_ACTIVATE_NOW;
break; break;
/* /*
...@@ -785,7 +765,6 @@ static int __init macfb_init(void) ...@@ -785,7 +765,6 @@ static int __init macfb_init(void)
strcpy(macfb_fix.id, "RBV"); strcpy(macfb_fix.id, "RBV");
macfb_setpalette = rbv_setpalette; macfb_setpalette = rbv_setpalette;
rbv_cmap_regs = ioremap(DAC_BASE, 0x1000); rbv_cmap_regs = ioremap(DAC_BASE, 0x1000);
macfb_defined.activate = FB_ACTIVATE_NOW;
break; break;
/* /*
...@@ -796,7 +775,6 @@ static int __init macfb_init(void) ...@@ -796,7 +775,6 @@ static int __init macfb_init(void)
strcpy(macfb_fix.id, "Civic"); strcpy(macfb_fix.id, "Civic");
macfb_setpalette = civic_setpalette; macfb_setpalette = civic_setpalette;
civic_cmap_regs = ioremap(CIVIC_BASE, 0x1000); civic_cmap_regs = ioremap(CIVIC_BASE, 0x1000);
macfb_defined.activate = FB_ACTIVATE_NOW;
break; break;
...@@ -810,7 +788,6 @@ static int __init macfb_init(void) ...@@ -810,7 +788,6 @@ static int __init macfb_init(void)
macfb_setpalette = v8_brazil_setpalette; macfb_setpalette = v8_brazil_setpalette;
v8_brazil_cmap_regs = v8_brazil_cmap_regs =
ioremap(DAC_BASE, 0x1000); ioremap(DAC_BASE, 0x1000);
macfb_defined.activate = FB_ACTIVATE_NOW;
} }
break; break;
...@@ -823,7 +800,6 @@ static int __init macfb_init(void) ...@@ -823,7 +800,6 @@ static int __init macfb_init(void)
macfb_setpalette = v8_brazil_setpalette; macfb_setpalette = v8_brazil_setpalette;
v8_brazil_cmap_regs = v8_brazil_cmap_regs =
ioremap(DAC_BASE, 0x1000); ioremap(DAC_BASE, 0x1000);
macfb_defined.activate = FB_ACTIVATE_NOW;
} }
break; break;
...@@ -892,7 +868,6 @@ static int __init macfb_init(void) ...@@ -892,7 +868,6 @@ static int __init macfb_init(void)
strcpy(macfb_fix.id, "CSC"); strcpy(macfb_fix.id, "CSC");
macfb_setpalette = csc_setpalette; macfb_setpalette = csc_setpalette;
csc_cmap_regs = ioremap(CSC_BASE, 0x1000); csc_cmap_regs = ioremap(CSC_BASE, 0x1000);
macfb_defined.activate = FB_ACTIVATE_NOW;
break; break;
default: default:
......
...@@ -181,6 +181,7 @@ struct mxsfb_info { ...@@ -181,6 +181,7 @@ struct mxsfb_info {
const struct mxsfb_devdata *devdata; const struct mxsfb_devdata *devdata;
u32 sync; u32 sync;
struct regulator *reg_lcd; struct regulator *reg_lcd;
int pre_init;
}; };
#define mxsfb_is_v3(host) (host->devdata->ipversion == 3) #define mxsfb_is_v3(host) (host->devdata->ipversion == 3)
...@@ -419,6 +420,12 @@ static int mxsfb_set_par(struct fb_info *fb_info) ...@@ -419,6 +420,12 @@ static int mxsfb_set_par(struct fb_info *fb_info)
fb_info->fix.line_length = line_size; fb_info->fix.line_length = line_size;
if (host->pre_init) {
mxsfb_enable_controller(fb_info);
host->pre_init = 0;
return 0;
}
/* /*
* It seems, you can't re-program the controller if it is still running. * It seems, you can't re-program the controller if it is still running.
* This may lead into shifted pictures (FIFO issue?). * This may lead into shifted pictures (FIFO issue?).
...@@ -623,7 +630,6 @@ static int mxsfb_restore_mode(struct fb_info *fb_info, ...@@ -623,7 +630,6 @@ static int mxsfb_restore_mode(struct fb_info *fb_info,
struct fb_videomode *vmode) struct fb_videomode *vmode)
{ {
struct mxsfb_info *host = fb_info->par; struct mxsfb_info *host = fb_info->par;
unsigned line_count;
unsigned period; unsigned period;
unsigned long pa, fbsize; unsigned long pa, fbsize;
int bits_per_pixel, ofs, ret = 0; int bits_per_pixel, ofs, ret = 0;
...@@ -710,7 +716,6 @@ static int mxsfb_restore_mode(struct fb_info *fb_info, ...@@ -710,7 +716,6 @@ static int mxsfb_restore_mode(struct fb_info *fb_info,
writel(fb_info->fix.smem_start, host->base + host->devdata->next_buf); writel(fb_info->fix.smem_start, host->base + host->devdata->next_buf);
} }
line_count = fb_info->fix.smem_len / fb_info->fix.line_length;
fb_info->fix.ypanstep = 1; fb_info->fix.ypanstep = 1;
clk_prepare_enable(host->clk); clk_prepare_enable(host->clk);
...@@ -931,6 +936,10 @@ static int mxsfb_probe(struct platform_device *pdev) ...@@ -931,6 +936,10 @@ static int mxsfb_probe(struct platform_device *pdev)
if (IS_ERR(host->reg_lcd)) if (IS_ERR(host->reg_lcd))
host->reg_lcd = NULL; host->reg_lcd = NULL;
#if defined(CONFIG_FB_PRE_INIT_FB)
host->pre_init = 1;
#endif
fb_info->pseudo_palette = devm_kcalloc(&pdev->dev, 16, sizeof(u32), fb_info->pseudo_palette = devm_kcalloc(&pdev->dev, 16, sizeof(u32),
GFP_KERNEL); GFP_KERNEL);
if (!fb_info->pseudo_palette) { if (!fb_info->pseudo_palette) {
...@@ -963,6 +972,7 @@ static int mxsfb_probe(struct platform_device *pdev) ...@@ -963,6 +972,7 @@ static int mxsfb_probe(struct platform_device *pdev)
mxsfb_enable_controller(fb_info); mxsfb_enable_controller(fb_info);
} }
host->pre_init = 0;
dev_info(&pdev->dev, "initialized\n"); dev_info(&pdev->dev, "initialized\n");
return 0; return 0;
......
...@@ -455,7 +455,7 @@ static int nuc900fb_cpufreq_transition(struct notifier_block *nb, ...@@ -455,7 +455,7 @@ static int nuc900fb_cpufreq_transition(struct notifier_block *nb,
struct fb_info *fbinfo; struct fb_info *fbinfo;
long delta_f; long delta_f;
info = container_of(nb, struct nuc900fb_info, freq_transition); info = container_of(nb, struct nuc900fb_info, freq_transition);
fbinfo = platform_get_drvdata(to_platform_device(info->dev)); fbinfo = dev_get_drvdata(info->dev);
delta_f = info->clk_rate - clk_get_rate(info->clk); delta_f = info->clk_rate - clk_get_rate(info->clk);
......
...@@ -57,5 +57,3 @@ config FB_OMAP_DMA_TUNE ...@@ -57,5 +57,3 @@ config FB_OMAP_DMA_TUNE
If you have such a system and want to use rotation If you have such a system and want to use rotation
answer yes. Answer no if you have a dedicated video answer yes. Answer no if you have a dedicated video
memory, or don't use any of the accelerated features. memory, or don't use any of the accelerated features.
...@@ -111,6 +111,8 @@ static void __init omapdss_omapify_node(struct device_node *node) ...@@ -111,6 +111,8 @@ static void __init omapdss_omapify_node(struct device_node *node)
new_len = prop->length + strlen(prefix) * num_strs; new_len = prop->length + strlen(prefix) * num_strs;
new_compat = kmalloc(new_len, GFP_KERNEL); new_compat = kmalloc(new_len, GFP_KERNEL);
if (!new_compat)
return;
omapdss_prefix_strcpy(new_compat, new_len, prop->value, prop->length); omapdss_prefix_strcpy(new_compat, new_len, prop->value, prop->length);
...@@ -193,8 +195,10 @@ static int __init omapdss_boot_init(void) ...@@ -193,8 +195,10 @@ static int __init omapdss_boot_init(void)
dss = of_find_matching_node(NULL, omapdss_of_match); dss = of_find_matching_node(NULL, omapdss_of_match);
if (dss == NULL || !of_device_is_available(dss)) if (dss == NULL || !of_device_is_available(dss)) {
of_node_put(dss);
return 0; return 0;
}
omapdss_walk_device(dss, true); omapdss_walk_device(dss, true);
......
...@@ -1071,7 +1071,6 @@ static struct pvr2_board { ...@@ -1071,7 +1071,6 @@ static struct pvr2_board {
static int __init pvr2fb_init(void) static int __init pvr2fb_init(void)
{ {
int i, ret = -ENODEV; int i, ret = -ENODEV;
int size;
#ifndef MODULE #ifndef MODULE
char *option = NULL; char *option = NULL;
...@@ -1080,7 +1079,6 @@ static int __init pvr2fb_init(void) ...@@ -1080,7 +1079,6 @@ static int __init pvr2fb_init(void)
return -ENODEV; return -ENODEV;
pvr2fb_setup(option); pvr2fb_setup(option);
#endif #endif
size = sizeof(struct fb_info) + sizeof(struct pvr2fb_par) + 16 * sizeof(u32);
fb_info = framebuffer_alloc(sizeof(struct pvr2fb_par), NULL); fb_info = framebuffer_alloc(sizeof(struct pvr2fb_par), NULL);
......
...@@ -777,7 +777,7 @@ static int s3c2410fb_cpufreq_transition(struct notifier_block *nb, ...@@ -777,7 +777,7 @@ static int s3c2410fb_cpufreq_transition(struct notifier_block *nb,
long delta_f; long delta_f;
info = container_of(nb, struct s3c2410fb_info, freq_transition); info = container_of(nb, struct s3c2410fb_info, freq_transition);
fbinfo = platform_get_drvdata(to_platform_device(info->dev)); fbinfo = dev_get_drvdata(info->dev);
/* work out change, <0 for speed-up */ /* work out change, <0 for speed-up */
delta_f = info->clk_rate - clk_get_rate(info->clk); delta_f = info->clk_rate - clk_get_rate(info->clk);
......
...@@ -16,14 +16,10 @@ ...@@ -16,14 +16,10 @@
#define FB_ACCEL_SMI_LYNX 88 #define FB_ACCEL_SMI_LYNX 88
#define SCREEN_X_RES 1024 #define SCREEN_X_RES 1024
#define SCREEN_Y_RES 600 #define SCREEN_Y_RES_PC 768
#define SCREEN_Y_RES_NETBOOK 600
#define SCREEN_BPP 16 #define SCREEN_BPP 16
/*Assume SM712 graphics chip has 4MB VRAM */
#define SM712_VIDEOMEMORYSIZE 0x00400000
/*Assume SM722 graphics chip has 8MB VRAM */
#define SM722_VIDEOMEMORYSIZE 0x00800000
#define dac_reg (0x3c8) #define dac_reg (0x3c8)
#define dac_val (0x3c9) #define dac_val (0x3c9)
......
This diff is collapsed.
...@@ -594,8 +594,7 @@ static int dlfb_render_hline(struct dlfb_data *dlfb, struct urb **urb_ptr, ...@@ -594,8 +594,7 @@ static int dlfb_render_hline(struct dlfb_data *dlfb, struct urb **urb_ptr,
return 0; return 0;
} }
static int dlfb_handle_damage(struct dlfb_data *dlfb, int x, int y, static int dlfb_handle_damage(struct dlfb_data *dlfb, int x, int y, int width, int height)
int width, int height, char *data)
{ {
int i, ret; int i, ret;
char *cmd; char *cmd;
...@@ -607,21 +606,29 @@ static int dlfb_handle_damage(struct dlfb_data *dlfb, int x, int y, ...@@ -607,21 +606,29 @@ static int dlfb_handle_damage(struct dlfb_data *dlfb, int x, int y,
start_cycles = get_cycles(); start_cycles = get_cycles();
mutex_lock(&dlfb->render_mutex);
aligned_x = DL_ALIGN_DOWN(x, sizeof(unsigned long)); aligned_x = DL_ALIGN_DOWN(x, sizeof(unsigned long));
width = DL_ALIGN_UP(width + (x-aligned_x), sizeof(unsigned long)); width = DL_ALIGN_UP(width + (x-aligned_x), sizeof(unsigned long));
x = aligned_x; x = aligned_x;
if ((width <= 0) || if ((width <= 0) ||
(x + width > dlfb->info->var.xres) || (x + width > dlfb->info->var.xres) ||
(y + height > dlfb->info->var.yres)) (y + height > dlfb->info->var.yres)) {
return -EINVAL; ret = -EINVAL;
goto unlock_ret;
}
if (!atomic_read(&dlfb->usb_active)) if (!atomic_read(&dlfb->usb_active)) {
return 0; ret = 0;
goto unlock_ret;
}
urb = dlfb_get_urb(dlfb); urb = dlfb_get_urb(dlfb);
if (!urb) if (!urb) {
return 0; ret = 0;
goto unlock_ret;
}
cmd = urb->transfer_buffer; cmd = urb->transfer_buffer;
for (i = y; i < y + height ; i++) { for (i = y; i < y + height ; i++) {
...@@ -641,7 +648,7 @@ static int dlfb_handle_damage(struct dlfb_data *dlfb, int x, int y, ...@@ -641,7 +648,7 @@ static int dlfb_handle_damage(struct dlfb_data *dlfb, int x, int y,
*cmd++ = 0xAF; *cmd++ = 0xAF;
/* Send partial buffer remaining before exiting */ /* Send partial buffer remaining before exiting */
len = cmd - (char *) urb->transfer_buffer; len = cmd - (char *) urb->transfer_buffer;
ret = dlfb_submit_urb(dlfb, urb, len); dlfb_submit_urb(dlfb, urb, len);
bytes_sent += len; bytes_sent += len;
} else } else
dlfb_urb_completion(urb); dlfb_urb_completion(urb);
...@@ -655,7 +662,55 @@ static int dlfb_handle_damage(struct dlfb_data *dlfb, int x, int y, ...@@ -655,7 +662,55 @@ static int dlfb_handle_damage(struct dlfb_data *dlfb, int x, int y,
>> 10)), /* Kcycles */ >> 10)), /* Kcycles */
&dlfb->cpu_kcycles_used); &dlfb->cpu_kcycles_used);
return 0; ret = 0;
unlock_ret:
mutex_unlock(&dlfb->render_mutex);
return ret;
}
static void dlfb_init_damage(struct dlfb_data *dlfb)
{
dlfb->damage_x = INT_MAX;
dlfb->damage_x2 = 0;
dlfb->damage_y = INT_MAX;
dlfb->damage_y2 = 0;
}
static void dlfb_damage_work(struct work_struct *w)
{
struct dlfb_data *dlfb = container_of(w, struct dlfb_data, damage_work);
int x, x2, y, y2;
spin_lock_irq(&dlfb->damage_lock);
x = dlfb->damage_x;
x2 = dlfb->damage_x2;
y = dlfb->damage_y;
y2 = dlfb->damage_y2;
dlfb_init_damage(dlfb);
spin_unlock_irq(&dlfb->damage_lock);
if (x < x2 && y < y2)
dlfb_handle_damage(dlfb, x, y, x2 - x, y2 - y);
}
static void dlfb_offload_damage(struct dlfb_data *dlfb, int x, int y, int width, int height)
{
unsigned long flags;
int x2 = x + width;
int y2 = y + height;
if (x >= x2 || y >= y2)
return;
spin_lock_irqsave(&dlfb->damage_lock, flags);
dlfb->damage_x = min(x, dlfb->damage_x);
dlfb->damage_x2 = max(x2, dlfb->damage_x2);
dlfb->damage_y = min(y, dlfb->damage_y);
dlfb->damage_y2 = max(y2, dlfb->damage_y2);
spin_unlock_irqrestore(&dlfb->damage_lock, flags);
schedule_work(&dlfb->damage_work);
} }
/* /*
...@@ -679,7 +734,7 @@ static ssize_t dlfb_ops_write(struct fb_info *info, const char __user *buf, ...@@ -679,7 +734,7 @@ static ssize_t dlfb_ops_write(struct fb_info *info, const char __user *buf,
(u32)info->var.yres); (u32)info->var.yres);
dlfb_handle_damage(dlfb, 0, start, info->var.xres, dlfb_handle_damage(dlfb, 0, start, info->var.xres,
lines, info->screen_base); lines);
} }
return result; return result;
...@@ -694,8 +749,8 @@ static void dlfb_ops_copyarea(struct fb_info *info, ...@@ -694,8 +749,8 @@ static void dlfb_ops_copyarea(struct fb_info *info,
sys_copyarea(info, area); sys_copyarea(info, area);
dlfb_handle_damage(dlfb, area->dx, area->dy, dlfb_offload_damage(dlfb, area->dx, area->dy,
area->width, area->height, info->screen_base); area->width, area->height);
} }
static void dlfb_ops_imageblit(struct fb_info *info, static void dlfb_ops_imageblit(struct fb_info *info,
...@@ -705,8 +760,8 @@ static void dlfb_ops_imageblit(struct fb_info *info, ...@@ -705,8 +760,8 @@ static void dlfb_ops_imageblit(struct fb_info *info,
sys_imageblit(info, image); sys_imageblit(info, image);
dlfb_handle_damage(dlfb, image->dx, image->dy, dlfb_offload_damage(dlfb, image->dx, image->dy,
image->width, image->height, info->screen_base); image->width, image->height);
} }
static void dlfb_ops_fillrect(struct fb_info *info, static void dlfb_ops_fillrect(struct fb_info *info,
...@@ -716,8 +771,8 @@ static void dlfb_ops_fillrect(struct fb_info *info, ...@@ -716,8 +771,8 @@ static void dlfb_ops_fillrect(struct fb_info *info,
sys_fillrect(info, rect); sys_fillrect(info, rect);
dlfb_handle_damage(dlfb, rect->dx, rect->dy, rect->width, dlfb_offload_damage(dlfb, rect->dx, rect->dy, rect->width,
rect->height, info->screen_base); rect->height);
} }
/* /*
...@@ -739,17 +794,19 @@ static void dlfb_dpy_deferred_io(struct fb_info *info, ...@@ -739,17 +794,19 @@ static void dlfb_dpy_deferred_io(struct fb_info *info,
int bytes_identical = 0; int bytes_identical = 0;
int bytes_rendered = 0; int bytes_rendered = 0;
mutex_lock(&dlfb->render_mutex);
if (!fb_defio) if (!fb_defio)
return; goto unlock_ret;
if (!atomic_read(&dlfb->usb_active)) if (!atomic_read(&dlfb->usb_active))
return; goto unlock_ret;
start_cycles = get_cycles(); start_cycles = get_cycles();
urb = dlfb_get_urb(dlfb); urb = dlfb_get_urb(dlfb);
if (!urb) if (!urb)
return; goto unlock_ret;
cmd = urb->transfer_buffer; cmd = urb->transfer_buffer;
...@@ -782,6 +839,8 @@ static void dlfb_dpy_deferred_io(struct fb_info *info, ...@@ -782,6 +839,8 @@ static void dlfb_dpy_deferred_io(struct fb_info *info,
atomic_add(((unsigned int) ((end_cycles - start_cycles) atomic_add(((unsigned int) ((end_cycles - start_cycles)
>> 10)), /* Kcycles */ >> 10)), /* Kcycles */
&dlfb->cpu_kcycles_used); &dlfb->cpu_kcycles_used);
unlock_ret:
mutex_unlock(&dlfb->render_mutex);
} }
static int dlfb_get_edid(struct dlfb_data *dlfb, char *edid, int len) static int dlfb_get_edid(struct dlfb_data *dlfb, char *edid, int len)
...@@ -859,8 +918,7 @@ static int dlfb_ops_ioctl(struct fb_info *info, unsigned int cmd, ...@@ -859,8 +918,7 @@ static int dlfb_ops_ioctl(struct fb_info *info, unsigned int cmd,
if (area.y > info->var.yres) if (area.y > info->var.yres)
area.y = info->var.yres; area.y = info->var.yres;
dlfb_handle_damage(dlfb, area.x, area.y, area.w, area.h, dlfb_handle_damage(dlfb, area.x, area.y, area.w, area.h);
info->screen_base);
} }
return 0; return 0;
...@@ -942,6 +1000,10 @@ static void dlfb_ops_destroy(struct fb_info *info) ...@@ -942,6 +1000,10 @@ static void dlfb_ops_destroy(struct fb_info *info)
{ {
struct dlfb_data *dlfb = info->par; struct dlfb_data *dlfb = info->par;
cancel_work_sync(&dlfb->damage_work);
mutex_destroy(&dlfb->render_mutex);
if (info->cmap.len != 0) if (info->cmap.len != 0)
fb_dealloc_cmap(&info->cmap); fb_dealloc_cmap(&info->cmap);
if (info->monspecs.modedb) if (info->monspecs.modedb)
...@@ -1065,8 +1127,7 @@ static int dlfb_ops_set_par(struct fb_info *info) ...@@ -1065,8 +1127,7 @@ static int dlfb_ops_set_par(struct fb_info *info)
pix_framebuffer[i] = 0x37e6; pix_framebuffer[i] = 0x37e6;
} }
dlfb_handle_damage(dlfb, 0, 0, info->var.xres, info->var.yres, dlfb_handle_damage(dlfb, 0, 0, info->var.xres, info->var.yres);
info->screen_base);
return 0; return 0;
} }
...@@ -1639,6 +1700,11 @@ static int dlfb_usb_probe(struct usb_interface *intf, ...@@ -1639,6 +1700,11 @@ static int dlfb_usb_probe(struct usb_interface *intf,
dlfb->ops = dlfb_ops; dlfb->ops = dlfb_ops;
info->fbops = &dlfb->ops; info->fbops = &dlfb->ops;
mutex_init(&dlfb->render_mutex);
dlfb_init_damage(dlfb);
spin_lock_init(&dlfb->damage_lock);
INIT_WORK(&dlfb->damage_work, dlfb_damage_work);
INIT_LIST_HEAD(&info->modelist); INIT_LIST_HEAD(&info->modelist);
if (!dlfb_alloc_urb_list(dlfb, WRITES_IN_FLIGHT, MAX_TRANSFER)) { if (!dlfb_alloc_urb_list(dlfb, WRITES_IN_FLIGHT, MAX_TRANSFER)) {
......
...@@ -1543,7 +1543,7 @@ static void uvesafb_ioremap(struct fb_info *info) ...@@ -1543,7 +1543,7 @@ static void uvesafb_ioremap(struct fb_info *info)
static ssize_t uvesafb_show_vbe_ver(struct device *dev, static ssize_t uvesafb_show_vbe_ver(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
struct fb_info *info = platform_get_drvdata(to_platform_device(dev)); struct fb_info *info = dev_get_drvdata(dev);
struct uvesafb_par *par = info->par; struct uvesafb_par *par = info->par;
return snprintf(buf, PAGE_SIZE, "%.4x\n", par->vbe_ib.vbe_version); return snprintf(buf, PAGE_SIZE, "%.4x\n", par->vbe_ib.vbe_version);
...@@ -1554,7 +1554,7 @@ static DEVICE_ATTR(vbe_version, S_IRUGO, uvesafb_show_vbe_ver, NULL); ...@@ -1554,7 +1554,7 @@ static DEVICE_ATTR(vbe_version, S_IRUGO, uvesafb_show_vbe_ver, NULL);
static ssize_t uvesafb_show_vbe_modes(struct device *dev, static ssize_t uvesafb_show_vbe_modes(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
struct fb_info *info = platform_get_drvdata(to_platform_device(dev)); struct fb_info *info = dev_get_drvdata(dev);
struct uvesafb_par *par = info->par; struct uvesafb_par *par = info->par;
int ret = 0, i; int ret = 0, i;
...@@ -1573,7 +1573,7 @@ static DEVICE_ATTR(vbe_modes, S_IRUGO, uvesafb_show_vbe_modes, NULL); ...@@ -1573,7 +1573,7 @@ static DEVICE_ATTR(vbe_modes, S_IRUGO, uvesafb_show_vbe_modes, NULL);
static ssize_t uvesafb_show_vendor(struct device *dev, static ssize_t uvesafb_show_vendor(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
struct fb_info *info = platform_get_drvdata(to_platform_device(dev)); struct fb_info *info = dev_get_drvdata(dev);
struct uvesafb_par *par = info->par; struct uvesafb_par *par = info->par;
if (par->vbe_ib.oem_vendor_name_ptr) if (par->vbe_ib.oem_vendor_name_ptr)
...@@ -1588,7 +1588,7 @@ static DEVICE_ATTR(oem_vendor, S_IRUGO, uvesafb_show_vendor, NULL); ...@@ -1588,7 +1588,7 @@ static DEVICE_ATTR(oem_vendor, S_IRUGO, uvesafb_show_vendor, NULL);
static ssize_t uvesafb_show_product_name(struct device *dev, static ssize_t uvesafb_show_product_name(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
struct fb_info *info = platform_get_drvdata(to_platform_device(dev)); struct fb_info *info = dev_get_drvdata(dev);
struct uvesafb_par *par = info->par; struct uvesafb_par *par = info->par;
if (par->vbe_ib.oem_product_name_ptr) if (par->vbe_ib.oem_product_name_ptr)
...@@ -1603,7 +1603,7 @@ static DEVICE_ATTR(oem_product_name, S_IRUGO, uvesafb_show_product_name, NULL); ...@@ -1603,7 +1603,7 @@ static DEVICE_ATTR(oem_product_name, S_IRUGO, uvesafb_show_product_name, NULL);
static ssize_t uvesafb_show_product_rev(struct device *dev, static ssize_t uvesafb_show_product_rev(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
struct fb_info *info = platform_get_drvdata(to_platform_device(dev)); struct fb_info *info = dev_get_drvdata(dev);
struct uvesafb_par *par = info->par; struct uvesafb_par *par = info->par;
if (par->vbe_ib.oem_product_rev_ptr) if (par->vbe_ib.oem_product_rev_ptr)
...@@ -1618,7 +1618,7 @@ static DEVICE_ATTR(oem_product_rev, S_IRUGO, uvesafb_show_product_rev, NULL); ...@@ -1618,7 +1618,7 @@ static DEVICE_ATTR(oem_product_rev, S_IRUGO, uvesafb_show_product_rev, NULL);
static ssize_t uvesafb_show_oem_string(struct device *dev, static ssize_t uvesafb_show_oem_string(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
struct fb_info *info = platform_get_drvdata(to_platform_device(dev)); struct fb_info *info = dev_get_drvdata(dev);
struct uvesafb_par *par = info->par; struct uvesafb_par *par = info->par;
if (par->vbe_ib.oem_string_ptr) if (par->vbe_ib.oem_string_ptr)
...@@ -1633,7 +1633,7 @@ static DEVICE_ATTR(oem_string, S_IRUGO, uvesafb_show_oem_string, NULL); ...@@ -1633,7 +1633,7 @@ static DEVICE_ATTR(oem_string, S_IRUGO, uvesafb_show_oem_string, NULL);
static ssize_t uvesafb_show_nocrtc(struct device *dev, static ssize_t uvesafb_show_nocrtc(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
struct fb_info *info = platform_get_drvdata(to_platform_device(dev)); struct fb_info *info = dev_get_drvdata(dev);
struct uvesafb_par *par = info->par; struct uvesafb_par *par = info->par;
return snprintf(buf, PAGE_SIZE, "%d\n", par->nocrtc); return snprintf(buf, PAGE_SIZE, "%d\n", par->nocrtc);
...@@ -1642,7 +1642,7 @@ static ssize_t uvesafb_show_nocrtc(struct device *dev, ...@@ -1642,7 +1642,7 @@ static ssize_t uvesafb_show_nocrtc(struct device *dev,
static ssize_t uvesafb_store_nocrtc(struct device *dev, static ssize_t uvesafb_store_nocrtc(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count) struct device_attribute *attr, const char *buf, size_t count)
{ {
struct fb_info *info = platform_get_drvdata(to_platform_device(dev)); struct fb_info *info = dev_get_drvdata(dev);
struct uvesafb_par *par = info->par; struct uvesafb_par *par = info->par;
if (count > 0) { if (count > 0) {
......
...@@ -337,7 +337,7 @@ static int vesafb_probe(struct platform_device *dev) ...@@ -337,7 +337,7 @@ static int vesafb_probe(struct platform_device *dev)
if (pmi_base[3]) { if (pmi_base[3]) {
printk(KERN_INFO "vesafb: pmi: ports = "); printk(KERN_INFO "vesafb: pmi: ports = ");
for (i = pmi_base[3]/2; pmi_base[i] != 0xffff; i++) for (i = pmi_base[3]/2; pmi_base[i] != 0xffff; i++)
printk("%x ",pmi_base[i]); printk("%x ", pmi_base[i]);
printk("\n"); printk("\n");
if (pmi_base[i] != 0xffff) { if (pmi_base[i] != 0xffff) {
/* /*
......
...@@ -677,7 +677,7 @@ static void xenfb_backend_changed(struct xenbus_device *dev, ...@@ -677,7 +677,7 @@ static void xenfb_backend_changed(struct xenbus_device *dev,
case XenbusStateClosed: case XenbusStateClosed:
if (dev->state == XenbusStateClosed) if (dev->state == XenbusStateClosed)
break; break;
/* Missed the backend's CLOSING state -- fallthrough */ /* fall through - Missed the backend's CLOSING state. */
case XenbusStateClosing: case XenbusStateClosing:
xenbus_frontend_closed(dev); xenbus_frontend_closed(dev);
break; break;
......
...@@ -124,38 +124,11 @@ struct clcd_board { ...@@ -124,38 +124,11 @@ struct clcd_board {
struct amba_device; struct amba_device;
struct clk; struct clk;
/**
* struct clcd_vendor_data - holds hardware (IP-block) vendor-specific
* variant information
*
* @clock_timregs: the CLCD needs to be clocked when accessing the
* timer registers, or the hardware will hang.
* @packed_24_bit_pixels: this variant supports 24bit packed pixel data,
* so that RGB accesses 3 bytes at a time, not just on even 32bit
* boundaries, packing the pixel data in memory. ST Microelectronics
* have this.
* @st_bitmux_control: ST Microelectronics have implemented output
* bit line multiplexing into the CLCD control register. This indicates
* that we need to use this.
* @init_board: custom board init function for this variant
* @init_panel: custom panel init function for this variant
*/
struct clcd_vendor_data {
bool clock_timregs;
bool packed_24_bit_pixels;
bool st_bitmux_control;
int (*init_board)(struct amba_device *adev,
struct clcd_board *board);
int (*init_panel)(struct clcd_fb *fb,
struct device_node *panel);
};
/* this data structure describes each frame buffer device we find */ /* this data structure describes each frame buffer device we find */
struct clcd_fb { struct clcd_fb {
struct fb_info fb; struct fb_info fb;
struct amba_device *dev; struct amba_device *dev;
struct clk *clk; struct clk *clk;
struct clcd_vendor_data *vendor;
struct clcd_panel *panel; struct clcd_panel *panel;
struct clcd_board *board; struct clcd_board *board;
void *board_data; void *board_data;
...@@ -257,10 +230,6 @@ static inline void clcdfb_decode(struct clcd_fb *fb, struct clcd_regs *regs) ...@@ -257,10 +230,6 @@ static inline void clcdfb_decode(struct clcd_fb *fb, struct clcd_regs *regs)
else else
val |= CNTL_LCDBPP16_444; val |= CNTL_LCDBPP16_444;
break; break;
case 24:
/* Modified variant supporting 24 bit packed pixels */
val |= CNTL_ST_LCDBPP24_PACKED;
break;
case 32: case 32:
val |= CNTL_LCDBPP24; val |= CNTL_LCDBPP24;
break; break;
......
...@@ -48,6 +48,13 @@ struct dlfb_data { ...@@ -48,6 +48,13 @@ struct dlfb_data {
int base8; int base8;
u32 pseudo_palette[256]; u32 pseudo_palette[256];
int blank_mode; /*one of FB_BLANK_ */ int blank_mode; /*one of FB_BLANK_ */
struct mutex render_mutex;
int damage_x;
int damage_y;
int damage_x2;
int damage_y2;
spinlock_t damage_lock;
struct work_struct damage_work;
struct fb_ops ops; struct fb_ops ops;
/* blit-only rendering path metrics, exposed through sysfs */ /* blit-only rendering path metrics, exposed through sysfs */
atomic_t bytes_rendered; /* raw pixel-bytes driver asked to render */ atomic_t bytes_rendered; /* raw pixel-bytes driver asked to render */
......
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