fbdev for 3.10
* use vm_iomap_memory() in various fb drivers to map the fb memory to userspace * Cleanups for the videomode and display_timing features * Updates to vt8500, wm8505 and auo-k190x fb drivers -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iQIcBAABAgAGBQJRflTCAAoJEPo9qoy8lh71w+8P/RBU/twhd0S1aqPC1Lb7H9Tb mfcIFzqpvIwItqw6dIe5c6WC3eggDpj0O74PnXtbxeQSYQOfoZgzayPkaYF2TmN6 5S3bVeHhQmybho3LZUjIclaBIF3mwNNmsVfBjfObCp6Gy9ziybDBiZhF0/GcUVGt h/D2QlmCDM7QrheYehVhquiPI5+7oxHqGbl+eYMjjNL7+jIiCCeqrXuDQJqx6Gxk Q88xicao8TCDLRniMrHAJv/e99x6cQ1Fa8grsbnFghLr6PITu088OZNNuYdUdIV3 WNfqTp7AGHHvja1evfj8kgTVwP/eeourkPIrRMFHNaHNOsTfu6HP//L5rynAQ5vI EwIGbZNzjI11zeJAljgXL4Lqgo7mavV24DoHHliQm79OdWrXLm+l8AFfA2OF6BNf 10H4m60deX4O6ALfjvLMx89gxXcPfb6pdnnWoyJW3DLU2BHv3V+tMNLRA+g7L7LC FE+Z23UCxSHk4S+WwtfrwHjPL+R260kOB9xkaal6ekc4utyg2KFqGyaOigWKGdCO jZZJOXMuQQ1dZhFh3Yh9Hy/Sw0FI+40g7HhqdtENlqlJVa7LCt5PQEI6lGtiNkCA MrH+5KnW2Pbut+DK8ONePhHEkc6PKGXxH3pD8IjRYZRufwBtEtmzaZk8kC0M2BHJ p3fSEPwBuaz84fM20Du1 =L5rT -----END PGP SIGNATURE----- Merge tag 'fbdev-for-3.10' of git://gitorious.org/linux-omap-dss2/linux Pull fbdev updates from Tomi Valkeinen: - use vm_iomap_memory() in various fb drivers to map the fb memory to userspace - Cleanups for the videomode and display_timing features - Updates to vt8500, wm8505 and auo-k190x fb drivers * tag 'fbdev-for-3.10' of git://gitorious.org/linux-omap-dss2/linux: (36 commits) fbdev: fix check for fb_mmap's mmio availability fbdev: improve fb_mmap bounds checks fbdev/ps3fb: use vm_iomap_memory() fbdev/sgivwfb: use vm_iomap_memory() fbdev/vermillion: use vm_iomap_memory() fbdev/sa1100fb: use vm_iomap_memory() fbdev/fb-puv3: use vm_iomap_memory() fbdev/controlfb: use vm_iomap_memory() fbdev/omapfb: use vm_iomap_memory() video: vt8500: fix Kconfig for videomode video/s3c: move platform_data out of arch/arm video/exynos: remove unnecessary header inclusions drivers/video: fsl-diu-fb: add hardware cursor support drivers: video: use module_platform_driver_probe() ARM: OMAP: remove "config FB_OMAP_CONSISTENT_DMA_SIZE" video: wm8505fb: Convert to devm_ioremap_resource() AUO-K190x: Add resolutions for portrait displays AUO-K190x: add framebuffer rotation support AUO-K190x: add a 16bit truecolor mode AUO-K190x: make color handling more flexible ...
This commit is contained in:
Коммит
8127b39e70
|
@ -5,58 +5,32 @@ Required properties:
|
|||
- compatible : "via,vt8500-fb"
|
||||
- reg : Should contain 1 register ranges(address and length)
|
||||
- interrupts : framebuffer controller interrupt
|
||||
- display: a phandle pointing to the display node
|
||||
- bits-per-pixel : bit depth of framebuffer (16 or 32)
|
||||
|
||||
Required nodes:
|
||||
- display: a display node is required to initialize the lcd panel
|
||||
This should be in the board dts.
|
||||
- default-mode: a videomode within the display with timing parameters
|
||||
as specified below.
|
||||
Required subnodes:
|
||||
- display-timings: see display-timing.txt for information
|
||||
|
||||
Example:
|
||||
|
||||
fb@d800e400 {
|
||||
fb@d8050800 {
|
||||
compatible = "via,vt8500-fb";
|
||||
reg = <0xd800e400 0x400>;
|
||||
interrupts = <12>;
|
||||
display = <&display>;
|
||||
default-mode = <&mode0>;
|
||||
};
|
||||
bits-per-pixel = <16>;
|
||||
|
||||
VIA VT8500 Display
|
||||
-----------------------------------------------------
|
||||
Required properties (as per of_videomode_helper):
|
||||
|
||||
- hactive, vactive: Display resolution
|
||||
- hfront-porch, hback-porch, hsync-len: Horizontal Display timing parameters
|
||||
in pixels
|
||||
vfront-porch, vback-porch, vsync-len: Vertical display timing parameters in
|
||||
lines
|
||||
- clock: displayclock in Hz
|
||||
- bpp: lcd panel bit-depth.
|
||||
<16> for RGB565, <32> for RGB888
|
||||
|
||||
Optional properties (as per of_videomode_helper):
|
||||
- width-mm, height-mm: Display dimensions in mm
|
||||
- hsync-active-high (bool): Hsync pulse is active high
|
||||
- vsync-active-high (bool): Vsync pulse is active high
|
||||
- interlaced (bool): This is an interlaced mode
|
||||
- doublescan (bool): This is a doublescan mode
|
||||
|
||||
Example:
|
||||
display: display@0 {
|
||||
modes {
|
||||
mode0: mode@0 {
|
||||
display-timings {
|
||||
native-mode = <&timing0>;
|
||||
timing0: 800x480 {
|
||||
clock-frequency = <0>; /* unused but required */
|
||||
hactive = <800>;
|
||||
vactive = <480>;
|
||||
hback-porch = <88>;
|
||||
hfront-porch = <40>;
|
||||
hback-porch = <88>;
|
||||
hsync-len = <0>;
|
||||
vback-porch = <32>;
|
||||
vfront-porch = <11>;
|
||||
vsync-len = <1>;
|
||||
clock = <0>; /* unused but required */
|
||||
bpp = <16>; /* non-standard but required */
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -4,20 +4,30 @@ Wondermedia WM8505 Framebuffer
|
|||
Required properties:
|
||||
- compatible : "wm,wm8505-fb"
|
||||
- reg : Should contain 1 register ranges(address and length)
|
||||
- via,display: a phandle pointing to the display node
|
||||
- bits-per-pixel : bit depth of framebuffer (16 or 32)
|
||||
|
||||
Required nodes:
|
||||
- display: a display node is required to initialize the lcd panel
|
||||
This should be in the board dts. See definition in
|
||||
Documentation/devicetree/bindings/video/via,vt8500-fb.txt
|
||||
- default-mode: a videomode node as specified in
|
||||
Documentation/devicetree/bindings/video/via,vt8500-fb.txt
|
||||
Required subnodes:
|
||||
- display-timings: see display-timing.txt for information
|
||||
|
||||
Example:
|
||||
|
||||
fb@d8050800 {
|
||||
fb@d8051700 {
|
||||
compatible = "wm,wm8505-fb";
|
||||
reg = <0xd8050800 0x200>;
|
||||
display = <&display>;
|
||||
default-mode = <&mode0>;
|
||||
reg = <0xd8051700 0x200>;
|
||||
bits-per-pixel = <16>;
|
||||
|
||||
display-timings {
|
||||
native-mode = <&timing0>;
|
||||
timing0: 800x480 {
|
||||
clock-frequency = <0>; /* unused but required */
|
||||
hactive = <800>;
|
||||
vactive = <480>;
|
||||
hfront-porch = <40>;
|
||||
hback-porch = <88>;
|
||||
hsync-len = <0>;
|
||||
vback-porch = <32>;
|
||||
vfront-porch = <11>;
|
||||
vsync-len = <1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -11,26 +11,22 @@
|
|||
|
||||
/ {
|
||||
model = "Benign BV07 Netbook";
|
||||
};
|
||||
|
||||
/*
|
||||
* Display node is based on Sascha Hauer's patch on dri-devel.
|
||||
* Added a bpp property to calculate the size of the framebuffer
|
||||
* until the binding is formalized.
|
||||
*/
|
||||
display: display@0 {
|
||||
modes {
|
||||
mode0: mode@0 {
|
||||
hactive = <800>;
|
||||
vactive = <480>;
|
||||
hback-porch = <88>;
|
||||
hfront-porch = <40>;
|
||||
hsync-len = <0>;
|
||||
vback-porch = <32>;
|
||||
vfront-porch = <11>;
|
||||
vsync-len = <1>;
|
||||
clock = <0>; /* unused but required */
|
||||
bpp = <16>; /* non-standard but required */
|
||||
};
|
||||
&fb {
|
||||
bits-per-pixel = <16>;
|
||||
display-timings {
|
||||
native-mode = <&timing0>;
|
||||
timing0: 800x480 {
|
||||
clock-frequency = <0>; /* unused but required */
|
||||
hactive = <800>;
|
||||
vactive = <480>;
|
||||
hfront-porch = <40>;
|
||||
hback-porch = <88>;
|
||||
hsync-len = <0>;
|
||||
vback-porch = <32>;
|
||||
vfront-porch = <11>;
|
||||
vsync-len = <1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -98,12 +98,10 @@
|
|||
interrupts = <43>;
|
||||
};
|
||||
|
||||
fb@d800e400 {
|
||||
fb: fb@d8050800 {
|
||||
compatible = "via,vt8500-fb";
|
||||
reg = <0xd800e400 0x400>;
|
||||
interrupts = <12>;
|
||||
display = <&display>;
|
||||
default-mode = <&mode0>;
|
||||
};
|
||||
|
||||
ge_rops@d8050400 {
|
||||
|
|
|
@ -11,26 +11,22 @@
|
|||
|
||||
/ {
|
||||
model = "Wondermedia WM8505 Netbook";
|
||||
};
|
||||
|
||||
/*
|
||||
* Display node is based on Sascha Hauer's patch on dri-devel.
|
||||
* Added a bpp property to calculate the size of the framebuffer
|
||||
* until the binding is formalized.
|
||||
*/
|
||||
display: display@0 {
|
||||
modes {
|
||||
mode0: mode@0 {
|
||||
hactive = <800>;
|
||||
vactive = <480>;
|
||||
hback-porch = <88>;
|
||||
hfront-porch = <40>;
|
||||
hsync-len = <0>;
|
||||
vback-porch = <32>;
|
||||
vfront-porch = <11>;
|
||||
vsync-len = <1>;
|
||||
clock = <0>; /* unused but required */
|
||||
bpp = <32>; /* non-standard but required */
|
||||
};
|
||||
&fb {
|
||||
bits-per-pixel = <32>;
|
||||
display-timings {
|
||||
native-mode = <&timing0>;
|
||||
timing0: 800x480 {
|
||||
clock-frequency = <0>; /* unused but required */
|
||||
hactive = <800>;
|
||||
vactive = <480>;
|
||||
hfront-porch = <40>;
|
||||
hback-porch = <88>;
|
||||
hsync-len = <0>;
|
||||
vback-porch = <32>;
|
||||
vfront-porch = <11>;
|
||||
vsync-len = <1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -128,11 +128,9 @@
|
|||
interrupts = <0>;
|
||||
};
|
||||
|
||||
fb@d8050800 {
|
||||
fb: fb@d8050800 {
|
||||
compatible = "wm,wm8505-fb";
|
||||
reg = <0xd8050800 0x200>;
|
||||
display = <&display>;
|
||||
default-mode = <&mode0>;
|
||||
};
|
||||
|
||||
ge_rops@d8050400 {
|
||||
|
|
|
@ -11,26 +11,24 @@
|
|||
|
||||
/ {
|
||||
model = "Wondermedia WM8650-MID Tablet";
|
||||
};
|
||||
|
||||
/*
|
||||
* Display node is based on Sascha Hauer's patch on dri-devel.
|
||||
* Added a bpp property to calculate the size of the framebuffer
|
||||
* until the binding is formalized.
|
||||
*/
|
||||
display: display@0 {
|
||||
modes {
|
||||
mode0: mode@0 {
|
||||
hactive = <800>;
|
||||
vactive = <480>;
|
||||
hback-porch = <88>;
|
||||
hfront-porch = <40>;
|
||||
hsync-len = <0>;
|
||||
vback-porch = <32>;
|
||||
vfront-porch = <11>;
|
||||
vsync-len = <1>;
|
||||
clock = <0>; /* unused but required */
|
||||
bpp = <16>; /* non-standard but required */
|
||||
};
|
||||
&fb {
|
||||
bits-per-pixel = <16>;
|
||||
|
||||
display-timings {
|
||||
native-mode = <&timing0>;
|
||||
timing0: 800x480 {
|
||||
clock-frequency = <0>; /* unused but required */
|
||||
hactive = <800>;
|
||||
vactive = <480>;
|
||||
hfront-porch = <40>;
|
||||
hback-porch = <88>;
|
||||
hsync-len = <0>;
|
||||
vback-porch = <32>;
|
||||
vfront-porch = <11>;
|
||||
vsync-len = <1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -128,11 +128,9 @@
|
|||
interrupts = <43>;
|
||||
};
|
||||
|
||||
fb@d8050800 {
|
||||
fb: fb@d8050800 {
|
||||
compatible = "wm,wm8505-fb";
|
||||
reg = <0xd8050800 0x200>;
|
||||
display = <&display>;
|
||||
default-mode = <&mode0>;
|
||||
};
|
||||
|
||||
ge_rops@d8050400 {
|
||||
|
|
|
@ -15,28 +15,6 @@
|
|||
/ {
|
||||
model = "Wondermedia WM8850-W70v2 Tablet";
|
||||
|
||||
/*
|
||||
* Display node is based on Sascha Hauer's patch on dri-devel.
|
||||
* Added a bpp property to calculate the size of the framebuffer
|
||||
* until the binding is formalized.
|
||||
*/
|
||||
display: display@0 {
|
||||
modes {
|
||||
mode0: mode@0 {
|
||||
hactive = <800>;
|
||||
vactive = <480>;
|
||||
hback-porch = <88>;
|
||||
hfront-porch = <40>;
|
||||
hsync-len = <0>;
|
||||
vback-porch = <32>;
|
||||
vfront-porch = <11>;
|
||||
vsync-len = <1>;
|
||||
clock = <0>; /* unused but required */
|
||||
bpp = <16>; /* non-standard but required */
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
backlight {
|
||||
compatible = "pwm-backlight";
|
||||
pwms = <&pwm 0 50000 1>; /* duty inverted */
|
||||
|
@ -45,3 +23,21 @@
|
|||
default-brightness-level = <5>;
|
||||
};
|
||||
};
|
||||
|
||||
&fb {
|
||||
bits-per-pixel = <16>;
|
||||
display-timings {
|
||||
native-mode = <&timing0>;
|
||||
timing0: 800x480 {
|
||||
clock-frequency = <0>; /* unused but required */
|
||||
hactive = <800>;
|
||||
vactive = <480>;
|
||||
hfront-porch = <40>;
|
||||
hback-porch = <88>;
|
||||
hsync-len = <0>;
|
||||
vback-porch = <32>;
|
||||
vfront-porch = <11>;
|
||||
vsync-len = <1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -135,11 +135,9 @@
|
|||
};
|
||||
};
|
||||
|
||||
fb@d8051700 {
|
||||
fb: fb@d8051700 {
|
||||
compatible = "wm,wm8505-fb";
|
||||
reg = <0xd8051700 0x200>;
|
||||
display = <&display>;
|
||||
default-mode = <&mode0>;
|
||||
};
|
||||
|
||||
ge_rops@d8050400 {
|
||||
|
|
|
@ -15,55 +15,7 @@
|
|||
#ifndef __PLAT_S3C_FB_H
|
||||
#define __PLAT_S3C_FB_H __FILE__
|
||||
|
||||
/* S3C_FB_MAX_WIN
|
||||
* Set to the maximum number of windows that any of the supported hardware
|
||||
* can use. Since the platform data uses this for an array size, having it
|
||||
* set to the maximum of any version of the hardware can do is safe.
|
||||
*/
|
||||
#define S3C_FB_MAX_WIN (5)
|
||||
|
||||
/**
|
||||
* struct s3c_fb_pd_win - per window setup data
|
||||
* @xres : The window X size.
|
||||
* @yres : The window Y size.
|
||||
* @virtual_x: The virtual X size.
|
||||
* @virtual_y: The virtual Y size.
|
||||
*/
|
||||
struct s3c_fb_pd_win {
|
||||
unsigned short default_bpp;
|
||||
unsigned short max_bpp;
|
||||
unsigned short xres;
|
||||
unsigned short yres;
|
||||
unsigned short virtual_x;
|
||||
unsigned short virtual_y;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct s3c_fb_platdata - S3C driver platform specific information
|
||||
* @setup_gpio: Setup the external GPIO pins to the right state to transfer
|
||||
* the data from the display system to the connected display
|
||||
* device.
|
||||
* @vidcon0: The base vidcon0 values to control the panel data format.
|
||||
* @vidcon1: The base vidcon1 values to control the panel data output.
|
||||
* @vtiming: Video timing when connected to a RGB type panel.
|
||||
* @win: The setup data for each hardware window, or NULL for unused.
|
||||
* @display_mode: The LCD output display mode.
|
||||
*
|
||||
* The platform data supplies the video driver with all the information
|
||||
* it requires to work with the display(s) attached to the machine. It
|
||||
* controls the initial mode, the number of display windows (0 is always
|
||||
* the base framebuffer) that are initialised etc.
|
||||
*
|
||||
*/
|
||||
struct s3c_fb_platdata {
|
||||
void (*setup_gpio)(void);
|
||||
|
||||
struct s3c_fb_pd_win *win[S3C_FB_MAX_WIN];
|
||||
struct fb_videomode *vtiming;
|
||||
|
||||
u32 vidcon0;
|
||||
u32 vidcon1;
|
||||
};
|
||||
#include <linux/platform_data/video_s3c.h>
|
||||
|
||||
/**
|
||||
* s3c_fb_set_platdata() - Setup the FB device with platform data.
|
||||
|
|
|
@ -506,7 +506,7 @@ drm_gtf_mode(struct drm_device *dev, int hdisplay, int vdisplay, int vrefresh,
|
|||
}
|
||||
EXPORT_SYMBOL(drm_gtf_mode);
|
||||
|
||||
#if IS_ENABLED(CONFIG_VIDEOMODE)
|
||||
#ifdef CONFIG_VIDEOMODE_HELPERS
|
||||
int drm_display_mode_from_videomode(const struct videomode *vm,
|
||||
struct drm_display_mode *dmode)
|
||||
{
|
||||
|
@ -523,26 +523,25 @@ int drm_display_mode_from_videomode(const struct videomode *vm,
|
|||
dmode->clock = vm->pixelclock / 1000;
|
||||
|
||||
dmode->flags = 0;
|
||||
if (vm->dmt_flags & VESA_DMT_HSYNC_HIGH)
|
||||
if (vm->flags & DISPLAY_FLAGS_HSYNC_HIGH)
|
||||
dmode->flags |= DRM_MODE_FLAG_PHSYNC;
|
||||
else if (vm->dmt_flags & VESA_DMT_HSYNC_LOW)
|
||||
else if (vm->flags & DISPLAY_FLAGS_HSYNC_LOW)
|
||||
dmode->flags |= DRM_MODE_FLAG_NHSYNC;
|
||||
if (vm->dmt_flags & VESA_DMT_VSYNC_HIGH)
|
||||
if (vm->flags & DISPLAY_FLAGS_VSYNC_HIGH)
|
||||
dmode->flags |= DRM_MODE_FLAG_PVSYNC;
|
||||
else if (vm->dmt_flags & VESA_DMT_VSYNC_LOW)
|
||||
else if (vm->flags & DISPLAY_FLAGS_VSYNC_LOW)
|
||||
dmode->flags |= DRM_MODE_FLAG_NVSYNC;
|
||||
if (vm->data_flags & DISPLAY_FLAGS_INTERLACED)
|
||||
if (vm->flags & DISPLAY_FLAGS_INTERLACED)
|
||||
dmode->flags |= DRM_MODE_FLAG_INTERLACE;
|
||||
if (vm->data_flags & DISPLAY_FLAGS_DOUBLESCAN)
|
||||
if (vm->flags & DISPLAY_FLAGS_DOUBLESCAN)
|
||||
dmode->flags |= DRM_MODE_FLAG_DBLSCAN;
|
||||
drm_mode_set_name(dmode);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(drm_display_mode_from_videomode);
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_OF_VIDEOMODE)
|
||||
#ifdef CONFIG_OF
|
||||
/**
|
||||
* of_get_drm_display_mode - get a drm_display_mode from devicetree
|
||||
* @np: device_node with the timing specification
|
||||
|
@ -572,7 +571,8 @@ int of_get_drm_display_mode(struct device_node *np,
|
|||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_get_drm_display_mode);
|
||||
#endif
|
||||
#endif /* CONFIG_OF */
|
||||
#endif /* CONFIG_VIDEOMODE_HELPERS */
|
||||
|
||||
/**
|
||||
* drm_mode_set_name - set the name on a mode
|
||||
|
|
|
@ -4,8 +4,7 @@ config DRM_TILCDC
|
|||
select DRM_KMS_HELPER
|
||||
select DRM_KMS_CMA_HELPER
|
||||
select DRM_GEM_CMA_HELPER
|
||||
select OF_VIDEOMODE
|
||||
select OF_DISPLAY_TIMING
|
||||
select VIDEOMODE_HELPERS
|
||||
select BACKLIGHT_CLASS_DEVICE
|
||||
help
|
||||
Choose this option if you have an TI SoC with LCDC display
|
||||
|
|
|
@ -173,7 +173,7 @@ static int panel_connector_get_modes(struct drm_connector *connector)
|
|||
struct drm_display_mode *mode = drm_mode_create(dev);
|
||||
struct videomode vm;
|
||||
|
||||
if (videomode_from_timing(timings, &vm, i))
|
||||
if (videomode_from_timings(timings, &vm, i))
|
||||
break;
|
||||
|
||||
drm_display_mode_from_videomode(&vm, mode);
|
||||
|
|
|
@ -31,26 +31,8 @@ config VIDEO_OUTPUT_CONTROL
|
|||
This framework adds support for low-level control of the video
|
||||
output switch.
|
||||
|
||||
config DISPLAY_TIMING
|
||||
bool
|
||||
|
||||
config VIDEOMODE
|
||||
bool
|
||||
|
||||
config OF_DISPLAY_TIMING
|
||||
bool "Enable device tree display timing support"
|
||||
depends on OF
|
||||
select DISPLAY_TIMING
|
||||
help
|
||||
helper to parse display timings from the devicetree
|
||||
|
||||
config OF_VIDEOMODE
|
||||
bool "Enable device tree videomode support"
|
||||
depends on OF
|
||||
select VIDEOMODE
|
||||
select OF_DISPLAY_TIMING
|
||||
help
|
||||
helper to get videomodes from the devicetree
|
||||
config VIDEOMODE_HELPERS
|
||||
bool
|
||||
|
||||
config HDMI
|
||||
bool
|
||||
|
@ -212,14 +194,6 @@ config FB_SYS_FOPS
|
|||
depends on FB
|
||||
default n
|
||||
|
||||
config FB_WMT_GE_ROPS
|
||||
tristate
|
||||
depends on FB
|
||||
default n
|
||||
---help---
|
||||
Include functions for accelerated rectangle filling and area
|
||||
copying using WonderMedia Graphics Engine operations.
|
||||
|
||||
config FB_DEFERRED_IO
|
||||
bool
|
||||
depends on FB
|
||||
|
@ -1797,22 +1771,37 @@ config FB_AU1200
|
|||
option au1200fb:panel=<name>.
|
||||
|
||||
config FB_VT8500
|
||||
bool "VT8500 LCD Driver"
|
||||
bool "VIA VT8500 framebuffer support"
|
||||
depends on (FB = y) && ARM && ARCH_VT8500
|
||||
select FB_WMT_GE_ROPS
|
||||
select FB_SYS_FILLRECT if (!FB_WMT_GE_ROPS)
|
||||
select FB_SYS_COPYAREA if (!FB_WMT_GE_ROPS)
|
||||
select FB_SYS_IMAGEBLIT
|
||||
select FB_MODE_HELPERS
|
||||
select VIDEOMODE_HELPERS
|
||||
help
|
||||
This is the framebuffer driver for VIA VT8500 integrated LCD
|
||||
controller.
|
||||
|
||||
config FB_WM8505
|
||||
bool "WM8505 frame buffer support"
|
||||
bool "Wondermedia WM8xxx-series frame buffer support"
|
||||
depends on (FB = y) && ARM && ARCH_VT8500
|
||||
select FB_WMT_GE_ROPS
|
||||
select FB_SYS_FILLRECT if (!FB_WMT_GE_ROPS)
|
||||
select FB_SYS_COPYAREA if (!FB_WMT_GE_ROPS)
|
||||
select FB_SYS_IMAGEBLIT
|
||||
select FB_MODE_HELPERS
|
||||
select VIDEOMODE_HELPERS
|
||||
help
|
||||
This is the framebuffer driver for WonderMedia WM8505/WM8650
|
||||
integrated LCD controller.
|
||||
This is the framebuffer driver for WonderMedia WM8xxx-series
|
||||
integrated LCD controller. This driver covers the WM8505, WM8650
|
||||
and WM8850 SoCs.
|
||||
|
||||
config FB_WMT_GE_ROPS
|
||||
bool "VT8500/WM8xxx accelerated raster ops support"
|
||||
depends on (FB = y) && (FB_VT8500 || FB_WM8505)
|
||||
default n
|
||||
help
|
||||
This adds support for accelerated raster operations on the
|
||||
VIA VT8500 and Wondermedia 85xx series SoCs.
|
||||
|
||||
source "drivers/video/geode/Kconfig"
|
||||
|
||||
|
|
|
@ -171,7 +171,7 @@ obj-$(CONFIG_FB_VIRTUAL) += vfb.o
|
|||
|
||||
#video output switch sysfs driver
|
||||
obj-$(CONFIG_VIDEO_OUTPUT_CONTROL) += output.o
|
||||
obj-$(CONFIG_DISPLAY_TIMING) += display_timing.o
|
||||
obj-$(CONFIG_OF_DISPLAY_TIMING) += of_display_timing.o
|
||||
obj-$(CONFIG_VIDEOMODE) += videomode.o
|
||||
obj-$(CONFIG_OF_VIDEOMODE) += of_videomode.o
|
||||
obj-$(CONFIG_VIDEOMODE_HELPERS) += display_timing.o videomode.o
|
||||
ifeq ($(CONFIG_OF),y)
|
||||
obj-$(CONFIG_VIDEOMODE_HELPERS) += of_display_timing.o of_videomode.o
|
||||
endif
|
||||
|
|
|
@ -3788,19 +3788,7 @@ static struct platform_driver amifb_driver = {
|
|||
},
|
||||
};
|
||||
|
||||
static int __init amifb_init(void)
|
||||
{
|
||||
return platform_driver_probe(&amifb_driver, amifb_probe);
|
||||
}
|
||||
|
||||
module_init(amifb_init);
|
||||
|
||||
static void __exit amifb_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&amifb_driver);
|
||||
}
|
||||
|
||||
module_exit(amifb_exit);
|
||||
module_platform_driver_probe(amifb_driver, amifb_probe);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("platform:amiga-video");
|
||||
|
|
|
@ -1158,18 +1158,7 @@ static struct platform_driver atmel_lcdfb_driver = {
|
|||
},
|
||||
};
|
||||
|
||||
static int __init atmel_lcdfb_init(void)
|
||||
{
|
||||
return platform_driver_probe(&atmel_lcdfb_driver, atmel_lcdfb_probe);
|
||||
}
|
||||
|
||||
static void __exit atmel_lcdfb_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&atmel_lcdfb_driver);
|
||||
}
|
||||
|
||||
module_init(atmel_lcdfb_init);
|
||||
module_exit(atmel_lcdfb_exit);
|
||||
module_platform_driver_probe(atmel_lcdfb_driver, atmel_lcdfb_probe);
|
||||
|
||||
MODULE_DESCRIPTION("AT91/AT32 LCD Controller framebuffer driver");
|
||||
MODULE_AUTHOR("Nicolas Ferre <nicolas.ferre@atmel.com>");
|
||||
|
|
|
@ -60,9 +60,12 @@
|
|||
|
||||
static void auok1900_init(struct auok190xfb_par *par)
|
||||
{
|
||||
struct device *dev = par->info->device;
|
||||
struct auok190x_board *board = par->board;
|
||||
u16 init_param = 0;
|
||||
|
||||
pm_runtime_get_sync(dev);
|
||||
|
||||
init_param |= AUOK1900_INIT_TEMP_AVERAGE;
|
||||
init_param |= AUOK1900_INIT_ROTATE(par->rotation);
|
||||
init_param |= AUOK190X_INIT_INVERSE_WHITE;
|
||||
|
@ -74,6 +77,9 @@ static void auok1900_init(struct auok190xfb_par *par)
|
|||
|
||||
/* let the controller finish */
|
||||
board->wait_for_rdy(par);
|
||||
|
||||
pm_runtime_mark_last_busy(dev);
|
||||
pm_runtime_put_autosuspend(dev);
|
||||
}
|
||||
|
||||
static void auok1900_update_region(struct auok190xfb_par *par, int mode,
|
||||
|
@ -82,6 +88,7 @@ static void auok1900_update_region(struct auok190xfb_par *par, int mode,
|
|||
struct device *dev = par->info->device;
|
||||
unsigned char *buf = (unsigned char *)par->info->screen_base;
|
||||
int xres = par->info->var.xres;
|
||||
int line_length = par->info->fix.line_length;
|
||||
u16 args[4];
|
||||
|
||||
pm_runtime_get_sync(dev);
|
||||
|
@ -100,9 +107,9 @@ static void auok1900_update_region(struct auok190xfb_par *par, int mode,
|
|||
args[1] = y1 + 1;
|
||||
args[2] = xres;
|
||||
args[3] = y2 - y1;
|
||||
buf += y1 * xres;
|
||||
buf += y1 * line_length;
|
||||
auok190x_send_cmdargs_pixels(par, AUOK1900_CMD_PARTIALDISP, 4, args,
|
||||
((y2 - y1) * xres)/2, (u16 *) buf);
|
||||
((y2 - y1) * line_length)/2, (u16 *) buf);
|
||||
auok190x_send_command(par, AUOK190X_CMD_DATA_STOP);
|
||||
|
||||
par->update_cnt++;
|
||||
|
|
|
@ -101,9 +101,12 @@
|
|||
|
||||
static void auok1901_init(struct auok190xfb_par *par)
|
||||
{
|
||||
struct device *dev = par->info->device;
|
||||
struct auok190x_board *board = par->board;
|
||||
u16 init_param = 0;
|
||||
|
||||
pm_runtime_get_sync(dev);
|
||||
|
||||
init_param |= AUOK190X_INIT_INVERSE_WHITE;
|
||||
init_param |= AUOK190X_INIT_FORMAT0;
|
||||
init_param |= AUOK1901_INIT_RESOLUTION(par->resolution);
|
||||
|
@ -113,6 +116,9 @@ static void auok1901_init(struct auok190xfb_par *par)
|
|||
|
||||
/* let the controller finish */
|
||||
board->wait_for_rdy(par);
|
||||
|
||||
pm_runtime_mark_last_busy(dev);
|
||||
pm_runtime_put_autosuspend(dev);
|
||||
}
|
||||
|
||||
static void auok1901_update_region(struct auok190xfb_par *par, int mode,
|
||||
|
@ -121,6 +127,7 @@ static void auok1901_update_region(struct auok190xfb_par *par, int mode,
|
|||
struct device *dev = par->info->device;
|
||||
unsigned char *buf = (unsigned char *)par->info->screen_base;
|
||||
int xres = par->info->var.xres;
|
||||
int line_length = par->info->fix.line_length;
|
||||
u16 args[5];
|
||||
|
||||
pm_runtime_get_sync(dev);
|
||||
|
@ -139,9 +146,9 @@ static void auok1901_update_region(struct auok190xfb_par *par, int mode,
|
|||
args[1] = y1 + 1;
|
||||
args[2] = xres;
|
||||
args[3] = y2 - y1;
|
||||
buf += y1 * xres;
|
||||
buf += y1 * line_length;
|
||||
auok190x_send_cmdargs_pixels_nowait(par, AUOK1901_CMD_DMA_START, 4,
|
||||
args, ((y2 - y1) * xres)/2,
|
||||
args, ((y2 - y1) * line_length)/2,
|
||||
(u16 *) buf);
|
||||
auok190x_send_command_nowait(par, AUOK190X_CMD_DATA_STOP);
|
||||
|
||||
|
|
|
@ -40,6 +40,14 @@ static struct panel_info panel_table[] = {
|
|||
.w = 1024,
|
||||
.h = 768,
|
||||
},
|
||||
[AUOK190X_RESOLUTION_600_800] = {
|
||||
.w = 600,
|
||||
.h = 800,
|
||||
},
|
||||
[AUOK190X_RESOLUTION_768_1024] = {
|
||||
.w = 768,
|
||||
.h = 1024,
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -60,8 +68,48 @@ static void auok190x_issue_cmd(struct auok190xfb_par *par, u16 data)
|
|||
par->board->set_ctl(par, AUOK190X_I80_DC, 1);
|
||||
}
|
||||
|
||||
static int auok190x_issue_pixels(struct auok190xfb_par *par, int size,
|
||||
u16 *data)
|
||||
/**
|
||||
* Conversion of 16bit color to 4bit grayscale
|
||||
* does roughly (0.3 * R + 0.6 G + 0.1 B) / 2
|
||||
*/
|
||||
static inline int rgb565_to_gray4(u16 data, struct fb_var_screeninfo *var)
|
||||
{
|
||||
return ((((data & 0xF800) >> var->red.offset) * 77 +
|
||||
((data & 0x07E0) >> (var->green.offset + 1)) * 151 +
|
||||
((data & 0x1F) >> var->blue.offset) * 28) >> 8 >> 1);
|
||||
}
|
||||
|
||||
static int auok190x_issue_pixels_rgb565(struct auok190xfb_par *par, int size,
|
||||
u16 *data)
|
||||
{
|
||||
struct fb_var_screeninfo *var = &par->info->var;
|
||||
struct device *dev = par->info->device;
|
||||
int i;
|
||||
u16 tmp;
|
||||
|
||||
if (size & 7) {
|
||||
dev_err(dev, "issue_pixels: size %d must be a multiple of 8\n",
|
||||
size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < (size >> 2); i++) {
|
||||
par->board->set_ctl(par, AUOK190X_I80_WR, 0);
|
||||
|
||||
tmp = (rgb565_to_gray4(data[4*i], var) & 0x000F);
|
||||
tmp |= (rgb565_to_gray4(data[4*i+1], var) << 4) & 0x00F0;
|
||||
tmp |= (rgb565_to_gray4(data[4*i+2], var) << 8) & 0x0F00;
|
||||
tmp |= (rgb565_to_gray4(data[4*i+3], var) << 12) & 0xF000;
|
||||
|
||||
par->board->set_hdb(par, tmp);
|
||||
par->board->set_ctl(par, AUOK190X_I80_WR, 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int auok190x_issue_pixels_gray8(struct auok190xfb_par *par, int size,
|
||||
u16 *data)
|
||||
{
|
||||
struct device *dev = par->info->device;
|
||||
int i;
|
||||
|
@ -91,6 +139,23 @@ static int auok190x_issue_pixels(struct auok190xfb_par *par, int size,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int auok190x_issue_pixels(struct auok190xfb_par *par, int size,
|
||||
u16 *data)
|
||||
{
|
||||
struct fb_info *info = par->info;
|
||||
struct device *dev = par->info->device;
|
||||
|
||||
if (info->var.bits_per_pixel == 8 && info->var.grayscale)
|
||||
auok190x_issue_pixels_gray8(par, size, data);
|
||||
else if (info->var.bits_per_pixel == 16)
|
||||
auok190x_issue_pixels_rgb565(par, size, data);
|
||||
else
|
||||
dev_err(dev, "unsupported color mode (bits: %d, gray: %d)\n",
|
||||
info->var.bits_per_pixel, info->var.grayscale);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u16 auok190x_read_data(struct auok190xfb_par *par)
|
||||
{
|
||||
u16 data;
|
||||
|
@ -224,8 +289,8 @@ static void auok190xfb_dpy_deferred_io(struct fb_info *info,
|
|||
{
|
||||
struct fb_deferred_io *fbdefio = info->fbdefio;
|
||||
struct auok190xfb_par *par = info->par;
|
||||
u16 line_length = info->fix.line_length;
|
||||
u16 yres = info->var.yres;
|
||||
u16 xres = info->var.xres;
|
||||
u16 y1 = 0, h = 0;
|
||||
int prev_index = -1;
|
||||
struct page *cur;
|
||||
|
@ -254,7 +319,7 @@ static void auok190xfb_dpy_deferred_io(struct fb_info *info,
|
|||
}
|
||||
|
||||
/* height increment is fixed per page */
|
||||
h_inc = DIV_ROUND_UP(PAGE_SIZE , xres);
|
||||
h_inc = DIV_ROUND_UP(PAGE_SIZE , line_length);
|
||||
|
||||
/* calculate number of pages from pixel height */
|
||||
threshold = par->consecutive_threshold / h_inc;
|
||||
|
@ -265,7 +330,7 @@ static void auok190xfb_dpy_deferred_io(struct fb_info *info,
|
|||
list_for_each_entry(cur, &fbdefio->pagelist, lru) {
|
||||
if (prev_index < 0) {
|
||||
/* just starting so assign first page */
|
||||
y1 = (cur->index << PAGE_SHIFT) / xres;
|
||||
y1 = (cur->index << PAGE_SHIFT) / line_length;
|
||||
h = h_inc;
|
||||
} else if ((cur->index - prev_index) <= threshold) {
|
||||
/* page is within our threshold for single updates */
|
||||
|
@ -275,7 +340,7 @@ static void auok190xfb_dpy_deferred_io(struct fb_info *info,
|
|||
par->update_partial(par, y1, y1 + h);
|
||||
|
||||
/* start over with our non consecutive page */
|
||||
y1 = (cur->index << PAGE_SHIFT) / xres;
|
||||
y1 = (cur->index << PAGE_SHIFT) / line_length;
|
||||
h = h_inc;
|
||||
}
|
||||
prev_index = cur->index;
|
||||
|
@ -376,27 +441,127 @@ static void auok190xfb_imageblit(struct fb_info *info,
|
|||
static int auok190xfb_check_var(struct fb_var_screeninfo *var,
|
||||
struct fb_info *info)
|
||||
{
|
||||
if (info->var.xres != var->xres || info->var.yres != var->yres ||
|
||||
info->var.xres_virtual != var->xres_virtual ||
|
||||
info->var.yres_virtual != var->yres_virtual) {
|
||||
pr_info("%s: Resolution not supported: X%u x Y%u\n",
|
||||
__func__, var->xres, var->yres);
|
||||
struct device *dev = info->device;
|
||||
struct auok190xfb_par *par = info->par;
|
||||
struct panel_info *panel = &panel_table[par->resolution];
|
||||
int size;
|
||||
|
||||
/*
|
||||
* Color depth
|
||||
*/
|
||||
|
||||
if (var->bits_per_pixel == 8 && var->grayscale == 1) {
|
||||
/*
|
||||
* For 8-bit grayscale, R, G, and B offset are equal.
|
||||
*/
|
||||
var->red.length = 8;
|
||||
var->red.offset = 0;
|
||||
var->red.msb_right = 0;
|
||||
|
||||
var->green.length = 8;
|
||||
var->green.offset = 0;
|
||||
var->green.msb_right = 0;
|
||||
|
||||
var->blue.length = 8;
|
||||
var->blue.offset = 0;
|
||||
var->blue.msb_right = 0;
|
||||
|
||||
var->transp.length = 0;
|
||||
var->transp.offset = 0;
|
||||
var->transp.msb_right = 0;
|
||||
} else if (var->bits_per_pixel == 16) {
|
||||
var->red.length = 5;
|
||||
var->red.offset = 11;
|
||||
var->red.msb_right = 0;
|
||||
|
||||
var->green.length = 6;
|
||||
var->green.offset = 5;
|
||||
var->green.msb_right = 0;
|
||||
|
||||
var->blue.length = 5;
|
||||
var->blue.offset = 0;
|
||||
var->blue.msb_right = 0;
|
||||
|
||||
var->transp.length = 0;
|
||||
var->transp.offset = 0;
|
||||
var->transp.msb_right = 0;
|
||||
} else {
|
||||
dev_warn(dev, "unsupported color mode (bits: %d, grayscale: %d)\n",
|
||||
info->var.bits_per_pixel, info->var.grayscale);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Dimensions
|
||||
*/
|
||||
|
||||
switch (var->rotate) {
|
||||
case FB_ROTATE_UR:
|
||||
case FB_ROTATE_UD:
|
||||
var->xres = panel->w;
|
||||
var->yres = panel->h;
|
||||
break;
|
||||
case FB_ROTATE_CW:
|
||||
case FB_ROTATE_CCW:
|
||||
var->xres = panel->h;
|
||||
var->yres = panel->w;
|
||||
break;
|
||||
default:
|
||||
dev_dbg(dev, "Invalid rotation request\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
var->xres_virtual = var->xres;
|
||||
var->yres_virtual = var->yres;
|
||||
|
||||
/*
|
||||
* Memory limit
|
||||
*/
|
||||
|
||||
if ((info->fix.line_length * var->yres_virtual) > info->fix.smem_len) {
|
||||
pr_info("%s: Memory Limit requested yres_virtual = %u\n",
|
||||
__func__, var->yres_virtual);
|
||||
size = var->xres_virtual * var->yres_virtual * var->bits_per_pixel / 8;
|
||||
if (size > info->fix.smem_len) {
|
||||
dev_err(dev, "Memory limit exceeded, requested %dK\n",
|
||||
size >> 10);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int auok190xfb_set_fix(struct fb_info *info)
|
||||
{
|
||||
struct fb_fix_screeninfo *fix = &info->fix;
|
||||
struct fb_var_screeninfo *var = &info->var;
|
||||
|
||||
fix->line_length = var->xres_virtual * var->bits_per_pixel / 8;
|
||||
|
||||
fix->type = FB_TYPE_PACKED_PIXELS;
|
||||
fix->accel = FB_ACCEL_NONE;
|
||||
fix->visual = (var->grayscale) ? FB_VISUAL_STATIC_PSEUDOCOLOR
|
||||
: FB_VISUAL_TRUECOLOR;
|
||||
fix->xpanstep = 0;
|
||||
fix->ypanstep = 0;
|
||||
fix->ywrapstep = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int auok190xfb_set_par(struct fb_info *info)
|
||||
{
|
||||
struct auok190xfb_par *par = info->par;
|
||||
|
||||
par->rotation = info->var.rotate;
|
||||
auok190xfb_set_fix(info);
|
||||
|
||||
/* reinit the controller to honor the rotation */
|
||||
par->init(par);
|
||||
|
||||
/* wait for init to complete */
|
||||
par->board->wait_for_rdy(par);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct fb_ops auok190xfb_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.fb_read = fb_sys_read,
|
||||
|
@ -405,6 +570,7 @@ static struct fb_ops auok190xfb_ops = {
|
|||
.fb_copyarea = auok190xfb_copyarea,
|
||||
.fb_imageblit = auok190xfb_imageblit,
|
||||
.fb_check_var = auok190xfb_check_var,
|
||||
.fb_set_par = auok190xfb_set_par,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -588,10 +754,16 @@ static int auok190x_power(struct auok190xfb_par *par, bool on)
|
|||
|
||||
static void auok190x_recover(struct auok190xfb_par *par)
|
||||
{
|
||||
struct device *dev = par->info->device;
|
||||
|
||||
auok190x_power(par, 0);
|
||||
msleep(100);
|
||||
auok190x_power(par, 1);
|
||||
|
||||
/* after powercycling the device, it's always active */
|
||||
pm_runtime_set_active(dev);
|
||||
par->standby = 0;
|
||||
|
||||
par->init(par);
|
||||
|
||||
/* wait for init to complete */
|
||||
|
@ -875,42 +1047,17 @@ int auok190x_common_probe(struct platform_device *pdev,
|
|||
/* initialise fix, var, resolution and rotation */
|
||||
|
||||
strlcpy(info->fix.id, init->id, 16);
|
||||
info->fix.type = FB_TYPE_PACKED_PIXELS;
|
||||
info->fix.visual = FB_VISUAL_STATIC_PSEUDOCOLOR;
|
||||
info->fix.xpanstep = 0;
|
||||
info->fix.ypanstep = 0;
|
||||
info->fix.ywrapstep = 0;
|
||||
info->fix.accel = FB_ACCEL_NONE;
|
||||
|
||||
info->var.bits_per_pixel = 8;
|
||||
info->var.grayscale = 1;
|
||||
info->var.red.length = 8;
|
||||
info->var.green.length = 8;
|
||||
info->var.blue.length = 8;
|
||||
|
||||
panel = &panel_table[board->resolution];
|
||||
|
||||
/* if 90 degree rotation, switch width and height */
|
||||
if (board->rotation & 1) {
|
||||
info->var.xres = panel->h;
|
||||
info->var.yres = panel->w;
|
||||
info->var.xres_virtual = panel->h;
|
||||
info->var.yres_virtual = panel->w;
|
||||
info->fix.line_length = panel->h;
|
||||
} else {
|
||||
info->var.xres = panel->w;
|
||||
info->var.yres = panel->h;
|
||||
info->var.xres_virtual = panel->w;
|
||||
info->var.yres_virtual = panel->h;
|
||||
info->fix.line_length = panel->w;
|
||||
}
|
||||
|
||||
par->resolution = board->resolution;
|
||||
par->rotation = board->rotation;
|
||||
par->rotation = 0;
|
||||
|
||||
/* videomemory handling */
|
||||
|
||||
videomemorysize = roundup((panel->w * panel->h), PAGE_SIZE);
|
||||
videomemorysize = roundup((panel->w * panel->h) * 2, PAGE_SIZE);
|
||||
videomemory = vmalloc(videomemorysize);
|
||||
if (!videomemory) {
|
||||
ret = -ENOMEM;
|
||||
|
@ -924,6 +1071,12 @@ int auok190x_common_probe(struct platform_device *pdev,
|
|||
info->flags = FBINFO_FLAG_DEFAULT | FBINFO_VIRTFB;
|
||||
info->fbops = &auok190xfb_ops;
|
||||
|
||||
ret = auok190xfb_check_var(&info->var, info);
|
||||
if (ret)
|
||||
goto err_defio;
|
||||
|
||||
auok190xfb_set_fix(info);
|
||||
|
||||
/* deferred io init */
|
||||
|
||||
info->fbdefio = devm_kzalloc(info->device,
|
||||
|
|
|
@ -285,36 +285,26 @@ static int controlfb_pan_display(struct fb_var_screeninfo *var,
|
|||
static int controlfb_mmap(struct fb_info *info,
|
||||
struct vm_area_struct *vma)
|
||||
{
|
||||
unsigned long off, start;
|
||||
u32 len;
|
||||
unsigned long mmio_pgoff;
|
||||
unsigned long start;
|
||||
u32 len;
|
||||
|
||||
off = vma->vm_pgoff << PAGE_SHIFT;
|
||||
start = info->fix.smem_start;
|
||||
len = info->fix.smem_len;
|
||||
mmio_pgoff = PAGE_ALIGN((start & ~PAGE_MASK) + len) >> PAGE_SHIFT;
|
||||
if (vma->vm_pgoff >= mmio_pgoff) {
|
||||
if (info->var.accel_flags)
|
||||
return -EINVAL;
|
||||
vma->vm_pgoff -= mmio_pgoff;
|
||||
start = info->fix.mmio_start;
|
||||
len = info->fix.mmio_len;
|
||||
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
|
||||
} else {
|
||||
/* framebuffer */
|
||||
vma->vm_page_prot = pgprot_cached_wthru(vma->vm_page_prot);
|
||||
}
|
||||
|
||||
/* frame buffer memory */
|
||||
start = info->fix.smem_start;
|
||||
len = PAGE_ALIGN((start & ~PAGE_MASK)+info->fix.smem_len);
|
||||
if (off >= len) {
|
||||
/* memory mapped io */
|
||||
off -= len;
|
||||
if (info->var.accel_flags)
|
||||
return -EINVAL;
|
||||
start = info->fix.mmio_start;
|
||||
len = PAGE_ALIGN((start & ~PAGE_MASK)+info->fix.mmio_len);
|
||||
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
|
||||
} else {
|
||||
/* framebuffer */
|
||||
vma->vm_page_prot = pgprot_cached_wthru(vma->vm_page_prot);
|
||||
}
|
||||
start &= PAGE_MASK;
|
||||
if ((vma->vm_end - vma->vm_start + off) > len)
|
||||
return -EINVAL;
|
||||
off += start;
|
||||
vma->vm_pgoff = off >> PAGE_SHIFT;
|
||||
if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
|
||||
vma->vm_end - vma->vm_start, vma->vm_page_prot))
|
||||
return -EAGAIN;
|
||||
|
||||
return 0;
|
||||
return vm_iomap_memory(vma, start, len);
|
||||
}
|
||||
|
||||
static int controlfb_blank(int blank_mode, struct fb_info *info)
|
||||
|
|
|
@ -35,8 +35,6 @@
|
|||
|
||||
#include <video/exynos_mipi_dsim.h>
|
||||
|
||||
#include <plat/fb.h>
|
||||
|
||||
#include "exynos_mipi_dsi_common.h"
|
||||
#include "exynos_mipi_dsi_lowlevel.h"
|
||||
|
||||
|
|
|
@ -31,8 +31,6 @@
|
|||
#include <video/mipi_display.h>
|
||||
#include <video/exynos_mipi_dsim.h>
|
||||
|
||||
#include <mach/map.h>
|
||||
|
||||
#include "exynos_mipi_dsi_regs.h"
|
||||
#include "exynos_mipi_dsi_lowlevel.h"
|
||||
#include "exynos_mipi_dsi_common.h"
|
||||
|
|
|
@ -26,8 +26,6 @@
|
|||
|
||||
#include <video/exynos_mipi_dsim.h>
|
||||
|
||||
#include <mach/map.h>
|
||||
|
||||
#include "exynos_mipi_dsi_regs.h"
|
||||
|
||||
void exynos_mipi_dsi_func_reset(struct mipi_dsim_device *dsim)
|
||||
|
|
|
@ -640,21 +640,9 @@ static int unifb_pan_display(struct fb_var_screeninfo *var,
|
|||
int unifb_mmap(struct fb_info *info,
|
||||
struct vm_area_struct *vma)
|
||||
{
|
||||
unsigned long size = vma->vm_end - vma->vm_start;
|
||||
unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
|
||||
unsigned long pos = info->fix.smem_start + offset;
|
||||
|
||||
if (offset + size > info->fix.smem_len)
|
||||
return -EINVAL;
|
||||
|
||||
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
|
||||
|
||||
if (io_remap_pfn_range(vma, vma->vm_start, pos >> PAGE_SHIFT, size,
|
||||
vma->vm_page_prot))
|
||||
return -EAGAIN;
|
||||
|
||||
/* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by remap_pfn_range() */
|
||||
return 0;
|
||||
return vm_iomap_memory(vma, info->fix.smem_start, info->fix.smem_len);
|
||||
}
|
||||
|
||||
static struct fb_ops unifb_ops = {
|
||||
|
|
|
@ -1398,6 +1398,11 @@ fb_mmap(struct file *file, struct vm_area_struct * vma)
|
|||
len = info->fix.smem_len;
|
||||
mmio_pgoff = PAGE_ALIGN((start & ~PAGE_MASK) + len) >> PAGE_SHIFT;
|
||||
if (vma->vm_pgoff >= mmio_pgoff) {
|
||||
if (info->var.accel_flags) {
|
||||
mutex_unlock(&info->mm_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
vma->vm_pgoff -= mmio_pgoff;
|
||||
start = info->fix.mmio_start;
|
||||
len = info->fix.mmio_len;
|
||||
|
|
|
@ -1376,7 +1376,7 @@ int fb_get_mode(int flags, u32 val, struct fb_var_screeninfo *var, struct fb_inf
|
|||
return err;
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_VIDEOMODE)
|
||||
#ifdef CONFIG_VIDEOMODE_HELPERS
|
||||
int fb_videomode_from_videomode(const struct videomode *vm,
|
||||
struct fb_videomode *fbmode)
|
||||
{
|
||||
|
@ -1398,13 +1398,13 @@ int fb_videomode_from_videomode(const struct videomode *vm,
|
|||
|
||||
fbmode->sync = 0;
|
||||
fbmode->vmode = 0;
|
||||
if (vm->dmt_flags & VESA_DMT_HSYNC_HIGH)
|
||||
if (vm->flags & DISPLAY_FLAGS_HSYNC_HIGH)
|
||||
fbmode->sync |= FB_SYNC_HOR_HIGH_ACT;
|
||||
if (vm->dmt_flags & VESA_DMT_VSYNC_HIGH)
|
||||
if (vm->flags & DISPLAY_FLAGS_VSYNC_HIGH)
|
||||
fbmode->sync |= FB_SYNC_VERT_HIGH_ACT;
|
||||
if (vm->data_flags & DISPLAY_FLAGS_INTERLACED)
|
||||
if (vm->flags & DISPLAY_FLAGS_INTERLACED)
|
||||
fbmode->vmode |= FB_VMODE_INTERLACED;
|
||||
if (vm->data_flags & DISPLAY_FLAGS_DOUBLESCAN)
|
||||
if (vm->flags & DISPLAY_FLAGS_DOUBLESCAN)
|
||||
fbmode->vmode |= FB_VMODE_DOUBLE;
|
||||
fbmode->flag = 0;
|
||||
|
||||
|
@ -1424,9 +1424,8 @@ int fb_videomode_from_videomode(const struct videomode *vm,
|
|||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(fb_videomode_from_videomode);
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_OF_VIDEOMODE)
|
||||
#ifdef CONFIG_OF
|
||||
static inline void dump_fb_videomode(const struct fb_videomode *m)
|
||||
{
|
||||
pr_debug("fb_videomode = %ux%u@%uHz (%ukHz) %u %u %u %u %u %u %u %u %u\n",
|
||||
|
@ -1465,7 +1464,8 @@ int of_get_fb_videomode(struct device_node *np, struct fb_videomode *fb,
|
|||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_get_fb_videomode);
|
||||
#endif
|
||||
#endif /* CONFIG_OF */
|
||||
#endif /* CONFIG_VIDEOMODE_HELPERS */
|
||||
|
||||
#else
|
||||
int fb_parse_edid(unsigned char *edid, struct fb_var_screeninfo *var)
|
||||
|
|
|
@ -375,7 +375,10 @@ struct fsl_diu_data {
|
|||
struct diu_ad dummy_ad __aligned(8);
|
||||
struct diu_ad ad[NUM_AOIS] __aligned(8);
|
||||
u8 gamma[256 * 3] __aligned(32);
|
||||
u8 cursor[MAX_CURS * MAX_CURS * 2] __aligned(32);
|
||||
/* It's easier to parse the cursor data as little-endian */
|
||||
__le16 cursor[MAX_CURS * MAX_CURS] __aligned(32);
|
||||
/* Blank cursor data -- used to hide the cursor */
|
||||
__le16 blank_cursor[MAX_CURS * MAX_CURS] __aligned(32);
|
||||
uint8_t edid_data[EDID_LENGTH];
|
||||
bool has_edid;
|
||||
} __aligned(32);
|
||||
|
@ -824,7 +827,6 @@ static void update_lcdc(struct fb_info *info)
|
|||
/* Program DIU registers */
|
||||
|
||||
out_be32(&hw->gamma, DMA_ADDR(data, gamma));
|
||||
out_be32(&hw->cursor, DMA_ADDR(data, cursor));
|
||||
|
||||
out_be32(&hw->bgnd, 0x007F7F7F); /* Set background to grey */
|
||||
out_be32(&hw->disp_size, (var->yres << 16) | var->xres);
|
||||
|
@ -967,6 +969,156 @@ static u32 fsl_diu_get_pixel_format(unsigned int bits_per_pixel)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Copies a cursor image from user space to the proper place in driver
|
||||
* memory so that the hardware can display the cursor image.
|
||||
*
|
||||
* Cursor data is represented as a sequence of 'width' bits packed into bytes.
|
||||
* That is, the first 8 bits are in the first byte, the second 8 bits in the
|
||||
* second byte, and so on. Therefore, the each row of the cursor is (width +
|
||||
* 7) / 8 bytes of 'data'
|
||||
*
|
||||
* The DIU only supports cursors up to 32x32 (MAX_CURS). We reject cursors
|
||||
* larger than this, so we already know that 'width' <= 32. Therefore, we can
|
||||
* simplify our code by using a 32-bit big-endian integer ("line") to read in
|
||||
* a single line of pixels, and only look at the top 'width' bits of that
|
||||
* integer.
|
||||
*
|
||||
* This could result in an unaligned 32-bit read. For example, if the cursor
|
||||
* is 24x24, then the first three bytes of 'image' contain the pixel data for
|
||||
* the top line of the cursor. We do a 32-bit read of 'image', but we look
|
||||
* only at the top 24 bits. Then we increment 'image' by 3 bytes. The next
|
||||
* read is unaligned. The only problem is that we might read past the end of
|
||||
* 'image' by 1-3 bytes, but that should not cause any problems.
|
||||
*/
|
||||
static void fsl_diu_load_cursor_image(struct fb_info *info,
|
||||
const void *image, uint16_t bg, uint16_t fg,
|
||||
unsigned int width, unsigned int height)
|
||||
{
|
||||
struct mfb_info *mfbi = info->par;
|
||||
struct fsl_diu_data *data = mfbi->parent;
|
||||
__le16 *cursor = data->cursor;
|
||||
__le16 _fg = cpu_to_le16(fg);
|
||||
__le16 _bg = cpu_to_le16(bg);
|
||||
unsigned int h, w;
|
||||
|
||||
for (h = 0; h < height; h++) {
|
||||
uint32_t mask = 1 << 31;
|
||||
uint32_t line = be32_to_cpup(image);
|
||||
|
||||
for (w = 0; w < width; w++) {
|
||||
cursor[w] = (line & mask) ? _fg : _bg;
|
||||
mask >>= 1;
|
||||
}
|
||||
|
||||
cursor += MAX_CURS;
|
||||
image += DIV_ROUND_UP(width, 8);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Set a hardware cursor. The image data for the cursor is passed via the
|
||||
* fb_cursor object.
|
||||
*/
|
||||
static int fsl_diu_cursor(struct fb_info *info, struct fb_cursor *cursor)
|
||||
{
|
||||
struct mfb_info *mfbi = info->par;
|
||||
struct fsl_diu_data *data = mfbi->parent;
|
||||
struct diu __iomem *hw = data->diu_reg;
|
||||
|
||||
if (cursor->image.width > MAX_CURS || cursor->image.height > MAX_CURS)
|
||||
return -EINVAL;
|
||||
|
||||
/* The cursor size has changed */
|
||||
if (cursor->set & FB_CUR_SETSIZE) {
|
||||
/*
|
||||
* The DIU cursor is a fixed size, so when we get this
|
||||
* message, instead of resizing the cursor, we just clear
|
||||
* all the image data, in expectation of new data. However,
|
||||
* in tests this control does not appear to be normally
|
||||
* called.
|
||||
*/
|
||||
memset(data->cursor, 0, sizeof(data->cursor));
|
||||
}
|
||||
|
||||
/* The cursor position has changed (cursor->image.dx|dy) */
|
||||
if (cursor->set & FB_CUR_SETPOS) {
|
||||
uint32_t xx, yy;
|
||||
|
||||
yy = (cursor->image.dy - info->var.yoffset) & 0x7ff;
|
||||
xx = (cursor->image.dx - info->var.xoffset) & 0x7ff;
|
||||
|
||||
out_be32(&hw->curs_pos, yy << 16 | xx);
|
||||
}
|
||||
|
||||
/*
|
||||
* FB_CUR_SETIMAGE - the cursor image has changed
|
||||
* FB_CUR_SETCMAP - the cursor colors has changed
|
||||
* FB_CUR_SETSHAPE - the cursor bitmask has changed
|
||||
*/
|
||||
if (cursor->set & (FB_CUR_SETSHAPE | FB_CUR_SETCMAP | FB_CUR_SETIMAGE)) {
|
||||
unsigned int image_size =
|
||||
DIV_ROUND_UP(cursor->image.width, 8) * cursor->image.height;
|
||||
unsigned int image_words =
|
||||
DIV_ROUND_UP(image_size, sizeof(uint32_t));
|
||||
unsigned int bg_idx = cursor->image.bg_color;
|
||||
unsigned int fg_idx = cursor->image.fg_color;
|
||||
uint8_t buffer[image_size];
|
||||
uint32_t *image, *source, *mask;
|
||||
uint16_t fg, bg;
|
||||
unsigned int i;
|
||||
|
||||
if (info->state != FBINFO_STATE_RUNNING)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Determine the size of the cursor image data. Normally,
|
||||
* it's 8x16.
|
||||
*/
|
||||
image_size = DIV_ROUND_UP(cursor->image.width, 8) *
|
||||
cursor->image.height;
|
||||
|
||||
bg = ((info->cmap.red[bg_idx] & 0xf8) << 7) |
|
||||
((info->cmap.green[bg_idx] & 0xf8) << 2) |
|
||||
((info->cmap.blue[bg_idx] & 0xf8) >> 3) |
|
||||
1 << 15;
|
||||
|
||||
fg = ((info->cmap.red[fg_idx] & 0xf8) << 7) |
|
||||
((info->cmap.green[fg_idx] & 0xf8) << 2) |
|
||||
((info->cmap.blue[fg_idx] & 0xf8) >> 3) |
|
||||
1 << 15;
|
||||
|
||||
/* Use 32-bit operations on the data to improve performance */
|
||||
image = (uint32_t *)buffer;
|
||||
source = (uint32_t *)cursor->image.data;
|
||||
mask = (uint32_t *)cursor->mask;
|
||||
|
||||
if (cursor->rop == ROP_XOR)
|
||||
for (i = 0; i < image_words; i++)
|
||||
image[i] = source[i] ^ mask[i];
|
||||
else
|
||||
for (i = 0; i < image_words; i++)
|
||||
image[i] = source[i] & mask[i];
|
||||
|
||||
fsl_diu_load_cursor_image(info, image, bg, fg,
|
||||
cursor->image.width, cursor->image.height);
|
||||
};
|
||||
|
||||
/*
|
||||
* Show or hide the cursor. The cursor data is always stored in the
|
||||
* 'cursor' memory block, and the actual cursor position is always in
|
||||
* the DIU's CURS_POS register. To hide the cursor, we redirect the
|
||||
* CURSOR register to a blank cursor. The show the cursor, we
|
||||
* redirect the CURSOR register to the real cursor data.
|
||||
*/
|
||||
if (cursor->enable)
|
||||
out_be32(&hw->cursor, DMA_ADDR(data, cursor));
|
||||
else
|
||||
out_be32(&hw->cursor, DMA_ADDR(data, blank_cursor));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Using the fb_var_screeninfo in fb_info we set the resolution of this
|
||||
* particular framebuffer. This function alters the fb_fix_screeninfo stored
|
||||
|
@ -1312,6 +1464,7 @@ static struct fb_ops fsl_diu_ops = {
|
|||
.fb_ioctl = fsl_diu_ioctl,
|
||||
.fb_open = fsl_diu_open,
|
||||
.fb_release = fsl_diu_release,
|
||||
.fb_cursor = fsl_diu_cursor,
|
||||
};
|
||||
|
||||
static int install_fb(struct fb_info *info)
|
||||
|
|
|
@ -1016,7 +1016,9 @@ static int gbefb_mmap(struct fb_info *info,
|
|||
/* check range */
|
||||
if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
|
||||
return -EINVAL;
|
||||
if (offset + size > gbe_mem_size)
|
||||
if (size > gbe_mem_size)
|
||||
return -EINVAL;
|
||||
if (offset > gbe_mem_size - size)
|
||||
return -EINVAL;
|
||||
|
||||
/* remap using the fastest write-through mode on architecture */
|
||||
|
|
|
@ -79,25 +79,24 @@ static struct display_timing *of_get_display_timing(struct device_node *np)
|
|||
ret |= parse_timing_property(np, "vsync-len", &dt->vsync_len);
|
||||
ret |= parse_timing_property(np, "clock-frequency", &dt->pixelclock);
|
||||
|
||||
dt->dmt_flags = 0;
|
||||
dt->data_flags = 0;
|
||||
dt->flags = 0;
|
||||
if (!of_property_read_u32(np, "vsync-active", &val))
|
||||
dt->dmt_flags |= val ? VESA_DMT_VSYNC_HIGH :
|
||||
VESA_DMT_VSYNC_LOW;
|
||||
dt->flags |= val ? DISPLAY_FLAGS_VSYNC_HIGH :
|
||||
DISPLAY_FLAGS_VSYNC_LOW;
|
||||
if (!of_property_read_u32(np, "hsync-active", &val))
|
||||
dt->dmt_flags |= val ? VESA_DMT_HSYNC_HIGH :
|
||||
VESA_DMT_HSYNC_LOW;
|
||||
dt->flags |= val ? DISPLAY_FLAGS_HSYNC_HIGH :
|
||||
DISPLAY_FLAGS_HSYNC_LOW;
|
||||
if (!of_property_read_u32(np, "de-active", &val))
|
||||
dt->data_flags |= val ? DISPLAY_FLAGS_DE_HIGH :
|
||||
dt->flags |= val ? DISPLAY_FLAGS_DE_HIGH :
|
||||
DISPLAY_FLAGS_DE_LOW;
|
||||
if (!of_property_read_u32(np, "pixelclk-active", &val))
|
||||
dt->data_flags |= val ? DISPLAY_FLAGS_PIXDATA_POSEDGE :
|
||||
dt->flags |= val ? DISPLAY_FLAGS_PIXDATA_POSEDGE :
|
||||
DISPLAY_FLAGS_PIXDATA_NEGEDGE;
|
||||
|
||||
if (of_property_read_bool(np, "interlaced"))
|
||||
dt->data_flags |= DISPLAY_FLAGS_INTERLACED;
|
||||
dt->flags |= DISPLAY_FLAGS_INTERLACED;
|
||||
if (of_property_read_bool(np, "doublescan"))
|
||||
dt->data_flags |= DISPLAY_FLAGS_DOUBLESCAN;
|
||||
dt->flags |= DISPLAY_FLAGS_DOUBLESCAN;
|
||||
|
||||
if (ret) {
|
||||
pr_err("%s: error reading timing properties\n",
|
||||
|
|
|
@ -43,7 +43,7 @@ int of_get_videomode(struct device_node *np, struct videomode *vm,
|
|||
if (index == OF_USE_NATIVE_MODE)
|
||||
index = disp->native_mode;
|
||||
|
||||
ret = videomode_from_timing(disp, vm, index);
|
||||
ret = videomode_from_timings(disp, vm, index);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
@ -39,17 +39,6 @@ config FB_OMAP_LCD_MIPID
|
|||
the Mobile Industry Processor Interface DBI-C/DCS
|
||||
specification. (Supported LCDs: Philips LPH8923, Sharp LS041Y3)
|
||||
|
||||
config FB_OMAP_CONSISTENT_DMA_SIZE
|
||||
int "Consistent DMA memory size (MB)"
|
||||
depends on FB_OMAP
|
||||
range 1 14
|
||||
default 2
|
||||
help
|
||||
Increase the DMA consistent memory size according to your video
|
||||
memory needs, for example if you want to use multiple planes.
|
||||
The size must be 2MB aligned.
|
||||
If unsure say 1.
|
||||
|
||||
config FB_OMAP_DMA_TUNE
|
||||
bool "Set DMA SDRAM access priority high"
|
||||
depends on FB_OMAP
|
||||
|
|
|
@ -1101,41 +1101,25 @@ static int omapfb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
|
|||
struct omapfb_info *ofbi = FB2OFB(fbi);
|
||||
struct fb_fix_screeninfo *fix = &fbi->fix;
|
||||
struct omapfb2_mem_region *rg;
|
||||
unsigned long off;
|
||||
unsigned long start;
|
||||
u32 len;
|
||||
int r = -EINVAL;
|
||||
|
||||
if (vma->vm_end - vma->vm_start == 0)
|
||||
return 0;
|
||||
if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
|
||||
return -EINVAL;
|
||||
off = vma->vm_pgoff << PAGE_SHIFT;
|
||||
int r;
|
||||
|
||||
rg = omapfb_get_mem_region(ofbi->region);
|
||||
|
||||
start = omapfb_get_region_paddr(ofbi);
|
||||
len = fix->smem_len;
|
||||
if (off >= len)
|
||||
goto error;
|
||||
if ((vma->vm_end - vma->vm_start + off) > len)
|
||||
goto error;
|
||||
|
||||
off += start;
|
||||
DBG("user mmap region start %lx, len %d, off %lx\n", start, len,
|
||||
vma->vm_pgoff << PAGE_SHIFT);
|
||||
|
||||
DBG("user mmap region start %lx, len %d, off %lx\n", start, len, off);
|
||||
|
||||
vma->vm_pgoff = off >> PAGE_SHIFT;
|
||||
/* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by remap_pfn_range() */
|
||||
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
|
||||
vma->vm_ops = &mmap_user_ops;
|
||||
vma->vm_private_data = rg;
|
||||
if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
|
||||
vma->vm_end - vma->vm_start,
|
||||
vma->vm_page_prot)) {
|
||||
r = -EAGAIN;
|
||||
|
||||
r = vm_iomap_memory(vma, start, len);
|
||||
if (r)
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* vm_ops.open won't be called for mmap itself. */
|
||||
atomic_inc(&rg->map_count);
|
||||
|
@ -1144,7 +1128,7 @@ static int omapfb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
|
|||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
error:
|
||||
omapfb_put_mem_region(ofbi->region);
|
||||
|
||||
return r;
|
||||
|
|
|
@ -397,18 +397,7 @@ static struct platform_driver vrfb_driver = {
|
|||
.remove = __exit_p(vrfb_remove),
|
||||
};
|
||||
|
||||
static int __init vrfb_init(void)
|
||||
{
|
||||
return platform_driver_probe(&vrfb_driver, &vrfb_probe);
|
||||
}
|
||||
|
||||
static void __exit vrfb_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&vrfb_driver);
|
||||
}
|
||||
|
||||
module_init(vrfb_init);
|
||||
module_exit(vrfb_exit);
|
||||
module_platform_driver_probe(vrfb_driver, vrfb_probe);
|
||||
|
||||
MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@ti.com>");
|
||||
MODULE_DESCRIPTION("OMAP VRFB");
|
||||
|
|
|
@ -705,21 +705,15 @@ static int ps3fb_pan_display(struct fb_var_screeninfo *var,
|
|||
|
||||
static int ps3fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
|
||||
{
|
||||
unsigned long size, offset;
|
||||
int r;
|
||||
|
||||
size = vma->vm_end - vma->vm_start;
|
||||
offset = vma->vm_pgoff << PAGE_SHIFT;
|
||||
if (offset + size > info->fix.smem_len)
|
||||
return -EINVAL;
|
||||
|
||||
offset += info->fix.smem_start;
|
||||
if (remap_pfn_range(vma, vma->vm_start, offset >> PAGE_SHIFT,
|
||||
size, vma->vm_page_prot))
|
||||
return -EAGAIN;
|
||||
r = vm_iomap_memory(vma, info->fix.smem_start, info->fix.smem_len);
|
||||
|
||||
dev_dbg(info->device, "ps3fb: mmap framebuffer P(%lx)->V(%lx)\n",
|
||||
offset, vma->vm_start);
|
||||
return 0;
|
||||
info->fix.smem_start + vma->vm_pgoff << PAGE_SHIFT,
|
||||
vma->vm_start);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -24,10 +24,9 @@
|
|||
#include <linux/uaccess.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/platform_data/video_s3c.h>
|
||||
|
||||
#include <video/samsung_fimd.h>
|
||||
#include <mach/map.h>
|
||||
#include <plat/fb.h>
|
||||
|
||||
/* This driver will export a number of framebuffer interfaces depending
|
||||
* on the configuration passed in via the platform data. Each fb instance
|
||||
|
|
|
@ -556,7 +556,7 @@ static int sa1100fb_mmap(struct fb_info *info,
|
|||
struct vm_area_struct *vma)
|
||||
{
|
||||
struct sa1100fb_info *fbi = (struct sa1100fb_info *)info;
|
||||
unsigned long start, len, off = vma->vm_pgoff << PAGE_SHIFT;
|
||||
unsigned long off = vma->vm_pgoff << PAGE_SHIFT;
|
||||
|
||||
if (off < info->fix.smem_len) {
|
||||
vma->vm_pgoff += 1; /* skip over the palette */
|
||||
|
@ -564,19 +564,9 @@ static int sa1100fb_mmap(struct fb_info *info,
|
|||
fbi->map_dma, fbi->map_size);
|
||||
}
|
||||
|
||||
start = info->fix.mmio_start;
|
||||
len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.mmio_len);
|
||||
|
||||
if ((vma->vm_end - vma->vm_start + off) > len)
|
||||
return -EINVAL;
|
||||
|
||||
off += start & PAGE_MASK;
|
||||
vma->vm_pgoff = off >> PAGE_SHIFT;
|
||||
vma->vm_flags |= VM_IO;
|
||||
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
|
||||
return io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
|
||||
vma->vm_end - vma->vm_start,
|
||||
vma->vm_page_prot);
|
||||
|
||||
return vm_iomap_memory(vma, info->fix.mmio_start, info->fix.mmio_len);
|
||||
}
|
||||
|
||||
static struct fb_ops sa1100fb_ops = {
|
||||
|
|
|
@ -705,23 +705,17 @@ static int sgivwfb_setcolreg(u_int regno, u_int red, u_int green,
|
|||
static int sgivwfb_mmap(struct fb_info *info,
|
||||
struct vm_area_struct *vma)
|
||||
{
|
||||
unsigned long size = vma->vm_end - vma->vm_start;
|
||||
unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
|
||||
int r;
|
||||
|
||||
if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
|
||||
return -EINVAL;
|
||||
if (offset + size > sgivwfb_mem_size)
|
||||
return -EINVAL;
|
||||
offset += sgivwfb_mem_phys;
|
||||
pgprot_val(vma->vm_page_prot) =
|
||||
pgprot_val(vma->vm_page_prot) | _PAGE_PCD;
|
||||
vma->vm_flags |= VM_IO;
|
||||
if (remap_pfn_range(vma, vma->vm_start, offset >> PAGE_SHIFT,
|
||||
size, vma->vm_page_prot))
|
||||
return -EAGAIN;
|
||||
pgprot_val(vma->vm_page_prot) | _PAGE_PCD;
|
||||
|
||||
r = vm_iomap_memory(vma, sgivwfb_mem_phys, sgivwfb_mem_size);
|
||||
|
||||
printk(KERN_DEBUG "sgivwfb: mmap framebuffer P(%lx)->V(%lx)\n",
|
||||
offset, vma->vm_start);
|
||||
return 0;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int __init sgivwfb_setup(char *options)
|
||||
|
|
|
@ -581,17 +581,7 @@ static struct platform_driver sh_mipi_driver = {
|
|||
},
|
||||
};
|
||||
|
||||
static int __init sh_mipi_init(void)
|
||||
{
|
||||
return platform_driver_probe(&sh_mipi_driver, sh_mipi_probe);
|
||||
}
|
||||
module_init(sh_mipi_init);
|
||||
|
||||
static void __exit sh_mipi_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&sh_mipi_driver);
|
||||
}
|
||||
module_exit(sh_mipi_exit);
|
||||
module_platform_driver_probe(sh_mipi_driver, sh_mipi_probe);
|
||||
|
||||
MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
|
||||
MODULE_DESCRIPTION("SuperH / ARM-shmobile MIPI DSI driver");
|
||||
|
|
|
@ -1445,17 +1445,7 @@ static struct platform_driver sh_hdmi_driver = {
|
|||
},
|
||||
};
|
||||
|
||||
static int __init sh_hdmi_init(void)
|
||||
{
|
||||
return platform_driver_probe(&sh_hdmi_driver, sh_hdmi_probe);
|
||||
}
|
||||
module_init(sh_hdmi_init);
|
||||
|
||||
static void __exit sh_hdmi_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&sh_hdmi_driver);
|
||||
}
|
||||
module_exit(sh_hdmi_exit);
|
||||
module_platform_driver_probe(sh_hdmi_driver, sh_hdmi_probe);
|
||||
|
||||
MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
|
||||
MODULE_DESCRIPTION("SuperH / ARM-shmobile HDMI driver");
|
||||
|
|
|
@ -782,7 +782,11 @@ static int ufx_ops_mmap(struct fb_info *info, struct vm_area_struct *vma)
|
|||
unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
|
||||
unsigned long page, pos;
|
||||
|
||||
if (offset + size > info->fix.smem_len)
|
||||
if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
|
||||
return -EINVAL;
|
||||
if (size > info->fix.smem_len)
|
||||
return -EINVAL;
|
||||
if (offset > info->fix.smem_len - size)
|
||||
return -EINVAL;
|
||||
|
||||
pos = (unsigned long)info->fix.smem_start + offset;
|
||||
|
|
|
@ -324,7 +324,11 @@ static int dlfb_ops_mmap(struct fb_info *info, struct vm_area_struct *vma)
|
|||
unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
|
||||
unsigned long page, pos;
|
||||
|
||||
if (offset + size > info->fix.smem_len)
|
||||
if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
|
||||
return -EINVAL;
|
||||
if (size > info->fix.smem_len)
|
||||
return -EINVAL;
|
||||
if (offset > info->fix.smem_len - size)
|
||||
return -EINVAL;
|
||||
|
||||
pos = (unsigned long)info->fix.smem_start + offset;
|
||||
|
|
|
@ -1003,24 +1003,18 @@ static int vmlfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
|
|||
static int vmlfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
|
||||
{
|
||||
struct vml_info *vinfo = container_of(info, struct vml_info, info);
|
||||
unsigned long size = vma->vm_end - vma->vm_start;
|
||||
unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
|
||||
int ret;
|
||||
|
||||
if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
|
||||
return -EINVAL;
|
||||
if (offset + size > vinfo->vram_contig_size)
|
||||
return -EINVAL;
|
||||
ret = vmlfb_vram_offset(vinfo, offset);
|
||||
if (ret)
|
||||
return -EINVAL;
|
||||
offset += vinfo->vram_start;
|
||||
|
||||
pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
|
||||
pgprot_val(vma->vm_page_prot) &= ~_PAGE_PWT;
|
||||
if (remap_pfn_range(vma, vma->vm_start, offset >> PAGE_SHIFT,
|
||||
size, vma->vm_page_prot))
|
||||
return -EAGAIN;
|
||||
return 0;
|
||||
|
||||
return vm_iomap_memory(vma, vinfo->vram_start,
|
||||
vinfo->vram_contig_size);
|
||||
}
|
||||
|
||||
static int vmlfb_sync(struct fb_info *info)
|
||||
|
|
|
@ -420,9 +420,12 @@ static int vfb_mmap(struct fb_info *info,
|
|||
unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
|
||||
unsigned long page, pos;
|
||||
|
||||
if (offset + size > info->fix.smem_len) {
|
||||
if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
|
||||
return -EINVAL;
|
||||
if (size > info->fix.smem_len)
|
||||
return -EINVAL;
|
||||
if (offset > info->fix.smem_len - size)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pos = (unsigned long)info->fix.smem_start + offset;
|
||||
|
||||
|
|
|
@ -11,7 +11,25 @@
|
|||
#include <video/display_timing.h>
|
||||
#include <video/videomode.h>
|
||||
|
||||
int videomode_from_timing(const struct display_timings *disp,
|
||||
void videomode_from_timing(const struct display_timing *dt,
|
||||
struct videomode *vm)
|
||||
{
|
||||
vm->pixelclock = dt->pixelclock.typ;
|
||||
vm->hactive = dt->hactive.typ;
|
||||
vm->hfront_porch = dt->hfront_porch.typ;
|
||||
vm->hback_porch = dt->hback_porch.typ;
|
||||
vm->hsync_len = dt->hsync_len.typ;
|
||||
|
||||
vm->vactive = dt->vactive.typ;
|
||||
vm->vfront_porch = dt->vfront_porch.typ;
|
||||
vm->vback_porch = dt->vback_porch.typ;
|
||||
vm->vsync_len = dt->vsync_len.typ;
|
||||
|
||||
vm->flags = dt->flags;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(videomode_from_timing);
|
||||
|
||||
int videomode_from_timings(const struct display_timings *disp,
|
||||
struct videomode *vm, unsigned int index)
|
||||
{
|
||||
struct display_timing *dt;
|
||||
|
@ -20,20 +38,8 @@ int videomode_from_timing(const struct display_timings *disp,
|
|||
if (!dt)
|
||||
return -EINVAL;
|
||||
|
||||
vm->pixelclock = display_timing_get_value(&dt->pixelclock, TE_TYP);
|
||||
vm->hactive = display_timing_get_value(&dt->hactive, TE_TYP);
|
||||
vm->hfront_porch = display_timing_get_value(&dt->hfront_porch, TE_TYP);
|
||||
vm->hback_porch = display_timing_get_value(&dt->hback_porch, TE_TYP);
|
||||
vm->hsync_len = display_timing_get_value(&dt->hsync_len, TE_TYP);
|
||||
|
||||
vm->vactive = display_timing_get_value(&dt->vactive, TE_TYP);
|
||||
vm->vfront_porch = display_timing_get_value(&dt->vfront_porch, TE_TYP);
|
||||
vm->vback_porch = display_timing_get_value(&dt->vback_porch, TE_TYP);
|
||||
vm->vsync_len = display_timing_get_value(&dt->vsync_len, TE_TYP);
|
||||
|
||||
vm->dmt_flags = dt->dmt_flags;
|
||||
vm->data_flags = dt->data_flags;
|
||||
videomode_from_timing(dt, vm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(videomode_from_timing);
|
||||
EXPORT_SYMBOL_GPL(videomode_from_timings);
|
||||
|
|
|
@ -15,22 +15,21 @@
|
|||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/fb.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/wait.h>
|
||||
|
||||
#include <linux/platform_data/video-vt8500lcdfb.h>
|
||||
#include <video/of_display_timing.h>
|
||||
|
||||
#include "vt8500lcdfb.h"
|
||||
#include "wmt_ge_rops.h"
|
||||
|
@ -277,11 +276,11 @@ static int vt8500lcd_probe(struct platform_device *pdev)
|
|||
{
|
||||
struct vt8500lcd_info *fbi;
|
||||
struct resource *res;
|
||||
struct display_timings *disp_timing;
|
||||
void *addr;
|
||||
int irq, ret;
|
||||
|
||||
struct fb_videomode of_mode;
|
||||
struct device_node *np;
|
||||
u32 bpp;
|
||||
dma_addr_t fb_mem_phys;
|
||||
unsigned long fb_mem_len;
|
||||
|
@ -346,32 +345,18 @@ static int vt8500lcd_probe(struct platform_device *pdev)
|
|||
goto failed_free_res;
|
||||
}
|
||||
|
||||
np = of_parse_phandle(pdev->dev.of_node, "default-mode", 0);
|
||||
if (!np) {
|
||||
pr_err("%s: No display description in Device Tree\n", __func__);
|
||||
ret = -EINVAL;
|
||||
goto failed_free_res;
|
||||
}
|
||||
disp_timing = of_get_display_timings(pdev->dev.of_node);
|
||||
if (!disp_timing)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* This code is copied from Sascha Hauer's of_videomode helper
|
||||
* and can be replaced with a call to the helper once mainlined
|
||||
*/
|
||||
ret = 0;
|
||||
ret |= of_property_read_u32(np, "hactive", &of_mode.xres);
|
||||
ret |= of_property_read_u32(np, "vactive", &of_mode.yres);
|
||||
ret |= of_property_read_u32(np, "hback-porch", &of_mode.left_margin);
|
||||
ret |= of_property_read_u32(np, "hfront-porch", &of_mode.right_margin);
|
||||
ret |= of_property_read_u32(np, "hsync-len", &of_mode.hsync_len);
|
||||
ret |= of_property_read_u32(np, "vback-porch", &of_mode.upper_margin);
|
||||
ret |= of_property_read_u32(np, "vfront-porch", &of_mode.lower_margin);
|
||||
ret |= of_property_read_u32(np, "vsync-len", &of_mode.vsync_len);
|
||||
ret |= of_property_read_u32(np, "bpp", &bpp);
|
||||
if (ret) {
|
||||
pr_err("%s: Unable to read display properties\n", __func__);
|
||||
goto failed_free_res;
|
||||
}
|
||||
of_mode.vmode = FB_VMODE_NONINTERLACED;
|
||||
ret = of_get_fb_videomode(pdev->dev.of_node, &of_mode,
|
||||
OF_USE_NATIVE_MODE);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = of_property_read_u32(pdev->dev.of_node, "bits-per-pixel", &bpp);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* try allocating the framebuffer */
|
||||
fb_mem_len = of_mode.xres * of_mode.yres * 2 * (bpp / 8);
|
||||
|
|
|
@ -14,25 +14,25 @@
|
|||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/fb.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/memblock.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_fdt.h>
|
||||
#include <linux/memblock.h>
|
||||
|
||||
#include <linux/platform_data/video-vt8500lcdfb.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/wait.h>
|
||||
#include <video/of_display_timing.h>
|
||||
|
||||
#include "wm8505fb_regs.h"
|
||||
#include "wmt_ge_rops.h"
|
||||
|
@ -263,26 +263,22 @@ static struct fb_ops wm8505fb_ops = {
|
|||
static int wm8505fb_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct wm8505fb_info *fbi;
|
||||
struct resource *res;
|
||||
struct resource *res;
|
||||
struct display_timings *disp_timing;
|
||||
void *addr;
|
||||
int ret;
|
||||
|
||||
struct fb_videomode of_mode;
|
||||
struct device_node *np;
|
||||
struct fb_videomode mode;
|
||||
u32 bpp;
|
||||
dma_addr_t fb_mem_phys;
|
||||
unsigned long fb_mem_len;
|
||||
void *fb_mem_virt;
|
||||
|
||||
ret = -ENOMEM;
|
||||
fbi = NULL;
|
||||
|
||||
fbi = devm_kzalloc(&pdev->dev, sizeof(struct wm8505fb_info) +
|
||||
sizeof(u32) * 16, GFP_KERNEL);
|
||||
if (!fbi) {
|
||||
dev_err(&pdev->dev, "Failed to initialize framebuffer device\n");
|
||||
ret = -ENOMEM;
|
||||
goto failed;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
strcpy(fbi->fb.fix.id, DRIVER_NAME);
|
||||
|
@ -308,54 +304,23 @@ static int wm8505fb_probe(struct platform_device *pdev)
|
|||
fbi->fb.pseudo_palette = addr;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (res == NULL) {
|
||||
dev_err(&pdev->dev, "no I/O memory resource defined\n");
|
||||
ret = -ENODEV;
|
||||
goto failed_fbi;
|
||||
}
|
||||
fbi->regbase = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (IS_ERR(fbi->regbase))
|
||||
return PTR_ERR(fbi->regbase);
|
||||
|
||||
res = request_mem_region(res->start, resource_size(res), DRIVER_NAME);
|
||||
if (res == NULL) {
|
||||
dev_err(&pdev->dev, "failed to request I/O memory\n");
|
||||
ret = -EBUSY;
|
||||
goto failed_fbi;
|
||||
}
|
||||
disp_timing = of_get_display_timings(pdev->dev.of_node);
|
||||
if (!disp_timing)
|
||||
return -EINVAL;
|
||||
|
||||
fbi->regbase = ioremap(res->start, resource_size(res));
|
||||
if (fbi->regbase == NULL) {
|
||||
dev_err(&pdev->dev, "failed to map I/O memory\n");
|
||||
ret = -EBUSY;
|
||||
goto failed_free_res;
|
||||
}
|
||||
ret = of_get_fb_videomode(pdev->dev.of_node, &mode, OF_USE_NATIVE_MODE);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
np = of_parse_phandle(pdev->dev.of_node, "default-mode", 0);
|
||||
if (!np) {
|
||||
pr_err("%s: No display description in Device Tree\n", __func__);
|
||||
ret = -EINVAL;
|
||||
goto failed_free_res;
|
||||
}
|
||||
ret = of_property_read_u32(pdev->dev.of_node, "bits-per-pixel", &bpp);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* This code is copied from Sascha Hauer's of_videomode helper
|
||||
* and can be replaced with a call to the helper once mainlined
|
||||
*/
|
||||
ret = 0;
|
||||
ret |= of_property_read_u32(np, "hactive", &of_mode.xres);
|
||||
ret |= of_property_read_u32(np, "vactive", &of_mode.yres);
|
||||
ret |= of_property_read_u32(np, "hback-porch", &of_mode.left_margin);
|
||||
ret |= of_property_read_u32(np, "hfront-porch", &of_mode.right_margin);
|
||||
ret |= of_property_read_u32(np, "hsync-len", &of_mode.hsync_len);
|
||||
ret |= of_property_read_u32(np, "vback-porch", &of_mode.upper_margin);
|
||||
ret |= of_property_read_u32(np, "vfront-porch", &of_mode.lower_margin);
|
||||
ret |= of_property_read_u32(np, "vsync-len", &of_mode.vsync_len);
|
||||
ret |= of_property_read_u32(np, "bpp", &bpp);
|
||||
if (ret) {
|
||||
pr_err("%s: Unable to read display properties\n", __func__);
|
||||
goto failed_free_res;
|
||||
}
|
||||
|
||||
of_mode.vmode = FB_VMODE_NONINTERLACED;
|
||||
fb_videomode_to_var(&fbi->fb.var, &of_mode);
|
||||
fb_videomode_to_var(&fbi->fb.var, &mode);
|
||||
|
||||
fbi->fb.var.nonstd = 0;
|
||||
fbi->fb.var.activate = FB_ACTIVATE_NOW;
|
||||
|
@ -364,16 +329,16 @@ static int wm8505fb_probe(struct platform_device *pdev)
|
|||
fbi->fb.var.width = -1;
|
||||
|
||||
/* try allocating the framebuffer */
|
||||
fb_mem_len = of_mode.xres * of_mode.yres * 2 * (bpp / 8);
|
||||
fb_mem_virt = dma_alloc_coherent(&pdev->dev, fb_mem_len, &fb_mem_phys,
|
||||
fb_mem_len = mode.xres * mode.yres * 2 * (bpp / 8);
|
||||
fb_mem_virt = dmam_alloc_coherent(&pdev->dev, fb_mem_len, &fb_mem_phys,
|
||||
GFP_KERNEL);
|
||||
if (!fb_mem_virt) {
|
||||
pr_err("%s: Failed to allocate framebuffer\n", __func__);
|
||||
return -ENOMEM;
|
||||
};
|
||||
}
|
||||
|
||||
fbi->fb.var.xres_virtual = of_mode.xres;
|
||||
fbi->fb.var.yres_virtual = of_mode.yres * 2;
|
||||
fbi->fb.var.xres_virtual = mode.xres;
|
||||
fbi->fb.var.yres_virtual = mode.yres * 2;
|
||||
fbi->fb.var.bits_per_pixel = bpp;
|
||||
|
||||
fbi->fb.fix.smem_start = fb_mem_phys;
|
||||
|
@ -381,28 +346,29 @@ static int wm8505fb_probe(struct platform_device *pdev)
|
|||
fbi->fb.screen_base = fb_mem_virt;
|
||||
fbi->fb.screen_size = fb_mem_len;
|
||||
|
||||
if (fb_alloc_cmap(&fbi->fb.cmap, 256, 0) < 0) {
|
||||
dev_err(&pdev->dev, "Failed to allocate color map\n");
|
||||
ret = -ENOMEM;
|
||||
goto failed_free_io;
|
||||
}
|
||||
|
||||
wm8505fb_init_hw(&fbi->fb);
|
||||
|
||||
fbi->contrast = 0x80;
|
||||
fbi->contrast = 0x10;
|
||||
ret = wm8505fb_set_par(&fbi->fb);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Failed to set parameters\n");
|
||||
goto failed_free_cmap;
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (fb_alloc_cmap(&fbi->fb.cmap, 256, 0) < 0) {
|
||||
dev_err(&pdev->dev, "Failed to allocate color map\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
wm8505fb_init_hw(&fbi->fb);
|
||||
|
||||
platform_set_drvdata(pdev, fbi);
|
||||
|
||||
ret = register_framebuffer(&fbi->fb);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev,
|
||||
"Failed to register framebuffer device: %d\n", ret);
|
||||
goto failed_free_cmap;
|
||||
if (fbi->fb.cmap.len)
|
||||
fb_dealloc_cmap(&fbi->fb.cmap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = device_create_file(&pdev->dev, &dev_attr_contrast);
|
||||
|
@ -416,25 +382,11 @@ static int wm8505fb_probe(struct platform_device *pdev)
|
|||
fbi->fb.fix.smem_start + fbi->fb.fix.smem_len - 1);
|
||||
|
||||
return 0;
|
||||
|
||||
failed_free_cmap:
|
||||
if (fbi->fb.cmap.len)
|
||||
fb_dealloc_cmap(&fbi->fb.cmap);
|
||||
failed_free_io:
|
||||
iounmap(fbi->regbase);
|
||||
failed_free_res:
|
||||
release_mem_region(res->start, resource_size(res));
|
||||
failed_fbi:
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
kfree(fbi);
|
||||
failed:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int wm8505fb_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct wm8505fb_info *fbi = platform_get_drvdata(pdev);
|
||||
struct resource *res;
|
||||
|
||||
device_remove_file(&pdev->dev, &dev_attr_contrast);
|
||||
|
||||
|
@ -445,13 +397,6 @@ static int wm8505fb_remove(struct platform_device *pdev)
|
|||
if (fbi->fb.cmap.len)
|
||||
fb_dealloc_cmap(&fbi->fb.cmap);
|
||||
|
||||
iounmap(fbi->regbase);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
release_mem_region(res->start, resource_size(res));
|
||||
|
||||
kfree(fbi);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,28 @@
|
|||
#ifdef CONFIG_FB_WMT_GE_ROPS
|
||||
|
||||
extern void wmt_ge_fillrect(struct fb_info *info,
|
||||
const struct fb_fillrect *rect);
|
||||
extern void wmt_ge_copyarea(struct fb_info *info,
|
||||
const struct fb_copyarea *area);
|
||||
extern int wmt_ge_sync(struct fb_info *info);
|
||||
|
||||
#else
|
||||
|
||||
static inline int wmt_ge_sync(struct fb_info *p)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void wmt_ge_fillrect(struct fb_info *p,
|
||||
const struct fb_fillrect *rect)
|
||||
{
|
||||
sys_fillrect(p, rect);
|
||||
}
|
||||
|
||||
static inline void wmt_ge_copyarea(struct fb_info *p,
|
||||
const struct fb_copyarea *area)
|
||||
{
|
||||
sys_copyarea(p, area);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
/*
|
||||
* VT8500/WM8505 Frame Buffer platform data definitions
|
||||
*
|
||||
* Copyright (C) 2010 Ed Spiridonov <edo.rus@gmail.com>
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _VT8500FB_H
|
||||
#define _VT8500FB_H
|
||||
|
||||
#include <linux/fb.h>
|
||||
|
||||
struct vt8500fb_platform_data {
|
||||
struct fb_videomode mode;
|
||||
u32 xres_virtual;
|
||||
u32 yres_virtual;
|
||||
u32 bpp;
|
||||
unsigned long video_mem_phys;
|
||||
void *video_mem_virt;
|
||||
unsigned long video_mem_len;
|
||||
};
|
||||
|
||||
#endif /* _VT8500FB_H */
|
|
@ -0,0 +1,54 @@
|
|||
#ifndef __PLATFORM_DATA_VIDEO_S3C
|
||||
#define __PLATFORM_DATA_VIDEO_S3C
|
||||
|
||||
/* S3C_FB_MAX_WIN
|
||||
* Set to the maximum number of windows that any of the supported hardware
|
||||
* can use. Since the platform data uses this for an array size, having it
|
||||
* set to the maximum of any version of the hardware can do is safe.
|
||||
*/
|
||||
#define S3C_FB_MAX_WIN (5)
|
||||
|
||||
/**
|
||||
* struct s3c_fb_pd_win - per window setup data
|
||||
* @xres : The window X size.
|
||||
* @yres : The window Y size.
|
||||
* @virtual_x: The virtual X size.
|
||||
* @virtual_y: The virtual Y size.
|
||||
*/
|
||||
struct s3c_fb_pd_win {
|
||||
unsigned short default_bpp;
|
||||
unsigned short max_bpp;
|
||||
unsigned short xres;
|
||||
unsigned short yres;
|
||||
unsigned short virtual_x;
|
||||
unsigned short virtual_y;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct s3c_fb_platdata - S3C driver platform specific information
|
||||
* @setup_gpio: Setup the external GPIO pins to the right state to transfer
|
||||
* the data from the display system to the connected display
|
||||
* device.
|
||||
* @vidcon0: The base vidcon0 values to control the panel data format.
|
||||
* @vidcon1: The base vidcon1 values to control the panel data output.
|
||||
* @vtiming: Video timing when connected to a RGB type panel.
|
||||
* @win: The setup data for each hardware window, or NULL for unused.
|
||||
* @display_mode: The LCD output display mode.
|
||||
*
|
||||
* The platform data supplies the video driver with all the information
|
||||
* it requires to work with the display(s) attached to the machine. It
|
||||
* controls the initial mode, the number of display windows (0 is always
|
||||
* the base framebuffer) that are initialised etc.
|
||||
*
|
||||
*/
|
||||
struct s3c_fb_platdata {
|
||||
void (*setup_gpio)(void);
|
||||
|
||||
struct s3c_fb_pd_win *win[S3C_FB_MAX_WIN];
|
||||
struct fb_videomode *vtiming;
|
||||
|
||||
u32 vidcon0;
|
||||
u32 vidcon1;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -22,6 +22,8 @@
|
|||
*/
|
||||
#define AUOK190X_RESOLUTION_800_600 0
|
||||
#define AUOK190X_RESOLUTION_1024_768 1
|
||||
#define AUOK190X_RESOLUTION_600_800 4
|
||||
#define AUOK190X_RESOLUTION_768_1024 5
|
||||
|
||||
/*
|
||||
* struct used by auok190x. board specific stuff comes from *board
|
||||
|
@ -98,7 +100,6 @@ struct auok190x_board {
|
|||
int gpio_nbusy;
|
||||
|
||||
int resolution;
|
||||
int rotation;
|
||||
int quirks;
|
||||
int fps;
|
||||
};
|
||||
|
|
|
@ -12,19 +12,22 @@
|
|||
#include <linux/bitops.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
/* VESA display monitor timing parameters */
|
||||
#define VESA_DMT_HSYNC_LOW BIT(0)
|
||||
#define VESA_DMT_HSYNC_HIGH BIT(1)
|
||||
#define VESA_DMT_VSYNC_LOW BIT(2)
|
||||
#define VESA_DMT_VSYNC_HIGH BIT(3)
|
||||
enum display_flags {
|
||||
DISPLAY_FLAGS_HSYNC_LOW = BIT(0),
|
||||
DISPLAY_FLAGS_HSYNC_HIGH = BIT(1),
|
||||
DISPLAY_FLAGS_VSYNC_LOW = BIT(2),
|
||||
DISPLAY_FLAGS_VSYNC_HIGH = BIT(3),
|
||||
|
||||
/* display specific flags */
|
||||
#define DISPLAY_FLAGS_DE_LOW BIT(0) /* data enable flag */
|
||||
#define DISPLAY_FLAGS_DE_HIGH BIT(1)
|
||||
#define DISPLAY_FLAGS_PIXDATA_POSEDGE BIT(2) /* drive data on pos. edge */
|
||||
#define DISPLAY_FLAGS_PIXDATA_NEGEDGE BIT(3) /* drive data on neg. edge */
|
||||
#define DISPLAY_FLAGS_INTERLACED BIT(4)
|
||||
#define DISPLAY_FLAGS_DOUBLESCAN BIT(5)
|
||||
/* data enable flag */
|
||||
DISPLAY_FLAGS_DE_LOW = BIT(4),
|
||||
DISPLAY_FLAGS_DE_HIGH = BIT(5),
|
||||
/* drive data on pos. edge */
|
||||
DISPLAY_FLAGS_PIXDATA_POSEDGE = BIT(6),
|
||||
/* drive data on neg. edge */
|
||||
DISPLAY_FLAGS_PIXDATA_NEGEDGE = BIT(7),
|
||||
DISPLAY_FLAGS_INTERLACED = BIT(8),
|
||||
DISPLAY_FLAGS_DOUBLESCAN = BIT(9),
|
||||
};
|
||||
|
||||
/*
|
||||
* A single signal can be specified via a range of minimal and maximal values
|
||||
|
@ -36,12 +39,6 @@ struct timing_entry {
|
|||
u32 max;
|
||||
};
|
||||
|
||||
enum timing_entry_index {
|
||||
TE_MIN = 0,
|
||||
TE_TYP = 1,
|
||||
TE_MAX = 2,
|
||||
};
|
||||
|
||||
/*
|
||||
* Single "mode" entry. This describes one set of signal timings a display can
|
||||
* have in one setting. This struct can later be converted to struct videomode
|
||||
|
@ -72,8 +69,7 @@ struct display_timing {
|
|||
struct timing_entry vback_porch; /* ver. back porch */
|
||||
struct timing_entry vsync_len; /* ver. sync len */
|
||||
|
||||
unsigned int dmt_flags; /* VESA DMT flags */
|
||||
unsigned int data_flags; /* video data flags */
|
||||
enum display_flags flags; /* display flags */
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -89,25 +85,6 @@ struct display_timings {
|
|||
struct display_timing **timings;
|
||||
};
|
||||
|
||||
/* get value specified by index from struct timing_entry */
|
||||
static inline u32 display_timing_get_value(const struct timing_entry *te,
|
||||
enum timing_entry_index index)
|
||||
{
|
||||
switch (index) {
|
||||
case TE_MIN:
|
||||
return te->min;
|
||||
break;
|
||||
case TE_TYP:
|
||||
return te->typ;
|
||||
break;
|
||||
case TE_MAX:
|
||||
return te->max;
|
||||
break;
|
||||
default:
|
||||
return te->typ;
|
||||
}
|
||||
}
|
||||
|
||||
/* get one entry from struct display_timings */
|
||||
static inline struct display_timing *display_timings_get(const struct
|
||||
display_timings *disp,
|
||||
|
|
|
@ -29,20 +29,30 @@ struct videomode {
|
|||
u32 vback_porch;
|
||||
u32 vsync_len;
|
||||
|
||||
unsigned int dmt_flags; /* VESA DMT flags */
|
||||
unsigned int data_flags; /* video data flags */
|
||||
enum display_flags flags; /* display flags */
|
||||
};
|
||||
|
||||
/**
|
||||
* videomode_from_timing - convert display timing to videomode
|
||||
* @dt: display_timing structure
|
||||
* @vm: return value
|
||||
*
|
||||
* DESCRIPTION:
|
||||
* This function converts a struct display_timing to a struct videomode.
|
||||
*/
|
||||
void videomode_from_timing(const struct display_timing *dt,
|
||||
struct videomode *vm);
|
||||
|
||||
/**
|
||||
* videomode_from_timings - convert one display timings entry to videomode
|
||||
* @disp: structure with all possible timing entries
|
||||
* @vm: return value
|
||||
* @index: index into the list of display timings in devicetree
|
||||
*
|
||||
* DESCRIPTION:
|
||||
* This function converts a struct display_timing to a struct videomode.
|
||||
* This function converts one struct display_timing entry to a struct videomode.
|
||||
*/
|
||||
int videomode_from_timing(const struct display_timings *disp,
|
||||
int videomode_from_timings(const struct display_timings *disp,
|
||||
struct videomode *vm, unsigned int index);
|
||||
|
||||
#endif
|
||||
|
|
Загрузка…
Ссылка в новой задаче