fbdev changes for 3.15 (main part)

Various fbdev fixes and improvements, but nothing big.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.14 (GNU/Linux)
 
 iQIcBAABAgAGBQJTPoIDAAoJEPo9qoy8lh71ScsQAI4sxk8ci/Al6uh3aOw90M+b
 Iy3MnBfjcItmtpmNUm8JJQ7ce5hfX2H8+uONu5iQCVLXZZyqDsIUtoJlZn2XCnEV
 3WFtHE12UwdiAiTYdinK6PH42A5G2U5RC2QMtPxAdm/QoKJgxI3ngsWJydFqWsRc
 wT7cFZ90ZybFc1+n5gcoXqoSfIm9ve/jTAVIzYCWRpqVUpsHbFGmK3t+MRaw4d6V
 AhJVYAwF5OJkB/QiKOiAmP1QytC7mKDtGy/GlQAZhrr924OK+/EVM1gUTdJEiE7x
 j1cZhQh5w/zisQE7N05ch5BTAZZRWMa5eUc/BbPal8sNwu3oK+WE5VOxClGLhCr/
 x3zq5Dzxr9r3xwonXILzUBqpGgmPuKPa0mAeknE0/tAgtqRvbLBttc1bp/sJj6/8
 6eNMEVg1SOg4387kR/kF4dRgeiLF9enrwNxVgm3rlJOXQQcpmqC7F4e9yiGdfqyr
 ZVzGYIvwErTLL/T/UBc6OTyGoG7Ifake1PEV8H0GWaF5uzIEZXoFJrEx7o9j9SR/
 H7qOcz7lm3YSmKB0tdgfBGMOnkOaWn+GMTW8N4M071PHyVEyJmz9uxLHQSiRRuMc
 Fwr1r2SyuxP1TmyIGT/Kyk2rApx/KP1TH/Z8MbFNL7J6VwgBzNrkIj1DbkngCODf
 VcbZiq04uICNKw8QsHtg
 =bavN
 -----END PGP SIGNATURE-----

Merge tag 'fbdev-main-3.15' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux

Pull fbdev changes from Tomi Valkeinen:
 "Various fbdev fixes and improvements, but nothing big"

* tag 'fbdev-main-3.15' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux: (38 commits)
  fbdev: Make the switch from generic to native driver less alarming
  Video: atmel: avoid the id of fix screen info is overwritten
  video: imxfb: Add DT default contrast control register property.
  video: atmel_lcdfb: ensure the hardware is initialized with the correct mode
  fbdev: vesafb: add dev->remove() callback
  fbdev: efifb: add dev->remove() callback
  video: pxa3xx-gcu: switch to devres functions
  video: pxa3xx-gcu: provide an empty .open call
  video: pxa3xx-gcu: pass around struct device *
  video: pxa3xx-gcu: rename some symbols
  sisfb: fix 1280x720 resolution support
  video: fbdev: uvesafb: Remove impossible code path in uvesafb_init_info
  video: fbdev: uvesafb: Remove redundant NULL check in uvesafb_remove
  fbdev: FB_OPENCORES should depend on HAS_DMA
  OMAPDSS: convert pixel clock to common videomode style
  OMAPDSS: Remove unused get_context_loss_count support
  OMAPDSS: use DISPC register to detect context loss
  video: da8xx-fb: Use "SIMPLE_DEV_PM_OPS" macro
  video: imxfb: Convert to SIMPLE_DEV_PM_OPS
  video: imxfb: Resolve mismatch between backlight/contrast
  ...
This commit is contained in:
Linus Torvalds 2014-04-04 21:28:36 -07:00
commit 8e0c083234
52 changed files with 709 additions and 886 deletions

View File

@ -15,8 +15,12 @@ Required nodes:
- fsl,pcr: LCDC PCR value
Optional properties:
- lcd-supply: Regulator for LCD supply voltage.
- fsl,dmacr: DMA Control Register value. This is optional. By default, the
register is not modified as recommended by the datasheet.
- fsl,lpccr: Contrast Control Register value. This property provides the
default value for the contrast control register.
If that property is ommited, the register is zeroed.
- fsl,lscr1: LCDC Sharp Configuration Register value.
Example:

View File

@ -21,6 +21,10 @@
#include <linux/mtd/physmap.h>
#include <linux/i2c.h>
#include <linux/irq.h>
#include <linux/regulator/fixed.h>
#include <linux/regulator/machine.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/time.h>
@ -195,14 +199,58 @@ static const struct imxi2c_platform_data mx27ads_i2c1_data __initconst = {
static struct i2c_board_info mx27ads_i2c_devices[] = {
};
void lcd_power(int on)
static void vgpio_set(struct gpio_chip *chip, unsigned offset, int value)
{
if (on)
if (value)
__raw_writew(PBC_BCTRL1_LCDON, PBC_BCTRL1_SET_REG);
else
__raw_writew(PBC_BCTRL1_LCDON, PBC_BCTRL1_CLEAR_REG);
}
static int vgpio_dir_out(struct gpio_chip *chip, unsigned offset, int value)
{
return 0;
}
#define MX27ADS_LCD_GPIO (6 * 32)
static struct regulator_consumer_supply mx27ads_lcd_regulator_consumer =
REGULATOR_SUPPLY("lcd", "imx-fb.0");
static struct regulator_init_data mx27ads_lcd_regulator_init_data = {
.constraints = {
.valid_ops_mask = REGULATOR_CHANGE_STATUS,
},
.consumer_supplies = &mx27ads_lcd_regulator_consumer,
.num_consumer_supplies = 1,
};
static struct fixed_voltage_config mx27ads_lcd_regulator_pdata = {
.supply_name = "LCD",
.microvolts = 3300000,
.gpio = MX27ADS_LCD_GPIO,
.init_data = &mx27ads_lcd_regulator_init_data,
};
static void __init mx27ads_regulator_init(void)
{
struct gpio_chip *vchip;
vchip = kzalloc(sizeof(*vchip), GFP_KERNEL);
vchip->owner = THIS_MODULE;
vchip->label = "LCD";
vchip->base = MX27ADS_LCD_GPIO;
vchip->ngpio = 1;
vchip->direction_output = vgpio_dir_out;
vchip->set = vgpio_set;
gpiochip_add(vchip);
platform_device_register_data(&platform_bus, "reg-fixed-voltage",
PLATFORM_DEVID_AUTO,
&mx27ads_lcd_regulator_pdata,
sizeof(mx27ads_lcd_regulator_pdata));
}
static struct imx_fb_videomode mx27ads_modes[] = {
{
.mode = {
@ -239,8 +287,6 @@ static const struct imx_fb_platform_data mx27ads_fb_data __initconst = {
.pwmr = 0x00A903FF,
.lscr1 = 0x00120300,
.dmacr = 0x00020010,
.lcd_power = lcd_power,
};
static int mx27ads_sdhc1_init(struct device *dev, irq_handler_t detect_irq,
@ -304,6 +350,7 @@ static void __init mx27ads_board_init(void)
i2c_register_board_info(1, mx27ads_i2c_devices,
ARRAY_SIZE(mx27ads_i2c_devices));
imx27_add_imx_i2c(1, &mx27ads_i2c1_data);
mx27ads_regulator_init();
imx27_add_imx_fb(&mx27ads_fb_data);
imx27_add_mxc_mmc(0, &sdhc1_pdata);
imx27_add_mxc_mmc(1, &sdhc2_pdata);

View File

@ -301,7 +301,6 @@ int __init omap_display_init(struct omap_dss_board_info *board_data)
board_data->version = ver;
board_data->dsi_enable_pads = omap_dsi_enable_pads;
board_data->dsi_disable_pads = omap_dsi_disable_pads;
board_data->get_context_loss_count = omap_pm_get_dev_context_loss_count;
board_data->set_min_bus_tput = omap_dss_set_min_bus_tput;
omap_display_device.dev.platform_data = board_data;

View File

@ -37,7 +37,7 @@ struct omap_connector {
void copy_timings_omap_to_drm(struct drm_display_mode *mode,
struct omap_video_timings *timings)
{
mode->clock = timings->pixel_clock;
mode->clock = timings->pixelclock / 1000;
mode->hdisplay = timings->x_res;
mode->hsync_start = mode->hdisplay + timings->hfp;
@ -68,7 +68,7 @@ void copy_timings_omap_to_drm(struct drm_display_mode *mode,
void copy_timings_drm_to_omap(struct omap_video_timings *timings,
struct drm_display_mode *mode)
{
timings->pixel_clock = mode->clock;
timings->pixelclock = mode->clock * 1000;
timings->x_res = mode->hdisplay;
timings->hfp = mode->hsync_start - mode->hdisplay;
@ -220,7 +220,7 @@ static int omap_connector_mode_valid(struct drm_connector *connector,
if (!r) {
/* check if vrefresh is still valid */
new_mode = drm_mode_duplicate(dev, mode);
new_mode->clock = timings.pixel_clock;
new_mode->clock = timings.pixelclock / 1000;
new_mode->vrefresh = 0;
if (mode->vrefresh == drm_mode_vrefresh(new_mode))
ret = MODE_OK;

View File

@ -967,7 +967,7 @@ config FB_PVR2
config FB_OPENCORES
tristate "OpenCores VGA/LCD core 2.0 framebuffer support"
depends on FB
depends on FB && HAS_DMA
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT

View File

@ -1190,12 +1190,12 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)
if (!sinfo->config)
goto free_info;
strcpy(info->fix.id, sinfo->pdev->name);
info->flags = ATMEL_LCDFB_FBINFO_DEFAULT;
info->pseudo_palette = sinfo->pseudo_palette;
info->fbops = &atmel_lcdfb_ops;
info->fix = atmel_lcdfb_fix;
strcpy(info->fix.id, sinfo->pdev->name);
/* Enable LCDC Clocks */
sinfo->bus_clk = clk_get(dev, "hclk");
@ -1298,6 +1298,12 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)
goto unregister_irqs;
}
ret = atmel_lcdfb_set_par(info);
if (ret < 0) {
dev_err(dev, "set par failed: %d\n", ret);
goto unregister_irqs;
}
dev_set_drvdata(dev, info);
/*

View File

@ -862,8 +862,8 @@ static int aty_var_to_crtc(const struct fb_info *info,
h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1;
if ((xres > 1600) || (yres > 1200)) {
FAIL("MACH64 chips are designed for max 1600x1200\n"
if ((xres > 1920) || (yres > 1200)) {
FAIL("MACH64 chips are designed for max 1920x1200\n"
"select another resolution.");
}
h_sync_strt = h_disp + var->right_margin;
@ -2653,7 +2653,8 @@ static int aty_init(struct fb_info *info)
FBINFO_HWACCEL_IMAGEBLIT |
FBINFO_HWACCEL_FILLRECT |
FBINFO_HWACCEL_COPYAREA |
FBINFO_HWACCEL_YPAN;
FBINFO_HWACCEL_YPAN |
FBINFO_READS_FAST;
#ifdef CONFIG_PMAC_BACKLIGHT
if (M64_HAS(G3_PB_1_1) && of_machine_is_compatible("PowerBook1,1")) {

View File

@ -4,6 +4,7 @@
*/
#include <linux/delay.h>
#include <asm/unaligned.h>
#include <linux/fb.h>
#include <video/mach64.h>
#include "atyfb.h"
@ -419,7 +420,7 @@ void atyfb_imageblit(struct fb_info *info, const struct fb_image *image)
u32 *pbitmap, dwords = (src_bytes + 3) / 4;
for (pbitmap = (u32*)(image->data); dwords; dwords--, pbitmap++) {
wait_for_fifo(1, par);
aty_st_le32(HOST_DATA0, le32_to_cpup(pbitmap), par);
aty_st_le32(HOST_DATA0, get_unaligned_le32(pbitmap), par);
}
}

View File

@ -5,6 +5,7 @@
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/string.h>
#include "../fb_draw.h"
#include <asm/io.h>
@ -157,24 +158,33 @@ static int atyfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
for (i = 0; i < height; i++) {
for (j = 0; j < width; j++) {
u16 l = 0xaaaa;
b = *src++;
m = *msk++;
switch (cursor->rop) {
case ROP_XOR:
// Upper 4 bits of mask data
fb_writeb(cursor_bits_lookup[(b ^ m) >> 4], dst++);
l = cursor_bits_lookup[(b ^ m) >> 4] |
// Lower 4 bits of mask
fb_writeb(cursor_bits_lookup[(b ^ m) & 0x0f],
dst++);
(cursor_bits_lookup[(b ^ m) & 0x0f] << 8);
break;
case ROP_COPY:
// Upper 4 bits of mask data
fb_writeb(cursor_bits_lookup[(b & m) >> 4], dst++);
l = cursor_bits_lookup[(b & m) >> 4] |
// Lower 4 bits of mask
fb_writeb(cursor_bits_lookup[(b & m) & 0x0f],
dst++);
(cursor_bits_lookup[(b & m) & 0x0f] << 8);
break;
}
/*
* If cursor size is not a multiple of 8 characters
* we must pad it with transparent pattern (0xaaaa).
*/
if ((j + 1) * 8 > cursor->image.width) {
l = comp(l, 0xaaaa,
(1 << ((cursor->image.width & 7) * 2)) - 1);
}
fb_writeb(l & 0xff, dst++);
fb_writeb(l >> 8, dst++);
}
dst += offset;
}

View File

@ -43,13 +43,22 @@
*/
static void
bitcpy(struct fb_info *p, unsigned long __iomem *dst, int dst_idx,
const unsigned long __iomem *src, int src_idx, int bits,
bitcpy(struct fb_info *p, unsigned long __iomem *dst, unsigned dst_idx,
const unsigned long __iomem *src, unsigned src_idx, int bits,
unsigned n, u32 bswapmask)
{
unsigned long first, last;
int const shift = dst_idx-src_idx;
int left, right;
#if 0
/*
* If you suspect bug in this function, compare it with this simple
* memmove implementation.
*/
fb_memmove((char *)dst + ((dst_idx & (bits - 1))) / 8,
(char *)src + ((src_idx & (bits - 1))) / 8, n / 8);
return;
#endif
first = fb_shifted_pixels_mask_long(p, dst_idx, bswapmask);
last = ~fb_shifted_pixels_mask_long(p, (dst_idx+n) % bits, bswapmask);
@ -98,9 +107,8 @@ bitcpy(struct fb_info *p, unsigned long __iomem *dst, int dst_idx,
unsigned long d0, d1;
int m;
right = shift & (bits - 1);
left = -shift & (bits - 1);
bswapmask &= shift;
int const left = shift & (bits - 1);
int const right = -shift & (bits - 1);
if (dst_idx+n <= bits) {
// Single destination word
@ -110,15 +118,15 @@ bitcpy(struct fb_info *p, unsigned long __iomem *dst, int dst_idx,
d0 = fb_rev_pixels_in_long(d0, bswapmask);
if (shift > 0) {
// Single source word
d0 >>= right;
d0 <<= left;
} else if (src_idx+n <= bits) {
// Single source word
d0 <<= left;
d0 >>= right;
} else {
// 2 source words
d1 = FB_READL(src + 1);
d1 = fb_rev_pixels_in_long(d1, bswapmask);
d0 = d0<<left | d1>>right;
d0 = d0 >> right | d1 << left;
}
d0 = fb_rev_pixels_in_long(d0, bswapmask);
FB_WRITEL(comp(d0, FB_READL(dst), first), dst);
@ -135,60 +143,59 @@ bitcpy(struct fb_info *p, unsigned long __iomem *dst, int dst_idx,
if (shift > 0) {
// Single source word
d1 = d0;
d0 >>= right;
dst++;
d0 <<= left;
n -= bits - dst_idx;
} else {
// 2 source words
d1 = FB_READL(src++);
d1 = fb_rev_pixels_in_long(d1, bswapmask);
d0 = d0<<left | d1>>right;
dst++;
d0 = d0 >> right | d1 << left;
n -= bits - dst_idx;
}
d0 = fb_rev_pixels_in_long(d0, bswapmask);
FB_WRITEL(comp(d0, FB_READL(dst), first), dst);
d0 = d1;
dst++;
// Main chunk
m = n % bits;
n /= bits;
while ((n >= 4) && !bswapmask) {
d1 = FB_READL(src++);
FB_WRITEL(d0 << left | d1 >> right, dst++);
FB_WRITEL(d0 >> right | d1 << left, dst++);
d0 = d1;
d1 = FB_READL(src++);
FB_WRITEL(d0 << left | d1 >> right, dst++);
FB_WRITEL(d0 >> right | d1 << left, dst++);
d0 = d1;
d1 = FB_READL(src++);
FB_WRITEL(d0 << left | d1 >> right, dst++);
FB_WRITEL(d0 >> right | d1 << left, dst++);
d0 = d1;
d1 = FB_READL(src++);
FB_WRITEL(d0 << left | d1 >> right, dst++);
FB_WRITEL(d0 >> right | d1 << left, dst++);
d0 = d1;
n -= 4;
}
while (n--) {
d1 = FB_READL(src++);
d1 = fb_rev_pixels_in_long(d1, bswapmask);
d0 = d0 << left | d1 >> right;
d0 = d0 >> right | d1 << left;
d0 = fb_rev_pixels_in_long(d0, bswapmask);
FB_WRITEL(d0, dst++);
d0 = d1;
}
// Trailing bits
if (last) {
if (m <= right) {
if (m) {
if (m <= bits - right) {
// Single source word
d0 <<= left;
d0 >>= right;
} else {
// 2 source words
d1 = FB_READL(src);
d1 = fb_rev_pixels_in_long(d1,
bswapmask);
d0 = d0<<left | d1>>right;
d0 = d0 >> right | d1 << left;
}
d0 = fb_rev_pixels_in_long(d0, bswapmask);
FB_WRITEL(comp(d0, FB_READL(dst), last), dst);
@ -202,43 +209,46 @@ bitcpy(struct fb_info *p, unsigned long __iomem *dst, int dst_idx,
*/
static void
bitcpy_rev(struct fb_info *p, unsigned long __iomem *dst, int dst_idx,
const unsigned long __iomem *src, int src_idx, int bits,
bitcpy_rev(struct fb_info *p, unsigned long __iomem *dst, unsigned dst_idx,
const unsigned long __iomem *src, unsigned src_idx, int bits,
unsigned n, u32 bswapmask)
{
unsigned long first, last;
int shift;
dst += (n-1)/bits;
src += (n-1)/bits;
if ((n-1) % bits) {
dst_idx += (n-1) % bits;
dst += dst_idx >> (ffs(bits) - 1);
dst_idx &= bits - 1;
src_idx += (n-1) % bits;
src += src_idx >> (ffs(bits) - 1);
src_idx &= bits - 1;
}
#if 0
/*
* If you suspect bug in this function, compare it with this simple
* memmove implementation.
*/
fb_memmove((char *)dst + ((dst_idx & (bits - 1))) / 8,
(char *)src + ((src_idx & (bits - 1))) / 8, n / 8);
return;
#endif
dst += (dst_idx + n - 1) / bits;
src += (src_idx + n - 1) / bits;
dst_idx = (dst_idx + n - 1) % bits;
src_idx = (src_idx + n - 1) % bits;
shift = dst_idx-src_idx;
first = fb_shifted_pixels_mask_long(p, bits - 1 - dst_idx, bswapmask);
last = ~fb_shifted_pixels_mask_long(p, bits - 1 - ((dst_idx-n) % bits),
bswapmask);
first = ~fb_shifted_pixels_mask_long(p, (dst_idx + 1) % bits, bswapmask);
last = fb_shifted_pixels_mask_long(p, (bits + dst_idx + 1 - n) % bits, bswapmask);
if (!shift) {
// Same alignment for source and dest
if ((unsigned long)dst_idx+1 >= n) {
// Single word
if (last)
first &= last;
FB_WRITEL( comp( FB_READL(src), FB_READL(dst), first), dst);
if (first)
last &= first;
FB_WRITEL( comp( FB_READL(src), FB_READL(dst), last), dst);
} else {
// Multiple destination words
// Leading bits
if (first != ~0UL) {
if (first) {
FB_WRITEL( comp( FB_READL(src), FB_READL(dst), first), dst);
dst--;
src--;
@ -262,7 +272,7 @@ bitcpy_rev(struct fb_info *p, unsigned long __iomem *dst, int dst_idx,
FB_WRITEL(FB_READL(src--), dst--);
// Trailing bits
if (last)
if (last != -1UL)
FB_WRITEL( comp( FB_READL(src), FB_READL(dst), last), dst);
}
} else {
@ -270,29 +280,28 @@ bitcpy_rev(struct fb_info *p, unsigned long __iomem *dst, int dst_idx,
unsigned long d0, d1;
int m;
int const left = -shift & (bits-1);
int const right = shift & (bits-1);
bswapmask &= shift;
int const left = shift & (bits-1);
int const right = -shift & (bits-1);
if ((unsigned long)dst_idx+1 >= n) {
// Single destination word
if (last)
first &= last;
if (first)
last &= first;
d0 = FB_READL(src);
if (shift < 0) {
// Single source word
d0 <<= left;
d0 >>= right;
} else if (1+(unsigned long)src_idx >= n) {
// Single source word
d0 >>= right;
d0 <<= left;
} else {
// 2 source words
d1 = FB_READL(src - 1);
d1 = fb_rev_pixels_in_long(d1, bswapmask);
d0 = d0>>right | d1<<left;
d0 = d0 << left | d1 >> right;
}
d0 = fb_rev_pixels_in_long(d0, bswapmask);
FB_WRITEL(comp(d0, FB_READL(dst), first), dst);
FB_WRITEL(comp(d0, FB_READL(dst), last), dst);
} else {
// Multiple destination words
/** We must always remember the last value read, because in case
@ -307,12 +316,12 @@ bitcpy_rev(struct fb_info *p, unsigned long __iomem *dst, int dst_idx,
if (shift < 0) {
// Single source word
d1 = d0;
d0 <<= left;
d0 >>= right;
} else {
// 2 source words
d1 = FB_READL(src--);
d1 = fb_rev_pixels_in_long(d1, bswapmask);
d0 = d0>>right | d1<<left;
d0 = d0 << left | d1 >> right;
}
d0 = fb_rev_pixels_in_long(d0, bswapmask);
FB_WRITEL(comp(d0, FB_READL(dst), first), dst);
@ -325,39 +334,39 @@ bitcpy_rev(struct fb_info *p, unsigned long __iomem *dst, int dst_idx,
n /= bits;
while ((n >= 4) && !bswapmask) {
d1 = FB_READL(src--);
FB_WRITEL(d0 >> right | d1 << left, dst--);
FB_WRITEL(d0 << left | d1 >> right, dst--);
d0 = d1;
d1 = FB_READL(src--);
FB_WRITEL(d0 >> right | d1 << left, dst--);
FB_WRITEL(d0 << left | d1 >> right, dst--);
d0 = d1;
d1 = FB_READL(src--);
FB_WRITEL(d0 >> right | d1 << left, dst--);
FB_WRITEL(d0 << left | d1 >> right, dst--);
d0 = d1;
d1 = FB_READL(src--);
FB_WRITEL(d0 >> right | d1 << left, dst--);
FB_WRITEL(d0 << left | d1 >> right, dst--);
d0 = d1;
n -= 4;
}
while (n--) {
d1 = FB_READL(src--);
d1 = fb_rev_pixels_in_long(d1, bswapmask);
d0 = d0 >> right | d1 << left;
d0 = d0 << left | d1 >> right;
d0 = fb_rev_pixels_in_long(d0, bswapmask);
FB_WRITEL(d0, dst--);
d0 = d1;
}
// Trailing bits
if (last) {
if (m <= left) {
if (m) {
if (m <= bits - left) {
// Single source word
d0 >>= right;
d0 <<= left;
} else {
// 2 source words
d1 = FB_READL(src);
d1 = fb_rev_pixels_in_long(d1,
bswapmask);
d0 = d0>>right | d1<<left;
d0 = d0 << left | d1 >> right;
}
d0 = fb_rev_pixels_in_long(d0, bswapmask);
FB_WRITEL(comp(d0, FB_READL(dst), last), dst);
@ -371,9 +380,9 @@ void cfb_copyarea(struct fb_info *p, const struct fb_copyarea *area)
u32 dx = area->dx, dy = area->dy, sx = area->sx, sy = area->sy;
u32 height = area->height, width = area->width;
unsigned long const bits_per_line = p->fix.line_length*8u;
unsigned long __iomem *dst = NULL, *src = NULL;
unsigned long __iomem *base = NULL;
int bits = BITS_PER_LONG, bytes = bits >> 3;
int dst_idx = 0, src_idx = 0, rev_copy = 0;
unsigned dst_idx = 0, src_idx = 0, rev_copy = 0;
u32 bswapmask = fb_compute_bswapmask(p);
if (p->state != FBINFO_STATE_RUNNING)
@ -389,7 +398,7 @@ void cfb_copyarea(struct fb_info *p, const struct fb_copyarea *area)
// split the base of the framebuffer into a long-aligned address and the
// index of the first bit
dst = src = (unsigned long __iomem *)((unsigned long)p->screen_base & ~(bytes-1));
base = (unsigned long __iomem *)((unsigned long)p->screen_base & ~(bytes-1));
dst_idx = src_idx = 8*((unsigned long)p->screen_base & (bytes-1));
// add offset of source and target area
dst_idx += dy*bits_per_line + dx*p->var.bits_per_pixel;
@ -402,20 +411,14 @@ void cfb_copyarea(struct fb_info *p, const struct fb_copyarea *area)
while (height--) {
dst_idx -= bits_per_line;
src_idx -= bits_per_line;
dst += dst_idx >> (ffs(bits) - 1);
dst_idx &= (bytes - 1);
src += src_idx >> (ffs(bits) - 1);
src_idx &= (bytes - 1);
bitcpy_rev(p, dst, dst_idx, src, src_idx, bits,
bitcpy_rev(p, base + (dst_idx / bits), dst_idx % bits,
base + (src_idx / bits), src_idx % bits, bits,
width*p->var.bits_per_pixel, bswapmask);
}
} else {
while (height--) {
dst += dst_idx >> (ffs(bits) - 1);
dst_idx &= (bytes - 1);
src += src_idx >> (ffs(bits) - 1);
src_idx &= (bytes - 1);
bitcpy(p, dst, dst_idx, src, src_idx, bits,
bitcpy(p, base + (dst_idx / bits), dst_idx % bits,
base + (src_idx / bits), src_idx % bits, bits,
width*p->var.bits_per_pixel, bswapmask);
dst_idx += bits_per_line;
src_idx += bits_per_line;

View File

@ -759,7 +759,7 @@ static int con2fb_release_oldinfo(struct vc_data *vc, struct fb_info *oldinfo,
newinfo in an undefined state. Thus, a call to
fb_set_par() may be needed for the newinfo.
*/
if (newinfo->fbops->fb_set_par) {
if (newinfo && newinfo->fbops->fb_set_par) {
ret = newinfo->fbops->fb_set_par(newinfo);
if (ret)
@ -3028,8 +3028,31 @@ static int fbcon_fb_unbind(int idx)
if (con2fb_map[i] == idx)
set_con2fb_map(i, new_idx, 0);
}
} else
} else {
struct fb_info *info = registered_fb[idx];
/* This is sort of like set_con2fb_map, except it maps
* the consoles to no device and then releases the
* oldinfo to free memory and cancel the cursor blink
* timer. I can imagine this just becoming part of
* set_con2fb_map where new_idx is -1
*/
for (i = first_fb_vc; i <= last_fb_vc; i++) {
if (con2fb_map[i] == idx) {
con2fb_map[i] = -1;
if (!search_fb_in_map(idx)) {
ret = con2fb_release_oldinfo(vc_cons[i].d,
info, NULL, i,
idx, 0);
if (ret) {
con2fb_map[i] = idx;
return ret;
}
}
}
}
ret = fbcon_unbind();
}
return ret;
}

View File

@ -1546,7 +1546,7 @@ err_pm_runtime_disable:
return ret;
}
#ifdef CONFIG_PM
#ifdef CONFIG_PM_SLEEP
static struct lcdc_context {
u32 clk_enable;
u32 ctrl;
@ -1610,9 +1610,9 @@ static void lcd_context_restore(void)
return;
}
static int fb_suspend(struct platform_device *dev, pm_message_t state)
static int fb_suspend(struct device *dev)
{
struct fb_info *info = platform_get_drvdata(dev);
struct fb_info *info = dev_get_drvdata(dev);
struct da8xx_fb_par *par = info->par;
console_lock();
@ -1622,18 +1622,18 @@ static int fb_suspend(struct platform_device *dev, pm_message_t state)
fb_set_suspend(info, 1);
lcd_disable_raster(DA8XX_FRAME_WAIT);
lcd_context_save();
pm_runtime_put_sync(&dev->dev);
pm_runtime_put_sync(dev);
console_unlock();
return 0;
}
static int fb_resume(struct platform_device *dev)
static int fb_resume(struct device *dev)
{
struct fb_info *info = platform_get_drvdata(dev);
struct fb_info *info = dev_get_drvdata(dev);
struct da8xx_fb_par *par = info->par;
console_lock();
pm_runtime_get_sync(&dev->dev);
pm_runtime_get_sync(dev);
lcd_context_restore();
if (par->blank == FB_BLANK_UNBLANK) {
lcd_enable_raster();
@ -1647,19 +1647,17 @@ static int fb_resume(struct platform_device *dev)
return 0;
}
#else
#define fb_suspend NULL
#define fb_resume NULL
#endif
static SIMPLE_DEV_PM_OPS(fb_pm_ops, fb_suspend, fb_resume);
static struct platform_driver da8xx_fb_driver = {
.probe = fb_probe,
.remove = fb_remove,
.suspend = fb_suspend,
.resume = fb_resume,
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
.pm = &fb_pm_ops,
},
};
module_platform_driver(da8xx_fb_driver);

View File

@ -73,7 +73,6 @@ static void efifb_destroy(struct fb_info *info)
release_mem_region(info->apertures->ranges[0].base,
info->apertures->ranges[0].size);
fb_dealloc_cmap(&info->cmap);
framebuffer_release(info);
}
static struct fb_ops efifb_ops = {
@ -244,6 +243,7 @@ static int efifb_probe(struct platform_device *dev)
err = -ENOMEM;
goto err_release_mem;
}
platform_set_drvdata(dev, info);
info->pseudo_palette = info->par;
info->par = NULL;
@ -337,12 +337,23 @@ err_release_mem:
return err;
}
static int efifb_remove(struct platform_device *pdev)
{
struct fb_info *info = platform_get_drvdata(pdev);
unregister_framebuffer(info);
framebuffer_release(info);
return 0;
}
static struct platform_driver efifb_driver = {
.driver = {
.name = "efi-framebuffer",
.owner = THIS_MODULE,
},
.probe = efifb_probe,
.remove = efifb_remove,
};
module_platform_driver(efifb_driver);

View File

@ -31,7 +31,7 @@ config EXYNOS_LCD_S6E8AX0
config EXYNOS_DP
bool "EXYNOS DP driver support"
depends on OF && ARCH_EXYNOS
depends on ARCH_EXYNOS
default n
help
This enables support for DP device.

View File

@ -794,19 +794,18 @@ static int s6e8ax0_probe(struct mipi_dsim_lcd_device *dsim_dev)
return ret;
}
lcd->ld = lcd_device_register("s6e8ax0", lcd->dev, lcd,
lcd->ld = devm_lcd_device_register(lcd->dev, "s6e8ax0", lcd->dev, lcd,
&s6e8ax0_lcd_ops);
if (IS_ERR(lcd->ld)) {
dev_err(lcd->dev, "failed to register lcd ops.\n");
return PTR_ERR(lcd->ld);
}
lcd->bd = backlight_device_register("s6e8ax0-bl", lcd->dev, lcd,
&s6e8ax0_backlight_ops, NULL);
lcd->bd = devm_backlight_device_register(lcd->dev, "s6e8ax0-bl",
lcd->dev, lcd, &s6e8ax0_backlight_ops, NULL);
if (IS_ERR(lcd->bd)) {
dev_err(lcd->dev, "failed to register backlight ops.\n");
ret = PTR_ERR(lcd->bd);
goto err_backlight_register;
return PTR_ERR(lcd->bd);
}
lcd->bd->props.max_brightness = MAX_BRIGHTNESS;
@ -834,10 +833,6 @@ static int s6e8ax0_probe(struct mipi_dsim_lcd_device *dsim_dev)
dev_dbg(lcd->dev, "probed s6e8ax0 panel driver.\n");
return 0;
err_backlight_register:
lcd_device_unregister(lcd->ld);
return ret;
}
#ifdef CONFIG_PM

View File

@ -1596,8 +1596,7 @@ static int do_remove_conflicting_framebuffers(struct apertures_struct *a,
(primary && gen_aper && gen_aper->count &&
gen_aper->ranges[0].base == VGA_FB_PHYS)) {
printk(KERN_INFO "fb: conflicting fb hw usage "
"%s vs %s - removing generic driver\n",
printk(KERN_INFO "fb: switching to %s from %s\n",
name, registered_fb[i]->fix.id);
ret = do_unregister_framebuffer(registered_fb[i]);
if (ret)

View File

@ -30,10 +30,13 @@
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/io.h>
#include <linux/lcd.h>
#include <linux/math64.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/regulator/consumer.h>
#include <video/of_display_timing.h>
#include <video/of_videomode.h>
#include <video/videomode.h>
@ -45,12 +48,6 @@
*/
#define DEBUG_VAR 1
#if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) || \
(defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE) && \
defined(CONFIG_FB_IMX_MODULE))
#define PWMR_BACKLIGHT_AVAILABLE
#endif
#define DRIVER_NAME "imx-fb"
#define LCDC_SSA 0x00
@ -153,11 +150,8 @@ struct imxfb_info {
* the framebuffer memory region to.
*/
dma_addr_t map_dma;
u_char *map_cpu;
u_int map_size;
u_char *screen_cpu;
dma_addr_t screen_dma;
u_int palette_size;
dma_addr_t dbar1;
@ -167,18 +161,13 @@ struct imxfb_info {
u_int pwmr;
u_int lscr1;
u_int dmacr;
u_int cmap_inverse:1,
cmap_static:1,
unused:30;
bool cmap_inverse;
bool cmap_static;
struct imx_fb_videomode *mode;
int num_modes;
#ifdef PWMR_BACKLIGHT_AVAILABLE
struct backlight_device *bl;
#endif
void (*lcd_power)(int);
void (*backlight_power)(int);
struct regulator *lcd_pwr;
};
static struct platform_device_id imxfb_devtype[] = {
@ -484,83 +473,6 @@ static int imxfb_set_par(struct fb_info *info)
return 0;
}
#ifdef PWMR_BACKLIGHT_AVAILABLE
static int imxfb_bl_get_brightness(struct backlight_device *bl)
{
struct imxfb_info *fbi = bl_get_data(bl);
return readl(fbi->regs + LCDC_PWMR) & 0xFF;
}
static int imxfb_bl_update_status(struct backlight_device *bl)
{
struct imxfb_info *fbi = bl_get_data(bl);
int brightness = bl->props.brightness;
if (!fbi->pwmr)
return 0;
if (bl->props.power != FB_BLANK_UNBLANK)
brightness = 0;
if (bl->props.fb_blank != FB_BLANK_UNBLANK)
brightness = 0;
fbi->pwmr = (fbi->pwmr & ~0xFF) | brightness;
if (bl->props.fb_blank != FB_BLANK_UNBLANK) {
clk_prepare_enable(fbi->clk_ipg);
clk_prepare_enable(fbi->clk_ahb);
clk_prepare_enable(fbi->clk_per);
}
writel(fbi->pwmr, fbi->regs + LCDC_PWMR);
if (bl->props.fb_blank != FB_BLANK_UNBLANK) {
clk_disable_unprepare(fbi->clk_per);
clk_disable_unprepare(fbi->clk_ahb);
clk_disable_unprepare(fbi->clk_ipg);
}
return 0;
}
static const struct backlight_ops imxfb_lcdc_bl_ops = {
.update_status = imxfb_bl_update_status,
.get_brightness = imxfb_bl_get_brightness,
};
static void imxfb_init_backlight(struct imxfb_info *fbi)
{
struct backlight_properties props;
struct backlight_device *bl;
if (fbi->bl)
return;
memset(&props, 0, sizeof(struct backlight_properties));
props.max_brightness = 0xff;
props.type = BACKLIGHT_RAW;
writel(fbi->pwmr, fbi->regs + LCDC_PWMR);
bl = backlight_device_register("imxfb-bl", &fbi->pdev->dev, fbi,
&imxfb_lcdc_bl_ops, &props);
if (IS_ERR(bl)) {
dev_err(&fbi->pdev->dev, "error %ld on backlight register\n",
PTR_ERR(bl));
return;
}
fbi->bl = bl;
bl->props.power = FB_BLANK_UNBLANK;
bl->props.fb_blank = FB_BLANK_UNBLANK;
bl->props.brightness = imxfb_bl_get_brightness(bl);
}
static void imxfb_exit_backlight(struct imxfb_info *fbi)
{
if (fbi->bl)
backlight_device_unregister(fbi->bl);
}
#endif
static void imxfb_enable_controller(struct imxfb_info *fbi)
{
@ -569,7 +481,7 @@ static void imxfb_enable_controller(struct imxfb_info *fbi)
pr_debug("Enabling LCD controller\n");
writel(fbi->screen_dma, fbi->regs + LCDC_SSA);
writel(fbi->map_dma, fbi->regs + LCDC_SSA);
/* panning offset 0 (0 pixel offset) */
writel(0x00000000, fbi->regs + LCDC_POS);
@ -588,11 +500,6 @@ static void imxfb_enable_controller(struct imxfb_info *fbi)
clk_prepare_enable(fbi->clk_ahb);
clk_prepare_enable(fbi->clk_per);
fbi->enabled = true;
if (fbi->backlight_power)
fbi->backlight_power(1);
if (fbi->lcd_power)
fbi->lcd_power(1);
}
static void imxfb_disable_controller(struct imxfb_info *fbi)
@ -602,11 +509,6 @@ static void imxfb_disable_controller(struct imxfb_info *fbi)
pr_debug("Disabling LCD controller\n");
if (fbi->backlight_power)
fbi->backlight_power(0);
if (fbi->lcd_power)
fbi->lcd_power(0);
clk_disable_unprepare(fbi->clk_per);
clk_disable_unprepare(fbi->clk_ipg);
clk_disable_unprepare(fbi->clk_ahb);
@ -709,10 +611,8 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf
fbi->regs + LCDC_SIZE);
writel(fbi->pcr, fbi->regs + LCDC_PCR);
#ifndef PWMR_BACKLIGHT_AVAILABLE
if (fbi->pwmr)
writel(fbi->pwmr, fbi->regs + LCDC_PWMR);
#endif
writel(fbi->lscr1, fbi->regs + LCDC_LSCR1);
/* dmacr = 0 is no valid value, as we need DMA control marks. */
@ -722,37 +622,6 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf
return 0;
}
#ifdef CONFIG_PM
/*
* Power management hooks. Note that we won't be called from IRQ context,
* unlike the blank functions above, so we may sleep.
*/
static int imxfb_suspend(struct platform_device *dev, pm_message_t state)
{
struct fb_info *info = platform_get_drvdata(dev);
struct imxfb_info *fbi = info->par;
pr_debug("%s\n", __func__);
imxfb_disable_controller(fbi);
return 0;
}
static int imxfb_resume(struct platform_device *dev)
{
struct fb_info *info = platform_get_drvdata(dev);
struct imxfb_info *fbi = info->par;
pr_debug("%s\n", __func__);
imxfb_enable_controller(fbi);
return 0;
}
#else
#define imxfb_suspend NULL
#define imxfb_resume NULL
#endif
static int imxfb_init_fbinfo(struct platform_device *pdev)
{
struct imx_fb_platform_data *pdata = dev_get_platdata(&pdev->dev);
@ -790,14 +659,9 @@ static int imxfb_init_fbinfo(struct platform_device *pdev)
info->flags = FBINFO_FLAG_DEFAULT |
FBINFO_READS_FAST;
if (pdata) {
info->var.grayscale = pdata->cmap_greyscale;
fbi->cmap_inverse = pdata->cmap_inverse;
fbi->cmap_static = pdata->cmap_static;
fbi->lscr1 = pdata->lscr1;
fbi->dmacr = pdata->dmacr;
fbi->pwmr = pdata->pwmr;
fbi->lcd_power = pdata->lcd_power;
fbi->backlight_power = pdata->backlight_power;
} else {
np = pdev->dev.of_node;
info->var.grayscale = of_property_read_bool(np,
@ -806,14 +670,12 @@ static int imxfb_init_fbinfo(struct platform_device *pdev)
fbi->cmap_static = of_property_read_bool(np, "cmap-static");
fbi->lscr1 = IMXFB_LSCR1_DEFAULT;
of_property_read_u32(np, "fsl,lpccr", &fbi->pwmr);
of_property_read_u32(np, "fsl,lscr1", &fbi->lscr1);
of_property_read_u32(np, "fsl,dmacr", &fbi->dmacr);
/* These two function pointers could be used by some specific
* platforms. */
fbi->lcd_power = NULL;
fbi->backlight_power = NULL;
}
return 0;
@ -856,9 +718,98 @@ static int imxfb_of_read_mode(struct device *dev, struct device_node *np,
return 0;
}
static int imxfb_lcd_check_fb(struct lcd_device *lcddev, struct fb_info *fi)
{
struct imxfb_info *fbi = dev_get_drvdata(&lcddev->dev);
if (!fi || fi->par == fbi)
return 1;
return 0;
}
static int imxfb_lcd_get_contrast(struct lcd_device *lcddev)
{
struct imxfb_info *fbi = dev_get_drvdata(&lcddev->dev);
return fbi->pwmr & 0xff;
}
static int imxfb_lcd_set_contrast(struct lcd_device *lcddev, int contrast)
{
struct imxfb_info *fbi = dev_get_drvdata(&lcddev->dev);
if (fbi->pwmr && fbi->enabled) {
if (contrast > 255)
contrast = 255;
else if (contrast < 0)
contrast = 0;
fbi->pwmr &= ~0xff;
fbi->pwmr |= contrast;
writel(fbi->pwmr, fbi->regs + LCDC_PWMR);
}
return 0;
}
static int imxfb_lcd_get_power(struct lcd_device *lcddev)
{
struct imxfb_info *fbi = dev_get_drvdata(&lcddev->dev);
if (!IS_ERR(fbi->lcd_pwr))
return regulator_is_enabled(fbi->lcd_pwr);
return 1;
}
static int imxfb_lcd_set_power(struct lcd_device *lcddev, int power)
{
struct imxfb_info *fbi = dev_get_drvdata(&lcddev->dev);
if (!IS_ERR(fbi->lcd_pwr)) {
if (power)
return regulator_enable(fbi->lcd_pwr);
else
return regulator_disable(fbi->lcd_pwr);
}
return 0;
}
static struct lcd_ops imxfb_lcd_ops = {
.check_fb = imxfb_lcd_check_fb,
.get_contrast = imxfb_lcd_get_contrast,
.set_contrast = imxfb_lcd_set_contrast,
.get_power = imxfb_lcd_get_power,
.set_power = imxfb_lcd_set_power,
};
static int imxfb_setup(void)
{
char *opt, *options = NULL;
if (fb_get_options("imxfb", &options))
return -ENODEV;
if (!options || !*options)
return 0;
while ((opt = strsep(&options, ",")) != NULL) {
if (!*opt)
continue;
else
fb_mode = opt;
}
return 0;
}
static int imxfb_probe(struct platform_device *pdev)
{
struct imxfb_info *fbi;
struct lcd_device *lcd;
struct fb_info *info;
struct imx_fb_platform_data *pdata;
struct resource *res;
@ -869,6 +820,10 @@ static int imxfb_probe(struct platform_device *pdev)
dev_info(&pdev->dev, "i.MX Framebuffer driver\n");
ret = imxfb_setup();
if (ret < 0)
return ret;
of_id = of_match_device(imxfb_of_dev_id, &pdev->dev);
if (of_id)
pdev->id_entry = of_id->data;
@ -966,32 +921,18 @@ static int imxfb_probe(struct platform_device *pdev)
goto failed_ioremap;
}
/* Seems not being used by anyone, so no support for oftree */
if (!pdata || !pdata->fixed_screen_cpu) {
fbi->map_size = PAGE_ALIGN(info->fix.smem_len);
fbi->map_cpu = dma_alloc_writecombine(&pdev->dev,
fbi->map_size, &fbi->map_dma, GFP_KERNEL);
fbi->map_size = PAGE_ALIGN(info->fix.smem_len);
info->screen_base = dma_alloc_writecombine(&pdev->dev, fbi->map_size,
&fbi->map_dma, GFP_KERNEL);
if (!fbi->map_cpu) {
dev_err(&pdev->dev, "Failed to allocate video RAM: %d\n", ret);
ret = -ENOMEM;
goto failed_map;
}
info->screen_base = fbi->map_cpu;
fbi->screen_cpu = fbi->map_cpu;
fbi->screen_dma = fbi->map_dma;
info->fix.smem_start = fbi->screen_dma;
} else {
/* Fixed framebuffer mapping enables location of the screen in eSRAM */
fbi->map_cpu = pdata->fixed_screen_cpu;
fbi->map_dma = pdata->fixed_screen_dma;
info->screen_base = fbi->map_cpu;
fbi->screen_cpu = fbi->map_cpu;
fbi->screen_dma = fbi->map_dma;
info->fix.smem_start = fbi->screen_dma;
if (!info->screen_base) {
dev_err(&pdev->dev, "Failed to allocate video RAM: %d\n", ret);
ret = -ENOMEM;
goto failed_map;
}
info->fix.smem_start = fbi->map_dma;
if (pdata && pdata->init) {
ret = pdata->init(fbi->pdev);
if (ret)
@ -1020,23 +961,37 @@ static int imxfb_probe(struct platform_device *pdev)
goto failed_register;
}
fbi->lcd_pwr = devm_regulator_get(&pdev->dev, "lcd");
if (IS_ERR(fbi->lcd_pwr) && (PTR_ERR(fbi->lcd_pwr) == -EPROBE_DEFER)) {
ret = -EPROBE_DEFER;
goto failed_lcd;
}
lcd = devm_lcd_device_register(&pdev->dev, "imxfb-lcd", &pdev->dev, fbi,
&imxfb_lcd_ops);
if (IS_ERR(lcd)) {
ret = PTR_ERR(lcd);
goto failed_lcd;
}
lcd->props.max_contrast = 0xff;
imxfb_enable_controller(fbi);
fbi->pdev = pdev;
#ifdef PWMR_BACKLIGHT_AVAILABLE
imxfb_init_backlight(fbi);
#endif
return 0;
failed_lcd:
unregister_framebuffer(info);
failed_register:
fb_dealloc_cmap(&info->cmap);
failed_cmap:
if (pdata && pdata->exit)
pdata->exit(fbi->pdev);
failed_platform_init:
if (pdata && !pdata->fixed_screen_cpu)
dma_free_writecombine(&pdev->dev,fbi->map_size,fbi->map_cpu,
fbi->map_dma);
dma_free_writecombine(&pdev->dev, fbi->map_size, info->screen_base,
fbi->map_dma);
failed_map:
iounmap(fbi->regs);
failed_ioremap:
@ -1061,9 +1016,6 @@ static int imxfb_remove(struct platform_device *pdev)
imxfb_disable_controller(fbi);
#ifdef PWMR_BACKLIGHT_AVAILABLE
imxfb_exit_backlight(fbi);
#endif
unregister_framebuffer(info);
pdata = dev_get_platdata(&pdev->dev);
@ -1074,69 +1026,49 @@ static int imxfb_remove(struct platform_device *pdev)
kfree(info->pseudo_palette);
framebuffer_release(info);
dma_free_writecombine(&pdev->dev, fbi->map_size, info->screen_base,
fbi->map_dma);
iounmap(fbi->regs);
release_mem_region(res->start, resource_size(res));
return 0;
}
static void imxfb_shutdown(struct platform_device *dev)
static int __maybe_unused imxfb_suspend(struct device *dev)
{
struct fb_info *info = platform_get_drvdata(dev);
struct fb_info *info = dev_get_drvdata(dev);
struct imxfb_info *fbi = info->par;
imxfb_disable_controller(fbi);
}
static struct platform_driver imxfb_driver = {
.suspend = imxfb_suspend,
.resume = imxfb_resume,
.remove = imxfb_remove,
.shutdown = imxfb_shutdown,
.driver = {
.name = DRIVER_NAME,
.of_match_table = imxfb_of_dev_id,
},
.id_table = imxfb_devtype,
};
static int imxfb_setup(void)
{
#ifndef MODULE
char *opt, *options = NULL;
if (fb_get_options("imxfb", &options))
return -ENODEV;
if (!options || !*options)
return 0;
while ((opt = strsep(&options, ",")) != NULL) {
if (!*opt)
continue;
else
fb_mode = opt;
}
#endif
return 0;
}
static int __init imxfb_init(void)
static int __maybe_unused imxfb_resume(struct device *dev)
{
int ret = imxfb_setup();
struct fb_info *info = dev_get_drvdata(dev);
struct imxfb_info *fbi = info->par;
if (ret < 0)
return ret;
imxfb_enable_controller(fbi);
return platform_driver_probe(&imxfb_driver, imxfb_probe);
return 0;
}
static void __exit imxfb_cleanup(void)
{
platform_driver_unregister(&imxfb_driver);
}
static SIMPLE_DEV_PM_OPS(imxfb_pm_ops, imxfb_suspend, imxfb_resume);
module_init(imxfb_init);
module_exit(imxfb_cleanup);
static struct platform_driver imxfb_driver = {
.driver = {
.name = DRIVER_NAME,
.of_match_table = imxfb_of_dev_id,
.owner = THIS_MODULE,
.pm = &imxfb_pm_ops,
},
.probe = imxfb_probe,
.remove = imxfb_remove,
.id_table = imxfb_devtype,
};
module_platform_driver(imxfb_driver);
MODULE_DESCRIPTION("Freescale i.MX framebuffer driver");
MODULE_AUTHOR("Sascha Hauer, Pengutronix");

View File

@ -192,10 +192,18 @@ void matrox_cfbX_init(struct matrox_fb_info *minfo)
minfo->accel.m_dwg_rect = M_DWG_TRAP | M_DWG_SOLID | M_DWG_ARZERO | M_DWG_SGNZERO | M_DWG_SHIFTZERO;
if (isMilleniumII(minfo)) minfo->accel.m_dwg_rect |= M_DWG_TRANSC;
minfo->accel.m_opmode = mopmode;
minfo->accel.m_access = maccess;
minfo->accel.m_pitch = mpitch;
}
EXPORT_SYMBOL(matrox_cfbX_init);
static void matrox_accel_restore_maccess(struct matrox_fb_info *minfo)
{
mga_outl(M_MACCESS, minfo->accel.m_access);
mga_outl(M_PITCH, minfo->accel.m_pitch);
}
static void matrox_accel_bmove(struct matrox_fb_info *minfo, int vxres, int sy,
int sx, int dy, int dx, int height, int width)
{
@ -207,7 +215,8 @@ static void matrox_accel_bmove(struct matrox_fb_info *minfo, int vxres, int sy,
CRITBEGIN
if ((dy < sy) || ((dy == sy) && (dx <= sx))) {
mga_fifo(2);
mga_fifo(4);
matrox_accel_restore_maccess(minfo);
mga_outl(M_DWGCTL, M_DWG_BITBLT | M_DWG_SHIFTZERO | M_DWG_SGNZERO |
M_DWG_BFCOL | M_DWG_REPLACE);
mga_outl(M_AR5, vxres);
@ -215,7 +224,8 @@ static void matrox_accel_bmove(struct matrox_fb_info *minfo, int vxres, int sy,
start = sy*vxres+sx+curr_ydstorg(minfo);
end = start+width;
} else {
mga_fifo(3);
mga_fifo(5);
matrox_accel_restore_maccess(minfo);
mga_outl(M_DWGCTL, M_DWG_BITBLT | M_DWG_SHIFTZERO | M_DWG_BFCOL | M_DWG_REPLACE);
mga_outl(M_SGN, 5);
mga_outl(M_AR5, -vxres);
@ -224,7 +234,8 @@ static void matrox_accel_bmove(struct matrox_fb_info *minfo, int vxres, int sy,
start = end+width;
dy += height-1;
}
mga_fifo(4);
mga_fifo(6);
matrox_accel_restore_maccess(minfo);
mga_outl(M_AR0, end);
mga_outl(M_AR3, start);
mga_outl(M_FXBNDRY, ((dx+width)<<16) | dx);
@ -246,7 +257,8 @@ static void matrox_accel_bmove_lin(struct matrox_fb_info *minfo, int vxres,
CRITBEGIN
if ((dy < sy) || ((dy == sy) && (dx <= sx))) {
mga_fifo(2);
mga_fifo(4);
matrox_accel_restore_maccess(minfo);
mga_outl(M_DWGCTL, M_DWG_BITBLT | M_DWG_SHIFTZERO | M_DWG_SGNZERO |
M_DWG_BFCOL | M_DWG_REPLACE);
mga_outl(M_AR5, vxres);
@ -254,7 +266,8 @@ static void matrox_accel_bmove_lin(struct matrox_fb_info *minfo, int vxres,
start = sy*vxres+sx+curr_ydstorg(minfo);
end = start+width;
} else {
mga_fifo(3);
mga_fifo(5);
matrox_accel_restore_maccess(minfo);
mga_outl(M_DWGCTL, M_DWG_BITBLT | M_DWG_SHIFTZERO | M_DWG_BFCOL | M_DWG_REPLACE);
mga_outl(M_SGN, 5);
mga_outl(M_AR5, -vxres);
@ -263,7 +276,8 @@ static void matrox_accel_bmove_lin(struct matrox_fb_info *minfo, int vxres,
start = end+width;
dy += height-1;
}
mga_fifo(5);
mga_fifo(7);
matrox_accel_restore_maccess(minfo);
mga_outl(M_AR0, end);
mga_outl(M_AR3, start);
mga_outl(M_FXBNDRY, ((dx+width)<<16) | dx);
@ -298,7 +312,8 @@ static void matroxfb_accel_clear(struct matrox_fb_info *minfo, u_int32_t color,
CRITBEGIN
mga_fifo(5);
mga_fifo(7);
matrox_accel_restore_maccess(minfo);
mga_outl(M_DWGCTL, minfo->accel.m_dwg_rect | M_DWG_REPLACE);
mga_outl(M_FCOL, color);
mga_outl(M_FXBNDRY, ((sx + width) << 16) | sx);
@ -341,7 +356,8 @@ static void matroxfb_cfb4_clear(struct matrox_fb_info *minfo, u_int32_t bgx,
width >>= 1;
sx >>= 1;
if (width) {
mga_fifo(5);
mga_fifo(7);
matrox_accel_restore_maccess(minfo);
mga_outl(M_DWGCTL, minfo->accel.m_dwg_rect | M_DWG_REPLACE2);
mga_outl(M_FCOL, bgx);
mga_outl(M_FXBNDRY, ((sx + width) << 16) | sx);
@ -415,7 +431,8 @@ static void matroxfb_1bpp_imageblit(struct matrox_fb_info *minfo, u_int32_t fgx,
CRITBEGIN
mga_fifo(3);
mga_fifo(5);
matrox_accel_restore_maccess(minfo);
if (easy)
mga_outl(M_DWGCTL, M_DWG_ILOAD | M_DWG_SGNZERO | M_DWG_SHIFTZERO | M_DWG_BMONOWF | M_DWG_LINEAR | M_DWG_REPLACE);
else
@ -425,7 +442,8 @@ static void matroxfb_1bpp_imageblit(struct matrox_fb_info *minfo, u_int32_t fgx,
fxbndry = ((xx + width - 1) << 16) | xx;
mmio = minfo->mmio.vbase;
mga_fifo(6);
mga_fifo(8);
matrox_accel_restore_maccess(minfo);
mga_writel(mmio, M_FXBNDRY, fxbndry);
mga_writel(mmio, M_AR0, ar0);
mga_writel(mmio, M_AR3, 0);

View File

@ -1773,7 +1773,8 @@ static int initMatrox2(struct matrox_fb_info *minfo, struct board *b)
FBINFO_HWACCEL_FILLRECT | /* And fillrect */
FBINFO_HWACCEL_IMAGEBLIT | /* And imageblit */
FBINFO_HWACCEL_XPAN | /* And we support both horizontal */
FBINFO_HWACCEL_YPAN; /* And vertical panning */
FBINFO_HWACCEL_YPAN | /* And vertical panning */
FBINFO_READS_FAST;
minfo->video.len_usable &= PAGE_MASK;
fb_alloc_cmap(&minfo->fbcon.cmap, 256, 1);

View File

@ -307,6 +307,8 @@ struct matrox_accel_data {
#endif
u_int32_t m_dwg_rect;
u_int32_t m_opmode;
u_int32_t m_access;
u_int32_t m_pitch;
};
struct v4l2_queryctrl;

View File

@ -31,7 +31,7 @@ struct panel_drv_data {
static const struct omap_video_timings tvc_pal_timings = {
.x_res = 720,
.y_res = 574,
.pixel_clock = 13500,
.pixelclock = 13500000,
.hsw = 64,
.hfp = 12,
.hbp = 68,

View File

@ -23,7 +23,7 @@ static const struct omap_video_timings dvic_default_timings = {
.x_res = 640,
.y_res = 480,
.pixel_clock = 23500,
.pixelclock = 23500000,
.hfp = 48,
.hsw = 32,

View File

@ -21,7 +21,7 @@
static const struct omap_video_timings hdmic_default_timings = {
.x_res = 640,
.y_res = 480,
.pixel_clock = 25175,
.pixelclock = 25175000,
.hsw = 96,
.hfp = 16,
.hbp = 48,

View File

@ -1184,7 +1184,7 @@ static int dsicm_probe(struct platform_device *pdev)
ddata->timings.x_res = 864;
ddata->timings.y_res = 480;
ddata->timings.pixel_clock = DIV_ROUND_UP(864 * 480 * 60, 1000);
ddata->timings.pixelclock = 864 * 480 * 60;
dssdev = &ddata->dssdev;
dssdev->dev = dev;

View File

@ -23,7 +23,7 @@ static struct omap_video_timings lb035q02_timings = {
.x_res = 320,
.y_res = 240,
.pixel_clock = 6500,
.pixelclock = 6500000,
.hsw = 2,
.hfp = 20,

View File

@ -40,7 +40,7 @@ struct panel_drv_data {
* NEC PIX Clock Ratings
* MIN:21.8MHz TYP:23.8MHz MAX:25.7MHz
*/
#define LCD_PIXEL_CLOCK 23800
#define LCD_PIXEL_CLOCK 23800000
static const struct {
unsigned char addr;
@ -69,7 +69,7 @@ static const struct {
static const struct omap_video_timings nec_8048_panel_timings = {
.x_res = LCD_XRES,
.y_res = LCD_YRES,
.pixel_clock = LCD_PIXEL_CLOCK,
.pixelclock = LCD_PIXEL_CLOCK,
.hfp = 6,
.hsw = 1,
.hbp = 4,

View File

@ -37,7 +37,7 @@ static const struct omap_video_timings sharp_ls_timings = {
.x_res = 480,
.y_res = 640,
.pixel_clock = 19200,
.pixelclock = 19200000,
.hsw = 2,
.hfp = 1,

View File

@ -93,7 +93,7 @@ struct panel_drv_data {
static const struct omap_video_timings acx565akm_panel_timings = {
.x_res = 800,
.y_res = 480,
.pixel_clock = 24000,
.pixelclock = 24000000,
.hfp = 28,
.hsw = 4,
.hbp = 24,

View File

@ -45,7 +45,7 @@ struct panel_drv_data {
static struct omap_video_timings td028ttec1_panel_timings = {
.x_res = 480,
.y_res = 640,
.pixel_clock = 22153,
.pixelclock = 22153000,
.hfp = 24,
.hsw = 8,
.hbp = 8,

View File

@ -76,7 +76,7 @@ static const struct omap_video_timings tpo_td043_timings = {
.x_res = 800,
.y_res = 480,
.pixel_clock = 36000,
.pixelclock = 36000000,
.hsw = 1,
.hfp = 68,

View File

@ -100,8 +100,6 @@ static struct {
struct platform_device *pdev;
void __iomem *base;
int ctx_loss_cnt;
int irq;
unsigned long core_clk_rate;
@ -357,29 +355,20 @@ static void dispc_save_context(void)
if (dss_has_feature(FEAT_CORE_CLK_DIV))
SR(DIVISOR);
dispc.ctx_loss_cnt = dss_get_ctx_loss_count();
dispc.ctx_valid = true;
DSSDBG("context saved, ctx_loss_count %d\n", dispc.ctx_loss_cnt);
DSSDBG("context saved\n");
}
static void dispc_restore_context(void)
{
int i, j, ctx;
int i, j;
DSSDBG("dispc_restore_context\n");
if (!dispc.ctx_valid)
return;
ctx = dss_get_ctx_loss_count();
if (ctx >= 0 && ctx == dispc.ctx_loss_cnt)
return;
DSSDBG("ctx_loss_count: saved %d, current %d\n",
dispc.ctx_loss_cnt, ctx);
/*RR(IRQENABLE);*/
/*RR(CONTROL);*/
RR(CONFIG);
@ -2884,7 +2873,7 @@ bool dispc_mgr_timings_ok(enum omap_channel channel,
timings_ok = _dispc_mgr_size_ok(timings->x_res, timings->y_res);
timings_ok &= _dispc_mgr_pclk_ok(channel, timings->pixel_clock * 1000);
timings_ok &= _dispc_mgr_pclk_ok(channel, timings->pixelclock);
if (dss_mgr_is_lcd(channel)) {
timings_ok &= _dispc_lcd_timings_ok(timings->hsw, timings->hfp,
@ -2979,10 +2968,10 @@ void dispc_mgr_set_timings(enum omap_channel channel,
xtot = t.x_res + t.hfp + t.hsw + t.hbp;
ytot = t.y_res + t.vfp + t.vsw + t.vbp;
ht = (timings->pixel_clock * 1000) / xtot;
vt = (timings->pixel_clock * 1000) / xtot / ytot;
ht = timings->pixelclock / xtot;
vt = timings->pixelclock / xtot / ytot;
DSSDBG("pck %u\n", timings->pixel_clock);
DSSDBG("pck %u\n", timings->pixelclock);
DSSDBG("hsw %d hfp %d hbp %d vsw %d vfp %d vbp %d\n",
t.hsw, t.hfp, t.hbp, t.vsw, t.vfp, t.vbp);
DSSDBG("vsync_level %d hsync_level %d data_pclk_edge %d de_level %d sync_pclk_edge %d\n",
@ -3768,6 +3757,15 @@ static int dispc_runtime_suspend(struct device *dev)
static int dispc_runtime_resume(struct device *dev)
{
/*
* The reset value for load mode is 0 (OMAP_DSS_LOAD_CLUT_AND_FRAME)
* but we always initialize it to 2 (OMAP_DSS_LOAD_FRAME_ONLY) in
* _omap_dispc_initial_config(). We can thus use it to detect if
* we have lost register context.
*/
if (REG_GET(DISPC_CONFIG, 2, 1) == OMAP_DSS_LOAD_FRAME_ONLY)
return 0;
_omap_dispc_initial_config();
dispc_restore_context();

View File

@ -132,7 +132,7 @@ static ssize_t display_timings_show(struct device *dev,
dssdev->driver->get_timings(dssdev, &t);
return snprintf(buf, PAGE_SIZE, "%u,%u/%u/%u/%u,%u/%u/%u/%u\n",
t.pixel_clock,
t.pixelclock,
t.x_res, t.hfp, t.hbp, t.hsw,
t.y_res, t.vfp, t.vbp, t.vsw);
}
@ -158,7 +158,7 @@ static ssize_t display_timings_store(struct device *dev,
}
#endif
if (!found && sscanf(buf, "%u,%hu/%hu/%hu/%hu,%hu/%hu/%hu/%hu",
&t.pixel_clock,
&t.pixelclock,
&t.x_res, &t.hfp, &t.hbp, &t.hsw,
&t.y_res, &t.vfp, &t.vbp, &t.vsw) != 9)
return -EINVAL;

View File

@ -248,7 +248,7 @@ void videomode_to_omap_video_timings(const struct videomode *vm,
{
memset(ovt, 0, sizeof(*ovt));
ovt->pixel_clock = vm->pixelclock / 1000;
ovt->pixelclock = vm->pixelclock;
ovt->x_res = vm->hactive;
ovt->hbp = vm->hback_porch;
ovt->hfp = vm->hfront_porch;
@ -280,7 +280,7 @@ void omap_video_timings_to_videomode(const struct omap_video_timings *ovt,
{
memset(vm, 0, sizeof(*vm));
vm->pixelclock = ovt->pixel_clock * 1000;
vm->pixelclock = ovt->pixelclock;
vm->hactive = ovt->x_res;
vm->hback_porch = ovt->hbp;

View File

@ -307,22 +307,21 @@ static int dpi_set_mode(struct omap_overlay_manager *mgr)
int r = 0;
if (dpi.dsidev)
r = dpi_set_dsi_clk(mgr->id, t->pixel_clock * 1000, &fck,
r = dpi_set_dsi_clk(mgr->id, t->pixelclock, &fck,
&lck_div, &pck_div);
else
r = dpi_set_dispc_clk(t->pixel_clock * 1000, &fck,
r = dpi_set_dispc_clk(t->pixelclock, &fck,
&lck_div, &pck_div);
if (r)
return r;
pck = fck / lck_div / pck_div / 1000;
pck = fck / lck_div / pck_div;
if (pck != t->pixel_clock) {
DSSWARN("Could not find exact pixel clock. "
"Requested %d kHz, got %lu kHz\n",
t->pixel_clock, pck);
if (pck != t->pixelclock) {
DSSWARN("Could not find exact pixel clock. Requested %d Hz, got %lu Hz\n",
t->pixelclock, pck);
t->pixel_clock = pck;
t->pixelclock = pck;
}
dss_mgr_set_timings(mgr, t);
@ -480,17 +479,17 @@ static int dpi_check_timings(struct omap_dss_device *dssdev,
if (mgr && !dispc_mgr_timings_ok(mgr->id, timings))
return -EINVAL;
if (timings->pixel_clock == 0)
if (timings->pixelclock == 0)
return -EINVAL;
if (dpi.dsidev) {
ok = dpi_dsi_clk_calc(timings->pixel_clock * 1000, &ctx);
ok = dpi_dsi_clk_calc(timings->pixelclock, &ctx);
if (!ok)
return -EINVAL;
fck = ctx.dsi_cinfo.dsi_pll_hsdiv_dispc_clk;
} else {
ok = dpi_dss_clk_calc(timings->pixel_clock * 1000, &ctx);
ok = dpi_dss_clk_calc(timings->pixelclock, &ctx);
if (!ok)
return -EINVAL;
@ -500,9 +499,9 @@ static int dpi_check_timings(struct omap_dss_device *dssdev,
lck_div = ctx.dispc_cinfo.lck_div;
pck_div = ctx.dispc_cinfo.pck_div;
pck = fck / lck_div / pck_div / 1000;
pck = fck / lck_div / pck_div;
timings->pixel_clock = pck;
timings->pixelclock = pck;
return 0;
}

View File

@ -4616,7 +4616,7 @@ static void print_dsi_vm(const char *str,
static void print_dispc_vm(const char *str, const struct omap_video_timings *t)
{
unsigned long pck = t->pixel_clock * 1000;
unsigned long pck = t->pixelclock;
int hact, bl, tot;
hact = t->x_res;
@ -4656,7 +4656,7 @@ static void print_dsi_dispc_vm(const char *str,
dsi_hact = DIV_ROUND_UP(DIV_ROUND_UP(t->hact * t->bitspp, 8) + 6, t->ndl);
dsi_htot = t->hss + t->hsa + t->hse + t->hbp + dsi_hact + t->hfp;
vm.pixel_clock = pck / 1000;
vm.pixelclock = pck;
vm.hsw = div64_u64((u64)(t->hsa + t->hse) * pck, byteclk);
vm.hbp = div64_u64((u64)t->hbp * pck, byteclk);
vm.hfp = div64_u64((u64)t->hfp * pck, byteclk);
@ -4678,7 +4678,7 @@ static bool dsi_cm_calc_dispc_cb(int lckd, int pckd, unsigned long lck,
ctx->dispc_cinfo.pck = pck;
*t = *ctx->config->timings;
t->pixel_clock = pck / 1000;
t->pixelclock = pck;
t->x_res = ctx->config->timings->x_res;
t->y_res = ctx->config->timings->y_res;
t->hsw = t->hfp = t->hbp = t->vsw = 1;
@ -4732,7 +4732,7 @@ static bool dsi_cm_calc(struct dsi_data *dsi,
* especially as we go to LP between each pixel packet due to HW
* "feature". So let's just estimate very roughly and multiply by 1.5.
*/
pck = cfg->timings->pixel_clock * 1000;
pck = cfg->timings->pixelclock;
pck = pck * 3 / 2;
txbyteclk = pck * bitspp / 8 / ndl;
@ -4909,7 +4909,7 @@ static bool dsi_vm_calc_blanking(struct dsi_clk_calc_ctx *ctx)
dispc_vm = &ctx->dispc_vm;
*dispc_vm = *req_vm;
dispc_vm->pixel_clock = dispc_pck / 1000;
dispc_vm->pixelclock = dispc_pck;
if (cfg->trans_mode == OMAP_DSS_DSI_PULSE_MODE) {
hsa = div64_u64((u64)req_vm->hsw * dispc_pck,
@ -5031,9 +5031,9 @@ static bool dsi_vm_calc(struct dsi_data *dsi,
ctx->dsi_cinfo.clkin = clkin;
/* these limits should come from the panel driver */
ctx->req_pck_min = t->pixel_clock * 1000 - 1000;
ctx->req_pck_nom = t->pixel_clock * 1000;
ctx->req_pck_max = t->pixel_clock * 1000 + 1000;
ctx->req_pck_min = t->pixelclock - 1000;
ctx->req_pck_nom = t->pixelclock;
ctx->req_pck_max = t->pixelclock + 1000;
byteclk_min = div64_u64((u64)ctx->req_pck_min * bitspp, ndl * 8);
pll_min = max(cfg->hs_clk_min * 4, byteclk_min * 4 * 4);

View File

@ -154,22 +154,6 @@ static void dss_restore_context(void)
#undef SR
#undef RR
int dss_get_ctx_loss_count(void)
{
struct platform_device *core_pdev = dss_get_core_pdev();
struct omap_dss_board_info *board_data = core_pdev->dev.platform_data;
int cnt;
if (!board_data->get_context_loss_count)
return -ENOENT;
cnt = board_data->get_context_loss_count(&dss.pdev->dev);
WARN_ONCE(cnt < 0, "get_context_loss_count failed: %d\n", cnt);
return cnt;
}
void dss_sdi_init(int datapairs)
{
u32 l;

View File

@ -225,8 +225,6 @@ void dss_dump_clocks(struct seq_file *s);
void dss_debug_dump_clocks(struct seq_file *s);
#endif
int dss_get_ctx_loss_count(void);
void dss_sdi_init(int datapairs);
int dss_sdi_enable(void);
void dss_sdi_disable(void);

View File

@ -153,7 +153,8 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res);
phy = p->pixel_clock;
/* the functions below use kHz pixel clock. TODO: change to Hz */
phy = p->pixelclock / 1000;
hdmi_pll_compute(&hdmi.pll, clk_get_rate(hdmi.sys_clk), phy);
@ -238,13 +239,13 @@ static void hdmi_display_set_timing(struct omap_dss_device *dssdev,
if (t != NULL) {
hdmi.cfg = *t;
dispc_set_tv_pclk(t->timings.pixel_clock * 1000);
dispc_set_tv_pclk(t->timings.pixelclock);
} else {
hdmi.cfg.timings = *timings;
hdmi.cfg.cm.code = 0;
hdmi.cfg.cm.mode = HDMI_DVI;
dispc_set_tv_pclk(timings->pixel_clock * 1000);
dispc_set_tv_pclk(timings->pixelclock);
}
DSSDBG("using mode: %s, code %d\n", hdmi.cfg.cm.mode == HDMI_DVI ?
@ -509,7 +510,7 @@ static int hdmi_audio_config(struct omap_dss_device *dssdev,
struct omap_dss_audio *audio)
{
int r;
u32 pclk = hdmi.cfg.timings.pixel_clock;
u32 pclk = hdmi.cfg.timings.pixelclock;
mutex_lock(&hdmi.lock);

View File

@ -23,91 +23,91 @@
static const struct hdmi_config cea_timings[] = {
{
{ 640, 480, 25200, 96, 16, 48, 2, 10, 33,
{ 640, 480, 25200000, 96, 16, 48, 2, 10, 33,
OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
false, },
{ 1, HDMI_HDMI },
},
{
{ 720, 480, 27027, 62, 16, 60, 6, 9, 30,
{ 720, 480, 27027000, 62, 16, 60, 6, 9, 30,
OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
false, },
{ 2, HDMI_HDMI },
},
{
{ 1280, 720, 74250, 40, 110, 220, 5, 5, 20,
{ 1280, 720, 74250000, 40, 110, 220, 5, 5, 20,
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
false, },
{ 4, HDMI_HDMI },
},
{
{ 1920, 540, 74250, 44, 88, 148, 5, 2, 15,
{ 1920, 540, 74250000, 44, 88, 148, 5, 2, 15,
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
true, },
{ 5, HDMI_HDMI },
},
{
{ 1440, 240, 27027, 124, 38, 114, 3, 4, 15,
{ 1440, 240, 27027000, 124, 38, 114, 3, 4, 15,
OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
true, },
{ 6, HDMI_HDMI },
},
{
{ 1920, 1080, 148500, 44, 88, 148, 5, 4, 36,
{ 1920, 1080, 148500000, 44, 88, 148, 5, 4, 36,
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
false, },
{ 16, HDMI_HDMI },
},
{
{ 720, 576, 27000, 64, 12, 68, 5, 5, 39,
{ 720, 576, 27000000, 64, 12, 68, 5, 5, 39,
OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
false, },
{ 17, HDMI_HDMI },
},
{
{ 1280, 720, 74250, 40, 440, 220, 5, 5, 20,
{ 1280, 720, 74250000, 40, 440, 220, 5, 5, 20,
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
false, },
{ 19, HDMI_HDMI },
},
{
{ 1920, 540, 74250, 44, 528, 148, 5, 2, 15,
{ 1920, 540, 74250000, 44, 528, 148, 5, 2, 15,
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
true, },
{ 20, HDMI_HDMI },
},
{
{ 1440, 288, 27000, 126, 24, 138, 3, 2, 19,
{ 1440, 288, 27000000, 126, 24, 138, 3, 2, 19,
OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
true, },
{ 21, HDMI_HDMI },
},
{
{ 1440, 576, 54000, 128, 24, 136, 5, 5, 39,
{ 1440, 576, 54000000, 128, 24, 136, 5, 5, 39,
OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
false, },
{ 29, HDMI_HDMI },
},
{
{ 1920, 1080, 148500, 44, 528, 148, 5, 4, 36,
{ 1920, 1080, 148500000, 44, 528, 148, 5, 4, 36,
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
false, },
{ 31, HDMI_HDMI },
},
{
{ 1920, 1080, 74250, 44, 638, 148, 5, 4, 36,
{ 1920, 1080, 74250000, 44, 638, 148, 5, 4, 36,
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
false, },
{ 32, HDMI_HDMI },
},
{
{ 2880, 480, 108108, 248, 64, 240, 6, 9, 30,
{ 2880, 480, 108108000, 248, 64, 240, 6, 9, 30,
OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
false, },
{ 35, HDMI_HDMI },
},
{
{ 2880, 576, 108000, 256, 48, 272, 5, 5, 39,
{ 2880, 576, 108000000, 256, 48, 272, 5, 5, 39,
OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
false, },
{ 37, HDMI_HDMI },
@ -117,121 +117,121 @@ static const struct hdmi_config cea_timings[] = {
static const struct hdmi_config vesa_timings[] = {
/* VESA From Here */
{
{ 640, 480, 25175, 96, 16, 48, 2, 11, 31,
{ 640, 480, 25175000, 96, 16, 48, 2, 11, 31,
OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
false, },
{ 4, HDMI_DVI },
},
{
{ 800, 600, 40000, 128, 40, 88, 4, 1, 23,
{ 800, 600, 40000000, 128, 40, 88, 4, 1, 23,
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
false, },
{ 9, HDMI_DVI },
},
{
{ 848, 480, 33750, 112, 16, 112, 8, 6, 23,
{ 848, 480, 33750000, 112, 16, 112, 8, 6, 23,
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
false, },
{ 0xE, HDMI_DVI },
},
{
{ 1280, 768, 79500, 128, 64, 192, 7, 3, 20,
{ 1280, 768, 79500000, 128, 64, 192, 7, 3, 20,
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
false, },
{ 0x17, HDMI_DVI },
},
{
{ 1280, 800, 83500, 128, 72, 200, 6, 3, 22,
{ 1280, 800, 83500000, 128, 72, 200, 6, 3, 22,
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
false, },
{ 0x1C, HDMI_DVI },
},
{
{ 1360, 768, 85500, 112, 64, 256, 6, 3, 18,
{ 1360, 768, 85500000, 112, 64, 256, 6, 3, 18,
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
false, },
{ 0x27, HDMI_DVI },
},
{
{ 1280, 960, 108000, 112, 96, 312, 3, 1, 36,
{ 1280, 960, 108000000, 112, 96, 312, 3, 1, 36,
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
false, },
{ 0x20, HDMI_DVI },
},
{
{ 1280, 1024, 108000, 112, 48, 248, 3, 1, 38,
{ 1280, 1024, 108000000, 112, 48, 248, 3, 1, 38,
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
false, },
{ 0x23, HDMI_DVI },
},
{
{ 1024, 768, 65000, 136, 24, 160, 6, 3, 29,
{ 1024, 768, 65000000, 136, 24, 160, 6, 3, 29,
OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
false, },
{ 0x10, HDMI_DVI },
},
{
{ 1400, 1050, 121750, 144, 88, 232, 4, 3, 32,
{ 1400, 1050, 121750000, 144, 88, 232, 4, 3, 32,
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
false, },
{ 0x2A, HDMI_DVI },
},
{
{ 1440, 900, 106500, 152, 80, 232, 6, 3, 25,
{ 1440, 900, 106500000, 152, 80, 232, 6, 3, 25,
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
false, },
{ 0x2F, HDMI_DVI },
},
{
{ 1680, 1050, 146250, 176 , 104, 280, 6, 3, 30,
{ 1680, 1050, 146250000, 176 , 104, 280, 6, 3, 30,
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
false, },
{ 0x3A, HDMI_DVI },
},
{
{ 1366, 768, 85500, 143, 70, 213, 3, 3, 24,
{ 1366, 768, 85500000, 143, 70, 213, 3, 3, 24,
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
false, },
{ 0x51, HDMI_DVI },
},
{
{ 1920, 1080, 148500, 44, 148, 80, 5, 4, 36,
{ 1920, 1080, 148500000, 44, 148, 80, 5, 4, 36,
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
false, },
{ 0x52, HDMI_DVI },
},
{
{ 1280, 768, 68250, 32, 48, 80, 7, 3, 12,
{ 1280, 768, 68250000, 32, 48, 80, 7, 3, 12,
OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
false, },
{ 0x16, HDMI_DVI },
},
{
{ 1400, 1050, 101000, 32, 48, 80, 4, 3, 23,
{ 1400, 1050, 101000000, 32, 48, 80, 4, 3, 23,
OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
false, },
{ 0x29, HDMI_DVI },
},
{
{ 1680, 1050, 119000, 32, 48, 80, 6, 3, 21,
{ 1680, 1050, 119000000, 32, 48, 80, 6, 3, 21,
OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
false, },
{ 0x39, HDMI_DVI },
},
{
{ 1280, 800, 79500, 32, 48, 80, 6, 3, 14,
{ 1280, 800, 79500000, 32, 48, 80, 6, 3, 14,
OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
false, },
{ 0x1B, HDMI_DVI },
},
{
{ 1280, 720, 74250, 40, 110, 220, 5, 5, 20,
{ 1280, 720, 74250000, 40, 110, 220, 5, 5, 20,
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
false, },
{ 0x55, HDMI_DVI },
},
{
{ 1920, 1200, 154000, 32, 48, 80, 6, 3, 26,
{ 1920, 1200, 154000000, 32, 48, 80, 6, 3, 26,
OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
false, },
{ 0x44, HDMI_DVI },
@ -277,8 +277,8 @@ static bool hdmi_timings_compare(struct omap_video_timings *timing1,
{
int timing1_vsync, timing1_hsync, timing2_vsync, timing2_hsync;
if ((DIV_ROUND_CLOSEST(timing2->pixel_clock, 1000) ==
DIV_ROUND_CLOSEST(timing1->pixel_clock, 1000)) &&
if ((DIV_ROUND_CLOSEST(timing2->pixelclock, 1000000) ==
DIV_ROUND_CLOSEST(timing1->pixelclock, 1000000)) &&
(timing2->x_res == timing1->x_res) &&
(timing2->y_res == timing1->y_res)) {

View File

@ -149,20 +149,19 @@ static int sdi_display_enable(struct omap_dss_device *dssdev)
t->data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
t->sync_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
r = sdi_calc_clock_div(t->pixel_clock * 1000, &fck, &dispc_cinfo);
r = sdi_calc_clock_div(t->pixelclock, &fck, &dispc_cinfo);
if (r)
goto err_calc_clock_div;
sdi.mgr_config.clock_info = dispc_cinfo;
pck = fck / dispc_cinfo.lck_div / dispc_cinfo.pck_div / 1000;
pck = fck / dispc_cinfo.lck_div / dispc_cinfo.pck_div;
if (pck != t->pixel_clock) {
DSSWARN("Could not find exact pixel clock. Requested %d kHz, "
"got %lu kHz\n",
t->pixel_clock, pck);
if (pck != t->pixelclock) {
DSSWARN("Could not find exact pixel clock. Requested %d Hz, got %lu Hz\n",
t->pixelclock, pck);
t->pixel_clock = pck;
t->pixelclock = pck;
}
@ -244,7 +243,7 @@ static int sdi_check_timings(struct omap_dss_device *dssdev,
if (mgr && !dispc_mgr_timings_ok(mgr->id, timings))
return -EINVAL;
if (timings->pixel_clock == 0)
if (timings->pixelclock == 0)
return -EINVAL;
return 0;

View File

@ -264,7 +264,7 @@ static const struct venc_config venc_config_pal_bdghi = {
const struct omap_video_timings omap_dss_pal_timings = {
.x_res = 720,
.y_res = 574,
.pixel_clock = 13500,
.pixelclock = 13500000,
.hsw = 64,
.hfp = 12,
.hbp = 68,
@ -279,7 +279,7 @@ EXPORT_SYMBOL(omap_dss_pal_timings);
const struct omap_video_timings omap_dss_ntsc_timings = {
.x_res = 720,
.y_res = 482,
.pixel_clock = 13500,
.pixelclock = 13500000,
.hsw = 64,
.hfp = 16,
.hbp = 58,

View File

@ -89,7 +89,7 @@ static int venc_panel_probe(struct omap_dss_device *dssdev)
const struct omap_video_timings default_timings = {
.x_res = 720,
.y_res = 574,
.pixel_clock = 13500,
.pixelclock = 13500000,
.hsw = 64,
.hfp = 12,
.hbp = 68,

View File

@ -723,8 +723,8 @@ int check_fb_var(struct fb_info *fbi, struct fb_var_screeninfo *var)
display->driver->get_timings(display, &timings);
/* pixclock in ps, the rest in pixclock */
var->pixclock = timings.pixel_clock != 0 ?
KHZ2PICOS(timings.pixel_clock) :
var->pixclock = timings.pixelclock != 0 ?
KHZ2PICOS(timings.pixelclock / 1000) :
0;
var->left_margin = timings.hbp;
var->right_margin = timings.hfp;
@ -2077,7 +2077,7 @@ static int omapfb_mode_to_timings(const char *mode_str,
timings->sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES;
}
timings->pixel_clock = PICOS2KHZ(var->pixclock);
timings->pixelclock = PICOS2KHZ(var->pixclock) * 1000;
timings->hbp = var->left_margin;
timings->hfp = var->right_margin;
timings->vbp = var->upper_margin;
@ -2229,7 +2229,7 @@ static void fb_videomode_to_omap_timings(struct fb_videomode *m,
t->x_res = m->xres;
t->y_res = m->yres;
t->pixel_clock = PICOS2KHZ(m->pixclock);
t->pixelclock = PICOS2KHZ(m->pixclock) * 1000;
t->hsw = m->hsync_len;
t->hfp = m->right_margin;
t->hbp = m->left_margin;

View File

@ -107,7 +107,6 @@ struct pxa3xx_gcu_priv {
struct timeval base_time;
struct pxa3xx_gcu_batch *free;
struct pxa3xx_gcu_batch *ready;
struct pxa3xx_gcu_batch *ready_last;
struct pxa3xx_gcu_batch *running;
@ -368,27 +367,35 @@ pxa3xx_gcu_wait_free(struct pxa3xx_gcu_priv *priv)
/* Misc device layer */
static inline struct pxa3xx_gcu_priv *file_dev(struct file *file)
static inline struct pxa3xx_gcu_priv *to_pxa3xx_gcu_priv(struct file *file)
{
struct miscdevice *dev = file->private_data;
return container_of(dev, struct pxa3xx_gcu_priv, misc_dev);
}
/*
* provide an empty .open callback, so the core sets file->private_data
* for us.
*/
static int pxa3xx_gcu_open(struct inode *inode, struct file *file)
{
return 0;
}
static ssize_t
pxa3xx_gcu_misc_write(struct file *file, const char *buff,
size_t count, loff_t *offp)
pxa3xx_gcu_write(struct file *file, const char *buff,
size_t count, loff_t *offp)
{
int ret;
unsigned long flags;
struct pxa3xx_gcu_batch *buffer;
struct pxa3xx_gcu_priv *priv = file_dev(file);
struct pxa3xx_gcu_priv *priv = to_pxa3xx_gcu_priv(file);
int words = count / 4;
/* Does not need to be atomic. There's a lock in user space,
* but anyhow, this is just for statistics. */
priv->shared->num_writes++;
priv->shared->num_words += words;
/* Last word reserved for batch buffer end command */
@ -406,10 +413,8 @@ pxa3xx_gcu_misc_write(struct file *file, const char *buff,
* Get buffer from free list
*/
spin_lock_irqsave(&priv->spinlock, flags);
buffer = priv->free;
priv->free = buffer->next;
spin_unlock_irqrestore(&priv->spinlock, flags);
@ -454,10 +459,10 @@ pxa3xx_gcu_misc_write(struct file *file, const char *buff,
static long
pxa3xx_gcu_misc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
pxa3xx_gcu_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
unsigned long flags;
struct pxa3xx_gcu_priv *priv = file_dev(file);
struct pxa3xx_gcu_priv *priv = to_pxa3xx_gcu_priv(file);
switch (cmd) {
case PXA3XX_GCU_IOCTL_RESET:
@ -474,10 +479,10 @@ pxa3xx_gcu_misc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
}
static int
pxa3xx_gcu_misc_mmap(struct file *file, struct vm_area_struct *vma)
pxa3xx_gcu_mmap(struct file *file, struct vm_area_struct *vma)
{
unsigned int size = vma->vm_end - vma->vm_start;
struct pxa3xx_gcu_priv *priv = file_dev(file);
struct pxa3xx_gcu_priv *priv = to_pxa3xx_gcu_priv(file);
switch (vma->vm_pgoff) {
case 0:
@ -532,8 +537,8 @@ static inline void pxa3xx_gcu_init_debug_timer(void) {}
#endif
static int
add_buffer(struct platform_device *dev,
struct pxa3xx_gcu_priv *priv)
pxa3xx_gcu_add_buffer(struct device *dev,
struct pxa3xx_gcu_priv *priv)
{
struct pxa3xx_gcu_batch *buffer;
@ -541,7 +546,7 @@ add_buffer(struct platform_device *dev,
if (!buffer)
return -ENOMEM;
buffer->ptr = dma_alloc_coherent(&dev->dev, PXA3XX_GCU_BATCH_WORDS * 4,
buffer->ptr = dma_alloc_coherent(dev, PXA3XX_GCU_BATCH_WORDS * 4,
&buffer->phys, GFP_KERNEL);
if (!buffer->ptr) {
kfree(buffer);
@ -549,57 +554,49 @@ add_buffer(struct platform_device *dev,
}
buffer->next = priv->free;
priv->free = buffer;
return 0;
}
static void
free_buffers(struct platform_device *dev,
struct pxa3xx_gcu_priv *priv)
pxa3xx_gcu_free_buffers(struct device *dev,
struct pxa3xx_gcu_priv *priv)
{
struct pxa3xx_gcu_batch *next, *buffer = priv->free;
while (buffer) {
next = buffer->next;
dma_free_coherent(&dev->dev, PXA3XX_GCU_BATCH_WORDS * 4,
dma_free_coherent(dev, PXA3XX_GCU_BATCH_WORDS * 4,
buffer->ptr, buffer->phys);
kfree(buffer);
buffer = next;
}
priv->free = NULL;
}
static const struct file_operations misc_fops = {
.owner = THIS_MODULE,
.write = pxa3xx_gcu_misc_write,
.unlocked_ioctl = pxa3xx_gcu_misc_ioctl,
.mmap = pxa3xx_gcu_misc_mmap
static const struct file_operations pxa3xx_gcu_miscdev_fops = {
.owner = THIS_MODULE,
.open = pxa3xx_gcu_open,
.write = pxa3xx_gcu_write,
.unlocked_ioctl = pxa3xx_gcu_ioctl,
.mmap = pxa3xx_gcu_mmap,
};
static int pxa3xx_gcu_probe(struct platform_device *dev)
static int pxa3xx_gcu_probe(struct platform_device *pdev)
{
int i, ret, irq;
struct resource *r;
struct pxa3xx_gcu_priv *priv;
struct device *dev = &pdev->dev;
priv = kzalloc(sizeof(struct pxa3xx_gcu_priv), GFP_KERNEL);
priv = devm_kzalloc(dev, sizeof(struct pxa3xx_gcu_priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
for (i = 0; i < 8; i++) {
ret = add_buffer(dev, priv);
if (ret) {
dev_err(&dev->dev, "failed to allocate DMA memory\n");
goto err_free_priv;
}
}
init_waitqueue_head(&priv->wait_idle);
init_waitqueue_head(&priv->wait_free);
spin_lock_init(&priv->spinlock);
@ -611,125 +608,99 @@ static int pxa3xx_gcu_probe(struct platform_device *dev)
priv->misc_dev.minor = MISCDEV_MINOR,
priv->misc_dev.name = DRV_NAME,
priv->misc_dev.fops = &misc_fops,
priv->misc_dev.fops = &pxa3xx_gcu_miscdev_fops;
/* handle IO resources */
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
priv->mmio_base = devm_request_and_ioremap(dev, r);
if (IS_ERR(priv->mmio_base)) {
dev_err(dev, "failed to map I/O memory\n");
return PTR_ERR(priv->mmio_base);
}
/* enable the clock */
priv->clk = devm_clk_get(dev, NULL);
if (IS_ERR(priv->clk)) {
dev_err(dev, "failed to get clock\n");
return PTR_ERR(priv->clk);
}
/* request the IRQ */
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_err(dev, "no IRQ defined\n");
return -ENODEV;
}
ret = devm_request_irq(dev, irq, pxa3xx_gcu_handle_irq,
0, DRV_NAME, priv);
if (ret < 0) {
dev_err(dev, "request_irq failed\n");
return ret;
}
/* allocate dma memory */
priv->shared = dma_alloc_coherent(dev, SHARED_SIZE,
&priv->shared_phys, GFP_KERNEL);
if (!priv->shared) {
dev_err(dev, "failed to allocate DMA memory\n");
return -ENOMEM;
}
/* register misc device */
ret = misc_register(&priv->misc_dev);
if (ret < 0) {
dev_err(&dev->dev, "misc_register() for minor %d failed\n",
dev_err(dev, "misc_register() for minor %d failed\n",
MISCDEV_MINOR);
goto err_free_priv;
}
/* handle IO resources */
r = platform_get_resource(dev, IORESOURCE_MEM, 0);
if (r == NULL) {
dev_err(&dev->dev, "no I/O memory resource defined\n");
ret = -ENODEV;
goto err_misc_deregister;
}
if (!request_mem_region(r->start, resource_size(r), dev->name)) {
dev_err(&dev->dev, "failed to request I/O memory\n");
ret = -EBUSY;
goto err_misc_deregister;
}
priv->mmio_base = ioremap_nocache(r->start, resource_size(r));
if (!priv->mmio_base) {
dev_err(&dev->dev, "failed to map I/O memory\n");
ret = -EBUSY;
goto err_free_mem_region;
}
/* allocate dma memory */
priv->shared = dma_alloc_coherent(&dev->dev, SHARED_SIZE,
&priv->shared_phys, GFP_KERNEL);
if (!priv->shared) {
dev_err(&dev->dev, "failed to allocate DMA memory\n");
ret = -ENOMEM;
goto err_free_io;
}
/* enable the clock */
priv->clk = clk_get(&dev->dev, NULL);
if (IS_ERR(priv->clk)) {
dev_err(&dev->dev, "failed to get clock\n");
ret = -ENODEV;
goto err_free_dma;
}
ret = clk_enable(priv->clk);
if (ret < 0) {
dev_err(&dev->dev, "failed to enable clock\n");
goto err_put_clk;
dev_err(dev, "failed to enable clock\n");
goto err_misc_deregister;
}
/* request the IRQ */
irq = platform_get_irq(dev, 0);
if (irq < 0) {
dev_err(&dev->dev, "no IRQ defined\n");
ret = -ENODEV;
goto err_put_clk;
for (i = 0; i < 8; i++) {
ret = pxa3xx_gcu_add_buffer(dev, priv);
if (ret) {
dev_err(dev, "failed to allocate DMA memory\n");
goto err_disable_clk;
}
}
ret = request_irq(irq, pxa3xx_gcu_handle_irq,
0, DRV_NAME, priv);
if (ret) {
dev_err(&dev->dev, "request_irq failed\n");
ret = -EBUSY;
goto err_put_clk;
}
platform_set_drvdata(dev, priv);
platform_set_drvdata(pdev, priv);
priv->resource_mem = r;
pxa3xx_gcu_reset(priv);
pxa3xx_gcu_init_debug_timer();
dev_info(&dev->dev, "registered @0x%p, DMA 0x%p (%d bytes), IRQ %d\n",
dev_info(dev, "registered @0x%p, DMA 0x%p (%d bytes), IRQ %d\n",
(void *) r->start, (void *) priv->shared_phys,
SHARED_SIZE, irq);
return 0;
err_put_clk:
clk_disable(priv->clk);
clk_put(priv->clk);
err_free_dma:
dma_free_coherent(&dev->dev, SHARED_SIZE,
dma_free_coherent(dev, SHARED_SIZE,
priv->shared, priv->shared_phys);
err_free_io:
iounmap(priv->mmio_base);
err_free_mem_region:
release_mem_region(r->start, resource_size(r));
err_misc_deregister:
misc_deregister(&priv->misc_dev);
err_free_priv:
free_buffers(dev, priv);
kfree(priv);
err_disable_clk:
clk_disable(priv->clk);
return ret;
}
static int pxa3xx_gcu_remove(struct platform_device *dev)
static int pxa3xx_gcu_remove(struct platform_device *pdev)
{
struct pxa3xx_gcu_priv *priv = platform_get_drvdata(dev);
struct resource *r = priv->resource_mem;
struct pxa3xx_gcu_priv *priv = platform_get_drvdata(pdev);
struct device *dev = &pdev->dev;
pxa3xx_gcu_wait_idle(priv);
misc_deregister(&priv->misc_dev);
dma_free_coherent(&dev->dev, SHARED_SIZE,
priv->shared, priv->shared_phys);
iounmap(priv->mmio_base);
release_mem_region(r->start, resource_size(r));
clk_disable(priv->clk);
free_buffers(dev, priv);
kfree(priv);
dma_free_coherent(dev, SHARED_SIZE, priv->shared, priv->shared_phys);
pxa3xx_gcu_free_buffers(dev, priv);
return 0;
}

View File

@ -651,6 +651,7 @@ SiS_GetModeID_LCD(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDispla
switch(VDisplay) {
case 720:
ModeIndex = ModeIndex_1280x720[Depth];
break;
case 768:
if(VGAEngine == SIS_300_VGA) {
ModeIndex = ModeIndex_300_1280x768[Depth];

View File

@ -182,6 +182,8 @@ tgafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
if (var->xres_virtual != var->xres || var->yres_virtual != var->yres)
return -EINVAL;
if (var->xres * var->yres * (var->bits_per_pixel >> 3) > info->fix.smem_len)
return -EINVAL;
if (var->nonstd)
return -EINVAL;
if (1000000000 / var->pixclock > TGA_PLL_MAX_FREQ)
@ -190,8 +192,8 @@ tgafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
return -EINVAL;
/* Some of the acceleration routines assume the line width is
a multiple of 64 bytes. */
if (var->xres * (par->tga_type == TGA_TYPE_8PLANE ? 1 : 4) % 64)
a multiple of 8 bytes. */
if (var->xres * (par->tga_type == TGA_TYPE_8PLANE ? 1 : 4) % 8)
return -EINVAL;
return 0;
@ -262,6 +264,7 @@ tgafb_set_par(struct fb_info *info)
par->yres = info->var.yres;
par->pll_freq = pll_freq = 1000000000 / info->var.pixclock;
par->bits_per_pixel = info->var.bits_per_pixel;
info->fix.line_length = par->xres * (par->bits_per_pixel >> 3);
tga_type = par->tga_type;
@ -1136,222 +1139,57 @@ copyarea_line_32bpp(struct fb_info *info, u32 dy, u32 sy,
__raw_writel(TGA_MODE_SBM_24BPP|TGA_MODE_SIMPLE, tga_regs+TGA_MODE_REG);
}
/* The general case of forward copy in 8bpp mode. */
static inline void
copyarea_foreward_8bpp(struct fb_info *info, u32 dx, u32 dy, u32 sx, u32 sy,
u32 height, u32 width, u32 line_length)
{
struct tga_par *par = (struct tga_par *) info->par;
unsigned long i, copied, left;
unsigned long dpos, spos, dalign, salign, yincr;
u32 smask_first, dmask_first, dmask_last;
int pixel_shift, need_prime, need_second;
unsigned long n64, n32, xincr_first;
void __iomem *tga_regs;
void __iomem *tga_fb;
yincr = line_length;
if (dy > sy) {
dy += height - 1;
sy += height - 1;
yincr = -yincr;
}
/* Compute the offsets and alignments in the frame buffer.
More than anything else, these control how we do copies. */
dpos = dy * line_length + dx;
spos = sy * line_length + sx;
dalign = dpos & 7;
salign = spos & 7;
dpos &= -8;
spos &= -8;
/* Compute the value for the PIXELSHIFT register. This controls
both non-co-aligned source and destination and copy direction. */
if (dalign >= salign)
pixel_shift = dalign - salign;
else
pixel_shift = 8 - (salign - dalign);
/* Figure out if we need an additional priming step for the
residue register. */
need_prime = (salign > dalign);
if (need_prime)
dpos -= 8;
/* Begin by copying the leading unaligned destination. Copy enough
to make the next destination address 32-byte aligned. */
copied = 32 - (dalign + (dpos & 31));
if (copied == 32)
copied = 0;
xincr_first = (copied + 7) & -8;
smask_first = dmask_first = (1ul << copied) - 1;
smask_first <<= salign;
dmask_first <<= dalign + need_prime*8;
if (need_prime && copied > 24)
copied -= 8;
left = width - copied;
/* Care for small copies. */
if (copied > width) {
u32 t;
t = (1ul << width) - 1;
t <<= dalign + need_prime*8;
dmask_first &= t;
left = 0;
}
/* Attempt to use 64-byte copies. This is only possible if the
source and destination are co-aligned at 64 bytes. */
n64 = need_second = 0;
if ((dpos & 63) == (spos & 63)
&& (height == 1 || line_length % 64 == 0)) {
/* We may need a 32-byte copy to ensure 64 byte alignment. */
need_second = (dpos + xincr_first) & 63;
if ((need_second & 32) != need_second)
printk(KERN_ERR "tgafb: need_second wrong\n");
if (left >= need_second + 64) {
left -= need_second;
n64 = left / 64;
left %= 64;
} else
need_second = 0;
}
/* Copy trailing full 32-byte sections. This will be the main
loop if the 64 byte loop can't be used. */
n32 = left / 32;
left %= 32;
/* Copy the trailing unaligned destination. */
dmask_last = (1ul << left) - 1;
tga_regs = par->tga_regs_base;
tga_fb = par->tga_fb_base;
/* Set up the MODE and PIXELSHIFT registers. */
__raw_writel(TGA_MODE_SBM_8BPP|TGA_MODE_COPY, tga_regs+TGA_MODE_REG);
__raw_writel(pixel_shift, tga_regs+TGA_PIXELSHIFT_REG);
wmb();
for (i = 0; i < height; ++i) {
unsigned long j;
void __iomem *sfb;
void __iomem *dfb;
sfb = tga_fb + spos;
dfb = tga_fb + dpos;
if (dmask_first) {
__raw_writel(smask_first, sfb);
wmb();
__raw_writel(dmask_first, dfb);
wmb();
sfb += xincr_first;
dfb += xincr_first;
}
if (need_second) {
__raw_writel(0xffffffff, sfb);
wmb();
__raw_writel(0xffffffff, dfb);
wmb();
sfb += 32;
dfb += 32;
}
if (n64 && (((unsigned long)sfb | (unsigned long)dfb) & 63))
printk(KERN_ERR
"tgafb: misaligned copy64 (s:%p, d:%p)\n",
sfb, dfb);
for (j = 0; j < n64; ++j) {
__raw_writel(sfb - tga_fb, tga_regs+TGA_COPY64_SRC);
wmb();
__raw_writel(dfb - tga_fb, tga_regs+TGA_COPY64_DST);
wmb();
sfb += 64;
dfb += 64;
}
for (j = 0; j < n32; ++j) {
__raw_writel(0xffffffff, sfb);
wmb();
__raw_writel(0xffffffff, dfb);
wmb();
sfb += 32;
dfb += 32;
}
if (dmask_last) {
__raw_writel(0xffffffff, sfb);
wmb();
__raw_writel(dmask_last, dfb);
wmb();
}
spos += yincr;
dpos += yincr;
}
/* Reset the MODE register to normal. */
__raw_writel(TGA_MODE_SBM_8BPP|TGA_MODE_SIMPLE, tga_regs+TGA_MODE_REG);
}
/* The (almost) general case of backward copy in 8bpp mode. */
static inline void
copyarea_backward_8bpp(struct fb_info *info, u32 dx, u32 dy, u32 sx, u32 sy,
u32 height, u32 width, u32 line_length,
const struct fb_copyarea *area)
copyarea_8bpp(struct fb_info *info, u32 dx, u32 dy, u32 sx, u32 sy,
u32 height, u32 width, u32 line_length,
const struct fb_copyarea *area)
{
struct tga_par *par = (struct tga_par *) info->par;
unsigned long i, left, yincr;
unsigned long depos, sepos, dealign, sealign;
u32 mask_first, mask_last;
unsigned long n32;
unsigned i, yincr;
int depos, sepos, backward, last_step, step;
u32 mask_last;
unsigned n32;
void __iomem *tga_regs;
void __iomem *tga_fb;
yincr = line_length;
if (dy > sy) {
dy += height - 1;
sy += height - 1;
yincr = -yincr;
}
/* Compute the offsets and alignments in the frame buffer.
More than anything else, these control how we do copies. */
depos = dy * line_length + dx + width;
sepos = sy * line_length + sx + width;
dealign = depos & 7;
sealign = sepos & 7;
/* ??? The documentation appears to be incorrect (or very
misleading) wrt how pixel shifting works in backward copy
mode, i.e. when PIXELSHIFT is negative. I give up for now.
Do handle the common case of co-aligned backward copies,
but frob everything else back on generic code. */
if (dealign != sealign) {
/* Do acceleration only if we are aligned on 8 pixels */
if ((dx | sx | width) & 7) {
cfb_copyarea(info, area);
return;
}
/* We begin the copy with the trailing pixels of the
unaligned destination. */
mask_first = (1ul << dealign) - 1;
left = width - dealign;
/* Care for small copies. */
if (dealign > width) {
mask_first ^= (1ul << (dealign - width)) - 1;
left = 0;
yincr = line_length;
if (dy > sy) {
dy += height - 1;
sy += height - 1;
yincr = -yincr;
}
backward = dy == sy && dx > sx && dx < sx + width;
/* Compute the offsets and alignments in the frame buffer.
More than anything else, these control how we do copies. */
depos = dy * line_length + dx;
sepos = sy * line_length + sx;
if (backward)
depos += width, sepos += width;
/* Next copy full words at a time. */
n32 = left / 32;
left %= 32;
n32 = width / 32;
last_step = width % 32;
/* Finally copy the unaligned head of the span. */
mask_last = -1 << (32 - left);
mask_last = (1ul << last_step) - 1;
if (!backward) {
step = 32;
last_step = 32;
} else {
step = -32;
last_step = -last_step;
sepos -= 32;
depos -= 32;
}
tga_regs = par->tga_regs_base;
tga_fb = par->tga_fb_base;
@ -1368,25 +1206,33 @@ copyarea_backward_8bpp(struct fb_info *info, u32 dx, u32 dy, u32 sx, u32 sy,
sfb = tga_fb + sepos;
dfb = tga_fb + depos;
if (mask_first) {
__raw_writel(mask_first, sfb);
wmb();
__raw_writel(mask_first, dfb);
wmb();
}
for (j = 0; j < n32; ++j) {
sfb -= 32;
dfb -= 32;
for (j = 0; j < n32; j++) {
if (j < 2 && j + 1 < n32 && !backward &&
!(((unsigned long)sfb | (unsigned long)dfb) & 63)) {
do {
__raw_writel(sfb - tga_fb, tga_regs+TGA_COPY64_SRC);
wmb();
__raw_writel(dfb - tga_fb, tga_regs+TGA_COPY64_DST);
wmb();
sfb += 64;
dfb += 64;
j += 2;
} while (j + 1 < n32);
j--;
continue;
}
__raw_writel(0xffffffff, sfb);
wmb();
__raw_writel(0xffffffff, dfb);
wmb();
sfb += step;
dfb += step;
}
if (mask_last) {
sfb -= 32;
dfb -= 32;
sfb += last_step - step;
dfb += last_step - step;
__raw_writel(mask_last, sfb);
wmb();
__raw_writel(mask_last, dfb);
@ -1434,7 +1280,7 @@ tgafb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
bpp = info->var.bits_per_pixel;
/* Detect copies of the entire line. */
if (width * (bpp >> 3) == line_length) {
if (!(line_length & 63) && width * (bpp >> 3) == line_length) {
if (bpp == 8)
copyarea_line_8bpp(info, dy, sy, height, width);
else
@ -1447,14 +1293,9 @@ tgafb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
else if (bpp == 32)
cfb_copyarea(info, area);
/* Detect overlapping source and destination that requires
a backward copy. */
else if (dy == sy && dx > sx && dx < sx + width)
copyarea_backward_8bpp(info, dx, dy, sx, sy, height,
width, line_length, area);
else
copyarea_foreward_8bpp(info, dx, dy, sx, sy, height,
width, line_length);
copyarea_8bpp(info, dx, dy, sx, sy, height,
width, line_length, area);
}
@ -1470,6 +1311,7 @@ tgafb_init_fix(struct fb_info *info)
int tga_bus_tc = TGA_BUS_TC(par->dev);
u8 tga_type = par->tga_type;
const char *tga_type_name = NULL;
unsigned memory_size;
switch (tga_type) {
case TGA_TYPE_8PLANE:
@ -1477,22 +1319,27 @@ tgafb_init_fix(struct fb_info *info)
tga_type_name = "Digital ZLXp-E1";
if (tga_bus_tc)
tga_type_name = "Digital ZLX-E1";
memory_size = 2097152;
break;
case TGA_TYPE_24PLANE:
if (tga_bus_pci)
tga_type_name = "Digital ZLXp-E2";
if (tga_bus_tc)
tga_type_name = "Digital ZLX-E2";
memory_size = 8388608;
break;
case TGA_TYPE_24PLUSZ:
if (tga_bus_pci)
tga_type_name = "Digital ZLXp-E3";
if (tga_bus_tc)
tga_type_name = "Digital ZLX-E3";
memory_size = 16777216;
break;
}
if (!tga_type_name)
if (!tga_type_name) {
tga_type_name = "Unknown";
memory_size = 16777216;
}
strlcpy(info->fix.id, tga_type_name, sizeof(info->fix.id));
@ -1502,9 +1349,8 @@ tgafb_init_fix(struct fb_info *info)
? FB_VISUAL_PSEUDOCOLOR
: FB_VISUAL_DIRECTCOLOR);
info->fix.line_length = par->xres * (par->bits_per_pixel >> 3);
info->fix.smem_start = (size_t) par->tga_fb_base;
info->fix.smem_len = info->fix.line_length * par->yres;
info->fix.smem_len = memory_size;
info->fix.mmio_start = (size_t) par->tga_regs_base;
info->fix.mmio_len = 512;
@ -1628,6 +1474,9 @@ static int tgafb_register(struct device *dev)
modedb_tga = &modedb_tc;
modedbsize_tga = 1;
}
tgafb_init_fix(info);
ret = fb_find_mode(&info->var, info,
mode_option ? mode_option : mode_option_tga,
modedb_tga, modedbsize_tga, NULL,
@ -1645,7 +1494,6 @@ static int tgafb_register(struct device *dev)
}
tgafb_set_par(info);
tgafb_init_fix(info);
if (register_framebuffer(info) < 0) {
printk(KERN_ERR "tgafb: Could not register framebuffer\n");

View File

@ -1474,12 +1474,7 @@ static void uvesafb_init_info(struct fb_info *info, struct vbe_mode_ib *mode)
* used video mode, i.e. the minimum amount of
* memory we need.
*/
if (mode != NULL) {
size_vmode = info->var.yres * mode->bytes_per_scan_line;
} else {
size_vmode = info->var.yres * info->var.xres *
((info->var.bits_per_pixel + 7) >> 3);
}
size_vmode = info->var.yres * mode->bytes_per_scan_line;
/*
* size_total -- all video memory we have. Used for mtrr
@ -1812,11 +1807,9 @@ static int uvesafb_remove(struct platform_device *dev)
fb_destroy_modedb(info->monspecs.modedb);
fb_dealloc_cmap(&info->cmap);
if (par) {
kfree(par->vbe_modes);
kfree(par->vbe_state_orig);
kfree(par->vbe_state_saved);
}
kfree(par->vbe_modes);
kfree(par->vbe_state_orig);
kfree(par->vbe_state_saved);
framebuffer_release(info);
}

View File

@ -179,7 +179,6 @@ static void vesafb_destroy(struct fb_info *info)
if (info->screen_base)
iounmap(info->screen_base);
release_mem_region(info->apertures->ranges[0].base, info->apertures->ranges[0].size);
framebuffer_release(info);
}
static struct fb_ops vesafb_ops = {
@ -297,6 +296,7 @@ static int vesafb_probe(struct platform_device *dev)
release_mem_region(vesafb_fix.smem_start, size_total);
return -ENOMEM;
}
platform_set_drvdata(dev, info);
info->pseudo_palette = info->par;
info->par = NULL;
@ -499,12 +499,23 @@ err:
return err;
}
static int vesafb_remove(struct platform_device *pdev)
{
struct fb_info *info = platform_get_drvdata(pdev);
unregister_framebuffer(info);
framebuffer_release(info);
return 0;
}
static struct platform_driver vesafb_driver = {
.driver = {
.name = "vesa-framebuffer",
.owner = THIS_MODULE,
},
.probe = vesafb_probe,
.remove = vesafb_remove,
};
module_platform_driver(vesafb_driver);

View File

@ -33,7 +33,6 @@
#include <linux/of_platform.h>
#include <linux/of_address.h>
#include <linux/io.h>
#include <linux/xilinxfb.h>
#include <linux/slab.h>
#ifdef CONFIG_PPC_DCR
@ -84,6 +83,20 @@
#define PALETTE_ENTRIES_NO 16 /* passed to fb_alloc_cmap() */
/* ML300/403 reference design framebuffer driver platform data struct */
struct xilinxfb_platform_data {
u32 rotate_screen; /* Flag to rotate display 180 degrees */
u32 screen_height_mm; /* Physical dimensions of screen in mm */
u32 screen_width_mm;
u32 xres, yres; /* resolution of screen in pixels */
u32 xvirt, yvirt; /* resolution of memory buffer */
/* Physical address of framebuffer memory; If non-zero, driver
* will use provided memory address instead of allocating one from
* the consistent pool. */
u32 fb_phys;
};
/*
* Default xilinxfb configuration
*/

View File

@ -61,24 +61,12 @@ struct imx_fb_platform_data {
struct imx_fb_videomode *mode;
int num_modes;
u_int cmap_greyscale:1,
cmap_inverse:1,
cmap_static:1,
unused:29;
u_int pwmr;
u_int lscr1;
u_int dmacr;
u_char * fixed_screen_cpu;
dma_addr_t fixed_screen_dma;
int (*init)(struct platform_device *);
void (*exit)(struct platform_device *);
void (*lcd_power)(int);
void (*backlight_power)(int);
};
void set_imx_fb_info(struct imx_fb_platform_data *);
#endif /* ifndef __MACH_IMXFB_H__ */

View File

@ -1,30 +0,0 @@
/*
* Platform device data for Xilinx Framebuffer device
*
* Copyright 2007 Secret Lab Technologies Ltd.
*
* This file is licensed under the terms of the GNU General Public License
* version 2. This program is licensed "as is" without any warranty of any
* kind, whether express or implied.
*/
#ifndef __XILINXFB_H__
#define __XILINXFB_H__
#include <linux/types.h>
/* ML300/403 reference design framebuffer driver platform data struct */
struct xilinxfb_platform_data {
u32 rotate_screen; /* Flag to rotate display 180 degrees */
u32 screen_height_mm; /* Physical dimensions of screen in mm */
u32 screen_width_mm;
u32 xres, yres; /* resolution of screen in pixels */
u32 xvirt, yvirt; /* resolution of memory buffer */
/* Physical address of framebuffer memory; If non-zero, driver
* will use provided memory address instead of allocating one from
* the consistent pool. */
u32 fb_phys;
};
#endif /* __XILINXFB_H__ */

View File

@ -323,7 +323,6 @@ enum omapdss_version {
/* Board specific data */
struct omap_dss_board_info {
int (*get_context_loss_count)(struct device *dev);
int num_devices;
struct omap_dss_device **devices;
struct omap_dss_device *default_device;
@ -344,8 +343,8 @@ struct omap_video_timings {
u16 x_res;
/* Unit: pixels */
u16 y_res;
/* Unit: KHz */
u32 pixel_clock;
/* Unit: Hz */
u32 pixelclock;
/* Unit: pixel clocks */
u16 hsw; /* Horizontal synchronization pulse width */
/* Unit: pixel clocks */