dect
/
linux-2.6
Archived
13
0
Fork 0

Merge branch 'fbdev-next' of git://github.com/schandinat/linux-2.6

* 'fbdev-next' of git://github.com/schandinat/linux-2.6: (270 commits)
  video: platinumfb: Add __devexit_p at necessary place
  drivers/video: fsl-diu-fb: merge diu_pool into fsl_diu_data
  drivers/video: fsl-diu-fb: merge diu_hw into fsl_diu_data
  drivers/video: fsl-diu-fb: only DIU modes 0 and 1 are supported
  drivers/video: fsl-diu-fb: remove unused panel operating mode support
  drivers/video: fsl-diu-fb: use an enum for the AOI index
  drivers/video: fsl-diu-fb: add several new video modes
  drivers/video: fsl-diu-fb: remove broken screen blanking support
  drivers/video: fsl-diu-fb: move some definitions out of the header file
  drivers/video: fsl-diu-fb: fix some ioctls
  video: da8xx-fb: Increased resolution configuration of revised LCDC IP
  OMAPDSS: picodlp: add missing #include <linux/module.h>
  fb: fix au1100fb bitrot.
  mx3fb: fix NULL pointer dereference in screen blanking.
  video: irq: Remove IRQF_DISABLED
  smscufx: change edid data to u8 instead of char
  OMAPDSS: DISPC: zorder support for DSS overlays
  OMAPDSS: DISPC: VIDEO3 pipeline support
  OMAPDSS/OMAP_VOUT: Fix incorrect OMAP3-alpha compatibility setting
  video/omap: fix build dependencies
  ...

Fix up conflicts in:
 - drivers/staging/xgifb/XGI_main_26.c
	Changes to XGIfb_pan_var()
 - drivers/video/omap/{lcd_apollon.c,lcd_ldp.c,lcd_overo.c}
	Removed (or in the case of apollon.c, merged into the generic
	DSS panel in drivers/video/omap2/displays/panel-generic-dpi.c)
This commit is contained in:
Linus Torvalds 2011-10-30 15:30:01 -07:00
commit acff987d94
163 changed files with 12125 additions and 7722 deletions

View File

@ -87,23 +87,38 @@ Special configuration for udlfb is usually unnecessary. There are a few
options, however.
From the command line, pass options to modprobe
modprobe udlfb defio=1 console=1
modprobe udlfb fb_defio=0 console=1 shadow=1
Or for permanent option, create file like /etc/modprobe.d/options with text
options udlfb defio=1 console=1
Or modify options on the fly at /sys/module/udlfb/parameters directory via
sudo nano fb_defio
change the parameter in place, and save the file.
Accepted options:
Unplug/replug USB device to apply with new settings
Or for permanent option, create file like /etc/modprobe.d/udlfb.conf with text
options udlfb fb_defio=0 console=1 shadow=1
Accepted boolean options:
fb_defio Make use of the fb_defio (CONFIG_FB_DEFERRED_IO) kernel
module to track changed areas of the framebuffer by page faults.
Standard fbdev applications that use mmap but that do not
report damage, may be able to work with this enabled.
Disabled by default because of overhead and other issues.
Standard fbdev applications that use mmap but that do not
report damage, should be able to work with this enabled.
Disable when running with X server that supports reporting
changed regions via ioctl, as this method is simpler,
more stable, and higher performance.
default: fb_defio=1
console Allow fbcon to attach to udlfb provided framebuffers. This
is disabled by default because fbcon will aggressively consume
the first framebuffer it finds, which isn't usually what the
user wants in the case of USB displays.
console Allow fbcon to attach to udlfb provided framebuffers.
Can be disabled if fbcon and other clients
(e.g. X with --shared-vt) are in conflict.
default: console=1
shadow Allocate a 2nd framebuffer to shadow what's currently across
the USB bus in device memory. If any pixels are unchanged,
do not transmit. Spends host memory to save USB transfers.
Enabled by default. Only disable on very low memory systems.
default: shadow=1
Sysfs Attributes
================

View File

@ -5970,6 +5970,12 @@ L: netdev@vger.kernel.org
S: Supported
F: drivers/net/ethernet/smsc/smsc9420.*
SMSC UFX6000 and UFX7000 USB to VGA DRIVER
M: Steve Glendinning <steve.glendinning@smsc.com>
L: linux-fbdev@vger.kernel.org
S: Supported
F: drivers/video/smscufx.c
SN-IA64 (Itanium) SUB-PLATFORM
M: Jes Sorensen <jes@sgi.com>
L: linux-altix@sgi.com

View File

@ -39,6 +39,9 @@
#include <plat/usb.h>
#include <plat/gpmc-smc91x.h>
#include <video/omapdss.h>
#include <video/omap-panel-generic-dpi.h>
#include "mux.h"
#include "hsmmc.h"
#include "common-board-devices.h"
@ -99,20 +102,72 @@ static struct platform_device sdp2430_flash_device = {
.resource = &sdp2430_flash_resource,
};
static struct platform_device sdp2430_lcd_device = {
.name = "sdp2430_lcd",
.id = -1,
};
static struct platform_device *sdp2430_devices[] __initdata = {
&sdp2430_flash_device,
};
/* LCD */
#define SDP2430_LCD_PANEL_BACKLIGHT_GPIO 91
#define SDP2430_LCD_PANEL_ENABLE_GPIO 154
static int sdp2430_panel_enable_lcd(struct omap_dss_device *dssdev)
{
gpio_direction_output(SDP2430_LCD_PANEL_ENABLE_GPIO, 1);
gpio_direction_output(SDP2430_LCD_PANEL_BACKLIGHT_GPIO, 1);
return 0;
}
static void sdp2430_panel_disable_lcd(struct omap_dss_device *dssdev)
{
gpio_direction_output(SDP2430_LCD_PANEL_ENABLE_GPIO, 0);
gpio_direction_output(SDP2430_LCD_PANEL_BACKLIGHT_GPIO, 0);
}
static struct panel_generic_dpi_data sdp2430_panel_data = {
.name = "nec_nl2432dr22-11b",
.platform_enable = sdp2430_panel_enable_lcd,
.platform_disable = sdp2430_panel_disable_lcd,
};
static struct omap_dss_device sdp2430_lcd_device = {
.name = "lcd",
.driver_name = "generic_dpi_panel",
.type = OMAP_DISPLAY_TYPE_DPI,
.phy.dpi.data_lines = 16,
.data = &sdp2430_panel_data,
};
static struct omap_dss_device *sdp2430_dss_devices[] = {
&sdp2430_lcd_device,
};
static struct omap_lcd_config sdp2430_lcd_config __initdata = {
.ctrl_name = "internal",
static struct omap_dss_board_info sdp2430_dss_data = {
.num_devices = ARRAY_SIZE(sdp2430_dss_devices),
.devices = sdp2430_dss_devices,
.default_device = &sdp2430_lcd_device,
};
static void __init sdp2430_display_init(void)
{
int r;
static struct gpio gpios[] __initdata = {
{ SDP2430_LCD_PANEL_ENABLE_GPIO, GPIOF_OUT_INIT_LOW,
"LCD reset" },
{ SDP2430_LCD_PANEL_BACKLIGHT_GPIO, GPIOF_OUT_INIT_LOW,
"LCD Backlight" },
};
r = gpio_request_array(gpios, ARRAY_SIZE(gpios));
if (r) {
pr_err("Cannot request LCD GPIOs, error %d\n", r);
return;
}
omap_display_init(&sdp2430_dss_data);
}
#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91x_MODULE)
static struct omap_smc91x_platform_data board_smc91x_data = {
@ -137,10 +192,6 @@ static inline void board_smc91x_init(void)
#endif
static struct omap_board_config_kernel sdp2430_config[] __initdata = {
{OMAP_TAG_LCD, &sdp2430_lcd_config},
};
static void __init omap_2430sdp_init_early(void)
{
omap2_init_common_infrastructure();
@ -229,9 +280,6 @@ static void __init omap_2430sdp_init(void)
{
omap2430_mux_init(board_mux, OMAP_PACKAGE_ZAC);
omap_board_config = sdp2430_config;
omap_board_config_size = ARRAY_SIZE(sdp2430_config);
omap2430_i2c_init();
platform_add_devices(sdp2430_devices, ARRAY_SIZE(sdp2430_devices));
@ -247,6 +295,8 @@ static void __init omap_2430sdp_init(void)
/* Turn off secondary LCD backlight */
gpio_request_one(SECONDARY_LCD_GPIO, GPIOF_OUT_INIT_LOW,
"Secondary LCD backlight");
sdp2430_display_init();
}
static void __init omap_2430sdp_map_io(void)

View File

@ -37,7 +37,7 @@
#include <plat/dma.h>
#include <plat/gpmc.h>
#include <video/omapdss.h>
#include <video/omap-panel-generic-dpi.h>
#include <video/omap-panel-dvi.h>
#include <plat/gpmc-smc91x.h>
@ -186,8 +186,7 @@ static struct omap_dss_device sdp3430_lcd_device = {
.platform_disable = sdp3430_panel_disable_lcd,
};
static struct panel_generic_dpi_data dvi_panel = {
.name = "generic",
static struct panel_dvi_platform_data dvi_panel = {
.platform_enable = sdp3430_panel_enable_dvi,
.platform_disable = sdp3430_panel_disable_dvi,
};
@ -195,7 +194,7 @@ static struct panel_generic_dpi_data dvi_panel = {
static struct omap_dss_device sdp3430_dvi_device = {
.name = "dvi",
.type = OMAP_DISPLAY_TYPE_DPI,
.driver_name = "generic_dpi_panel",
.driver_name = "dvi",
.data = &dvi_panel,
.phy.dpi.data_lines = 24,
};

View File

@ -38,6 +38,8 @@
#include <plat/mmc.h>
#include <plat/omap4-keypad.h>
#include <video/omapdss.h>
#include <video/omap-panel-nokia-dsi.h>
#include <video/omap-panel-picodlp.h>
#include <linux/wl12xx.h>
#include "mux.h"
@ -52,6 +54,8 @@
#define OMAP4_SFH7741_ENABLE_GPIO 188
#define HDMI_GPIO_HPD 60 /* Hot plug pin for HDMI */
#define HDMI_GPIO_LS_OE 41 /* Level shifter for HDMI */
#define DISPLAY_SEL_GPIO 59 /* LCD2/PicoDLP switch */
#define DLP_POWER_ON_GPIO 40
#define GPIO_WIFI_PMENA 54
#define GPIO_WIFI_IRQ 53
@ -340,11 +344,6 @@ static int __init omap_ethernet_init(void)
return status;
}
static struct platform_device sdp4430_lcd_device = {
.name = "sdp4430_lcd",
.id = -1,
};
static struct regulator_consumer_supply sdp4430_vbat_supply[] = {
REGULATOR_SUPPLY("vddvibl", "twl6040-vibra"),
REGULATOR_SUPPLY("vddvibr", "twl6040-vibra"),
@ -374,21 +373,12 @@ static struct platform_device sdp4430_vbat = {
};
static struct platform_device *sdp4430_devices[] __initdata = {
&sdp4430_lcd_device,
&sdp4430_gpio_keys_device,
&sdp4430_leds_gpio,
&sdp4430_leds_pwm,
&sdp4430_vbat,
};
static struct omap_lcd_config sdp4430_lcd_config __initdata = {
.ctrl_name = "internal",
};
static struct omap_board_config_kernel sdp4430_config[] __initdata = {
{ OMAP_TAG_LCD, &sdp4430_lcd_config },
};
static void __init omap_4430sdp_init_early(void)
{
omap2_init_common_infrastructure();
@ -648,37 +638,202 @@ static void sdp4430_panel_disable_hdmi(struct omap_dss_device *dssdev)
gpio_free(HDMI_GPIO_HPD);
}
static struct nokia_dsi_panel_data dsi1_panel = {
.name = "taal",
.reset_gpio = 102,
.use_ext_te = false,
.ext_te_gpio = 101,
.esd_interval = 0,
};
static struct omap_dss_device sdp4430_lcd_device = {
.name = "lcd",
.driver_name = "taal",
.type = OMAP_DISPLAY_TYPE_DSI,
.data = &dsi1_panel,
.phy.dsi = {
.clk_lane = 1,
.clk_pol = 0,
.data1_lane = 2,
.data1_pol = 0,
.data2_lane = 3,
.data2_pol = 0,
.module = 0,
},
.clocks = {
.dispc = {
.channel = {
/* Logic Clock = 172.8 MHz */
.lck_div = 1,
/* Pixel Clock = 34.56 MHz */
.pck_div = 5,
.lcd_clk_src = OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC,
},
.dispc_fclk_src = OMAP_DSS_CLK_SRC_FCK,
},
.dsi = {
.regn = 16, /* Fint = 2.4 MHz */
.regm = 180, /* DDR Clock = 216 MHz */
.regm_dispc = 5, /* PLL1_CLK1 = 172.8 MHz */
.regm_dsi = 5, /* PLL1_CLK2 = 172.8 MHz */
.lp_clk_div = 10, /* LP Clock = 8.64 MHz */
.dsi_fclk_src = OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI,
},
},
.channel = OMAP_DSS_CHANNEL_LCD,
};
static struct nokia_dsi_panel_data dsi2_panel = {
.name = "taal",
.reset_gpio = 104,
.use_ext_te = false,
.ext_te_gpio = 103,
.esd_interval = 0,
};
static struct omap_dss_device sdp4430_lcd2_device = {
.name = "lcd2",
.driver_name = "taal",
.type = OMAP_DISPLAY_TYPE_DSI,
.data = &dsi2_panel,
.phy.dsi = {
.clk_lane = 1,
.clk_pol = 0,
.data1_lane = 2,
.data1_pol = 0,
.data2_lane = 3,
.data2_pol = 0,
.module = 1,
},
.clocks = {
.dispc = {
.channel = {
/* Logic Clock = 172.8 MHz */
.lck_div = 1,
/* Pixel Clock = 34.56 MHz */
.pck_div = 5,
.lcd_clk_src = OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC,
},
.dispc_fclk_src = OMAP_DSS_CLK_SRC_FCK,
},
.dsi = {
.regn = 16, /* Fint = 2.4 MHz */
.regm = 180, /* DDR Clock = 216 MHz */
.regm_dispc = 5, /* PLL1_CLK1 = 172.8 MHz */
.regm_dsi = 5, /* PLL1_CLK2 = 172.8 MHz */
.lp_clk_div = 10, /* LP Clock = 8.64 MHz */
.dsi_fclk_src = OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI,
},
},
.channel = OMAP_DSS_CHANNEL_LCD2,
};
static void sdp4430_lcd_init(void)
{
int r;
r = gpio_request_one(dsi1_panel.reset_gpio, GPIOF_DIR_OUT,
"lcd1_reset_gpio");
if (r)
pr_err("%s: Could not get lcd1_reset_gpio\n", __func__);
r = gpio_request_one(dsi2_panel.reset_gpio, GPIOF_DIR_OUT,
"lcd2_reset_gpio");
if (r)
pr_err("%s: Could not get lcd2_reset_gpio\n", __func__);
}
static struct omap_dss_device sdp4430_hdmi_device = {
.name = "hdmi",
.driver_name = "hdmi_panel",
.type = OMAP_DISPLAY_TYPE_HDMI,
.clocks = {
.dispc = {
.dispc_fclk_src = OMAP_DSS_CLK_SRC_FCK,
},
.hdmi = {
.regn = 15,
.regm2 = 1,
},
},
.platform_enable = sdp4430_panel_enable_hdmi,
.platform_disable = sdp4430_panel_disable_hdmi,
.channel = OMAP_DSS_CHANNEL_DIGIT,
};
static struct picodlp_panel_data sdp4430_picodlp_pdata = {
.picodlp_adapter_id = 2,
.emu_done_gpio = 44,
.pwrgood_gpio = 45,
};
static void sdp4430_picodlp_init(void)
{
int r;
const struct gpio picodlp_gpios[] = {
{DLP_POWER_ON_GPIO, GPIOF_OUT_INIT_LOW,
"DLP POWER ON"},
{sdp4430_picodlp_pdata.emu_done_gpio, GPIOF_IN,
"DLP EMU DONE"},
{sdp4430_picodlp_pdata.pwrgood_gpio, GPIOF_OUT_INIT_LOW,
"DLP PWRGOOD"},
};
r = gpio_request_array(picodlp_gpios, ARRAY_SIZE(picodlp_gpios));
if (r)
pr_err("Cannot request PicoDLP GPIOs, error %d\n", r);
}
static int sdp4430_panel_enable_picodlp(struct omap_dss_device *dssdev)
{
gpio_set_value(DISPLAY_SEL_GPIO, 0);
gpio_set_value(DLP_POWER_ON_GPIO, 1);
return 0;
}
static void sdp4430_panel_disable_picodlp(struct omap_dss_device *dssdev)
{
gpio_set_value(DLP_POWER_ON_GPIO, 0);
gpio_set_value(DISPLAY_SEL_GPIO, 1);
}
static struct omap_dss_device sdp4430_picodlp_device = {
.name = "picodlp",
.driver_name = "picodlp_panel",
.type = OMAP_DISPLAY_TYPE_DPI,
.phy.dpi.data_lines = 24,
.channel = OMAP_DSS_CHANNEL_LCD2,
.platform_enable = sdp4430_panel_enable_picodlp,
.platform_disable = sdp4430_panel_disable_picodlp,
.data = &sdp4430_picodlp_pdata,
};
static struct omap_dss_device *sdp4430_dss_devices[] = {
&sdp4430_lcd_device,
&sdp4430_lcd2_device,
&sdp4430_hdmi_device,
&sdp4430_picodlp_device,
};
static struct omap_dss_board_info sdp4430_dss_data = {
.num_devices = ARRAY_SIZE(sdp4430_dss_devices),
.devices = sdp4430_dss_devices,
.default_device = &sdp4430_hdmi_device,
.default_device = &sdp4430_lcd_device,
};
void omap_4430sdp_display_init(void)
static void omap_4430sdp_display_init(void)
{
int r;
/* Enable LCD2 by default (instead of Pico DLP) */
r = gpio_request_one(DISPLAY_SEL_GPIO, GPIOF_OUT_INIT_HIGH,
"display_sel");
if (r)
pr_err("%s: Could not get display_sel GPIO\n", __func__);
sdp4430_lcd_init();
sdp4430_hdmi_mux_init();
sdp4430_picodlp_init();
omap_display_init(&sdp4430_dss_data);
}
@ -802,9 +957,6 @@ static void __init omap_4430sdp_init(void)
package = OMAP_PACKAGE_CBL;
omap4_mux_init(board_mux, NULL, package);
omap_board_config = sdp4430_config;
omap_board_config_size = ARRAY_SIZE(sdp4430_config);
omap4_i2c_init();
omap_sfh7741prox_init();
platform_add_devices(sdp4430_devices, ARRAY_SIZE(sdp4430_devices));

View File

@ -36,6 +36,7 @@
#include <plat/usb.h>
#include <video/omapdss.h>
#include <video/omap-panel-generic-dpi.h>
#include <video/omap-panel-dvi.h>
#include "mux.h"
#include "control.h"
@ -333,8 +334,7 @@ static void am3517_evm_panel_disable_dvi(struct omap_dss_device *dssdev)
dvi_enabled = 0;
}
static struct panel_generic_dpi_data dvi_panel = {
.name = "generic",
static struct panel_dvi_platform_data dvi_panel = {
.platform_enable = am3517_evm_panel_enable_dvi,
.platform_disable = am3517_evm_panel_disable_dvi,
};
@ -342,7 +342,7 @@ static struct panel_generic_dpi_data dvi_panel = {
static struct omap_dss_device am3517_evm_dvi_device = {
.type = OMAP_DISPLAY_TYPE_DPI,
.name = "dvi",
.driver_name = "generic_dpi_panel",
.driver_name = "dvi",
.data = &dvi_panel,
.phy.dpi.data_lines = 24,
};

View File

@ -40,6 +40,9 @@
#include <plat/common.h>
#include <plat/gpmc.h>
#include <video/omapdss.h>
#include <video/omap-panel-generic-dpi.h>
#include "mux.h"
#include "control.h"
@ -149,11 +152,6 @@ static struct platform_device apollon_smc91x_device = {
.resource = apollon_smc91x_resources,
};
static struct platform_device apollon_lcd_device = {
.name = "apollon_lcd",
.id = -1,
};
static struct omap_led_config apollon_led_config[] = {
{
.cdev = {
@ -191,7 +189,6 @@ static struct platform_device apollon_led_device = {
static struct platform_device *apollon_devices[] __initdata = {
&apollon_onenand_device,
&apollon_smc91x_device,
&apollon_lcd_device,
&apollon_led_device,
};
@ -265,12 +262,26 @@ static struct omap_usb_config apollon_usb_config __initdata = {
.pins[0] = 6,
};
static struct omap_lcd_config apollon_lcd_config __initdata = {
.ctrl_name = "internal",
static struct panel_generic_dpi_data apollon_panel_data = {
.name = "apollon",
};
static struct omap_board_config_kernel apollon_config[] __initdata = {
{ OMAP_TAG_LCD, &apollon_lcd_config },
static struct omap_dss_device apollon_lcd_device = {
.name = "lcd",
.driver_name = "generic_dpi_panel",
.type = OMAP_DISPLAY_TYPE_DPI,
.phy.dpi.data_lines = 18,
.data = &apollon_panel_data,
};
static struct omap_dss_device *apollon_dss_devices[] = {
&apollon_lcd_device,
};
static struct omap_dss_board_info apollon_dss_data = {
.num_devices = ARRAY_SIZE(apollon_dss_devices),
.devices = apollon_dss_devices,
.default_device = &apollon_lcd_device,
};
static void __init omap_apollon_init_early(void)
@ -314,8 +325,6 @@ static void __init omap_apollon_init(void)
u32 v;
omap2420_mux_init(board_mux, OMAP_PACKAGE_ZAC);
omap_board_config = apollon_config;
omap_board_config_size = ARRAY_SIZE(apollon_config);
apollon_init_smc91x();
apollon_led_init();
@ -340,6 +349,8 @@ static void __init omap_apollon_init(void)
*/
platform_add_devices(apollon_devices, ARRAY_SIZE(apollon_devices));
omap_serial_init();
omap_display_init(&apollon_dss_data);
}
static void __init omap_apollon_map_io(void)

View File

@ -43,6 +43,7 @@
#include <plat/usb.h>
#include <video/omapdss.h>
#include <video/omap-panel-generic-dpi.h>
#include <video/omap-panel-dvi.h>
#include <plat/mcspi.h>
#include <mach/hardware.h>
@ -242,8 +243,7 @@ static struct omap_dss_device cm_t35_lcd_device = {
.phy.dpi.data_lines = 18,
};
static struct panel_generic_dpi_data dvi_panel = {
.name = "generic",
static struct panel_dvi_platform_data dvi_panel = {
.platform_enable = cm_t35_panel_enable_dvi,
.platform_disable = cm_t35_panel_disable_dvi,
};
@ -251,7 +251,7 @@ static struct panel_generic_dpi_data dvi_panel = {
static struct omap_dss_device cm_t35_dvi_device = {
.name = "dvi",
.type = OMAP_DISPLAY_TYPE_DPI,
.driver_name = "generic_dpi_panel",
.driver_name = "dvi",
.data = &dvi_panel,
.phy.dpi.data_lines = 24,
};

View File

@ -47,6 +47,7 @@
#include <plat/usb.h>
#include <video/omapdss.h>
#include <video/omap-panel-generic-dpi.h>
#include <video/omap-panel-dvi.h>
#include <plat/mcspi.h>
#include <linux/input/matrix_keypad.h>
@ -139,7 +140,7 @@ static struct regulator_consumer_supply devkit8000_vio_supply[] = {
};
static struct panel_generic_dpi_data lcd_panel = {
.name = "generic",
.name = "innolux_at070tn83",
.platform_enable = devkit8000_panel_enable_lcd,
.platform_disable = devkit8000_panel_disable_lcd,
};
@ -152,8 +153,7 @@ static struct omap_dss_device devkit8000_lcd_device = {
.phy.dpi.data_lines = 24,
};
static struct panel_generic_dpi_data dvi_panel = {
.name = "generic",
static struct panel_dvi_platform_data dvi_panel = {
.platform_enable = devkit8000_panel_enable_dvi,
.platform_disable = devkit8000_panel_disable_dvi,
};
@ -161,7 +161,7 @@ static struct panel_generic_dpi_data dvi_panel = {
static struct omap_dss_device devkit8000_dvi_device = {
.name = "dvi",
.type = OMAP_DISPLAY_TYPE_DPI,
.driver_name = "generic_dpi_panel",
.driver_name = "dvi",
.data = &dvi_panel,
.phy.dpi.data_lines = 24,
};
@ -267,7 +267,7 @@ static struct twl4030_gpio_platform_data devkit8000_gpio_data = {
static struct regulator_consumer_supply devkit8000_vpll1_supplies[] = {
REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
};
/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */

View File

@ -39,6 +39,9 @@
#include <plat/dma.h>
#include <plat/gpmc.h>
#include <video/omapdss.h>
#include <video/omap-panel-generic-dpi.h>
#include "mux.h"
#include "control.h"
@ -156,17 +159,33 @@ static struct platform_device h4_kp_device = {
},
};
static struct platform_device h4_lcd_device = {
.name = "lcd_h4",
.id = -1,
};
static struct platform_device *h4_devices[] __initdata = {
&h4_flash_device,
&h4_kp_device,
};
static struct panel_generic_dpi_data h4_panel_data = {
.name = "h4",
};
static struct omap_dss_device h4_lcd_device = {
.name = "lcd",
.driver_name = "generic_dpi_panel",
.type = OMAP_DISPLAY_TYPE_DPI,
.phy.dpi.data_lines = 16,
.data = &h4_panel_data,
};
static struct omap_dss_device *h4_dss_devices[] = {
&h4_lcd_device,
};
static struct omap_dss_board_info h4_dss_data = {
.num_devices = ARRAY_SIZE(h4_dss_devices),
.devices = h4_dss_devices,
.default_device = &h4_lcd_device,
};
/* 2420 Sysboot setup (2430 is different) */
static u32 get_sysboot_value(void)
{
@ -270,10 +289,6 @@ static void __init h4_init_flash(void)
h4_flash_resource.end = base + SZ_64M - 1;
}
static struct omap_lcd_config h4_lcd_config __initdata = {
.ctrl_name = "internal",
};
static struct omap_usb_config h4_usb_config __initdata = {
/* S1.10 OFF -- usb "download port"
* usb0 switched to Mini-B port and isp1105 transceiver;
@ -285,10 +300,6 @@ static struct omap_usb_config h4_usb_config __initdata = {
.hmc_mode = 0x00, /* 0:dev|otg 1:disable 2:disable */
};
static struct omap_board_config_kernel h4_config[] __initdata = {
{ OMAP_TAG_LCD, &h4_lcd_config },
};
static void __init omap_h4_init_early(void)
{
omap2_init_common_infrastructure();
@ -330,9 +341,6 @@ static void __init omap_h4_init(void)
{
omap2420_mux_init(board_mux, OMAP_PACKAGE_ZAF);
omap_board_config = h4_config;
omap_board_config_size = ARRAY_SIZE(h4_config);
/*
* Make sure the serial ports are muxed on at this point.
* You have to mux them off in device drivers later on
@ -371,6 +379,8 @@ static void __init omap_h4_init(void)
omap2_usbfs_init(&h4_usb_config);
omap_serial_init();
h4_init_flash();
omap_display_init(&h4_dss_data);
}
static void __init omap_h4_map_io(void)

View File

@ -32,7 +32,7 @@
#include <plat/gpmc.h>
#include <plat/usb.h>
#include <video/omapdss.h>
#include <video/omap-panel-generic-dpi.h>
#include <video/omap-panel-dvi.h>
#include <plat/onenand.h>
#include "mux.h"
@ -455,16 +455,16 @@ static void igep2_disable_dvi(struct omap_dss_device *dssdev)
gpio_direction_output(IGEP2_GPIO_DVI_PUP, 0);
}
static struct panel_generic_dpi_data dvi_panel = {
.name = "generic",
static struct panel_dvi_platform_data dvi_panel = {
.platform_enable = igep2_enable_dvi,
.platform_disable = igep2_disable_dvi,
.i2c_bus_num = 3,
};
static struct omap_dss_device igep2_dvi_device = {
.type = OMAP_DISPLAY_TYPE_DPI,
.name = "dvi",
.driver_name = "generic_dpi_panel",
.driver_name = "dvi",
.data = &dvi_panel,
.phy.dpi.data_lines = 24,
};

View File

@ -27,6 +27,7 @@
#include <linux/io.h>
#include <linux/smsc911x.h>
#include <linux/mmc/host.h>
#include <linux/gpio.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
@ -43,6 +44,9 @@
#include <plat/usb.h>
#include <plat/gpmc-smsc911x.h>
#include <video/omapdss.h>
#include <video/omap-panel-generic-dpi.h>
#include "board-flash.h"
#include "mux.h"
#include "hsmmc.h"
@ -179,29 +183,108 @@ static inline void __init ldp_init_smsc911x(void)
gpmc_smsc911x_init(&smsc911x_cfg);
}
static struct platform_device ldp_lcd_device = {
.name = "ldp_lcd",
.id = -1,
/* LCD */
static int ldp_backlight_gpio;
static int ldp_lcd_enable_gpio;
#define LCD_PANEL_RESET_GPIO 55
#define LCD_PANEL_QVGA_GPIO 56
static int ldp_panel_enable_lcd(struct omap_dss_device *dssdev)
{
if (gpio_is_valid(ldp_lcd_enable_gpio))
gpio_direction_output(ldp_lcd_enable_gpio, 1);
if (gpio_is_valid(ldp_backlight_gpio))
gpio_direction_output(ldp_backlight_gpio, 1);
return 0;
}
static void ldp_panel_disable_lcd(struct omap_dss_device *dssdev)
{
if (gpio_is_valid(ldp_lcd_enable_gpio))
gpio_direction_output(ldp_lcd_enable_gpio, 0);
if (gpio_is_valid(ldp_backlight_gpio))
gpio_direction_output(ldp_backlight_gpio, 0);
}
static struct panel_generic_dpi_data ldp_panel_data = {
.name = "nec_nl2432dr22-11b",
.platform_enable = ldp_panel_enable_lcd,
.platform_disable = ldp_panel_disable_lcd,
};
static struct omap_lcd_config ldp_lcd_config __initdata = {
.ctrl_name = "internal",
static struct omap_dss_device ldp_lcd_device = {
.name = "lcd",
.driver_name = "generic_dpi_panel",
.type = OMAP_DISPLAY_TYPE_DPI,
.phy.dpi.data_lines = 18,
.data = &ldp_panel_data,
};
static struct omap_board_config_kernel ldp_config[] __initdata = {
{ OMAP_TAG_LCD, &ldp_lcd_config },
static struct omap_dss_device *ldp_dss_devices[] = {
&ldp_lcd_device,
};
static struct omap_dss_board_info ldp_dss_data = {
.num_devices = ARRAY_SIZE(ldp_dss_devices),
.devices = ldp_dss_devices,
.default_device = &ldp_lcd_device,
};
static void __init ldp_display_init(void)
{
int r;
static struct gpio gpios[] __initdata = {
{LCD_PANEL_RESET_GPIO, GPIOF_OUT_INIT_HIGH, "LCD RESET"},
{LCD_PANEL_QVGA_GPIO, GPIOF_OUT_INIT_HIGH, "LCD QVGA"},
};
r = gpio_request_array(gpios, ARRAY_SIZE(gpios));
if (r) {
pr_err("Cannot request LCD GPIOs, error %d\n", r);
return;
}
omap_display_init(&ldp_dss_data);
}
static void __init omap_ldp_init_early(void)
{
omap2_init_common_infrastructure();
omap2_init_common_devices(NULL, NULL);
}
static int ldp_twl_gpio_setup(struct device *dev, unsigned gpio, unsigned ngpio)
{
int r;
struct gpio gpios[] = {
{gpio + 7 , GPIOF_OUT_INIT_LOW, "LCD ENABLE"},
{gpio + 15, GPIOF_OUT_INIT_LOW, "LCD BACKLIGHT"},
};
r = gpio_request_array(gpios, ARRAY_SIZE(gpios));
if (r) {
pr_err("Cannot request LCD GPIOs, error %d\n", r);
ldp_backlight_gpio = -EINVAL;
ldp_lcd_enable_gpio = -EINVAL;
return r;
}
ldp_backlight_gpio = gpio + 15;
ldp_lcd_enable_gpio = gpio + 7;
return 0;
}
static struct twl4030_gpio_platform_data ldp_gpio_data = {
.gpio_base = OMAP_MAX_GPIO_LINES,
.irq_base = TWL4030_GPIO_IRQ_BASE,
.irq_end = TWL4030_GPIO_IRQ_END,
.setup = ldp_twl_gpio_setup,
};
static struct regulator_consumer_supply ldp_vmmc1_supply[] = {
@ -243,10 +326,31 @@ static struct regulator_init_data ldp_vaux1 = {
.consumer_supplies = ldp_vaux1_supplies,
};
static struct regulator_consumer_supply ldp_vpll2_supplies[] = {
REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
};
static struct regulator_init_data ldp_vpll2 = {
.constraints = {
.name = "VDVI",
.min_uV = 1800000,
.max_uV = 1800000,
.apply_uV = true,
.valid_modes_mask = REGULATOR_MODE_NORMAL
| REGULATOR_MODE_STANDBY,
.valid_ops_mask = REGULATOR_CHANGE_MODE
| REGULATOR_CHANGE_STATUS,
},
.num_consumer_supplies = ARRAY_SIZE(ldp_vpll2_supplies),
.consumer_supplies = ldp_vpll2_supplies,
};
static struct twl4030_platform_data ldp_twldata = {
/* platform_data for children goes here */
.vmmc1 = &ldp_vmmc1,
.vaux1 = &ldp_vaux1,
.vpll2 = &ldp_vpll2,
.gpio = &ldp_gpio_data,
.keypad = &ldp_kp_twl4030_data,
};
@ -272,7 +376,6 @@ static struct omap2_hsmmc_info mmc[] __initdata = {
};
static struct platform_device *ldp_devices[] __initdata = {
&ldp_lcd_device,
&ldp_gpio_keys_device,
};
@ -317,8 +420,6 @@ static struct mtd_partition ldp_nand_partitions[] = {
static void __init omap_ldp_init(void)
{
omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
omap_board_config = ldp_config;
omap_board_config_size = ARRAY_SIZE(ldp_config);
ldp_init_smsc911x();
omap_i2c_init();
platform_add_devices(ldp_devices, ARRAY_SIZE(ldp_devices));
@ -329,6 +430,7 @@ static void __init omap_ldp_init(void)
ARRAY_SIZE(ldp_nand_partitions), ZOOM_NAND_CS, 0);
omap2_hsmmc_init(mmc);
ldp_display_init();
}
MACHINE_START(OMAP_LDP, "OMAP LDP board")

View File

@ -42,7 +42,7 @@
#include <plat/board.h>
#include <plat/common.h>
#include <video/omapdss.h>
#include <video/omap-panel-generic-dpi.h>
#include <video/omap-panel-dvi.h>
#include <plat/gpmc.h>
#include <plat/nand.h>
#include <plat/usb.h>
@ -203,16 +203,16 @@ static void beagle_disable_dvi(struct omap_dss_device *dssdev)
gpio_set_value(dssdev->reset_gpio, 0);
}
static struct panel_generic_dpi_data dvi_panel = {
.name = "generic",
static struct panel_dvi_platform_data dvi_panel = {
.platform_enable = beagle_enable_dvi,
.platform_disable = beagle_disable_dvi,
.i2c_bus_num = 3,
};
static struct omap_dss_device beagle_dvi_device = {
.type = OMAP_DISPLAY_TYPE_DPI,
.name = "dvi",
.driver_name = "generic_dpi_panel",
.driver_name = "dvi",
.data = &dvi_panel,
.phy.dpi.data_lines = 24,
.reset_gpio = -EINVAL,

View File

@ -45,7 +45,7 @@
#include <plat/common.h>
#include <plat/mcspi.h>
#include <video/omapdss.h>
#include <video/omap-panel-generic-dpi.h>
#include <video/omap-panel-dvi.h>
#include "mux.h"
#include "sdram-micron-mt46h32m32lf-6.h"
@ -247,8 +247,7 @@ static void omap3_evm_disable_dvi(struct omap_dss_device *dssdev)
dvi_enabled = 0;
}
static struct panel_generic_dpi_data dvi_panel = {
.name = "generic",
static struct panel_dvi_platform_data dvi_panel = {
.platform_enable = omap3_evm_enable_dvi,
.platform_disable = omap3_evm_disable_dvi,
};
@ -256,7 +255,7 @@ static struct panel_generic_dpi_data dvi_panel = {
static struct omap_dss_device omap3_evm_dvi_device = {
.name = "dvi",
.type = OMAP_DISPLAY_TYPE_DPI,
.driver_name = "generic_dpi_panel",
.driver_name = "dvi",
.data = &dvi_panel,
.phy.dpi.data_lines = 24,
};

View File

@ -335,7 +335,7 @@ static struct regulator_consumer_supply pandora_vmmc3_supply[] = {
static struct regulator_consumer_supply pandora_vdds_supplies[] = {
REGULATOR_SUPPLY("vdds_sdi", "omapdss"),
REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
};
static struct regulator_consumer_supply pandora_vcc_lcd_supply[] = {

View File

@ -41,6 +41,7 @@
#include <plat/usb.h>
#include <video/omapdss.h>
#include <video/omap-panel-generic-dpi.h>
#include <video/omap-panel-dvi.h>
#include <plat/mcspi.h>
#include <linux/input/matrix_keypad.h>
@ -107,39 +108,6 @@ static void __init omap3_stalker_display_init(void)
return;
}
static int omap3_stalker_enable_lcd(struct omap_dss_device *dssdev)
{
if (dvi_enabled) {
printk(KERN_ERR "cannot enable LCD, DVI is enabled\n");
return -EINVAL;
}
gpio_set_value(DSS_ENABLE_GPIO, 1);
gpio_set_value(LCD_PANEL_BKLIGHT_GPIO, 1);
lcd_enabled = 1;
return 0;
}
static void omap3_stalker_disable_lcd(struct omap_dss_device *dssdev)
{
gpio_set_value(DSS_ENABLE_GPIO, 0);
gpio_set_value(LCD_PANEL_BKLIGHT_GPIO, 0);
lcd_enabled = 0;
}
static struct panel_generic_dpi_data lcd_panel = {
.name = "generic",
.platform_enable = omap3_stalker_enable_lcd,
.platform_disable = omap3_stalker_disable_lcd,
};
static struct omap_dss_device omap3_stalker_lcd_device = {
.name = "lcd",
.driver_name = "generic_dpi_panel",
.data = &lcd_panel,
.phy.dpi.data_lines = 24,
.type = OMAP_DISPLAY_TYPE_DPI,
};
static int omap3_stalker_enable_tv(struct omap_dss_device *dssdev)
{
return 0;
@ -179,8 +147,7 @@ static void omap3_stalker_disable_dvi(struct omap_dss_device *dssdev)
dvi_enabled = 0;
}
static struct panel_generic_dpi_data dvi_panel = {
.name = "generic",
static struct panel_dvi_platform_data dvi_panel = {
.platform_enable = omap3_stalker_enable_dvi,
.platform_disable = omap3_stalker_disable_dvi,
};
@ -188,13 +155,12 @@ static struct panel_generic_dpi_data dvi_panel = {
static struct omap_dss_device omap3_stalker_dvi_device = {
.name = "dvi",
.type = OMAP_DISPLAY_TYPE_DPI,
.driver_name = "generic_dpi_panel",
.driver_name = "dvi",
.data = &dvi_panel,
.phy.dpi.data_lines = 24,
};
static struct omap_dss_device *omap3_stalker_dss_devices[] = {
&omap3_stalker_lcd_device,
&omap3_stalker_tv_device,
&omap3_stalker_dvi_device,
};

View File

@ -104,15 +104,6 @@ static struct omap2_hsmmc_info mmc[] = {
{} /* Terminator */
};
static struct platform_device omap3_touchbook_lcd_device = {
.name = "omap3touchbook_lcd",
.id = -1,
};
static struct omap_lcd_config omap3_touchbook_lcd_config __initdata = {
.ctrl_name = "internal",
};
static struct regulator_consumer_supply touchbook_vmmc1_supply[] = {
REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"),
};
@ -165,14 +156,12 @@ static struct twl4030_gpio_platform_data touchbook_gpio_data = {
static struct regulator_consumer_supply touchbook_vdac_supply[] = {
{
.supply = "vdac",
.dev = &omap3_touchbook_lcd_device.dev,
},
};
static struct regulator_consumer_supply touchbook_vdvi_supply[] = {
{
.supply = "vdvi",
.dev = &omap3_touchbook_lcd_device.dev,
},
};
@ -316,10 +305,6 @@ static struct platform_device keys_gpio = {
},
};
static struct omap_board_config_kernel omap3_touchbook_config[] __initdata = {
{ OMAP_TAG_LCD, &omap3_touchbook_lcd_config },
};
#ifdef CONFIG_OMAP_MUX
static struct omap_board_mux board_mux[] __initdata = {
{ .reg_offset = OMAP_MUX_TERMINATOR },
@ -339,7 +324,6 @@ static void __init omap3_touchbook_init_irq(void)
}
static struct platform_device *omap3_touchbook_devices[] __initdata = {
&omap3_touchbook_lcd_device,
&leds_gpio,
&keys_gpio,
};
@ -376,8 +360,6 @@ early_param("tbr", early_touchbook_revision);
static void __init omap3_touchbook_init(void)
{
omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
omap_board_config = omap3_touchbook_config;
omap_board_config_size = ARRAY_SIZE(omap3_touchbook_config);
pm_power_off = omap3_touchbook_poweroff;

View File

@ -40,7 +40,7 @@
#include <plat/common.h>
#include <plat/usb.h>
#include <plat/mmc.h>
#include <video/omap-panel-generic-dpi.h>
#include <video/omap-panel-dvi.h>
#include "hsmmc.h"
#include "control.h"
@ -455,16 +455,16 @@ static void omap4_panda_disable_dvi(struct omap_dss_device *dssdev)
}
/* Using generic display panel */
static struct panel_generic_dpi_data omap4_dvi_panel = {
.name = "generic",
static struct panel_dvi_platform_data omap4_dvi_panel = {
.platform_enable = omap4_panda_enable_dvi,
.platform_disable = omap4_panda_disable_dvi,
.i2c_bus_num = 3,
};
struct omap_dss_device omap4_panda_dvi_device = {
.type = OMAP_DISPLAY_TYPE_DPI,
.name = "dvi",
.driver_name = "generic_dpi_panel",
.driver_name = "dvi",
.data = &omap4_dvi_panel,
.phy.dpi.data_lines = 24,
.reset_gpio = PANDA_DVI_TFP410_POWER_DOWN_GPIO,

View File

@ -46,6 +46,7 @@
#include <plat/common.h>
#include <video/omapdss.h>
#include <video/omap-panel-generic-dpi.h>
#include <video/omap-panel-dvi.h>
#include <plat/gpmc.h>
#include <mach/hardware.h>
#include <plat/nand.h>
@ -182,16 +183,16 @@ static void overo_panel_disable_dvi(struct omap_dss_device *dssdev)
dvi_enabled = 0;
}
static struct panel_generic_dpi_data dvi_panel = {
.name = "generic",
static struct panel_dvi_platform_data dvi_panel = {
.platform_enable = overo_panel_enable_dvi,
.platform_disable = overo_panel_disable_dvi,
.i2c_bus_num = 3,
};
static struct omap_dss_device overo_dvi_device = {
.name = "dvi",
.type = OMAP_DISPLAY_TYPE_DPI,
.driver_name = "generic_dpi_panel",
.driver_name = "dvi",
.data = &dvi_panel,
.phy.dpi.data_lines = 24,
};

View File

@ -79,29 +79,6 @@ static struct cpuidle_params rx51_cpuidle_params[] = {
{7505 + 15274, 484329, 1},
};
static struct omap_lcd_config rx51_lcd_config = {
.ctrl_name = "internal",
};
static struct omap_fbmem_config rx51_fbmem0_config = {
.size = 752 * 1024,
};
static struct omap_fbmem_config rx51_fbmem1_config = {
.size = 752 * 1024,
};
static struct omap_fbmem_config rx51_fbmem2_config = {
.size = 752 * 1024,
};
static struct omap_board_config_kernel rx51_config[] = {
{ OMAP_TAG_FBMEM, &rx51_fbmem0_config },
{ OMAP_TAG_FBMEM, &rx51_fbmem1_config },
{ OMAP_TAG_FBMEM, &rx51_fbmem2_config },
{ OMAP_TAG_LCD, &rx51_lcd_config },
};
static void __init rx51_init_early(void)
{
struct omap_sdrc_params *sdrc_params;
@ -128,8 +105,6 @@ static struct omap_musb_board_data musb_board_data = {
static void __init rx51_init(void)
{
omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
omap_board_config = rx51_config;
omap_board_config_size = ARRAY_SIZE(rx51_config);
omap3_pm_init_cpuidle(rx51_cpuidle_params);
omap_serial_init();
usb_musb_init(&musb_board_data);

View File

@ -27,6 +27,8 @@
#include <plat/omap_device.h>
#include <plat/omap-pm.h>
#include "control.h"
static struct platform_device omap_display_device = {
.name = "omapdss",
.id = -1,
@ -61,7 +63,7 @@ static const struct omap_dss_hwmod_data omap3_dss_hwmod_data[] __initdata = {
{ "dss_dispc", "omapdss_dispc", -1 },
{ "dss_rfbi", "omapdss_rfbi", -1 },
{ "dss_venc", "omapdss_venc", -1 },
{ "dss_dsi1", "omapdss_dsi1", -1 },
{ "dss_dsi1", "omapdss_dsi", 0 },
};
static const struct omap_dss_hwmod_data omap4_dss_hwmod_data[] __initdata = {
@ -69,11 +71,58 @@ static const struct omap_dss_hwmod_data omap4_dss_hwmod_data[] __initdata = {
{ "dss_dispc", "omapdss_dispc", -1 },
{ "dss_rfbi", "omapdss_rfbi", -1 },
{ "dss_venc", "omapdss_venc", -1 },
{ "dss_dsi1", "omapdss_dsi1", -1 },
{ "dss_dsi2", "omapdss_dsi2", -1 },
{ "dss_dsi1", "omapdss_dsi", 0 },
{ "dss_dsi2", "omapdss_dsi", 1 },
{ "dss_hdmi", "omapdss_hdmi", -1 },
};
static int omap4_dsi_mux_pads(int dsi_id, unsigned lanes)
{
u32 enable_mask, enable_shift;
u32 pipd_mask, pipd_shift;
u32 reg;
if (dsi_id == 0) {
enable_mask = OMAP4_DSI1_LANEENABLE_MASK;
enable_shift = OMAP4_DSI1_LANEENABLE_SHIFT;
pipd_mask = OMAP4_DSI1_PIPD_MASK;
pipd_shift = OMAP4_DSI1_PIPD_SHIFT;
} else if (dsi_id == 1) {
enable_mask = OMAP4_DSI2_LANEENABLE_MASK;
enable_shift = OMAP4_DSI2_LANEENABLE_SHIFT;
pipd_mask = OMAP4_DSI2_PIPD_MASK;
pipd_shift = OMAP4_DSI2_PIPD_SHIFT;
} else {
return -ENODEV;
}
reg = omap4_ctrl_pad_readl(OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_DSIPHY);
reg &= ~enable_mask;
reg &= ~pipd_mask;
reg |= (lanes << enable_shift) & enable_mask;
reg |= (lanes << pipd_shift) & pipd_mask;
omap4_ctrl_pad_writel(reg, OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_DSIPHY);
return 0;
}
static int omap_dsi_enable_pads(int dsi_id, unsigned lane_mask)
{
if (cpu_is_omap44xx())
return omap4_dsi_mux_pads(dsi_id, lane_mask);
return 0;
}
static void omap_dsi_disable_pads(int dsi_id, unsigned lane_mask)
{
if (cpu_is_omap44xx())
omap4_dsi_mux_pads(dsi_id, 0);
}
int __init omap_display_init(struct omap_dss_board_info *board_data)
{
int r = 0;
@ -96,6 +145,11 @@ int __init omap_display_init(struct omap_dss_board_info *board_data)
oh_count = ARRAY_SIZE(omap4_dss_hwmod_data);
}
if (board_data->dsi_enable_pads == NULL)
board_data->dsi_enable_pads = omap_dsi_enable_pads;
if (board_data->dsi_disable_pads == NULL)
board_data->dsi_disable_pads = omap_dsi_disable_pads;
pdata.board_data = board_data;
pdata.board_data->get_context_loss_count =
omap_pm_get_dev_context_loss_count;

View File

@ -99,7 +99,7 @@ static struct regulator_init_data omap3_vdac_idata = {
static struct regulator_consumer_supply omap3_vpll2_supplies[] = {
REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
};
static struct regulator_init_data omap3_vpll2_idata = {
@ -235,6 +235,12 @@ static struct regulator_init_data omap4_vana_idata = {
},
};
static struct regulator_consumer_supply omap4_vcxio_supply[] = {
REGULATOR_SUPPLY("vdds_dsi", "omapdss_dss"),
REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.1"),
};
static struct regulator_init_data omap4_vcxio_idata = {
.constraints = {
.min_uV = 1800000,
@ -243,7 +249,10 @@ static struct regulator_init_data omap4_vcxio_idata = {
| REGULATOR_MODE_STANDBY,
.valid_ops_mask = REGULATOR_CHANGE_MODE
| REGULATOR_CHANGE_STATUS,
.always_on = true,
},
.num_consumer_supplies = ARRAY_SIZE(omap4_vcxio_supply),
.consumer_supplies = omap4_vcxio_supply,
};
static struct regulator_init_data omap4_vusb_idata = {

View File

@ -1597,6 +1597,7 @@ static void __init mackerel_init(void)
sh7372_add_device_to_domain(&sh7372_a4lc, &lcdc_device);
sh7372_add_device_to_domain(&sh7372_a4lc, &hdmi_lcdc_device);
sh7372_add_device_to_domain(&sh7372_a4lc, &meram_device);
sh7372_add_device_to_domain(&sh7372_a4mp, &fsi_device);
sh7372_add_device_to_domain(&sh7372_a3sp, &usbhs0_device);
sh7372_add_device_to_domain(&sh7372_a3sp, &usbhs1_device);

View File

@ -66,8 +66,8 @@ struct fsl_diu_shared_fb {
bool in_use;
};
unsigned int mpc512x_get_pixel_format(unsigned int bits_per_pixel,
int monitor_port)
u32 mpc512x_get_pixel_format(enum fsl_diu_monitor_port port,
unsigned int bits_per_pixel)
{
switch (bits_per_pixel) {
case 32:
@ -80,11 +80,12 @@ unsigned int mpc512x_get_pixel_format(unsigned int bits_per_pixel,
return 0x00000400;
}
void mpc512x_set_gamma_table(int monitor_port, char *gamma_table_base)
void mpc512x_set_gamma_table(enum fsl_diu_monitor_port port,
char *gamma_table_base)
{
}
void mpc512x_set_monitor_port(int monitor_port)
void mpc512x_set_monitor_port(enum fsl_diu_monitor_port port)
{
}
@ -182,14 +183,10 @@ void mpc512x_set_pixel_clock(unsigned int pixclock)
iounmap(ccm);
}
ssize_t mpc512x_show_monitor_port(int monitor_port, char *buf)
enum fsl_diu_monitor_port
mpc512x_valid_monitor_port(enum fsl_diu_monitor_port port)
{
return sprintf(buf, "0 - 5121 LCD\n");
}
int mpc512x_set_sysfs_monitor_port(int val)
{
return 0;
return FSL_DIU_PORT_DVI;
}
static struct fsl_diu_shared_fb __attribute__ ((__aligned__(8))) diu_shared_fb;
@ -256,7 +253,7 @@ void __init mpc512x_init_diu(void)
}
mode = in_be32(&diu_reg->diu_mode);
if (mode != MFB_MODE1) {
if (mode == MFB_MODE0) {
pr_info("%s: DIU OFF\n", __func__);
goto out;
}
@ -332,8 +329,7 @@ void __init mpc512x_setup_diu(void)
diu_ops.set_gamma_table = mpc512x_set_gamma_table;
diu_ops.set_monitor_port = mpc512x_set_monitor_port;
diu_ops.set_pixel_clock = mpc512x_set_pixel_clock;
diu_ops.show_monitor_port = mpc512x_show_monitor_port;
diu_ops.set_sysfs_monitor_port = mpc512x_set_sysfs_monitor_port;
diu_ops.valid_monitor_port = mpc512x_valid_monitor_port;
diu_ops.release_bootmem = mpc512x_release_bootmem;
#endif
}

View File

@ -93,8 +93,8 @@
* The Area Descriptor is a 32-bit value that determine which bits in each
* pixel are to be used for each color.
*/
static unsigned int p1022ds_get_pixel_format(unsigned int bits_per_pixel,
int monitor_port)
static u32 p1022ds_get_pixel_format(enum fsl_diu_monitor_port port,
unsigned int bits_per_pixel)
{
switch (bits_per_pixel) {
case 32:
@ -118,7 +118,8 @@ static unsigned int p1022ds_get_pixel_format(unsigned int bits_per_pixel,
* On some boards, the gamma table for some ports may need to be modified.
* This is not the case on the P1022DS, so we do nothing.
*/
static void p1022ds_set_gamma_table(int monitor_port, char *gamma_table_base)
static void p1022ds_set_gamma_table(enum fsl_diu_monitor_port port,
char *gamma_table_base)
{
}
@ -126,7 +127,7 @@ static void p1022ds_set_gamma_table(int monitor_port, char *gamma_table_base)
* p1022ds_set_monitor_port: switch the output to a different monitor port
*
*/
static void p1022ds_set_monitor_port(int monitor_port)
static void p1022ds_set_monitor_port(enum fsl_diu_monitor_port port)
{
struct device_node *pixis_node;
void __iomem *pixis;
@ -145,19 +146,21 @@ static void p1022ds_set_monitor_port(int monitor_port)
}
brdcfg1 = pixis + 9; /* BRDCFG1 is at offset 9 in the ngPIXIS */
switch (monitor_port) {
case 0: /* DVI */
switch (port) {
case FSL_DIU_PORT_DVI:
printk(KERN_INFO "%s:%u\n", __func__, __LINE__);
/* Enable the DVI port, disable the DFP and the backlight */
clrsetbits_8(brdcfg1, PX_BRDCFG1_DFPEN | PX_BRDCFG1_BACKLIGHT,
PX_BRDCFG1_DVIEN);
break;
case 1: /* Single link LVDS */
case FSL_DIU_PORT_LVDS:
printk(KERN_INFO "%s:%u\n", __func__, __LINE__);
/* Enable the DFP port, disable the DVI and the backlight */
clrsetbits_8(brdcfg1, PX_BRDCFG1_DVIEN | PX_BRDCFG1_BACKLIGHT,
PX_BRDCFG1_DFPEN);
break;
default:
pr_err("p1022ds: unsupported monitor port %i\n", monitor_port);
pr_err("p1022ds: unsupported monitor port %i\n", port);
}
iounmap(pixis);
@ -214,23 +217,18 @@ void p1022ds_set_pixel_clock(unsigned int pixclock)
}
/**
* p1022ds_show_monitor_port: show the current monitor
*
* This function returns a string indicating whether the current monitor is
* set to DVI or LVDS.
* p1022ds_valid_monitor_port: set the monitor port for sysfs
*/
ssize_t p1022ds_show_monitor_port(int monitor_port, char *buf)
enum fsl_diu_monitor_port
p1022ds_valid_monitor_port(enum fsl_diu_monitor_port port)
{
return sprintf(buf, "%c0 - DVI\n%c1 - Single link LVDS\n",
monitor_port == 0 ? '*' : ' ', monitor_port == 1 ? '*' : ' ');
}
/**
* p1022ds_set_sysfs_monitor_port: set the monitor port for sysfs
*/
int p1022ds_set_sysfs_monitor_port(int val)
{
return val < 2 ? val : 0;
switch (port) {
case FSL_DIU_PORT_DVI:
case FSL_DIU_PORT_LVDS:
return port;
default:
return FSL_DIU_PORT_DVI; /* Dual-link LVDS is not supported */
}
}
#endif
@ -305,8 +303,7 @@ static void __init p1022_ds_setup_arch(void)
diu_ops.set_gamma_table = p1022ds_set_gamma_table;
diu_ops.set_monitor_port = p1022ds_set_monitor_port;
diu_ops.set_pixel_clock = p1022ds_set_pixel_clock;
diu_ops.show_monitor_port = p1022ds_show_monitor_port;
diu_ops.set_sysfs_monitor_port = p1022ds_set_sysfs_monitor_port;
diu_ops.valid_monitor_port = p1022ds_valid_monitor_port;
#endif
#ifdef CONFIG_SMP

View File

@ -152,10 +152,10 @@ machine_device_initcall(mpc86xx_hpcd, mpc8610_declare_of_platform_devices);
(c2 << AD_COMP_2_SHIFT) | (c1 << AD_COMP_1_SHIFT) | \
(c0 << AD_COMP_0_SHIFT) | (size << AD_PIXEL_S_SHIFT))
unsigned int mpc8610hpcd_get_pixel_format(unsigned int bits_per_pixel,
int monitor_port)
u32 mpc8610hpcd_get_pixel_format(enum fsl_diu_monitor_port port,
unsigned int bits_per_pixel)
{
static const unsigned long pixelformat[][3] = {
static const u32 pixelformat[][3] = {
{
MAKE_AD(3, 0, 2, 1, 3, 8, 8, 8, 8),
MAKE_AD(4, 2, 0, 1, 2, 8, 8, 8, 0),
@ -170,7 +170,8 @@ unsigned int mpc8610hpcd_get_pixel_format(unsigned int bits_per_pixel,
unsigned int arch_monitor;
/* The DVI port is mis-wired on revision 1 of this board. */
arch_monitor = ((*pixis_arch == 0x01) && (monitor_port == 0))? 0 : 1;
arch_monitor =
((*pixis_arch == 0x01) && (port == FSL_DIU_PORT_DVI)) ? 0 : 1;
switch (bits_per_pixel) {
case 32:
@ -185,10 +186,11 @@ unsigned int mpc8610hpcd_get_pixel_format(unsigned int bits_per_pixel,
}
}
void mpc8610hpcd_set_gamma_table(int monitor_port, char *gamma_table_base)
void mpc8610hpcd_set_gamma_table(enum fsl_diu_monitor_port port,
char *gamma_table_base)
{
int i;
if (monitor_port == 2) { /* dual link LVDS */
if (port == FSL_DIU_PORT_DLVDS) {
for (i = 0; i < 256*3; i++)
gamma_table_base[i] = (gamma_table_base[i] << 2) |
((gamma_table_base[i] >> 6) & 0x03);
@ -199,17 +201,21 @@ void mpc8610hpcd_set_gamma_table(int monitor_port, char *gamma_table_base)
#define PX_BRDCFG0_DLINK (1 << 4)
#define PX_BRDCFG0_DIU_MASK (PX_BRDCFG0_DVISEL | PX_BRDCFG0_DLINK)
void mpc8610hpcd_set_monitor_port(int monitor_port)
void mpc8610hpcd_set_monitor_port(enum fsl_diu_monitor_port port)
{
static const u8 bdcfg[] = {
PX_BRDCFG0_DVISEL | PX_BRDCFG0_DLINK,
PX_BRDCFG0_DLINK,
0,
};
if (monitor_port < 3)
switch (port) {
case FSL_DIU_PORT_DVI:
clrsetbits_8(pixis_bdcfg0, PX_BRDCFG0_DIU_MASK,
bdcfg[monitor_port]);
PX_BRDCFG0_DVISEL | PX_BRDCFG0_DLINK);
break;
case FSL_DIU_PORT_LVDS:
clrsetbits_8(pixis_bdcfg0, PX_BRDCFG0_DIU_MASK,
PX_BRDCFG0_DLINK);
break;
case FSL_DIU_PORT_DLVDS:
clrbits8(pixis_bdcfg0, PX_BRDCFG0_DIU_MASK);
break;
}
}
/**
@ -262,20 +268,10 @@ void mpc8610hpcd_set_pixel_clock(unsigned int pixclock)
iounmap(guts);
}
ssize_t mpc8610hpcd_show_monitor_port(int monitor_port, char *buf)
enum fsl_diu_monitor_port
mpc8610hpcd_valid_monitor_port(enum fsl_diu_monitor_port port)
{
return snprintf(buf, PAGE_SIZE,
"%c0 - DVI\n"
"%c1 - Single link LVDS\n"
"%c2 - Dual link LVDS\n",
monitor_port == 0 ? '*' : ' ',
monitor_port == 1 ? '*' : ' ',
monitor_port == 2 ? '*' : ' ');
}
int mpc8610hpcd_set_sysfs_monitor_port(int val)
{
return val < 3 ? val : 0;
return port;
}
#endif
@ -307,8 +303,7 @@ static void __init mpc86xx_hpcd_setup_arch(void)
diu_ops.set_gamma_table = mpc8610hpcd_set_gamma_table;
diu_ops.set_monitor_port = mpc8610hpcd_set_monitor_port;
diu_ops.set_pixel_clock = mpc8610hpcd_set_pixel_clock;
diu_ops.show_monitor_port = mpc8610hpcd_show_monitor_port;
diu_ops.set_sysfs_monitor_port = mpc8610hpcd_set_sysfs_monitor_port;
diu_ops.valid_monitor_port = mpc8610hpcd_valid_monitor_port;
#endif
pixis_node = of_find_compatible_node(NULL, NULL, "fsl,fpga-pixis");

View File

@ -22,15 +22,24 @@ struct device_node;
extern void fsl_rstcr_restart(char *cmd);
#if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
/* The different ports that the DIU can be connected to */
enum fsl_diu_monitor_port {
FSL_DIU_PORT_DVI, /* DVI */
FSL_DIU_PORT_LVDS, /* Single-link LVDS */
FSL_DIU_PORT_DLVDS /* Dual-link LVDS */
};
struct platform_diu_data_ops {
unsigned int (*get_pixel_format) (unsigned int bits_per_pixel,
int monitor_port);
void (*set_gamma_table) (int monitor_port, char *gamma_table_base);
void (*set_monitor_port) (int monitor_port);
void (*set_pixel_clock) (unsigned int pixclock);
ssize_t (*show_monitor_port) (int monitor_port, char *buf);
int (*set_sysfs_monitor_port) (int val);
void (*release_bootmem) (void);
u32 (*get_pixel_format)(enum fsl_diu_monitor_port port,
unsigned int bpp);
void (*set_gamma_table)(enum fsl_diu_monitor_port port,
char *gamma_table_base);
void (*set_monitor_port)(enum fsl_diu_monitor_port port);
void (*set_pixel_clock)(unsigned int pixclock);
enum fsl_diu_monitor_port (*valid_monitor_port)
(enum fsl_diu_monitor_port port);
void (*release_bootmem)(void);
};
extern struct platform_diu_data_ops diu_ops;

View File

@ -400,7 +400,6 @@ static int omapvid_setup_overlay(struct omap_vout_device *vout,
ovl->get_overlay_info(ovl, &info);
info.paddr = addr;
info.vaddr = NULL;
info.width = cropwidth;
info.height = cropheight;
info.color_mode = vout->dss_mode;
@ -1165,12 +1164,17 @@ static int vidioc_try_fmt_vid_overlay(struct file *file, void *fh,
{
int ret = 0;
struct omap_vout_device *vout = fh;
struct omap_overlay *ovl;
struct omapvideo_info *ovid;
struct v4l2_window *win = &f->fmt.win;
ovid = &vout->vid_info;
ovl = ovid->overlays[0];
ret = omap_vout_try_window(&vout->fbuf, win);
if (!ret) {
if (vout->vid == OMAP_VIDEO1)
if ((ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0)
win->global_alpha = 255;
else
win->global_alpha = f->fmt.win.global_alpha;
@ -1194,8 +1198,8 @@ static int vidioc_s_fmt_vid_overlay(struct file *file, void *fh,
ret = omap_vout_new_window(&vout->crop, &vout->win, &vout->fbuf, win);
if (!ret) {
/* Video1 plane does not support global alpha */
if (ovl->id == OMAP_DSS_VIDEO1)
/* Video1 plane does not support global alpha on OMAP3 */
if ((ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0)
vout->win.global_alpha = 255;
else
vout->win.global_alpha = f->fmt.win.global_alpha;
@ -1788,7 +1792,9 @@ static int vidioc_s_fbuf(struct file *file, void *fh,
if (ovl->manager && ovl->manager->get_manager_info &&
ovl->manager->set_manager_info) {
ovl->manager->get_manager_info(ovl->manager, &info);
info.alpha_enabled = enable;
/* enable this only if there is no zorder cap */
if ((ovl->caps & OMAP_DSS_OVL_CAP_ZORDER) == 0)
info.partial_alpha_enabled = enable;
if (ovl->manager->set_manager_info(ovl->manager, &info))
return -EINVAL;
}
@ -1820,7 +1826,7 @@ static int vidioc_g_fbuf(struct file *file, void *fh,
}
if (ovl->manager && ovl->manager->get_manager_info) {
ovl->manager->get_manager_info(ovl->manager, &info);
if (info.alpha_enabled)
if (info.partial_alpha_enabled)
a->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
}

View File

@ -1300,27 +1300,17 @@ static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
return 0;
}
static int XGIfb_pan_var(struct xgifb_video_info *xgifb_info,
struct fb_var_screeninfo *var)
static int XGIfb_pan_var(struct fb_var_screeninfo *var, struct fb_info *info)
{
struct xgifb_video_info *xgifb_info = info->par;
unsigned int base;
/* printk("Inside pan_var"); */
if (var->xoffset > (var->xres_virtual - var->xres)) {
/* printk("Pan: xo: %d xv %d xr %d\n",
var->xoffset, var->xres_virtual, var->xres); */
return -EINVAL;
}
if (var->yoffset > (var->yres_virtual - var->yres)) {
/* printk("Pan: yo: %d yv %d yr %d\n",
var->yoffset, var->yres_virtual, var->yres); */
return -EINVAL;
}
base = var->yoffset * var->xres_virtual + var->xoffset;
base = var->yoffset * info->var.xres_virtual + var->xoffset;
/* calculate base bpp dep. */
switch (var->bits_per_pixel) {
switch (info->var.bits_per_pixel) {
case 16:
base >>= 1;
break;
@ -1615,13 +1605,12 @@ static int XGIfb_pan_display(struct fb_var_screeninfo *var,
struct fb_info *info)
{
int err;
struct xgifb_video_info *xgifb_info = info->par;
/* printk("\nInside pan_display:\n"); */
if (var->xoffset > (var->xres_virtual - var->xres))
if (var->xoffset > (info->var.xres_virtual - info->var.xres))
return -EINVAL;
if (var->yoffset > (var->yres_virtual - var->yres))
if (var->yoffset > (info->var.yres_virtual - info->var.yres))
return -EINVAL;
if (var->vmode & FB_VMODE_YWRAP) {
@ -1634,7 +1623,7 @@ static int XGIfb_pan_display(struct fb_var_screeninfo *var,
> info->var.yres_virtual)
return -EINVAL;
}
err = XGIfb_pan_var(xgifb_info, var);
err = XGIfb_pan_var(var, info);
if (err < 0)
return err;

View File

@ -378,8 +378,8 @@ static int mc68x328fb_pan_display(struct fb_var_screeninfo *var,
|| var->xoffset)
return -EINVAL;
} else {
if (var->xoffset + var->xres > info->var.xres_virtual ||
var->yoffset + var->yres > info->var.yres_virtual)
if (var->xoffset + info->var.xres > info->var.xres_virtual ||
var->yoffset + info->var.yres > info->var.yres_virtual)
return -EINVAL;
}
info->var.xoffset = var->xoffset;

View File

@ -259,6 +259,15 @@ config FB_TILEBLITTING
comment "Frame buffer hardware drivers"
depends on FB
config FB_GRVGA
tristate "Aeroflex Gaisler framebuffer support"
depends on FB && SPARC
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
---help---
This enables support for the SVGACTRL framebuffer in the GRLIB IP library from Aeroflex Gaisler.
config FB_CIRRUS
tristate "Cirrus Logic support"
depends on FB && (ZORRO || PCI)
@ -1756,9 +1765,10 @@ config FB_AU1100
config FB_AU1200
bool "Au1200 LCD Driver"
depends on (FB = y) && MIPS && SOC_AU1200
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select FB_SYS_FILLRECT
select FB_SYS_COPYAREA
select FB_SYS_IMAGEBLIT
select FB_SYS_FOPS
help
This is the framebuffer driver for the AMD Au1200 SOC. It can drive
various panels and CRTs by passing in kernel cmd line option
@ -2027,7 +2037,7 @@ config FB_TMIO_ACCELL
config FB_S3C
tristate "Samsung S3C framebuffer support"
depends on FB && S3C_DEV_FB
depends on FB && (S3C_DEV_FB || S5P_DEV_FIMD0)
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
@ -2110,6 +2120,22 @@ config FB_SM501
If unsure, say N.
config FB_SMSCUFX
tristate "SMSC UFX6000/7000 USB Framebuffer support"
depends on FB && USB
select FB_MODE_HELPERS
select FB_SYS_FILLRECT
select FB_SYS_COPYAREA
select FB_SYS_IMAGEBLIT
select FB_SYS_FOPS
select FB_DEFERRED_IO
---help---
This is a kernel framebuffer driver for SMSC UFX USB devices.
Supports fbdev clients like xf86-video-fbdev, kdrive, fbi, and
mplayer -vo fbdev. Supports both UFX6000 (USB 2.0) and UFX7000
(USB 3.0) devices.
To compile as a module, choose M here: the module name is smscufx.
config FB_UDL
tristate "Displaylink USB Framebuffer support"
depends on FB && USB

View File

@ -33,6 +33,7 @@ obj-$(CONFIG_FB_AMIGA) += amifb.o c2p_planar.o
obj-$(CONFIG_FB_ARC) += arcfb.o
obj-$(CONFIG_FB_CLPS711X) += clps711xfb.o
obj-$(CONFIG_FB_CYBER2000) += cyber2000fb.o
obj-$(CONFIG_FB_GRVGA) += grvga.o
obj-$(CONFIG_FB_PM2) += pm2fb.o
obj-$(CONFIG_FB_PM3) += pm3fb.o
@ -127,6 +128,7 @@ obj-$(CONFIG_FB_IBM_GXT4500) += gxt4500.o
obj-$(CONFIG_FB_PS3) += ps3fb.o
obj-$(CONFIG_FB_SM501) += sm501fb.o
obj-$(CONFIG_FB_UDL) += udlfb.o
obj-$(CONFIG_FB_SMSCUFX) += smscufx.o
obj-$(CONFIG_FB_XILINX) += xilinxfb.o
obj-$(CONFIG_SH_MIPI_DSI) += sh_mipi_dsi.o
obj-$(CONFIG_FB_SH_MOBILE_HDMI) += sh_mobile_hdmi.o

View File

@ -850,9 +850,10 @@ acornfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
u_int y_bottom = var->yoffset;
if (!(var->vmode & FB_VMODE_YWRAP))
y_bottom += var->yres;
y_bottom += info->var.yres;
BUG_ON(y_bottom > var->yres_virtual);
if (y_bottom > info->var.yres_virtual)
return -EINVAL;
acornfb_update_dma(info, var);

View File

@ -908,13 +908,14 @@ static int arkfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info
unsigned int offset;
/* Calculate the offset */
if (var->bits_per_pixel == 0) {
offset = (var->yoffset / 16) * (var->xres_virtual / 2) + (var->xoffset / 2);
if (info->var.bits_per_pixel == 0) {
offset = (var->yoffset / 16) * (info->var.xres_virtual / 2)
+ (var->xoffset / 2);
offset = offset >> 2;
} else {
offset = (var->yoffset * info->fix.line_length) +
(var->xoffset * var->bits_per_pixel / 8);
offset = offset >> ((var->bits_per_pixel == 4) ? 2 : 3);
(var->xoffset * info->var.bits_per_pixel / 8);
offset = offset >> ((info->var.bits_per_pixel == 4) ? 2 : 3);
}
/* Set the offset */

View File

@ -39,7 +39,8 @@
| FBINFO_HWACCEL_YPAN)
static inline void atmel_lcdfb_update_dma2d(struct atmel_lcdfb_info *sinfo,
struct fb_var_screeninfo *var)
struct fb_var_screeninfo *var,
struct fb_info *info)
{
}
@ -50,14 +51,16 @@ static inline void atmel_lcdfb_update_dma2d(struct atmel_lcdfb_info *sinfo,
| FBINFO_HWACCEL_YPAN)
static void atmel_lcdfb_update_dma2d(struct atmel_lcdfb_info *sinfo,
struct fb_var_screeninfo *var)
struct fb_var_screeninfo *var,
struct fb_info *info)
{
u32 dma2dcfg;
u32 pixeloff;
pixeloff = (var->xoffset * var->bits_per_pixel) & 0x1f;
pixeloff = (var->xoffset * info->var.bits_per_pixel) & 0x1f;
dma2dcfg = ((var->xres_virtual - var->xres) * var->bits_per_pixel) / 8;
dma2dcfg = (info->var.xres_virtual - info->var.xres)
* info->var.bits_per_pixel / 8;
dma2dcfg |= pixeloff << ATMEL_LCDC_PIXELOFF_OFFSET;
lcdc_writel(sinfo, ATMEL_LCDC_DMA2DCFG, dma2dcfg);
@ -249,14 +252,14 @@ static void atmel_lcdfb_update_dma(struct fb_info *info,
unsigned long dma_addr;
dma_addr = (fix->smem_start + var->yoffset * fix->line_length
+ var->xoffset * var->bits_per_pixel / 8);
+ var->xoffset * info->var.bits_per_pixel / 8);
dma_addr &= ~3UL;
/* Set framebuffer DMA base address and pixel offset */
lcdc_writel(sinfo, ATMEL_LCDC_DMABADDR1, dma_addr);
atmel_lcdfb_update_dma2d(sinfo, var);
atmel_lcdfb_update_dma2d(sinfo, var, info);
}
static inline void atmel_lcdfb_free_video_memory(struct atmel_lcdfb_info *sinfo)

View File

@ -845,16 +845,16 @@ static int radeonfb_pan_display (struct fb_var_screeninfo *var,
{
struct radeonfb_info *rinfo = info->par;
if ((var->xoffset + var->xres > var->xres_virtual)
|| (var->yoffset + var->yres > var->yres_virtual))
return -EINVAL;
if ((var->xoffset + info->var.xres > info->var.xres_virtual)
|| (var->yoffset + info->var.yres > info->var.yres_virtual))
return -EINVAL;
if (rinfo->asleep)
return 0;
radeon_fifo_wait(2);
OUTREG(CRTC_OFFSET, ((var->yoffset * var->xres_virtual + var->xoffset)
* var->bits_per_pixel / 8) & ~7);
OUTREG(CRTC_OFFSET, (var->yoffset * info->fix.line_length +
var->xoffset * info->var.bits_per_pixel / 8) & ~7);
return 0;
}

View File

@ -110,12 +110,6 @@ static struct fb_var_screeninfo au1100fb_var __devinitdata = {
.vmode = FB_VMODE_NONINTERLACED,
};
static struct au1100fb_drv_info drv_info;
static int nocursor = 0;
module_param(nocursor, int, 0644);
MODULE_PARM_DESC(nocursor, "cursor enable/disable");
/* fb_blank
* Blank the screen. Depending on the mode, the screen will be
* activated with the backlight color, or desactivated
@ -132,7 +126,7 @@ static int au1100fb_fb_blank(int blank_mode, struct fb_info *fbi)
/* Turn on panel */
fbdev->regs->lcd_control |= LCD_CONTROL_GO;
#ifdef CONFIG_MIPS_PB1100
if (drv_info.panel_idx == 1) {
if (fbdev->panel_idx == 1) {
au_writew(au_readw(PB1100_G_CONTROL)
| (PB1100_G_CONTROL_BL | PB1100_G_CONTROL_VDD),
PB1100_G_CONTROL);
@ -147,7 +141,7 @@ static int au1100fb_fb_blank(int blank_mode, struct fb_info *fbi)
/* Turn off panel */
fbdev->regs->lcd_control &= ~LCD_CONTROL_GO;
#ifdef CONFIG_MIPS_PB1100
if (drv_info.panel_idx == 1) {
if (fbdev->panel_idx == 1) {
au_writew(au_readw(PB1100_G_CONTROL)
& ~(PB1100_G_CONTROL_BL | PB1100_G_CONTROL_VDD),
PB1100_G_CONTROL);
@ -428,17 +422,6 @@ int au1100fb_fb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
return 0;
}
/* fb_cursor
* Used to disable cursor drawing...
*/
int au1100fb_fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
{
if (nocursor)
return 0;
else
return -EINVAL; /* just to force soft_cursor() call */
}
static struct fb_ops au1100fb_ops =
{
.owner = THIS_MODULE,
@ -450,13 +433,53 @@ static struct fb_ops au1100fb_ops =
.fb_imageblit = cfb_imageblit,
.fb_rotate = au1100fb_fb_rotate,
.fb_mmap = au1100fb_fb_mmap,
.fb_cursor = au1100fb_fb_cursor,
};
/*-------------------------------------------------------------------------*/
/* AU1100 LCD controller device driver */
static int au1100fb_setup(struct au1100fb_device *fbdev)
{
char *this_opt, *options;
int num_panels = ARRAY_SIZE(known_lcd_panels);
if (num_panels <= 0) {
print_err("No LCD panels supported by driver!");
return -ENODEV;
}
if (fb_get_options(DRIVER_NAME, &options))
return -ENODEV;
if (!options)
return -ENODEV;
while ((this_opt = strsep(&options, ",")) != NULL) {
/* Panel option */
if (!strncmp(this_opt, "panel:", 6)) {
int i;
this_opt += 6;
for (i = 0; i < num_panels; i++) {
if (!strncmp(this_opt, known_lcd_panels[i].name,
strlen(this_opt))) {
fbdev->panel = &known_lcd_panels[i];
fbdev->panel_idx = i;
break;
}
}
if (i >= num_panels) {
print_warn("Panel '%s' not supported!", this_opt);
return -ENODEV;
}
}
/* Unsupported option */
else
print_warn("Unsupported option \"%s\"", this_opt);
}
print_info("Panel=%s", fbdev->panel->name);
return 0;
}
static int __devinit au1100fb_drv_probe(struct platform_device *dev)
{
@ -465,22 +488,21 @@ static int __devinit au1100fb_drv_probe(struct platform_device *dev)
unsigned long page;
u32 sys_clksrc;
if (!dev)
return -EINVAL;
/* Allocate new device private */
if (!(fbdev = kzalloc(sizeof(struct au1100fb_device), GFP_KERNEL))) {
fbdev = kzalloc(sizeof(struct au1100fb_device), GFP_KERNEL);
if (!fbdev) {
print_err("fail to allocate device private record");
return -ENOMEM;
}
fbdev->panel = &known_lcd_panels[drv_info.panel_idx];
if (au1100fb_setup(fbdev))
goto failed;
platform_set_drvdata(dev, (void *)fbdev);
/* Allocate region for our registers and map them */
if (!(regs_res = platform_get_resource(to_platform_device(dev),
IORESOURCE_MEM, 0))) {
regs_res = platform_get_resource(dev, IORESOURCE_MEM, 0);
if (!regs_res) {
print_err("fail to retrieve registers resource");
return -EFAULT;
}
@ -500,13 +522,11 @@ static int __devinit au1100fb_drv_probe(struct platform_device *dev)
print_dbg("Register memory map at %p", fbdev->regs);
print_dbg("phys=0x%08x, size=%d", fbdev->regs_phys, fbdev->regs_len);
/* Allocate the framebuffer to the maximum screen size * nbr of video buffers */
fbdev->fb_len = fbdev->panel->xres * fbdev->panel->yres *
(fbdev->panel->bpp >> 3) * AU1100FB_NBR_VIDEO_BUFFERS;
fbdev->fb_mem = dma_alloc_coherent(dev, PAGE_ALIGN(fbdev->fb_len),
fbdev->fb_mem = dma_alloc_coherent(&dev->dev, PAGE_ALIGN(fbdev->fb_len),
&fbdev->fb_phys, GFP_KERNEL);
if (!fbdev->fb_mem) {
print_err("fail to allocate frambuffer (size: %dK))",
@ -525,7 +545,7 @@ static int __devinit au1100fb_drv_probe(struct platform_device *dev)
page < PAGE_ALIGN((unsigned long)fbdev->fb_mem + fbdev->fb_len);
page += PAGE_SIZE) {
#if CONFIG_DMA_NONCOHERENT
SetPageReserved(virt_to_page(CAC_ADDR(page)));
SetPageReserved(virt_to_page(CAC_ADDR((void *)page)));
#else
SetPageReserved(virt_to_page(page));
#endif
@ -578,7 +598,8 @@ failed:
release_mem_region(fbdev->regs_phys, fbdev->regs_len);
}
if (fbdev->fb_mem) {
dma_free_noncoherent(dev, fbdev->fb_len, fbdev->fb_mem, fbdev->fb_phys);
dma_free_noncoherent(&dev->dev, fbdev->fb_len, fbdev->fb_mem,
fbdev->fb_phys);
}
if (fbdev->info.cmap.len != 0) {
fb_dealloc_cmap(&fbdev->info.cmap);
@ -608,7 +629,8 @@ int au1100fb_drv_remove(struct platform_device *dev)
release_mem_region(fbdev->regs_phys, fbdev->regs_len);
dma_free_coherent(dev, PAGE_ALIGN(fbdev->fb_len), fbdev->fb_mem, fbdev->fb_phys);
dma_free_coherent(&dev->dev, PAGE_ALIGN(fbdev->fb_len), fbdev->fb_mem,
fbdev->fb_phys);
fb_dealloc_cmap(&fbdev->info.cmap);
kfree(fbdev->info.pseudo_palette);
@ -675,101 +697,18 @@ static struct platform_driver au1100fb_driver = {
.resume = au1100fb_drv_resume,
};
/*-------------------------------------------------------------------------*/
/* Kernel driver */
int au1100fb_setup(char *options)
static int __init au1100fb_load(void)
{
char* this_opt;
int num_panels = ARRAY_SIZE(known_lcd_panels);
char* mode = NULL;
int panel_idx = 0;
if (num_panels <= 0) {
print_err("No LCD panels supported by driver!");
return -EFAULT;
}
if (options) {
while ((this_opt = strsep(&options,",")) != NULL) {
/* Panel option */
if (!strncmp(this_opt, "panel:", 6)) {
int i;
this_opt += 6;
for (i = 0; i < num_panels; i++) {
if (!strncmp(this_opt,
known_lcd_panels[i].name,
strlen(this_opt))) {
panel_idx = i;
break;
}
}
if (i >= num_panels) {
print_warn("Panel %s not supported!", this_opt);
}
}
if (!strncmp(this_opt, "nocursor", 8)) {
this_opt += 8;
nocursor = 1;
print_info("Cursor disabled");
}
/* Mode option (only option that start with digit) */
else if (isdigit(this_opt[0])) {
mode = kstrdup(this_opt, GFP_KERNEL);
if (!mode) {
print_err("memory allocation failed");
return -ENOMEM;
}
}
/* Unsupported option */
else {
print_warn("Unsupported option \"%s\"", this_opt);
}
}
}
drv_info.panel_idx = panel_idx;
drv_info.opt_mode = mode;
print_info("Panel=%s Mode=%s",
known_lcd_panels[drv_info.panel_idx].name,
drv_info.opt_mode ? drv_info.opt_mode : "default");
return 0;
}
int __init au1100fb_init(void)
{
char* options;
int ret;
print_info("" DRIVER_DESC "");
memset(&drv_info, 0, sizeof(drv_info));
if (fb_get_options(DRIVER_NAME, &options))
return -ENODEV;
/* Setup driver with options */
ret = au1100fb_setup(options);
if (ret < 0) {
print_err("Fail to setup driver");
return ret;
}
return platform_driver_register(&au1100fb_driver);
}
void __exit au1100fb_cleanup(void)
static void __exit au1100fb_unload(void)
{
platform_driver_unregister(&au1100fb_driver);
kfree(drv_info.opt_mode);
}
module_init(au1100fb_init);
module_exit(au1100fb_cleanup);
module_init(au1100fb_load);
module_exit(au1100fb_unload);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");

View File

@ -108,6 +108,7 @@ struct au1100fb_device {
unsigned char* fb_mem; /* FrameBuffer memory map */
size_t fb_len;
dma_addr_t fb_phys;
int panel_idx;
};
/********************************************************************/
@ -364,11 +365,6 @@ static struct au1100fb_panel known_lcd_panels[] =
},
};
struct au1100fb_drv_info {
int panel_idx;
char *opt_mode;
};
/********************************************************************/
/* Inline helpers */

View File

@ -46,18 +46,10 @@
#include <asm/mach-au1x00/au1000.h>
#include "au1200fb.h"
#ifdef CONFIG_PM
#include <asm/mach-au1x00/au1xxx_pm.h>
#endif
#ifndef CONFIG_FB_AU1200_DEVS
#define CONFIG_FB_AU1200_DEVS 4
#endif
#define DRIVER_NAME "au1200fb"
#define DRIVER_DESC "LCD controller driver for AU1200 processors"
#define DEBUG 1
#define DEBUG 0
#define print_err(f, arg...) printk(KERN_ERR DRIVER_NAME ": " f "\n", ## arg)
#define print_warn(f, arg...) printk(KERN_WARNING DRIVER_NAME ": " f "\n", ## arg)
@ -150,7 +142,7 @@ struct au1200_lcd_iodata_t {
/* Private, per-framebuffer management information (independent of the panel itself) */
struct au1200fb_device {
struct fb_info fb_info; /* FB driver info record */
struct fb_info *fb_info; /* FB driver info record */
int plane;
unsigned char* fb_mem; /* FrameBuffer memory map */
@ -158,7 +150,6 @@ struct au1200fb_device {
dma_addr_t fb_phys;
};
static struct au1200fb_device _au1200fb_devices[CONFIG_FB_AU1200_DEVS];
/********************************************************************/
/* LCD controller restrictions */
@ -171,10 +162,18 @@ static struct au1200fb_device _au1200fb_devices[CONFIG_FB_AU1200_DEVS];
/* Default number of visible screen buffer to allocate */
#define AU1200FB_NBR_VIDEO_BUFFERS 1
/* Default maximum number of fb devices to create */
#define MAX_DEVICE_COUNT 4
/* Default window configuration entry to use (see windows[]) */
#define DEFAULT_WINDOW_INDEX 2
/********************************************************************/
static struct fb_info *_au1200fb_infos[MAX_DEVICE_COUNT];
static struct au1200_lcd *lcd = (struct au1200_lcd *) AU1200_LCD_ADDR;
static int window_index = 2; /* default is zero */
static int device_count = MAX_DEVICE_COUNT;
static int window_index = DEFAULT_WINDOW_INDEX; /* default is zero */
static int panel_index = 2; /* default is zero */
static struct window_settings *win;
static struct panel_settings *panel;
@ -205,12 +204,6 @@ struct window_settings {
extern int board_au1200fb_panel_init (void);
extern int board_au1200fb_panel_shutdown (void);
#ifdef CONFIG_PM
int au1200fb_pm_callback(au1xxx_power_dev_t *dev,
au1xxx_request_t request, void *data);
au1xxx_power_dev_t *LCD_pm_dev;
#endif
/*
* Default window configurations
*/
@ -652,25 +645,6 @@ static struct panel_settings known_lcd_panels[] =
/********************************************************************/
#ifdef CONFIG_PM
static int set_brightness(unsigned int brightness)
{
unsigned int hi1, divider;
/* limit brightness pwm duty to >= 30/1600 */
if (brightness < 30) {
brightness = 30;
}
divider = (lcd->pwmdiv & 0x3FFFF) + 1;
hi1 = (lcd->pwmhi >> 16) + 1;
hi1 = (((brightness & 0xFF) + 1) * divider >> 8);
lcd->pwmhi &= 0xFFFF;
lcd->pwmhi |= (hi1 << 16);
return brightness;
}
#endif /* CONFIG_PM */
static int winbpp (unsigned int winctrl1)
{
int bits = 0;
@ -712,8 +686,8 @@ static int fbinfo2index (struct fb_info *fb_info)
{
int i;
for (i = 0; i < CONFIG_FB_AU1200_DEVS; ++i) {
if (fb_info == (struct fb_info *)(&_au1200fb_devices[i].fb_info))
for (i = 0; i < device_count; ++i) {
if (fb_info == _au1200fb_infos[i])
return i;
}
printk("au1200fb: ERROR: fbinfo2index failed!\n");
@ -962,7 +936,7 @@ static void au1200_setmode(struct au1200fb_device *fbdev)
lcd->window[plane].winctrl2 = ( 0
| LCD_WINCTRL2_CKMODE_00
| LCD_WINCTRL2_DBM
| LCD_WINCTRL2_BX_N( fbdev->fb_info.fix.line_length)
| LCD_WINCTRL2_BX_N(fbdev->fb_info->fix.line_length)
| LCD_WINCTRL2_SCX_1
| LCD_WINCTRL2_SCY_1
) ;
@ -1050,7 +1024,7 @@ static void au1200fb_update_fbinfo(struct fb_info *fbi)
static int au1200fb_fb_check_var(struct fb_var_screeninfo *var,
struct fb_info *fbi)
{
struct au1200fb_device *fbdev = (struct au1200fb_device *)fbi;
struct au1200fb_device *fbdev = fbi->par;
u32 pixclock;
int screen_size, plane;
@ -1142,7 +1116,7 @@ static int au1200fb_fb_check_var(struct fb_var_screeninfo *var,
*/
static int au1200fb_fb_set_par(struct fb_info *fbi)
{
struct au1200fb_device *fbdev = (struct au1200fb_device *)fbi;
struct au1200fb_device *fbdev = fbi->par;
au1200fb_update_fbinfo(fbi);
au1200_setmode(fbdev);
@ -1246,11 +1220,7 @@ static int au1200fb_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
{
unsigned int len;
unsigned long start=0, off;
struct au1200fb_device *fbdev = (struct au1200fb_device *) info;
#ifdef CONFIG_PM
au1xxx_pm_access(LCD_pm_dev);
#endif
struct au1200fb_device *fbdev = info->par;
if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) {
return -EINVAL;
@ -1461,10 +1431,6 @@ static int au1200fb_ioctl(struct fb_info *info, unsigned int cmd,
int plane;
int val;
#ifdef CONFIG_PM
au1xxx_pm_access(LCD_pm_dev);
#endif
plane = fbinfo2index(info);
print_dbg("au1200fb: ioctl %d on plane %d\n", cmd, plane);
@ -1536,9 +1502,11 @@ static struct fb_ops au1200fb_fb_ops = {
.fb_set_par = au1200fb_fb_set_par,
.fb_setcolreg = au1200fb_fb_setcolreg,
.fb_blank = au1200fb_fb_blank,
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
.fb_fillrect = sys_fillrect,
.fb_copyarea = sys_copyarea,
.fb_imageblit = sys_imageblit,
.fb_read = fb_sys_read,
.fb_write = fb_sys_write,
.fb_sync = NULL,
.fb_ioctl = au1200fb_ioctl,
.fb_mmap = au1200fb_fb_mmap,
@ -1561,10 +1529,9 @@ static irqreturn_t au1200fb_handle_irq(int irq, void* dev_id)
static int au1200fb_init_fbinfo(struct au1200fb_device *fbdev)
{
struct fb_info *fbi = &fbdev->fb_info;
struct fb_info *fbi = fbdev->fb_info;
int bpp;
memset(fbi, 0, sizeof(struct fb_info));
fbi->fbops = &au1200fb_fb_ops;
bpp = winbpp(win->w[fbdev->plane].mode_winctrl1);
@ -1623,24 +1590,36 @@ static int au1200fb_init_fbinfo(struct au1200fb_device *fbdev)
/* AU1200 LCD controller device driver */
static int au1200fb_drv_probe(struct platform_device *dev)
static int __devinit au1200fb_drv_probe(struct platform_device *dev)
{
struct au1200fb_device *fbdev;
struct fb_info *fbi = NULL;
unsigned long page;
int bpp, plane, ret;
int bpp, plane, ret, irq;
if (!dev)
return -EINVAL;
/* shut gcc up */
ret = 0;
fbdev = NULL;
for (plane = 0; plane < CONFIG_FB_AU1200_DEVS; ++plane) {
/* Kickstart the panel */
au1200_setpanel(panel);
for (plane = 0; plane < device_count; ++plane) {
bpp = winbpp(win->w[plane].mode_winctrl1);
if (win->w[plane].xres == 0)
win->w[plane].xres = panel->Xres;
if (win->w[plane].yres == 0)
win->w[plane].yres = panel->Yres;
fbdev = &_au1200fb_devices[plane];
memset(fbdev, 0, sizeof(struct au1200fb_device));
fbi = framebuffer_alloc(sizeof(struct au1200fb_device),
&dev->dev);
if (!fbi)
goto failed;
_au1200fb_infos[plane] = fbi;
fbdev = fbi->par;
fbdev->fb_info = fbi;
fbdev->plane = plane;
/* Allocate the framebuffer to the maximum screen size */
@ -1673,30 +1652,31 @@ static int au1200fb_drv_probe(struct platform_device *dev)
goto failed;
/* Register new framebuffer */
if ((ret = register_framebuffer(&fbdev->fb_info)) < 0) {
ret = register_framebuffer(fbi);
if (ret < 0) {
print_err("cannot register new framebuffer");
goto failed;
}
au1200fb_fb_set_par(&fbdev->fb_info);
au1200fb_fb_set_par(fbi);
#if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO)
if (plane == 0)
if (fb_prepare_logo(&fbdev->fb_info, FB_ROTATE_UR)) {
if (fb_prepare_logo(fbi, FB_ROTATE_UR)) {
/* Start display and show logo on boot */
fb_set_cmap(&fbdev->fb_info.cmap,
&fbdev->fb_info);
fb_show_logo(&fbdev->fb_info, FB_ROTATE_UR);
fb_set_cmap(&fbi->cmap, fbi);
fb_show_logo(fbi, FB_ROTATE_UR);
}
#endif
}
/* Now hook interrupt too */
if ((ret = request_irq(AU1200_LCD_INT, au1200fb_handle_irq,
IRQF_DISABLED | IRQF_SHARED, "lcd", (void *)dev)) < 0) {
irq = platform_get_irq(dev, 0);
ret = request_irq(irq, au1200fb_handle_irq,
IRQF_SHARED, "lcd", (void *)dev);
if (ret) {
print_err("fail to request interrupt line %d (err: %d)",
AU1200_LCD_INT, ret);
irq, ret);
goto failed;
}
@ -1705,84 +1685,108 @@ static int au1200fb_drv_probe(struct platform_device *dev)
failed:
/* NOTE: This only does the current plane/window that failed; others are still active */
if (fbdev->fb_mem)
dma_free_noncoherent(dev, PAGE_ALIGN(fbdev->fb_len),
dma_free_noncoherent(&dev->dev, PAGE_ALIGN(fbdev->fb_len),
fbdev->fb_mem, fbdev->fb_phys);
if (fbdev->fb_info.cmap.len != 0)
fb_dealloc_cmap(&fbdev->fb_info.cmap);
if (fbdev->fb_info.pseudo_palette)
kfree(fbdev->fb_info.pseudo_palette);
if (fbi) {
if (fbi->cmap.len != 0)
fb_dealloc_cmap(&fbi->cmap);
kfree(fbi->pseudo_palette);
}
if (plane == 0)
free_irq(AU1200_LCD_INT, (void*)dev);
return ret;
}
static int au1200fb_drv_remove(struct platform_device *dev)
static int __devexit au1200fb_drv_remove(struct platform_device *dev)
{
struct au1200fb_device *fbdev;
struct fb_info *fbi;
int plane;
if (!dev)
return -ENODEV;
/* Turn off the panel */
au1200_setpanel(NULL);
for (plane = 0; plane < CONFIG_FB_AU1200_DEVS; ++plane)
{
fbdev = &_au1200fb_devices[plane];
for (plane = 0; plane < device_count; ++plane) {
fbi = _au1200fb_infos[plane];
fbdev = fbi->par;
/* Clean up all probe data */
unregister_framebuffer(&fbdev->fb_info);
unregister_framebuffer(fbi);
if (fbdev->fb_mem)
dma_free_noncoherent(&dev->dev,
PAGE_ALIGN(fbdev->fb_len),
fbdev->fb_mem, fbdev->fb_phys);
if (fbdev->fb_info.cmap.len != 0)
fb_dealloc_cmap(&fbdev->fb_info.cmap);
if (fbdev->fb_info.pseudo_palette)
kfree(fbdev->fb_info.pseudo_palette);
if (fbi->cmap.len != 0)
fb_dealloc_cmap(&fbi->cmap);
kfree(fbi->pseudo_palette);
framebuffer_release(fbi);
_au1200fb_infos[plane] = NULL;
}
free_irq(AU1200_LCD_INT, (void *)dev);
free_irq(platform_get_irq(dev, 0), (void *)dev);
return 0;
}
#ifdef CONFIG_PM
static int au1200fb_drv_suspend(struct platform_device *dev, u32 state)
static int au1200fb_drv_suspend(struct device *dev)
{
/* TODO */
au1200_setpanel(NULL);
lcd->outmask = 0;
au_sync();
return 0;
}
static int au1200fb_drv_resume(struct platform_device *dev)
static int au1200fb_drv_resume(struct device *dev)
{
/* TODO */
struct fb_info *fbi;
int i;
/* Kickstart the panel */
au1200_setpanel(panel);
for (i = 0; i < device_count; i++) {
fbi = _au1200fb_infos[i];
au1200fb_fb_set_par(fbi);
}
return 0;
}
static const struct dev_pm_ops au1200fb_pmops = {
.suspend = au1200fb_drv_suspend,
.resume = au1200fb_drv_resume,
.freeze = au1200fb_drv_suspend,
.thaw = au1200fb_drv_resume,
};
#define AU1200FB_PMOPS (&au1200fb_pmops)
#else
#define AU1200FB_PMOPS NULL
#endif /* CONFIG_PM */
static struct platform_driver au1200fb_driver = {
.driver = {
.name = "au1200-lcd",
.owner = THIS_MODULE,
.name = "au1200-lcd",
.owner = THIS_MODULE,
.pm = AU1200FB_PMOPS,
},
.probe = au1200fb_drv_probe,
.remove = au1200fb_drv_remove,
#ifdef CONFIG_PM
.suspend = au1200fb_drv_suspend,
.resume = au1200fb_drv_resume,
#endif
.remove = __devexit_p(au1200fb_drv_remove),
};
/*-------------------------------------------------------------------------*/
/* Kernel driver */
static void au1200fb_setup(void)
static int au1200fb_setup(void)
{
char* options = NULL;
char* this_opt;
char *options = NULL;
char *this_opt, *endptr;
int num_panels = ARRAY_SIZE(known_lcd_panels);
int panel_idx = -1;
@ -1827,70 +1831,42 @@ static void au1200fb_setup(void)
nohwcursor = 1;
}
else if (strncmp(this_opt, "devices:", 8) == 0) {
this_opt += 8;
device_count = simple_strtol(this_opt,
&endptr, 0);
if ((device_count < 0) ||
(device_count > MAX_DEVICE_COUNT))
device_count = MAX_DEVICE_COUNT;
}
else if (strncmp(this_opt, "wincfg:", 7) == 0) {
this_opt += 7;
window_index = simple_strtol(this_opt,
&endptr, 0);
if ((window_index < 0) ||
(window_index >= ARRAY_SIZE(windows)))
window_index = DEFAULT_WINDOW_INDEX;
}
else if (strncmp(this_opt, "off", 3) == 0)
return 1;
/* Unsupported option */
else {
print_warn("Unsupported option \"%s\"", this_opt);
}
}
}
return 0;
}
#ifdef CONFIG_PM
static int au1200fb_pm_callback(au1xxx_power_dev_t *dev,
au1xxx_request_t request, void *data) {
int retval = -1;
unsigned int d = 0;
unsigned int brightness = 0;
if (request == AU1XXX_PM_SLEEP) {
board_au1200fb_panel_shutdown();
}
else if (request == AU1XXX_PM_WAKEUP) {
if(dev->prev_state == SLEEP_STATE)
{
int plane;
au1200_setpanel(panel);
for (plane = 0; plane < CONFIG_FB_AU1200_DEVS; ++plane) {
struct au1200fb_device *fbdev;
fbdev = &_au1200fb_devices[plane];
au1200fb_fb_set_par(&fbdev->fb_info);
}
}
d = *((unsigned int*)data);
if(d <=10) brightness = 26;
else if(d<=20) brightness = 51;
else if(d<=30) brightness = 77;
else if(d<=40) brightness = 102;
else if(d<=50) brightness = 128;
else if(d<=60) brightness = 153;
else if(d<=70) brightness = 179;
else if(d<=80) brightness = 204;
else if(d<=90) brightness = 230;
else brightness = 255;
set_brightness(brightness);
} else if (request == AU1XXX_PM_GETSTATUS) {
return dev->cur_state;
} else if (request == AU1XXX_PM_ACCESS) {
if (dev->cur_state != SLEEP_STATE)
return retval;
else {
au1200_setpanel(panel);
}
} else if (request == AU1XXX_PM_IDLE) {
} else if (request == AU1XXX_PM_CLEANUP) {
}
return retval;
}
#endif
static int __init au1200fb_init(void)
{
print_info("" DRIVER_DESC "");
/* Setup driver with options */
au1200fb_setup();
if (au1200fb_setup())
return -ENODEV;
/* Point to the panel selected */
panel = &known_lcd_panels[panel_index];
@ -1899,17 +1875,6 @@ static int __init au1200fb_init(void)
printk(DRIVER_NAME ": Panel %d %s\n", panel_index, panel->name);
printk(DRIVER_NAME ": Win %d %s\n", window_index, win->name);
/* Kickstart the panel, the framebuffers/windows come soon enough */
au1200_setpanel(panel);
#ifdef CONFIG_PM
LCD_pm_dev = new_au1xxx_power_device("LCD", &au1200fb_pm_callback, NULL);
if ( LCD_pm_dev == NULL)
printk(KERN_INFO "Unable to create a power management device entry for the au1200fb.\n");
else
printk(KERN_INFO "Power management device entry for the au1200fb loaded.\n");
#endif
return platform_driver_register(&au1200fb_driver);
}

View File

@ -7,7 +7,6 @@
*/
#include <linux/module.h>
#include <linux/version.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/pm.h>

View File

@ -7,7 +7,6 @@
*/
#include <linux/module.h>
#include <linux/version.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/pm.h>

View File

@ -633,7 +633,7 @@ static int __devinit bfin_bf54x_probe(struct platform_device *pdev)
goto out7;
}
if (request_irq(info->irq, bfin_bf54x_irq_error, IRQF_DISABLED,
if (request_irq(info->irq, bfin_bf54x_irq_error, 0,
"PPI ERROR", info) < 0) {
printk(KERN_ERR DRIVER_NAME
": unable to request PPI ERROR IRQ\n");

View File

@ -695,7 +695,7 @@ static int __devinit bfin_lq035q1_probe(struct platform_device *pdev)
goto out7;
}
ret = request_irq(info->irq, bfin_lq035q1_irq_error, IRQF_DISABLED,
ret = request_irq(info->irq, bfin_lq035q1_irq_error, 0,
DRIVER_NAME" PPI ERROR", info);
if (ret < 0) {
dev_err(&pdev->dev, "unable to request PPI ERROR IRQ\n");

View File

@ -529,7 +529,7 @@ static int __devinit bfin_t350mcqb_probe(struct platform_device *pdev)
goto out7;
}
ret = request_irq(info->irq, bfin_t350mcqb_irq_error, IRQF_DISABLED,
ret = request_irq(info->irq, bfin_t350mcqb_irq_error, 0,
"PPI ERROR", info);
if (ret < 0) {
printk(KERN_ERR DRIVER_NAME

View File

@ -481,7 +481,7 @@ static int __devinit bfin_adv7393_fb_probe(struct i2c_client *client,
goto out_4;
}
if (request_irq(IRQ_PPI_ERROR, ppi_irq_error, IRQF_DISABLED,
if (request_irq(IRQ_PPI_ERROR, ppi_irq_error, 0,
"PPI ERROR", fbdev) < 0) {
dev_err(&client->dev, "unable to request PPI ERROR IRQ\n");
ret = -EFAULT;

View File

@ -32,11 +32,11 @@
#define CARMINEFB_DEFAULT_VIDEO_MODE 1
static unsigned int fb_mode = CARMINEFB_DEFAULT_VIDEO_MODE;
module_param(fb_mode, uint, 444);
module_param(fb_mode, uint, 0444);
MODULE_PARM_DESC(fb_mode, "Initial video mode as integer.");
static char *fb_mode_str;
module_param(fb_mode_str, charp, 444);
module_param(fb_mode_str, charp, 0444);
MODULE_PARM_DESC(fb_mode_str, "Initial video mode in characters.");
/*
@ -46,7 +46,7 @@ MODULE_PARM_DESC(fb_mode_str, "Initial video mode in characters.");
* 0b010 Display 1
*/
static int fb_displays = CARMINE_USE_DISPLAY0 | CARMINE_USE_DISPLAY1;
module_param(fb_displays, int, 444);
module_param(fb_displays, int, 0444);
MODULE_PARM_DESC(fb_displays, "Bit mode, which displays are used");
struct carmine_hw {

View File

@ -550,7 +550,7 @@ static void control_set_hardware(struct fb_info_control *p, struct fb_par_contro
/*
* Parse user speficied options (`video=controlfb:')
* Parse user specified options (`video=controlfb:')
*/
static void __init control_setup(char *options)
{

View File

@ -35,6 +35,9 @@
#define DRIVER_NAME "da8xx_lcdc"
#define LCD_VERSION_1 1
#define LCD_VERSION_2 2
/* LCD Status Register */
#define LCD_END_OF_FRAME1 BIT(9)
#define LCD_END_OF_FRAME0 BIT(8)
@ -49,7 +52,9 @@
#define LCD_DMA_BURST_4 0x2
#define LCD_DMA_BURST_8 0x3
#define LCD_DMA_BURST_16 0x4
#define LCD_END_OF_FRAME_INT_ENA BIT(2)
#define LCD_V1_END_OF_FRAME_INT_ENA BIT(2)
#define LCD_V2_END_OF_FRAME0_INT_ENA BIT(8)
#define LCD_V2_END_OF_FRAME1_INT_ENA BIT(9)
#define LCD_DUAL_FRAME_BUFFER_ENABLE BIT(0)
/* LCD Control Register */
@ -65,12 +70,18 @@
#define LCD_MONO_8BIT_MODE BIT(9)
#define LCD_RASTER_ORDER BIT(8)
#define LCD_TFT_MODE BIT(7)
#define LCD_UNDERFLOW_INT_ENA BIT(6)
#define LCD_PL_ENABLE BIT(4)
#define LCD_V1_UNDERFLOW_INT_ENA BIT(6)
#define LCD_V2_UNDERFLOW_INT_ENA BIT(5)
#define LCD_V1_PL_INT_ENA BIT(4)
#define LCD_V2_PL_INT_ENA BIT(6)
#define LCD_MONOCHROME_MODE BIT(1)
#define LCD_RASTER_ENABLE BIT(0)
#define LCD_TFT_ALT_ENABLE BIT(23)
#define LCD_STN_565_ENABLE BIT(24)
#define LCD_V2_DMA_CLK_EN BIT(2)
#define LCD_V2_LIDD_CLK_EN BIT(1)
#define LCD_V2_CORE_CLK_EN BIT(0)
#define LCD_V2_LPP_B10 26
/* LCD Raster Timing 2 Register */
#define LCD_AC_BIAS_TRANSITIONS_PER_INT(x) ((x) << 16)
@ -82,6 +93,7 @@
#define LCD_INVERT_FRAME_CLOCK BIT(20)
/* LCD Block */
#define LCD_PID_REG 0x0
#define LCD_CTRL_REG 0x4
#define LCD_STAT_REG 0x8
#define LCD_RASTER_CTRL_REG 0x28
@ -94,6 +106,17 @@
#define LCD_DMA_FRM_BUF_BASE_ADDR_1_REG 0x4C
#define LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG 0x50
/* Interrupt Registers available only in Version 2 */
#define LCD_RAW_STAT_REG 0x58
#define LCD_MASKED_STAT_REG 0x5c
#define LCD_INT_ENABLE_SET_REG 0x60
#define LCD_INT_ENABLE_CLR_REG 0x64
#define LCD_END_OF_INT_IND_REG 0x68
/* Clock registers available only on Version 2 */
#define LCD_CLK_ENABLE_REG 0x6c
#define LCD_CLK_RESET_REG 0x70
#define LCD_NUM_BUFFERS 2
#define WSI_TIMEOUT 50
@ -105,6 +128,8 @@
static resource_size_t da8xx_fb_reg_base;
static struct resource *lcdc_regs;
static unsigned int lcd_revision;
static irq_handler_t lcdc_irq_handler;
static inline unsigned int lcdc_read(unsigned int addr)
{
@ -240,6 +265,7 @@ static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
u32 end;
u32 reg_ras;
u32 reg_dma;
u32 reg_int;
/* init reg to clear PLM (loading mode) fields */
reg_ras = lcdc_read(LCD_RASTER_CTRL_REG);
@ -252,7 +278,14 @@ static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
end = par->dma_end;
reg_ras |= LCD_PALETTE_LOAD_MODE(DATA_ONLY);
reg_dma |= LCD_END_OF_FRAME_INT_ENA;
if (lcd_revision == LCD_VERSION_1) {
reg_dma |= LCD_V1_END_OF_FRAME_INT_ENA;
} else {
reg_int = lcdc_read(LCD_INT_ENABLE_SET_REG) |
LCD_V2_END_OF_FRAME0_INT_ENA |
LCD_V2_END_OF_FRAME1_INT_ENA;
lcdc_write(reg_int, LCD_INT_ENABLE_SET_REG);
}
reg_dma |= LCD_DUAL_FRAME_BUFFER_ENABLE;
lcdc_write(start, LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
@ -264,7 +297,14 @@ static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
end = start + par->palette_sz - 1;
reg_ras |= LCD_PALETTE_LOAD_MODE(PALETTE_ONLY);
reg_ras |= LCD_PL_ENABLE;
if (lcd_revision == LCD_VERSION_1) {
reg_ras |= LCD_V1_PL_INT_ENA;
} else {
reg_int = lcdc_read(LCD_INT_ENABLE_SET_REG) |
LCD_V2_PL_INT_ENA;
lcdc_write(reg_int, LCD_INT_ENABLE_SET_REG);
}
lcdc_write(start, LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
lcdc_write(end, LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG);
@ -348,6 +388,7 @@ static void lcd_cfg_vertical_sync(int back_porch, int pulse_width,
static int lcd_cfg_display(const struct lcd_ctrl_config *cfg)
{
u32 reg;
u32 reg_int;
reg = lcdc_read(LCD_RASTER_CTRL_REG) & ~(LCD_TFT_MODE |
LCD_MONO_8BIT_MODE |
@ -375,7 +416,13 @@ static int lcd_cfg_display(const struct lcd_ctrl_config *cfg)
}
/* enable additional interrupts here */
reg |= LCD_UNDERFLOW_INT_ENA;
if (lcd_revision == LCD_VERSION_1) {
reg |= LCD_V1_UNDERFLOW_INT_ENA;
} else {
reg_int = lcdc_read(LCD_INT_ENABLE_SET_REG) |
LCD_V2_UNDERFLOW_INT_ENA;
lcdc_write(reg_int, LCD_INT_ENABLE_SET_REG);
}
lcdc_write(reg, LCD_RASTER_CTRL_REG);
@ -413,18 +460,43 @@ static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height,
/* Set the Panel Width */
/* Pixels per line = (PPL + 1)*16 */
/*0x3F in bits 4..9 gives max horisontal resolution = 1024 pixels*/
width &= 0x3f0;
if (lcd_revision == LCD_VERSION_1) {
/*
* 0x3F in bits 4..9 gives max horizontal resolution = 1024
* pixels.
*/
width &= 0x3f0;
} else {
/*
* 0x7F in bits 4..10 gives max horizontal resolution = 2048
* pixels.
*/
width &= 0x7f0;
}
reg = lcdc_read(LCD_RASTER_TIMING_0_REG);
reg &= 0xfffffc00;
reg |= ((width >> 4) - 1) << 4;
if (lcd_revision == LCD_VERSION_1) {
reg |= ((width >> 4) - 1) << 4;
} else {
width = (width >> 4) - 1;
reg |= ((width & 0x3f) << 4) | ((width & 0x40) >> 3);
}
lcdc_write(reg, LCD_RASTER_TIMING_0_REG);
/* Set the Panel Height */
/* Set bits 9:0 of Lines Per Pixel */
reg = lcdc_read(LCD_RASTER_TIMING_1_REG);
reg = ((height - 1) & 0x3ff) | (reg & 0xfffffc00);
lcdc_write(reg, LCD_RASTER_TIMING_1_REG);
/* Set bit 10 of Lines Per Pixel */
if (lcd_revision == LCD_VERSION_2) {
reg = lcdc_read(LCD_RASTER_TIMING_2_REG);
reg |= ((height - 1) & 0x400) << 16;
lcdc_write(reg, LCD_RASTER_TIMING_2_REG);
}
/* Set the Raster Order of the Frame Buffer */
reg = lcdc_read(LCD_RASTER_CTRL_REG) & ~(1 << 8);
if (raster_order)
@ -511,6 +583,9 @@ static void lcd_reset(struct da8xx_fb_par *par)
/* DMA has to be disabled */
lcdc_write(0, LCD_DMA_CTRL_REG);
lcdc_write(0, LCD_RASTER_CTRL_REG);
if (lcd_revision == LCD_VERSION_2)
lcdc_write(0, LCD_INT_ENABLE_SET_REG);
}
static void lcd_calc_clk_divider(struct da8xx_fb_par *par)
@ -523,6 +598,11 @@ static void lcd_calc_clk_divider(struct da8xx_fb_par *par)
/* Configure the LCD clock divisor. */
lcdc_write(LCD_CLK_DIVISOR(div) |
(LCD_RASTER_MODE & 0x1), LCD_CTRL_REG);
if (lcd_revision == LCD_VERSION_2)
lcdc_write(LCD_V2_DMA_CLK_EN | LCD_V2_LIDD_CLK_EN |
LCD_V2_CORE_CLK_EN, LCD_CLK_ENABLE_REG);
}
static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
@ -583,7 +663,63 @@ static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
return 0;
}
static irqreturn_t lcdc_irq_handler(int irq, void *arg)
/* IRQ handler for version 2 of LCDC */
static irqreturn_t lcdc_irq_handler_rev02(int irq, void *arg)
{
struct da8xx_fb_par *par = arg;
u32 stat = lcdc_read(LCD_MASKED_STAT_REG);
u32 reg_int;
if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) {
lcd_disable_raster();
lcdc_write(stat, LCD_MASKED_STAT_REG);
lcd_enable_raster();
} else if (stat & LCD_PL_LOAD_DONE) {
/*
* Must disable raster before changing state of any control bit.
* And also must be disabled before clearing the PL loading
* interrupt via the following write to the status register. If
* this is done after then one gets multiple PL done interrupts.
*/
lcd_disable_raster();
lcdc_write(stat, LCD_MASKED_STAT_REG);
/* Disable PL completion inerrupt */
reg_int = lcdc_read(LCD_INT_ENABLE_CLR_REG) |
(LCD_V2_PL_INT_ENA);
lcdc_write(reg_int, LCD_INT_ENABLE_CLR_REG);
/* Setup and start data loading mode */
lcd_blit(LOAD_DATA, par);
} else {
lcdc_write(stat, LCD_MASKED_STAT_REG);
if (stat & LCD_END_OF_FRAME0) {
lcdc_write(par->dma_start,
LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
lcdc_write(par->dma_end,
LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG);
par->vsync_flag = 1;
wake_up_interruptible(&par->vsync_wait);
}
if (stat & LCD_END_OF_FRAME1) {
lcdc_write(par->dma_start,
LCD_DMA_FRM_BUF_BASE_ADDR_1_REG);
lcdc_write(par->dma_end,
LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG);
par->vsync_flag = 1;
wake_up_interruptible(&par->vsync_wait);
}
}
lcdc_write(0, LCD_END_OF_INT_IND_REG);
return IRQ_HANDLED;
}
/* IRQ handler for version 1 LCDC */
static irqreturn_t lcdc_irq_handler_rev01(int irq, void *arg)
{
struct da8xx_fb_par *par = arg;
u32 stat = lcdc_read(LCD_STAT_REG);
@ -606,7 +742,7 @@ static irqreturn_t lcdc_irq_handler(int irq, void *arg)
/* Disable PL completion inerrupt */
reg_ras = lcdc_read(LCD_RASTER_CTRL_REG);
reg_ras &= ~LCD_PL_ENABLE;
reg_ras &= ~LCD_V1_PL_INT_ENA;
lcdc_write(reg_ras, LCD_RASTER_CTRL_REG);
/* Setup and start data loading mode */
@ -877,8 +1013,8 @@ static int da8xx_pan_display(struct fb_var_screeninfo *var,
start = fix->smem_start +
new_var.yoffset * fix->line_length +
new_var.xoffset * var->bits_per_pixel / 8;
end = start + var->yres * fix->line_length - 1;
new_var.xoffset * fbi->var.bits_per_pixel / 8;
end = start + fbi->var.yres * fix->line_length - 1;
par->dma_start = start;
par->dma_end = end;
}
@ -945,6 +1081,22 @@ static int __devinit fb_probe(struct platform_device *device)
if (ret)
goto err_clk_put;
/* Determine LCD IP Version */
switch (lcdc_read(LCD_PID_REG)) {
case 0x4C100102:
lcd_revision = LCD_VERSION_1;
break;
case 0x4F200800:
lcd_revision = LCD_VERSION_2;
break;
default:
dev_warn(&device->dev, "Unknown PID Reg value 0x%x, "
"defaulting to LCD revision 1\n",
lcdc_read(LCD_PID_REG));
lcd_revision = LCD_VERSION_1;
break;
}
for (i = 0, lcdc_info = known_lcd_panels;
i < ARRAY_SIZE(known_lcd_panels);
i++, lcdc_info++) {
@ -1085,7 +1237,13 @@ static int __devinit fb_probe(struct platform_device *device)
}
#endif
ret = request_irq(par->irq, lcdc_irq_handler, 0, DRIVER_NAME, par);
if (lcd_revision == LCD_VERSION_1)
lcdc_irq_handler = lcdc_irq_handler_rev01;
else
lcdc_irq_handler = lcdc_irq_handler_rev02;
ret = request_irq(par->irq, lcdc_irq_handler, 0,
DRIVER_NAME, par);
if (ret)
goto irq_freq;
return 0;

View File

@ -624,8 +624,8 @@ static int unifb_pan_display(struct fb_var_screeninfo *var,
|| var->xoffset)
return -EINVAL;
} else {
if (var->xoffset + var->xres > info->var.xres_virtual ||
var->yoffset + var->yres > info->var.yres_virtual)
if (var->xoffset + info->var.xres > info->var.xres_virtual ||
var->yoffset + info->var.yres > info->var.yres_virtual)
return -EINVAL;
}
info->var.xoffset = var->xoffset;

View File

@ -223,8 +223,7 @@ void fb_deferred_io_cleanup(struct fb_info *info)
int i;
BUG_ON(!fbdefio);
cancel_delayed_work(&info->deferred_work);
flush_scheduled_work();
cancel_delayed_work_sync(&info->deferred_work);
/* clear out the mapping that we setup */
for (i = 0 ; i < info->fix.smem_len; i += PAGE_SIZE) {

View File

@ -1738,8 +1738,6 @@ void fb_set_suspend(struct fb_info *info, int state)
{
struct fb_event event;
if (!lock_fb_info(info))
return;
event.info = info;
if (state) {
fb_notifier_call_chain(FB_EVENT_SUSPEND, &event);
@ -1748,7 +1746,6 @@ void fb_set_suspend(struct fb_info *info, int state)
info->state = FBINFO_STATE_RUNNING;
fb_notifier_call_chain(FB_EVENT_RESUME, &event);
}
unlock_fb_info(info);
}
/**

View File

@ -493,7 +493,8 @@ static int get_est_timing(unsigned char *block, struct fb_videomode *mode)
return num;
}
static int get_std_timing(unsigned char *block, struct fb_videomode *mode)
static int get_std_timing(unsigned char *block, struct fb_videomode *mode,
int ver, int rev)
{
int xres, yres = 0, refresh, ratio, i;
@ -504,7 +505,11 @@ static int get_std_timing(unsigned char *block, struct fb_videomode *mode)
ratio = (block[1] & 0xc0) >> 6;
switch (ratio) {
case 0:
yres = xres;
/* in EDID 1.3 the meaning of 0 changed to 16:10 (prior 1:1) */
if (ver < 1 || (ver == 1 && rev < 3))
yres = xres;
else
yres = (xres * 10)/16;
break;
case 1:
yres = (xres * 3)/4;
@ -533,12 +538,12 @@ static int get_std_timing(unsigned char *block, struct fb_videomode *mode)
}
static int get_dst_timing(unsigned char *block,
struct fb_videomode *mode)
struct fb_videomode *mode, int ver, int rev)
{
int j, num = 0;
for (j = 0; j < 6; j++, block += STD_TIMING_DESCRIPTION_SIZE)
num += get_std_timing(block, &mode[num]);
num += get_std_timing(block, &mode[num], ver, rev);
return num;
}
@ -599,6 +604,10 @@ static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize)
struct fb_videomode *mode, *m;
unsigned char *block;
int num = 0, i, first = 1;
int ver, rev;
ver = edid[EDID_STRUCT_VERSION];
rev = edid[EDID_STRUCT_REVISION];
mode = kzalloc(50 * sizeof(struct fb_videomode), GFP_KERNEL);
if (mode == NULL)
@ -632,12 +641,12 @@ static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize)
DPRINTK(" Standard Timings\n");
block = edid + STD_TIMING_DESCRIPTIONS_START;
for (i = 0; i < STD_TIMING; i++, block += STD_TIMING_DESCRIPTION_SIZE)
num += get_std_timing(block, &mode[num]);
num += get_std_timing(block, &mode[num], ver, rev);
block = edid + DETAILED_TIMING_DESCRIPTIONS_START;
for (i = 0; i < 4; i++, block+= DETAILED_TIMING_DESCRIPTION_SIZE) {
if (block[0] == 0x00 && block[1] == 0x00 && block[3] == 0xfa)
num += get_dst_timing(block + 5, &mode[num]);
num += get_dst_timing(block + 5, &mode[num], ver, rev);
}
/* Yikes, EDID data is totally useless */

View File

@ -399,9 +399,12 @@ static ssize_t store_fbstate(struct device *device,
state = simple_strtoul(buf, &last, 0);
if (!lock_fb_info(fb_info))
return -ENODEV;
console_lock();
fb_set_suspend(fb_info, (int)state);
console_unlock();
unlock_fb_info(fb_info);
return count;
}

File diff suppressed because it is too large Load Diff

View File

@ -149,10 +149,11 @@ int g364fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
static int g364fb_pan_display(struct fb_var_screeninfo *var,
struct fb_info *info)
{
if (var->xoffset || var->yoffset + var->yres > var->yres_virtual)
if (var->xoffset ||
var->yoffset + info->var.yres > info->var.yres_virtual)
return -EINVAL;
*(unsigned int *) TOP_REG = var->yoffset * var->xres;
*(unsigned int *) TOP_REG = var->yoffset * info->var.xres;
return 0;
}

579
drivers/video/grvga.c Normal file
View File

@ -0,0 +1,579 @@
/*
* Driver for Aeroflex Gaisler SVGACTRL framebuffer device.
*
* 2011 (c) Aeroflex Gaisler AB
*
* Full documentation of the core can be found here:
* http://www.gaisler.com/products/grlib/grip.pdf
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* Contributors: Kristoffer Glembo <kristoffer@gaisler.com>
*
*/
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/of_platform.h>
#include <linux/of_device.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/tty.h>
#include <linux/mm.h>
#include <linux/fb.h>
#include <linux/io.h>
struct grvga_regs {
u32 status; /* 0x00 */
u32 video_length; /* 0x04 */
u32 front_porch; /* 0x08 */
u32 sync_length; /* 0x0C */
u32 line_length; /* 0x10 */
u32 fb_pos; /* 0x14 */
u32 clk_vector[4]; /* 0x18 */
u32 clut; /* 0x20 */
};
struct grvga_par {
struct grvga_regs *regs;
u32 color_palette[16]; /* 16 entry pseudo palette used by fbcon in true color mode */
int clk_sel;
int fb_alloced; /* = 1 if framebuffer is allocated in main memory */
};
static const struct fb_videomode grvga_modedb[] = {
{
/* 640x480 @ 60 Hz */
NULL, 60, 640, 480, 40000, 48, 16, 39, 11, 96, 2,
0, FB_VMODE_NONINTERLACED
}, {
/* 800x600 @ 60 Hz */
NULL, 60, 800, 600, 25000, 88, 40, 23, 1, 128, 4,
0, FB_VMODE_NONINTERLACED
}, {
/* 800x600 @ 72 Hz */
NULL, 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6,
0, FB_VMODE_NONINTERLACED
}, {
/* 1024x768 @ 60 Hz */
NULL, 60, 1024, 768, 15385, 160, 24, 29, 3, 136, 6,
0, FB_VMODE_NONINTERLACED
}
};
static struct fb_fix_screeninfo grvga_fix __initdata = {
.id = "AG SVGACTRL",
.type = FB_TYPE_PACKED_PIXELS,
.visual = FB_VISUAL_PSEUDOCOLOR,
.xpanstep = 0,
.ypanstep = 1,
.ywrapstep = 0,
.accel = FB_ACCEL_NONE,
};
static int grvga_check_var(struct fb_var_screeninfo *var,
struct fb_info *info)
{
struct grvga_par *par = info->par;
int i;
if (!var->xres)
var->xres = 1;
if (!var->yres)
var->yres = 1;
if (var->bits_per_pixel <= 8)
var->bits_per_pixel = 8;
else if (var->bits_per_pixel <= 16)
var->bits_per_pixel = 16;
else if (var->bits_per_pixel <= 24)
var->bits_per_pixel = 24;
else if (var->bits_per_pixel <= 32)
var->bits_per_pixel = 32;
else
return -EINVAL;
var->xres_virtual = var->xres;
var->yres_virtual = 2*var->yres;
if (info->fix.smem_len) {
if ((var->yres_virtual*var->xres_virtual*var->bits_per_pixel/8) > info->fix.smem_len)
return -ENOMEM;
}
/* Which clocks that are available can be read out in these registers */
for (i = 0; i <= 3 ; i++) {
if (var->pixclock == par->regs->clk_vector[i])
break;
}
if (i <= 3)
par->clk_sel = i;
else
return -EINVAL;
switch (info->var.bits_per_pixel) {
case 8:
var->red = (struct fb_bitfield) {0, 8, 0}; /* offset, length, msb-right */
var->green = (struct fb_bitfield) {0, 8, 0};
var->blue = (struct fb_bitfield) {0, 8, 0};
var->transp = (struct fb_bitfield) {0, 0, 0};
break;
case 16:
var->red = (struct fb_bitfield) {11, 5, 0};
var->green = (struct fb_bitfield) {5, 6, 0};
var->blue = (struct fb_bitfield) {0, 5, 0};
var->transp = (struct fb_bitfield) {0, 0, 0};
break;
case 24:
case 32:
var->red = (struct fb_bitfield) {16, 8, 0};
var->green = (struct fb_bitfield) {8, 8, 0};
var->blue = (struct fb_bitfield) {0, 8, 0};
var->transp = (struct fb_bitfield) {24, 8, 0};
break;
default:
return -EINVAL;
}
return 0;
}
static int grvga_set_par(struct fb_info *info)
{
u32 func = 0;
struct grvga_par *par = info->par;
__raw_writel(((info->var.yres - 1) << 16) | (info->var.xres - 1),
&par->regs->video_length);
__raw_writel((info->var.lower_margin << 16) | (info->var.right_margin),
&par->regs->front_porch);
__raw_writel((info->var.vsync_len << 16) | (info->var.hsync_len),
&par->regs->sync_length);
__raw_writel(((info->var.yres + info->var.lower_margin + info->var.upper_margin + info->var.vsync_len - 1) << 16) |
(info->var.xres + info->var.right_margin + info->var.left_margin + info->var.hsync_len - 1),
&par->regs->line_length);
switch (info->var.bits_per_pixel) {
case 8:
info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
func = 1;
break;
case 16:
info->fix.visual = FB_VISUAL_TRUECOLOR;
func = 2;
break;
case 24:
case 32:
info->fix.visual = FB_VISUAL_TRUECOLOR;
func = 3;
break;
default:
return -EINVAL;
}
__raw_writel((par->clk_sel << 6) | (func << 4) | 1,
&par->regs->status);
info->fix.line_length = (info->var.xres_virtual*info->var.bits_per_pixel)/8;
return 0;
}
static int grvga_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *info)
{
struct grvga_par *par;
par = info->par;
if (regno >= 256) /* Size of CLUT */
return -EINVAL;
if (info->var.grayscale) {
/* grayscale = 0.30*R + 0.59*G + 0.11*B */
red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
}
#define CNVT_TOHW(val, width) ((((val)<<(width))+0x7FFF-(val))>>16)
red = CNVT_TOHW(red, info->var.red.length);
green = CNVT_TOHW(green, info->var.green.length);
blue = CNVT_TOHW(blue, info->var.blue.length);
transp = CNVT_TOHW(transp, info->var.transp.length);
#undef CNVT_TOHW
/* In PSEUDOCOLOR we use the hardware CLUT */
if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR)
__raw_writel((regno << 24) | (red << 16) | (green << 8) | blue,
&par->regs->clut);
/* Truecolor uses the pseudo palette */
else if (info->fix.visual == FB_VISUAL_TRUECOLOR) {
u32 v;
if (regno >= 16)
return -EINVAL;
v = (red << info->var.red.offset) |
(green << info->var.green.offset) |
(blue << info->var.blue.offset) |
(transp << info->var.transp.offset);
((u32 *) (info->pseudo_palette))[regno] = v;
}
return 0;
}
static int grvga_pan_display(struct fb_var_screeninfo *var,
struct fb_info *info)
{
struct grvga_par *par = info->par;
struct fb_fix_screeninfo *fix = &info->fix;
u32 base_addr;
if (var->xoffset != 0)
return -EINVAL;
base_addr = fix->smem_start + (var->yoffset * fix->line_length);
base_addr &= ~3UL;
/* Set framebuffer base address */
__raw_writel(base_addr,
&par->regs->fb_pos);
return 0;
}
static struct fb_ops grvga_ops = {
.owner = THIS_MODULE,
.fb_check_var = grvga_check_var,
.fb_set_par = grvga_set_par,
.fb_setcolreg = grvga_setcolreg,
.fb_pan_display = grvga_pan_display,
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit
};
static int __init grvga_parse_custom(char *options,
struct fb_var_screeninfo *screendata)
{
char *this_opt;
int count = 0;
if (!options || !*options)
return -1;
while ((this_opt = strsep(&options, " ")) != NULL) {
if (!*this_opt)
continue;
switch (count) {
case 0:
screendata->pixclock = simple_strtoul(this_opt, NULL, 0);
count++;
break;
case 1:
screendata->xres = screendata->xres_virtual = simple_strtoul(this_opt, NULL, 0);
count++;
break;
case 2:
screendata->right_margin = simple_strtoul(this_opt, NULL, 0);
count++;
break;
case 3:
screendata->hsync_len = simple_strtoul(this_opt, NULL, 0);
count++;
break;
case 4:
screendata->left_margin = simple_strtoul(this_opt, NULL, 0);
count++;
break;
case 5:
screendata->yres = screendata->yres_virtual = simple_strtoul(this_opt, NULL, 0);
count++;
break;
case 6:
screendata->lower_margin = simple_strtoul(this_opt, NULL, 0);
count++;
break;
case 7:
screendata->vsync_len = simple_strtoul(this_opt, NULL, 0);
count++;
break;
case 8:
screendata->upper_margin = simple_strtoul(this_opt, NULL, 0);
count++;
break;
case 9:
screendata->bits_per_pixel = simple_strtoul(this_opt, NULL, 0);
count++;
break;
default:
return -1;
}
}
screendata->activate = FB_ACTIVATE_NOW;
screendata->vmode = FB_VMODE_NONINTERLACED;
return 0;
}
static int __devinit grvga_probe(struct platform_device *dev)
{
struct fb_info *info;
int retval = -ENOMEM;
unsigned long virtual_start;
unsigned long grvga_fix_addr = 0;
unsigned long physical_start = 0;
unsigned long grvga_mem_size = 0;
struct grvga_par *par = NULL;
char *options = NULL, *mode_opt = NULL;
info = framebuffer_alloc(sizeof(struct grvga_par), &dev->dev);
if (!info) {
dev_err(&dev->dev, "framebuffer_alloc failed\n");
return -ENOMEM;
}
/* Expecting: "grvga: modestring, [addr:<framebuffer physical address>], [size:<framebuffer size>]
*
* If modestring is custom:<custom mode string> we parse the string which then contains all videoparameters
* If address is left out, we allocate memory,
* if size is left out we only allocate enough to support the given mode.
*/
if (fb_get_options("grvga", &options)) {
retval = -ENODEV;
goto err;
}
if (!options || !*options)
options = "640x480-8@60";
while (1) {
char *this_opt = strsep(&options, ",");
if (!this_opt)
break;
if (!strncmp(this_opt, "custom", 6)) {
if (grvga_parse_custom(this_opt, &info->var) < 0) {
dev_err(&dev->dev, "Failed to parse custom mode (%s).\n", this_opt);
retval = -EINVAL;
goto err1;
}
} else if (!strncmp(this_opt, "addr", 4))
grvga_fix_addr = simple_strtoul(this_opt + 5, NULL, 16);
else if (!strncmp(this_opt, "size", 4))
grvga_mem_size = simple_strtoul(this_opt + 5, NULL, 0);
else
mode_opt = this_opt;
}
par = info->par;
info->fbops = &grvga_ops;
info->fix = grvga_fix;
info->pseudo_palette = par->color_palette;
info->flags = FBINFO_DEFAULT | FBINFO_PARTIAL_PAN_OK | FBINFO_HWACCEL_YPAN;
info->fix.smem_len = grvga_mem_size;
if (!request_mem_region(dev->resource[0].start, resource_size(&dev->resource[0]), "grlib-svgactrl regs")) {
dev_err(&dev->dev, "registers already mapped\n");
retval = -EBUSY;
goto err;
}
par->regs = of_ioremap(&dev->resource[0], 0,
resource_size(&dev->resource[0]),
"grlib-svgactrl regs");
if (!par->regs) {
dev_err(&dev->dev, "failed to map registers\n");
retval = -ENOMEM;
goto err1;
}
retval = fb_alloc_cmap(&info->cmap, 256, 0);
if (retval < 0) {
dev_err(&dev->dev, "failed to allocate mem with fb_alloc_cmap\n");
retval = -ENOMEM;
goto err2;
}
if (mode_opt) {
retval = fb_find_mode(&info->var, info, mode_opt,
grvga_modedb, sizeof(grvga_modedb), &grvga_modedb[0], 8);
if (!retval || retval == 4) {
retval = -EINVAL;
goto err3;
}
}
if (!grvga_mem_size)
grvga_mem_size = info->var.xres_virtual * info->var.yres_virtual * info->var.bits_per_pixel/8;
if (grvga_fix_addr) {
/* Got framebuffer base address from argument list */
physical_start = grvga_fix_addr;
if (!request_mem_region(physical_start, grvga_mem_size, dev->name)) {
dev_err(&dev->dev, "failed to request memory region\n");
retval = -ENOMEM;
goto err3;
}
virtual_start = (unsigned long) ioremap(physical_start, grvga_mem_size);
if (!virtual_start) {
dev_err(&dev->dev, "error mapping framebuffer memory\n");
retval = -ENOMEM;
goto err4;
}
} else { /* Allocate frambuffer memory */
unsigned long page;
virtual_start = (unsigned long) __get_free_pages(GFP_DMA,
get_order(grvga_mem_size));
if (!virtual_start) {
dev_err(&dev->dev,
"unable to allocate framebuffer memory (%lu bytes)\n",
grvga_mem_size);
retval = -ENOMEM;
goto err3;
}
physical_start = dma_map_single(&dev->dev, (void *)virtual_start, grvga_mem_size, DMA_TO_DEVICE);
/* Set page reserved so that mmap will work. This is necessary
* since we'll be remapping normal memory.
*/
for (page = virtual_start;
page < PAGE_ALIGN(virtual_start + grvga_mem_size);
page += PAGE_SIZE) {
SetPageReserved(virt_to_page(page));
}
par->fb_alloced = 1;
}
memset((unsigned long *) virtual_start, 0, grvga_mem_size);
info->screen_base = (char __iomem *) virtual_start;
info->fix.smem_start = physical_start;
info->fix.smem_len = grvga_mem_size;
dev_set_drvdata(&dev->dev, info);
dev_info(&dev->dev,
"Aeroflex Gaisler framebuffer device (fb%d), %dx%d-%d, using %luK of video memory @ %p\n",
info->node, info->var.xres, info->var.yres, info->var.bits_per_pixel,
grvga_mem_size >> 10, info->screen_base);
retval = register_framebuffer(info);
if (retval < 0) {
dev_err(&dev->dev, "failed to register framebuffer\n");
goto err4;
}
__raw_writel(physical_start, &par->regs->fb_pos);
__raw_writel(__raw_readl(&par->regs->status) | 1, /* Enable framebuffer */
&par->regs->status);
return 0;
err4:
dev_set_drvdata(&dev->dev, NULL);
if (grvga_fix_addr) {
release_mem_region(physical_start, grvga_mem_size);
iounmap((void *)virtual_start);
} else
kfree((void *)virtual_start);
err3:
fb_dealloc_cmap(&info->cmap);
err2:
of_iounmap(&dev->resource[0], par->regs,
resource_size(&dev->resource[0]));
err1:
release_mem_region(dev->resource[0].start, resource_size(&dev->resource[0]));
err:
framebuffer_release(info);
return retval;
}
static int __devexit grvga_remove(struct platform_device *device)
{
struct fb_info *info = dev_get_drvdata(&device->dev);
struct grvga_par *par = info->par;
if (info) {
unregister_framebuffer(info);
fb_dealloc_cmap(&info->cmap);
of_iounmap(&device->resource[0], par->regs,
resource_size(&device->resource[0]));
release_mem_region(device->resource[0].start, resource_size(&device->resource[0]));
if (!par->fb_alloced) {
release_mem_region(info->fix.smem_start, info->fix.smem_len);
iounmap(info->screen_base);
} else
kfree((void *)info->screen_base);
framebuffer_release(info);
dev_set_drvdata(&device->dev, NULL);
}
return 0;
}
static struct of_device_id svgactrl_of_match[] = {
{
.name = "GAISLER_SVGACTRL",
},
{
.name = "01_063",
},
{},
};
MODULE_DEVICE_TABLE(of, svgactrl_of_match);
static struct platform_driver grvga_driver = {
.driver = {
.name = "grlib-svgactrl",
.owner = THIS_MODULE,
.of_match_table = svgactrl_of_match,
},
.probe = grvga_probe,
.remove = __devexit_p(grvga_remove),
};
static int __init grvga_init(void)
{
return platform_driver_register(&grvga_driver);
}
static void __exit grvga_exit(void)
{
platform_driver_unregister(&grvga_driver);
}
module_init(grvga_init);
module_exit(grvga_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Aeroflex Gaisler");
MODULE_DESCRIPTION("Aeroflex Gaisler framebuffer device driver");

View File

@ -543,8 +543,8 @@ static int gxt4500_pan_display(struct fb_var_screeninfo *var,
if (var->xoffset & 7)
return -EINVAL;
if (var->xoffset + var->xres > var->xres_virtual ||
var->yoffset + var->yres > var->yres_virtual)
if (var->xoffset + info->var.xres > info->var.xres_virtual ||
var->yoffset + info->var.yres > info->var.yres_virtual)
return -EINVAL;
writereg(par, REFRESH_START, (var->xoffset << 16) | var->yoffset);

View File

@ -422,8 +422,8 @@ static int hgafb_pan_display(struct fb_var_screeninfo *var,
var->xoffset)
return -EINVAL;
} else {
if (var->xoffset + var->xres > info->var.xres_virtual
|| var->yoffset + var->yres > info->var.yres_virtual
if (var->xoffset + info->var.xres > info->var.xres_virtual
|| var->yoffset + info->var.yres > info->var.yres_virtual
|| var->yoffset % 8)
return -EINVAL;
}

View File

@ -749,7 +749,7 @@ set_offset (struct fb_var_screeninfo *var, struct fb_info *info)
{
struct imstt_par *par = info->par;
__u32 off = var->yoffset * (info->fix.line_length >> 3)
+ ((var->xoffset * (var->bits_per_pixel >> 3)) >> 3);
+ ((var->xoffset * (info->var.bits_per_pixel >> 3)) >> 3);
write_reg_le32(par->dc_regs, SSR, off);
}

View File

@ -390,12 +390,12 @@ int intelfbhw_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
xoffset = ROUND_DOWN_TO(var->xoffset, 8);
yoffset = var->yoffset;
if ((xoffset + var->xres > var->xres_virtual) ||
(yoffset + var->yres > var->yres_virtual))
if ((xoffset + info->var.xres > info->var.xres_virtual) ||
(yoffset + info->var.yres > info->var.yres_virtual))
return -EINVAL;
offset = (yoffset * dinfo->pitch) +
(xoffset * var->bits_per_pixel) / 8;
(xoffset * info->var.bits_per_pixel) / 8;
offset += dinfo->fb.offset << 12;

View File

@ -23,7 +23,7 @@ static int mb862xx_i2c_wait_event(struct i2c_adapter *adap)
u32 reg;
do {
udelay(1);
udelay(10);
reg = inreg(i2c, GC_I2C_BCR);
if (reg & (I2C_INT | I2C_BER))
break;

View File

@ -278,7 +278,7 @@ static int mb862xxfb_pan(struct fb_var_screeninfo *var,
reg = pack(var->yoffset, var->xoffset);
outreg(disp, GC_L0WY_L0WX, reg);
reg = pack(var->yres_virtual, var->xres_virtual);
reg = pack(info->var.yres_virtual, info->var.xres_virtual);
outreg(disp, GC_L0WH_L0WW, reg);
return 0;
}
@ -737,7 +737,7 @@ static int __devinit of_platform_mb862xx_probe(struct platform_device *ofdev)
if (mb862xx_gdc_init(par))
goto io_unmap;
if (request_irq(par->irq, mb862xx_intr, IRQF_DISABLED,
if (request_irq(par->irq, mb862xx_intr, 0,
DRV_NAME, (void *)par)) {
dev_err(dev, "Cannot request irq\n");
goto io_unmap;
@ -1073,7 +1073,7 @@ static int __devinit mb862xx_pci_probe(struct pci_dev *pdev,
if (mb862xx_pci_gdc_init(par))
goto io_unmap;
if (request_irq(par->irq, mb862xx_intr, IRQF_DISABLED | IRQF_SHARED,
if (request_irq(par->irq, mb862xx_intr, IRQF_SHARED,
DRV_NAME, (void *)par)) {
dev_err(dev, "Cannot request irq\n");
goto io_unmap;

View File

@ -491,55 +491,56 @@ EXPORT_SYMBOL(vesa_modes);
static int fb_try_mode(struct fb_var_screeninfo *var, struct fb_info *info,
const struct fb_videomode *mode, unsigned int bpp)
{
int err = 0;
int err = 0;
DPRINTK("Trying mode %s %dx%d-%d@%d\n", mode->name ? mode->name : "noname",
mode->xres, mode->yres, bpp, mode->refresh);
var->xres = mode->xres;
var->yres = mode->yres;
var->xres_virtual = mode->xres;
var->yres_virtual = mode->yres;
var->xoffset = 0;
var->yoffset = 0;
var->bits_per_pixel = bpp;
var->activate |= FB_ACTIVATE_TEST;
var->pixclock = mode->pixclock;
var->left_margin = mode->left_margin;
var->right_margin = mode->right_margin;
var->upper_margin = mode->upper_margin;
var->lower_margin = mode->lower_margin;
var->hsync_len = mode->hsync_len;
var->vsync_len = mode->vsync_len;
var->sync = mode->sync;
var->vmode = mode->vmode;
if (info->fbops->fb_check_var)
err = info->fbops->fb_check_var(var, info);
var->activate &= ~FB_ACTIVATE_TEST;
return err;
DPRINTK("Trying mode %s %dx%d-%d@%d\n",
mode->name ? mode->name : "noname",
mode->xres, mode->yres, bpp, mode->refresh);
var->xres = mode->xres;
var->yres = mode->yres;
var->xres_virtual = mode->xres;
var->yres_virtual = mode->yres;
var->xoffset = 0;
var->yoffset = 0;
var->bits_per_pixel = bpp;
var->activate |= FB_ACTIVATE_TEST;
var->pixclock = mode->pixclock;
var->left_margin = mode->left_margin;
var->right_margin = mode->right_margin;
var->upper_margin = mode->upper_margin;
var->lower_margin = mode->lower_margin;
var->hsync_len = mode->hsync_len;
var->vsync_len = mode->vsync_len;
var->sync = mode->sync;
var->vmode = mode->vmode;
if (info->fbops->fb_check_var)
err = info->fbops->fb_check_var(var, info);
var->activate &= ~FB_ACTIVATE_TEST;
return err;
}
/**
* fb_find_mode - finds a valid video mode
* @var: frame buffer user defined part of display
* @info: frame buffer info structure
* @mode_option: string video mode to find
* @db: video mode database
* @dbsize: size of @db
* @default_mode: default video mode to fall back to
* @default_bpp: default color depth in bits per pixel
* fb_find_mode - finds a valid video mode
* @var: frame buffer user defined part of display
* @info: frame buffer info structure
* @mode_option: string video mode to find
* @db: video mode database
* @dbsize: size of @db
* @default_mode: default video mode to fall back to
* @default_bpp: default color depth in bits per pixel
*
* Finds a suitable video mode, starting with the specified mode
* in @mode_option with fallback to @default_mode. If
* @default_mode fails, all modes in the video mode database will
* be tried.
* Finds a suitable video mode, starting with the specified mode
* in @mode_option with fallback to @default_mode. If
* @default_mode fails, all modes in the video mode database will
* be tried.
*
* Valid mode specifiers for @mode_option:
* Valid mode specifiers for @mode_option:
*
* <xres>x<yres>[M][R][-<bpp>][@<refresh>][i][m] or
* <name>[-<bpp>][@<refresh>]
* <xres>x<yres>[M][R][-<bpp>][@<refresh>][i][m] or
* <name>[-<bpp>][@<refresh>]
*
* with <xres>, <yres>, <bpp> and <refresh> decimal numbers and
* <name> a string.
* with <xres>, <yres>, <bpp> and <refresh> decimal numbers and
* <name> a string.
*
* If 'M' is present after yres (and before refresh/bpp if present),
* the function will compute the timings using VESA(tm) Coordinated
@ -551,12 +552,12 @@ static int fb_try_mode(struct fb_var_screeninfo *var, struct fb_info *info,
*
* 1024x768MR-8@60m - Reduced blank with margins at 60Hz.
*
* NOTE: The passed struct @var is _not_ cleared! This allows you
* to supply values for e.g. the grayscale and accel_flags fields.
* NOTE: The passed struct @var is _not_ cleared! This allows you
* to supply values for e.g. the grayscale and accel_flags fields.
*
* Returns zero for failure, 1 if using specified @mode_option,
* 2 if using specified @mode_option with an ignored refresh rate,
* 3 if default mode is used, 4 if fall back to any valid mode.
* Returns zero for failure, 1 if using specified @mode_option,
* 2 if using specified @mode_option with an ignored refresh rate,
* 3 if default mode is used, 4 if fall back to any valid mode.
*
*/
@ -566,198 +567,203 @@ int fb_find_mode(struct fb_var_screeninfo *var,
const struct fb_videomode *default_mode,
unsigned int default_bpp)
{
int i;
int i;
/* Set up defaults */
if (!db) {
db = modedb;
dbsize = ARRAY_SIZE(modedb);
}
if (!default_mode)
default_mode = &db[0];
if (!default_bpp)
default_bpp = 8;
/* Did the user specify a video mode? */
if (!mode_option)
mode_option = fb_mode_option;
if (mode_option) {
const char *name = mode_option;
unsigned int namelen = strlen(name);
int res_specified = 0, bpp_specified = 0, refresh_specified = 0;
unsigned int xres = 0, yres = 0, bpp = default_bpp, refresh = 0;
int yres_specified = 0, cvt = 0, rb = 0, interlace = 0, margins = 0;
u32 best, diff, tdiff;
for (i = namelen-1; i >= 0; i--) {
switch (name[i]) {
case '@':
namelen = i;
if (!refresh_specified && !bpp_specified &&
!yres_specified) {
refresh = simple_strtol(&name[i+1], NULL, 10);
refresh_specified = 1;
if (cvt || rb)
cvt = 0;
} else
goto done;
break;
case '-':
namelen = i;
if (!bpp_specified && !yres_specified) {
bpp = simple_strtol(&name[i+1], NULL, 10);
bpp_specified = 1;
if (cvt || rb)
cvt = 0;
} else
goto done;
break;
case 'x':
if (!yres_specified) {
yres = simple_strtol(&name[i+1], NULL, 10);
yres_specified = 1;
} else
goto done;
break;
case '0' ... '9':
break;
case 'M':
if (!yres_specified)
cvt = 1;
break;
case 'R':
if (!cvt)
rb = 1;
break;
case 'm':
if (!cvt)
margins = 1;
break;
case 'i':
if (!cvt)
interlace = 1;
break;
default:
goto done;
}
}
if (i < 0 && yres_specified) {
xres = simple_strtol(name, NULL, 10);
res_specified = 1;
}
done:
if (cvt) {
struct fb_videomode cvt_mode;
int ret;
DPRINTK("CVT mode %dx%d@%dHz%s%s%s\n", xres, yres,
(refresh) ? refresh : 60, (rb) ? " reduced blanking" :
"", (margins) ? " with margins" : "", (interlace) ?
" interlaced" : "");
memset(&cvt_mode, 0, sizeof(cvt_mode));
cvt_mode.xres = xres;
cvt_mode.yres = yres;
cvt_mode.refresh = (refresh) ? refresh : 60;
if (interlace)
cvt_mode.vmode |= FB_VMODE_INTERLACED;
else
cvt_mode.vmode &= ~FB_VMODE_INTERLACED;
ret = fb_find_mode_cvt(&cvt_mode, margins, rb);
if (!ret && !fb_try_mode(var, info, &cvt_mode, bpp)) {
DPRINTK("modedb CVT: CVT mode ok\n");
return 1;
}
DPRINTK("CVT mode invalid, getting mode from database\n");
/* Set up defaults */
if (!db) {
db = modedb;
dbsize = ARRAY_SIZE(modedb);
}
DPRINTK("Trying specified video mode%s %ix%i\n",
refresh_specified ? "" : " (ignoring refresh rate)", xres, yres);
if (!default_mode)
default_mode = &db[0];
if (!refresh_specified) {
/*
* If the caller has provided a custom mode database and a
* valid monspecs structure, we look for the mode with the
* highest refresh rate. Otherwise we play it safe it and
* try to find a mode with a refresh rate closest to the
* standard 60 Hz.
*/
if (db != modedb &&
info->monspecs.vfmin && info->monspecs.vfmax &&
info->monspecs.hfmin && info->monspecs.hfmax &&
info->monspecs.dclkmax) {
refresh = 1000;
} else {
refresh = 60;
if (!default_bpp)
default_bpp = 8;
/* Did the user specify a video mode? */
if (!mode_option)
mode_option = fb_mode_option;
if (mode_option) {
const char *name = mode_option;
unsigned int namelen = strlen(name);
int res_specified = 0, bpp_specified = 0, refresh_specified = 0;
unsigned int xres = 0, yres = 0, bpp = default_bpp, refresh = 0;
int yres_specified = 0, cvt = 0, rb = 0, interlace = 0;
int margins = 0;
u32 best, diff, tdiff;
for (i = namelen-1; i >= 0; i--) {
switch (name[i]) {
case '@':
namelen = i;
if (!refresh_specified && !bpp_specified &&
!yres_specified) {
refresh = simple_strtol(&name[i+1], NULL,
10);
refresh_specified = 1;
if (cvt || rb)
cvt = 0;
} else
goto done;
break;
case '-':
namelen = i;
if (!bpp_specified && !yres_specified) {
bpp = simple_strtol(&name[i+1], NULL,
10);
bpp_specified = 1;
if (cvt || rb)
cvt = 0;
} else
goto done;
break;
case 'x':
if (!yres_specified) {
yres = simple_strtol(&name[i+1], NULL,
10);
yres_specified = 1;
} else
goto done;
break;
case '0' ... '9':
break;
case 'M':
if (!yres_specified)
cvt = 1;
break;
case 'R':
if (!cvt)
rb = 1;
break;
case 'm':
if (!cvt)
margins = 1;
break;
case 'i':
if (!cvt)
interlace = 1;
break;
default:
goto done;
}
}
}
if (i < 0 && yres_specified) {
xres = simple_strtol(name, NULL, 10);
res_specified = 1;
}
done:
if (cvt) {
struct fb_videomode cvt_mode;
int ret;
diff = -1;
best = -1;
for (i = 0; i < dbsize; i++) {
if ((name_matches(db[i], name, namelen) ||
(res_specified && res_matches(db[i], xres, yres))) &&
!fb_try_mode(var, info, &db[i], bpp)) {
if (refresh_specified && db[i].refresh == refresh) {
DPRINTK("CVT mode %dx%d@%dHz%s%s%s\n", xres, yres,
(refresh) ? refresh : 60,
(rb) ? " reduced blanking" : "",
(margins) ? " with margins" : "",
(interlace) ? " interlaced" : "");
memset(&cvt_mode, 0, sizeof(cvt_mode));
cvt_mode.xres = xres;
cvt_mode.yres = yres;
cvt_mode.refresh = (refresh) ? refresh : 60;
if (interlace)
cvt_mode.vmode |= FB_VMODE_INTERLACED;
else
cvt_mode.vmode &= ~FB_VMODE_INTERLACED;
ret = fb_find_mode_cvt(&cvt_mode, margins, rb);
if (!ret && !fb_try_mode(var, info, &cvt_mode, bpp)) {
DPRINTK("modedb CVT: CVT mode ok\n");
return 1;
}
DPRINTK("CVT mode invalid, getting mode from database\n");
}
DPRINTK("Trying specified video mode%s %ix%i\n",
refresh_specified ? "" : " (ignoring refresh rate)",
xres, yres);
if (!refresh_specified) {
/*
* If the caller has provided a custom mode database and
* a valid monspecs structure, we look for the mode with
* the highest refresh rate. Otherwise we play it safe
* it and try to find a mode with a refresh rate closest
* to the standard 60 Hz.
*/
if (db != modedb &&
info->monspecs.vfmin && info->monspecs.vfmax &&
info->monspecs.hfmin && info->monspecs.hfmax &&
info->monspecs.dclkmax) {
refresh = 1000;
} else {
refresh = 60;
}
}
diff = -1;
best = -1;
for (i = 0; i < dbsize; i++) {
if ((name_matches(db[i], name, namelen) ||
(res_specified && res_matches(db[i], xres, yres))) &&
!fb_try_mode(var, info, &db[i], bpp)) {
if (refresh_specified && db[i].refresh == refresh)
return 1;
if (abs(db[i].refresh - refresh) < diff) {
diff = abs(db[i].refresh - refresh);
best = i;
}
}
}
}
if (best != -1) {
fb_try_mode(var, info, &db[best], bpp);
return (refresh_specified) ? 2 : 1;
}
if (best != -1) {
fb_try_mode(var, info, &db[best], bpp);
return (refresh_specified) ? 2 : 1;
}
diff = 2 * (xres + yres);
best = -1;
DPRINTK("Trying best-fit modes\n");
for (i = 0; i < dbsize; i++) {
DPRINTK("Trying %ix%i\n", db[i].xres, db[i].yres);
if (!fb_try_mode(var, info, &db[i], bpp)) {
tdiff = abs(db[i].xres - xres) +
abs(db[i].yres - yres);
diff = 2 * (xres + yres);
best = -1;
DPRINTK("Trying best-fit modes\n");
for (i = 0; i < dbsize; i++) {
DPRINTK("Trying %ix%i\n", db[i].xres, db[i].yres);
if (!fb_try_mode(var, info, &db[i], bpp)) {
tdiff = abs(db[i].xres - xres) +
abs(db[i].yres - yres);
/*
* Penalize modes with resolutions smaller
* than requested.
*/
if (xres > db[i].xres || yres > db[i].yres)
tdiff += xres + yres;
/*
* Penalize modes with resolutions smaller
* than requested.
*/
if (xres > db[i].xres || yres > db[i].yres)
tdiff += xres + yres;
if (diff > tdiff) {
diff = tdiff;
best = i;
if (diff > tdiff) {
diff = tdiff;
best = i;
}
}
}
if (best != -1) {
fb_try_mode(var, info, &db[best], bpp);
return 5;
}
}
if (best != -1) {
fb_try_mode(var, info, &db[best], bpp);
return 5;
}
}
DPRINTK("Trying default video mode\n");
if (!fb_try_mode(var, info, default_mode, default_bpp))
return 3;
DPRINTK("Trying default video mode\n");
if (!fb_try_mode(var, info, default_mode, default_bpp))
return 3;
DPRINTK("Trying all modes\n");
for (i = 0; i < dbsize; i++)
if (!fb_try_mode(var, info, &db[i], default_bpp))
return 4;
DPRINTK("Trying all modes\n");
for (i = 0; i < dbsize; i++)
if (!fb_try_mode(var, info, &db[i], default_bpp))
return 4;
DPRINTK("No valid mode found\n");
return 0;
DPRINTK("No valid mode found\n");
return 0;
}
/**

View File

@ -715,7 +715,7 @@ static int __devinit mddi_probe(struct platform_device *pdev)
mddi->int_enable = 0;
mddi_writel(mddi->int_enable, INTEN);
ret = request_irq(mddi->irq, mddi_isr, IRQF_DISABLED, "mddi",
ret = request_irq(mddi->irq, mddi_isr, 0, "mddi",
&mddi->client_data);
if (ret) {
printk(KERN_ERR "mddi: failed to request enable irq!\n");

View File

@ -421,10 +421,11 @@ int mdp_probe(struct platform_device *pdev)
clk = clk_get(&pdev->dev, "mdp_clk");
if (IS_ERR(clk)) {
printk(KERN_INFO "mdp: failed to get mdp clk");
return PTR_ERR(clk);
ret = PTR_ERR(clk);
goto error_get_clk;
}
ret = request_irq(mdp->irq, mdp_isr, IRQF_DISABLED, "msm_mdp", mdp);
ret = request_irq(mdp->irq, mdp_isr, 0, "msm_mdp", mdp);
if (ret)
goto error_request_irq;
disable_irq(mdp->irq);
@ -495,6 +496,7 @@ int mdp_probe(struct platform_device *pdev)
error_device_register:
free_irq(mdp->irq, mdp);
error_request_irq:
error_get_clk:
iounmap(mdp->base);
error_get_irq:
error_ioremap:

View File

@ -382,6 +382,9 @@ static void sdc_disable_channel(struct mx3fb_info *mx3_fbi)
uint32_t enabled;
unsigned long flags;
if (mx3_fbi->txd == NULL)
return;
spin_lock_irqsave(&mx3fb->lock, flags);
enabled = sdc_fb_uninit(mx3_fbi);
@ -986,9 +989,19 @@ static void __blank(int blank, struct fb_info *fbi)
{
struct mx3fb_info *mx3_fbi = fbi->par;
struct mx3fb_data *mx3fb = mx3_fbi->mx3fb;
int was_blank = mx3_fbi->blank;
mx3_fbi->blank = blank;
/* Attention!
* Do not call sdc_disable_channel() for a channel that is disabled
* already! This will result in a kernel NULL pointer dereference
* (mx3_fbi->txd is NULL). Hide the fact, that all blank modes are
* handled equally by this driver.
*/
if (blank > FB_BLANK_UNBLANK && was_blank > FB_BLANK_UNBLANK)
return;
switch (blank) {
case FB_BLANK_POWERDOWN:
case FB_BLANK_VSYNC_SUSPEND:
@ -1062,15 +1075,15 @@ static int mx3fb_pan_display(struct fb_var_screeninfo *var,
y_bottom = var->yoffset;
if (!(var->vmode & FB_VMODE_YWRAP))
y_bottom += var->yres;
y_bottom += fbi->var.yres;
if (y_bottom > fbi->var.yres_virtual)
return -EINVAL;
mutex_lock(&mx3_fbi->mutex);
offset = (var->yoffset * var->xres_virtual + var->xoffset) *
(var->bits_per_pixel / 8);
offset = var->yoffset * fbi->fix.line_length
+ var->xoffset * (fbi->var.bits_per_pixel / 8);
base = fbi->fix.smem_start + offset;
dev_dbg(fbi->device, "Updating SDC BG buf %d address=0x%08lX\n",

View File

@ -39,6 +39,7 @@
* the required value in the imx_fb_videomode structure.
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/clk.h>

View File

@ -1185,8 +1185,8 @@ static int neofb_pan_display(struct fb_var_screeninfo *var,
DBG("neofb_update_start");
Base = (var->yoffset * var->xres_virtual + var->xoffset) >> 2;
Base *= (var->bits_per_pixel + 7) / 8;
Base = (var->yoffset * info->var.xres_virtual + var->xoffset) >> 2;
Base *= (info->var.bits_per_pixel + 7) / 8;
neoUnlock();

View File

@ -39,7 +39,6 @@
#include <mach/regs-clock.h>
#include <mach/regs-ldm.h>
#include <mach/fb.h>
#include <mach/clkdev.h>
#include "nuc900fb.h"
@ -588,7 +587,7 @@ static int __devinit nuc900fb_probe(struct platform_device *pdev)
fbinfo->flags = FBINFO_FLAG_DEFAULT;
fbinfo->pseudo_palette = &fbi->pseudo_pal;
ret = request_irq(irq, nuc900fb_irqhandler, IRQF_DISABLED,
ret = request_irq(irq, nuc900fb_irqhandler, 0,
pdev->name, fbinfo);
if (ret) {
dev_err(&pdev->dev, "cannot register irq handler %d -err %d\n",

View File

@ -9,35 +9,6 @@ config FB_OMAP
help
Frame buffer driver for OMAP based boards.
config FB_OMAP_LCD_VGA
bool "Use LCD in VGA mode"
depends on MACH_OMAP_3430SDP || MACH_OMAP_LDP
help
Set LCD resolution as VGA (640 X 480).
Default resolution without this option is QVGA(320 X 240).
Please take a look at drivers/video/omap/lcd_ldp.c file
for lcd driver code.
choice
depends on FB_OMAP && MACH_OVERO
prompt "Screen resolution"
default FB_OMAP_079M3R
help
Selected desired screen resolution
config FB_OMAP_031M3R
boolean "640 x 480 @ 60 Hz Reduced blanking"
config FB_OMAP_048M3R
boolean "800 x 600 @ 60 Hz Reduced blanking"
config FB_OMAP_079M3R
boolean "1024 x 768 @ 60 Hz Reduced blanking"
config FB_OMAP_092M9R
boolean "1280 x 720 @ 60 Hz Reduced blanking"
endchoice
config FB_OMAP_LCDC_EXTERNAL
bool "External LCD controller support"
depends on FB_OMAP

View File

@ -17,7 +17,6 @@ objs-y$(CONFIG_FB_OMAP_LCDC_HWA742) += hwa742.o
objs-y$(CONFIG_FB_OMAP_LCDC_BLIZZARD) += blizzard.o
objs-y$(CONFIG_MACH_AMS_DELTA) += lcd_ams_delta.o
objs-y$(CONFIG_MACH_OMAP_H4) += lcd_h4.o
objs-y$(CONFIG_MACH_OMAP_H3) += lcd_h3.o
objs-y$(CONFIG_MACH_OMAP_PALMTE) += lcd_palmte.o
objs-y$(CONFIG_MACH_OMAP_PALMTT) += lcd_palmtt.o
@ -26,14 +25,7 @@ objs-$(CONFIG_ARCH_OMAP16XX)$(CONFIG_MACH_OMAP_INNOVATOR) += lcd_inn1610.o
objs-$(CONFIG_ARCH_OMAP15XX)$(CONFIG_MACH_OMAP_INNOVATOR) += lcd_inn1510.o
objs-y$(CONFIG_MACH_OMAP_OSK) += lcd_osk.o
objs-y$(CONFIG_MACH_OMAP_APOLLON) += lcd_apollon.o
objs-y$(CONFIG_MACH_OMAP_2430SDP) += lcd_2430sdp.o
objs-y$(CONFIG_MACH_OMAP_3430SDP) += lcd_2430sdp.o
objs-y$(CONFIG_MACH_OMAP_LDP) += lcd_ldp.o
objs-y$(CONFIG_MACH_OMAP3EVM) += lcd_omap3evm.o
objs-y$(CONFIG_MACH_OMAP3_BEAGLE) += lcd_omap3beagle.o
objs-y$(CONFIG_FB_OMAP_LCD_MIPID) += lcd_mipid.o
objs-y$(CONFIG_MACH_OVERO) += lcd_overo.o
objs-y$(CONFIG_MACH_HERALD) += lcd_htcherald.o
omapfb-objs := $(objs-yy)

View File

@ -1,203 +0,0 @@
/*
* LCD panel support for the TI 2430SDP board
*
* Copyright (C) 2007 MontaVista
* Author: Hunyue Yau <hyau@mvista.com>
*
* Derived from drivers/video/omap/lcd-apollon.c
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* 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.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/gpio.h>
#include <linux/i2c/twl.h>
#include <plat/mux.h>
#include <asm/mach-types.h>
#include "omapfb.h"
#define SDP2430_LCD_PANEL_BACKLIGHT_GPIO 91
#define SDP2430_LCD_PANEL_ENABLE_GPIO 154
#define SDP3430_LCD_PANEL_BACKLIGHT_GPIO 24
#define SDP3430_LCD_PANEL_ENABLE_GPIO 28
static unsigned backlight_gpio;
static unsigned enable_gpio;
#define LCD_PIXCLOCK_MAX 5400 /* freq 5.4 MHz */
#define PM_RECEIVER TWL4030_MODULE_PM_RECEIVER
#define ENABLE_VAUX2_DEDICATED 0x09
#define ENABLE_VAUX2_DEV_GRP 0x20
#define ENABLE_VAUX3_DEDICATED 0x03
#define ENABLE_VAUX3_DEV_GRP 0x20
#define ENABLE_VPLL2_DEDICATED 0x05
#define ENABLE_VPLL2_DEV_GRP 0xE0
#define TWL4030_VPLL2_DEV_GRP 0x33
#define TWL4030_VPLL2_DEDICATED 0x36
#define t2_out(c, r, v) twl_i2c_write_u8(c, r, v)
static int sdp2430_panel_init(struct lcd_panel *panel,
struct omapfb_device *fbdev)
{
if (machine_is_omap_3430sdp()) {
enable_gpio = SDP3430_LCD_PANEL_ENABLE_GPIO;
backlight_gpio = SDP3430_LCD_PANEL_BACKLIGHT_GPIO;
} else {
enable_gpio = SDP2430_LCD_PANEL_ENABLE_GPIO;
backlight_gpio = SDP2430_LCD_PANEL_BACKLIGHT_GPIO;
}
gpio_request(enable_gpio, "LCD enable"); /* LCD panel */
gpio_request(backlight_gpio, "LCD bl"); /* LCD backlight */
gpio_direction_output(enable_gpio, 0);
gpio_direction_output(backlight_gpio, 0);
return 0;
}
static void sdp2430_panel_cleanup(struct lcd_panel *panel)
{
gpio_free(backlight_gpio);
gpio_free(enable_gpio);
}
static int sdp2430_panel_enable(struct lcd_panel *panel)
{
u8 ded_val, ded_reg;
u8 grp_val, grp_reg;
if (machine_is_omap_3430sdp()) {
ded_reg = TWL4030_VAUX3_DEDICATED;
ded_val = ENABLE_VAUX3_DEDICATED;
grp_reg = TWL4030_VAUX3_DEV_GRP;
grp_val = ENABLE_VAUX3_DEV_GRP;
if (omap_rev() > OMAP3430_REV_ES1_0) {
t2_out(PM_RECEIVER, ENABLE_VPLL2_DEDICATED,
TWL4030_VPLL2_DEDICATED);
t2_out(PM_RECEIVER, ENABLE_VPLL2_DEV_GRP,
TWL4030_VPLL2_DEV_GRP);
}
} else {
ded_reg = TWL4030_VAUX2_DEDICATED;
ded_val = ENABLE_VAUX2_DEDICATED;
grp_reg = TWL4030_VAUX2_DEV_GRP;
grp_val = ENABLE_VAUX2_DEV_GRP;
}
gpio_set_value(enable_gpio, 1);
gpio_set_value(backlight_gpio, 1);
if (0 != t2_out(PM_RECEIVER, ded_val, ded_reg))
return -EIO;
if (0 != t2_out(PM_RECEIVER, grp_val, grp_reg))
return -EIO;
return 0;
}
static void sdp2430_panel_disable(struct lcd_panel *panel)
{
gpio_set_value(enable_gpio, 0);
gpio_set_value(backlight_gpio, 0);
if (omap_rev() > OMAP3430_REV_ES1_0) {
t2_out(PM_RECEIVER, 0x0, TWL4030_VPLL2_DEDICATED);
t2_out(PM_RECEIVER, 0x0, TWL4030_VPLL2_DEV_GRP);
msleep(4);
}
}
static unsigned long sdp2430_panel_get_caps(struct lcd_panel *panel)
{
return 0;
}
struct lcd_panel sdp2430_panel = {
.name = "sdp2430",
.config = OMAP_LCDC_PANEL_TFT | OMAP_LCDC_INV_VSYNC |
OMAP_LCDC_INV_HSYNC,
.bpp = 16,
.data_lines = 16,
.x_res = 240,
.y_res = 320,
.hsw = 3, /* hsync_len (4) - 1 */
.hfp = 3, /* right_margin (4) - 1 */
.hbp = 39, /* left_margin (40) - 1 */
.vsw = 1, /* vsync_len (2) - 1 */
.vfp = 2, /* lower_margin */
.vbp = 7, /* upper_margin (8) - 1 */
.pixel_clock = LCD_PIXCLOCK_MAX,
.init = sdp2430_panel_init,
.cleanup = sdp2430_panel_cleanup,
.enable = sdp2430_panel_enable,
.disable = sdp2430_panel_disable,
.get_caps = sdp2430_panel_get_caps,
};
static int sdp2430_panel_probe(struct platform_device *pdev)
{
omapfb_register_panel(&sdp2430_panel);
return 0;
}
static int sdp2430_panel_remove(struct platform_device *pdev)
{
return 0;
}
static int sdp2430_panel_suspend(struct platform_device *pdev,
pm_message_t mesg)
{
return 0;
}
static int sdp2430_panel_resume(struct platform_device *pdev)
{
return 0;
}
struct platform_driver sdp2430_panel_driver = {
.probe = sdp2430_panel_probe,
.remove = sdp2430_panel_remove,
.suspend = sdp2430_panel_suspend,
.resume = sdp2430_panel_resume,
.driver = {
.name = "sdp2430_lcd",
.owner = THIS_MODULE,
},
};
static int __init sdp2430_panel_drv_init(void)
{
return platform_driver_register(&sdp2430_panel_driver);
}
static void __exit sdp2430_panel_drv_exit(void)
{
platform_driver_unregister(&sdp2430_panel_driver);
}
module_init(sdp2430_panel_drv_init);
module_exit(sdp2430_panel_drv_exit);

View File

@ -1,136 +0,0 @@
/*
* LCD panel support for the Samsung OMAP2 Apollon board
*
* Copyright (C) 2005,2006 Samsung Electronics
* Author: Kyungmin Park <kyungmin.park@samsung.com>
*
* Derived from drivers/video/omap/lcd-h4.c
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* 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.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <linux/module.h>
#include <linux/platform_device.h>
#include <asm/gpio.h>
#include "omapfb.h"
/* #define USE_35INCH_LCD 1 */
static int apollon_panel_init(struct lcd_panel *panel,
struct omapfb_device *fbdev)
{
return 0;
}
static void apollon_panel_cleanup(struct lcd_panel *panel)
{
}
static int apollon_panel_enable(struct lcd_panel *panel)
{
return 0;
}
static void apollon_panel_disable(struct lcd_panel *panel)
{
}
static unsigned long apollon_panel_get_caps(struct lcd_panel *panel)
{
return 0;
}
struct lcd_panel apollon_panel = {
.name = "apollon",
.config = OMAP_LCDC_PANEL_TFT | OMAP_LCDC_INV_VSYNC |
OMAP_LCDC_INV_HSYNC,
.bpp = 16,
.data_lines = 18,
#ifdef USE_35INCH_LCD
.x_res = 240,
.y_res = 320,
.hsw = 2,
.hfp = 3,
.hbp = 9,
.vsw = 4,
.vfp = 3,
.vbp = 5,
#else
.x_res = 480,
.y_res = 272,
.hsw = 41,
.hfp = 2,
.hbp = 2,
.vsw = 10,
.vfp = 2,
.vbp = 2,
#endif
.pixel_clock = 6250,
.init = apollon_panel_init,
.cleanup = apollon_panel_cleanup,
.enable = apollon_panel_enable,
.disable = apollon_panel_disable,
.get_caps = apollon_panel_get_caps,
};
static int apollon_panel_probe(struct platform_device *pdev)
{
omapfb_register_panel(&apollon_panel);
return 0;
}
static int apollon_panel_remove(struct platform_device *pdev)
{
return 0;
}
static int apollon_panel_suspend(struct platform_device *pdev,
pm_message_t mesg)
{
return 0;
}
static int apollon_panel_resume(struct platform_device *pdev)
{
return 0;
}
struct platform_driver apollon_panel_driver = {
.probe = apollon_panel_probe,
.remove = apollon_panel_remove,
.suspend = apollon_panel_suspend,
.resume = apollon_panel_resume,
.driver = {
.name = "apollon_lcd",
.owner = THIS_MODULE,
},
};
static int __init apollon_panel_drv_init(void)
{
return platform_driver_register(&apollon_panel_driver);
}
static void __exit apollon_panel_drv_exit(void)
{
platform_driver_unregister(&apollon_panel_driver);
}
module_init(apollon_panel_drv_init);
module_exit(apollon_panel_drv_exit);

View File

@ -1,117 +0,0 @@
/*
* LCD panel support for the TI OMAP H4 board
*
* Copyright (C) 2004 Nokia Corporation
* Author: Imre Deak <imre.deak@nokia.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* 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.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <linux/module.h>
#include <linux/platform_device.h>
#include "omapfb.h"
static int h4_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev)
{
return 0;
}
static void h4_panel_cleanup(struct lcd_panel *panel)
{
}
static int h4_panel_enable(struct lcd_panel *panel)
{
return 0;
}
static void h4_panel_disable(struct lcd_panel *panel)
{
}
static unsigned long h4_panel_get_caps(struct lcd_panel *panel)
{
return 0;
}
static struct lcd_panel h4_panel = {
.name = "h4",
.config = OMAP_LCDC_PANEL_TFT,
.bpp = 16,
.data_lines = 16,
.x_res = 240,
.y_res = 320,
.pixel_clock = 6250,
.hsw = 15,
.hfp = 15,
.hbp = 60,
.vsw = 1,
.vfp = 1,
.vbp = 1,
.init = h4_panel_init,
.cleanup = h4_panel_cleanup,
.enable = h4_panel_enable,
.disable = h4_panel_disable,
.get_caps = h4_panel_get_caps,
};
static int h4_panel_probe(struct platform_device *pdev)
{
omapfb_register_panel(&h4_panel);
return 0;
}
static int h4_panel_remove(struct platform_device *pdev)
{
return 0;
}
static int h4_panel_suspend(struct platform_device *pdev, pm_message_t mesg)
{
return 0;
}
static int h4_panel_resume(struct platform_device *pdev)
{
return 0;
}
static struct platform_driver h4_panel_driver = {
.probe = h4_panel_probe,
.remove = h4_panel_remove,
.suspend = h4_panel_suspend,
.resume = h4_panel_resume,
.driver = {
.name = "lcd_h4",
.owner = THIS_MODULE,
},
};
static int __init h4_panel_drv_init(void)
{
return platform_driver_register(&h4_panel_driver);
}
static void __exit h4_panel_drv_cleanup(void)
{
platform_driver_unregister(&h4_panel_driver);
}
module_init(h4_panel_drv_init);
module_exit(h4_panel_drv_cleanup);

View File

@ -1,201 +0,0 @@
/*
* LCD panel support for the TI LDP board
*
* Copyright (C) 2007 WindRiver
* Author: Stanley Miao <stanley.miao@windriver.com>
*
* Derived from drivers/video/omap/lcd-2430sdp.c
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* 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.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/i2c/twl.h>
#include <asm/gpio.h>
#include <plat/mux.h>
#include <asm/mach-types.h>
#include "omapfb.h"
#define LCD_PANEL_BACKLIGHT_GPIO (15 + OMAP_MAX_GPIO_LINES)
#define LCD_PANEL_ENABLE_GPIO (7 + OMAP_MAX_GPIO_LINES)
#define LCD_PANEL_RESET_GPIO 55
#define LCD_PANEL_QVGA_GPIO 56
#ifdef CONFIG_FB_OMAP_LCD_VGA
#define LCD_XRES 480
#define LCD_YRES 640
#define LCD_PIXCLOCK_MAX 41700
#else
#define LCD_XRES 240
#define LCD_YRES 320
#define LCD_PIXCLOCK_MAX 185186
#endif
#define PM_RECEIVER TWL4030_MODULE_PM_RECEIVER
#define ENABLE_VAUX2_DEDICATED 0x09
#define ENABLE_VAUX2_DEV_GRP 0x20
#define ENABLE_VAUX3_DEDICATED 0x03
#define ENABLE_VAUX3_DEV_GRP 0x20
#define ENABLE_VPLL2_DEDICATED 0x05
#define ENABLE_VPLL2_DEV_GRP 0xE0
#define TWL4030_VPLL2_DEV_GRP 0x33
#define TWL4030_VPLL2_DEDICATED 0x36
#define t2_out(c, r, v) twl_i2c_write_u8(c, r, v)
static int ldp_panel_init(struct lcd_panel *panel,
struct omapfb_device *fbdev)
{
gpio_request(LCD_PANEL_RESET_GPIO, "lcd reset");
gpio_request(LCD_PANEL_QVGA_GPIO, "lcd qvga");
gpio_request(LCD_PANEL_ENABLE_GPIO, "lcd panel");
gpio_request(LCD_PANEL_BACKLIGHT_GPIO, "lcd backlight");
gpio_direction_output(LCD_PANEL_QVGA_GPIO, 0);
gpio_direction_output(LCD_PANEL_RESET_GPIO, 0);
gpio_direction_output(LCD_PANEL_ENABLE_GPIO, 0);
gpio_direction_output(LCD_PANEL_BACKLIGHT_GPIO, 0);
#ifdef CONFIG_FB_OMAP_LCD_VGA
gpio_set_value(LCD_PANEL_QVGA_GPIO, 0);
#else
gpio_set_value(LCD_PANEL_QVGA_GPIO, 1);
#endif
gpio_set_value(LCD_PANEL_RESET_GPIO, 1);
return 0;
}
static void ldp_panel_cleanup(struct lcd_panel *panel)
{
gpio_free(LCD_PANEL_BACKLIGHT_GPIO);
gpio_free(LCD_PANEL_ENABLE_GPIO);
gpio_free(LCD_PANEL_QVGA_GPIO);
gpio_free(LCD_PANEL_RESET_GPIO);
}
static int ldp_panel_enable(struct lcd_panel *panel)
{
if (0 != t2_out(PM_RECEIVER, ENABLE_VPLL2_DEDICATED,
TWL4030_VPLL2_DEDICATED))
return -EIO;
if (0 != t2_out(PM_RECEIVER, ENABLE_VPLL2_DEV_GRP,
TWL4030_VPLL2_DEV_GRP))
return -EIO;
gpio_direction_output(LCD_PANEL_ENABLE_GPIO, 1);
gpio_direction_output(LCD_PANEL_BACKLIGHT_GPIO, 1);
if (0 != t2_out(PM_RECEIVER, ENABLE_VAUX3_DEDICATED,
TWL4030_VAUX3_DEDICATED))
return -EIO;
if (0 != t2_out(PM_RECEIVER, ENABLE_VAUX3_DEV_GRP,
TWL4030_VAUX3_DEV_GRP))
return -EIO;
return 0;
}
static void ldp_panel_disable(struct lcd_panel *panel)
{
gpio_direction_output(LCD_PANEL_ENABLE_GPIO, 0);
gpio_direction_output(LCD_PANEL_BACKLIGHT_GPIO, 0);
t2_out(PM_RECEIVER, 0x0, TWL4030_VPLL2_DEDICATED);
t2_out(PM_RECEIVER, 0x0, TWL4030_VPLL2_DEV_GRP);
msleep(4);
}
static unsigned long ldp_panel_get_caps(struct lcd_panel *panel)
{
return 0;
}
struct lcd_panel ldp_panel = {
.name = "ldp",
.config = OMAP_LCDC_PANEL_TFT | OMAP_LCDC_INV_VSYNC |
OMAP_LCDC_INV_HSYNC,
.bpp = 16,
.data_lines = 18,
.x_res = LCD_XRES,
.y_res = LCD_YRES,
.hsw = 3, /* hsync_len (4) - 1 */
.hfp = 3, /* right_margin (4) - 1 */
.hbp = 39, /* left_margin (40) - 1 */
.vsw = 1, /* vsync_len (2) - 1 */
.vfp = 2, /* lower_margin */
.vbp = 7, /* upper_margin (8) - 1 */
.pixel_clock = LCD_PIXCLOCK_MAX,
.init = ldp_panel_init,
.cleanup = ldp_panel_cleanup,
.enable = ldp_panel_enable,
.disable = ldp_panel_disable,
.get_caps = ldp_panel_get_caps,
};
static int ldp_panel_probe(struct platform_device *pdev)
{
omapfb_register_panel(&ldp_panel);
return 0;
}
static int ldp_panel_remove(struct platform_device *pdev)
{
return 0;
}
static int ldp_panel_suspend(struct platform_device *pdev, pm_message_t mesg)
{
return 0;
}
static int ldp_panel_resume(struct platform_device *pdev)
{
return 0;
}
struct platform_driver ldp_panel_driver = {
.probe = ldp_panel_probe,
.remove = ldp_panel_remove,
.suspend = ldp_panel_suspend,
.resume = ldp_panel_resume,
.driver = {
.name = "ldp_lcd",
.owner = THIS_MODULE,
},
};
static int __init ldp_panel_drv_init(void)
{
return platform_driver_register(&ldp_panel_driver);
}
static void __exit ldp_panel_drv_exit(void)
{
platform_driver_unregister(&ldp_panel_driver);
}
module_init(ldp_panel_drv_init);
module_exit(ldp_panel_drv_exit);

View File

@ -1,130 +0,0 @@
/*
* LCD panel support for the TI OMAP3 Beagle board
*
* Author: Koen Kooi <koen@openembedded.org>
*
* Derived from drivers/video/omap/lcd-omap3evm.c
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* 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.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/i2c/twl.h>
#include <asm/mach-types.h>
#include "omapfb.h"
#define LCD_PANEL_ENABLE_GPIO 170
static int omap3beagle_panel_init(struct lcd_panel *panel,
struct omapfb_device *fbdev)
{
gpio_request(LCD_PANEL_ENABLE_GPIO, "LCD enable");
return 0;
}
static void omap3beagle_panel_cleanup(struct lcd_panel *panel)
{
gpio_free(LCD_PANEL_ENABLE_GPIO);
}
static int omap3beagle_panel_enable(struct lcd_panel *panel)
{
gpio_set_value(LCD_PANEL_ENABLE_GPIO, 1);
return 0;
}
static void omap3beagle_panel_disable(struct lcd_panel *panel)
{
gpio_set_value(LCD_PANEL_ENABLE_GPIO, 0);
}
static unsigned long omap3beagle_panel_get_caps(struct lcd_panel *panel)
{
return 0;
}
struct lcd_panel omap3beagle_panel = {
.name = "omap3beagle",
.config = OMAP_LCDC_PANEL_TFT,
.bpp = 16,
.data_lines = 24,
.x_res = 1024,
.y_res = 768,
.hsw = 3, /* hsync_len (4) - 1 */
.hfp = 3, /* right_margin (4) - 1 */
.hbp = 39, /* left_margin (40) - 1 */
.vsw = 1, /* vsync_len (2) - 1 */
.vfp = 2, /* lower_margin */
.vbp = 7, /* upper_margin (8) - 1 */
.pixel_clock = 64000,
.init = omap3beagle_panel_init,
.cleanup = omap3beagle_panel_cleanup,
.enable = omap3beagle_panel_enable,
.disable = omap3beagle_panel_disable,
.get_caps = omap3beagle_panel_get_caps,
};
static int omap3beagle_panel_probe(struct platform_device *pdev)
{
omapfb_register_panel(&omap3beagle_panel);
return 0;
}
static int omap3beagle_panel_remove(struct platform_device *pdev)
{
return 0;
}
static int omap3beagle_panel_suspend(struct platform_device *pdev,
pm_message_t mesg)
{
return 0;
}
static int omap3beagle_panel_resume(struct platform_device *pdev)
{
return 0;
}
struct platform_driver omap3beagle_panel_driver = {
.probe = omap3beagle_panel_probe,
.remove = omap3beagle_panel_remove,
.suspend = omap3beagle_panel_suspend,
.resume = omap3beagle_panel_resume,
.driver = {
.name = "omap3beagle_lcd",
.owner = THIS_MODULE,
},
};
static int __init omap3beagle_panel_drv_init(void)
{
return platform_driver_register(&omap3beagle_panel_driver);
}
static void __exit omap3beagle_panel_drv_exit(void)
{
platform_driver_unregister(&omap3beagle_panel_driver);
}
module_init(omap3beagle_panel_drv_init);
module_exit(omap3beagle_panel_drv_exit);

View File

@ -1,193 +0,0 @@
/*
* LCD panel support for the TI OMAP3 EVM board
*
* Author: Steve Sakoman <steve@sakoman.com>
*
* Derived from drivers/video/omap/lcd-apollon.c
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* 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.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/i2c/twl.h>
#include <plat/mux.h>
#include <asm/mach-types.h>
#include "omapfb.h"
#define LCD_PANEL_ENABLE_GPIO 153
#define LCD_PANEL_LR 2
#define LCD_PANEL_UD 3
#define LCD_PANEL_INI 152
#define LCD_PANEL_QVGA 154
#define LCD_PANEL_RESB 155
#define ENABLE_VDAC_DEDICATED 0x03
#define ENABLE_VDAC_DEV_GRP 0x20
#define ENABLE_VPLL2_DEDICATED 0x05
#define ENABLE_VPLL2_DEV_GRP 0xE0
#define TWL_LED_LEDEN 0x00
#define TWL_PWMA_PWMAON 0x00
#define TWL_PWMA_PWMAOFF 0x01
static unsigned int bklight_level;
static int omap3evm_panel_init(struct lcd_panel *panel,
struct omapfb_device *fbdev)
{
gpio_request(LCD_PANEL_LR, "LCD lr");
gpio_request(LCD_PANEL_UD, "LCD ud");
gpio_request(LCD_PANEL_INI, "LCD ini");
gpio_request(LCD_PANEL_RESB, "LCD resb");
gpio_request(LCD_PANEL_QVGA, "LCD qvga");
gpio_direction_output(LCD_PANEL_RESB, 1);
gpio_direction_output(LCD_PANEL_INI, 1);
gpio_direction_output(LCD_PANEL_QVGA, 0);
gpio_direction_output(LCD_PANEL_LR, 1);
gpio_direction_output(LCD_PANEL_UD, 1);
twl_i2c_write_u8(TWL4030_MODULE_LED, 0x11, TWL_LED_LEDEN);
twl_i2c_write_u8(TWL4030_MODULE_PWMA, 0x01, TWL_PWMA_PWMAON);
twl_i2c_write_u8(TWL4030_MODULE_PWMA, 0x02, TWL_PWMA_PWMAOFF);
bklight_level = 100;
return 0;
}
static void omap3evm_panel_cleanup(struct lcd_panel *panel)
{
gpio_free(LCD_PANEL_QVGA);
gpio_free(LCD_PANEL_RESB);
gpio_free(LCD_PANEL_INI);
gpio_free(LCD_PANEL_UD);
gpio_free(LCD_PANEL_LR);
}
static int omap3evm_panel_enable(struct lcd_panel *panel)
{
gpio_set_value(LCD_PANEL_ENABLE_GPIO, 0);
return 0;
}
static void omap3evm_panel_disable(struct lcd_panel *panel)
{
gpio_set_value(LCD_PANEL_ENABLE_GPIO, 1);
}
static unsigned long omap3evm_panel_get_caps(struct lcd_panel *panel)
{
return 0;
}
static int omap3evm_bklight_setlevel(struct lcd_panel *panel,
unsigned int level)
{
u8 c;
if ((level >= 0) && (level <= 100)) {
c = (125 * (100 - level)) / 100 + 2;
twl_i2c_write_u8(TWL4030_MODULE_PWMA, c, TWL_PWMA_PWMAOFF);
bklight_level = level;
}
return 0;
}
static unsigned int omap3evm_bklight_getlevel(struct lcd_panel *panel)
{
return bklight_level;
}
static unsigned int omap3evm_bklight_getmaxlevel(struct lcd_panel *panel)
{
return 100;
}
struct lcd_panel omap3evm_panel = {
.name = "omap3evm",
.config = OMAP_LCDC_PANEL_TFT | OMAP_LCDC_INV_VSYNC |
OMAP_LCDC_INV_HSYNC,
.bpp = 16,
.data_lines = 18,
.x_res = 480,
.y_res = 640,
.hsw = 3, /* hsync_len (4) - 1 */
.hfp = 3, /* right_margin (4) - 1 */
.hbp = 39, /* left_margin (40) - 1 */
.vsw = 1, /* vsync_len (2) - 1 */
.vfp = 2, /* lower_margin */
.vbp = 7, /* upper_margin (8) - 1 */
.pixel_clock = 26000,
.init = omap3evm_panel_init,
.cleanup = omap3evm_panel_cleanup,
.enable = omap3evm_panel_enable,
.disable = omap3evm_panel_disable,
.get_caps = omap3evm_panel_get_caps,
.set_bklight_level = omap3evm_bklight_setlevel,
.get_bklight_level = omap3evm_bklight_getlevel,
.get_bklight_max = omap3evm_bklight_getmaxlevel,
};
static int omap3evm_panel_probe(struct platform_device *pdev)
{
omapfb_register_panel(&omap3evm_panel);
return 0;
}
static int omap3evm_panel_remove(struct platform_device *pdev)
{
return 0;
}
static int omap3evm_panel_suspend(struct platform_device *pdev,
pm_message_t mesg)
{
return 0;
}
static int omap3evm_panel_resume(struct platform_device *pdev)
{
return 0;
}
struct platform_driver omap3evm_panel_driver = {
.probe = omap3evm_panel_probe,
.remove = omap3evm_panel_remove,
.suspend = omap3evm_panel_suspend,
.resume = omap3evm_panel_resume,
.driver = {
.name = "omap3evm_lcd",
.owner = THIS_MODULE,
},
};
static int __init omap3evm_panel_drv_init(void)
{
return platform_driver_register(&omap3evm_panel_driver);
}
static void __exit omap3evm_panel_drv_exit(void)
{
platform_driver_unregister(&omap3evm_panel_driver);
}
module_init(omap3evm_panel_drv_init);
module_exit(omap3evm_panel_drv_exit);

View File

@ -1,180 +0,0 @@
/*
* LCD panel support for the Gumstix Overo
*
* Author: Steve Sakoman <steve@sakoman.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* 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.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/i2c/twl.h>
#include <asm/gpio.h>
#include <plat/mux.h>
#include <asm/mach-types.h>
#include "omapfb.h"
#define LCD_ENABLE 144
static int overo_panel_init(struct lcd_panel *panel,
struct omapfb_device *fbdev)
{
if ((gpio_request(LCD_ENABLE, "LCD_ENABLE") == 0) &&
(gpio_direction_output(LCD_ENABLE, 1) == 0))
gpio_export(LCD_ENABLE, 0);
else
printk(KERN_ERR "could not obtain gpio for LCD_ENABLE\n");
return 0;
}
static void overo_panel_cleanup(struct lcd_panel *panel)
{
gpio_free(LCD_ENABLE);
}
static int overo_panel_enable(struct lcd_panel *panel)
{
gpio_set_value(LCD_ENABLE, 1);
return 0;
}
static void overo_panel_disable(struct lcd_panel *panel)
{
gpio_set_value(LCD_ENABLE, 0);
}
static unsigned long overo_panel_get_caps(struct lcd_panel *panel)
{
return 0;
}
struct lcd_panel overo_panel = {
.name = "overo",
.config = OMAP_LCDC_PANEL_TFT,
.bpp = 16,
.data_lines = 24,
#if defined CONFIG_FB_OMAP_031M3R
/* 640 x 480 @ 60 Hz Reduced blanking VESA CVT 0.31M3-R */
.x_res = 640,
.y_res = 480,
.hfp = 48,
.hsw = 32,
.hbp = 80,
.vfp = 3,
.vsw = 4,
.vbp = 7,
.pixel_clock = 23500,
#elif defined CONFIG_FB_OMAP_048M3R
/* 800 x 600 @ 60 Hz Reduced blanking VESA CVT 0.48M3-R */
.x_res = 800,
.y_res = 600,
.hfp = 48,
.hsw = 32,
.hbp = 80,
.vfp = 3,
.vsw = 4,
.vbp = 11,
.pixel_clock = 35500,
#elif defined CONFIG_FB_OMAP_079M3R
/* 1024 x 768 @ 60 Hz Reduced blanking VESA CVT 0.79M3-R */
.x_res = 1024,
.y_res = 768,
.hfp = 48,
.hsw = 32,
.hbp = 80,
.vfp = 3,
.vsw = 4,
.vbp = 15,
.pixel_clock = 56000,
#elif defined CONFIG_FB_OMAP_092M9R
/* 1280 x 720 @ 60 Hz Reduced blanking VESA CVT 0.92M9-R */
.x_res = 1280,
.y_res = 720,
.hfp = 48,
.hsw = 32,
.hbp = 80,
.vfp = 3,
.vsw = 5,
.vbp = 13,
.pixel_clock = 64000,
#else
/* use 640 x 480 if no config option */
/* 640 x 480 @ 60 Hz Reduced blanking VESA CVT 0.31M3-R */
.x_res = 640,
.y_res = 480,
.hfp = 48,
.hsw = 32,
.hbp = 80,
.vfp = 3,
.vsw = 4,
.vbp = 7,
.pixel_clock = 23500,
#endif
.init = overo_panel_init,
.cleanup = overo_panel_cleanup,
.enable = overo_panel_enable,
.disable = overo_panel_disable,
.get_caps = overo_panel_get_caps,
};
static int overo_panel_probe(struct platform_device *pdev)
{
omapfb_register_panel(&overo_panel);
return 0;
}
static int overo_panel_remove(struct platform_device *pdev)
{
/* omapfb does not have unregister_panel */
return 0;
}
static struct platform_driver overo_panel_driver = {
.probe = overo_panel_probe,
.remove = overo_panel_remove,
.driver = {
.name = "overo_lcd",
.owner = THIS_MODULE,
},
};
static int __init overo_panel_drv_init(void)
{
return platform_driver_register(&overo_panel_driver);
}
static void __exit overo_panel_drv_exit(void)
{
platform_driver_unregister(&overo_panel_driver);
}
module_init(overo_panel_drv_init);
module_exit(overo_panel_drv_exit);

View File

@ -10,6 +10,13 @@ config PANEL_GENERIC_DPI
Supports LCD Panel used in TI SDP3430 and EVM boards,
OMAP3517 EVM boards and CM-T35.
config PANEL_DVI
tristate "DVI output"
depends on OMAP2_DSS_DPI
help
Driver for external monitors, connected via DVI. The driver uses i2c
to read EDID information from the monitor.
config PANEL_LGPHILIPS_LB035Q02
tristate "LG.Philips LB035Q02 LCD Panel"
depends on OMAP2_DSS_DPI && SPI
@ -19,20 +26,30 @@ config PANEL_LGPHILIPS_LB035Q02
config PANEL_SHARP_LS037V7DW01
tristate "Sharp LS037V7DW01 LCD Panel"
depends on OMAP2_DSS_DPI
select BACKLIGHT_CLASS_DEVICE
depends on BACKLIGHT_CLASS_DEVICE
help
LCD Panel used in TI's SDP3430 and EVM boards
config PANEL_NEC_NL8048HL11_01B
tristate "NEC NL8048HL11-01B Panel"
depends on OMAP2_DSS_DPI
depends on SPI
depends on BACKLIGHT_CLASS_DEVICE
help
This NEC NL8048HL11-01B panel is TFT LCD
used in the Zoom2/3/3630 sdp boards.
config PANEL_PICODLP
tristate "TI PICO DLP mini-projector"
depends on OMAP2_DSS && I2C
help
A mini-projector used in TI's SDP4430 and EVM boards
For more info please visit http://www.dlp.com/projector/
config PANEL_TAAL
tristate "Taal DSI Panel"
depends on OMAP2_DSS_DSI
depends on BACKLIGHT_CLASS_DEVICE
help
Taal DSI command mode panel from TPO.
@ -45,7 +62,14 @@ config PANEL_TPO_TD043MTEA1
config PANEL_ACX565AKM
tristate "ACX565AKM Panel"
depends on OMAP2_DSS_SDI && SPI
select BACKLIGHT_CLASS_DEVICE
depends on BACKLIGHT_CLASS_DEVICE
help
This is the LCD panel used on Nokia N900
config PANEL_N8X0
tristate "N8X0 Panel"
depends on OMAP2_DSS_RFBI && SPI
depends on BACKLIGHT_CLASS_DEVICE
help
This is the LCD panel used on Nokia N8x0
endmenu

View File

@ -1,8 +1,11 @@
obj-$(CONFIG_PANEL_GENERIC_DPI) += panel-generic-dpi.o
obj-$(CONFIG_PANEL_DVI) += panel-dvi.o
obj-$(CONFIG_PANEL_LGPHILIPS_LB035Q02) += panel-lgphilips-lb035q02.o
obj-$(CONFIG_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o
obj-$(CONFIG_PANEL_NEC_NL8048HL11_01B) += panel-nec-nl8048hl11-01b.o
obj-$(CONFIG_PANEL_TAAL) += panel-taal.o
obj-$(CONFIG_PANEL_PICODLP) += panel-picodlp.o
obj-$(CONFIG_PANEL_TPO_TD043MTEA1) += panel-tpo-td043mtea1.o
obj-$(CONFIG_PANEL_ACX565AKM) += panel-acx565akm.o
obj-$(CONFIG_PANEL_N8X0) += panel-n8x0.o

View File

@ -0,0 +1,363 @@
/*
* DVI output support
*
* Copyright (C) 2011 Texas Instruments Inc
* Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*
* 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.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/module.h>
#include <linux/slab.h>
#include <video/omapdss.h>
#include <linux/i2c.h>
#include <drm/drm_edid.h>
#include <video/omap-panel-dvi.h>
static const struct omap_video_timings panel_dvi_default_timings = {
.x_res = 640,
.y_res = 480,
.pixel_clock = 23500,
.hfp = 48,
.hsw = 32,
.hbp = 80,
.vfp = 3,
.vsw = 4,
.vbp = 7,
};
struct panel_drv_data {
struct omap_dss_device *dssdev;
struct mutex lock;
};
static inline struct panel_dvi_platform_data
*get_pdata(const struct omap_dss_device *dssdev)
{
return dssdev->data;
}
static int panel_dvi_power_on(struct omap_dss_device *dssdev)
{
struct panel_dvi_platform_data *pdata = get_pdata(dssdev);
int r;
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
return 0;
r = omapdss_dpi_display_enable(dssdev);
if (r)
goto err0;
if (pdata->platform_enable) {
r = pdata->platform_enable(dssdev);
if (r)
goto err1;
}
return 0;
err1:
omapdss_dpi_display_disable(dssdev);
err0:
return r;
}
static void panel_dvi_power_off(struct omap_dss_device *dssdev)
{
struct panel_dvi_platform_data *pdata = get_pdata(dssdev);
if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
return;
if (pdata->platform_disable)
pdata->platform_disable(dssdev);
omapdss_dpi_display_disable(dssdev);
}
static int panel_dvi_probe(struct omap_dss_device *dssdev)
{
struct panel_drv_data *ddata;
ddata = kzalloc(sizeof(*ddata), GFP_KERNEL);
if (!ddata)
return -ENOMEM;
dssdev->panel.timings = panel_dvi_default_timings;
dssdev->panel.config = OMAP_DSS_LCD_TFT;
ddata->dssdev = dssdev;
mutex_init(&ddata->lock);
dev_set_drvdata(&dssdev->dev, ddata);
return 0;
}
static void __exit panel_dvi_remove(struct omap_dss_device *dssdev)
{
struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
mutex_lock(&ddata->lock);
dev_set_drvdata(&dssdev->dev, NULL);
mutex_unlock(&ddata->lock);
kfree(ddata);
}
static int panel_dvi_enable(struct omap_dss_device *dssdev)
{
struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
int r;
mutex_lock(&ddata->lock);
r = panel_dvi_power_on(dssdev);
if (r == 0)
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
mutex_unlock(&ddata->lock);
return r;
}
static void panel_dvi_disable(struct omap_dss_device *dssdev)
{
struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
mutex_lock(&ddata->lock);
panel_dvi_power_off(dssdev);
dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
mutex_unlock(&ddata->lock);
}
static int panel_dvi_suspend(struct omap_dss_device *dssdev)
{
struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
mutex_lock(&ddata->lock);
panel_dvi_power_off(dssdev);
dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
mutex_unlock(&ddata->lock);
return 0;
}
static int panel_dvi_resume(struct omap_dss_device *dssdev)
{
struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
int r;
mutex_lock(&ddata->lock);
r = panel_dvi_power_on(dssdev);
if (r == 0)
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
mutex_unlock(&ddata->lock);
return r;
}
static void panel_dvi_set_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
{
struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
mutex_lock(&ddata->lock);
dpi_set_timings(dssdev, timings);
mutex_unlock(&ddata->lock);
}
static void panel_dvi_get_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
{
struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
mutex_lock(&ddata->lock);
*timings = dssdev->panel.timings;
mutex_unlock(&ddata->lock);
}
static int panel_dvi_check_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
{
struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
int r;
mutex_lock(&ddata->lock);
r = dpi_check_timings(dssdev, timings);
mutex_unlock(&ddata->lock);
return r;
}
static int panel_dvi_ddc_read(struct i2c_adapter *adapter,
unsigned char *buf, u16 count, u8 offset)
{
int r, retries;
for (retries = 3; retries > 0; retries--) {
struct i2c_msg msgs[] = {
{
.addr = DDC_ADDR,
.flags = 0,
.len = 1,
.buf = &offset,
}, {
.addr = DDC_ADDR,
.flags = I2C_M_RD,
.len = count,
.buf = buf,
}
};
r = i2c_transfer(adapter, msgs, 2);
if (r == 2)
return 0;
if (r != -EAGAIN)
break;
}
return r < 0 ? r : -EIO;
}
static int panel_dvi_read_edid(struct omap_dss_device *dssdev,
u8 *edid, int len)
{
struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
struct panel_dvi_platform_data *pdata = get_pdata(dssdev);
struct i2c_adapter *adapter;
int r, l, bytes_read;
mutex_lock(&ddata->lock);
if (pdata->i2c_bus_num == 0) {
r = -ENODEV;
goto err;
}
adapter = i2c_get_adapter(pdata->i2c_bus_num);
if (!adapter) {
dev_err(&dssdev->dev, "Failed to get I2C adapter, bus %d\n",
pdata->i2c_bus_num);
r = -EINVAL;
goto err;
}
l = min(EDID_LENGTH, len);
r = panel_dvi_ddc_read(adapter, edid, l, 0);
if (r)
goto err;
bytes_read = l;
/* if there are extensions, read second block */
if (len > EDID_LENGTH && edid[0x7e] > 0) {
l = min(EDID_LENGTH, len - EDID_LENGTH);
r = panel_dvi_ddc_read(adapter, edid + EDID_LENGTH,
l, EDID_LENGTH);
if (r)
goto err;
bytes_read += l;
}
mutex_unlock(&ddata->lock);
return bytes_read;
err:
mutex_unlock(&ddata->lock);
return r;
}
static bool panel_dvi_detect(struct omap_dss_device *dssdev)
{
struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
struct panel_dvi_platform_data *pdata = get_pdata(dssdev);
struct i2c_adapter *adapter;
unsigned char out;
int r;
mutex_lock(&ddata->lock);
if (pdata->i2c_bus_num == 0)
goto out;
adapter = i2c_get_adapter(pdata->i2c_bus_num);
if (!adapter)
goto out;
r = panel_dvi_ddc_read(adapter, &out, 1, 0);
mutex_unlock(&ddata->lock);
return r == 0;
out:
mutex_unlock(&ddata->lock);
return true;
}
static struct omap_dss_driver panel_dvi_driver = {
.probe = panel_dvi_probe,
.remove = __exit_p(panel_dvi_remove),
.enable = panel_dvi_enable,
.disable = panel_dvi_disable,
.suspend = panel_dvi_suspend,
.resume = panel_dvi_resume,
.set_timings = panel_dvi_set_timings,
.get_timings = panel_dvi_get_timings,
.check_timings = panel_dvi_check_timings,
.read_edid = panel_dvi_read_edid,
.detect = panel_dvi_detect,
.driver = {
.name = "dvi",
.owner = THIS_MODULE,
},
};
static int __init panel_dvi_init(void)
{
return omap_dss_register_driver(&panel_dvi_driver);
}
static void __exit panel_dvi_exit(void)
{
omap_dss_unregister_driver(&panel_dvi_driver);
}
module_init(panel_dvi_init);
module_exit(panel_dvi_exit);
MODULE_LICENSE("GPL");

View File

@ -58,30 +58,6 @@ struct panel_config {
/* Panel configurations */
static struct panel_config generic_dpi_panels[] = {
/* Generic Panel */
{
{
.x_res = 640,
.y_res = 480,
.pixel_clock = 23500,
.hfp = 48,
.hsw = 32,
.hbp = 80,
.vfp = 3,
.vsw = 4,
.vbp = 7,
},
.acbi = 0x0,
.acb = 0x0,
.config = OMAP_DSS_LCD_TFT,
.power_on_delay = 0,
.power_off_delay = 0,
.name = "generic",
},
/* Sharp LQ043T1DG01 */
{
{
@ -232,6 +208,95 @@ static struct panel_config generic_dpi_panels[] = {
.power_off_delay = 0,
.name = "powertip_ph480272t",
},
/* Innolux AT070TN83 */
{
{
.x_res = 800,
.y_res = 480,
.pixel_clock = 40000,
.hsw = 48,
.hfp = 1,
.hbp = 1,
.vsw = 3,
.vfp = 12,
.vbp = 25,
},
.acbi = 0x0,
.acb = 0x28,
.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
OMAP_DSS_LCD_IHS,
.power_on_delay = 0,
.power_off_delay = 0,
.name = "innolux_at070tn83",
},
/* NEC NL2432DR22-11B */
{
{
.x_res = 240,
.y_res = 320,
.pixel_clock = 5400,
.hsw = 3,
.hfp = 3,
.hbp = 39,
.vsw = 1,
.vfp = 2,
.vbp = 7,
},
.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
OMAP_DSS_LCD_IHS,
.name = "nec_nl2432dr22-11b",
},
/* Unknown panel used in OMAP H4 */
{
{
.x_res = 240,
.y_res = 320,
.pixel_clock = 6250,
.hsw = 15,
.hfp = 15,
.hbp = 60,
.vsw = 1,
.vfp = 1,
.vbp = 1,
},
.config = OMAP_DSS_LCD_TFT,
.name = "h4",
},
/* Unknown panel used in Samsung OMAP2 Apollon */
{
{
.x_res = 480,
.y_res = 272,
.pixel_clock = 6250,
.hsw = 41,
.hfp = 2,
.hbp = 2,
.vsw = 10,
.vfp = 2,
.vbp = 2,
},
.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
OMAP_DSS_LCD_IHS,
.name = "apollon",
},
};
struct panel_drv_data {

View File

@ -0,0 +1,747 @@
/* #define DEBUG */
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/gpio.h>
#include <linux/spi/spi.h>
#include <linux/backlight.h>
#include <linux/fb.h>
#include <video/omapdss.h>
#include <video/omap-panel-n8x0.h>
#define BLIZZARD_REV_CODE 0x00
#define BLIZZARD_CONFIG 0x02
#define BLIZZARD_PLL_DIV 0x04
#define BLIZZARD_PLL_LOCK_RANGE 0x06
#define BLIZZARD_PLL_CLOCK_SYNTH_0 0x08
#define BLIZZARD_PLL_CLOCK_SYNTH_1 0x0a
#define BLIZZARD_PLL_MODE 0x0c
#define BLIZZARD_CLK_SRC 0x0e
#define BLIZZARD_MEM_BANK0_ACTIVATE 0x10
#define BLIZZARD_MEM_BANK0_STATUS 0x14
#define BLIZZARD_PANEL_CONFIGURATION 0x28
#define BLIZZARD_HDISP 0x2a
#define BLIZZARD_HNDP 0x2c
#define BLIZZARD_VDISP0 0x2e
#define BLIZZARD_VDISP1 0x30
#define BLIZZARD_VNDP 0x32
#define BLIZZARD_HSW 0x34
#define BLIZZARD_VSW 0x38
#define BLIZZARD_DISPLAY_MODE 0x68
#define BLIZZARD_INPUT_WIN_X_START_0 0x6c
#define BLIZZARD_DATA_SOURCE_SELECT 0x8e
#define BLIZZARD_DISP_MEM_DATA_PORT 0x90
#define BLIZZARD_DISP_MEM_READ_ADDR0 0x92
#define BLIZZARD_POWER_SAVE 0xE6
#define BLIZZARD_NDISP_CTRL_STATUS 0xE8
/* Data source select */
/* For S1D13745 */
#define BLIZZARD_SRC_WRITE_LCD_BACKGROUND 0x00
#define BLIZZARD_SRC_WRITE_LCD_DESTRUCTIVE 0x01
#define BLIZZARD_SRC_WRITE_OVERLAY_ENABLE 0x04
#define BLIZZARD_SRC_DISABLE_OVERLAY 0x05
/* For S1D13744 */
#define BLIZZARD_SRC_WRITE_LCD 0x00
#define BLIZZARD_SRC_BLT_LCD 0x06
#define BLIZZARD_COLOR_RGB565 0x01
#define BLIZZARD_COLOR_YUV420 0x09
#define BLIZZARD_VERSION_S1D13745 0x01 /* Hailstorm */
#define BLIZZARD_VERSION_S1D13744 0x02 /* Blizzard */
#define MIPID_CMD_READ_DISP_ID 0x04
#define MIPID_CMD_READ_RED 0x06
#define MIPID_CMD_READ_GREEN 0x07
#define MIPID_CMD_READ_BLUE 0x08
#define MIPID_CMD_READ_DISP_STATUS 0x09
#define MIPID_CMD_RDDSDR 0x0F
#define MIPID_CMD_SLEEP_IN 0x10
#define MIPID_CMD_SLEEP_OUT 0x11
#define MIPID_CMD_DISP_OFF 0x28
#define MIPID_CMD_DISP_ON 0x29
static struct panel_drv_data {
struct mutex lock;
struct omap_dss_device *dssdev;
struct spi_device *spidev;
struct backlight_device *bldev;
int blizzard_ver;
} s_drv_data;
static inline
struct panel_n8x0_data *get_board_data(const struct omap_dss_device *dssdev)
{
return dssdev->data;
}
static inline
struct panel_drv_data *get_drv_data(const struct omap_dss_device *dssdev)
{
return &s_drv_data;
}
static inline void blizzard_cmd(u8 cmd)
{
omap_rfbi_write_command(&cmd, 1);
}
static inline void blizzard_write(u8 cmd, const u8 *buf, int len)
{
omap_rfbi_write_command(&cmd, 1);
omap_rfbi_write_data(buf, len);
}
static inline void blizzard_read(u8 cmd, u8 *buf, int len)
{
omap_rfbi_write_command(&cmd, 1);
omap_rfbi_read_data(buf, len);
}
static u8 blizzard_read_reg(u8 cmd)
{
u8 data;
blizzard_read(cmd, &data, 1);
return data;
}
static void blizzard_ctrl_setup_update(struct omap_dss_device *dssdev,
int x, int y, int w, int h)
{
struct panel_drv_data *ddata = get_drv_data(dssdev);
u8 tmp[18];
int x_end, y_end;
x_end = x + w - 1;
y_end = y + h - 1;
tmp[0] = x;
tmp[1] = x >> 8;
tmp[2] = y;
tmp[3] = y >> 8;
tmp[4] = x_end;
tmp[5] = x_end >> 8;
tmp[6] = y_end;
tmp[7] = y_end >> 8;
/* scaling? */
tmp[8] = x;
tmp[9] = x >> 8;
tmp[10] = y;
tmp[11] = y >> 8;
tmp[12] = x_end;
tmp[13] = x_end >> 8;
tmp[14] = y_end;
tmp[15] = y_end >> 8;
tmp[16] = BLIZZARD_COLOR_RGB565;
if (ddata->blizzard_ver == BLIZZARD_VERSION_S1D13745)
tmp[17] = BLIZZARD_SRC_WRITE_LCD_BACKGROUND;
else
tmp[17] = ddata->blizzard_ver == BLIZZARD_VERSION_S1D13744 ?
BLIZZARD_SRC_WRITE_LCD :
BLIZZARD_SRC_WRITE_LCD_DESTRUCTIVE;
omap_rfbi_configure(dssdev, 16, 8);
blizzard_write(BLIZZARD_INPUT_WIN_X_START_0, tmp, 18);
omap_rfbi_configure(dssdev, 16, 16);
}
static void mipid_transfer(struct spi_device *spi, int cmd, const u8 *wbuf,
int wlen, u8 *rbuf, int rlen)
{
struct spi_message m;
struct spi_transfer *x, xfer[4];
u16 w;
int r;
spi_message_init(&m);
memset(xfer, 0, sizeof(xfer));
x = &xfer[0];
cmd &= 0xff;
x->tx_buf = &cmd;
x->bits_per_word = 9;
x->len = 2;
spi_message_add_tail(x, &m);
if (wlen) {
x++;
x->tx_buf = wbuf;
x->len = wlen;
x->bits_per_word = 9;
spi_message_add_tail(x, &m);
}
if (rlen) {
x++;
x->rx_buf = &w;
x->len = 1;
spi_message_add_tail(x, &m);
if (rlen > 1) {
/* Arrange for the extra clock before the first
* data bit.
*/
x->bits_per_word = 9;
x->len = 2;
x++;
x->rx_buf = &rbuf[1];
x->len = rlen - 1;
spi_message_add_tail(x, &m);
}
}
r = spi_sync(spi, &m);
if (r < 0)
dev_dbg(&spi->dev, "spi_sync %d\n", r);
if (rlen)
rbuf[0] = w & 0xff;
}
static inline void mipid_cmd(struct spi_device *spi, int cmd)
{
mipid_transfer(spi, cmd, NULL, 0, NULL, 0);
}
static inline void mipid_write(struct spi_device *spi,
int reg, const u8 *buf, int len)
{
mipid_transfer(spi, reg, buf, len, NULL, 0);
}
static inline void mipid_read(struct spi_device *spi,
int reg, u8 *buf, int len)
{
mipid_transfer(spi, reg, NULL, 0, buf, len);
}
static void set_data_lines(struct spi_device *spi, int data_lines)
{
u16 par;
switch (data_lines) {
case 16:
par = 0x150;
break;
case 18:
par = 0x160;
break;
case 24:
par = 0x170;
break;
}
mipid_write(spi, 0x3a, (u8 *)&par, 2);
}
static void send_init_string(struct spi_device *spi)
{
u16 initpar[] = { 0x0102, 0x0100, 0x0100 };
mipid_write(spi, 0xc2, (u8 *)initpar, sizeof(initpar));
}
static void send_display_on(struct spi_device *spi)
{
mipid_cmd(spi, MIPID_CMD_DISP_ON);
}
static void send_display_off(struct spi_device *spi)
{
mipid_cmd(spi, MIPID_CMD_DISP_OFF);
}
static void send_sleep_out(struct spi_device *spi)
{
mipid_cmd(spi, MIPID_CMD_SLEEP_OUT);
msleep(120);
}
static void send_sleep_in(struct spi_device *spi)
{
mipid_cmd(spi, MIPID_CMD_SLEEP_IN);
msleep(50);
}
static int n8x0_panel_power_on(struct omap_dss_device *dssdev)
{
int r;
struct panel_n8x0_data *bdata = get_board_data(dssdev);
struct panel_drv_data *ddata = get_drv_data(dssdev);
struct spi_device *spi = ddata->spidev;
u8 rev, conf;
u8 display_id[3];
const char *panel_name;
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
return 0;
gpio_direction_output(bdata->ctrl_pwrdown, 1);
if (bdata->platform_enable) {
r = bdata->platform_enable(dssdev);
if (r)
goto err_plat_en;
}
r = omapdss_rfbi_display_enable(dssdev);
if (r)
goto err_rfbi_en;
rev = blizzard_read_reg(BLIZZARD_REV_CODE);
conf = blizzard_read_reg(BLIZZARD_CONFIG);
switch (rev & 0xfc) {
case 0x9c:
ddata->blizzard_ver = BLIZZARD_VERSION_S1D13744;
dev_info(&dssdev->dev, "s1d13744 LCD controller rev %d "
"initialized (CNF pins %x)\n", rev & 0x03, conf & 0x07);
break;
case 0xa4:
ddata->blizzard_ver = BLIZZARD_VERSION_S1D13745;
dev_info(&dssdev->dev, "s1d13745 LCD controller rev %d "
"initialized (CNF pins %x)\n", rev & 0x03, conf & 0x07);
break;
default:
dev_err(&dssdev->dev, "invalid s1d1374x revision %02x\n", rev);
r = -ENODEV;
goto err_inv_chip;
}
/* panel */
gpio_direction_output(bdata->panel_reset, 1);
mipid_read(spi, MIPID_CMD_READ_DISP_ID, display_id, 3);
dev_dbg(&spi->dev, "MIPI display ID: %02x%02x%02x\n",
display_id[0], display_id[1], display_id[2]);
switch (display_id[0]) {
case 0x45:
panel_name = "lph8923";
break;
case 0x83:
panel_name = "ls041y3";
break;
default:
dev_err(&dssdev->dev, "invalid display ID 0x%x\n",
display_id[0]);
r = -ENODEV;
goto err_inv_panel;
}
dev_info(&dssdev->dev, "%s rev %02x LCD detected\n",
panel_name, display_id[1]);
send_sleep_out(spi);
send_init_string(spi);
set_data_lines(spi, 24);
send_display_on(spi);
return 0;
err_inv_panel:
/*
* HACK: we should turn off the panel here, but there is some problem
* with the initialization sequence, and we fail to init the panel if we
* have turned it off
*/
/* gpio_direction_output(bdata->panel_reset, 0); */
err_inv_chip:
omapdss_rfbi_display_disable(dssdev);
err_rfbi_en:
if (bdata->platform_disable)
bdata->platform_disable(dssdev);
err_plat_en:
gpio_direction_output(bdata->ctrl_pwrdown, 0);
return r;
}
static void n8x0_panel_power_off(struct omap_dss_device *dssdev)
{
struct panel_n8x0_data *bdata = get_board_data(dssdev);
struct panel_drv_data *ddata = get_drv_data(dssdev);
struct spi_device *spi = ddata->spidev;
if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
return;
send_display_off(spi);
send_sleep_in(spi);
if (bdata->platform_disable)
bdata->platform_disable(dssdev);
/*
* HACK: we should turn off the panel here, but there is some problem
* with the initialization sequence, and we fail to init the panel if we
* have turned it off
*/
/* gpio_direction_output(bdata->panel_reset, 0); */
gpio_direction_output(bdata->ctrl_pwrdown, 0);
omapdss_rfbi_display_disable(dssdev);
}
static const struct rfbi_timings n8x0_panel_timings = {
.cs_on_time = 0,
.we_on_time = 9000,
.we_off_time = 18000,
.we_cycle_time = 36000,
.re_on_time = 9000,
.re_off_time = 27000,
.re_cycle_time = 36000,
.access_time = 27000,
.cs_off_time = 36000,
.cs_pulse_width = 0,
};
static int n8x0_bl_update_status(struct backlight_device *dev)
{
struct omap_dss_device *dssdev = dev_get_drvdata(&dev->dev);
struct panel_n8x0_data *bdata = get_board_data(dssdev);
struct panel_drv_data *ddata = get_drv_data(dssdev);
int r;
int level;
mutex_lock(&ddata->lock);
if (dev->props.fb_blank == FB_BLANK_UNBLANK &&
dev->props.power == FB_BLANK_UNBLANK)
level = dev->props.brightness;
else
level = 0;
dev_dbg(&dssdev->dev, "update brightness to %d\n", level);
if (!bdata->set_backlight)
r = -EINVAL;
else
r = bdata->set_backlight(dssdev, level);
mutex_unlock(&ddata->lock);
return r;
}
static int n8x0_bl_get_intensity(struct backlight_device *dev)
{
if (dev->props.fb_blank == FB_BLANK_UNBLANK &&
dev->props.power == FB_BLANK_UNBLANK)
return dev->props.brightness;
return 0;
}
static const struct backlight_ops n8x0_bl_ops = {
.get_brightness = n8x0_bl_get_intensity,
.update_status = n8x0_bl_update_status,
};
static int n8x0_panel_probe(struct omap_dss_device *dssdev)
{
struct panel_n8x0_data *bdata = get_board_data(dssdev);
struct panel_drv_data *ddata;
struct backlight_device *bldev;
struct backlight_properties props;
int r;
dev_dbg(&dssdev->dev, "probe\n");
if (!bdata)
return -EINVAL;
s_drv_data.dssdev = dssdev;
ddata = &s_drv_data;
mutex_init(&ddata->lock);
dssdev->panel.config = OMAP_DSS_LCD_TFT;
dssdev->panel.timings.x_res = 800;
dssdev->panel.timings.y_res = 480;
dssdev->ctrl.pixel_size = 16;
dssdev->ctrl.rfbi_timings = n8x0_panel_timings;
memset(&props, 0, sizeof(props));
props.max_brightness = 127;
props.type = BACKLIGHT_PLATFORM;
bldev = backlight_device_register(dev_name(&dssdev->dev), &dssdev->dev,
dssdev, &n8x0_bl_ops, &props);
if (IS_ERR(bldev)) {
r = PTR_ERR(bldev);
dev_err(&dssdev->dev, "register backlight failed\n");
return r;
}
ddata->bldev = bldev;
bldev->props.fb_blank = FB_BLANK_UNBLANK;
bldev->props.power = FB_BLANK_UNBLANK;
bldev->props.brightness = 127;
n8x0_bl_update_status(bldev);
return 0;
}
static void n8x0_panel_remove(struct omap_dss_device *dssdev)
{
struct panel_drv_data *ddata = get_drv_data(dssdev);
struct backlight_device *bldev;
dev_dbg(&dssdev->dev, "remove\n");
bldev = ddata->bldev;
bldev->props.power = FB_BLANK_POWERDOWN;
n8x0_bl_update_status(bldev);
backlight_device_unregister(bldev);
dev_set_drvdata(&dssdev->dev, NULL);
}
static int n8x0_panel_enable(struct omap_dss_device *dssdev)
{
struct panel_drv_data *ddata = get_drv_data(dssdev);
int r;
dev_dbg(&dssdev->dev, "enable\n");
mutex_lock(&ddata->lock);
rfbi_bus_lock();
r = n8x0_panel_power_on(dssdev);
rfbi_bus_unlock();
if (r) {
mutex_unlock(&ddata->lock);
return r;
}
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
mutex_unlock(&ddata->lock);
return 0;
}
static void n8x0_panel_disable(struct omap_dss_device *dssdev)
{
struct panel_drv_data *ddata = get_drv_data(dssdev);
dev_dbg(&dssdev->dev, "disable\n");
mutex_lock(&ddata->lock);
rfbi_bus_lock();
n8x0_panel_power_off(dssdev);
rfbi_bus_unlock();
dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
mutex_unlock(&ddata->lock);
}
static int n8x0_panel_suspend(struct omap_dss_device *dssdev)
{
struct panel_drv_data *ddata = get_drv_data(dssdev);
dev_dbg(&dssdev->dev, "suspend\n");
mutex_lock(&ddata->lock);
rfbi_bus_lock();
n8x0_panel_power_off(dssdev);
rfbi_bus_unlock();
dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
mutex_unlock(&ddata->lock);
return 0;
}
static int n8x0_panel_resume(struct omap_dss_device *dssdev)
{
struct panel_drv_data *ddata = get_drv_data(dssdev);
int r;
dev_dbg(&dssdev->dev, "resume\n");
mutex_lock(&ddata->lock);
rfbi_bus_lock();
r = n8x0_panel_power_on(dssdev);
rfbi_bus_unlock();
if (r) {
mutex_unlock(&ddata->lock);
return r;
}
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
mutex_unlock(&ddata->lock);
return 0;
}
static void n8x0_panel_get_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
{
*timings = dssdev->panel.timings;
}
static void n8x0_panel_get_resolution(struct omap_dss_device *dssdev,
u16 *xres, u16 *yres)
{
*xres = dssdev->panel.timings.x_res;
*yres = dssdev->panel.timings.y_res;
}
static void update_done(void *data)
{
rfbi_bus_unlock();
}
static int n8x0_panel_update(struct omap_dss_device *dssdev,
u16 x, u16 y, u16 w, u16 h)
{
struct panel_drv_data *ddata = get_drv_data(dssdev);
dev_dbg(&dssdev->dev, "update\n");
mutex_lock(&ddata->lock);
rfbi_bus_lock();
omap_rfbi_prepare_update(dssdev, &x, &y, &w, &h);
blizzard_ctrl_setup_update(dssdev, x, y, w, h);
omap_rfbi_update(dssdev, x, y, w, h, update_done, NULL);
mutex_unlock(&ddata->lock);
return 0;
}
static int n8x0_panel_sync(struct omap_dss_device *dssdev)
{
struct panel_drv_data *ddata = get_drv_data(dssdev);
dev_dbg(&dssdev->dev, "sync\n");
mutex_lock(&ddata->lock);
rfbi_bus_lock();
rfbi_bus_unlock();
mutex_unlock(&ddata->lock);
return 0;
}
static struct omap_dss_driver n8x0_panel_driver = {
.probe = n8x0_panel_probe,
.remove = n8x0_panel_remove,
.enable = n8x0_panel_enable,
.disable = n8x0_panel_disable,
.suspend = n8x0_panel_suspend,
.resume = n8x0_panel_resume,
.update = n8x0_panel_update,
.sync = n8x0_panel_sync,
.get_resolution = n8x0_panel_get_resolution,
.get_recommended_bpp = omapdss_default_get_recommended_bpp,
.get_timings = n8x0_panel_get_timings,
.driver = {
.name = "n8x0_panel",
.owner = THIS_MODULE,
},
};
/* PANEL */
static int mipid_spi_probe(struct spi_device *spi)
{
dev_dbg(&spi->dev, "mipid_spi_probe\n");
spi->mode = SPI_MODE_0;
s_drv_data.spidev = spi;
return 0;
}
static int mipid_spi_remove(struct spi_device *spi)
{
dev_dbg(&spi->dev, "mipid_spi_remove\n");
return 0;
}
static struct spi_driver mipid_spi_driver = {
.driver = {
.name = "lcd_mipid",
.bus = &spi_bus_type,
.owner = THIS_MODULE,
},
.probe = mipid_spi_probe,
.remove = __devexit_p(mipid_spi_remove),
};
static int __init n8x0_panel_drv_init(void)
{
int r;
r = spi_register_driver(&mipid_spi_driver);
if (r) {
pr_err("n8x0_panel: spi driver registration failed\n");
return r;
}
r = omap_dss_register_driver(&n8x0_panel_driver);
if (r) {
pr_err("n8x0_panel: dss driver registration failed\n");
spi_unregister_driver(&mipid_spi_driver);
return r;
}
return 0;
}
static void __exit n8x0_panel_drv_exit(void)
{
spi_unregister_driver(&mipid_spi_driver);
omap_dss_unregister_driver(&n8x0_panel_driver);
}
module_init(n8x0_panel_drv_init);
module_exit(n8x0_panel_drv_exit);
MODULE_LICENSE("GPL");

View File

@ -0,0 +1,594 @@
/*
* picodlp panel driver
* picodlp_i2c_driver: i2c_client driver
*
* Copyright (C) 2009-2011 Texas Instruments
* Author: Mythri P K <mythripk@ti.com>
* Mayuresh Janorkar <mayur@ti.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*
* 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.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/module.h>
#include <linux/input.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/firmware.h>
#include <linux/slab.h>
#include <linux/mutex.h>
#include <linux/i2c.h>
#include <linux/delay.h>
#include <linux/gpio.h>
#include <video/omapdss.h>
#include <video/omap-panel-picodlp.h>
#include "panel-picodlp.h"
struct picodlp_data {
struct mutex lock;
struct i2c_client *picodlp_i2c_client;
};
static struct i2c_board_info picodlp_i2c_board_info = {
I2C_BOARD_INFO("picodlp_i2c_driver", 0x1b),
};
struct picodlp_i2c_data {
struct mutex xfer_lock;
};
static struct i2c_device_id picodlp_i2c_id[] = {
{ "picodlp_i2c_driver", 0 },
};
struct picodlp_i2c_command {
u8 reg;
u32 value;
};
static struct omap_video_timings pico_ls_timings = {
.x_res = 864,
.y_res = 480,
.hsw = 7,
.hfp = 11,
.hbp = 7,
.pixel_clock = 19200,
.vsw = 2,
.vfp = 3,
.vbp = 14,
};
static inline struct picodlp_panel_data
*get_panel_data(const struct omap_dss_device *dssdev)
{
return (struct picodlp_panel_data *) dssdev->data;
}
static u32 picodlp_i2c_read(struct i2c_client *client, u8 reg)
{
u8 read_cmd[] = {READ_REG_SELECT, reg}, data[4];
struct picodlp_i2c_data *picodlp_i2c_data = i2c_get_clientdata(client);
struct i2c_msg msg[2];
mutex_lock(&picodlp_i2c_data->xfer_lock);
msg[0].addr = client->addr;
msg[0].flags = 0;
msg[0].len = 2;
msg[0].buf = read_cmd;
msg[1].addr = client->addr;
msg[1].flags = I2C_M_RD;
msg[1].len = 4;
msg[1].buf = data;
i2c_transfer(client->adapter, msg, 2);
mutex_unlock(&picodlp_i2c_data->xfer_lock);
return (data[3] | (data[2] << 8) | (data[1] << 16) | (data[0] << 24));
}
static int picodlp_i2c_write_block(struct i2c_client *client,
u8 *data, int len)
{
struct i2c_msg msg;
int i, r, msg_count = 1;
struct picodlp_i2c_data *picodlp_i2c_data = i2c_get_clientdata(client);
if (len < 1 || len > 32) {
dev_err(&client->dev,
"too long syn_write_block len %d\n", len);
return -EIO;
}
mutex_lock(&picodlp_i2c_data->xfer_lock);
msg.addr = client->addr;
msg.flags = 0;
msg.len = len;
msg.buf = data;
r = i2c_transfer(client->adapter, &msg, msg_count);
mutex_unlock(&picodlp_i2c_data->xfer_lock);
/*
* i2c_transfer returns:
* number of messages sent in case of success
* a negative error number in case of failure
*/
if (r != msg_count)
goto err;
/* In case of success */
for (i = 0; i < len; i++)
dev_dbg(&client->dev,
"addr %x bw 0x%02x[%d]: 0x%02x\n",
client->addr, data[0] + i, i, data[i]);
return 0;
err:
dev_err(&client->dev, "picodlp_i2c_write error\n");
return r;
}
static int picodlp_i2c_write(struct i2c_client *client, u8 reg, u32 value)
{
u8 data[5];
int i;
data[0] = reg;
for (i = 1; i < 5; i++)
data[i] = (value >> (32 - (i) * 8)) & 0xFF;
return picodlp_i2c_write_block(client, data, 5);
}
static int picodlp_i2c_write_array(struct i2c_client *client,
const struct picodlp_i2c_command commands[],
int count)
{
int i, r = 0;
for (i = 0; i < count; i++) {
r = picodlp_i2c_write(client, commands[i].reg,
commands[i].value);
if (r)
return r;
}
return r;
}
static int picodlp_wait_for_dma_done(struct i2c_client *client)
{
u8 trial = 100;
do {
msleep(1);
if (!trial--)
return -ETIMEDOUT;
} while (picodlp_i2c_read(client, MAIN_STATUS) & DMA_STATUS);
return 0;
}
/**
* picodlp_i2c_init: i2c_initialization routine
* client: i2c_client for communication
*
* return
* 0 : Success, no error
* error code : Failure
*/
static int picodlp_i2c_init(struct i2c_client *client)
{
int r;
static const struct picodlp_i2c_command init_cmd_set1[] = {
{SOFT_RESET, 1},
{DMD_PARK_TRIGGER, 1},
{MISC_REG, 5},
{SEQ_CONTROL, 0},
{SEQ_VECTOR, 0x100},
{DMD_BLOCK_COUNT, 7},
{DMD_VCC_CONTROL, 0x109},
{DMD_PARK_PULSE_COUNT, 0xA},
{DMD_PARK_PULSE_WIDTH, 0xB},
{DMD_PARK_DELAY, 0x2ED},
{DMD_SHADOW_ENABLE, 0},
{FLASH_OPCODE, 0xB},
{FLASH_DUMMY_BYTES, 1},
{FLASH_ADDR_BYTES, 3},
{PBC_CONTROL, 0},
{FLASH_START_ADDR, CMT_LUT_0_START_ADDR},
{FLASH_READ_BYTES, CMT_LUT_0_SIZE},
{CMT_SPLASH_LUT_START_ADDR, 0},
{CMT_SPLASH_LUT_DEST_SELECT, CMT_LUT_ALL},
{PBC_CONTROL, 1},
};
static const struct picodlp_i2c_command init_cmd_set2[] = {
{PBC_CONTROL, 0},
{CMT_SPLASH_LUT_DEST_SELECT, 0},
{PBC_CONTROL, 0},
{FLASH_START_ADDR, SEQUENCE_0_START_ADDR},
{FLASH_READ_BYTES, SEQUENCE_0_SIZE},
{SEQ_RESET_LUT_START_ADDR, 0},
{SEQ_RESET_LUT_DEST_SELECT, SEQ_SEQ_LUT},
{PBC_CONTROL, 1},
};
static const struct picodlp_i2c_command init_cmd_set3[] = {
{PBC_CONTROL, 0},
{SEQ_RESET_LUT_DEST_SELECT, 0},
{PBC_CONTROL, 0},
{FLASH_START_ADDR, DRC_TABLE_0_START_ADDR},
{FLASH_READ_BYTES, DRC_TABLE_0_SIZE},
{SEQ_RESET_LUT_START_ADDR, 0},
{SEQ_RESET_LUT_DEST_SELECT, SEQ_DRC_LUT_ALL},
{PBC_CONTROL, 1},
};
static const struct picodlp_i2c_command init_cmd_set4[] = {
{PBC_CONTROL, 0},
{SEQ_RESET_LUT_DEST_SELECT, 0},
{SDC_ENABLE, 1},
{AGC_CTRL, 7},
{CCA_C1A, 0x100},
{CCA_C1B, 0x0},
{CCA_C1C, 0x0},
{CCA_C2A, 0x0},
{CCA_C2B, 0x100},
{CCA_C2C, 0x0},
{CCA_C3A, 0x0},
{CCA_C3B, 0x0},
{CCA_C3C, 0x100},
{CCA_C7A, 0x100},
{CCA_C7B, 0x100},
{CCA_C7C, 0x100},
{CCA_ENABLE, 1},
{CPU_IF_MODE, 1},
{SHORT_FLIP, 1},
{CURTAIN_CONTROL, 0},
{DMD_PARK_TRIGGER, 0},
{R_DRIVE_CURRENT, 0x298},
{G_DRIVE_CURRENT, 0x298},
{B_DRIVE_CURRENT, 0x298},
{RGB_DRIVER_ENABLE, 7},
{SEQ_CONTROL, 0},
{ACTGEN_CONTROL, 0x10},
{SEQUENCE_MODE, SEQ_LOCK},
{DATA_FORMAT, RGB888},
{INPUT_RESOLUTION, WVGA_864_LANDSCAPE},
{INPUT_SOURCE, PARALLEL_RGB},
{CPU_IF_SYNC_METHOD, 1},
{SEQ_CONTROL, 1}
};
r = picodlp_i2c_write_array(client, init_cmd_set1,
ARRAY_SIZE(init_cmd_set1));
if (r)
return r;
r = picodlp_wait_for_dma_done(client);
if (r)
return r;
r = picodlp_i2c_write_array(client, init_cmd_set2,
ARRAY_SIZE(init_cmd_set2));
if (r)
return r;
r = picodlp_wait_for_dma_done(client);
if (r)
return r;
r = picodlp_i2c_write_array(client, init_cmd_set3,
ARRAY_SIZE(init_cmd_set3));
if (r)
return r;
r = picodlp_wait_for_dma_done(client);
if (r)
return r;
r = picodlp_i2c_write_array(client, init_cmd_set4,
ARRAY_SIZE(init_cmd_set4));
if (r)
return r;
return 0;
}
static int picodlp_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct picodlp_i2c_data *picodlp_i2c_data;
picodlp_i2c_data = kzalloc(sizeof(struct picodlp_i2c_data), GFP_KERNEL);
if (!picodlp_i2c_data)
return -ENOMEM;
mutex_init(&picodlp_i2c_data->xfer_lock);
i2c_set_clientdata(client, picodlp_i2c_data);
return 0;
}
static int picodlp_i2c_remove(struct i2c_client *client)
{
struct picodlp_i2c_data *picodlp_i2c_data =
i2c_get_clientdata(client);
kfree(picodlp_i2c_data);
return 0;
}
static struct i2c_driver picodlp_i2c_driver = {
.driver = {
.name = "picodlp_i2c_driver",
},
.probe = picodlp_i2c_probe,
.remove = picodlp_i2c_remove,
.id_table = picodlp_i2c_id,
};
static int picodlp_panel_power_on(struct omap_dss_device *dssdev)
{
int r, trial = 100;
struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev);
struct picodlp_panel_data *picodlp_pdata = get_panel_data(dssdev);
if (dssdev->platform_enable) {
r = dssdev->platform_enable(dssdev);
if (r)
return r;
}
gpio_set_value(picodlp_pdata->pwrgood_gpio, 0);
msleep(1);
gpio_set_value(picodlp_pdata->pwrgood_gpio, 1);
while (!gpio_get_value(picodlp_pdata->emu_done_gpio)) {
if (!trial--) {
dev_err(&dssdev->dev, "emu_done signal not"
" going high\n");
return -ETIMEDOUT;
}
msleep(5);
}
/*
* As per dpp2600 programming guide,
* it is required to sleep for 1000ms after emu_done signal goes high
* then only i2c commands can be successfully sent to dpp2600
*/
msleep(1000);
r = omapdss_dpi_display_enable(dssdev);
if (r) {
dev_err(&dssdev->dev, "failed to enable DPI\n");
goto err1;
}
r = picodlp_i2c_init(picod->picodlp_i2c_client);
if (r)
goto err;
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
return r;
err:
omapdss_dpi_display_disable(dssdev);
err1:
if (dssdev->platform_disable)
dssdev->platform_disable(dssdev);
return r;
}
static void picodlp_panel_power_off(struct omap_dss_device *dssdev)
{
struct picodlp_panel_data *picodlp_pdata = get_panel_data(dssdev);
omapdss_dpi_display_disable(dssdev);
gpio_set_value(picodlp_pdata->emu_done_gpio, 0);
gpio_set_value(picodlp_pdata->pwrgood_gpio, 0);
if (dssdev->platform_disable)
dssdev->platform_disable(dssdev);
}
static int picodlp_panel_probe(struct omap_dss_device *dssdev)
{
struct picodlp_data *picod;
struct picodlp_panel_data *picodlp_pdata = get_panel_data(dssdev);
struct i2c_adapter *adapter;
struct i2c_client *picodlp_i2c_client;
int r = 0, picodlp_adapter_id;
dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_ONOFF |
OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IVS;
dssdev->panel.acb = 0x0;
dssdev->panel.timings = pico_ls_timings;
picod = kzalloc(sizeof(struct picodlp_data), GFP_KERNEL);
if (!picod)
return -ENOMEM;
mutex_init(&picod->lock);
picodlp_adapter_id = picodlp_pdata->picodlp_adapter_id;
adapter = i2c_get_adapter(picodlp_adapter_id);
if (!adapter) {
dev_err(&dssdev->dev, "can't get i2c adapter\n");
r = -ENODEV;
goto err;
}
picodlp_i2c_client = i2c_new_device(adapter, &picodlp_i2c_board_info);
if (!picodlp_i2c_client) {
dev_err(&dssdev->dev, "can't add i2c device::"
" picodlp_i2c_client is NULL\n");
r = -ENODEV;
goto err;
}
picod->picodlp_i2c_client = picodlp_i2c_client;
dev_set_drvdata(&dssdev->dev, picod);
return r;
err:
kfree(picod);
return r;
}
static void picodlp_panel_remove(struct omap_dss_device *dssdev)
{
struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev);
i2c_unregister_device(picod->picodlp_i2c_client);
dev_set_drvdata(&dssdev->dev, NULL);
dev_dbg(&dssdev->dev, "removing picodlp panel\n");
kfree(picod);
}
static int picodlp_panel_enable(struct omap_dss_device *dssdev)
{
struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev);
int r;
dev_dbg(&dssdev->dev, "enabling picodlp panel\n");
mutex_lock(&picod->lock);
if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
mutex_unlock(&picod->lock);
return -EINVAL;
}
r = picodlp_panel_power_on(dssdev);
mutex_unlock(&picod->lock);
return r;
}
static void picodlp_panel_disable(struct omap_dss_device *dssdev)
{
struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev);
mutex_lock(&picod->lock);
/* Turn off DLP Power */
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
picodlp_panel_power_off(dssdev);
dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
mutex_unlock(&picod->lock);
dev_dbg(&dssdev->dev, "disabling picodlp panel\n");
}
static int picodlp_panel_suspend(struct omap_dss_device *dssdev)
{
struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev);
mutex_lock(&picod->lock);
/* Turn off DLP Power */
if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
mutex_unlock(&picod->lock);
dev_err(&dssdev->dev, "unable to suspend picodlp panel,"
" panel is not ACTIVE\n");
return -EINVAL;
}
picodlp_panel_power_off(dssdev);
dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
mutex_unlock(&picod->lock);
dev_dbg(&dssdev->dev, "suspending picodlp panel\n");
return 0;
}
static int picodlp_panel_resume(struct omap_dss_device *dssdev)
{
struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev);
int r;
mutex_lock(&picod->lock);
if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) {
mutex_unlock(&picod->lock);
dev_err(&dssdev->dev, "unable to resume picodlp panel,"
" panel is not ACTIVE\n");
return -EINVAL;
}
r = picodlp_panel_power_on(dssdev);
mutex_unlock(&picod->lock);
dev_dbg(&dssdev->dev, "resuming picodlp panel\n");
return r;
}
static void picodlp_get_resolution(struct omap_dss_device *dssdev,
u16 *xres, u16 *yres)
{
*xres = dssdev->panel.timings.x_res;
*yres = dssdev->panel.timings.y_res;
}
static struct omap_dss_driver picodlp_driver = {
.probe = picodlp_panel_probe,
.remove = picodlp_panel_remove,
.enable = picodlp_panel_enable,
.disable = picodlp_panel_disable,
.get_resolution = picodlp_get_resolution,
.suspend = picodlp_panel_suspend,
.resume = picodlp_panel_resume,
.driver = {
.name = "picodlp_panel",
.owner = THIS_MODULE,
},
};
static int __init picodlp_init(void)
{
int r = 0;
r = i2c_add_driver(&picodlp_i2c_driver);
if (r) {
printk(KERN_WARNING "picodlp_i2c_driver" \
" registration failed\n");
return r;
}
r = omap_dss_register_driver(&picodlp_driver);
if (r)
i2c_del_driver(&picodlp_i2c_driver);
return r;
}
static void __exit picodlp_exit(void)
{
i2c_del_driver(&picodlp_i2c_driver);
omap_dss_unregister_driver(&picodlp_driver);
}
module_init(picodlp_init);
module_exit(picodlp_exit);
MODULE_AUTHOR("Mythri P K <mythripk@ti.com>");
MODULE_DESCRIPTION("picodlp driver");
MODULE_LICENSE("GPL");

View File

@ -0,0 +1,288 @@
/*
* Header file required by picodlp panel driver
*
* Copyright (C) 2009-2011 Texas Instruments
* Author: Mythri P K <mythripk@ti.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*
* 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.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __OMAP2_DISPLAY_PANEL_PICODLP_H
#define __OMAP2_DISPLAY_PANEL_PICODLP_H
/* Commands used for configuring picodlp panel */
#define MAIN_STATUS 0x03
#define PBC_CONTROL 0x08
#define INPUT_SOURCE 0x0B
#define INPUT_RESOLUTION 0x0C
#define DATA_FORMAT 0x0D
#define IMG_ROTATION 0x0E
#define LONG_FLIP 0x0F
#define SHORT_FLIP 0x10
#define TEST_PAT_SELECT 0x11
#define R_DRIVE_CURRENT 0x12
#define G_DRIVE_CURRENT 0x13
#define B_DRIVE_CURRENT 0x14
#define READ_REG_SELECT 0x15
#define RGB_DRIVER_ENABLE 0x16
#define CPU_IF_MODE 0x18
#define FRAME_RATE 0x19
#define CPU_IF_SYNC_METHOD 0x1A
#define CPU_IF_SOF 0x1B
#define CPU_IF_EOF 0x1C
#define CPU_IF_SLEEP 0x1D
#define SEQUENCE_MODE 0x1E
#define SOFT_RESET 0x1F
#define FRONT_END_RESET 0x21
#define AUTO_PWR_ENABLE 0x22
#define VSYNC_LINE_DELAY 0x23
#define CPU_PI_HORIZ_START 0x24
#define CPU_PI_VERT_START 0x25
#define CPU_PI_HORIZ_WIDTH 0x26
#define CPU_PI_VERT_HEIGHT 0x27
#define PIXEL_MASK_CROP 0x28
#define CROP_FIRST_LINE 0x29
#define CROP_LAST_LINE 0x2A
#define CROP_FIRST_PIXEL 0x2B
#define CROP_LAST_PIXEL 0x2C
#define DMD_PARK_TRIGGER 0x2D
#define MISC_REG 0x30
/* AGC registers */
#define AGC_CTRL 0x50
#define AGC_CLIPPED_PIXS 0x55
#define AGC_BRIGHT_PIXS 0x56
#define AGC_BG_PIXS 0x57
#define AGC_SAFETY_MARGIN 0x17
/* Color Coordinate Adjustment registers */
#define CCA_ENABLE 0x5E
#define CCA_C1A 0x5F
#define CCA_C1B 0x60
#define CCA_C1C 0x61
#define CCA_C2A 0x62
#define CCA_C2B 0x63
#define CCA_C2C 0x64
#define CCA_C3A 0x65
#define CCA_C3B 0x66
#define CCA_C3C 0x67
#define CCA_C7A 0x71
#define CCA_C7B 0x72
#define CCA_C7C 0x73
/**
* DLP Pico Processor 2600 comes with flash
* We can do DMA operations from flash for accessing Look Up Tables
*/
#define DMA_STATUS 0x100
#define FLASH_ADDR_BYTES 0x74
#define FLASH_DUMMY_BYTES 0x75
#define FLASH_WRITE_BYTES 0x76
#define FLASH_READ_BYTES 0x77
#define FLASH_OPCODE 0x78
#define FLASH_START_ADDR 0x79
#define FLASH_DUMMY2 0x7A
#define FLASH_WRITE_DATA 0x7B
#define TEMPORAL_DITH_DISABLE 0x7E
#define SEQ_CONTROL 0x82
#define SEQ_VECTOR 0x83
/* DMD is Digital Micromirror Device */
#define DMD_BLOCK_COUNT 0x84
#define DMD_VCC_CONTROL 0x86
#define DMD_PARK_PULSE_COUNT 0x87
#define DMD_PARK_PULSE_WIDTH 0x88
#define DMD_PARK_DELAY 0x89
#define DMD_SHADOW_ENABLE 0x8E
#define SEQ_STATUS 0x8F
#define FLASH_CLOCK_CONTROL 0x98
#define DMD_PARK 0x2D
#define SDRAM_BIST_ENABLE 0x46
#define DDR_DRIVER_STRENGTH 0x9A
#define SDC_ENABLE 0x9D
#define SDC_BUFF_SWAP_DISABLE 0xA3
#define CURTAIN_CONTROL 0xA6
#define DDR_BUS_SWAP_ENABLE 0xA7
#define DMD_TRC_ENABLE 0xA8
#define DMD_BUS_SWAP_ENABLE 0xA9
#define ACTGEN_ENABLE 0xAE
#define ACTGEN_CONTROL 0xAF
#define ACTGEN_HORIZ_BP 0xB0
#define ACTGEN_VERT_BP 0xB1
/* Look Up Table access */
#define CMT_SPLASH_LUT_START_ADDR 0xFA
#define CMT_SPLASH_LUT_DEST_SELECT 0xFB
#define CMT_SPLASH_LUT_DATA 0xFC
#define SEQ_RESET_LUT_START_ADDR 0xFD
#define SEQ_RESET_LUT_DEST_SELECT 0xFE
#define SEQ_RESET_LUT_DATA 0xFF
/* Input source definitions */
#define PARALLEL_RGB 0
#define INT_TEST_PATTERN 1
#define SPLASH_SCREEN 2
#define CPU_INTF 3
#define BT656 4
/* Standard input resolution definitions */
#define QWVGA_LANDSCAPE 3 /* (427h*240v) */
#define WVGA_864_LANDSCAPE 21 /* (864h*480v) */
#define WVGA_DMD_OPTICAL_TEST 35 /* (608h*684v) */
/* Standard data format definitions */
#define RGB565 0
#define RGB666 1
#define RGB888 2
/* Test Pattern definitions */
#define TPG_CHECKERBOARD 0
#define TPG_BLACK 1
#define TPG_WHITE 2
#define TPG_RED 3
#define TPG_BLUE 4
#define TPG_GREEN 5
#define TPG_VLINES_BLACK 6
#define TPG_HLINES_BLACK 7
#define TPG_VLINES_ALT 8
#define TPG_HLINES_ALT 9
#define TPG_DIAG_LINES 10
#define TPG_GREYRAMP_VERT 11
#define TPG_GREYRAMP_HORIZ 12
#define TPG_ANSI_CHECKERBOARD 13
/* sequence mode definitions */
#define SEQ_FREE_RUN 0
#define SEQ_LOCK 1
/* curtain color definitions */
#define CURTAIN_BLACK 0
#define CURTAIN_RED 1
#define CURTAIN_GREEN 2
#define CURTAIN_BLUE 3
#define CURTAIN_YELLOW 4
#define CURTAIN_MAGENTA 5
#define CURTAIN_CYAN 6
#define CURTAIN_WHITE 7
/* LUT definitions */
#define CMT_LUT_NONE 0
#define CMT_LUT_GREEN 1
#define CMT_LUT_RED 2
#define CMT_LUT_BLUE 3
#define CMT_LUT_ALL 4
#define SPLASH_LUT 5
#define SEQ_LUT_NONE 0
#define SEQ_DRC_LUT_0 1
#define SEQ_DRC_LUT_1 2
#define SEQ_DRC_LUT_2 3
#define SEQ_DRC_LUT_3 4
#define SEQ_SEQ_LUT 5
#define SEQ_DRC_LUT_ALL 6
#define WPC_PROGRAM_LUT 7
#define BITSTREAM_START_ADDR 0x00000000
#define BITSTREAM_SIZE 0x00040000
#define WPC_FW_0_START_ADDR 0x00040000
#define WPC_FW_0_SIZE 0x00000ce8
#define SEQUENCE_0_START_ADDR 0x00044000
#define SEQUENCE_0_SIZE 0x00001000
#define SEQUENCE_1_START_ADDR 0x00045000
#define SEQUENCE_1_SIZE 0x00000d10
#define SEQUENCE_2_START_ADDR 0x00046000
#define SEQUENCE_2_SIZE 0x00000d10
#define SEQUENCE_3_START_ADDR 0x00047000
#define SEQUENCE_3_SIZE 0x00000d10
#define SEQUENCE_4_START_ADDR 0x00048000
#define SEQUENCE_4_SIZE 0x00000d10
#define SEQUENCE_5_START_ADDR 0x00049000
#define SEQUENCE_5_SIZE 0x00000d10
#define SEQUENCE_6_START_ADDR 0x0004a000
#define SEQUENCE_6_SIZE 0x00000d10
#define CMT_LUT_0_START_ADDR 0x0004b200
#define CMT_LUT_0_SIZE 0x00000600
#define CMT_LUT_1_START_ADDR 0x0004b800
#define CMT_LUT_1_SIZE 0x00000600
#define CMT_LUT_2_START_ADDR 0x0004be00
#define CMT_LUT_2_SIZE 0x00000600
#define CMT_LUT_3_START_ADDR 0x0004c400
#define CMT_LUT_3_SIZE 0x00000600
#define CMT_LUT_4_START_ADDR 0x0004ca00
#define CMT_LUT_4_SIZE 0x00000600
#define CMT_LUT_5_START_ADDR 0x0004d000
#define CMT_LUT_5_SIZE 0x00000600
#define CMT_LUT_6_START_ADDR 0x0004d600
#define CMT_LUT_6_SIZE 0x00000600
#define DRC_TABLE_0_START_ADDR 0x0004dc00
#define DRC_TABLE_0_SIZE 0x00000100
#define SPLASH_0_START_ADDR 0x0004dd00
#define SPLASH_0_SIZE 0x00032280
#define SEQUENCE_7_START_ADDR 0x00080000
#define SEQUENCE_7_SIZE 0x00000d10
#define SEQUENCE_8_START_ADDR 0x00081800
#define SEQUENCE_8_SIZE 0x00000d10
#define SEQUENCE_9_START_ADDR 0x00083000
#define SEQUENCE_9_SIZE 0x00000d10
#define CMT_LUT_7_START_ADDR 0x0008e000
#define CMT_LUT_7_SIZE 0x00000600
#define CMT_LUT_8_START_ADDR 0x0008e800
#define CMT_LUT_8_SIZE 0x00000600
#define CMT_LUT_9_START_ADDR 0x0008f000
#define CMT_LUT_9_SIZE 0x00000600
#define SPLASH_1_START_ADDR 0x0009a000
#define SPLASH_1_SIZE 0x00032280
#define SPLASH_2_START_ADDR 0x000cd000
#define SPLASH_2_SIZE 0x00032280
#define SPLASH_3_START_ADDR 0x00100000
#define SPLASH_3_SIZE 0x00032280
#define OPT_SPLASH_0_START_ADDR 0x00134000
#define OPT_SPLASH_0_SIZE 0x000cb100
#endif

View File

@ -35,26 +35,12 @@
#include <video/omapdss.h>
#include <video/omap-panel-nokia-dsi.h>
#include <video/mipi_display.h>
/* DSI Virtual channel. Hardcoded for now. */
#define TCH 0
#define DCS_READ_NUM_ERRORS 0x05
#define DCS_READ_POWER_MODE 0x0a
#define DCS_READ_MADCTL 0x0b
#define DCS_READ_PIXEL_FORMAT 0x0c
#define DCS_RDDSDR 0x0f
#define DCS_SLEEP_IN 0x10
#define DCS_SLEEP_OUT 0x11
#define DCS_DISPLAY_OFF 0x28
#define DCS_DISPLAY_ON 0x29
#define DCS_COLUMN_ADDR 0x2a
#define DCS_PAGE_ADDR 0x2b
#define DCS_MEMORY_WRITE 0x2c
#define DCS_TEAR_OFF 0x34
#define DCS_TEAR_ON 0x35
#define DCS_MEM_ACC_CTRL 0x36
#define DCS_PIXEL_FORMAT 0x3a
#define DCS_BRIGHTNESS 0x51
#define DCS_CTRL_DISPLAY 0x53
#define DCS_WRITE_CABC 0x55
@ -222,8 +208,6 @@ struct taal_data {
struct delayed_work te_timeout_work;
bool use_dsi_bl;
bool cabc_broken;
unsigned cabc_mode;
@ -302,7 +286,7 @@ static int taal_sleep_in(struct taal_data *td)
hw_guard_wait(td);
cmd = DCS_SLEEP_IN;
cmd = MIPI_DCS_ENTER_SLEEP_MODE;
r = dsi_vc_dcs_write_nosync(td->dssdev, td->channel, &cmd, 1);
if (r)
return r;
@ -321,7 +305,7 @@ static int taal_sleep_out(struct taal_data *td)
hw_guard_wait(td);
r = taal_dcs_write_0(td, DCS_SLEEP_OUT);
r = taal_dcs_write_0(td, MIPI_DCS_EXIT_SLEEP_MODE);
if (r)
return r;
@ -356,7 +340,7 @@ static int taal_set_addr_mode(struct taal_data *td, u8 rotate, bool mirror)
u8 mode;
int b5, b6, b7;
r = taal_dcs_read_1(td, DCS_READ_MADCTL, &mode);
r = taal_dcs_read_1(td, MIPI_DCS_GET_ADDRESS_MODE, &mode);
if (r)
return r;
@ -390,7 +374,7 @@ static int taal_set_addr_mode(struct taal_data *td, u8 rotate, bool mirror)
mode &= ~((1<<7) | (1<<6) | (1<<5));
mode |= (b7 << 7) | (b6 << 6) | (b5 << 5);
return taal_dcs_write_1(td, DCS_MEM_ACC_CTRL, mode);
return taal_dcs_write_1(td, MIPI_DCS_SET_ADDRESS_MODE, mode);
}
static int taal_set_update_window(struct taal_data *td,
@ -403,7 +387,7 @@ static int taal_set_update_window(struct taal_data *td,
u16 y2 = y + h - 1;
u8 buf[5];
buf[0] = DCS_COLUMN_ADDR;
buf[0] = MIPI_DCS_SET_COLUMN_ADDRESS;
buf[1] = (x1 >> 8) & 0xff;
buf[2] = (x1 >> 0) & 0xff;
buf[3] = (x2 >> 8) & 0xff;
@ -413,7 +397,7 @@ static int taal_set_update_window(struct taal_data *td,
if (r)
return r;
buf[0] = DCS_PAGE_ADDR;
buf[0] = MIPI_DCS_SET_PAGE_ADDRESS;
buf[1] = (y1 >> 8) & 0xff;
buf[2] = (y1 >> 0) & 0xff;
buf[3] = (y2 >> 8) & 0xff;
@ -555,7 +539,6 @@ static int taal_bl_update_status(struct backlight_device *dev)
{
struct omap_dss_device *dssdev = dev_get_drvdata(&dev->dev);
struct taal_data *td = dev_get_drvdata(&dssdev->dev);
struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
int r;
int level;
@ -569,23 +552,16 @@ static int taal_bl_update_status(struct backlight_device *dev)
mutex_lock(&td->lock);
if (td->use_dsi_bl) {
if (td->enabled) {
dsi_bus_lock(dssdev);
if (td->enabled) {
dsi_bus_lock(dssdev);
r = taal_wake_up(dssdev);
if (!r)
r = taal_dcs_write_1(td, DCS_BRIGHTNESS, level);
r = taal_wake_up(dssdev);
if (!r)
r = taal_dcs_write_1(td, DCS_BRIGHTNESS, level);
dsi_bus_unlock(dssdev);
} else {
r = 0;
}
dsi_bus_unlock(dssdev);
} else {
if (!panel_data->set_backlight)
r = -EINVAL;
else
r = panel_data->set_backlight(dssdev, level);
r = 0;
}
mutex_unlock(&td->lock);
@ -964,7 +940,7 @@ static int taal_probe(struct omap_dss_device *dssdev)
{
struct backlight_properties props;
struct taal_data *td;
struct backlight_device *bldev;
struct backlight_device *bldev = NULL;
struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
struct panel_config *panel_config = NULL;
int r, i;
@ -990,7 +966,7 @@ static int taal_probe(struct omap_dss_device *dssdev)
dssdev->panel.config = OMAP_DSS_LCD_TFT;
dssdev->panel.timings = panel_config->timings;
dssdev->ctrl.pixel_size = 24;
dssdev->panel.dsi_pix_fmt = OMAP_DSS_DSI_FMT_RGB888;
td = kzalloc(sizeof(*td), GFP_KERNEL);
if (!td) {
@ -1025,35 +1001,26 @@ static int taal_probe(struct omap_dss_device *dssdev)
taal_hw_reset(dssdev);
/* if no platform set_backlight() defined, presume DSI backlight
* control */
memset(&props, 0, sizeof(struct backlight_properties));
if (!panel_data->set_backlight)
td->use_dsi_bl = true;
if (td->use_dsi_bl)
if (panel_data->use_dsi_backlight) {
memset(&props, 0, sizeof(struct backlight_properties));
props.max_brightness = 255;
else
props.max_brightness = 127;
props.type = BACKLIGHT_RAW;
bldev = backlight_device_register(dev_name(&dssdev->dev), &dssdev->dev,
dssdev, &taal_bl_ops, &props);
if (IS_ERR(bldev)) {
r = PTR_ERR(bldev);
goto err_bl;
}
props.type = BACKLIGHT_RAW;
bldev = backlight_device_register(dev_name(&dssdev->dev),
&dssdev->dev, dssdev, &taal_bl_ops, &props);
if (IS_ERR(bldev)) {
r = PTR_ERR(bldev);
goto err_bl;
}
td->bldev = bldev;
td->bldev = bldev;
bldev->props.fb_blank = FB_BLANK_UNBLANK;
bldev->props.power = FB_BLANK_UNBLANK;
if (td->use_dsi_bl)
bldev->props.fb_blank = FB_BLANK_UNBLANK;
bldev->props.power = FB_BLANK_UNBLANK;
bldev->props.brightness = 255;
else
bldev->props.brightness = 127;
taal_bl_update_status(bldev);
taal_bl_update_status(bldev);
}
if (panel_data->use_ext_te) {
int gpio = panel_data->ext_te_gpio;
@ -1067,7 +1034,7 @@ static int taal_probe(struct omap_dss_device *dssdev)
gpio_direction_input(gpio);
r = request_irq(gpio_to_irq(gpio), taal_te_isr,
IRQF_DISABLED | IRQF_TRIGGER_RISING,
IRQF_TRIGGER_RISING,
"taal vsync", dssdev);
if (r) {
@ -1111,7 +1078,8 @@ err_irq:
if (panel_data->use_ext_te)
gpio_free(panel_data->ext_te_gpio);
err_gpio:
backlight_device_unregister(bldev);
if (bldev != NULL)
backlight_device_unregister(bldev);
err_bl:
destroy_workqueue(td->workqueue);
err_wq:
@ -1140,9 +1108,11 @@ static void __exit taal_remove(struct omap_dss_device *dssdev)
}
bldev = td->bldev;
bldev->props.power = FB_BLANK_POWERDOWN;
taal_bl_update_status(bldev);
backlight_device_unregister(bldev);
if (bldev != NULL) {
bldev->props.power = FB_BLANK_POWERDOWN;
taal_bl_update_status(bldev);
backlight_device_unregister(bldev);
}
taal_cancel_ulps_work(dssdev);
taal_cancel_esd_work(dssdev);
@ -1195,7 +1165,8 @@ static int taal_power_on(struct omap_dss_device *dssdev)
if (r)
goto err;
r = taal_dcs_write_1(td, DCS_PIXEL_FORMAT, 0x7); /* 24bit/pixel */
r = taal_dcs_write_1(td, MIPI_DCS_SET_PIXEL_FORMAT,
MIPI_DCS_PIXEL_FMT_24BIT);
if (r)
goto err;
@ -1209,7 +1180,7 @@ static int taal_power_on(struct omap_dss_device *dssdev)
goto err;
}
r = taal_dcs_write_0(td, DCS_DISPLAY_ON);
r = taal_dcs_write_0(td, MIPI_DCS_SET_DISPLAY_ON);
if (r)
goto err;
@ -1246,7 +1217,7 @@ static void taal_power_off(struct omap_dss_device *dssdev)
struct taal_data *td = dev_get_drvdata(&dssdev->dev);
int r;
r = taal_dcs_write_0(td, DCS_DISPLAY_OFF);
r = taal_dcs_write_0(td, MIPI_DCS_SET_DISPLAY_OFF);
if (!r)
r = taal_sleep_in(td);
@ -1529,9 +1500,9 @@ static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable)
int r;
if (enable)
r = taal_dcs_write_1(td, DCS_TEAR_ON, 0);
r = taal_dcs_write_1(td, MIPI_DCS_SET_TEAR_ON, 0);
else
r = taal_dcs_write_0(td, DCS_TEAR_OFF);
r = taal_dcs_write_0(td, MIPI_DCS_SET_TEAR_OFF);
if (!panel_data->use_ext_te)
omapdss_dsi_enable_te(dssdev, enable);
@ -1851,7 +1822,7 @@ static void taal_esd_work(struct work_struct *work)
goto err;
}
r = taal_dcs_read_1(td, DCS_RDDSDR, &state1);
r = taal_dcs_read_1(td, MIPI_DCS_GET_DIAGNOSTIC_RESULT, &state1);
if (r) {
dev_err(&dssdev->dev, "failed to read Taal status\n");
goto err;
@ -1864,7 +1835,7 @@ static void taal_esd_work(struct work_struct *work)
goto err;
}
r = taal_dcs_read_1(td, DCS_RDDSDR, &state2);
r = taal_dcs_read_1(td, MIPI_DCS_GET_DIAGNOSTIC_RESULT, &state2);
if (r) {
dev_err(&dssdev->dev, "failed to read Taal status\n");
goto err;
@ -1880,7 +1851,7 @@ static void taal_esd_work(struct work_struct *work)
/* Self-diagnostics result is also shown on TE GPIO line. We need
* to re-enable TE after self diagnostics */
if (td->te_enabled && panel_data->use_ext_te) {
r = taal_dcs_write_1(td, DCS_TEAR_ON, 0);
r = taal_dcs_write_1(td, MIPI_DCS_SET_TEAR_ON, 0);
if (r)
goto err;
}

View File

@ -1,5 +1,5 @@
menuconfig OMAP2_DSS
tristate "OMAP2+ Display Subsystem support (EXPERIMENTAL)"
tristate "OMAP2+ Display Subsystem support"
depends on ARCH_OMAP2PLUS
help
OMAP2+ Display Subsystem support.

View File

@ -6,4 +6,4 @@ omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o
omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o
omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o
omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi.o \
hdmi_omap4_panel.o
hdmi_panel.o ti_hdmi_4xxx_ip.o

View File

@ -144,6 +144,10 @@ static int dss_initialize_debugfs(void)
#ifdef CONFIG_OMAP2_DSS_VENC
debugfs_create_file("venc", S_IRUGO, dss_debugfs_dir,
&venc_dump_regs, &dss_debug_fops);
#endif
#ifdef CONFIG_OMAP4_DSS_HDMI
debugfs_create_file("hdmi", S_IRUGO, dss_debugfs_dir,
&hdmi_dump_regs, &dss_debug_fops);
#endif
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -291,6 +291,8 @@ static inline u16 DISPC_OVL_BASE(enum omap_plane plane)
return 0x00BC;
case OMAP_DSS_VIDEO2:
return 0x014C;
case OMAP_DSS_VIDEO3:
return 0x0300;
default:
BUG();
}
@ -304,6 +306,8 @@ static inline u16 DISPC_BA0_OFFSET(enum omap_plane plane)
case OMAP_DSS_VIDEO1:
case OMAP_DSS_VIDEO2:
return 0x0000;
case OMAP_DSS_VIDEO3:
return 0x0008;
default:
BUG();
}
@ -316,6 +320,8 @@ static inline u16 DISPC_BA1_OFFSET(enum omap_plane plane)
case OMAP_DSS_VIDEO1:
case OMAP_DSS_VIDEO2:
return 0x0004;
case OMAP_DSS_VIDEO3:
return 0x000C;
default:
BUG();
}
@ -330,6 +336,8 @@ static inline u16 DISPC_BA0_UV_OFFSET(enum omap_plane plane)
return 0x0544;
case OMAP_DSS_VIDEO2:
return 0x04BC;
case OMAP_DSS_VIDEO3:
return 0x0310;
default:
BUG();
}
@ -344,6 +352,8 @@ static inline u16 DISPC_BA1_UV_OFFSET(enum omap_plane plane)
return 0x0548;
case OMAP_DSS_VIDEO2:
return 0x04C0;
case OMAP_DSS_VIDEO3:
return 0x0314;
default:
BUG();
}
@ -356,6 +366,8 @@ static inline u16 DISPC_POS_OFFSET(enum omap_plane plane)
case OMAP_DSS_VIDEO1:
case OMAP_DSS_VIDEO2:
return 0x0008;
case OMAP_DSS_VIDEO3:
return 0x009C;
default:
BUG();
}
@ -368,6 +380,8 @@ static inline u16 DISPC_SIZE_OFFSET(enum omap_plane plane)
case OMAP_DSS_VIDEO1:
case OMAP_DSS_VIDEO2:
return 0x000C;
case OMAP_DSS_VIDEO3:
return 0x00A8;
default:
BUG();
}
@ -381,6 +395,8 @@ static inline u16 DISPC_ATTR_OFFSET(enum omap_plane plane)
case OMAP_DSS_VIDEO1:
case OMAP_DSS_VIDEO2:
return 0x0010;
case OMAP_DSS_VIDEO3:
return 0x0070;
default:
BUG();
}
@ -395,6 +411,8 @@ static inline u16 DISPC_ATTR2_OFFSET(enum omap_plane plane)
return 0x0568;
case OMAP_DSS_VIDEO2:
return 0x04DC;
case OMAP_DSS_VIDEO3:
return 0x032C;
default:
BUG();
}
@ -408,6 +426,8 @@ static inline u16 DISPC_FIFO_THRESH_OFFSET(enum omap_plane plane)
case OMAP_DSS_VIDEO1:
case OMAP_DSS_VIDEO2:
return 0x0014;
case OMAP_DSS_VIDEO3:
return 0x008C;
default:
BUG();
}
@ -421,6 +441,8 @@ static inline u16 DISPC_FIFO_SIZE_STATUS_OFFSET(enum omap_plane plane)
case OMAP_DSS_VIDEO1:
case OMAP_DSS_VIDEO2:
return 0x0018;
case OMAP_DSS_VIDEO3:
return 0x0088;
default:
BUG();
}
@ -434,6 +456,8 @@ static inline u16 DISPC_ROW_INC_OFFSET(enum omap_plane plane)
case OMAP_DSS_VIDEO1:
case OMAP_DSS_VIDEO2:
return 0x001C;
case OMAP_DSS_VIDEO3:
return 0x00A4;
default:
BUG();
}
@ -447,6 +471,8 @@ static inline u16 DISPC_PIX_INC_OFFSET(enum omap_plane plane)
case OMAP_DSS_VIDEO1:
case OMAP_DSS_VIDEO2:
return 0x0020;
case OMAP_DSS_VIDEO3:
return 0x0098;
default:
BUG();
}
@ -459,6 +485,7 @@ static inline u16 DISPC_WINDOW_SKIP_OFFSET(enum omap_plane plane)
return 0x0034;
case OMAP_DSS_VIDEO1:
case OMAP_DSS_VIDEO2:
case OMAP_DSS_VIDEO3:
BUG();
default:
BUG();
@ -472,6 +499,7 @@ static inline u16 DISPC_TABLE_BA_OFFSET(enum omap_plane plane)
return 0x0038;
case OMAP_DSS_VIDEO1:
case OMAP_DSS_VIDEO2:
case OMAP_DSS_VIDEO3:
BUG();
default:
BUG();
@ -486,6 +514,8 @@ static inline u16 DISPC_FIR_OFFSET(enum omap_plane plane)
case OMAP_DSS_VIDEO1:
case OMAP_DSS_VIDEO2:
return 0x0024;
case OMAP_DSS_VIDEO3:
return 0x0090;
default:
BUG();
}
@ -500,6 +530,8 @@ static inline u16 DISPC_FIR2_OFFSET(enum omap_plane plane)
return 0x0580;
case OMAP_DSS_VIDEO2:
return 0x055C;
case OMAP_DSS_VIDEO3:
return 0x0424;
default:
BUG();
}
@ -513,6 +545,8 @@ static inline u16 DISPC_PIC_SIZE_OFFSET(enum omap_plane plane)
case OMAP_DSS_VIDEO1:
case OMAP_DSS_VIDEO2:
return 0x0028;
case OMAP_DSS_VIDEO3:
return 0x0094;
default:
BUG();
}
@ -527,6 +561,8 @@ static inline u16 DISPC_ACCU0_OFFSET(enum omap_plane plane)
case OMAP_DSS_VIDEO1:
case OMAP_DSS_VIDEO2:
return 0x002C;
case OMAP_DSS_VIDEO3:
return 0x0000;
default:
BUG();
}
@ -541,6 +577,8 @@ static inline u16 DISPC_ACCU2_0_OFFSET(enum omap_plane plane)
return 0x0584;
case OMAP_DSS_VIDEO2:
return 0x0560;
case OMAP_DSS_VIDEO3:
return 0x0428;
default:
BUG();
}
@ -554,6 +592,8 @@ static inline u16 DISPC_ACCU1_OFFSET(enum omap_plane plane)
case OMAP_DSS_VIDEO1:
case OMAP_DSS_VIDEO2:
return 0x0030;
case OMAP_DSS_VIDEO3:
return 0x0004;
default:
BUG();
}
@ -568,6 +608,8 @@ static inline u16 DISPC_ACCU2_1_OFFSET(enum omap_plane plane)
return 0x0588;
case OMAP_DSS_VIDEO2:
return 0x0564;
case OMAP_DSS_VIDEO3:
return 0x042C;
default:
BUG();
}
@ -582,6 +624,8 @@ static inline u16 DISPC_FIR_COEF_H_OFFSET(enum omap_plane plane, u16 i)
case OMAP_DSS_VIDEO1:
case OMAP_DSS_VIDEO2:
return 0x0034 + i * 0x8;
case OMAP_DSS_VIDEO3:
return 0x0010 + i * 0x8;
default:
BUG();
}
@ -597,6 +641,8 @@ static inline u16 DISPC_FIR_COEF_H2_OFFSET(enum omap_plane plane, u16 i)
return 0x058C + i * 0x8;
case OMAP_DSS_VIDEO2:
return 0x0568 + i * 0x8;
case OMAP_DSS_VIDEO3:
return 0x0430 + i * 0x8;
default:
BUG();
}
@ -611,6 +657,8 @@ static inline u16 DISPC_FIR_COEF_HV_OFFSET(enum omap_plane plane, u16 i)
case OMAP_DSS_VIDEO1:
case OMAP_DSS_VIDEO2:
return 0x0038 + i * 0x8;
case OMAP_DSS_VIDEO3:
return 0x0014 + i * 0x8;
default:
BUG();
}
@ -626,6 +674,8 @@ static inline u16 DISPC_FIR_COEF_HV2_OFFSET(enum omap_plane plane, u16 i)
return 0x0590 + i * 8;
case OMAP_DSS_VIDEO2:
return 0x056C + i * 0x8;
case OMAP_DSS_VIDEO3:
return 0x0434 + i * 0x8;
default:
BUG();
}
@ -639,6 +689,7 @@ static inline u16 DISPC_CONV_COEF_OFFSET(enum omap_plane plane, u16 i)
BUG();
case OMAP_DSS_VIDEO1:
case OMAP_DSS_VIDEO2:
case OMAP_DSS_VIDEO3:
return 0x0074 + i * 0x4;
default:
BUG();
@ -655,6 +706,8 @@ static inline u16 DISPC_FIR_COEF_V_OFFSET(enum omap_plane plane, u16 i)
return 0x0124 + i * 0x4;
case OMAP_DSS_VIDEO2:
return 0x00B4 + i * 0x4;
case OMAP_DSS_VIDEO3:
return 0x0050 + i * 0x4;
default:
BUG();
}
@ -670,6 +723,8 @@ static inline u16 DISPC_FIR_COEF_V2_OFFSET(enum omap_plane plane, u16 i)
return 0x05CC + i * 0x4;
case OMAP_DSS_VIDEO2:
return 0x05A8 + i * 0x4;
case OMAP_DSS_VIDEO3:
return 0x0470 + i * 0x4;
default:
BUG();
}
@ -684,6 +739,8 @@ static inline u16 DISPC_PRELOAD_OFFSET(enum omap_plane plane)
return 0x0174;
case OMAP_DSS_VIDEO2:
return 0x00E8;
case OMAP_DSS_VIDEO3:
return 0x00A0;
default:
BUG();
}

View File

@ -45,14 +45,13 @@ static ssize_t display_enabled_store(struct device *dev,
const char *buf, size_t size)
{
struct omap_dss_device *dssdev = to_dss_device(dev);
int r, enabled;
int r;
bool enabled;
r = kstrtoint(buf, 0, &enabled);
r = strtobool(buf, &enabled);
if (r)
return r;
enabled = !!enabled;
if (enabled != (dssdev->state != OMAP_DSS_DISPLAY_DISABLED)) {
if (enabled) {
r = dssdev->driver->enable(dssdev);
@ -79,17 +78,16 @@ static ssize_t display_tear_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size)
{
struct omap_dss_device *dssdev = to_dss_device(dev);
int te, r;
int r;
bool te;
if (!dssdev->driver->enable_te || !dssdev->driver->get_te)
return -ENOENT;
r = kstrtoint(buf, 0, &te);
r = strtobool(buf, &te);
if (r)
return r;
te = !!te;
r = dssdev->driver->enable_te(dssdev, te);
if (r)
return r;
@ -195,17 +193,16 @@ static ssize_t display_mirror_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size)
{
struct omap_dss_device *dssdev = to_dss_device(dev);
int mirror, r;
int r;
bool mirror;
if (!dssdev->driver->set_mirror || !dssdev->driver->get_mirror)
return -ENOENT;
r = kstrtoint(buf, 0, &mirror);
r = strtobool(buf, &mirror);
if (r)
return r;
mirror = !!mirror;
r = dssdev->driver->set_mirror(dssdev, mirror);
if (r)
return r;
@ -302,11 +299,15 @@ int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev)
return 16;
case OMAP_DISPLAY_TYPE_DBI:
case OMAP_DISPLAY_TYPE_DSI:
if (dssdev->ctrl.pixel_size == 24)
return 24;
else
return 16;
case OMAP_DISPLAY_TYPE_DSI:
if (dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt) > 16)
return 24;
else
return 16;
case OMAP_DISPLAY_TYPE_VENC:
case OMAP_DISPLAY_TYPE_SDI:
case OMAP_DISPLAY_TYPE_HDMI:
@ -342,9 +343,11 @@ bool dss_use_replication(struct omap_dss_device *dssdev,
bpp = 24;
break;
case OMAP_DISPLAY_TYPE_DBI:
case OMAP_DISPLAY_TYPE_DSI:
bpp = dssdev->ctrl.pixel_size;
break;
case OMAP_DISPLAY_TYPE_DSI:
bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
break;
default:
BUG();
}

View File

@ -82,9 +82,11 @@ static int dpi_set_dsi_clk(struct omap_dss_device *dssdev, bool is_tft,
dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src);
r = dispc_set_clock_div(dssdev->manager->id, &dispc_cinfo);
if (r)
r = dispc_mgr_set_clock_div(dssdev->manager->id, &dispc_cinfo);
if (r) {
dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
return r;
}
*fck = dsi_cinfo.dsi_pll_hsdiv_dispc_clk;
*lck_div = dispc_cinfo.lck_div;
@ -109,7 +111,7 @@ static int dpi_set_dispc_clk(struct omap_dss_device *dssdev, bool is_tft,
if (r)
return r;
r = dispc_set_clock_div(dssdev->manager->id, &dispc_cinfo);
r = dispc_mgr_set_clock_div(dssdev->manager->id, &dispc_cinfo);
if (r)
return r;
@ -129,7 +131,7 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
bool is_tft;
int r = 0;
dispc_set_pol_freq(dssdev->manager->id, dssdev->panel.config,
dispc_mgr_set_pol_freq(dssdev->manager->id, dssdev->panel.config,
dssdev->panel.acbi, dssdev->panel.acb);
is_tft = (dssdev->panel.config & OMAP_DSS_LCD_TFT) != 0;
@ -153,7 +155,7 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
t->pixel_clock = pck;
}
dispc_set_lcd_timings(dssdev->manager->id, t);
dispc_mgr_set_lcd_timings(dssdev->manager->id, t);
return 0;
}
@ -164,11 +166,12 @@ static void dpi_basic_init(struct omap_dss_device *dssdev)
is_tft = (dssdev->panel.config & OMAP_DSS_LCD_TFT) != 0;
dispc_set_parallel_interface_mode(dssdev->manager->id,
OMAP_DSS_PARALLELMODE_BYPASS);
dispc_set_lcd_display_type(dssdev->manager->id, is_tft ?
dispc_mgr_set_io_pad_mode(DSS_IO_PAD_MODE_BYPASS);
dispc_mgr_enable_stallmode(dssdev->manager->id, false);
dispc_mgr_set_lcd_display_type(dssdev->manager->id, is_tft ?
OMAP_DSS_LCD_DISPLAY_TFT : OMAP_DSS_LCD_DISPLAY_STN);
dispc_set_tft_data_lines(dssdev->manager->id,
dispc_mgr_set_tft_data_lines(dssdev->manager->id,
dssdev->phy.dpi.data_lines);
}
@ -176,6 +179,11 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
{
int r;
if (dssdev->manager == NULL) {
DSSERR("failed to enable display: no manager\n");
return -ENODEV;
}
r = omap_dss_start_device(dssdev);
if (r) {
DSSERR("failed to start device\n");
@ -277,7 +285,7 @@ void dpi_set_timings(struct omap_dss_device *dssdev,
}
dpi_set_mode(dssdev);
dispc_go(dssdev->manager->id);
dispc_mgr_go(dssdev->manager->id);
dispc_runtime_put();
dss_runtime_put();

File diff suppressed because it is too large Load Diff

View File

@ -639,6 +639,17 @@ void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select hdmi)
REG_FLD_MOD(DSS_CONTROL, hdmi, 15, 15); /* VENC_HDMI_SWITCH */
}
enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void)
{
enum omap_display_type displays;
displays = dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_DIGIT);
if ((displays & OMAP_DISPLAY_TYPE_HDMI) == 0)
return DSS_VENC_TV_CLK;
return REG_GET(DSS_CONTROL, 15, 15);
}
static int dss_get_clocks(void)
{
struct clk *clk;
@ -691,11 +702,6 @@ static void dss_put_clocks(void)
clk_put(dss.dss_clk);
}
struct clk *dss_get_ick(void)
{
return clk_get(&dss.pdev->dev, "ick");
}
int dss_runtime_get(void)
{
int r;
@ -824,13 +830,11 @@ static int omap_dsshw_remove(struct platform_device *pdev)
static int dss_runtime_suspend(struct device *dev)
{
dss_save_context();
clk_disable(dss.dss_clk);
return 0;
}
static int dss_runtime_resume(struct device *dev)
{
clk_enable(dss.dss_clk);
dss_restore_context();
return 0;
}

View File

@ -97,10 +97,10 @@ extern unsigned int dss_debug;
#define FLD_MOD(orig, val, start, end) \
(((orig) & ~FLD_MASK(start, end)) | FLD_VAL(val, start, end))
enum omap_parallel_interface_mode {
OMAP_DSS_PARALLELMODE_BYPASS, /* MIPI DPI */
OMAP_DSS_PARALLELMODE_RFBI, /* MIPI DBI */
OMAP_DSS_PARALLELMODE_DSI,
enum dss_io_pad_mode {
DSS_IO_PAD_MODE_RESET,
DSS_IO_PAD_MODE_RFBI,
DSS_IO_PAD_MODE_BYPASS,
};
enum dss_hdmi_venc_clk_source_select {
@ -108,6 +108,11 @@ enum dss_hdmi_venc_clk_source_select {
DSS_HDMI_M_PCLK = 1,
};
enum dss_dsi_content_type {
DSS_DSI_CONTENT_DCS,
DSS_DSI_CONTENT_GENERIC,
};
struct dss_clock_info {
/* rates that we get with dividers below */
unsigned long fck;
@ -150,16 +155,6 @@ struct dsi_clock_info {
bool use_sys_clk;
};
/* HDMI PLL structure */
struct hdmi_pll_info {
u16 regn;
u16 regm;
u32 regmf;
u16 regm2;
u16 regsd;
u16 dcofreq;
};
struct seq_file;
struct platform_device;
@ -209,9 +204,8 @@ void dss_uninit_platform_driver(void);
int dss_runtime_get(void);
void dss_runtime_put(void);
struct clk *dss_get_ick(void);
void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select);
enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void);
const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src);
void dss_dump_clocks(struct seq_file *s);
@ -279,6 +273,8 @@ void dsi_create_debugfs_files_reg(struct dentry *debugfs_dir,
int dsi_init_display(struct omap_dss_device *display);
void dsi_irq_handler(void);
u8 dsi_get_pixel_size(enum omap_dss_dsi_pixel_format fmt);
unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev);
int dsi_pll_set_clock_div(struct platform_device *dsidev,
struct dsi_clock_info *cinfo);
@ -309,6 +305,11 @@ static inline int dsi_runtime_get(struct platform_device *dsidev)
static inline void dsi_runtime_put(struct platform_device *dsidev)
{
}
static inline u8 dsi_get_pixel_size(enum omap_dss_dsi_pixel_format fmt)
{
WARN("%s: DSI not compiled in, returning pixel_size as 0\n", __func__);
return 0;
}
static inline unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev)
{
WARN("%s: DSI not compiled in, returning rate as 0\n", __func__);
@ -385,90 +386,71 @@ void dispc_disable_sidle(void);
void dispc_lcd_enable_signal_polarity(bool act_high);
void dispc_lcd_enable_signal(bool enable);
void dispc_pck_free_enable(bool enable);
void dispc_enable_fifohandcheck(enum omap_channel channel, bool enable);
void dispc_set_lcd_size(enum omap_channel channel, u16 width, u16 height);
void dispc_set_digit_size(u16 width, u16 height);
u32 dispc_get_plane_fifo_size(enum omap_plane plane);
void dispc_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high);
void dispc_enable_fifomerge(bool enable);
u32 dispc_get_burst_size(enum omap_plane plane);
void dispc_enable_cpr(enum omap_channel channel, bool enable);
void dispc_set_cpr_coef(enum omap_channel channel,
struct omap_dss_cpr_coefs *coefs);
void dispc_set_plane_ba0(enum omap_plane plane, u32 paddr);
void dispc_set_plane_ba1(enum omap_plane plane, u32 paddr);
void dispc_set_plane_pos(enum omap_plane plane, u16 x, u16 y);
void dispc_set_plane_size(enum omap_plane plane, u16 width, u16 height);
void dispc_set_channel_out(enum omap_plane plane,
enum omap_channel channel_out);
void dispc_enable_gamma_table(bool enable);
int dispc_setup_plane(enum omap_plane plane,
u32 paddr, u16 screen_width,
u16 pos_x, u16 pos_y,
u16 width, u16 height,
u16 out_width, u16 out_height,
enum omap_color_mode color_mode,
bool ilace,
enum omap_dss_rotation_type rotation_type,
u8 rotation, bool mirror,
u8 global_alpha, u8 pre_mult_alpha,
enum omap_channel channel,
u32 puv_addr);
bool dispc_go_busy(enum omap_channel channel);
void dispc_go(enum omap_channel channel);
void dispc_enable_channel(enum omap_channel channel, bool enable);
bool dispc_is_channel_enabled(enum omap_channel channel);
int dispc_enable_plane(enum omap_plane plane, bool enable);
void dispc_enable_replication(enum omap_plane plane, bool enable);
void dispc_set_parallel_interface_mode(enum omap_channel channel,
enum omap_parallel_interface_mode mode);
void dispc_set_tft_data_lines(enum omap_channel channel, u8 data_lines);
void dispc_set_lcd_display_type(enum omap_channel channel,
enum omap_lcd_display_type type);
void dispc_set_loadmode(enum omap_dss_load_mode mode);
void dispc_set_default_color(enum omap_channel channel, u32 color);
u32 dispc_get_default_color(enum omap_channel channel);
void dispc_set_trans_key(enum omap_channel ch,
enum omap_dss_trans_key_type type,
u32 trans_key);
void dispc_get_trans_key(enum omap_channel ch,
enum omap_dss_trans_key_type *type,
u32 *trans_key);
void dispc_enable_trans_key(enum omap_channel ch, bool enable);
void dispc_enable_alpha_blending(enum omap_channel ch, bool enable);
bool dispc_trans_key_enabled(enum omap_channel ch);
bool dispc_alpha_blending_enabled(enum omap_channel ch);
bool dispc_lcd_timings_ok(struct omap_video_timings *timings);
void dispc_set_lcd_timings(enum omap_channel channel,
struct omap_video_timings *timings);
unsigned long dispc_fclk_rate(void);
unsigned long dispc_lclk_rate(enum omap_channel channel);
unsigned long dispc_pclk_rate(enum omap_channel channel);
void dispc_set_pol_freq(enum omap_channel channel,
enum omap_panel_config config, u8 acbi, u8 acb);
void dispc_find_clk_divs(bool is_tft, unsigned long req_pck, unsigned long fck,
struct dispc_clock_info *cinfo);
int dispc_calc_clock_rates(unsigned long dispc_fclk_rate,
struct dispc_clock_info *cinfo);
int dispc_set_clock_div(enum omap_channel channel,
struct dispc_clock_info *cinfo);
int dispc_get_clock_div(enum omap_channel channel,
struct dispc_clock_info *cinfo);
u32 dispc_ovl_get_fifo_size(enum omap_plane plane);
u32 dispc_ovl_get_burst_size(enum omap_plane plane);
int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
bool ilace, enum omap_channel channel, bool replication,
u32 fifo_low, u32 fifo_high);
int dispc_ovl_enable(enum omap_plane plane, bool enable);
void dispc_mgr_enable_fifohandcheck(enum omap_channel channel, bool enable);
void dispc_mgr_set_lcd_size(enum omap_channel channel, u16 width, u16 height);
void dispc_mgr_enable_cpr(enum omap_channel channel, bool enable);
void dispc_mgr_set_cpr_coef(enum omap_channel channel,
struct omap_dss_cpr_coefs *coefs);
bool dispc_mgr_go_busy(enum omap_channel channel);
void dispc_mgr_go(enum omap_channel channel);
void dispc_mgr_enable(enum omap_channel channel, bool enable);
bool dispc_mgr_is_channel_enabled(enum omap_channel channel);
void dispc_mgr_set_io_pad_mode(enum dss_io_pad_mode mode);
void dispc_mgr_enable_stallmode(enum omap_channel channel, bool enable);
void dispc_mgr_set_tft_data_lines(enum omap_channel channel, u8 data_lines);
void dispc_mgr_set_lcd_display_type(enum omap_channel channel,
enum omap_lcd_display_type type);
void dispc_mgr_set_default_color(enum omap_channel channel, u32 color);
u32 dispc_mgr_get_default_color(enum omap_channel channel);
void dispc_mgr_set_trans_key(enum omap_channel ch,
enum omap_dss_trans_key_type type,
u32 trans_key);
void dispc_mgr_get_trans_key(enum omap_channel ch,
enum omap_dss_trans_key_type *type,
u32 *trans_key);
void dispc_mgr_enable_trans_key(enum omap_channel ch, bool enable);
void dispc_mgr_enable_alpha_fixed_zorder(enum omap_channel ch, bool enable);
bool dispc_mgr_trans_key_enabled(enum omap_channel ch);
bool dispc_mgr_alpha_fixed_zorder_enabled(enum omap_channel ch);
void dispc_mgr_set_lcd_timings(enum omap_channel channel,
struct omap_video_timings *timings);
void dispc_mgr_set_pol_freq(enum omap_channel channel,
enum omap_panel_config config, u8 acbi, u8 acb);
unsigned long dispc_mgr_lclk_rate(enum omap_channel channel);
unsigned long dispc_mgr_pclk_rate(enum omap_channel channel);
int dispc_mgr_set_clock_div(enum omap_channel channel,
struct dispc_clock_info *cinfo);
int dispc_mgr_get_clock_div(enum omap_channel channel,
struct dispc_clock_info *cinfo);
/* VENC */
#ifdef CONFIG_OMAP2_DSS_VENC
int venc_init_platform_driver(void);
void venc_uninit_platform_driver(void);
void venc_dump_regs(struct seq_file *s);
int venc_init_display(struct omap_dss_device *display);
unsigned long venc_get_pixel_clock(void);
#else
static inline int venc_init_platform_driver(void)
{
@ -477,6 +459,11 @@ static inline int venc_init_platform_driver(void)
static inline void venc_uninit_platform_driver(void)
{
}
static inline unsigned long venc_get_pixel_clock(void)
{
WARN("%s: VENC not compiled in, returning pclk as 0\n", __func__);
return 0;
}
#endif
/* HDMI */
@ -484,6 +471,8 @@ static inline void venc_uninit_platform_driver(void)
int hdmi_init_platform_driver(void);
void hdmi_uninit_platform_driver(void);
int hdmi_init_display(struct omap_dss_device *dssdev);
unsigned long hdmi_get_pixel_clock(void);
void hdmi_dump_regs(struct seq_file *s);
#else
static inline int hdmi_init_display(struct omap_dss_device *dssdev)
{
@ -496,12 +485,19 @@ static inline int hdmi_init_platform_driver(void)
static inline void hdmi_uninit_platform_driver(void)
{
}
static inline unsigned long hdmi_get_pixel_clock(void)
{
WARN("%s: HDMI not compiled in, returning pclk as 0\n", __func__);
return 0;
}
#endif
int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev);
void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev);
void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev);
int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
struct omap_video_timings *timings);
int omapdss_hdmi_read_edid(u8 *buf, int len);
bool omapdss_hdmi_detect(void);
int hdmi_panel_init(void);
void hdmi_panel_exit(void);

View File

@ -47,6 +47,7 @@ struct omap_dss_features {
const int num_ovls;
const enum omap_display_type *supported_displays;
const enum omap_color_mode *supported_color_modes;
const enum omap_overlay_caps *overlay_caps;
const char * const *clksrc_names;
const struct dss_param_range *dss_params;
@ -209,6 +210,68 @@ static const enum omap_color_mode omap4_dss_supported_color_modes[] = {
OMAP_DSS_COLOR_ARGB16 | OMAP_DSS_COLOR_XRGB16_1555 |
OMAP_DSS_COLOR_ARGB32 | OMAP_DSS_COLOR_RGBX16 |
OMAP_DSS_COLOR_RGBX32,
/* OMAP_DSS_VIDEO3 */
OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB12U |
OMAP_DSS_COLOR_YUV2 | OMAP_DSS_COLOR_ARGB16_1555 |
OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_NV12 |
OMAP_DSS_COLOR_RGBA16 | OMAP_DSS_COLOR_RGB24U |
OMAP_DSS_COLOR_RGB24P | OMAP_DSS_COLOR_UYVY |
OMAP_DSS_COLOR_ARGB16 | OMAP_DSS_COLOR_XRGB16_1555 |
OMAP_DSS_COLOR_ARGB32 | OMAP_DSS_COLOR_RGBX16 |
OMAP_DSS_COLOR_RGBX32,
};
static const enum omap_overlay_caps omap2_dss_overlay_caps[] = {
/* OMAP_DSS_GFX */
0,
/* OMAP_DSS_VIDEO1 */
OMAP_DSS_OVL_CAP_SCALE,
/* OMAP_DSS_VIDEO2 */
OMAP_DSS_OVL_CAP_SCALE,
};
static const enum omap_overlay_caps omap3430_dss_overlay_caps[] = {
/* OMAP_DSS_GFX */
OMAP_DSS_OVL_CAP_GLOBAL_ALPHA,
/* OMAP_DSS_VIDEO1 */
OMAP_DSS_OVL_CAP_SCALE,
/* OMAP_DSS_VIDEO2 */
OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA,
};
static const enum omap_overlay_caps omap3630_dss_overlay_caps[] = {
/* OMAP_DSS_GFX */
OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA,
/* OMAP_DSS_VIDEO1 */
OMAP_DSS_OVL_CAP_SCALE,
/* OMAP_DSS_VIDEO2 */
OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA,
};
static const enum omap_overlay_caps omap4_dss_overlay_caps[] = {
/* OMAP_DSS_GFX */
OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA |
OMAP_DSS_OVL_CAP_ZORDER,
/* OMAP_DSS_VIDEO1 */
OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER,
/* OMAP_DSS_VIDEO2 */
OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER,
/* OMAP_DSS_VIDEO3 */
OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER,
};
static const char * const omap2_dss_clk_source_names[] = {
@ -233,32 +296,38 @@ static const char * const omap4_dss_clk_source_names[] = {
static const struct dss_param_range omap2_dss_param_range[] = {
[FEAT_PARAM_DSS_FCK] = { 0, 173000000 },
[FEAT_PARAM_DSS_PCD] = { 2, 255 },
[FEAT_PARAM_DSIPLL_REGN] = { 0, 0 },
[FEAT_PARAM_DSIPLL_REGM] = { 0, 0 },
[FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, 0 },
[FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, 0 },
[FEAT_PARAM_DSIPLL_FINT] = { 0, 0 },
[FEAT_PARAM_DSIPLL_LPDIV] = { 0, 0 },
[FEAT_PARAM_DOWNSCALE] = { 1, 2 },
};
static const struct dss_param_range omap3_dss_param_range[] = {
[FEAT_PARAM_DSS_FCK] = { 0, 173000000 },
[FEAT_PARAM_DSS_PCD] = { 1, 255 },
[FEAT_PARAM_DSIPLL_REGN] = { 0, (1 << 7) - 1 },
[FEAT_PARAM_DSIPLL_REGM] = { 0, (1 << 11) - 1 },
[FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, (1 << 4) - 1 },
[FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, (1 << 4) - 1 },
[FEAT_PARAM_DSIPLL_FINT] = { 750000, 2100000 },
[FEAT_PARAM_DSIPLL_LPDIV] = { 1, (1 << 13) - 1},
[FEAT_PARAM_DOWNSCALE] = { 1, 4 },
};
static const struct dss_param_range omap4_dss_param_range[] = {
[FEAT_PARAM_DSS_FCK] = { 0, 186000000 },
[FEAT_PARAM_DSS_PCD] = { 1, 255 },
[FEAT_PARAM_DSIPLL_REGN] = { 0, (1 << 8) - 1 },
[FEAT_PARAM_DSIPLL_REGM] = { 0, (1 << 12) - 1 },
[FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, (1 << 5) - 1 },
[FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, (1 << 5) - 1 },
[FEAT_PARAM_DSIPLL_FINT] = { 500000, 2500000 },
[FEAT_PARAM_DSIPLL_LPDIV] = { 0, (1 << 13) - 1 },
[FEAT_PARAM_DOWNSCALE] = { 1, 4 },
};
/* OMAP2 DSS Features */
@ -275,6 +344,7 @@ static const struct omap_dss_features omap2_dss_features = {
.num_ovls = 3,
.supported_displays = omap2_dss_supported_displays,
.supported_color_modes = omap2_dss_supported_color_modes,
.overlay_caps = omap2_dss_overlay_caps,
.clksrc_names = omap2_dss_clk_source_names,
.dss_params = omap2_dss_param_range,
.buffer_size_unit = 1,
@ -287,18 +357,19 @@ static const struct omap_dss_features omap3430_dss_features = {
.num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields),
.has_feature =
FEAT_GLOBAL_ALPHA | FEAT_LCDENABLEPOL |
FEAT_LCDENABLEPOL |
FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE |
FEAT_FUNCGATED | FEAT_ROWREPEATENABLE |
FEAT_LINEBUFFERSPLIT | FEAT_RESIZECONF |
FEAT_DSI_PLL_FREQSEL | FEAT_DSI_REVERSE_TXCLKESC |
FEAT_VENC_REQUIRES_TV_DAC_CLK | FEAT_CPR | FEAT_PRELOAD |
FEAT_FIR_COEF_V,
FEAT_FIR_COEF_V | FEAT_ALPHA_FIXED_ZORDER,
.num_mgrs = 2,
.num_ovls = 3,
.supported_displays = omap3430_dss_supported_displays,
.supported_color_modes = omap3_dss_supported_color_modes,
.overlay_caps = omap3430_dss_overlay_caps,
.clksrc_names = omap3_dss_clk_source_names,
.dss_params = omap3_dss_param_range,
.buffer_size_unit = 1,
@ -310,18 +381,19 @@ static const struct omap_dss_features omap3630_dss_features = {
.num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields),
.has_feature =
FEAT_GLOBAL_ALPHA | FEAT_LCDENABLEPOL |
FEAT_LCDENABLEPOL |
FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE |
FEAT_PRE_MULT_ALPHA | FEAT_FUNCGATED |
FEAT_FUNCGATED |
FEAT_ROWREPEATENABLE | FEAT_LINEBUFFERSPLIT |
FEAT_RESIZECONF | FEAT_DSI_PLL_PWR_BUG |
FEAT_DSI_PLL_FREQSEL | FEAT_CPR | FEAT_PRELOAD |
FEAT_FIR_COEF_V,
FEAT_FIR_COEF_V | FEAT_ALPHA_FIXED_ZORDER,
.num_mgrs = 2,
.num_ovls = 3,
.supported_displays = omap3630_dss_supported_displays,
.supported_color_modes = omap3_dss_supported_color_modes,
.overlay_caps = omap3630_dss_overlay_caps,
.clksrc_names = omap3_dss_clk_source_names,
.dss_params = omap3_dss_param_range,
.buffer_size_unit = 1,
@ -335,17 +407,18 @@ static const struct omap_dss_features omap4430_es1_0_dss_features = {
.num_reg_fields = ARRAY_SIZE(omap4_dss_reg_fields),
.has_feature =
FEAT_GLOBAL_ALPHA | FEAT_PRE_MULT_ALPHA |
FEAT_MGR_LCD2 | FEAT_GLOBAL_ALPHA_VID1 |
FEAT_MGR_LCD2 |
FEAT_CORE_CLK_DIV | FEAT_LCD_CLK_SRC |
FEAT_DSI_DCS_CMD_CONFIG_VC | FEAT_DSI_VC_OCP_WIDTH |
FEAT_DSI_GNQ | FEAT_HANDLE_UV_SEPARATE | FEAT_ATTR2 |
FEAT_CPR | FEAT_PRELOAD | FEAT_FIR_COEF_V,
FEAT_CPR | FEAT_PRELOAD | FEAT_FIR_COEF_V |
FEAT_ALPHA_FREE_ZORDER,
.num_mgrs = 3,
.num_ovls = 3,
.num_ovls = 4,
.supported_displays = omap4_dss_supported_displays,
.supported_color_modes = omap4_dss_supported_color_modes,
.overlay_caps = omap4_dss_overlay_caps,
.clksrc_names = omap4_dss_clk_source_names,
.dss_params = omap4_dss_param_range,
.buffer_size_unit = 16,
@ -358,24 +431,50 @@ static const struct omap_dss_features omap4_dss_features = {
.num_reg_fields = ARRAY_SIZE(omap4_dss_reg_fields),
.has_feature =
FEAT_GLOBAL_ALPHA | FEAT_PRE_MULT_ALPHA |
FEAT_MGR_LCD2 | FEAT_GLOBAL_ALPHA_VID1 |
FEAT_MGR_LCD2 |
FEAT_CORE_CLK_DIV | FEAT_LCD_CLK_SRC |
FEAT_DSI_DCS_CMD_CONFIG_VC | FEAT_DSI_VC_OCP_WIDTH |
FEAT_DSI_GNQ | FEAT_HDMI_CTS_SWMODE |
FEAT_HANDLE_UV_SEPARATE | FEAT_ATTR2 | FEAT_CPR |
FEAT_PRELOAD | FEAT_FIR_COEF_V,
FEAT_PRELOAD | FEAT_FIR_COEF_V | FEAT_ALPHA_FREE_ZORDER,
.num_mgrs = 3,
.num_ovls = 3,
.num_ovls = 4,
.supported_displays = omap4_dss_supported_displays,
.supported_color_modes = omap4_dss_supported_color_modes,
.overlay_caps = omap4_dss_overlay_caps,
.clksrc_names = omap4_dss_clk_source_names,
.dss_params = omap4_dss_param_range,
.buffer_size_unit = 16,
.burst_size_unit = 16,
};
#if defined(CONFIG_OMAP4_DSS_HDMI)
/* HDMI OMAP4 Functions*/
static const struct ti_hdmi_ip_ops omap4_hdmi_functions = {
.video_configure = ti_hdmi_4xxx_basic_configure,
.phy_enable = ti_hdmi_4xxx_phy_enable,
.phy_disable = ti_hdmi_4xxx_phy_disable,
.read_edid = ti_hdmi_4xxx_read_edid,
.detect = ti_hdmi_4xxx_detect,
.pll_enable = ti_hdmi_4xxx_pll_enable,
.pll_disable = ti_hdmi_4xxx_pll_disable,
.video_enable = ti_hdmi_4xxx_wp_video_start,
.dump_wrapper = ti_hdmi_4xxx_wp_dump,
.dump_core = ti_hdmi_4xxx_core_dump,
.dump_pll = ti_hdmi_4xxx_pll_dump,
.dump_phy = ti_hdmi_4xxx_phy_dump,
};
void dss_init_hdmi_ip_ops(struct hdmi_ip_data *ip_data)
{
if (cpu_is_omap44xx())
ip_data->ops = &omap4_hdmi_functions;
}
#endif
/* Functions returning values related to a DSS feature */
int dss_feat_get_num_mgrs(void)
{
@ -407,6 +506,11 @@ enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane)
return omap_current_dss_features->supported_color_modes[plane];
}
enum omap_overlay_caps dss_feat_get_overlay_caps(enum omap_plane plane)
{
return omap_current_dss_features->overlay_caps[plane];
}
bool dss_feat_color_mode_supported(enum omap_plane plane,
enum omap_color_mode color_mode)
{

View File

@ -20,16 +20,17 @@
#ifndef __OMAP2_DSS_FEATURES_H
#define __OMAP2_DSS_FEATURES_H
#if defined(CONFIG_OMAP4_DSS_HDMI)
#include "ti_hdmi.h"
#endif
#define MAX_DSS_MANAGERS 3
#define MAX_DSS_OVERLAYS 3
#define MAX_DSS_OVERLAYS 4
#define MAX_DSS_LCD_MANAGERS 2
#define MAX_NUM_DSI 2
/* DSS has feature id */
enum dss_feat_id {
FEAT_GLOBAL_ALPHA = 1 << 0,
FEAT_GLOBAL_ALPHA_VID1 = 1 << 1,
FEAT_PRE_MULT_ALPHA = 1 << 2,
FEAT_LCDENABLEPOL = 1 << 3,
FEAT_LCDENABLESIGNAL = 1 << 4,
FEAT_PCKFREEENABLE = 1 << 5,
@ -55,6 +56,8 @@ enum dss_feat_id {
FEAT_CPR = 1 << 23,
FEAT_PRELOAD = 1 << 24,
FEAT_FIR_COEF_V = 1 << 25,
FEAT_ALPHA_FIXED_ZORDER = 1 << 26,
FEAT_ALPHA_FREE_ZORDER = 1 << 27,
};
/* DSS register field id */
@ -75,12 +78,14 @@ enum dss_feat_reg_field {
enum dss_range_param {
FEAT_PARAM_DSS_FCK,
FEAT_PARAM_DSS_PCD,
FEAT_PARAM_DSIPLL_REGN,
FEAT_PARAM_DSIPLL_REGM,
FEAT_PARAM_DSIPLL_REGM_DISPC,
FEAT_PARAM_DSIPLL_REGM_DSI,
FEAT_PARAM_DSIPLL_FINT,
FEAT_PARAM_DSIPLL_LPDIV,
FEAT_PARAM_DOWNSCALE,
};
/* DSS Feature Functions */
@ -90,6 +95,7 @@ unsigned long dss_feat_get_param_min(enum dss_range_param param);
unsigned long dss_feat_get_param_max(enum dss_range_param param);
enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel);
enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane);
enum omap_overlay_caps dss_feat_get_overlay_caps(enum omap_plane plane);
bool dss_feat_color_mode_supported(enum omap_plane plane,
enum omap_color_mode color_mode);
const char *dss_feat_get_clk_source_name(enum omap_dss_clk_source id);
@ -100,4 +106,7 @@ u32 dss_feat_get_burst_size_unit(void); /* in bytes */
bool dss_has_feature(enum dss_feat_id id);
void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end);
void dss_features_init(void);
#if defined(CONFIG_OMAP4_DSS_HDMI)
void dss_init_hdmi_ip_ops(struct hdmi_ip_data *ip_data);
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/*
* hdmi_omap4_panel.c
* hdmi_panel.c
*
* HDMI library support functions for TI OMAP4 processors.
*
@ -25,6 +25,7 @@
#include <linux/mutex.h>
#include <linux/module.h>
#include <video/omapdss.h>
#include <linux/slab.h>
#include "dss.h"
@ -40,13 +41,7 @@ static int hdmi_panel_probe(struct omap_dss_device *dssdev)
dssdev->panel.config = OMAP_DSS_LCD_TFT |
OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IHS;
/*
* Initialize the timings to 640 * 480
* This is only for framebuffer update not for TV timing setting
* Setting TV timing will be done only on enable
*/
dssdev->panel.timings.x_res = 640;
dssdev->panel.timings.y_res = 480;
dssdev->panel.timings = (struct omap_video_timings){640, 480, 25175, 96, 16, 48, 2 , 11, 31};
DSSDBG("hdmi_panel_probe x_res= %d y_res = %d\n",
dssdev->panel.timings.x_res,
@ -161,12 +156,7 @@ static void hdmi_set_timings(struct omap_dss_device *dssdev,
mutex_lock(&hdmi.hdmi_lock);
dssdev->panel.timings = *timings;
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
/* turn the hdmi off and on to get new timings to use */
omapdss_hdmi_display_disable(dssdev);
omapdss_hdmi_display_set_timing(dssdev);
}
omapdss_hdmi_display_set_timing(dssdev);
mutex_unlock(&hdmi.hdmi_lock);
}
@ -181,12 +171,54 @@ static int hdmi_check_timings(struct omap_dss_device *dssdev,
mutex_lock(&hdmi.hdmi_lock);
r = omapdss_hdmi_display_check_timing(dssdev, timings);
if (r) {
DSSERR("Timing cannot be applied\n");
goto err;
mutex_unlock(&hdmi.hdmi_lock);
return r;
}
static int hdmi_read_edid(struct omap_dss_device *dssdev, u8 *buf, int len)
{
int r;
mutex_lock(&hdmi.hdmi_lock);
if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
r = omapdss_hdmi_display_enable(dssdev);
if (r)
goto err;
}
r = omapdss_hdmi_read_edid(buf, len);
if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED ||
dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED)
omapdss_hdmi_display_disable(dssdev);
err:
mutex_unlock(&hdmi.hdmi_lock);
return r;
}
static bool hdmi_detect(struct omap_dss_device *dssdev)
{
int r;
mutex_lock(&hdmi.hdmi_lock);
if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
r = omapdss_hdmi_display_enable(dssdev);
if (r)
goto err;
}
r = omapdss_hdmi_detect();
if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED ||
dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED)
omapdss_hdmi_display_disable(dssdev);
err:
mutex_unlock(&hdmi.hdmi_lock);
return r;
}
@ -200,6 +232,8 @@ static struct omap_dss_driver hdmi_driver = {
.get_timings = hdmi_get_timings,
.set_timings = hdmi_set_timings,
.check_timings = hdmi_check_timings,
.read_edid = hdmi_read_edid,
.detect = hdmi_detect,
.driver = {
.name = "hdmi_panel",
.owner = THIS_MODULE,

Some files were not shown because too many files have changed in this diff Show More