Merge git://git.kernel.org/pub/scm/linux/kernel/git/lethal/fbdev-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/lethal/fbdev-2.6: (140 commits) MAINTAINERS: de-orphan fbdev. MAINTAINERS: Add file pattern for fb dt bindings. video: Move sm501fb devicetree binding documentation to a better place. fbcon: fix situation where fbcon gets deinitialised and can't reinit. video, sm501: add OF binding to support SM501 video, sm501: add edid and commandline support video, sm501: add I/O functions for use on powerpc video: Fix EDID macros H_SYNC_WIDTH and H_SYNC_OFFSET fbcon: Bugfix soft cursor detection in Tile Blitting video: add missing framebuffer_release in error path video: metronomefb: add __devexit_p around reference to metronomefb_remove video: hecubafb: add __devexit_p around reference to hecubafb_remove drivers:video:aty:radeon_base Fix typo occationally to occasionally atmel_lcdfb: add fb_blank function atmel_lcdfb: implement inverted contrast pwm video: s3c-fb: return proper error if clk_get fails uvesafb,vesafb: create WC or WB PAT-entries video: ffb: fix ffb_probe error path radeonfb: Let hwmon driver probe the "monid" I2C bus fbdev: sh_mobile_lcdc: checking NULL instead of IS_ERR() ...
This commit is contained in:
commit
4cc4d24efc
4
.mailmap
4
.mailmap
@ -20,6 +20,7 @@ Andreas Herrmann <aherrman@de.ibm.com>
|
||||
Andrew Morton <akpm@osdl.org>
|
||||
Andrew Vasquez <andrew.vasquez@qlogic.com>
|
||||
Andy Adamson <andros@citi.umich.edu>
|
||||
Archit Taneja <archit@ti.com>
|
||||
Arnaud Patard <arnaud.patard@rtp-net.org>
|
||||
Arnd Bergmann <arnd@arndb.de>
|
||||
Axel Dyks <xl@xlsigned.net>
|
||||
@ -70,6 +71,7 @@ Leonid I Ananiev <leonid.i.ananiev@intel.com>
|
||||
Linas Vepstas <linas@austin.ibm.com>
|
||||
Mark Brown <broonie@sirena.org.uk>
|
||||
Matthieu CASTET <castet.matthieu@free.fr>
|
||||
Mayuresh Janorkar <mayur@ti.com>
|
||||
Michael Buesch <mb@bu3sch.de>
|
||||
Michael Buesch <mbuesch@freenet.de>
|
||||
Michel Dänzer <michel@tungstengraphics.com>
|
||||
@ -78,6 +80,7 @@ Morten Welinder <terra@gnome.org>
|
||||
Morten Welinder <welinder@anemone.rentec.com>
|
||||
Morten Welinder <welinder@darter.rentec.com>
|
||||
Morten Welinder <welinder@troll.com>
|
||||
Mythri P K <mythripk@ti.com>
|
||||
Nguyen Anh Quynh <aquynh@gmail.com>
|
||||
Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
|
||||
Patrick Mochel <mochel@digitalimplant.org>
|
||||
@ -98,6 +101,7 @@ S.Çağlar Onur <caglar@pardus.org.tr>
|
||||
Simon Kelley <simon@thekelleys.org.uk>
|
||||
Stéphane Witzmann <stephane.witzmann@ubpmes.univ-bpclermont.fr>
|
||||
Stephen Hemminger <shemminger@osdl.org>
|
||||
Sumit Semwal <sumit.semwal@ti.com>
|
||||
Tejun Heo <htejun@gmail.com>
|
||||
Thomas Graf <tgraf@suug.ch>
|
||||
Tony Luck <tony.luck@intel.com>
|
||||
|
34
Documentation/devicetree/bindings/fb/sm501fb.txt
Normal file
34
Documentation/devicetree/bindings/fb/sm501fb.txt
Normal file
@ -0,0 +1,34 @@
|
||||
* SM SM501
|
||||
|
||||
The SM SM501 is a LCD controller, with proper hardware, it can also
|
||||
drive DVI monitors.
|
||||
|
||||
Required properties:
|
||||
- compatible : should be "smi,sm501".
|
||||
- reg : contain two entries:
|
||||
- First entry: System Configuration register
|
||||
- Second entry: IO space (Display Controller register)
|
||||
- interrupts : SMI interrupt to the cpu should be described here.
|
||||
- interrupt-parent : the phandle for the interrupt controller that
|
||||
services interrupts for this device.
|
||||
|
||||
Optional properties:
|
||||
- mode : select a video mode:
|
||||
<xres>x<yres>[-<bpp>][@<refresh>]
|
||||
- edid : verbatim EDID data block describing attached display.
|
||||
Data from the detailed timing descriptor will be used to
|
||||
program the display controller.
|
||||
- little-endian: availiable on big endian systems, to
|
||||
set different foreign endian.
|
||||
- big-endian: availiable on little endian systems, to
|
||||
set different foreign endian.
|
||||
|
||||
Example for MPC5200:
|
||||
display@1,0 {
|
||||
compatible = "smi,sm501";
|
||||
reg = <1 0x00000000 0x00800000
|
||||
1 0x03e00000 0x00200000>;
|
||||
interrupts = <1 1 3>;
|
||||
mode = "640x480-32@60";
|
||||
edid = [edid-data];
|
||||
};
|
10
Documentation/fb/sm501.txt
Normal file
10
Documentation/fb/sm501.txt
Normal file
@ -0,0 +1,10 @@
|
||||
Configuration:
|
||||
|
||||
You can pass the following kernel command line options to sm501 videoframebuffer:
|
||||
|
||||
sm501fb.bpp= SM501 Display driver:
|
||||
Specifiy bits-per-pixel if not specified by 'mode'
|
||||
|
||||
sm501fb.mode= SM501 Display driver:
|
||||
Specify resolution as
|
||||
"<xres>x<yres>[-<bpp>][@<refresh>]"
|
@ -2631,12 +2631,14 @@ F: drivers/net/wan/dlci.c
|
||||
F: drivers/net/wan/sdla.c
|
||||
|
||||
FRAMEBUFFER LAYER
|
||||
M: Paul Mundt <lethal@linux-sh.org>
|
||||
L: linux-fbdev@vger.kernel.org
|
||||
W: http://linux-fbdev.sourceforge.net/
|
||||
Q: http://patchwork.kernel.org/project/linux-fbdev/list/
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/lethal/fbdev-2.6.git
|
||||
S: Orphan
|
||||
S: Maintained
|
||||
F: Documentation/fb/
|
||||
F: Documentation/devicetree/bindings/fb/
|
||||
F: drivers/video/
|
||||
F: include/video/
|
||||
F: include/linux/fb.h
|
||||
@ -4535,14 +4537,14 @@ S: Maintained
|
||||
F: sound/soc/omap/
|
||||
|
||||
OMAP FRAMEBUFFER SUPPORT
|
||||
M: Tomi Valkeinen <tomi.valkeinen@nokia.com>
|
||||
M: Tomi Valkeinen <tomi.valkeinen@ti.com>
|
||||
L: linux-fbdev@vger.kernel.org
|
||||
L: linux-omap@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/video/omap/
|
||||
|
||||
OMAP DISPLAY SUBSYSTEM and FRAMEBUFFER SUPPORT (DSS2)
|
||||
M: Tomi Valkeinen <tomi.valkeinen@nokia.com>
|
||||
M: Tomi Valkeinen <tomi.valkeinen@ti.com>
|
||||
L: linux-omap@vger.kernel.org
|
||||
L: linux-fbdev@vger.kernel.org
|
||||
S: Maintained
|
||||
|
@ -193,6 +193,17 @@ CONFIG_FIRMWARE_EDID=y
|
||||
CONFIG_FB_MODE_HELPERS=y
|
||||
CONFIG_FB_TILEBLITTING=y
|
||||
CONFIG_FB_OMAP_LCD_VGA=y
|
||||
CONFIG_OMAP2_DSS=m
|
||||
CONFIG_OMAP2_DSS_RFBI=y
|
||||
CONFIG_OMAP2_DSS_SDI=y
|
||||
CONFIG_OMAP2_DSS_DSI=y
|
||||
CONFIG_FB_OMAP2=m
|
||||
CONFIG_PANEL_GENERIC_DPI=m
|
||||
CONFIG_PANEL_SHARP_LS037V7DW01=m
|
||||
CONFIG_PANEL_NEC_NL8048HL11_01B=m
|
||||
CONFIG_PANEL_TAAL=m
|
||||
CONFIG_PANEL_TPO_TD043MTEA1=m
|
||||
CONFIG_PANEL_ACX565AKM=m
|
||||
CONFIG_BACKLIGHT_LCD_SUPPORT=y
|
||||
CONFIG_LCD_CLASS_DEVICE=y
|
||||
CONFIG_LCD_PLATFORM=y
|
||||
|
@ -307,9 +307,6 @@ static struct omap_dss_board_info sdp3430_dss_data = {
|
||||
.default_device = &sdp3430_lcd_device,
|
||||
};
|
||||
|
||||
static struct regulator_consumer_supply sdp3430_vdda_dac_supply =
|
||||
REGULATOR_SUPPLY("vdda_dac", "omapdss");
|
||||
|
||||
static struct omap_board_config_kernel sdp3430_config[] __initdata = {
|
||||
};
|
||||
|
||||
@ -398,12 +395,13 @@ static struct regulator_consumer_supply sdp3430_vaux3_supplies[] = {
|
||||
};
|
||||
|
||||
static struct regulator_consumer_supply sdp3430_vdda_dac_supplies[] = {
|
||||
REGULATOR_SUPPLY("vdda_dac", "omapdss"),
|
||||
REGULATOR_SUPPLY("vdda_dac", "omapdss_venc"),
|
||||
};
|
||||
|
||||
/* VPLL2 for digital video outputs */
|
||||
static struct regulator_consumer_supply sdp3430_vpll2_supplies[] = {
|
||||
REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
|
||||
REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
|
||||
};
|
||||
|
||||
static struct regulator_consumer_supply sdp3430_vmmc1_supplies[] = {
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include <plat/usb.h>
|
||||
#include <plat/mmc.h>
|
||||
#include <plat/omap4-keypad.h>
|
||||
#include <plat/display.h>
|
||||
|
||||
#include "mux.h"
|
||||
#include "hsmmc.h"
|
||||
@ -47,6 +48,8 @@
|
||||
#define ETH_KS8851_QUART 138
|
||||
#define OMAP4_SFH7741_SENSOR_OUTPUT_GPIO 184
|
||||
#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 */
|
||||
|
||||
static const int sdp4430_keymap[] = {
|
||||
KEY(0, 0, KEY_E),
|
||||
@ -621,6 +624,76 @@ static void __init omap_sfh7741prox_init(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void sdp4430_hdmi_mux_init(void)
|
||||
{
|
||||
/* PAD0_HDMI_HPD_PAD1_HDMI_CEC */
|
||||
omap_mux_init_signal("hdmi_hpd",
|
||||
OMAP_PIN_INPUT_PULLUP);
|
||||
omap_mux_init_signal("hdmi_cec",
|
||||
OMAP_PIN_INPUT_PULLUP);
|
||||
/* PAD0_HDMI_DDC_SCL_PAD1_HDMI_DDC_SDA */
|
||||
omap_mux_init_signal("hdmi_ddc_scl",
|
||||
OMAP_PIN_INPUT_PULLUP);
|
||||
omap_mux_init_signal("hdmi_ddc_sda",
|
||||
OMAP_PIN_INPUT_PULLUP);
|
||||
}
|
||||
|
||||
static int sdp4430_panel_enable_hdmi(struct omap_dss_device *dssdev)
|
||||
{
|
||||
int status;
|
||||
|
||||
status = gpio_request_one(HDMI_GPIO_HPD, GPIOF_OUT_INIT_HIGH,
|
||||
"hdmi_gpio_hpd");
|
||||
if (status) {
|
||||
pr_err("Cannot request GPIO %d\n", HDMI_GPIO_HPD);
|
||||
return status;
|
||||
}
|
||||
status = gpio_request_one(HDMI_GPIO_LS_OE, GPIOF_OUT_INIT_HIGH,
|
||||
"hdmi_gpio_ls_oe");
|
||||
if (status) {
|
||||
pr_err("Cannot request GPIO %d\n", HDMI_GPIO_LS_OE);
|
||||
goto error1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error1:
|
||||
gpio_free(HDMI_GPIO_HPD);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void sdp4430_panel_disable_hdmi(struct omap_dss_device *dssdev)
|
||||
{
|
||||
gpio_free(HDMI_GPIO_LS_OE);
|
||||
gpio_free(HDMI_GPIO_HPD);
|
||||
}
|
||||
|
||||
static struct omap_dss_device sdp4430_hdmi_device = {
|
||||
.name = "hdmi",
|
||||
.driver_name = "hdmi_panel",
|
||||
.type = OMAP_DISPLAY_TYPE_HDMI,
|
||||
.platform_enable = sdp4430_panel_enable_hdmi,
|
||||
.platform_disable = sdp4430_panel_disable_hdmi,
|
||||
.channel = OMAP_DSS_CHANNEL_DIGIT,
|
||||
};
|
||||
|
||||
static struct omap_dss_device *sdp4430_dss_devices[] = {
|
||||
&sdp4430_hdmi_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,
|
||||
};
|
||||
|
||||
void omap_4430sdp_display_init(void)
|
||||
{
|
||||
sdp4430_hdmi_mux_init();
|
||||
omap_display_init(&sdp4430_dss_data);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OMAP_MUX
|
||||
static struct omap_board_mux board_mux[] __initdata = {
|
||||
OMAP4_MUX(USBB2_ULPITLL_CLK, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
|
||||
@ -729,6 +802,8 @@ static void __init omap_4430sdp_init(void)
|
||||
status = omap4_keyboard_init(&sdp4430_keypad_data);
|
||||
if (status)
|
||||
pr_err("Keypad initialization failed: %d\n", status);
|
||||
|
||||
omap_4430sdp_display_init();
|
||||
}
|
||||
|
||||
static void __init omap_4430sdp_map_io(void)
|
||||
|
@ -488,7 +488,7 @@ static struct regulator_consumer_supply cm_t35_vsim_supply = {
|
||||
};
|
||||
|
||||
static struct regulator_consumer_supply cm_t35_vdac_supply =
|
||||
REGULATOR_SUPPLY("vdda_dac", "omapdss");
|
||||
REGULATOR_SUPPLY("vdda_dac", "omapdss_venc");
|
||||
|
||||
static struct regulator_consumer_supply cm_t35_vdvi_supply =
|
||||
REGULATOR_SUPPLY("vdvi", "omapdss");
|
||||
|
@ -196,7 +196,7 @@ static struct omap_dss_board_info devkit8000_dss_data = {
|
||||
};
|
||||
|
||||
static struct regulator_consumer_supply devkit8000_vdda_dac_supply =
|
||||
REGULATOR_SUPPLY("vdda_dac", "omapdss");
|
||||
REGULATOR_SUPPLY("vdda_dac", "omapdss_venc");
|
||||
|
||||
static uint32_t board_keymap[] = {
|
||||
KEY(0, 0, KEY_1),
|
||||
@ -277,8 +277,10 @@ static struct twl4030_gpio_platform_data devkit8000_gpio_data = {
|
||||
.setup = devkit8000_twl_gpio_setup,
|
||||
};
|
||||
|
||||
static struct regulator_consumer_supply devkit8000_vpll1_supply =
|
||||
REGULATOR_SUPPLY("vdds_dsi", "omapdss");
|
||||
static struct regulator_consumer_supply devkit8000_vpll1_supplies[] = {
|
||||
REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
|
||||
REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
|
||||
};
|
||||
|
||||
/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
|
||||
static struct regulator_init_data devkit8000_vmmc1 = {
|
||||
@ -319,8 +321,8 @@ static struct regulator_init_data devkit8000_vpll1 = {
|
||||
.valid_ops_mask = REGULATOR_CHANGE_MODE
|
||||
| REGULATOR_CHANGE_STATUS,
|
||||
},
|
||||
.num_consumer_supplies = 1,
|
||||
.consumer_supplies = &devkit8000_vpll1_supply,
|
||||
.num_consumer_supplies = ARRAY_SIZE(devkit8000_vpll1_supplies),
|
||||
.consumer_supplies = devkit8000_vpll1_supplies,
|
||||
};
|
||||
|
||||
/* VAUX4 for ads7846 and nubs */
|
||||
|
@ -485,8 +485,10 @@ static struct omap_dss_board_info igep2_dss_data = {
|
||||
.default_device = &igep2_dvi_device,
|
||||
};
|
||||
|
||||
static struct regulator_consumer_supply igep2_vpll2_supply =
|
||||
REGULATOR_SUPPLY("vdds_dsi", "omapdss");
|
||||
static struct regulator_consumer_supply igep2_vpll2_supplies[] = {
|
||||
REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
|
||||
REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
|
||||
};
|
||||
|
||||
static struct regulator_init_data igep2_vpll2 = {
|
||||
.constraints = {
|
||||
@ -499,8 +501,8 @@ static struct regulator_init_data igep2_vpll2 = {
|
||||
.valid_ops_mask = REGULATOR_CHANGE_MODE
|
||||
| REGULATOR_CHANGE_STATUS,
|
||||
},
|
||||
.num_consumer_supplies = 1,
|
||||
.consumer_supplies = &igep2_vpll2_supply,
|
||||
.num_consumer_supplies = ARRAY_SIZE(igep2_vpll2_supplies),
|
||||
.consumer_supplies = igep2_vpll2_supplies,
|
||||
};
|
||||
|
||||
static void __init igep2_display_init(void)
|
||||
|
@ -232,10 +232,12 @@ static struct omap_dss_board_info beagle_dss_data = {
|
||||
};
|
||||
|
||||
static struct regulator_consumer_supply beagle_vdac_supply =
|
||||
REGULATOR_SUPPLY("vdda_dac", "omapdss");
|
||||
REGULATOR_SUPPLY("vdda_dac", "omapdss_venc");
|
||||
|
||||
static struct regulator_consumer_supply beagle_vdvi_supply =
|
||||
REGULATOR_SUPPLY("vdds_dsi", "omapdss");
|
||||
static struct regulator_consumer_supply beagle_vdvi_supplies[] = {
|
||||
REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
|
||||
REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
|
||||
};
|
||||
|
||||
static void __init beagle_display_init(void)
|
||||
{
|
||||
@ -422,8 +424,8 @@ static struct regulator_init_data beagle_vpll2 = {
|
||||
.valid_ops_mask = REGULATOR_CHANGE_MODE
|
||||
| REGULATOR_CHANGE_STATUS,
|
||||
},
|
||||
.num_consumer_supplies = 1,
|
||||
.consumer_supplies = &beagle_vdvi_supply,
|
||||
.num_consumer_supplies = ARRAY_SIZE(beagle_vdvi_supplies),
|
||||
.consumer_supplies = beagle_vdvi_supplies,
|
||||
};
|
||||
|
||||
static struct twl4030_usb_data beagle_usb_data = {
|
||||
|
@ -542,7 +542,7 @@ static struct twl4030_codec_data omap3evm_codec_data = {
|
||||
};
|
||||
|
||||
static struct regulator_consumer_supply omap3_evm_vdda_dac_supply =
|
||||
REGULATOR_SUPPLY("vdda_dac", "omapdss");
|
||||
REGULATOR_SUPPLY("vdda_dac", "omapdss_venc");
|
||||
|
||||
/* VDAC for DSS driving S-Video */
|
||||
static struct regulator_init_data omap3_evm_vdac = {
|
||||
@ -560,8 +560,10 @@ static struct regulator_init_data omap3_evm_vdac = {
|
||||
};
|
||||
|
||||
/* VPLL2 for digital video outputs */
|
||||
static struct regulator_consumer_supply omap3_evm_vpll2_supply =
|
||||
REGULATOR_SUPPLY("vdds_dsi", "omapdss");
|
||||
static struct regulator_consumer_supply omap3_evm_vpll2_supplies[] = {
|
||||
REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
|
||||
REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
|
||||
};
|
||||
|
||||
static struct regulator_init_data omap3_evm_vpll2 = {
|
||||
.constraints = {
|
||||
@ -573,8 +575,8 @@ static struct regulator_init_data omap3_evm_vpll2 = {
|
||||
.valid_ops_mask = REGULATOR_CHANGE_MODE
|
||||
| REGULATOR_CHANGE_STATUS,
|
||||
},
|
||||
.num_consumer_supplies = 1,
|
||||
.consumer_supplies = &omap3_evm_vpll2_supply,
|
||||
.num_consumer_supplies = ARRAY_SIZE(omap3_evm_vpll2_supplies),
|
||||
.consumer_supplies = omap3_evm_vpll2_supplies,
|
||||
};
|
||||
|
||||
/* ads7846 on SPI */
|
||||
|
@ -342,11 +342,12 @@ static struct regulator_consumer_supply pandora_vmmc3_supply =
|
||||
REGULATOR_SUPPLY("vmmc", "omap_hsmmc.2");
|
||||
|
||||
static struct regulator_consumer_supply pandora_vdda_dac_supply =
|
||||
REGULATOR_SUPPLY("vdda_dac", "omapdss");
|
||||
REGULATOR_SUPPLY("vdda_dac", "omapdss_venc");
|
||||
|
||||
static struct regulator_consumer_supply pandora_vdds_supplies[] = {
|
||||
REGULATOR_SUPPLY("vdds_sdi", "omapdss"),
|
||||
REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
|
||||
REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
|
||||
};
|
||||
|
||||
static struct regulator_consumer_supply pandora_vcc_lcd_supply =
|
||||
|
@ -439,7 +439,7 @@ static struct twl4030_codec_data omap3stalker_codec_data = {
|
||||
};
|
||||
|
||||
static struct regulator_consumer_supply omap3_stalker_vdda_dac_supply =
|
||||
REGULATOR_SUPPLY("vdda_dac", "omapdss");
|
||||
REGULATOR_SUPPLY("vdda_dac", "omapdss_venc");
|
||||
|
||||
/* VDAC for DSS driving S-Video */
|
||||
static struct regulator_init_data omap3_stalker_vdac = {
|
||||
@ -457,8 +457,10 @@ static struct regulator_init_data omap3_stalker_vdac = {
|
||||
};
|
||||
|
||||
/* VPLL2 for digital video outputs */
|
||||
static struct regulator_consumer_supply omap3_stalker_vpll2_supply =
|
||||
REGULATOR_SUPPLY("vdds_dsi", "omapdss");
|
||||
static struct regulator_consumer_supply omap3_stalker_vpll2_supplies[] = {
|
||||
REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
|
||||
REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
|
||||
};
|
||||
|
||||
static struct regulator_init_data omap3_stalker_vpll2 = {
|
||||
.constraints = {
|
||||
@ -471,8 +473,8 @@ static struct regulator_init_data omap3_stalker_vpll2 = {
|
||||
.valid_ops_mask = REGULATOR_CHANGE_MODE
|
||||
| REGULATOR_CHANGE_STATUS,
|
||||
},
|
||||
.num_consumer_supplies = 1,
|
||||
.consumer_supplies = &omap3_stalker_vpll2_supply,
|
||||
.num_consumer_supplies = ARRAY_SIZE(omap3_stalker_vpll2_supplies),
|
||||
.consumer_supplies = omap3_stalker_vpll2_supplies,
|
||||
};
|
||||
|
||||
static struct twl4030_platform_data omap3stalker_twldata = {
|
||||
|
@ -34,11 +34,13 @@
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/map.h>
|
||||
#include <plat/display.h>
|
||||
|
||||
#include <plat/board.h>
|
||||
#include <plat/common.h>
|
||||
#include <plat/usb.h>
|
||||
#include <plat/mmc.h>
|
||||
#include <plat/panel-generic-dpi.h>
|
||||
#include "timer-gp.h"
|
||||
|
||||
#include "hsmmc.h"
|
||||
@ -49,6 +51,8 @@
|
||||
#define GPIO_HUB_NRESET 62
|
||||
#define GPIO_WIFI_PMENA 43
|
||||
#define GPIO_WIFI_IRQ 53
|
||||
#define HDMI_GPIO_HPD 60 /* Hot plug pin for HDMI */
|
||||
#define HDMI_GPIO_LS_OE 41 /* Level shifter for HDMI */
|
||||
|
||||
/* wl127x BT, FM, GPS connectivity chip */
|
||||
static int wl1271_gpios[] = {46, -1, -1};
|
||||
@ -433,6 +437,17 @@ static struct i2c_board_info __initdata omap4_panda_i2c_boardinfo[] = {
|
||||
.platform_data = &omap4_panda_twldata,
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* Display monitor features are burnt in their EEPROM as EDID data. The EEPROM
|
||||
* is connected as I2C slave device, and can be accessed at address 0x50
|
||||
*/
|
||||
static struct i2c_board_info __initdata panda_i2c_eeprom[] = {
|
||||
{
|
||||
I2C_BOARD_INFO("eeprom", 0x50),
|
||||
},
|
||||
};
|
||||
|
||||
static int __init omap4_panda_i2c_init(void)
|
||||
{
|
||||
/*
|
||||
@ -442,7 +457,12 @@ static int __init omap4_panda_i2c_init(void)
|
||||
omap_register_i2c_bus(1, 400, omap4_panda_i2c_boardinfo,
|
||||
ARRAY_SIZE(omap4_panda_i2c_boardinfo));
|
||||
omap_register_i2c_bus(2, 400, NULL, 0);
|
||||
omap_register_i2c_bus(3, 400, NULL, 0);
|
||||
/*
|
||||
* Bus 3 is attached to the DVI port where devices like the pico DLP
|
||||
* projector don't work reliably with 400kHz
|
||||
*/
|
||||
omap_register_i2c_bus(3, 100, panda_i2c_eeprom,
|
||||
ARRAY_SIZE(panda_i2c_eeprom));
|
||||
omap_register_i2c_bus(4, 400, NULL, 0);
|
||||
return 0;
|
||||
}
|
||||
@ -462,6 +482,64 @@ static struct omap_board_mux board_mux[] __initdata = {
|
||||
OMAP4_MUX(SDMMC5_DAT1, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
|
||||
OMAP4_MUX(SDMMC5_DAT2, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
|
||||
OMAP4_MUX(SDMMC5_DAT3, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
|
||||
/* gpio 0 - TFP410 PD */
|
||||
OMAP4_MUX(KPD_COL1, OMAP_PIN_OUTPUT | OMAP_MUX_MODE3),
|
||||
/* dispc2_data23 */
|
||||
OMAP4_MUX(USBB2_ULPITLL_STP, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
|
||||
/* dispc2_data22 */
|
||||
OMAP4_MUX(USBB2_ULPITLL_DIR, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
|
||||
/* dispc2_data21 */
|
||||
OMAP4_MUX(USBB2_ULPITLL_NXT, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
|
||||
/* dispc2_data20 */
|
||||
OMAP4_MUX(USBB2_ULPITLL_DAT0, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
|
||||
/* dispc2_data19 */
|
||||
OMAP4_MUX(USBB2_ULPITLL_DAT1, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
|
||||
/* dispc2_data18 */
|
||||
OMAP4_MUX(USBB2_ULPITLL_DAT2, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
|
||||
/* dispc2_data15 */
|
||||
OMAP4_MUX(USBB2_ULPITLL_DAT3, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
|
||||
/* dispc2_data14 */
|
||||
OMAP4_MUX(USBB2_ULPITLL_DAT4, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
|
||||
/* dispc2_data13 */
|
||||
OMAP4_MUX(USBB2_ULPITLL_DAT5, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
|
||||
/* dispc2_data12 */
|
||||
OMAP4_MUX(USBB2_ULPITLL_DAT6, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
|
||||
/* dispc2_data11 */
|
||||
OMAP4_MUX(USBB2_ULPITLL_DAT7, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
|
||||
/* dispc2_data10 */
|
||||
OMAP4_MUX(DPM_EMU3, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
|
||||
/* dispc2_data9 */
|
||||
OMAP4_MUX(DPM_EMU4, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
|
||||
/* dispc2_data16 */
|
||||
OMAP4_MUX(DPM_EMU5, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
|
||||
/* dispc2_data17 */
|
||||
OMAP4_MUX(DPM_EMU6, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
|
||||
/* dispc2_hsync */
|
||||
OMAP4_MUX(DPM_EMU7, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
|
||||
/* dispc2_pclk */
|
||||
OMAP4_MUX(DPM_EMU8, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
|
||||
/* dispc2_vsync */
|
||||
OMAP4_MUX(DPM_EMU9, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
|
||||
/* dispc2_de */
|
||||
OMAP4_MUX(DPM_EMU10, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
|
||||
/* dispc2_data8 */
|
||||
OMAP4_MUX(DPM_EMU11, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
|
||||
/* dispc2_data7 */
|
||||
OMAP4_MUX(DPM_EMU12, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
|
||||
/* dispc2_data6 */
|
||||
OMAP4_MUX(DPM_EMU13, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
|
||||
/* dispc2_data5 */
|
||||
OMAP4_MUX(DPM_EMU14, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
|
||||
/* dispc2_data4 */
|
||||
OMAP4_MUX(DPM_EMU15, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
|
||||
/* dispc2_data3 */
|
||||
OMAP4_MUX(DPM_EMU16, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
|
||||
/* dispc2_data2 */
|
||||
OMAP4_MUX(DPM_EMU17, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
|
||||
/* dispc2_data1 */
|
||||
OMAP4_MUX(DPM_EMU18, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
|
||||
/* dispc2_data0 */
|
||||
OMAP4_MUX(DPM_EMU19, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
|
||||
{ .reg_offset = OMAP_MUX_TERMINATOR },
|
||||
};
|
||||
|
||||
@ -535,6 +613,128 @@ static inline void board_serial_init(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Display DVI */
|
||||
#define PANDA_DVI_TFP410_POWER_DOWN_GPIO 0
|
||||
|
||||
static int omap4_panda_enable_dvi(struct omap_dss_device *dssdev)
|
||||
{
|
||||
gpio_set_value(dssdev->reset_gpio, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void omap4_panda_disable_dvi(struct omap_dss_device *dssdev)
|
||||
{
|
||||
gpio_set_value(dssdev->reset_gpio, 0);
|
||||
}
|
||||
|
||||
/* Using generic display panel */
|
||||
static struct panel_generic_dpi_data omap4_dvi_panel = {
|
||||
.name = "generic",
|
||||
.platform_enable = omap4_panda_enable_dvi,
|
||||
.platform_disable = omap4_panda_disable_dvi,
|
||||
};
|
||||
|
||||
struct omap_dss_device omap4_panda_dvi_device = {
|
||||
.type = OMAP_DISPLAY_TYPE_DPI,
|
||||
.name = "dvi",
|
||||
.driver_name = "generic_dpi_panel",
|
||||
.data = &omap4_dvi_panel,
|
||||
.phy.dpi.data_lines = 24,
|
||||
.reset_gpio = PANDA_DVI_TFP410_POWER_DOWN_GPIO,
|
||||
.channel = OMAP_DSS_CHANNEL_LCD2,
|
||||
};
|
||||
|
||||
int __init omap4_panda_dvi_init(void)
|
||||
{
|
||||
int r;
|
||||
|
||||
/* Requesting TFP410 DVI GPIO and disabling it, at bootup */
|
||||
r = gpio_request_one(omap4_panda_dvi_device.reset_gpio,
|
||||
GPIOF_OUT_INIT_LOW, "DVI PD");
|
||||
if (r)
|
||||
pr_err("Failed to get DVI powerdown GPIO\n");
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
static void omap4_panda_hdmi_mux_init(void)
|
||||
{
|
||||
/* PAD0_HDMI_HPD_PAD1_HDMI_CEC */
|
||||
omap_mux_init_signal("hdmi_hpd",
|
||||
OMAP_PIN_INPUT_PULLUP);
|
||||
omap_mux_init_signal("hdmi_cec",
|
||||
OMAP_PIN_INPUT_PULLUP);
|
||||
/* PAD0_HDMI_DDC_SCL_PAD1_HDMI_DDC_SDA */
|
||||
omap_mux_init_signal("hdmi_ddc_scl",
|
||||
OMAP_PIN_INPUT_PULLUP);
|
||||
omap_mux_init_signal("hdmi_ddc_sda",
|
||||
OMAP_PIN_INPUT_PULLUP);
|
||||
}
|
||||
|
||||
static int omap4_panda_panel_enable_hdmi(struct omap_dss_device *dssdev)
|
||||
{
|
||||
int status;
|
||||
|
||||
status = gpio_request_one(HDMI_GPIO_HPD, GPIOF_OUT_INIT_HIGH,
|
||||
"hdmi_gpio_hpd");
|
||||
if (status) {
|
||||
pr_err("Cannot request GPIO %d\n", HDMI_GPIO_HPD);
|
||||
return status;
|
||||
}
|
||||
status = gpio_request_one(HDMI_GPIO_LS_OE, GPIOF_OUT_INIT_HIGH,
|
||||
"hdmi_gpio_ls_oe");
|
||||
if (status) {
|
||||
pr_err("Cannot request GPIO %d\n", HDMI_GPIO_LS_OE);
|
||||
goto error1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error1:
|
||||
gpio_free(HDMI_GPIO_HPD);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void omap4_panda_panel_disable_hdmi(struct omap_dss_device *dssdev)
|
||||
{
|
||||
gpio_free(HDMI_GPIO_LS_OE);
|
||||
gpio_free(HDMI_GPIO_HPD);
|
||||
}
|
||||
|
||||
static struct omap_dss_device omap4_panda_hdmi_device = {
|
||||
.name = "hdmi",
|
||||
.driver_name = "hdmi_panel",
|
||||
.type = OMAP_DISPLAY_TYPE_HDMI,
|
||||
.platform_enable = omap4_panda_panel_enable_hdmi,
|
||||
.platform_disable = omap4_panda_panel_disable_hdmi,
|
||||
.channel = OMAP_DSS_CHANNEL_DIGIT,
|
||||
};
|
||||
|
||||
static struct omap_dss_device *omap4_panda_dss_devices[] = {
|
||||
&omap4_panda_dvi_device,
|
||||
&omap4_panda_hdmi_device,
|
||||
};
|
||||
|
||||
static struct omap_dss_board_info omap4_panda_dss_data = {
|
||||
.num_devices = ARRAY_SIZE(omap4_panda_dss_devices),
|
||||
.devices = omap4_panda_dss_devices,
|
||||
.default_device = &omap4_panda_dvi_device,
|
||||
};
|
||||
|
||||
void omap4_panda_display_init(void)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = omap4_panda_dvi_init();
|
||||
if (r)
|
||||
pr_err("error initializing panda DVI\n");
|
||||
|
||||
omap4_panda_hdmi_mux_init();
|
||||
omap_display_init(&omap4_panda_dss_data);
|
||||
}
|
||||
|
||||
static void __init omap4_panda_init(void)
|
||||
{
|
||||
int package = OMAP_PACKAGE_CBS;
|
||||
@ -553,6 +753,7 @@ static void __init omap4_panda_init(void)
|
||||
omap4_twl6030_hsmmc_init(mmc);
|
||||
omap4_ehci_init();
|
||||
usb_musb_init(&musb_board_data);
|
||||
omap4_panda_display_init();
|
||||
}
|
||||
|
||||
static void __init omap4_panda_map_io(void)
|
||||
|
@ -28,6 +28,8 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/i2c/twl.h>
|
||||
#include <linux/regulator/machine.h>
|
||||
#include <linux/regulator/fixed.h>
|
||||
#include <linux/spi/spi.h>
|
||||
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/nand.h>
|
||||
@ -41,10 +43,14 @@
|
||||
|
||||
#include <plat/board.h>
|
||||
#include <plat/common.h>
|
||||
#include <plat/display.h>
|
||||
#include <plat/panel-generic-dpi.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <plat/gpmc.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <plat/nand.h>
|
||||
#include <plat/mcspi.h>
|
||||
#include <plat/mux.h>
|
||||
#include <plat/usb.h>
|
||||
|
||||
#include "mux.h"
|
||||
@ -68,8 +74,6 @@
|
||||
#if defined(CONFIG_TOUCHSCREEN_ADS7846) || \
|
||||
defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
|
||||
|
||||
#include <plat/mcspi.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/spi/ads7846.h>
|
||||
|
||||
static struct omap2_mcspi_device_config ads7846_mcspi_config = {
|
||||
@ -94,16 +98,32 @@ static struct ads7846_platform_data ads7846_config = {
|
||||
.keep_vref_on = 1,
|
||||
};
|
||||
|
||||
static struct spi_board_info overo_spi_board_info[] __initdata = {
|
||||
{
|
||||
.modalias = "ads7846",
|
||||
.bus_num = 1,
|
||||
.chip_select = 0,
|
||||
.max_speed_hz = 1500000,
|
||||
.controller_data = &ads7846_mcspi_config,
|
||||
.irq = OMAP_GPIO_IRQ(OVERO_GPIO_PENDOWN),
|
||||
.platform_data = &ads7846_config,
|
||||
}
|
||||
/* fixed regulator for ads7846 */
|
||||
static struct regulator_consumer_supply ads7846_supply =
|
||||
REGULATOR_SUPPLY("vcc", "spi1.0");
|
||||
|
||||
static struct regulator_init_data vads7846_regulator = {
|
||||
.constraints = {
|
||||
.valid_ops_mask = REGULATOR_CHANGE_STATUS,
|
||||
},
|
||||
.num_consumer_supplies = 1,
|
||||
.consumer_supplies = &ads7846_supply,
|
||||
};
|
||||
|
||||
static struct fixed_voltage_config vads7846 = {
|
||||
.supply_name = "vads7846",
|
||||
.microvolts = 3300000, /* 3.3V */
|
||||
.gpio = -EINVAL,
|
||||
.startup_delay = 0,
|
||||
.init_data = &vads7846_regulator,
|
||||
};
|
||||
|
||||
static struct platform_device vads7846_device = {
|
||||
.name = "reg-fixed-voltage",
|
||||
.id = 1,
|
||||
.dev = {
|
||||
.platform_data = &vads7846,
|
||||
},
|
||||
};
|
||||
|
||||
static void __init overo_ads7846_init(void)
|
||||
@ -116,8 +136,7 @@ static void __init overo_ads7846_init(void)
|
||||
return;
|
||||
}
|
||||
|
||||
spi_register_board_info(overo_spi_board_info,
|
||||
ARRAY_SIZE(overo_spi_board_info));
|
||||
platform_device_register(&vads7846_device);
|
||||
}
|
||||
|
||||
#else
|
||||
@ -233,6 +252,137 @@ static inline void __init overo_init_smsc911x(void)
|
||||
static inline void __init overo_init_smsc911x(void) { return; }
|
||||
#endif
|
||||
|
||||
/* DSS */
|
||||
static int lcd_enabled;
|
||||
static int dvi_enabled;
|
||||
|
||||
#define OVERO_GPIO_LCD_EN 144
|
||||
#define OVERO_GPIO_LCD_BL 145
|
||||
|
||||
static void __init overo_display_init(void)
|
||||
{
|
||||
if ((gpio_request(OVERO_GPIO_LCD_EN, "OVERO_GPIO_LCD_EN") == 0) &&
|
||||
(gpio_direction_output(OVERO_GPIO_LCD_EN, 1) == 0))
|
||||
gpio_export(OVERO_GPIO_LCD_EN, 0);
|
||||
else
|
||||
printk(KERN_ERR "could not obtain gpio for "
|
||||
"OVERO_GPIO_LCD_EN\n");
|
||||
|
||||
if ((gpio_request(OVERO_GPIO_LCD_BL, "OVERO_GPIO_LCD_BL") == 0) &&
|
||||
(gpio_direction_output(OVERO_GPIO_LCD_BL, 1) == 0))
|
||||
gpio_export(OVERO_GPIO_LCD_BL, 0);
|
||||
else
|
||||
printk(KERN_ERR "could not obtain gpio for "
|
||||
"OVERO_GPIO_LCD_BL\n");
|
||||
}
|
||||
|
||||
static int overo_panel_enable_dvi(struct omap_dss_device *dssdev)
|
||||
{
|
||||
if (lcd_enabled) {
|
||||
printk(KERN_ERR "cannot enable DVI, LCD is enabled\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
dvi_enabled = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void overo_panel_disable_dvi(struct omap_dss_device *dssdev)
|
||||
{
|
||||
dvi_enabled = 0;
|
||||
}
|
||||
|
||||
static struct panel_generic_dpi_data dvi_panel = {
|
||||
.name = "generic",
|
||||
.platform_enable = overo_panel_enable_dvi,
|
||||
.platform_disable = overo_panel_disable_dvi,
|
||||
};
|
||||
|
||||
static struct omap_dss_device overo_dvi_device = {
|
||||
.name = "dvi",
|
||||
.type = OMAP_DISPLAY_TYPE_DPI,
|
||||
.driver_name = "generic_dpi_panel",
|
||||
.data = &dvi_panel,
|
||||
.phy.dpi.data_lines = 24,
|
||||
};
|
||||
|
||||
static struct omap_dss_device overo_tv_device = {
|
||||
.name = "tv",
|
||||
.driver_name = "venc",
|
||||
.type = OMAP_DISPLAY_TYPE_VENC,
|
||||
.phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO,
|
||||
};
|
||||
|
||||
static int overo_panel_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(OVERO_GPIO_LCD_EN, 1);
|
||||
gpio_set_value(OVERO_GPIO_LCD_BL, 1);
|
||||
lcd_enabled = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void overo_panel_disable_lcd(struct omap_dss_device *dssdev)
|
||||
{
|
||||
gpio_set_value(OVERO_GPIO_LCD_EN, 0);
|
||||
gpio_set_value(OVERO_GPIO_LCD_BL, 0);
|
||||
lcd_enabled = 0;
|
||||
}
|
||||
|
||||
static struct panel_generic_dpi_data lcd43_panel = {
|
||||
.name = "samsung_lte430wq_f0c",
|
||||
.platform_enable = overo_panel_enable_lcd,
|
||||
.platform_disable = overo_panel_disable_lcd,
|
||||
};
|
||||
|
||||
static struct omap_dss_device overo_lcd43_device = {
|
||||
.name = "lcd43",
|
||||
.type = OMAP_DISPLAY_TYPE_DPI,
|
||||
.driver_name = "generic_dpi_panel",
|
||||
.data = &lcd43_panel,
|
||||
.phy.dpi.data_lines = 24,
|
||||
};
|
||||
|
||||
#if defined(CONFIG_PANEL_LGPHILIPS_LB035Q02) || \
|
||||
defined(CONFIG_PANEL_LGPHILIPS_LB035Q02_MODULE)
|
||||
static struct omap_dss_device overo_lcd35_device = {
|
||||
.type = OMAP_DISPLAY_TYPE_DPI,
|
||||
.name = "lcd35",
|
||||
.driver_name = "lgphilips_lb035q02_panel",
|
||||
.phy.dpi.data_lines = 24,
|
||||
.platform_enable = overo_panel_enable_lcd,
|
||||
.platform_disable = overo_panel_disable_lcd,
|
||||
};
|
||||
#endif
|
||||
|
||||
static struct omap_dss_device *overo_dss_devices[] = {
|
||||
&overo_dvi_device,
|
||||
&overo_tv_device,
|
||||
#if defined(CONFIG_PANEL_LGPHILIPS_LB035Q02) || \
|
||||
defined(CONFIG_PANEL_LGPHILIPS_LB035Q02_MODULE)
|
||||
&overo_lcd35_device,
|
||||
#endif
|
||||
&overo_lcd43_device,
|
||||
};
|
||||
|
||||
static struct omap_dss_board_info overo_dss_data = {
|
||||
.num_devices = ARRAY_SIZE(overo_dss_devices),
|
||||
.devices = overo_dss_devices,
|
||||
.default_device = &overo_dvi_device,
|
||||
};
|
||||
|
||||
static struct regulator_consumer_supply overo_vdda_dac_supply =
|
||||
REGULATOR_SUPPLY("vdda_dac", "omapdss_venc");
|
||||
|
||||
static struct regulator_consumer_supply overo_vdds_dsi_supply[] = {
|
||||
REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
|
||||
REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
|
||||
};
|
||||
|
||||
static struct mtd_partition overo_nand_partitions[] = {
|
||||
{
|
||||
.name = "xloader",
|
||||
@ -323,6 +473,93 @@ static struct regulator_consumer_supply overo_vmmc1_supply = {
|
||||
.supply = "vmmc",
|
||||
};
|
||||
|
||||
#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
|
||||
#include <linux/leds.h>
|
||||
|
||||
static struct gpio_led gpio_leds[] = {
|
||||
{
|
||||
.name = "overo:red:gpio21",
|
||||
.default_trigger = "heartbeat",
|
||||
.gpio = 21,
|
||||
.active_low = true,
|
||||
},
|
||||
{
|
||||
.name = "overo:blue:gpio22",
|
||||
.default_trigger = "none",
|
||||
.gpio = 22,
|
||||
.active_low = true,
|
||||
},
|
||||
{
|
||||
.name = "overo:blue:COM",
|
||||
.default_trigger = "mmc0",
|
||||
.gpio = -EINVAL, /* gets replaced */
|
||||
.active_low = true,
|
||||
},
|
||||
};
|
||||
|
||||
static struct gpio_led_platform_data gpio_leds_pdata = {
|
||||
.leds = gpio_leds,
|
||||
.num_leds = ARRAY_SIZE(gpio_leds),
|
||||
};
|
||||
|
||||
static struct platform_device gpio_leds_device = {
|
||||
.name = "leds-gpio",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &gpio_leds_pdata,
|
||||
},
|
||||
};
|
||||
|
||||
static void __init overo_init_led(void)
|
||||
{
|
||||
platform_device_register(&gpio_leds_device);
|
||||
}
|
||||
|
||||
#else
|
||||
static inline void __init overo_init_led(void) { return; }
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
|
||||
#include <linux/input.h>
|
||||
#include <linux/gpio_keys.h>
|
||||
|
||||
static struct gpio_keys_button gpio_buttons[] = {
|
||||
{
|
||||
.code = BTN_0,
|
||||
.gpio = 23,
|
||||
.desc = "button0",
|
||||
.wakeup = 1,
|
||||
},
|
||||
{
|
||||
.code = BTN_1,
|
||||
.gpio = 14,
|
||||
.desc = "button1",
|
||||
.wakeup = 1,
|
||||
},
|
||||
};
|
||||
|
||||
static struct gpio_keys_platform_data gpio_keys_pdata = {
|
||||
.buttons = gpio_buttons,
|
||||
.nbuttons = ARRAY_SIZE(gpio_buttons),
|
||||
};
|
||||
|
||||
static struct platform_device gpio_keys_device = {
|
||||
.name = "gpio-keys",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &gpio_keys_pdata,
|
||||
},
|
||||
};
|
||||
|
||||
static void __init overo_init_keys(void)
|
||||
{
|
||||
platform_device_register(&gpio_keys_device);
|
||||
}
|
||||
|
||||
#else
|
||||
static inline void __init overo_init_keys(void) { return; }
|
||||
#endif
|
||||
|
||||
static int overo_twl_gpio_setup(struct device *dev,
|
||||
unsigned gpio, unsigned ngpio)
|
||||
{
|
||||
@ -330,6 +567,11 @@ static int overo_twl_gpio_setup(struct device *dev,
|
||||
|
||||
overo_vmmc1_supply.dev = mmc[0].dev;
|
||||
|
||||
#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
|
||||
/* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */
|
||||
gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -337,6 +579,7 @@ static struct twl4030_gpio_platform_data overo_gpio_data = {
|
||||
.gpio_base = OMAP_MAX_GPIO_LINES,
|
||||
.irq_base = TWL4030_GPIO_IRQ_BASE,
|
||||
.irq_end = TWL4030_GPIO_IRQ_END,
|
||||
.use_leds = true,
|
||||
.setup = overo_twl_gpio_setup,
|
||||
};
|
||||
|
||||
@ -358,6 +601,35 @@ static struct regulator_init_data overo_vmmc1 = {
|
||||
.consumer_supplies = &overo_vmmc1_supply,
|
||||
};
|
||||
|
||||
/* VDAC for DSS driving S-Video (8 mA unloaded, max 65 mA) */
|
||||
static struct regulator_init_data overo_vdac = {
|
||||
.constraints = {
|
||||
.min_uV = 1800000,
|
||||
.max_uV = 1800000,
|
||||
.valid_modes_mask = REGULATOR_MODE_NORMAL
|
||||
| REGULATOR_MODE_STANDBY,
|
||||
.valid_ops_mask = REGULATOR_CHANGE_MODE
|
||||
| REGULATOR_CHANGE_STATUS,
|
||||
},
|
||||
.num_consumer_supplies = 1,
|
||||
.consumer_supplies = &overo_vdda_dac_supply,
|
||||
};
|
||||
|
||||
/* VPLL2 for digital video outputs */
|
||||
static struct regulator_init_data overo_vpll2 = {
|
||||
.constraints = {
|
||||
.name = "VDVI",
|
||||
.min_uV = 1800000,
|
||||
.max_uV = 1800000,
|
||||
.valid_modes_mask = REGULATOR_MODE_NORMAL
|
||||
| REGULATOR_MODE_STANDBY,
|
||||
.valid_ops_mask = REGULATOR_CHANGE_MODE
|
||||
| REGULATOR_CHANGE_STATUS,
|
||||
},
|
||||
.num_consumer_supplies = ARRAY_SIZE(overo_vdds_dsi_supply),
|
||||
.consumer_supplies = overo_vdds_dsi_supply,
|
||||
};
|
||||
|
||||
static struct twl4030_codec_audio_data overo_audio_data;
|
||||
|
||||
static struct twl4030_codec_data overo_codec_data = {
|
||||
@ -365,8 +637,6 @@ static struct twl4030_codec_data overo_codec_data = {
|
||||
.audio = &overo_audio_data,
|
||||
};
|
||||
|
||||
/* mmc2 (WLAN) and Bluetooth don't use twl4030 regulators */
|
||||
|
||||
static struct twl4030_platform_data overo_twldata = {
|
||||
.irq_base = TWL4030_IRQ_BASE,
|
||||
.irq_end = TWL4030_IRQ_END,
|
||||
@ -374,6 +644,8 @@ static struct twl4030_platform_data overo_twldata = {
|
||||
.usb = &overo_usb_data,
|
||||
.codec = &overo_codec_data,
|
||||
.vmmc1 = &overo_vmmc1,
|
||||
.vdac = &overo_vdac,
|
||||
.vpll2 = &overo_vpll2,
|
||||
};
|
||||
|
||||
static struct i2c_board_info __initdata overo_i2c_boardinfo[] = {
|
||||
@ -394,18 +666,38 @@ static int __init overo_i2c_init(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_device overo_lcd_device = {
|
||||
.name = "overo_lcd",
|
||||
.id = -1,
|
||||
static struct spi_board_info overo_spi_board_info[] __initdata = {
|
||||
#if defined(CONFIG_TOUCHSCREEN_ADS7846) || \
|
||||
defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
|
||||
{
|
||||
.modalias = "ads7846",
|
||||
.bus_num = 1,
|
||||
.chip_select = 0,
|
||||
.max_speed_hz = 1500000,
|
||||
.controller_data = &ads7846_mcspi_config,
|
||||
.irq = OMAP_GPIO_IRQ(OVERO_GPIO_PENDOWN),
|
||||
.platform_data = &ads7846_config,
|
||||
},
|
||||
#endif
|
||||
#if defined(CONFIG_PANEL_LGPHILIPS_LB035Q02) || \
|
||||
defined(CONFIG_PANEL_LGPHILIPS_LB035Q02_MODULE)
|
||||
{
|
||||
.modalias = "lgphilips_lb035q02_panel-spi",
|
||||
.bus_num = 1,
|
||||
.chip_select = 1,
|
||||
.max_speed_hz = 500000,
|
||||
.mode = SPI_MODE_3,
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct omap_lcd_config overo_lcd_config __initdata = {
|
||||
.ctrl_name = "internal",
|
||||
};
|
||||
|
||||
static struct omap_board_config_kernel overo_config[] __initdata = {
|
||||
{ OMAP_TAG_LCD, &overo_lcd_config },
|
||||
};
|
||||
static int __init overo_spi_init(void)
|
||||
{
|
||||
overo_ads7846_init();
|
||||
spi_register_board_info(overo_spi_board_info,
|
||||
ARRAY_SIZE(overo_spi_board_info));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __init overo_init_early(void)
|
||||
{
|
||||
@ -414,15 +706,10 @@ static void __init overo_init_early(void)
|
||||
mt46h32m32lf6_sdrc_params);
|
||||
}
|
||||
|
||||
static struct platform_device *overo_devices[] __initdata = {
|
||||
&overo_lcd_device,
|
||||
};
|
||||
|
||||
static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
|
||||
.port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED,
|
||||
.port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
|
||||
.port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
|
||||
|
||||
.phy_reset = true,
|
||||
.reset_gpio_port[0] = -EINVAL,
|
||||
.reset_gpio_port[1] = OVERO_GPIO_USBH_NRESET,
|
||||
@ -444,16 +731,18 @@ static struct omap_musb_board_data musb_board_data = {
|
||||
static void __init overo_init(void)
|
||||
{
|
||||
omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
|
||||
omap_board_config = overo_config;
|
||||
omap_board_config_size = ARRAY_SIZE(overo_config);
|
||||
overo_i2c_init();
|
||||
platform_add_devices(overo_devices, ARRAY_SIZE(overo_devices));
|
||||
omap_display_init(&overo_dss_data);
|
||||
omap_serial_init();
|
||||
overo_flash_init();
|
||||
usb_musb_init(&musb_board_data);
|
||||
usbhs_init(&usbhs_bdata);
|
||||
overo_spi_init();
|
||||
overo_ads7846_init();
|
||||
overo_init_smsc911x();
|
||||
overo_display_init();
|
||||
overo_init_led();
|
||||
overo_init_keys();
|
||||
|
||||
/* Ensure SDRC pins are mux'd for self-refresh */
|
||||
omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
|
||||
|
@ -372,7 +372,7 @@ static struct regulator_consumer_supply rx51_vaux1_consumers[] = {
|
||||
};
|
||||
|
||||
static struct regulator_consumer_supply rx51_vdac_supply[] = {
|
||||
REGULATOR_SUPPLY("vdda_dac", "omapdss"),
|
||||
REGULATOR_SUPPLY("vdda_dac", "omapdss_venc"),
|
||||
};
|
||||
|
||||
static struct regulator_init_data rx51_vaux1 = {
|
||||
|
@ -226,11 +226,13 @@ static struct omap2_hsmmc_info mmc[] = {
|
||||
{} /* Terminator */
|
||||
};
|
||||
|
||||
static struct regulator_consumer_supply zoom_vpll2_supply =
|
||||
REGULATOR_SUPPLY("vdds_dsi", "omapdss");
|
||||
static struct regulator_consumer_supply zoom_vpll2_supplies[] = {
|
||||
REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
|
||||
REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
|
||||
};
|
||||
|
||||
static struct regulator_consumer_supply zoom_vdda_dac_supply =
|
||||
REGULATOR_SUPPLY("vdda_dac", "omapdss");
|
||||
REGULATOR_SUPPLY("vdda_dac", "omapdss_venc");
|
||||
|
||||
static struct regulator_init_data zoom_vpll2 = {
|
||||
.constraints = {
|
||||
@ -241,8 +243,8 @@ static struct regulator_init_data zoom_vpll2 = {
|
||||
.valid_ops_mask = REGULATOR_CHANGE_MODE
|
||||
| REGULATOR_CHANGE_STATUS,
|
||||
},
|
||||
.num_consumer_supplies = 1,
|
||||
.consumer_supplies = &zoom_vpll2_supply,
|
||||
.num_consumer_supplies = ARRAY_SIZE(zoom_vpll2_supplies),
|
||||
.consumer_supplies = zoom_vpll2_supplies,
|
||||
};
|
||||
|
||||
static struct regulator_init_data zoom_vdac = {
|
||||
|
@ -1804,10 +1804,10 @@ static struct omap_clk omap2420_clks[] = {
|
||||
CLK(NULL, "gfx_2d_fck", &gfx_2d_fck, CK_242X),
|
||||
CLK(NULL, "gfx_ick", &gfx_ick, CK_242X),
|
||||
/* DSS domain clocks */
|
||||
CLK("omapdss", "ick", &dss_ick, CK_242X),
|
||||
CLK("omapdss", "dss1_fck", &dss1_fck, CK_242X),
|
||||
CLK("omapdss", "dss2_fck", &dss2_fck, CK_242X),
|
||||
CLK("omapdss", "tv_fck", &dss_54m_fck, CK_242X),
|
||||
CLK("omapdss_dss", "ick", &dss_ick, CK_242X),
|
||||
CLK("omapdss_dss", "fck", &dss1_fck, CK_242X),
|
||||
CLK("omapdss_dss", "sys_clk", &dss2_fck, CK_242X),
|
||||
CLK("omapdss_dss", "tv_clk", &dss_54m_fck, CK_242X),
|
||||
/* L3 domain clocks */
|
||||
CLK(NULL, "core_l3_ck", &core_l3_ck, CK_242X),
|
||||
CLK(NULL, "ssi_fck", &ssi_ssr_sst_fck, CK_242X),
|
||||
|
@ -1894,10 +1894,10 @@ static struct omap_clk omap2430_clks[] = {
|
||||
CLK(NULL, "mdm_ick", &mdm_ick, CK_243X),
|
||||
CLK(NULL, "mdm_osc_ck", &mdm_osc_ck, CK_243X),
|
||||
/* DSS domain clocks */
|
||||
CLK("omapdss", "ick", &dss_ick, CK_243X),
|
||||
CLK("omapdss", "dss1_fck", &dss1_fck, CK_243X),
|
||||
CLK("omapdss", "dss2_fck", &dss2_fck, CK_243X),
|
||||
CLK("omapdss", "tv_fck", &dss_54m_fck, CK_243X),
|
||||
CLK("omapdss_dss", "ick", &dss_ick, CK_243X),
|
||||
CLK("omapdss_dss", "fck", &dss1_fck, CK_243X),
|
||||
CLK("omapdss_dss", "sys_clk", &dss2_fck, CK_243X),
|
||||
CLK("omapdss_dss", "tv_clk", &dss_54m_fck, CK_243X),
|
||||
/* L3 domain clocks */
|
||||
CLK(NULL, "core_l3_ck", &core_l3_ck, CK_243X),
|
||||
CLK(NULL, "ssi_fck", &ssi_ssr_sst_fck, CK_243X),
|
||||
|
@ -3356,13 +3356,13 @@ static struct omap_clk omap3xxx_clks[] = {
|
||||
CLK("omap_rng", "ick", &rng_ick, CK_34XX | CK_36XX),
|
||||
CLK(NULL, "sha11_ick", &sha11_ick, CK_34XX | CK_36XX),
|
||||
CLK(NULL, "des1_ick", &des1_ick, CK_34XX | CK_36XX),
|
||||
CLK("omapdss", "dss1_fck", &dss1_alwon_fck_3430es1, CK_3430ES1),
|
||||
CLK("omapdss", "dss1_fck", &dss1_alwon_fck_3430es2, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
|
||||
CLK("omapdss", "tv_fck", &dss_tv_fck, CK_3XXX),
|
||||
CLK("omapdss", "video_fck", &dss_96m_fck, CK_3XXX),
|
||||
CLK("omapdss", "dss2_fck", &dss2_alwon_fck, CK_3XXX),
|
||||
CLK("omapdss", "ick", &dss_ick_3430es1, CK_3430ES1),
|
||||
CLK("omapdss", "ick", &dss_ick_3430es2, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
|
||||
CLK("omapdss_dss", "fck", &dss1_alwon_fck_3430es1, CK_3430ES1),
|
||||
CLK("omapdss_dss", "fck", &dss1_alwon_fck_3430es2, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
|
||||
CLK("omapdss_dss", "tv_clk", &dss_tv_fck, CK_3XXX),
|
||||
CLK("omapdss_dss", "video_clk", &dss_96m_fck, CK_3XXX),
|
||||
CLK("omapdss_dss", "sys_clk", &dss2_alwon_fck, CK_3XXX),
|
||||
CLK("omapdss_dss", "ick", &dss_ick_3430es1, CK_3430ES1),
|
||||
CLK("omapdss_dss", "ick", &dss_ick_3430es2, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
|
||||
CLK(NULL, "cam_mclk", &cam_mclk, CK_34XX | CK_36XX),
|
||||
CLK(NULL, "cam_ick", &cam_ick, CK_34XX | CK_36XX),
|
||||
CLK(NULL, "csi2_96m_fck", &csi2_96m_fck, CK_34XX | CK_36XX),
|
||||
|
@ -3114,11 +3114,16 @@ static struct omap_clk omap44xx_clks[] = {
|
||||
CLK(NULL, "dmic_sync_mux_ck", &dmic_sync_mux_ck, CK_443X),
|
||||
CLK(NULL, "dmic_fck", &dmic_fck, CK_443X),
|
||||
CLK(NULL, "dsp_fck", &dsp_fck, CK_443X),
|
||||
CLK(NULL, "dss_sys_clk", &dss_sys_clk, CK_443X),
|
||||
CLK(NULL, "dss_tv_clk", &dss_tv_clk, CK_443X),
|
||||
CLK(NULL, "dss_dss_clk", &dss_dss_clk, CK_443X),
|
||||
CLK(NULL, "dss_48mhz_clk", &dss_48mhz_clk, CK_443X),
|
||||
CLK(NULL, "dss_fck", &dss_fck, CK_443X),
|
||||
CLK("omapdss_dss", "sys_clk", &dss_sys_clk, CK_443X),
|
||||
CLK("omapdss_dss", "tv_clk", &dss_tv_clk, CK_443X),
|
||||
CLK("omapdss_dss", "dss_clk", &dss_dss_clk, CK_443X),
|
||||
CLK("omapdss_dss", "video_clk", &dss_48mhz_clk, CK_443X),
|
||||
CLK("omapdss_dss", "fck", &dss_fck, CK_443X),
|
||||
/*
|
||||
* On OMAP4, DSS ick is a dummy clock; this is needed for compatibility
|
||||
* with OMAP2/3.
|
||||
*/
|
||||
CLK("omapdss_dss", "ick", &dummy_ck, CK_443X),
|
||||
CLK(NULL, "efuse_ctrl_cust_fck", &efuse_ctrl_cust_fck, CK_443X),
|
||||
CLK(NULL, "emif1_fck", &emif1_fck, CK_443X),
|
||||
CLK(NULL, "emif2_fck", &emif2_fck, CK_443X),
|
||||
|
@ -23,6 +23,8 @@
|
||||
#include <linux/err.h>
|
||||
|
||||
#include <plat/display.h>
|
||||
#include <plat/omap_hwmod.h>
|
||||
#include <plat/omap_device.h>
|
||||
|
||||
static struct platform_device omap_display_device = {
|
||||
.name = "omapdss",
|
||||
@ -32,9 +34,87 @@ static struct platform_device omap_display_device = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct omap_device_pm_latency omap_dss_latency[] = {
|
||||
[0] = {
|
||||
.deactivate_func = omap_device_idle_hwmods,
|
||||
.activate_func = omap_device_enable_hwmods,
|
||||
.flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
|
||||
},
|
||||
};
|
||||
|
||||
/* oh_core is used for getting opt-clocks */
|
||||
static struct omap_hwmod *oh_core;
|
||||
|
||||
static bool opt_clock_available(const char *clk_role)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < oh_core->opt_clks_cnt; i++) {
|
||||
if (!strcmp(oh_core->opt_clks[i].role, clk_role))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int __init omap_display_init(struct omap_dss_board_info *board_data)
|
||||
{
|
||||
int r = 0;
|
||||
struct omap_hwmod *oh;
|
||||
struct omap_device *od;
|
||||
int i;
|
||||
struct omap_display_platform_data pdata;
|
||||
|
||||
/*
|
||||
* omap: valid DSS hwmod names
|
||||
* omap2,3,4: dss_core, dss_dispc, dss_rfbi, dss_venc
|
||||
* omap3,4: dss_dsi1
|
||||
* omap4: dss_dsi2, dss_hdmi
|
||||
*/
|
||||
char *oh_name[] = { "dss_core", "dss_dispc", "dss_rfbi", "dss_venc",
|
||||
"dss_dsi1", "dss_dsi2", "dss_hdmi" };
|
||||
char *dev_name[] = { "omapdss_dss", "omapdss_dispc", "omapdss_rfbi",
|
||||
"omapdss_venc", "omapdss_dsi1", "omapdss_dsi2",
|
||||
"omapdss_hdmi" };
|
||||
int oh_count;
|
||||
|
||||
memset(&pdata, 0, sizeof(pdata));
|
||||
|
||||
if (cpu_is_omap24xx())
|
||||
oh_count = ARRAY_SIZE(oh_name) - 3;
|
||||
/* last 3 hwmod dev in oh_name are not available for omap2 */
|
||||
else if (cpu_is_omap44xx())
|
||||
oh_count = ARRAY_SIZE(oh_name);
|
||||
else
|
||||
oh_count = ARRAY_SIZE(oh_name) - 2;
|
||||
/* last 2 hwmod dev in oh_name are not available for omap3 */
|
||||
|
||||
/* opt_clks are always associated with dss hwmod */
|
||||
oh_core = omap_hwmod_lookup("dss_core");
|
||||
if (!oh_core) {
|
||||
pr_err("Could not look up dss_core.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
pdata.board_data = board_data;
|
||||
pdata.board_data->get_last_off_on_transaction_id = NULL;
|
||||
pdata.opt_clock_available = opt_clock_available;
|
||||
|
||||
for (i = 0; i < oh_count; i++) {
|
||||
oh = omap_hwmod_lookup(oh_name[i]);
|
||||
if (!oh) {
|
||||
pr_err("Could not look up %s\n", oh_name[i]);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
od = omap_device_build(dev_name[i], -1, oh, &pdata,
|
||||
sizeof(struct omap_display_platform_data),
|
||||
omap_dss_latency,
|
||||
ARRAY_SIZE(omap_dss_latency), 0);
|
||||
|
||||
if (WARN((IS_ERR(od)), "Could not build omap_device for %s\n",
|
||||
oh_name[i]))
|
||||
return -ENODEV;
|
||||
}
|
||||
omap_display_device.dev.platform_data = board_data;
|
||||
|
||||
r = platform_device_register(&omap_display_device);
|
||||
|
@ -1168,11 +1168,6 @@ static struct omap_hwmod_class omap2420_dss_hwmod_class = {
|
||||
.sysc = &omap2420_dss_sysc,
|
||||
};
|
||||
|
||||
/* dss */
|
||||
static struct omap_hwmod_irq_info omap2420_dss_irqs[] = {
|
||||
{ .irq = 25 },
|
||||
};
|
||||
|
||||
static struct omap_hwmod_dma_info omap2420_dss_sdma_chs[] = {
|
||||
{ .name = "dispc", .dma_req = 5 },
|
||||
};
|
||||
@ -1221,8 +1216,6 @@ static struct omap_hwmod omap2420_dss_core_hwmod = {
|
||||
.name = "dss_core",
|
||||
.class = &omap2420_dss_hwmod_class,
|
||||
.main_clk = "dss1_fck", /* instead of dss_fck */
|
||||
.mpu_irqs = omap2420_dss_irqs,
|
||||
.mpu_irqs_cnt = ARRAY_SIZE(omap2420_dss_irqs),
|
||||
.sdma_reqs = omap2420_dss_sdma_chs,
|
||||
.sdma_reqs_cnt = ARRAY_SIZE(omap2420_dss_sdma_chs),
|
||||
.prcm = {
|
||||
@ -1265,6 +1258,10 @@ static struct omap_hwmod_class omap2420_dispc_hwmod_class = {
|
||||
.sysc = &omap2420_dispc_sysc,
|
||||
};
|
||||
|
||||
static struct omap_hwmod_irq_info omap2420_dispc_irqs[] = {
|
||||
{ .irq = 25 },
|
||||
};
|
||||
|
||||
static struct omap_hwmod_addr_space omap2420_dss_dispc_addrs[] = {
|
||||
{
|
||||
.pa_start = 0x48050400,
|
||||
@ -1297,6 +1294,8 @@ static struct omap_hwmod_ocp_if *omap2420_dss_dispc_slaves[] = {
|
||||
static struct omap_hwmod omap2420_dss_dispc_hwmod = {
|
||||
.name = "dss_dispc",
|
||||
.class = &omap2420_dispc_hwmod_class,
|
||||
.mpu_irqs = omap2420_dispc_irqs,
|
||||
.mpu_irqs_cnt = ARRAY_SIZE(omap2420_dispc_irqs),
|
||||
.main_clk = "dss1_fck",
|
||||
.prcm = {
|
||||
.omap2 = {
|
||||
|
@ -1268,10 +1268,6 @@ static struct omap_hwmod_class omap2430_dss_hwmod_class = {
|
||||
.sysc = &omap2430_dss_sysc,
|
||||
};
|
||||
|
||||
/* dss */
|
||||
static struct omap_hwmod_irq_info omap2430_dss_irqs[] = {
|
||||
{ .irq = 25 },
|
||||
};
|
||||
static struct omap_hwmod_dma_info omap2430_dss_sdma_chs[] = {
|
||||
{ .name = "dispc", .dma_req = 5 },
|
||||
};
|
||||
@ -1314,8 +1310,6 @@ static struct omap_hwmod omap2430_dss_core_hwmod = {
|
||||
.name = "dss_core",
|
||||
.class = &omap2430_dss_hwmod_class,
|
||||
.main_clk = "dss1_fck", /* instead of dss_fck */
|
||||
.mpu_irqs = omap2430_dss_irqs,
|
||||
.mpu_irqs_cnt = ARRAY_SIZE(omap2430_dss_irqs),
|
||||
.sdma_reqs = omap2430_dss_sdma_chs,
|
||||
.sdma_reqs_cnt = ARRAY_SIZE(omap2430_dss_sdma_chs),
|
||||
.prcm = {
|
||||
@ -1358,6 +1352,10 @@ static struct omap_hwmod_class omap2430_dispc_hwmod_class = {
|
||||
.sysc = &omap2430_dispc_sysc,
|
||||
};
|
||||
|
||||
static struct omap_hwmod_irq_info omap2430_dispc_irqs[] = {
|
||||
{ .irq = 25 },
|
||||
};
|
||||
|
||||
static struct omap_hwmod_addr_space omap2430_dss_dispc_addrs[] = {
|
||||
{
|
||||
.pa_start = 0x48050400,
|
||||
@ -1384,6 +1382,8 @@ static struct omap_hwmod_ocp_if *omap2430_dss_dispc_slaves[] = {
|
||||
static struct omap_hwmod omap2430_dss_dispc_hwmod = {
|
||||
.name = "dss_dispc",
|
||||
.class = &omap2430_dispc_hwmod_class,
|
||||
.mpu_irqs = omap2430_dispc_irqs,
|
||||
.mpu_irqs_cnt = ARRAY_SIZE(omap2430_dispc_irqs),
|
||||
.main_clk = "dss1_fck",
|
||||
.prcm = {
|
||||
.omap2 = {
|
||||
|
@ -1480,11 +1480,6 @@ static struct omap_hwmod_class omap3xxx_dss_hwmod_class = {
|
||||
.sysc = &omap3xxx_dss_sysc,
|
||||
};
|
||||
|
||||
/* dss */
|
||||
static struct omap_hwmod_irq_info omap3xxx_dss_irqs[] = {
|
||||
{ .irq = 25 },
|
||||
};
|
||||
|
||||
static struct omap_hwmod_dma_info omap3xxx_dss_sdma_chs[] = {
|
||||
{ .name = "dispc", .dma_req = 5 },
|
||||
{ .name = "dsi1", .dma_req = 74 },
|
||||
@ -1548,7 +1543,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_dss_slaves[] = {
|
||||
|
||||
static struct omap_hwmod_opt_clk dss_opt_clks[] = {
|
||||
{ .role = "tv_clk", .clk = "dss_tv_fck" },
|
||||
{ .role = "dssclk", .clk = "dss_96m_fck" },
|
||||
{ .role = "video_clk", .clk = "dss_96m_fck" },
|
||||
{ .role = "sys_clk", .clk = "dss2_alwon_fck" },
|
||||
};
|
||||
|
||||
@ -1556,8 +1551,6 @@ static struct omap_hwmod omap3430es1_dss_core_hwmod = {
|
||||
.name = "dss_core",
|
||||
.class = &omap3xxx_dss_hwmod_class,
|
||||
.main_clk = "dss1_alwon_fck", /* instead of dss_fck */
|
||||
.mpu_irqs = omap3xxx_dss_irqs,
|
||||
.mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_dss_irqs),
|
||||
.sdma_reqs = omap3xxx_dss_sdma_chs,
|
||||
.sdma_reqs_cnt = ARRAY_SIZE(omap3xxx_dss_sdma_chs),
|
||||
|
||||
@ -1584,8 +1577,6 @@ static struct omap_hwmod omap3xxx_dss_core_hwmod = {
|
||||
.name = "dss_core",
|
||||
.class = &omap3xxx_dss_hwmod_class,
|
||||
.main_clk = "dss1_alwon_fck", /* instead of dss_fck */
|
||||
.mpu_irqs = omap3xxx_dss_irqs,
|
||||
.mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_dss_irqs),
|
||||
.sdma_reqs = omap3xxx_dss_sdma_chs,
|
||||
.sdma_reqs_cnt = ARRAY_SIZE(omap3xxx_dss_sdma_chs),
|
||||
|
||||
@ -1631,6 +1622,10 @@ static struct omap_hwmod_class omap3xxx_dispc_hwmod_class = {
|
||||
.sysc = &omap3xxx_dispc_sysc,
|
||||
};
|
||||
|
||||
static struct omap_hwmod_irq_info omap3xxx_dispc_irqs[] = {
|
||||
{ .irq = 25 },
|
||||
};
|
||||
|
||||
static struct omap_hwmod_addr_space omap3xxx_dss_dispc_addrs[] = {
|
||||
{
|
||||
.pa_start = 0x48050400,
|
||||
@ -1664,6 +1659,8 @@ static struct omap_hwmod_ocp_if *omap3xxx_dss_dispc_slaves[] = {
|
||||
static struct omap_hwmod omap3xxx_dss_dispc_hwmod = {
|
||||
.name = "dss_dispc",
|
||||
.class = &omap3xxx_dispc_hwmod_class,
|
||||
.mpu_irqs = omap3xxx_dispc_irqs,
|
||||
.mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_dispc_irqs),
|
||||
.main_clk = "dss1_alwon_fck",
|
||||
.prcm = {
|
||||
.omap2 = {
|
||||
@ -1689,6 +1686,10 @@ static struct omap_hwmod_class omap3xxx_dsi_hwmod_class = {
|
||||
.name = "dsi",
|
||||
};
|
||||
|
||||
static struct omap_hwmod_irq_info omap3xxx_dsi1_irqs[] = {
|
||||
{ .irq = 25 },
|
||||
};
|
||||
|
||||
/* dss_dsi1 */
|
||||
static struct omap_hwmod_addr_space omap3xxx_dss_dsi1_addrs[] = {
|
||||
{
|
||||
@ -1722,6 +1723,8 @@ static struct omap_hwmod_ocp_if *omap3xxx_dss_dsi1_slaves[] = {
|
||||
static struct omap_hwmod omap3xxx_dss_dsi1_hwmod = {
|
||||
.name = "dss_dsi1",
|
||||
.class = &omap3xxx_dsi_hwmod_class,
|
||||
.mpu_irqs = omap3xxx_dsi1_irqs,
|
||||
.mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_dsi1_irqs),
|
||||
.main_clk = "dss1_alwon_fck",
|
||||
.prcm = {
|
||||
.omap2 = {
|
||||
|
@ -58,6 +58,7 @@ enum omap_display_type {
|
||||
OMAP_DISPLAY_TYPE_SDI = 1 << 2,
|
||||
OMAP_DISPLAY_TYPE_DSI = 1 << 3,
|
||||
OMAP_DISPLAY_TYPE_VENC = 1 << 4,
|
||||
OMAP_DISPLAY_TYPE_HDMI = 1 << 5,
|
||||
};
|
||||
|
||||
enum omap_plane {
|
||||
@ -237,6 +238,13 @@ static inline int omap_display_init(struct omap_dss_board_info *board_data)
|
||||
}
|
||||
#endif
|
||||
|
||||
struct omap_display_platform_data {
|
||||
struct omap_dss_board_info *board_data;
|
||||
/* TODO: Additional members to be added when PM is considered */
|
||||
|
||||
bool (*opt_clock_available)(const char *clk_role);
|
||||
};
|
||||
|
||||
struct omap_video_timings {
|
||||
/* Unit: pixels */
|
||||
u16 x_res;
|
||||
@ -396,8 +404,8 @@ struct omap_dss_device {
|
||||
struct {
|
||||
u16 regn;
|
||||
u16 regm;
|
||||
u16 regm3;
|
||||
u16 regm4;
|
||||
u16 regm_dispc;
|
||||
u16 regm_dsi;
|
||||
|
||||
u16 lp_clk_div;
|
||||
|
||||
@ -555,6 +563,9 @@ int omap_dsi_update(struct omap_dss_device *dssdev,
|
||||
int channel,
|
||||
u16 x, u16 y, u16 w, u16 h,
|
||||
void (*callback)(int, void *), void *data);
|
||||
int omap_dsi_request_vc(struct omap_dss_device *dssdev, int *channel);
|
||||
int omap_dsi_set_vc_id(struct omap_dss_device *dssdev, int channel, int vc_id);
|
||||
void omap_dsi_release_vc(struct omap_dss_device *dssdev, int channel);
|
||||
|
||||
int omapdss_dsi_display_enable(struct omap_dss_device *dssdev);
|
||||
void omapdss_dsi_display_disable(struct omap_dss_device *dssdev);
|
||||
|
@ -889,7 +889,7 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
|
||||
}
|
||||
|
||||
if (rdev->flags & RADEON_IS_MOBILITY) {
|
||||
/* A temporal workaround for the occational blanking on certain laptop panels.
|
||||
/* A temporal workaround for the occasional blanking on certain laptop panels.
|
||||
This appears to related to the PLL divider registers (fail to lock?).
|
||||
It occurs even when all dividers are the same with their old settings.
|
||||
In this case we really don't need to fiddle with PLL registers.
|
||||
|
@ -133,10 +133,10 @@ static unsigned long decode_div(unsigned long pll2, unsigned long val,
|
||||
|
||||
static void sm501_dump_clk(struct sm501_devdata *sm)
|
||||
{
|
||||
unsigned long misct = readl(sm->regs + SM501_MISC_TIMING);
|
||||
unsigned long pm0 = readl(sm->regs + SM501_POWER_MODE_0_CLOCK);
|
||||
unsigned long pm1 = readl(sm->regs + SM501_POWER_MODE_1_CLOCK);
|
||||
unsigned long pmc = readl(sm->regs + SM501_POWER_MODE_CONTROL);
|
||||
unsigned long misct = smc501_readl(sm->regs + SM501_MISC_TIMING);
|
||||
unsigned long pm0 = smc501_readl(sm->regs + SM501_POWER_MODE_0_CLOCK);
|
||||
unsigned long pm1 = smc501_readl(sm->regs + SM501_POWER_MODE_1_CLOCK);
|
||||
unsigned long pmc = smc501_readl(sm->regs + SM501_POWER_MODE_CONTROL);
|
||||
unsigned long sdclk0, sdclk1;
|
||||
unsigned long pll2 = 0;
|
||||
|
||||
@ -193,29 +193,29 @@ static void sm501_dump_regs(struct sm501_devdata *sm)
|
||||
void __iomem *regs = sm->regs;
|
||||
|
||||
dev_info(sm->dev, "System Control %08x\n",
|
||||
readl(regs + SM501_SYSTEM_CONTROL));
|
||||
smc501_readl(regs + SM501_SYSTEM_CONTROL));
|
||||
dev_info(sm->dev, "Misc Control %08x\n",
|
||||
readl(regs + SM501_MISC_CONTROL));
|
||||
smc501_readl(regs + SM501_MISC_CONTROL));
|
||||
dev_info(sm->dev, "GPIO Control Low %08x\n",
|
||||
readl(regs + SM501_GPIO31_0_CONTROL));
|
||||
smc501_readl(regs + SM501_GPIO31_0_CONTROL));
|
||||
dev_info(sm->dev, "GPIO Control Hi %08x\n",
|
||||
readl(regs + SM501_GPIO63_32_CONTROL));
|
||||
smc501_readl(regs + SM501_GPIO63_32_CONTROL));
|
||||
dev_info(sm->dev, "DRAM Control %08x\n",
|
||||
readl(regs + SM501_DRAM_CONTROL));
|
||||
smc501_readl(regs + SM501_DRAM_CONTROL));
|
||||
dev_info(sm->dev, "Arbitration Ctrl %08x\n",
|
||||
readl(regs + SM501_ARBTRTN_CONTROL));
|
||||
smc501_readl(regs + SM501_ARBTRTN_CONTROL));
|
||||
dev_info(sm->dev, "Misc Timing %08x\n",
|
||||
readl(regs + SM501_MISC_TIMING));
|
||||
smc501_readl(regs + SM501_MISC_TIMING));
|
||||
}
|
||||
|
||||
static void sm501_dump_gate(struct sm501_devdata *sm)
|
||||
{
|
||||
dev_info(sm->dev, "CurrentGate %08x\n",
|
||||
readl(sm->regs + SM501_CURRENT_GATE));
|
||||
smc501_readl(sm->regs + SM501_CURRENT_GATE));
|
||||
dev_info(sm->dev, "CurrentClock %08x\n",
|
||||
readl(sm->regs + SM501_CURRENT_CLOCK));
|
||||
smc501_readl(sm->regs + SM501_CURRENT_CLOCK));
|
||||
dev_info(sm->dev, "PowerModeControl %08x\n",
|
||||
readl(sm->regs + SM501_POWER_MODE_CONTROL));
|
||||
smc501_readl(sm->regs + SM501_POWER_MODE_CONTROL));
|
||||
}
|
||||
|
||||
#else
|
||||
@ -231,7 +231,7 @@ static inline void sm501_dump_clk(struct sm501_devdata *sm) { }
|
||||
|
||||
static void sm501_sync_regs(struct sm501_devdata *sm)
|
||||
{
|
||||
readl(sm->regs);
|
||||
smc501_readl(sm->regs);
|
||||
}
|
||||
|
||||
static inline void sm501_mdelay(struct sm501_devdata *sm, unsigned int delay)
|
||||
@ -261,11 +261,11 @@ int sm501_misc_control(struct device *dev,
|
||||
|
||||
spin_lock_irqsave(&sm->reg_lock, save);
|
||||
|
||||
misc = readl(sm->regs + SM501_MISC_CONTROL);
|
||||
misc = smc501_readl(sm->regs + SM501_MISC_CONTROL);
|
||||
to = (misc & ~clear) | set;
|
||||
|
||||
if (to != misc) {
|
||||
writel(to, sm->regs + SM501_MISC_CONTROL);
|
||||
smc501_writel(to, sm->regs + SM501_MISC_CONTROL);
|
||||
sm501_sync_regs(sm);
|
||||
|
||||
dev_dbg(sm->dev, "MISC_CONTROL %08lx\n", misc);
|
||||
@ -294,11 +294,11 @@ unsigned long sm501_modify_reg(struct device *dev,
|
||||
|
||||
spin_lock_irqsave(&sm->reg_lock, save);
|
||||
|
||||
data = readl(sm->regs + reg);
|
||||
data = smc501_readl(sm->regs + reg);
|
||||
data |= set;
|
||||
data &= ~clear;
|
||||
|
||||
writel(data, sm->regs + reg);
|
||||
smc501_writel(data, sm->regs + reg);
|
||||
sm501_sync_regs(sm);
|
||||
|
||||
spin_unlock_irqrestore(&sm->reg_lock, save);
|
||||
@ -322,9 +322,9 @@ int sm501_unit_power(struct device *dev, unsigned int unit, unsigned int to)
|
||||
|
||||
mutex_lock(&sm->clock_lock);
|
||||
|
||||
mode = readl(sm->regs + SM501_POWER_MODE_CONTROL);
|
||||
gate = readl(sm->regs + SM501_CURRENT_GATE);
|
||||
clock = readl(sm->regs + SM501_CURRENT_CLOCK);
|
||||
mode = smc501_readl(sm->regs + SM501_POWER_MODE_CONTROL);
|
||||
gate = smc501_readl(sm->regs + SM501_CURRENT_GATE);
|
||||
clock = smc501_readl(sm->regs + SM501_CURRENT_CLOCK);
|
||||
|
||||
mode &= 3; /* get current power mode */
|
||||
|
||||
@ -356,14 +356,14 @@ int sm501_unit_power(struct device *dev, unsigned int unit, unsigned int to)
|
||||
|
||||
switch (mode) {
|
||||
case 1:
|
||||
writel(gate, sm->regs + SM501_POWER_MODE_0_GATE);
|
||||
writel(clock, sm->regs + SM501_POWER_MODE_0_CLOCK);
|
||||
smc501_writel(gate, sm->regs + SM501_POWER_MODE_0_GATE);
|
||||
smc501_writel(clock, sm->regs + SM501_POWER_MODE_0_CLOCK);
|
||||
mode = 0;
|
||||
break;
|
||||
case 2:
|
||||
case 0:
|
||||
writel(gate, sm->regs + SM501_POWER_MODE_1_GATE);
|
||||
writel(clock, sm->regs + SM501_POWER_MODE_1_CLOCK);
|
||||
smc501_writel(gate, sm->regs + SM501_POWER_MODE_1_GATE);
|
||||
smc501_writel(clock, sm->regs + SM501_POWER_MODE_1_CLOCK);
|
||||
mode = 1;
|
||||
break;
|
||||
|
||||
@ -372,7 +372,7 @@ int sm501_unit_power(struct device *dev, unsigned int unit, unsigned int to)
|
||||
goto already;
|
||||
}
|
||||
|
||||
writel(mode, sm->regs + SM501_POWER_MODE_CONTROL);
|
||||
smc501_writel(mode, sm->regs + SM501_POWER_MODE_CONTROL);
|
||||
sm501_sync_regs(sm);
|
||||
|
||||
dev_dbg(sm->dev, "gate %08lx, clock %08lx, mode %08lx\n",
|
||||
@ -519,9 +519,9 @@ unsigned long sm501_set_clock(struct device *dev,
|
||||
unsigned long req_freq)
|
||||
{
|
||||
struct sm501_devdata *sm = dev_get_drvdata(dev);
|
||||
unsigned long mode = readl(sm->regs + SM501_POWER_MODE_CONTROL);
|
||||
unsigned long gate = readl(sm->regs + SM501_CURRENT_GATE);
|
||||
unsigned long clock = readl(sm->regs + SM501_CURRENT_CLOCK);
|
||||
unsigned long mode = smc501_readl(sm->regs + SM501_POWER_MODE_CONTROL);
|
||||
unsigned long gate = smc501_readl(sm->regs + SM501_CURRENT_GATE);
|
||||
unsigned long clock = smc501_readl(sm->regs + SM501_CURRENT_CLOCK);
|
||||
unsigned char reg;
|
||||
unsigned int pll_reg = 0;
|
||||
unsigned long sm501_freq; /* the actual frequency achieved */
|
||||
@ -592,9 +592,9 @@ unsigned long sm501_set_clock(struct device *dev,
|
||||
|
||||
mutex_lock(&sm->clock_lock);
|
||||
|
||||
mode = readl(sm->regs + SM501_POWER_MODE_CONTROL);
|
||||
gate = readl(sm->regs + SM501_CURRENT_GATE);
|
||||
clock = readl(sm->regs + SM501_CURRENT_CLOCK);
|
||||
mode = smc501_readl(sm->regs + SM501_POWER_MODE_CONTROL);
|
||||
gate = smc501_readl(sm->regs + SM501_CURRENT_GATE);
|
||||
clock = smc501_readl(sm->regs + SM501_CURRENT_CLOCK);
|
||||
|
||||
clock = clock & ~(0xFF << clksrc);
|
||||
clock |= reg<<clksrc;
|
||||
@ -603,14 +603,14 @@ unsigned long sm501_set_clock(struct device *dev,
|
||||
|
||||
switch (mode) {
|
||||
case 1:
|
||||
writel(gate, sm->regs + SM501_POWER_MODE_0_GATE);
|
||||
writel(clock, sm->regs + SM501_POWER_MODE_0_CLOCK);
|
||||
smc501_writel(gate, sm->regs + SM501_POWER_MODE_0_GATE);
|
||||
smc501_writel(clock, sm->regs + SM501_POWER_MODE_0_CLOCK);
|
||||
mode = 0;
|
||||
break;
|
||||
case 2:
|
||||
case 0:
|
||||
writel(gate, sm->regs + SM501_POWER_MODE_1_GATE);
|
||||
writel(clock, sm->regs + SM501_POWER_MODE_1_CLOCK);
|
||||
smc501_writel(gate, sm->regs + SM501_POWER_MODE_1_GATE);
|
||||
smc501_writel(clock, sm->regs + SM501_POWER_MODE_1_CLOCK);
|
||||
mode = 1;
|
||||
break;
|
||||
|
||||
@ -619,10 +619,11 @@ unsigned long sm501_set_clock(struct device *dev,
|
||||
return -1;
|
||||
}
|
||||
|
||||
writel(mode, sm->regs + SM501_POWER_MODE_CONTROL);
|
||||
smc501_writel(mode, sm->regs + SM501_POWER_MODE_CONTROL);
|
||||
|
||||
if (pll_reg)
|
||||
writel(pll_reg, sm->regs + SM501_PROGRAMMABLE_PLL_CONTROL);
|
||||
smc501_writel(pll_reg,
|
||||
sm->regs + SM501_PROGRAMMABLE_PLL_CONTROL);
|
||||
|
||||
sm501_sync_regs(sm);
|
||||
|
||||
@ -902,7 +903,7 @@ static int sm501_gpio_get(struct gpio_chip *chip, unsigned offset)
|
||||
struct sm501_gpio_chip *smgpio = to_sm501_gpio(chip);
|
||||
unsigned long result;
|
||||
|
||||
result = readl(smgpio->regbase + SM501_GPIO_DATA_LOW);
|
||||
result = smc501_readl(smgpio->regbase + SM501_GPIO_DATA_LOW);
|
||||
result >>= offset;
|
||||
|
||||
return result & 1UL;
|
||||
@ -915,13 +916,13 @@ static void sm501_gpio_ensure_gpio(struct sm501_gpio_chip *smchip,
|
||||
|
||||
/* check and modify if this pin is not set as gpio. */
|
||||
|
||||
if (readl(smchip->control) & bit) {
|
||||
if (smc501_readl(smchip->control) & bit) {
|
||||
dev_info(sm501_gpio_to_dev(smchip->ourgpio)->dev,
|
||||
"changing mode of gpio, bit %08lx\n", bit);
|
||||
|
||||
ctrl = readl(smchip->control);
|
||||
ctrl = smc501_readl(smchip->control);
|
||||
ctrl &= ~bit;
|
||||
writel(ctrl, smchip->control);
|
||||
smc501_writel(ctrl, smchip->control);
|
||||
|
||||
sm501_sync_regs(sm501_gpio_to_dev(smchip->ourgpio));
|
||||
}
|
||||
@ -942,10 +943,10 @@ static void sm501_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
|
||||
|
||||
spin_lock_irqsave(&smgpio->lock, save);
|
||||
|
||||
val = readl(regs + SM501_GPIO_DATA_LOW) & ~bit;
|
||||
val = smc501_readl(regs + SM501_GPIO_DATA_LOW) & ~bit;
|
||||
if (value)
|
||||
val |= bit;
|
||||
writel(val, regs);
|
||||
smc501_writel(val, regs);
|
||||
|
||||
sm501_sync_regs(sm501_gpio_to_dev(smgpio));
|
||||
sm501_gpio_ensure_gpio(smchip, bit);
|
||||
@ -967,8 +968,8 @@ static int sm501_gpio_input(struct gpio_chip *chip, unsigned offset)
|
||||
|
||||
spin_lock_irqsave(&smgpio->lock, save);
|
||||
|
||||
ddr = readl(regs + SM501_GPIO_DDR_LOW);
|
||||
writel(ddr & ~bit, regs + SM501_GPIO_DDR_LOW);
|
||||
ddr = smc501_readl(regs + SM501_GPIO_DDR_LOW);
|
||||
smc501_writel(ddr & ~bit, regs + SM501_GPIO_DDR_LOW);
|
||||
|
||||
sm501_sync_regs(sm501_gpio_to_dev(smgpio));
|
||||
sm501_gpio_ensure_gpio(smchip, bit);
|
||||
@ -994,18 +995,18 @@ static int sm501_gpio_output(struct gpio_chip *chip,
|
||||
|
||||
spin_lock_irqsave(&smgpio->lock, save);
|
||||
|
||||
val = readl(regs + SM501_GPIO_DATA_LOW);
|
||||
val = smc501_readl(regs + SM501_GPIO_DATA_LOW);
|
||||
if (value)
|
||||
val |= bit;
|
||||
else
|
||||
val &= ~bit;
|
||||
writel(val, regs);
|
||||
smc501_writel(val, regs);
|
||||
|
||||
ddr = readl(regs + SM501_GPIO_DDR_LOW);
|
||||
writel(ddr | bit, regs + SM501_GPIO_DDR_LOW);
|
||||
ddr = smc501_readl(regs + SM501_GPIO_DDR_LOW);
|
||||
smc501_writel(ddr | bit, regs + SM501_GPIO_DDR_LOW);
|
||||
|
||||
sm501_sync_regs(sm501_gpio_to_dev(smgpio));
|
||||
writel(val, regs + SM501_GPIO_DATA_LOW);
|
||||
smc501_writel(val, regs + SM501_GPIO_DATA_LOW);
|
||||
|
||||
sm501_sync_regs(sm501_gpio_to_dev(smgpio));
|
||||
spin_unlock_irqrestore(&smgpio->lock, save);
|
||||
@ -1231,7 +1232,7 @@ static ssize_t sm501_dbg_regs(struct device *dev,
|
||||
|
||||
for (reg = 0x00; reg < 0x70; reg += 4) {
|
||||
ret = sprintf(ptr, "%08x = %08x\n",
|
||||
reg, readl(sm->regs + reg));
|
||||
reg, smc501_readl(sm->regs + reg));
|
||||
ptr += ret;
|
||||
}
|
||||
|
||||
@ -1255,10 +1256,10 @@ static inline void sm501_init_reg(struct sm501_devdata *sm,
|
||||
{
|
||||
unsigned long tmp;
|
||||
|
||||
tmp = readl(sm->regs + reg);
|
||||
tmp = smc501_readl(sm->regs + reg);
|
||||
tmp &= ~r->mask;
|
||||
tmp |= r->set;
|
||||
writel(tmp, sm->regs + reg);
|
||||
smc501_writel(tmp, sm->regs + reg);
|
||||
}
|
||||
|
||||
/* sm501_init_regs
|
||||
@ -1299,7 +1300,7 @@ static void sm501_init_regs(struct sm501_devdata *sm,
|
||||
|
||||
static int sm501_check_clocks(struct sm501_devdata *sm)
|
||||
{
|
||||
unsigned long pwrmode = readl(sm->regs + SM501_CURRENT_CLOCK);
|
||||
unsigned long pwrmode = smc501_readl(sm->regs + SM501_CURRENT_CLOCK);
|
||||
unsigned long msrc = (pwrmode & SM501_POWERMODE_M_SRC);
|
||||
unsigned long m1src = (pwrmode & SM501_POWERMODE_M1_SRC);
|
||||
|
||||
@ -1334,7 +1335,7 @@ static int __devinit sm501_init_dev(struct sm501_devdata *sm)
|
||||
|
||||
INIT_LIST_HEAD(&sm->devices);
|
||||
|
||||
devid = readl(sm->regs + SM501_DEVICEID);
|
||||
devid = smc501_readl(sm->regs + SM501_DEVICEID);
|
||||
|
||||
if ((devid & SM501_DEVICEID_IDMASK) != SM501_DEVICEID_SM501) {
|
||||
dev_err(sm->dev, "incorrect device id %08lx\n", devid);
|
||||
@ -1342,9 +1343,9 @@ static int __devinit sm501_init_dev(struct sm501_devdata *sm)
|
||||
}
|
||||
|
||||
/* disable irqs */
|
||||
writel(0, sm->regs + SM501_IRQ_MASK);
|
||||
smc501_writel(0, sm->regs + SM501_IRQ_MASK);
|
||||
|
||||
dramctrl = readl(sm->regs + SM501_DRAM_CONTROL);
|
||||
dramctrl = smc501_readl(sm->regs + SM501_DRAM_CONTROL);
|
||||
mem_avail = sm501_mem_local[(dramctrl >> 13) & 0x7];
|
||||
|
||||
dev_info(sm->dev, "SM501 At %p: Version %08lx, %ld Mb, IRQ %d\n",
|
||||
@ -1376,7 +1377,7 @@ static int __devinit sm501_init_dev(struct sm501_devdata *sm)
|
||||
sm501_register_gpio(sm);
|
||||
}
|
||||
|
||||
if (pdata->gpio_i2c != NULL && pdata->gpio_i2c_nr > 0) {
|
||||
if (pdata && pdata->gpio_i2c != NULL && pdata->gpio_i2c_nr > 0) {
|
||||
if (!sm501_gpio_isregistered(sm))
|
||||
dev_err(sm->dev, "no gpio available for i2c gpio.\n");
|
||||
else
|
||||
@ -1421,6 +1422,7 @@ static int __devinit sm501_plat_probe(struct platform_device *dev)
|
||||
|
||||
sm->io_res = platform_get_resource(dev, IORESOURCE_MEM, 1);
|
||||
sm->mem_res = platform_get_resource(dev, IORESOURCE_MEM, 0);
|
||||
|
||||
if (sm->io_res == NULL || sm->mem_res == NULL) {
|
||||
dev_err(&dev->dev, "failed to get IO resource\n");
|
||||
ret = -ENOENT;
|
||||
@ -1489,7 +1491,7 @@ static int sm501_plat_suspend(struct platform_device *pdev, pm_message_t state)
|
||||
struct sm501_devdata *sm = platform_get_drvdata(pdev);
|
||||
|
||||
sm->in_suspend = 1;
|
||||
sm->pm_misc = readl(sm->regs + SM501_MISC_CONTROL);
|
||||
sm->pm_misc = smc501_readl(sm->regs + SM501_MISC_CONTROL);
|
||||
|
||||
sm501_dump_regs(sm);
|
||||
|
||||
@ -1513,9 +1515,9 @@ static int sm501_plat_resume(struct platform_device *pdev)
|
||||
|
||||
/* check to see if we are in the same state as when suspended */
|
||||
|
||||
if (readl(sm->regs + SM501_MISC_CONTROL) != sm->pm_misc) {
|
||||
if (smc501_readl(sm->regs + SM501_MISC_CONTROL) != sm->pm_misc) {
|
||||
dev_info(sm->dev, "SM501_MISC_CONTROL changed over sleep\n");
|
||||
writel(sm->pm_misc, sm->regs + SM501_MISC_CONTROL);
|
||||
smc501_writel(sm->pm_misc, sm->regs + SM501_MISC_CONTROL);
|
||||
|
||||
/* our suspend causes the controller state to change,
|
||||
* either by something attempting setup, power loss,
|
||||
@ -1734,10 +1736,16 @@ static struct pci_driver sm501_pci_driver = {
|
||||
|
||||
MODULE_ALIAS("platform:sm501");
|
||||
|
||||
static struct of_device_id __devinitdata of_sm501_match_tbl[] = {
|
||||
{ .compatible = "smi,sm501", },
|
||||
{ /* end */ }
|
||||
};
|
||||
|
||||
static struct platform_driver sm501_plat_driver = {
|
||||
.driver = {
|
||||
.name = "sm501",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = of_sm501_match_tbl,
|
||||
},
|
||||
.probe = sm501_plat_probe,
|
||||
.remove = sm501_plat_remove,
|
||||
|
@ -158,12 +158,19 @@ static void arkfb_settile(struct fb_info *info, struct fb_tilemap *map)
|
||||
}
|
||||
}
|
||||
|
||||
static void arkfb_tilecursor(struct fb_info *info, struct fb_tilecursor *cursor)
|
||||
{
|
||||
struct arkfb_info *par = info->par;
|
||||
|
||||
svga_tilecursor(par->state.vgabase, info, cursor);
|
||||
}
|
||||
|
||||
static struct fb_tile_ops arkfb_tile_ops = {
|
||||
.fb_settile = arkfb_settile,
|
||||
.fb_tilecopy = svga_tilecopy,
|
||||
.fb_tilefill = svga_tilefill,
|
||||
.fb_tileblit = svga_tileblit,
|
||||
.fb_tilecursor = svga_tilecursor,
|
||||
.fb_tilecursor = arkfb_tilecursor,
|
||||
.fb_get_tilemax = svga_get_tilemax,
|
||||
};
|
||||
|
||||
@ -466,32 +473,40 @@ static unsigned short dac_regs[4] = {0x3c8, 0x3c9, 0x3c6, 0x3c7};
|
||||
|
||||
static void ark_dac_read_regs(void *data, u8 *code, int count)
|
||||
{
|
||||
u8 regval = vga_rseq(NULL, 0x1C);
|
||||
struct fb_info *info = data;
|
||||
struct arkfb_info *par;
|
||||
u8 regval;
|
||||
|
||||
par = info->par;
|
||||
regval = vga_rseq(par->state.vgabase, 0x1C);
|
||||
while (count != 0)
|
||||
{
|
||||
vga_wseq(NULL, 0x1C, regval | (code[0] & 4 ? 0x80 : 0));
|
||||
code[1] = vga_r(NULL, dac_regs[code[0] & 3]);
|
||||
vga_wseq(par->state.vgabase, 0x1C, regval | (code[0] & 4 ? 0x80 : 0));
|
||||
code[1] = vga_r(par->state.vgabase, dac_regs[code[0] & 3]);
|
||||
count--;
|
||||
code += 2;
|
||||
}
|
||||
|
||||
vga_wseq(NULL, 0x1C, regval);
|
||||
vga_wseq(par->state.vgabase, 0x1C, regval);
|
||||
}
|
||||
|
||||
static void ark_dac_write_regs(void *data, u8 *code, int count)
|
||||
{
|
||||
u8 regval = vga_rseq(NULL, 0x1C);
|
||||
struct fb_info *info = data;
|
||||
struct arkfb_info *par;
|
||||
u8 regval;
|
||||
|
||||
par = info->par;
|
||||
regval = vga_rseq(par->state.vgabase, 0x1C);
|
||||
while (count != 0)
|
||||
{
|
||||
vga_wseq(NULL, 0x1C, regval | (code[0] & 4 ? 0x80 : 0));
|
||||
vga_w(NULL, dac_regs[code[0] & 3], code[1]);
|
||||
vga_wseq(par->state.vgabase, 0x1C, regval | (code[0] & 4 ? 0x80 : 0));
|
||||
vga_w(par->state.vgabase, dac_regs[code[0] & 3], code[1]);
|
||||
count--;
|
||||
code += 2;
|
||||
}
|
||||
|
||||
vga_wseq(NULL, 0x1C, regval);
|
||||
vga_wseq(par->state.vgabase, 0x1C, regval);
|
||||
}
|
||||
|
||||
|
||||
@ -507,8 +522,8 @@ static void ark_set_pixclock(struct fb_info *info, u32 pixclock)
|
||||
}
|
||||
|
||||
/* Set VGA misc register */
|
||||
regval = vga_r(NULL, VGA_MIS_R);
|
||||
vga_w(NULL, VGA_MIS_W, regval | VGA_MIS_ENB_PLL_LOAD);
|
||||
regval = vga_r(par->state.vgabase, VGA_MIS_R);
|
||||
vga_w(par->state.vgabase, VGA_MIS_W, regval | VGA_MIS_ENB_PLL_LOAD);
|
||||
}
|
||||
|
||||
|
||||
@ -520,7 +535,10 @@ static int arkfb_open(struct fb_info *info, int user)
|
||||
|
||||
mutex_lock(&(par->open_lock));
|
||||
if (par->ref_count == 0) {
|
||||
void __iomem *vgabase = par->state.vgabase;
|
||||
|
||||
memset(&(par->state), 0, sizeof(struct vgastate));
|
||||
par->state.vgabase = vgabase;
|
||||
par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS | VGA_SAVE_CMAP;
|
||||
par->state.num_crtc = 0x60;
|
||||
par->state.num_seq = 0x30;
|
||||
@ -646,50 +664,50 @@ static int arkfb_set_par(struct fb_info *info)
|
||||
info->var.activate = FB_ACTIVATE_NOW;
|
||||
|
||||
/* Unlock registers */
|
||||
svga_wcrt_mask(0x11, 0x00, 0x80);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x11, 0x00, 0x80);
|
||||
|
||||
/* Blank screen and turn off sync */
|
||||
svga_wseq_mask(0x01, 0x20, 0x20);
|
||||
svga_wcrt_mask(0x17, 0x00, 0x80);
|
||||
svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x17, 0x00, 0x80);
|
||||
|
||||
/* Set default values */
|
||||
svga_set_default_gfx_regs();
|
||||
svga_set_default_atc_regs();
|
||||
svga_set_default_seq_regs();
|
||||
svga_set_default_crt_regs();
|
||||
svga_wcrt_multi(ark_line_compare_regs, 0xFFFFFFFF);
|
||||
svga_wcrt_multi(ark_start_address_regs, 0);
|
||||
svga_set_default_gfx_regs(par->state.vgabase);
|
||||
svga_set_default_atc_regs(par->state.vgabase);
|
||||
svga_set_default_seq_regs(par->state.vgabase);
|
||||
svga_set_default_crt_regs(par->state.vgabase);
|
||||
svga_wcrt_multi(par->state.vgabase, ark_line_compare_regs, 0xFFFFFFFF);
|
||||
svga_wcrt_multi(par->state.vgabase, ark_start_address_regs, 0);
|
||||
|
||||
/* ARK specific initialization */
|
||||
svga_wseq_mask(0x10, 0x1F, 0x1F); /* enable linear framebuffer and full memory access */
|
||||
svga_wseq_mask(0x12, 0x03, 0x03); /* 4 MB linear framebuffer size */
|
||||
svga_wseq_mask(par->state.vgabase, 0x10, 0x1F, 0x1F); /* enable linear framebuffer and full memory access */
|
||||
svga_wseq_mask(par->state.vgabase, 0x12, 0x03, 0x03); /* 4 MB linear framebuffer size */
|
||||
|
||||
vga_wseq(NULL, 0x13, info->fix.smem_start >> 16);
|
||||
vga_wseq(NULL, 0x14, info->fix.smem_start >> 24);
|
||||
vga_wseq(NULL, 0x15, 0);
|
||||
vga_wseq(NULL, 0x16, 0);
|
||||
vga_wseq(par->state.vgabase, 0x13, info->fix.smem_start >> 16);
|
||||
vga_wseq(par->state.vgabase, 0x14, info->fix.smem_start >> 24);
|
||||
vga_wseq(par->state.vgabase, 0x15, 0);
|
||||
vga_wseq(par->state.vgabase, 0x16, 0);
|
||||
|
||||
/* Set the FIFO threshold register */
|
||||
/* It is fascinating way to store 5-bit value in 8-bit register */
|
||||
regval = 0x10 | ((threshold & 0x0E) >> 1) | (threshold & 0x01) << 7 | (threshold & 0x10) << 1;
|
||||
vga_wseq(NULL, 0x18, regval);
|
||||
vga_wseq(par->state.vgabase, 0x18, regval);
|
||||
|
||||
/* Set the offset register */
|
||||
pr_debug("fb%d: offset register : %d\n", info->node, offset_value);
|
||||
svga_wcrt_multi(ark_offset_regs, offset_value);
|
||||
svga_wcrt_multi(par->state.vgabase, ark_offset_regs, offset_value);
|
||||
|
||||
/* fix for hi-res textmode */
|
||||
svga_wcrt_mask(0x40, 0x08, 0x08);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x40, 0x08, 0x08);
|
||||
|
||||
if (info->var.vmode & FB_VMODE_DOUBLE)
|
||||
svga_wcrt_mask(0x09, 0x80, 0x80);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x09, 0x80, 0x80);
|
||||
else
|
||||
svga_wcrt_mask(0x09, 0x00, 0x80);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x09, 0x00, 0x80);
|
||||
|
||||
if (info->var.vmode & FB_VMODE_INTERLACED)
|
||||
svga_wcrt_mask(0x44, 0x04, 0x04);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x44, 0x04, 0x04);
|
||||
else
|
||||
svga_wcrt_mask(0x44, 0x00, 0x04);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x44, 0x00, 0x04);
|
||||
|
||||
hmul = 1;
|
||||
hdiv = 1;
|
||||
@ -699,40 +717,40 @@ static int arkfb_set_par(struct fb_info *info)
|
||||
switch (mode) {
|
||||
case 0:
|
||||
pr_debug("fb%d: text mode\n", info->node);
|
||||
svga_set_textmode_vga_regs();
|
||||
svga_set_textmode_vga_regs(par->state.vgabase);
|
||||
|
||||
vga_wseq(NULL, 0x11, 0x10); /* basic VGA mode */
|
||||
svga_wcrt_mask(0x46, 0x00, 0x04); /* 8bit pixel path */
|
||||
vga_wseq(par->state.vgabase, 0x11, 0x10); /* basic VGA mode */
|
||||
svga_wcrt_mask(par->state.vgabase, 0x46, 0x00, 0x04); /* 8bit pixel path */
|
||||
dac_set_mode(par->dac, DAC_PSEUDO8_8);
|
||||
|
||||
break;
|
||||
case 1:
|
||||
pr_debug("fb%d: 4 bit pseudocolor\n", info->node);
|
||||
vga_wgfx(NULL, VGA_GFX_MODE, 0x40);
|
||||
vga_wgfx(par->state.vgabase, VGA_GFX_MODE, 0x40);
|
||||
|
||||
vga_wseq(NULL, 0x11, 0x10); /* basic VGA mode */
|
||||
svga_wcrt_mask(0x46, 0x00, 0x04); /* 8bit pixel path */
|
||||
vga_wseq(par->state.vgabase, 0x11, 0x10); /* basic VGA mode */
|
||||
svga_wcrt_mask(par->state.vgabase, 0x46, 0x00, 0x04); /* 8bit pixel path */
|
||||
dac_set_mode(par->dac, DAC_PSEUDO8_8);
|
||||
break;
|
||||
case 2:
|
||||
pr_debug("fb%d: 4 bit pseudocolor, planar\n", info->node);
|
||||
|
||||
vga_wseq(NULL, 0x11, 0x10); /* basic VGA mode */
|
||||
svga_wcrt_mask(0x46, 0x00, 0x04); /* 8bit pixel path */
|
||||
vga_wseq(par->state.vgabase, 0x11, 0x10); /* basic VGA mode */
|
||||
svga_wcrt_mask(par->state.vgabase, 0x46, 0x00, 0x04); /* 8bit pixel path */
|
||||
dac_set_mode(par->dac, DAC_PSEUDO8_8);
|
||||
break;
|
||||
case 3:
|
||||
pr_debug("fb%d: 8 bit pseudocolor\n", info->node);
|
||||
|
||||
vga_wseq(NULL, 0x11, 0x16); /* 8bpp accel mode */
|
||||
vga_wseq(par->state.vgabase, 0x11, 0x16); /* 8bpp accel mode */
|
||||
|
||||
if (info->var.pixclock > 20000) {
|
||||
pr_debug("fb%d: not using multiplex\n", info->node);
|
||||
svga_wcrt_mask(0x46, 0x00, 0x04); /* 8bit pixel path */
|
||||
svga_wcrt_mask(par->state.vgabase, 0x46, 0x00, 0x04); /* 8bit pixel path */
|
||||
dac_set_mode(par->dac, DAC_PSEUDO8_8);
|
||||
} else {
|
||||
pr_debug("fb%d: using multiplex\n", info->node);
|
||||
svga_wcrt_mask(0x46, 0x04, 0x04); /* 16bit pixel path */
|
||||
svga_wcrt_mask(par->state.vgabase, 0x46, 0x04, 0x04); /* 16bit pixel path */
|
||||
dac_set_mode(par->dac, DAC_PSEUDO8_16);
|
||||
hdiv = 2;
|
||||
}
|
||||
@ -740,22 +758,22 @@ static int arkfb_set_par(struct fb_info *info)
|
||||
case 4:
|
||||
pr_debug("fb%d: 5/5/5 truecolor\n", info->node);
|
||||
|
||||
vga_wseq(NULL, 0x11, 0x1A); /* 16bpp accel mode */
|
||||
svga_wcrt_mask(0x46, 0x04, 0x04); /* 16bit pixel path */
|
||||
vga_wseq(par->state.vgabase, 0x11, 0x1A); /* 16bpp accel mode */
|
||||
svga_wcrt_mask(par->state.vgabase, 0x46, 0x04, 0x04); /* 16bit pixel path */
|
||||
dac_set_mode(par->dac, DAC_RGB1555_16);
|
||||
break;
|
||||
case 5:
|
||||
pr_debug("fb%d: 5/6/5 truecolor\n", info->node);
|
||||
|
||||
vga_wseq(NULL, 0x11, 0x1A); /* 16bpp accel mode */
|
||||
svga_wcrt_mask(0x46, 0x04, 0x04); /* 16bit pixel path */
|
||||
vga_wseq(par->state.vgabase, 0x11, 0x1A); /* 16bpp accel mode */
|
||||
svga_wcrt_mask(par->state.vgabase, 0x46, 0x04, 0x04); /* 16bit pixel path */
|
||||
dac_set_mode(par->dac, DAC_RGB0565_16);
|
||||
break;
|
||||
case 6:
|
||||
pr_debug("fb%d: 8/8/8 truecolor\n", info->node);
|
||||
|
||||
vga_wseq(NULL, 0x11, 0x16); /* 8bpp accel mode ??? */
|
||||
svga_wcrt_mask(0x46, 0x04, 0x04); /* 16bit pixel path */
|
||||
vga_wseq(par->state.vgabase, 0x11, 0x16); /* 8bpp accel mode ??? */
|
||||
svga_wcrt_mask(par->state.vgabase, 0x46, 0x04, 0x04); /* 16bit pixel path */
|
||||
dac_set_mode(par->dac, DAC_RGB0888_16);
|
||||
hmul = 3;
|
||||
hdiv = 2;
|
||||
@ -763,8 +781,8 @@ static int arkfb_set_par(struct fb_info *info)
|
||||
case 7:
|
||||
pr_debug("fb%d: 8/8/8/8 truecolor\n", info->node);
|
||||
|
||||
vga_wseq(NULL, 0x11, 0x1E); /* 32bpp accel mode */
|
||||
svga_wcrt_mask(0x46, 0x04, 0x04); /* 16bit pixel path */
|
||||
vga_wseq(par->state.vgabase, 0x11, 0x1E); /* 32bpp accel mode */
|
||||
svga_wcrt_mask(par->state.vgabase, 0x46, 0x04, 0x04); /* 16bit pixel path */
|
||||
dac_set_mode(par->dac, DAC_RGB8888_16);
|
||||
hmul = 2;
|
||||
break;
|
||||
@ -774,7 +792,7 @@ static int arkfb_set_par(struct fb_info *info)
|
||||
}
|
||||
|
||||
ark_set_pixclock(info, (hdiv * info->var.pixclock) / hmul);
|
||||
svga_set_timings(&ark_timing_regs, &(info->var), hmul, hdiv,
|
||||
svga_set_timings(par->state.vgabase, &ark_timing_regs, &(info->var), hmul, hdiv,
|
||||
(info->var.vmode & FB_VMODE_DOUBLE) ? 2 : 1,
|
||||
(info->var.vmode & FB_VMODE_INTERLACED) ? 2 : 1,
|
||||
hmul, info->node);
|
||||
@ -782,12 +800,12 @@ static int arkfb_set_par(struct fb_info *info)
|
||||
/* Set interlaced mode start/end register */
|
||||
value = info->var.xres + info->var.left_margin + info->var.right_margin + info->var.hsync_len;
|
||||
value = ((value * hmul / hdiv) / 8) - 5;
|
||||
vga_wcrt(NULL, 0x42, (value + 1) / 2);
|
||||
vga_wcrt(par->state.vgabase, 0x42, (value + 1) / 2);
|
||||
|
||||
memset_io(info->screen_base, 0x00, screen_size);
|
||||
/* Device and screen back on */
|
||||
svga_wcrt_mask(0x17, 0x80, 0x80);
|
||||
svga_wseq_mask(0x01, 0x00, 0x20);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x17, 0x80, 0x80);
|
||||
svga_wseq_mask(par->state.vgabase, 0x01, 0x00, 0x20);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -857,23 +875,25 @@ static int arkfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
|
||||
|
||||
static int arkfb_blank(int blank_mode, struct fb_info *info)
|
||||
{
|
||||
struct arkfb_info *par = info->par;
|
||||
|
||||
switch (blank_mode) {
|
||||
case FB_BLANK_UNBLANK:
|
||||
pr_debug("fb%d: unblank\n", info->node);
|
||||
svga_wseq_mask(0x01, 0x00, 0x20);
|
||||
svga_wcrt_mask(0x17, 0x80, 0x80);
|
||||
svga_wseq_mask(par->state.vgabase, 0x01, 0x00, 0x20);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x17, 0x80, 0x80);
|
||||
break;
|
||||
case FB_BLANK_NORMAL:
|
||||
pr_debug("fb%d: blank\n", info->node);
|
||||
svga_wseq_mask(0x01, 0x20, 0x20);
|
||||
svga_wcrt_mask(0x17, 0x80, 0x80);
|
||||
svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x17, 0x80, 0x80);
|
||||
break;
|
||||
case FB_BLANK_POWERDOWN:
|
||||
case FB_BLANK_HSYNC_SUSPEND:
|
||||
case FB_BLANK_VSYNC_SUSPEND:
|
||||
pr_debug("fb%d: sync down\n", info->node);
|
||||
svga_wseq_mask(0x01, 0x20, 0x20);
|
||||
svga_wcrt_mask(0x17, 0x00, 0x80);
|
||||
svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x17, 0x00, 0x80);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
@ -884,6 +904,7 @@ static int arkfb_blank(int blank_mode, struct fb_info *info)
|
||||
|
||||
static int arkfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
|
||||
{
|
||||
struct arkfb_info *par = info->par;
|
||||
unsigned int offset;
|
||||
|
||||
/* Calculate the offset */
|
||||
@ -897,7 +918,7 @@ static int arkfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info
|
||||
}
|
||||
|
||||
/* Set the offset */
|
||||
svga_wcrt_multi(ark_start_address_regs, offset);
|
||||
svga_wcrt_multi(par->state.vgabase, ark_start_address_regs, offset);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -930,6 +951,8 @@ static struct fb_ops arkfb_ops = {
|
||||
/* PCI probe */
|
||||
static int __devinit ark_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
||||
{
|
||||
struct pci_bus_region bus_reg;
|
||||
struct resource vga_res;
|
||||
struct fb_info *info;
|
||||
struct arkfb_info *par;
|
||||
int rc;
|
||||
@ -985,8 +1008,17 @@ static int __devinit ark_pci_probe(struct pci_dev *dev, const struct pci_device_
|
||||
goto err_iomap;
|
||||
}
|
||||
|
||||
bus_reg.start = 0;
|
||||
bus_reg.end = 64 * 1024;
|
||||
|
||||
vga_res.flags = IORESOURCE_IO;
|
||||
|
||||
pcibios_bus_to_resource(dev, &vga_res, &bus_reg);
|
||||
|
||||
par->state.vgabase = (void __iomem *) vga_res.start;
|
||||
|
||||
/* FIXME get memsize */
|
||||
regval = vga_rseq(NULL, 0x10);
|
||||
regval = vga_rseq(par->state.vgabase, 0x10);
|
||||
info->screen_size = (1 << (regval >> 6)) << 20;
|
||||
info->fix.smem_len = info->screen_size;
|
||||
|
||||
|
@ -68,7 +68,7 @@ static void atmel_lcdfb_update_dma2d(struct atmel_lcdfb_info *sinfo,
|
||||
}
|
||||
#endif
|
||||
|
||||
static const u32 contrast_ctr = ATMEL_LCDC_PS_DIV8
|
||||
static u32 contrast_ctr = ATMEL_LCDC_PS_DIV8
|
||||
| ATMEL_LCDC_POL_POSITIVE
|
||||
| ATMEL_LCDC_ENA_PWMENABLE;
|
||||
|
||||
@ -164,6 +164,10 @@ static void exit_backlight(struct atmel_lcdfb_info *sinfo)
|
||||
|
||||
static void init_contrast(struct atmel_lcdfb_info *sinfo)
|
||||
{
|
||||
/* contrast pwm can be 'inverted' */
|
||||
if (sinfo->lcdcon_pol_negative)
|
||||
contrast_ctr &= ~(ATMEL_LCDC_POL_POSITIVE);
|
||||
|
||||
/* have some default contrast/backlight settings */
|
||||
lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, contrast_ctr);
|
||||
lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_VAL, ATMEL_LCDC_CVAL_DEFAULT);
|
||||
@ -711,11 +715,35 @@ static int atmel_lcdfb_pan_display(struct fb_var_screeninfo *var,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int atmel_lcdfb_blank(int blank_mode, struct fb_info *info)
|
||||
{
|
||||
struct atmel_lcdfb_info *sinfo = info->par;
|
||||
|
||||
switch (blank_mode) {
|
||||
case FB_BLANK_UNBLANK:
|
||||
case FB_BLANK_NORMAL:
|
||||
atmel_lcdfb_start(sinfo);
|
||||
break;
|
||||
case FB_BLANK_VSYNC_SUSPEND:
|
||||
case FB_BLANK_HSYNC_SUSPEND:
|
||||
break;
|
||||
case FB_BLANK_POWERDOWN:
|
||||
atmel_lcdfb_stop(sinfo);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* let fbcon do a soft blank for us */
|
||||
return ((blank_mode == FB_BLANK_NORMAL) ? 1 : 0);
|
||||
}
|
||||
|
||||
static struct fb_ops atmel_lcdfb_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.fb_check_var = atmel_lcdfb_check_var,
|
||||
.fb_set_par = atmel_lcdfb_set_par,
|
||||
.fb_setcolreg = atmel_lcdfb_setcolreg,
|
||||
.fb_blank = atmel_lcdfb_blank,
|
||||
.fb_pan_display = atmel_lcdfb_pan_display,
|
||||
.fb_fillrect = cfb_fillrect,
|
||||
.fb_copyarea = cfb_copyarea,
|
||||
@ -817,6 +845,7 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)
|
||||
sinfo->guard_time = pdata_sinfo->guard_time;
|
||||
sinfo->smem_len = pdata_sinfo->smem_len;
|
||||
sinfo->lcdcon_is_backlight = pdata_sinfo->lcdcon_is_backlight;
|
||||
sinfo->lcdcon_pol_negative = pdata_sinfo->lcdcon_pol_negative;
|
||||
sinfo->lcd_wiring_mode = pdata_sinfo->lcd_wiring_mode;
|
||||
} else {
|
||||
dev_err(dev, "cannot get default configuration\n");
|
||||
|
@ -1248,7 +1248,7 @@ static void radeon_write_pll_regs(struct radeonfb_info *rinfo, struct radeon_reg
|
||||
|
||||
/* Workaround from XFree */
|
||||
if (rinfo->is_mobility) {
|
||||
/* A temporal workaround for the occational blanking on certain laptop
|
||||
/* A temporal workaround for the occasional blanking on certain laptop
|
||||
* panels. This appears to related to the PLL divider registers
|
||||
* (fail to lock?). It occurs even when all dividers are the same
|
||||
* with their old settings. In this case we really don't need to
|
||||
|
@ -100,6 +100,9 @@ void radeon_create_i2c_busses(struct radeonfb_info *rinfo)
|
||||
{
|
||||
rinfo->i2c[0].rinfo = rinfo;
|
||||
rinfo->i2c[0].ddc_reg = GPIO_MONID;
|
||||
#ifndef CONFIG_PPC
|
||||
rinfo->i2c[0].adapter.class = I2C_CLASS_HWMON;
|
||||
#endif
|
||||
radeon_setup_i2c_bus(&rinfo->i2c[0], "monid");
|
||||
|
||||
rinfo->i2c[1].rinfo = rinfo;
|
||||
|
@ -565,6 +565,7 @@ out_dealloc_cmap:
|
||||
|
||||
out_unmap_regs:
|
||||
cg14_unmap_regs(op, info, par);
|
||||
framebuffer_release(info);
|
||||
|
||||
out_err:
|
||||
return err;
|
||||
|
@ -821,6 +821,7 @@ out_dealloc_cmap:
|
||||
|
||||
out_unmap_regs:
|
||||
cg6_unmap_regs(op, info, par);
|
||||
framebuffer_release(info);
|
||||
|
||||
out_err:
|
||||
return err;
|
||||
|
@ -823,10 +823,10 @@ static int set_con2fb_map(int unit, int newidx, int user)
|
||||
if (oldidx == newidx)
|
||||
return 0;
|
||||
|
||||
if (!info || fbcon_has_exited)
|
||||
if (!info)
|
||||
return -EINVAL;
|
||||
|
||||
if (!err && !search_for_mapped_con()) {
|
||||
if (!search_for_mapped_con() || !con_is_bound(&fb_con)) {
|
||||
info_idx = newidx;
|
||||
return fbcon_takeover(0);
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ static void tile_cursor(struct vc_data *vc, struct fb_info *info, int mode,
|
||||
int softback_lines, int fg, int bg)
|
||||
{
|
||||
struct fb_tilecursor cursor;
|
||||
int use_sw = (vc->vc_cursor_type & 0x01);
|
||||
int use_sw = (vc->vc_cursor_type & 0x10);
|
||||
|
||||
cursor.sx = vc->vc_x;
|
||||
cursor.sy = vc->vc_y;
|
||||
|
@ -101,8 +101,8 @@
|
||||
#define V_SYNC_WIDTH COMBINE_HI_4LO( V_SYNC_WIDTH_HI, V_SYNC_WIDTH_LO )
|
||||
#define V_SYNC_OFFSET COMBINE_HI_4LO( V_SYNC_OFFSET_HI, V_SYNC_OFFSET_LO )
|
||||
|
||||
#define H_SYNC_WIDTH COMBINE_HI_4LO( H_SYNC_WIDTH_HI, H_SYNC_WIDTH_LO )
|
||||
#define H_SYNC_OFFSET COMBINE_HI_4LO( H_SYNC_OFFSET_HI, H_SYNC_OFFSET_LO )
|
||||
#define H_SYNC_WIDTH COMBINE_HI_8LO( H_SYNC_WIDTH_HI, H_SYNC_WIDTH_LO )
|
||||
#define H_SYNC_OFFSET COMBINE_HI_8LO( H_SYNC_OFFSET_HI, H_SYNC_OFFSET_LO )
|
||||
|
||||
#define H_SIZE_LO (unsigned)block[ 12 ]
|
||||
#define V_SIZE_LO (unsigned)block[ 13 ]
|
||||
|
@ -1010,7 +1010,7 @@ out_dealloc_cmap:
|
||||
fb_dealloc_cmap(&info->cmap);
|
||||
|
||||
out_unmap_dac:
|
||||
of_iounmap(&op->resource[2], par->fbc, sizeof(struct ffb_fbc));
|
||||
of_iounmap(&op->resource[1], par->dac, sizeof(struct ffb_dac));
|
||||
|
||||
out_unmap_fbc:
|
||||
of_iounmap(&op->resource[2], par->fbc, sizeof(struct ffb_fbc));
|
||||
|
@ -299,7 +299,7 @@ static int __devexit hecubafb_remove(struct platform_device *dev)
|
||||
|
||||
static struct platform_driver hecubafb_driver = {
|
||||
.probe = hecubafb_probe,
|
||||
.remove = hecubafb_remove,
|
||||
.remove = __devexit_p(hecubafb_remove),
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "hecubafb",
|
||||
|
@ -321,11 +321,11 @@ static int __devinit hpfb_dio_probe(struct dio_dev * d, const struct dio_device_
|
||||
unsigned long paddr, vaddr;
|
||||
|
||||
paddr = d->resource.start;
|
||||
if (!request_mem_region(d->resource.start, d->resource.end - d->resource.start, d->name))
|
||||
if (!request_mem_region(d->resource.start, resource_size(&d->resource), d->name))
|
||||
return -EBUSY;
|
||||
|
||||
if (d->scode >= DIOII_SCBASE) {
|
||||
vaddr = (unsigned long)ioremap(paddr, d->resource.end - d->resource.start);
|
||||
vaddr = (unsigned long)ioremap(paddr, resource_size(&d->resource));
|
||||
} else {
|
||||
vaddr = paddr + DIO_VIRADDRBASE;
|
||||
}
|
||||
@ -344,7 +344,7 @@ static void __devexit hpfb_remove_one(struct dio_dev *d)
|
||||
unregister_framebuffer(&fb_info);
|
||||
if (d->scode >= DIOII_SCBASE)
|
||||
iounmap((void *)fb_regs);
|
||||
release_mem_region(d->resource.start, d->resource.end - d->resource.start);
|
||||
release_mem_region(d->resource.start, resource_size(&d->resource));
|
||||
}
|
||||
|
||||
static struct dio_device_id hpfb_dio_tbl[] = {
|
||||
|
@ -765,7 +765,7 @@ static int __devexit metronomefb_remove(struct platform_device *dev)
|
||||
|
||||
static struct platform_driver metronomefb_driver = {
|
||||
.probe = metronomefb_probe,
|
||||
.remove = metronomefb_remove,
|
||||
.remove = __devexit_p(metronomefb_remove),
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "metronomefb",
|
||||
|
@ -5,13 +5,18 @@ config FB_OMAP
|
||||
select FB_CFB_FILLRECT
|
||||
select FB_CFB_COPYAREA
|
||||
select FB_CFB_IMAGEBLIT
|
||||
select TWL4030_CORE if MACH_OMAP_2430SDP
|
||||
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"
|
||||
|
@ -397,8 +397,7 @@ static inline void free_req(struct blizzard_request *req)
|
||||
|
||||
spin_lock_irqsave(&blizzard.req_lock, flags);
|
||||
|
||||
list_del(&req->entry);
|
||||
list_add(&req->entry, &blizzard.free_req_list);
|
||||
list_move(&req->entry, &blizzard.free_req_list);
|
||||
if (!(req->flags & REQ_FROM_IRQ_POOL))
|
||||
up(&blizzard.req_sema);
|
||||
|
||||
|
@ -269,8 +269,7 @@ static inline void free_req(struct hwa742_request *req)
|
||||
|
||||
spin_lock_irqsave(&hwa742.req_lock, flags);
|
||||
|
||||
list_del(&req->entry);
|
||||
list_add(&req->entry, &hwa742.free_req_list);
|
||||
list_move(&req->entry, &hwa742.free_req_list);
|
||||
if (!(req->flags & REQ_FROM_IRQ_POOL))
|
||||
up(&hwa742.req_sema);
|
||||
|
||||
|
@ -9,6 +9,12 @@ config PANEL_GENERIC_DPI
|
||||
Supports LCD Panel used in TI SDP3430 and EVM boards,
|
||||
OMAP3517 EVM boards and CM-T35.
|
||||
|
||||
config PANEL_LGPHILIPS_LB035Q02
|
||||
tristate "LG.Philips LB035Q02 LCD Panel"
|
||||
depends on OMAP2_DSS && SPI
|
||||
help
|
||||
LCD Panel used on the Gumstix Overo Palo35
|
||||
|
||||
config PANEL_SHARP_LS037V7DW01
|
||||
tristate "Sharp LS037V7DW01 LCD Panel"
|
||||
depends on OMAP2_DSS
|
||||
|
@ -1,4 +1,5 @@
|
||||
obj-$(CONFIG_PANEL_GENERIC_DPI) += panel-generic-dpi.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
|
||||
|
||||
|
@ -156,6 +156,31 @@ static struct panel_config generic_dpi_panels[] = {
|
||||
.power_off_delay = 0,
|
||||
.name = "toppoly_tdo35s",
|
||||
},
|
||||
|
||||
/* Samsung LTE430WQ-F0C */
|
||||
{
|
||||
{
|
||||
.x_res = 480,
|
||||
.y_res = 272,
|
||||
|
||||
.pixel_clock = 9200,
|
||||
|
||||
.hfp = 8,
|
||||
.hsw = 41,
|
||||
.hbp = 45 - 41,
|
||||
|
||||
.vfp = 4,
|
||||
.vsw = 10,
|
||||
.vbp = 12 - 10,
|
||||
},
|
||||
.acbi = 0x0,
|
||||
.acb = 0x0,
|
||||
.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
|
||||
OMAP_DSS_LCD_IHS,
|
||||
.power_on_delay = 0,
|
||||
.power_off_delay = 0,
|
||||
.name = "samsung_lte430wq_f0c",
|
||||
},
|
||||
};
|
||||
|
||||
struct panel_drv_data {
|
||||
|
279
drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
Normal file
279
drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
Normal file
@ -0,0 +1,279 @@
|
||||
/*
|
||||
* LCD panel driver for LG.Philips LB035Q02
|
||||
*
|
||||
* 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 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/delay.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/mutex.h>
|
||||
|
||||
#include <plat/display.h>
|
||||
|
||||
struct lb035q02_data {
|
||||
struct mutex lock;
|
||||
};
|
||||
|
||||
static struct omap_video_timings lb035q02_timings = {
|
||||
.x_res = 320,
|
||||
.y_res = 240,
|
||||
|
||||
.pixel_clock = 6500,
|
||||
|
||||
.hsw = 2,
|
||||
.hfp = 20,
|
||||
.hbp = 68,
|
||||
|
||||
.vsw = 2,
|
||||
.vfp = 4,
|
||||
.vbp = 18,
|
||||
};
|
||||
|
||||
static int lb035q02_panel_power_on(struct omap_dss_device *dssdev)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
|
||||
return 0;
|
||||
|
||||
r = omapdss_dpi_display_enable(dssdev);
|
||||
if (r)
|
||||
goto err0;
|
||||
|
||||
if (dssdev->platform_enable) {
|
||||
r = dssdev->platform_enable(dssdev);
|
||||
if (r)
|
||||
goto err1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
err1:
|
||||
omapdss_dpi_display_disable(dssdev);
|
||||
err0:
|
||||
return r;
|
||||
}
|
||||
|
||||
static void lb035q02_panel_power_off(struct omap_dss_device *dssdev)
|
||||
{
|
||||
if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
|
||||
return;
|
||||
|
||||
if (dssdev->platform_disable)
|
||||
dssdev->platform_disable(dssdev);
|
||||
|
||||
omapdss_dpi_display_disable(dssdev);
|
||||
}
|
||||
|
||||
static int lb035q02_panel_probe(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct lb035q02_data *ld;
|
||||
int r;
|
||||
|
||||
dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
|
||||
OMAP_DSS_LCD_IHS;
|
||||
dssdev->panel.timings = lb035q02_timings;
|
||||
|
||||
ld = kzalloc(sizeof(*ld), GFP_KERNEL);
|
||||
if (!ld) {
|
||||
r = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
mutex_init(&ld->lock);
|
||||
dev_set_drvdata(&dssdev->dev, ld);
|
||||
return 0;
|
||||
err:
|
||||
return r;
|
||||
}
|
||||
|
||||
static void lb035q02_panel_remove(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct lb035q02_data *ld = dev_get_drvdata(&dssdev->dev);
|
||||
|
||||
kfree(ld);
|
||||
}
|
||||
|
||||
static int lb035q02_panel_enable(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct lb035q02_data *ld = dev_get_drvdata(&dssdev->dev);
|
||||
int r;
|
||||
|
||||
mutex_lock(&ld->lock);
|
||||
|
||||
r = lb035q02_panel_power_on(dssdev);
|
||||
if (r)
|
||||
goto err;
|
||||
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
|
||||
|
||||
mutex_unlock(&ld->lock);
|
||||
return 0;
|
||||
err:
|
||||
mutex_unlock(&ld->lock);
|
||||
return r;
|
||||
}
|
||||
|
||||
static void lb035q02_panel_disable(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct lb035q02_data *ld = dev_get_drvdata(&dssdev->dev);
|
||||
|
||||
mutex_lock(&ld->lock);
|
||||
|
||||
lb035q02_panel_power_off(dssdev);
|
||||
dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
|
||||
|
||||
mutex_unlock(&ld->lock);
|
||||
}
|
||||
|
||||
static int lb035q02_panel_suspend(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct lb035q02_data *ld = dev_get_drvdata(&dssdev->dev);
|
||||
|
||||
mutex_lock(&ld->lock);
|
||||
|
||||
lb035q02_panel_power_off(dssdev);
|
||||
dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
|
||||
|
||||
mutex_unlock(&ld->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lb035q02_panel_resume(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct lb035q02_data *ld = dev_get_drvdata(&dssdev->dev);
|
||||
int r;
|
||||
|
||||
mutex_lock(&ld->lock);
|
||||
|
||||
r = lb035q02_panel_power_on(dssdev);
|
||||
if (r)
|
||||
goto err;
|
||||
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
|
||||
|
||||
mutex_unlock(&ld->lock);
|
||||
return 0;
|
||||
err:
|
||||
mutex_unlock(&ld->lock);
|
||||
return r;
|
||||
}
|
||||
|
||||
static struct omap_dss_driver lb035q02_driver = {
|
||||
.probe = lb035q02_panel_probe,
|
||||
.remove = lb035q02_panel_remove,
|
||||
|
||||
.enable = lb035q02_panel_enable,
|
||||
.disable = lb035q02_panel_disable,
|
||||
.suspend = lb035q02_panel_suspend,
|
||||
.resume = lb035q02_panel_resume,
|
||||
|
||||
.driver = {
|
||||
.name = "lgphilips_lb035q02_panel",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int lb035q02_write_reg(struct spi_device *spi, u8 reg, u16 val)
|
||||
{
|
||||
struct spi_message msg;
|
||||
struct spi_transfer index_xfer = {
|
||||
.len = 3,
|
||||
.cs_change = 1,
|
||||
};
|
||||
struct spi_transfer value_xfer = {
|
||||
.len = 3,
|
||||
};
|
||||
u8 buffer[16];
|
||||
|
||||
spi_message_init(&msg);
|
||||
|
||||
/* register index */
|
||||
buffer[0] = 0x70;
|
||||
buffer[1] = 0x00;
|
||||
buffer[2] = reg & 0x7f;
|
||||
index_xfer.tx_buf = buffer;
|
||||
spi_message_add_tail(&index_xfer, &msg);
|
||||
|
||||
/* register value */
|
||||
buffer[4] = 0x72;
|
||||
buffer[5] = val >> 8;
|
||||
buffer[6] = val;
|
||||
value_xfer.tx_buf = buffer + 4;
|
||||
spi_message_add_tail(&value_xfer, &msg);
|
||||
|
||||
return spi_sync(spi, &msg);
|
||||
}
|
||||
|
||||
static void init_lb035q02_panel(struct spi_device *spi)
|
||||
{
|
||||
/* Init sequence from page 28 of the lb035q02 spec */
|
||||
lb035q02_write_reg(spi, 0x01, 0x6300);
|
||||
lb035q02_write_reg(spi, 0x02, 0x0200);
|
||||
lb035q02_write_reg(spi, 0x03, 0x0177);
|
||||
lb035q02_write_reg(spi, 0x04, 0x04c7);
|
||||
lb035q02_write_reg(spi, 0x05, 0xffc0);
|
||||
lb035q02_write_reg(spi, 0x06, 0xe806);
|
||||
lb035q02_write_reg(spi, 0x0a, 0x4008);
|
||||
lb035q02_write_reg(spi, 0x0b, 0x0000);
|
||||
lb035q02_write_reg(spi, 0x0d, 0x0030);
|
||||
lb035q02_write_reg(spi, 0x0e, 0x2800);
|
||||
lb035q02_write_reg(spi, 0x0f, 0x0000);
|
||||
lb035q02_write_reg(spi, 0x16, 0x9f80);
|
||||
lb035q02_write_reg(spi, 0x17, 0x0a0f);
|
||||
lb035q02_write_reg(spi, 0x1e, 0x00c1);
|
||||
lb035q02_write_reg(spi, 0x30, 0x0300);
|
||||
lb035q02_write_reg(spi, 0x31, 0x0007);
|
||||
lb035q02_write_reg(spi, 0x32, 0x0000);
|
||||
lb035q02_write_reg(spi, 0x33, 0x0000);
|
||||
lb035q02_write_reg(spi, 0x34, 0x0707);
|
||||
lb035q02_write_reg(spi, 0x35, 0x0004);
|
||||
lb035q02_write_reg(spi, 0x36, 0x0302);
|
||||
lb035q02_write_reg(spi, 0x37, 0x0202);
|
||||
lb035q02_write_reg(spi, 0x3a, 0x0a0d);
|
||||
lb035q02_write_reg(spi, 0x3b, 0x0806);
|
||||
}
|
||||
|
||||
static int __devinit lb035q02_panel_spi_probe(struct spi_device *spi)
|
||||
{
|
||||
init_lb035q02_panel(spi);
|
||||
return omap_dss_register_driver(&lb035q02_driver);
|
||||
}
|
||||
|
||||
static int __devexit lb035q02_panel_spi_remove(struct spi_device *spi)
|
||||
{
|
||||
omap_dss_unregister_driver(&lb035q02_driver);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct spi_driver lb035q02_spi_driver = {
|
||||
.driver = {
|
||||
.name = "lgphilips_lb035q02_panel-spi",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = lb035q02_panel_spi_probe,
|
||||
.remove = __devexit_p(lb035q02_panel_spi_remove),
|
||||
};
|
||||
|
||||
static int __init lb035q02_panel_drv_init(void)
|
||||
{
|
||||
return spi_register_driver(&lb035q02_spi_driver);
|
||||
}
|
||||
|
||||
static void __exit lb035q02_panel_drv_exit(void)
|
||||
{
|
||||
spi_unregister_driver(&lb035q02_spi_driver);
|
||||
}
|
||||
|
||||
module_init(lb035q02_panel_drv_init);
|
||||
module_exit(lb035q02_panel_drv_exit);
|
||||
MODULE_LICENSE("GPL");
|
@ -218,6 +218,8 @@ struct taal_data {
|
||||
u16 w;
|
||||
u16 h;
|
||||
} update_region;
|
||||
int channel;
|
||||
|
||||
struct delayed_work te_timeout_work;
|
||||
|
||||
bool use_dsi_bl;
|
||||
@ -257,12 +259,12 @@ static void hw_guard_wait(struct taal_data *td)
|
||||
}
|
||||
}
|
||||
|
||||
static int taal_dcs_read_1(u8 dcs_cmd, u8 *data)
|
||||
static int taal_dcs_read_1(struct taal_data *td, u8 dcs_cmd, u8 *data)
|
||||
{
|
||||
int r;
|
||||
u8 buf[1];
|
||||
|
||||
r = dsi_vc_dcs_read(TCH, dcs_cmd, buf, 1);
|
||||
r = dsi_vc_dcs_read(td->channel, dcs_cmd, buf, 1);
|
||||
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -272,17 +274,17 @@ static int taal_dcs_read_1(u8 dcs_cmd, u8 *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int taal_dcs_write_0(u8 dcs_cmd)
|
||||
static int taal_dcs_write_0(struct taal_data *td, u8 dcs_cmd)
|
||||
{
|
||||
return dsi_vc_dcs_write(TCH, &dcs_cmd, 1);
|
||||
return dsi_vc_dcs_write(td->channel, &dcs_cmd, 1);
|
||||
}
|
||||
|
||||
static int taal_dcs_write_1(u8 dcs_cmd, u8 param)
|
||||
static int taal_dcs_write_1(struct taal_data *td, u8 dcs_cmd, u8 param)
|
||||
{
|
||||
u8 buf[2];
|
||||
buf[0] = dcs_cmd;
|
||||
buf[1] = param;
|
||||
return dsi_vc_dcs_write(TCH, buf, 2);
|
||||
return dsi_vc_dcs_write(td->channel, buf, 2);
|
||||
}
|
||||
|
||||
static int taal_sleep_in(struct taal_data *td)
|
||||
@ -294,7 +296,7 @@ static int taal_sleep_in(struct taal_data *td)
|
||||
hw_guard_wait(td);
|
||||
|
||||
cmd = DCS_SLEEP_IN;
|
||||
r = dsi_vc_dcs_write_nosync(TCH, &cmd, 1);
|
||||
r = dsi_vc_dcs_write_nosync(td->channel, &cmd, 1);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
@ -312,7 +314,7 @@ static int taal_sleep_out(struct taal_data *td)
|
||||
|
||||
hw_guard_wait(td);
|
||||
|
||||
r = taal_dcs_write_0(DCS_SLEEP_OUT);
|
||||
r = taal_dcs_write_0(td, DCS_SLEEP_OUT);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
@ -324,30 +326,30 @@ static int taal_sleep_out(struct taal_data *td)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int taal_get_id(u8 *id1, u8 *id2, u8 *id3)
|
||||
static int taal_get_id(struct taal_data *td, u8 *id1, u8 *id2, u8 *id3)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = taal_dcs_read_1(DCS_GET_ID1, id1);
|
||||
r = taal_dcs_read_1(td, DCS_GET_ID1, id1);
|
||||
if (r)
|
||||
return r;
|
||||
r = taal_dcs_read_1(DCS_GET_ID2, id2);
|
||||
r = taal_dcs_read_1(td, DCS_GET_ID2, id2);
|
||||
if (r)
|
||||
return r;
|
||||
r = taal_dcs_read_1(DCS_GET_ID3, id3);
|
||||
r = taal_dcs_read_1(td, DCS_GET_ID3, id3);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int taal_set_addr_mode(u8 rotate, bool mirror)
|
||||
static int taal_set_addr_mode(struct taal_data *td, u8 rotate, bool mirror)
|
||||
{
|
||||
int r;
|
||||
u8 mode;
|
||||
int b5, b6, b7;
|
||||
|
||||
r = taal_dcs_read_1(DCS_READ_MADCTL, &mode);
|
||||
r = taal_dcs_read_1(td, DCS_READ_MADCTL, &mode);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
@ -381,10 +383,11 @@ static int taal_set_addr_mode(u8 rotate, bool mirror)
|
||||
mode &= ~((1<<7) | (1<<6) | (1<<5));
|
||||
mode |= (b7 << 7) | (b6 << 6) | (b5 << 5);
|
||||
|
||||
return taal_dcs_write_1(DCS_MEM_ACC_CTRL, mode);
|
||||
return taal_dcs_write_1(td, DCS_MEM_ACC_CTRL, mode);
|
||||
}
|
||||
|
||||
static int taal_set_update_window(u16 x, u16 y, u16 w, u16 h)
|
||||
static int taal_set_update_window(struct taal_data *td,
|
||||
u16 x, u16 y, u16 w, u16 h)
|
||||
{
|
||||
int r;
|
||||
u16 x1 = x;
|
||||
@ -399,7 +402,7 @@ static int taal_set_update_window(u16 x, u16 y, u16 w, u16 h)
|
||||
buf[3] = (x2 >> 8) & 0xff;
|
||||
buf[4] = (x2 >> 0) & 0xff;
|
||||
|
||||
r = dsi_vc_dcs_write_nosync(TCH, buf, sizeof(buf));
|
||||
r = dsi_vc_dcs_write_nosync(td->channel, buf, sizeof(buf));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
@ -409,11 +412,11 @@ static int taal_set_update_window(u16 x, u16 y, u16 w, u16 h)
|
||||
buf[3] = (y2 >> 8) & 0xff;
|
||||
buf[4] = (y2 >> 0) & 0xff;
|
||||
|
||||
r = dsi_vc_dcs_write_nosync(TCH, buf, sizeof(buf));
|
||||
r = dsi_vc_dcs_write_nosync(td->channel, buf, sizeof(buf));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
dsi_vc_send_bta_sync(TCH);
|
||||
dsi_vc_send_bta_sync(td->channel);
|
||||
|
||||
return r;
|
||||
}
|
||||
@ -439,7 +442,7 @@ static int taal_bl_update_status(struct backlight_device *dev)
|
||||
if (td->use_dsi_bl) {
|
||||
if (td->enabled) {
|
||||
dsi_bus_lock();
|
||||
r = taal_dcs_write_1(DCS_BRIGHTNESS, level);
|
||||
r = taal_dcs_write_1(td, DCS_BRIGHTNESS, level);
|
||||
dsi_bus_unlock();
|
||||
} else {
|
||||
r = 0;
|
||||
@ -502,7 +505,7 @@ static ssize_t taal_num_errors_show(struct device *dev,
|
||||
|
||||
if (td->enabled) {
|
||||
dsi_bus_lock();
|
||||
r = taal_dcs_read_1(DCS_READ_NUM_ERRORS, &errors);
|
||||
r = taal_dcs_read_1(td, DCS_READ_NUM_ERRORS, &errors);
|
||||
dsi_bus_unlock();
|
||||
} else {
|
||||
r = -ENODEV;
|
||||
@ -528,7 +531,7 @@ static ssize_t taal_hw_revision_show(struct device *dev,
|
||||
|
||||
if (td->enabled) {
|
||||
dsi_bus_lock();
|
||||
r = taal_get_id(&id1, &id2, &id3);
|
||||
r = taal_get_id(td, &id1, &id2, &id3);
|
||||
dsi_bus_unlock();
|
||||
} else {
|
||||
r = -ENODEV;
|
||||
@ -590,7 +593,7 @@ static ssize_t store_cabc_mode(struct device *dev,
|
||||
if (td->enabled) {
|
||||
dsi_bus_lock();
|
||||
if (!td->cabc_broken)
|
||||
taal_dcs_write_1(DCS_WRITE_CABC, i);
|
||||
taal_dcs_write_1(td, DCS_WRITE_CABC, i);
|
||||
dsi_bus_unlock();
|
||||
}
|
||||
|
||||
@ -776,14 +779,29 @@ static int taal_probe(struct omap_dss_device *dssdev)
|
||||
dev_dbg(&dssdev->dev, "Using GPIO TE\n");
|
||||
}
|
||||
|
||||
r = omap_dsi_request_vc(dssdev, &td->channel);
|
||||
if (r) {
|
||||
dev_err(&dssdev->dev, "failed to get virtual channel\n");
|
||||
goto err_req_vc;
|
||||
}
|
||||
|
||||
r = omap_dsi_set_vc_id(dssdev, td->channel, TCH);
|
||||
if (r) {
|
||||
dev_err(&dssdev->dev, "failed to set VC_ID\n");
|
||||
goto err_vc_id;
|
||||
}
|
||||
|
||||
r = sysfs_create_group(&dssdev->dev.kobj, &taal_attr_group);
|
||||
if (r) {
|
||||
dev_err(&dssdev->dev, "failed to create sysfs files\n");
|
||||
goto err_sysfs;
|
||||
goto err_vc_id;
|
||||
}
|
||||
|
||||
return 0;
|
||||
err_sysfs:
|
||||
|
||||
err_vc_id:
|
||||
omap_dsi_release_vc(dssdev, td->channel);
|
||||
err_req_vc:
|
||||
if (panel_data->use_ext_te)
|
||||
free_irq(gpio_to_irq(panel_data->ext_te_gpio), dssdev);
|
||||
err_irq:
|
||||
@ -810,6 +828,7 @@ static void taal_remove(struct omap_dss_device *dssdev)
|
||||
dev_dbg(&dssdev->dev, "remove\n");
|
||||
|
||||
sysfs_remove_group(&dssdev->dev.kobj, &taal_attr_group);
|
||||
omap_dsi_release_vc(dssdev, td->channel);
|
||||
|
||||
if (panel_data->use_ext_te) {
|
||||
int gpio = panel_data->ext_te_gpio;
|
||||
@ -848,13 +867,13 @@ static int taal_power_on(struct omap_dss_device *dssdev)
|
||||
|
||||
taal_hw_reset(dssdev);
|
||||
|
||||
omapdss_dsi_vc_enable_hs(TCH, false);
|
||||
omapdss_dsi_vc_enable_hs(td->channel, false);
|
||||
|
||||
r = taal_sleep_out(td);
|
||||
if (r)
|
||||
goto err;
|
||||
|
||||
r = taal_get_id(&id1, &id2, &id3);
|
||||
r = taal_get_id(td, &id1, &id2, &id3);
|
||||
if (r)
|
||||
goto err;
|
||||
|
||||
@ -863,30 +882,30 @@ static int taal_power_on(struct omap_dss_device *dssdev)
|
||||
(id2 == 0x00 || id2 == 0xff || id2 == 0x81))
|
||||
td->cabc_broken = true;
|
||||
|
||||
r = taal_dcs_write_1(DCS_BRIGHTNESS, 0xff);
|
||||
r = taal_dcs_write_1(td, DCS_BRIGHTNESS, 0xff);
|
||||
if (r)
|
||||
goto err;
|
||||
|
||||
r = taal_dcs_write_1(DCS_CTRL_DISPLAY,
|
||||
r = taal_dcs_write_1(td, DCS_CTRL_DISPLAY,
|
||||
(1<<2) | (1<<5)); /* BL | BCTRL */
|
||||
if (r)
|
||||
goto err;
|
||||
|
||||
r = taal_dcs_write_1(DCS_PIXEL_FORMAT, 0x7); /* 24bit/pixel */
|
||||
r = taal_dcs_write_1(td, DCS_PIXEL_FORMAT, 0x7); /* 24bit/pixel */
|
||||
if (r)
|
||||
goto err;
|
||||
|
||||
r = taal_set_addr_mode(td->rotate, td->mirror);
|
||||
r = taal_set_addr_mode(td, td->rotate, td->mirror);
|
||||
if (r)
|
||||
goto err;
|
||||
|
||||
if (!td->cabc_broken) {
|
||||
r = taal_dcs_write_1(DCS_WRITE_CABC, td->cabc_mode);
|
||||
r = taal_dcs_write_1(td, DCS_WRITE_CABC, td->cabc_mode);
|
||||
if (r)
|
||||
goto err;
|
||||
}
|
||||
|
||||
r = taal_dcs_write_0(DCS_DISPLAY_ON);
|
||||
r = taal_dcs_write_0(td, DCS_DISPLAY_ON);
|
||||
if (r)
|
||||
goto err;
|
||||
|
||||
@ -905,7 +924,7 @@ static int taal_power_on(struct omap_dss_device *dssdev)
|
||||
td->intro_printed = true;
|
||||
}
|
||||
|
||||
omapdss_dsi_vc_enable_hs(TCH, true);
|
||||
omapdss_dsi_vc_enable_hs(td->channel, true);
|
||||
|
||||
return 0;
|
||||
err:
|
||||
@ -923,7 +942,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(DCS_DISPLAY_OFF);
|
||||
r = taal_dcs_write_0(td, DCS_DISPLAY_OFF);
|
||||
if (!r) {
|
||||
r = taal_sleep_in(td);
|
||||
/* HACK: wait a bit so that the message goes through */
|
||||
@ -1091,7 +1110,7 @@ static irqreturn_t taal_te_isr(int irq, void *data)
|
||||
if (old) {
|
||||
cancel_delayed_work(&td->te_timeout_work);
|
||||
|
||||
r = omap_dsi_update(dssdev, TCH,
|
||||
r = omap_dsi_update(dssdev, td->channel,
|
||||
td->update_region.x,
|
||||
td->update_region.y,
|
||||
td->update_region.w,
|
||||
@ -1141,7 +1160,7 @@ static int taal_update(struct omap_dss_device *dssdev,
|
||||
if (r)
|
||||
goto err;
|
||||
|
||||
r = taal_set_update_window(x, y, w, h);
|
||||
r = taal_set_update_window(td, x, y, w, h);
|
||||
if (r)
|
||||
goto err;
|
||||
|
||||
@ -1155,7 +1174,7 @@ static int taal_update(struct omap_dss_device *dssdev,
|
||||
msecs_to_jiffies(250));
|
||||
atomic_set(&td->do_update, 1);
|
||||
} else {
|
||||
r = omap_dsi_update(dssdev, TCH, x, y, w, h,
|
||||
r = omap_dsi_update(dssdev, td->channel, x, y, w, h,
|
||||
taal_framedone_cb, dssdev);
|
||||
if (r)
|
||||
goto err;
|
||||
@ -1193,9 +1212,9 @@ static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable)
|
||||
int r;
|
||||
|
||||
if (enable)
|
||||
r = taal_dcs_write_1(DCS_TEAR_ON, 0);
|
||||
r = taal_dcs_write_1(td, DCS_TEAR_ON, 0);
|
||||
else
|
||||
r = taal_dcs_write_0(DCS_TEAR_OFF);
|
||||
r = taal_dcs_write_0(td, DCS_TEAR_OFF);
|
||||
|
||||
if (!panel_data->use_ext_te)
|
||||
omapdss_dsi_enable_te(dssdev, enable);
|
||||
@ -1265,7 +1284,7 @@ static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate)
|
||||
dsi_bus_lock();
|
||||
|
||||
if (td->enabled) {
|
||||
r = taal_set_addr_mode(rotate, td->mirror);
|
||||
r = taal_set_addr_mode(td, rotate, td->mirror);
|
||||
if (r)
|
||||
goto err;
|
||||
}
|
||||
@ -1308,7 +1327,7 @@ static int taal_mirror(struct omap_dss_device *dssdev, bool enable)
|
||||
|
||||
dsi_bus_lock();
|
||||
if (td->enabled) {
|
||||
r = taal_set_addr_mode(td->rotate, enable);
|
||||
r = taal_set_addr_mode(td, td->rotate, enable);
|
||||
if (r)
|
||||
goto err;
|
||||
}
|
||||
@ -1352,13 +1371,13 @@ static int taal_run_test(struct omap_dss_device *dssdev, int test_num)
|
||||
|
||||
dsi_bus_lock();
|
||||
|
||||
r = taal_dcs_read_1(DCS_GET_ID1, &id1);
|
||||
r = taal_dcs_read_1(td, DCS_GET_ID1, &id1);
|
||||
if (r)
|
||||
goto err2;
|
||||
r = taal_dcs_read_1(DCS_GET_ID2, &id2);
|
||||
r = taal_dcs_read_1(td, DCS_GET_ID2, &id2);
|
||||
if (r)
|
||||
goto err2;
|
||||
r = taal_dcs_read_1(DCS_GET_ID3, &id3);
|
||||
r = taal_dcs_read_1(td, DCS_GET_ID3, &id3);
|
||||
if (r)
|
||||
goto err2;
|
||||
|
||||
@ -1406,9 +1425,9 @@ static int taal_memory_read(struct omap_dss_device *dssdev,
|
||||
else
|
||||
plen = 2;
|
||||
|
||||
taal_set_update_window(x, y, w, h);
|
||||
taal_set_update_window(td, x, y, w, h);
|
||||
|
||||
r = dsi_vc_set_max_rx_packet_size(TCH, plen);
|
||||
r = dsi_vc_set_max_rx_packet_size(td->channel, plen);
|
||||
if (r)
|
||||
goto err2;
|
||||
|
||||
@ -1416,7 +1435,7 @@ static int taal_memory_read(struct omap_dss_device *dssdev,
|
||||
u8 dcs_cmd = first ? 0x2e : 0x3e;
|
||||
first = 0;
|
||||
|
||||
r = dsi_vc_dcs_read(TCH, dcs_cmd,
|
||||
r = dsi_vc_dcs_read(td->channel, dcs_cmd,
|
||||
buf + buf_used, size - buf_used);
|
||||
|
||||
if (r < 0) {
|
||||
@ -1442,7 +1461,7 @@ static int taal_memory_read(struct omap_dss_device *dssdev,
|
||||
r = buf_used;
|
||||
|
||||
err3:
|
||||
dsi_vc_set_max_rx_packet_size(TCH, 1);
|
||||
dsi_vc_set_max_rx_packet_size(td->channel, 1);
|
||||
err2:
|
||||
dsi_bus_unlock();
|
||||
err1:
|
||||
@ -1468,7 +1487,7 @@ static void taal_esd_work(struct work_struct *work)
|
||||
|
||||
dsi_bus_lock();
|
||||
|
||||
r = taal_dcs_read_1(DCS_RDDSDR, &state1);
|
||||
r = taal_dcs_read_1(td, DCS_RDDSDR, &state1);
|
||||
if (r) {
|
||||
dev_err(&dssdev->dev, "failed to read Taal status\n");
|
||||
goto err;
|
||||
@ -1481,7 +1500,7 @@ static void taal_esd_work(struct work_struct *work)
|
||||
goto err;
|
||||
}
|
||||
|
||||
r = taal_dcs_read_1(DCS_RDDSDR, &state2);
|
||||
r = taal_dcs_read_1(td, DCS_RDDSDR, &state2);
|
||||
if (r) {
|
||||
dev_err(&dssdev->dev, "failed to read Taal status\n");
|
||||
goto err;
|
||||
@ -1497,7 +1516,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(DCS_TEAR_ON, 0);
|
||||
r = taal_dcs_write_1(td, DCS_TEAR_ON, 0);
|
||||
if (r)
|
||||
goto err;
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
menuconfig OMAP2_DSS
|
||||
tristate "OMAP2/3 Display Subsystem support (EXPERIMENTAL)"
|
||||
depends on ARCH_OMAP2 || ARCH_OMAP3
|
||||
tristate "OMAP2+ Display Subsystem support (EXPERIMENTAL)"
|
||||
depends on ARCH_OMAP2PLUS
|
||||
help
|
||||
OMAP2/3 Display Subsystem support.
|
||||
OMAP2+ Display Subsystem support.
|
||||
|
||||
if OMAP2_DSS
|
||||
|
||||
@ -60,6 +60,14 @@ config OMAP2_DSS_VENC
|
||||
help
|
||||
OMAP Video Encoder support for S-Video and composite TV-out.
|
||||
|
||||
config OMAP4_DSS_HDMI
|
||||
bool "HDMI support"
|
||||
depends on ARCH_OMAP4
|
||||
default y
|
||||
help
|
||||
HDMI Interface. This adds the High Definition Multimedia Interface.
|
||||
See http://www.hdmi.org/ for HDMI specification.
|
||||
|
||||
config OMAP2_DSS_SDI
|
||||
bool "SDI support"
|
||||
depends on ARCH_OMAP3
|
||||
|
@ -5,3 +5,5 @@ omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o
|
||||
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
|
||||
|
@ -34,332 +34,26 @@
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
||||
#include <plat/display.h>
|
||||
#include <plat/clock.h>
|
||||
|
||||
#include "dss.h"
|
||||
#include "dss_features.h"
|
||||
|
||||
static struct {
|
||||
struct platform_device *pdev;
|
||||
int ctx_id;
|
||||
|
||||
struct clk *dss_ick;
|
||||
struct clk *dss1_fck;
|
||||
struct clk *dss2_fck;
|
||||
struct clk *dss_54m_fck;
|
||||
struct clk *dss_96m_fck;
|
||||
unsigned num_clks_enabled;
|
||||
|
||||
struct regulator *vdds_dsi_reg;
|
||||
struct regulator *vdds_sdi_reg;
|
||||
struct regulator *vdda_dac_reg;
|
||||
} core;
|
||||
|
||||
static void dss_clk_enable_all_no_ctx(void);
|
||||
static void dss_clk_disable_all_no_ctx(void);
|
||||
static void dss_clk_enable_no_ctx(enum dss_clock clks);
|
||||
static void dss_clk_disable_no_ctx(enum dss_clock clks);
|
||||
|
||||
static char *def_disp_name;
|
||||
module_param_named(def_disp, def_disp_name, charp, 0);
|
||||
MODULE_PARM_DESC(def_disp_name, "default display name");
|
||||
MODULE_PARM_DESC(def_disp, "default display name");
|
||||
|
||||
#ifdef DEBUG
|
||||
unsigned int dss_debug;
|
||||
module_param_named(debug, dss_debug, bool, 0644);
|
||||
#endif
|
||||
|
||||
/* CONTEXT */
|
||||
static int dss_get_ctx_id(void)
|
||||
{
|
||||
struct omap_dss_board_info *pdata = core.pdev->dev.platform_data;
|
||||
int r;
|
||||
|
||||
if (!pdata->get_last_off_on_transaction_id)
|
||||
return 0;
|
||||
r = pdata->get_last_off_on_transaction_id(&core.pdev->dev);
|
||||
if (r < 0) {
|
||||
dev_err(&core.pdev->dev, "getting transaction ID failed, "
|
||||
"will force context restore\n");
|
||||
r = -1;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
int dss_need_ctx_restore(void)
|
||||
{
|
||||
int id = dss_get_ctx_id();
|
||||
|
||||
if (id < 0 || id != core.ctx_id) {
|
||||
DSSDBG("ctx id %d -> id %d\n",
|
||||
core.ctx_id, id);
|
||||
core.ctx_id = id;
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void save_all_ctx(void)
|
||||
{
|
||||
DSSDBG("save context\n");
|
||||
|
||||
dss_clk_enable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK1);
|
||||
|
||||
dss_save_context();
|
||||
dispc_save_context();
|
||||
#ifdef CONFIG_OMAP2_DSS_DSI
|
||||
dsi_save_context();
|
||||
#endif
|
||||
|
||||
dss_clk_disable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK1);
|
||||
}
|
||||
|
||||
static void restore_all_ctx(void)
|
||||
{
|
||||
DSSDBG("restore context\n");
|
||||
|
||||
dss_clk_enable_all_no_ctx();
|
||||
|
||||
dss_restore_context();
|
||||
dispc_restore_context();
|
||||
#ifdef CONFIG_OMAP2_DSS_DSI
|
||||
dsi_restore_context();
|
||||
#endif
|
||||
|
||||
dss_clk_disable_all_no_ctx();
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
|
||||
/* CLOCKS */
|
||||
static void core_dump_clocks(struct seq_file *s)
|
||||
{
|
||||
int i;
|
||||
struct clk *clocks[5] = {
|
||||
core.dss_ick,
|
||||
core.dss1_fck,
|
||||
core.dss2_fck,
|
||||
core.dss_54m_fck,
|
||||
core.dss_96m_fck
|
||||
};
|
||||
|
||||
seq_printf(s, "- CORE -\n");
|
||||
|
||||
seq_printf(s, "internal clk count\t\t%u\n", core.num_clks_enabled);
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
if (!clocks[i])
|
||||
continue;
|
||||
seq_printf(s, "%-15s\t%lu\t%d\n",
|
||||
clocks[i]->name,
|
||||
clk_get_rate(clocks[i]),
|
||||
clocks[i]->usecount);
|
||||
}
|
||||
}
|
||||
#endif /* defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) */
|
||||
|
||||
static int dss_get_clock(struct clk **clock, const char *clk_name)
|
||||
{
|
||||
struct clk *clk;
|
||||
|
||||
clk = clk_get(&core.pdev->dev, clk_name);
|
||||
|
||||
if (IS_ERR(clk)) {
|
||||
DSSERR("can't get clock %s", clk_name);
|
||||
return PTR_ERR(clk);
|
||||
}
|
||||
|
||||
*clock = clk;
|
||||
|
||||
DSSDBG("clk %s, rate %ld\n", clk_name, clk_get_rate(clk));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dss_get_clocks(void)
|
||||
{
|
||||
int r;
|
||||
|
||||
core.dss_ick = NULL;
|
||||
core.dss1_fck = NULL;
|
||||
core.dss2_fck = NULL;
|
||||
core.dss_54m_fck = NULL;
|
||||
core.dss_96m_fck = NULL;
|
||||
|
||||
r = dss_get_clock(&core.dss_ick, "ick");
|
||||
if (r)
|
||||
goto err;
|
||||
|
||||
r = dss_get_clock(&core.dss1_fck, "dss1_fck");
|
||||
if (r)
|
||||
goto err;
|
||||
|
||||
r = dss_get_clock(&core.dss2_fck, "dss2_fck");
|
||||
if (r)
|
||||
goto err;
|
||||
|
||||
r = dss_get_clock(&core.dss_54m_fck, "tv_fck");
|
||||
if (r)
|
||||
goto err;
|
||||
|
||||
r = dss_get_clock(&core.dss_96m_fck, "video_fck");
|
||||
if (r)
|
||||
goto err;
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
if (core.dss_ick)
|
||||
clk_put(core.dss_ick);
|
||||
if (core.dss1_fck)
|
||||
clk_put(core.dss1_fck);
|
||||
if (core.dss2_fck)
|
||||
clk_put(core.dss2_fck);
|
||||
if (core.dss_54m_fck)
|
||||
clk_put(core.dss_54m_fck);
|
||||
if (core.dss_96m_fck)
|
||||
clk_put(core.dss_96m_fck);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static void dss_put_clocks(void)
|
||||
{
|
||||
if (core.dss_96m_fck)
|
||||
clk_put(core.dss_96m_fck);
|
||||
clk_put(core.dss_54m_fck);
|
||||
clk_put(core.dss1_fck);
|
||||
clk_put(core.dss2_fck);
|
||||
clk_put(core.dss_ick);
|
||||
}
|
||||
|
||||
unsigned long dss_clk_get_rate(enum dss_clock clk)
|
||||
{
|
||||
switch (clk) {
|
||||
case DSS_CLK_ICK:
|
||||
return clk_get_rate(core.dss_ick);
|
||||
case DSS_CLK_FCK1:
|
||||
return clk_get_rate(core.dss1_fck);
|
||||
case DSS_CLK_FCK2:
|
||||
return clk_get_rate(core.dss2_fck);
|
||||
case DSS_CLK_54M:
|
||||
return clk_get_rate(core.dss_54m_fck);
|
||||
case DSS_CLK_96M:
|
||||
return clk_get_rate(core.dss_96m_fck);
|
||||
}
|
||||
|
||||
BUG();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned count_clk_bits(enum dss_clock clks)
|
||||
{
|
||||
unsigned num_clks = 0;
|
||||
|
||||
if (clks & DSS_CLK_ICK)
|
||||
++num_clks;
|
||||
if (clks & DSS_CLK_FCK1)
|
||||
++num_clks;
|
||||
if (clks & DSS_CLK_FCK2)
|
||||
++num_clks;
|
||||
if (clks & DSS_CLK_54M)
|
||||
++num_clks;
|
||||
if (clks & DSS_CLK_96M)
|
||||
++num_clks;
|
||||
|
||||
return num_clks;
|
||||
}
|
||||
|
||||
static void dss_clk_enable_no_ctx(enum dss_clock clks)
|
||||
{
|
||||
unsigned num_clks = count_clk_bits(clks);
|
||||
|
||||
if (clks & DSS_CLK_ICK)
|
||||
clk_enable(core.dss_ick);
|
||||
if (clks & DSS_CLK_FCK1)
|
||||
clk_enable(core.dss1_fck);
|
||||
if (clks & DSS_CLK_FCK2)
|
||||
clk_enable(core.dss2_fck);
|
||||
if (clks & DSS_CLK_54M)
|
||||
clk_enable(core.dss_54m_fck);
|
||||
if (clks & DSS_CLK_96M)
|
||||
clk_enable(core.dss_96m_fck);
|
||||
|
||||
core.num_clks_enabled += num_clks;
|
||||
}
|
||||
|
||||
void dss_clk_enable(enum dss_clock clks)
|
||||
{
|
||||
bool check_ctx = core.num_clks_enabled == 0;
|
||||
|
||||
dss_clk_enable_no_ctx(clks);
|
||||
|
||||
if (check_ctx && cpu_is_omap34xx() && dss_need_ctx_restore())
|
||||
restore_all_ctx();
|
||||
}
|
||||
|
||||
static void dss_clk_disable_no_ctx(enum dss_clock clks)
|
||||
{
|
||||
unsigned num_clks = count_clk_bits(clks);
|
||||
|
||||
if (clks & DSS_CLK_ICK)
|
||||
clk_disable(core.dss_ick);
|
||||
if (clks & DSS_CLK_FCK1)
|
||||
clk_disable(core.dss1_fck);
|
||||
if (clks & DSS_CLK_FCK2)
|
||||
clk_disable(core.dss2_fck);
|
||||
if (clks & DSS_CLK_54M)
|
||||
clk_disable(core.dss_54m_fck);
|
||||
if (clks & DSS_CLK_96M)
|
||||
clk_disable(core.dss_96m_fck);
|
||||
|
||||
core.num_clks_enabled -= num_clks;
|
||||
}
|
||||
|
||||
void dss_clk_disable(enum dss_clock clks)
|
||||
{
|
||||
if (cpu_is_omap34xx()) {
|
||||
unsigned num_clks = count_clk_bits(clks);
|
||||
|
||||
BUG_ON(core.num_clks_enabled < num_clks);
|
||||
|
||||
if (core.num_clks_enabled == num_clks)
|
||||
save_all_ctx();
|
||||
}
|
||||
|
||||
dss_clk_disable_no_ctx(clks);
|
||||
}
|
||||
|
||||
static void dss_clk_enable_all_no_ctx(void)
|
||||
{
|
||||
enum dss_clock clks;
|
||||
|
||||
clks = DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M;
|
||||
if (cpu_is_omap34xx())
|
||||
clks |= DSS_CLK_96M;
|
||||
dss_clk_enable_no_ctx(clks);
|
||||
}
|
||||
|
||||
static void dss_clk_disable_all_no_ctx(void)
|
||||
{
|
||||
enum dss_clock clks;
|
||||
|
||||
clks = DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M;
|
||||
if (cpu_is_omap34xx())
|
||||
clks |= DSS_CLK_96M;
|
||||
dss_clk_disable_no_ctx(clks);
|
||||
}
|
||||
|
||||
static void dss_clk_disable_all(void)
|
||||
{
|
||||
enum dss_clock clks;
|
||||
|
||||
clks = DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M;
|
||||
if (cpu_is_omap34xx())
|
||||
clks |= DSS_CLK_96M;
|
||||
dss_clk_disable(clks);
|
||||
}
|
||||
|
||||
/* REGULATORS */
|
||||
|
||||
struct regulator *dss_get_vdds_dsi(void)
|
||||
@ -390,32 +84,7 @@ struct regulator *dss_get_vdds_sdi(void)
|
||||
return reg;
|
||||
}
|
||||
|
||||
struct regulator *dss_get_vdda_dac(void)
|
||||
{
|
||||
struct regulator *reg;
|
||||
|
||||
if (core.vdda_dac_reg != NULL)
|
||||
return core.vdda_dac_reg;
|
||||
|
||||
reg = regulator_get(&core.pdev->dev, "vdda_dac");
|
||||
if (!IS_ERR(reg))
|
||||
core.vdda_dac_reg = reg;
|
||||
|
||||
return reg;
|
||||
}
|
||||
|
||||
/* DEBUGFS */
|
||||
#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
|
||||
static void dss_debug_dump_clocks(struct seq_file *s)
|
||||
{
|
||||
core_dump_clocks(s);
|
||||
dss_dump_clocks(s);
|
||||
dispc_dump_clocks(s);
|
||||
#ifdef CONFIG_OMAP2_DSS_DSI
|
||||
dsi_dump_clocks(s);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int dss_debug_show(struct seq_file *s, void *unused)
|
||||
{
|
||||
void (*func)(struct seq_file *) = s->private;
|
||||
@ -497,7 +166,6 @@ static inline void dss_uninitialize_debugfs(void)
|
||||
static int omap_dss_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct omap_dss_board_info *pdata = pdev->dev.platform_data;
|
||||
int skip_init = 0;
|
||||
int r;
|
||||
int i;
|
||||
|
||||
@ -508,63 +176,43 @@ static int omap_dss_probe(struct platform_device *pdev)
|
||||
dss_init_overlay_managers(pdev);
|
||||
dss_init_overlays(pdev);
|
||||
|
||||
r = dss_get_clocks();
|
||||
if (r)
|
||||
goto err_clocks;
|
||||
|
||||
dss_clk_enable_all_no_ctx();
|
||||
|
||||
core.ctx_id = dss_get_ctx_id();
|
||||
DSSDBG("initial ctx id %u\n", core.ctx_id);
|
||||
|
||||
#ifdef CONFIG_FB_OMAP_BOOTLOADER_INIT
|
||||
/* DISPC_CONTROL */
|
||||
if (omap_readl(0x48050440) & 1) /* LCD enabled? */
|
||||
skip_init = 1;
|
||||
#endif
|
||||
|
||||
r = dss_init(skip_init);
|
||||
r = dss_init_platform_driver();
|
||||
if (r) {
|
||||
DSSERR("Failed to initialize DSS\n");
|
||||
DSSERR("Failed to initialize DSS platform driver\n");
|
||||
goto err_dss;
|
||||
}
|
||||
|
||||
r = rfbi_init();
|
||||
/* keep clocks enabled to prevent context saves/restores during init */
|
||||
dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
|
||||
|
||||
r = rfbi_init_platform_driver();
|
||||
if (r) {
|
||||
DSSERR("Failed to initialize rfbi\n");
|
||||
DSSERR("Failed to initialize rfbi platform driver\n");
|
||||
goto err_rfbi;
|
||||
}
|
||||
|
||||
r = dpi_init(pdev);
|
||||
r = dispc_init_platform_driver();
|
||||
if (r) {
|
||||
DSSERR("Failed to initialize dpi\n");
|
||||
goto err_dpi;
|
||||
}
|
||||
|
||||
r = dispc_init();
|
||||
if (r) {
|
||||
DSSERR("Failed to initialize dispc\n");
|
||||
DSSERR("Failed to initialize dispc platform driver\n");
|
||||
goto err_dispc;
|
||||
}
|
||||
|
||||
r = venc_init(pdev);
|
||||
r = venc_init_platform_driver();
|
||||
if (r) {
|
||||
DSSERR("Failed to initialize venc\n");
|
||||
DSSERR("Failed to initialize venc platform driver\n");
|
||||
goto err_venc;
|
||||
}
|
||||
|
||||
if (cpu_is_omap34xx()) {
|
||||
r = sdi_init(skip_init);
|
||||
if (r) {
|
||||
DSSERR("Failed to initialize SDI\n");
|
||||
goto err_sdi;
|
||||
}
|
||||
r = dsi_init_platform_driver();
|
||||
if (r) {
|
||||
DSSERR("Failed to initialize DSI platform driver\n");
|
||||
goto err_dsi;
|
||||
}
|
||||
|
||||
r = dsi_init(pdev);
|
||||
if (r) {
|
||||
DSSERR("Failed to initialize DSI\n");
|
||||
goto err_dsi;
|
||||
}
|
||||
r = hdmi_init_platform_driver();
|
||||
if (r) {
|
||||
DSSERR("Failed to initialize hdmi\n");
|
||||
goto err_hdmi;
|
||||
}
|
||||
|
||||
r = dss_initialize_debugfs();
|
||||
@ -589,32 +237,25 @@ static int omap_dss_probe(struct platform_device *pdev)
|
||||
pdata->default_device = dssdev;
|
||||
}
|
||||
|
||||
dss_clk_disable_all();
|
||||
dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
|
||||
|
||||
return 0;
|
||||
|
||||
err_register:
|
||||
dss_uninitialize_debugfs();
|
||||
err_debugfs:
|
||||
if (cpu_is_omap34xx())
|
||||
dsi_exit();
|
||||
hdmi_uninit_platform_driver();
|
||||
err_hdmi:
|
||||
dsi_uninit_platform_driver();
|
||||
err_dsi:
|
||||
if (cpu_is_omap34xx())
|
||||
sdi_exit();
|
||||
err_sdi:
|
||||
venc_exit();
|
||||
venc_uninit_platform_driver();
|
||||
err_venc:
|
||||
dispc_exit();
|
||||
dispc_uninit_platform_driver();
|
||||
err_dispc:
|
||||
dpi_exit();
|
||||
err_dpi:
|
||||
rfbi_exit();
|
||||
rfbi_uninit_platform_driver();
|
||||
err_rfbi:
|
||||
dss_exit();
|
||||
dss_uninit_platform_driver();
|
||||
err_dss:
|
||||
dss_clk_disable_all_no_ctx();
|
||||
dss_put_clocks();
|
||||
err_clocks:
|
||||
|
||||
return r;
|
||||
}
|
||||
@ -623,61 +264,15 @@ static int omap_dss_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct omap_dss_board_info *pdata = pdev->dev.platform_data;
|
||||
int i;
|
||||
int c;
|
||||
|
||||
dss_uninitialize_debugfs();
|
||||
|
||||
venc_exit();
|
||||
dispc_exit();
|
||||
dpi_exit();
|
||||
rfbi_exit();
|
||||
if (cpu_is_omap34xx()) {
|
||||
dsi_exit();
|
||||
sdi_exit();
|
||||
}
|
||||
|
||||
dss_exit();
|
||||
|
||||
/* these should be removed at some point */
|
||||
c = core.dss_ick->usecount;
|
||||
if (c > 0) {
|
||||
DSSERR("warning: dss_ick usecount %d, disabling\n", c);
|
||||
while (c-- > 0)
|
||||
clk_disable(core.dss_ick);
|
||||
}
|
||||
|
||||
c = core.dss1_fck->usecount;
|
||||
if (c > 0) {
|
||||
DSSERR("warning: dss1_fck usecount %d, disabling\n", c);
|
||||
while (c-- > 0)
|
||||
clk_disable(core.dss1_fck);
|
||||
}
|
||||
|
||||
c = core.dss2_fck->usecount;
|
||||
if (c > 0) {
|
||||
DSSERR("warning: dss2_fck usecount %d, disabling\n", c);
|
||||
while (c-- > 0)
|
||||
clk_disable(core.dss2_fck);
|
||||
}
|
||||
|
||||
c = core.dss_54m_fck->usecount;
|
||||
if (c > 0) {
|
||||
DSSERR("warning: dss_54m_fck usecount %d, disabling\n", c);
|
||||
while (c-- > 0)
|
||||
clk_disable(core.dss_54m_fck);
|
||||
}
|
||||
|
||||
if (core.dss_96m_fck) {
|
||||
c = core.dss_96m_fck->usecount;
|
||||
if (c > 0) {
|
||||
DSSERR("warning: dss_96m_fck usecount %d, disabling\n",
|
||||
c);
|
||||
while (c-- > 0)
|
||||
clk_disable(core.dss_96m_fck);
|
||||
}
|
||||
}
|
||||
|
||||
dss_put_clocks();
|
||||
venc_uninit_platform_driver();
|
||||
dispc_uninit_platform_driver();
|
||||
rfbi_uninit_platform_driver();
|
||||
dsi_uninit_platform_driver();
|
||||
hdmi_uninit_platform_driver();
|
||||
dss_uninit_platform_driver();
|
||||
|
||||
dss_uninit_overlays(pdev);
|
||||
dss_uninit_overlay_managers(pdev);
|
||||
@ -965,11 +560,6 @@ static void __exit omap_dss_exit(void)
|
||||
core.vdds_sdi_reg = NULL;
|
||||
}
|
||||
|
||||
if (core.vdda_dac_reg != NULL) {
|
||||
regulator_put(core.vdda_dac_reg);
|
||||
core.vdda_dac_reg = NULL;
|
||||
}
|
||||
|
||||
platform_driver_unregister(&omap_dss_driver);
|
||||
|
||||
omap_dss_bus_unregister();
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/hardirq.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include <plat/sram.h>
|
||||
#include <plat/clock.h>
|
||||
@ -42,8 +43,6 @@
|
||||
#include "dss_features.h"
|
||||
|
||||
/* DISPC */
|
||||
#define DISPC_BASE 0x48050400
|
||||
|
||||
#define DISPC_SZ_REGS SZ_4K
|
||||
|
||||
struct dispc_reg { u16 idx; };
|
||||
@ -74,7 +73,7 @@ struct dispc_reg { u16 idx; };
|
||||
#define DISPC_TIMING_H(ch) DISPC_REG(ch != 2 ? 0x0064 : 0x0400)
|
||||
#define DISPC_TIMING_V(ch) DISPC_REG(ch != 2 ? 0x0068 : 0x0404)
|
||||
#define DISPC_POL_FREQ(ch) DISPC_REG(ch != 2 ? 0x006C : 0x0408)
|
||||
#define DISPC_DIVISOR(ch) DISPC_REG(ch != 2 ? 0x0070 : 0x040C)
|
||||
#define DISPC_DIVISORo(ch) DISPC_REG(ch != 2 ? 0x0070 : 0x040C)
|
||||
#define DISPC_GLOBAL_ALPHA DISPC_REG(0x0074)
|
||||
#define DISPC_SIZE_DIG DISPC_REG(0x0078)
|
||||
#define DISPC_SIZE_LCD(ch) DISPC_REG(ch != 2 ? 0x007C : 0x03CC)
|
||||
@ -129,6 +128,7 @@ struct dispc_reg { u16 idx; };
|
||||
|
||||
#define DISPC_VID_PRELOAD(n) DISPC_REG(0x230 + (n)*0x04)
|
||||
|
||||
#define DISPC_DIVISOR DISPC_REG(0x0804)
|
||||
|
||||
#define DISPC_IRQ_MASK_ERROR (DISPC_IRQ_GFX_FIFO_UNDERFLOW | \
|
||||
DISPC_IRQ_OCP_ERR | \
|
||||
@ -178,7 +178,9 @@ struct dispc_irq_stats {
|
||||
};
|
||||
|
||||
static struct {
|
||||
struct platform_device *pdev;
|
||||
void __iomem *base;
|
||||
int irq;
|
||||
|
||||
u32 fifo_size[3];
|
||||
|
||||
@ -230,7 +232,7 @@ void dispc_save_context(void)
|
||||
SR(TIMING_H(0));
|
||||
SR(TIMING_V(0));
|
||||
SR(POL_FREQ(0));
|
||||
SR(DIVISOR(0));
|
||||
SR(DIVISORo(0));
|
||||
SR(GLOBAL_ALPHA);
|
||||
SR(SIZE_DIG);
|
||||
SR(SIZE_LCD(0));
|
||||
@ -242,7 +244,7 @@ void dispc_save_context(void)
|
||||
SR(TIMING_H(2));
|
||||
SR(TIMING_V(2));
|
||||
SR(POL_FREQ(2));
|
||||
SR(DIVISOR(2));
|
||||
SR(DIVISORo(2));
|
||||
SR(CONFIG2);
|
||||
}
|
||||
|
||||
@ -373,6 +375,9 @@ void dispc_save_context(void)
|
||||
SR(VID_FIR_COEF_V(1, 7));
|
||||
|
||||
SR(VID_PRELOAD(1));
|
||||
|
||||
if (dss_has_feature(FEAT_CORE_CLK_DIV))
|
||||
SR(DIVISOR);
|
||||
}
|
||||
|
||||
void dispc_restore_context(void)
|
||||
@ -389,7 +394,7 @@ void dispc_restore_context(void)
|
||||
RR(TIMING_H(0));
|
||||
RR(TIMING_V(0));
|
||||
RR(POL_FREQ(0));
|
||||
RR(DIVISOR(0));
|
||||
RR(DIVISORo(0));
|
||||
RR(GLOBAL_ALPHA);
|
||||
RR(SIZE_DIG);
|
||||
RR(SIZE_LCD(0));
|
||||
@ -400,7 +405,7 @@ void dispc_restore_context(void)
|
||||
RR(TIMING_H(2));
|
||||
RR(TIMING_V(2));
|
||||
RR(POL_FREQ(2));
|
||||
RR(DIVISOR(2));
|
||||
RR(DIVISORo(2));
|
||||
RR(CONFIG2);
|
||||
}
|
||||
|
||||
@ -532,6 +537,9 @@ void dispc_restore_context(void)
|
||||
|
||||
RR(VID_PRELOAD(1));
|
||||
|
||||
if (dss_has_feature(FEAT_CORE_CLK_DIV))
|
||||
RR(DIVISOR);
|
||||
|
||||
/* enable last, because LCD & DIGIT enable are here */
|
||||
RR(CONTROL);
|
||||
if (dss_has_feature(FEAT_MGR_LCD2))
|
||||
@ -552,9 +560,9 @@ void dispc_restore_context(void)
|
||||
static inline void enable_clocks(bool enable)
|
||||
{
|
||||
if (enable)
|
||||
dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
|
||||
dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
|
||||
else
|
||||
dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
|
||||
dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
|
||||
}
|
||||
|
||||
bool dispc_go_busy(enum omap_channel channel)
|
||||
@ -1000,6 +1008,20 @@ void dispc_set_burst_size(enum omap_plane plane,
|
||||
enable_clocks(0);
|
||||
}
|
||||
|
||||
void dispc_enable_gamma_table(bool enable)
|
||||
{
|
||||
/*
|
||||
* This is partially implemented to support only disabling of
|
||||
* the gamma table.
|
||||
*/
|
||||
if (enable) {
|
||||
DSSWARN("Gamma table enabling for TV not yet supported");
|
||||
return;
|
||||
}
|
||||
|
||||
REG_FLD_MOD(DISPC_CONFIG, enable, 9, 9);
|
||||
}
|
||||
|
||||
static void _dispc_set_vid_color_conv(enum omap_plane plane, bool enable)
|
||||
{
|
||||
u32 val;
|
||||
@ -1129,10 +1151,16 @@ static void _dispc_set_vid_accu0(enum omap_plane plane, int haccu, int vaccu)
|
||||
u32 val;
|
||||
const struct dispc_reg ac0_reg[] = { DISPC_VID_ACCU0(0),
|
||||
DISPC_VID_ACCU0(1) };
|
||||
u8 hor_start, hor_end, vert_start, vert_end;
|
||||
|
||||
BUG_ON(plane == OMAP_DSS_GFX);
|
||||
|
||||
val = FLD_VAL(vaccu, 25, 16) | FLD_VAL(haccu, 9, 0);
|
||||
dss_feat_get_reg_field(FEAT_REG_HORIZONTALACCU, &hor_start, &hor_end);
|
||||
dss_feat_get_reg_field(FEAT_REG_VERTICALACCU, &vert_start, &vert_end);
|
||||
|
||||
val = FLD_VAL(vaccu, vert_start, vert_end) |
|
||||
FLD_VAL(haccu, hor_start, hor_end);
|
||||
|
||||
dispc_write_reg(ac0_reg[plane-1], val);
|
||||
}
|
||||
|
||||
@ -1141,10 +1169,16 @@ static void _dispc_set_vid_accu1(enum omap_plane plane, int haccu, int vaccu)
|
||||
u32 val;
|
||||
const struct dispc_reg ac1_reg[] = { DISPC_VID_ACCU1(0),
|
||||
DISPC_VID_ACCU1(1) };
|
||||
u8 hor_start, hor_end, vert_start, vert_end;
|
||||
|
||||
BUG_ON(plane == OMAP_DSS_GFX);
|
||||
|
||||
val = FLD_VAL(vaccu, 25, 16) | FLD_VAL(haccu, 9, 0);
|
||||
dss_feat_get_reg_field(FEAT_REG_HORIZONTALACCU, &hor_start, &hor_end);
|
||||
dss_feat_get_reg_field(FEAT_REG_VERTICALACCU, &vert_start, &vert_end);
|
||||
|
||||
val = FLD_VAL(vaccu, vert_start, vert_end) |
|
||||
FLD_VAL(haccu, hor_start, hor_end);
|
||||
|
||||
dispc_write_reg(ac1_reg[plane-1], val);
|
||||
}
|
||||
|
||||
@ -1182,16 +1216,25 @@ static void _dispc_set_scaling(enum omap_plane plane,
|
||||
_dispc_set_fir(plane, fir_hinc, fir_vinc);
|
||||
|
||||
l = dispc_read_reg(dispc_reg_att[plane]);
|
||||
l &= ~((0x0f << 5) | (0x3 << 21));
|
||||
|
||||
/* RESIZEENABLE and VERTICALTAPS */
|
||||
l &= ~((0x3 << 5) | (0x1 << 21));
|
||||
l |= fir_hinc ? (1 << 5) : 0;
|
||||
l |= fir_vinc ? (1 << 6) : 0;
|
||||
|
||||
l |= hscaleup ? 0 : (1 << 7);
|
||||
l |= vscaleup ? 0 : (1 << 8);
|
||||
|
||||
l |= five_taps ? (1 << 21) : 0;
|
||||
l |= five_taps ? (1 << 22) : 0;
|
||||
|
||||
/* VRESIZECONF and HRESIZECONF */
|
||||
if (dss_has_feature(FEAT_RESIZECONF)) {
|
||||
l &= ~(0x3 << 7);
|
||||
l |= hscaleup ? 0 : (1 << 7);
|
||||
l |= vscaleup ? 0 : (1 << 8);
|
||||
}
|
||||
|
||||
/* LINEBUFFERSPLIT */
|
||||
if (dss_has_feature(FEAT_LINEBUFFERSPLIT)) {
|
||||
l &= ~(0x1 << 22);
|
||||
l |= five_taps ? (1 << 22) : 0;
|
||||
}
|
||||
|
||||
dispc_write_reg(dispc_reg_att[plane], l);
|
||||
|
||||
@ -1215,9 +1258,11 @@ static void _dispc_set_scaling(enum omap_plane plane,
|
||||
static void _dispc_set_rotation_attrs(enum omap_plane plane, u8 rotation,
|
||||
bool mirroring, enum omap_color_mode color_mode)
|
||||
{
|
||||
bool row_repeat = false;
|
||||
int vidrot = 0;
|
||||
|
||||
if (color_mode == OMAP_DSS_COLOR_YUV2 ||
|
||||
color_mode == OMAP_DSS_COLOR_UYVY) {
|
||||
int vidrot = 0;
|
||||
|
||||
if (mirroring) {
|
||||
switch (rotation) {
|
||||
@ -1251,16 +1296,15 @@ static void _dispc_set_rotation_attrs(enum omap_plane plane, u8 rotation,
|
||||
}
|
||||
}
|
||||
|
||||
REG_FLD_MOD(dispc_reg_att[plane], vidrot, 13, 12);
|
||||
|
||||
if (rotation == OMAP_DSS_ROT_90 || rotation == OMAP_DSS_ROT_270)
|
||||
REG_FLD_MOD(dispc_reg_att[plane], 0x1, 18, 18);
|
||||
row_repeat = true;
|
||||
else
|
||||
REG_FLD_MOD(dispc_reg_att[plane], 0x0, 18, 18);
|
||||
} else {
|
||||
REG_FLD_MOD(dispc_reg_att[plane], 0, 13, 12);
|
||||
REG_FLD_MOD(dispc_reg_att[plane], 0, 18, 18);
|
||||
row_repeat = false;
|
||||
}
|
||||
|
||||
REG_FLD_MOD(dispc_reg_att[plane], vidrot, 13, 12);
|
||||
if (dss_has_feature(FEAT_ROWREPEATENABLE))
|
||||
REG_FLD_MOD(dispc_reg_att[plane], row_repeat ? 1 : 0, 18, 18);
|
||||
}
|
||||
|
||||
static int color_mode_to_bpp(enum omap_color_mode color_mode)
|
||||
@ -2293,7 +2337,7 @@ static void dispc_set_lcd_divisor(enum omap_channel channel, u16 lck_div,
|
||||
BUG_ON(pck_div < 2);
|
||||
|
||||
enable_clocks(1);
|
||||
dispc_write_reg(DISPC_DIVISOR(channel),
|
||||
dispc_write_reg(DISPC_DIVISORo(channel),
|
||||
FLD_VAL(lck_div, 23, 16) | FLD_VAL(pck_div, 7, 0));
|
||||
enable_clocks(0);
|
||||
}
|
||||
@ -2302,7 +2346,7 @@ static void dispc_get_lcd_divisor(enum omap_channel channel, int *lck_div,
|
||||
int *pck_div)
|
||||
{
|
||||
u32 l;
|
||||
l = dispc_read_reg(DISPC_DIVISOR(channel));
|
||||
l = dispc_read_reg(DISPC_DIVISORo(channel));
|
||||
*lck_div = FLD_GET(l, 23, 16);
|
||||
*pck_div = FLD_GET(l, 7, 0);
|
||||
}
|
||||
@ -2311,14 +2355,17 @@ unsigned long dispc_fclk_rate(void)
|
||||
{
|
||||
unsigned long r = 0;
|
||||
|
||||
if (dss_get_dispc_clk_source() == DSS_SRC_DSS1_ALWON_FCLK)
|
||||
r = dss_clk_get_rate(DSS_CLK_FCK1);
|
||||
else
|
||||
#ifdef CONFIG_OMAP2_DSS_DSI
|
||||
r = dsi_get_dsi1_pll_rate();
|
||||
#else
|
||||
BUG();
|
||||
#endif
|
||||
switch (dss_get_dispc_clk_source()) {
|
||||
case DSS_CLK_SRC_FCK:
|
||||
r = dss_clk_get_rate(DSS_CLK_FCK);
|
||||
break;
|
||||
case DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
|
||||
r = dsi_get_pll_hsdiv_dispc_rate();
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -2328,47 +2375,72 @@ unsigned long dispc_lclk_rate(enum omap_channel channel)
|
||||
unsigned long r;
|
||||
u32 l;
|
||||
|
||||
l = dispc_read_reg(DISPC_DIVISOR(channel));
|
||||
l = dispc_read_reg(DISPC_DIVISORo(channel));
|
||||
|
||||
lcd = FLD_GET(l, 23, 16);
|
||||
|
||||
r = dispc_fclk_rate();
|
||||
switch (dss_get_lcd_clk_source(channel)) {
|
||||
case DSS_CLK_SRC_FCK:
|
||||
r = dss_clk_get_rate(DSS_CLK_FCK);
|
||||
break;
|
||||
case DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
|
||||
r = dsi_get_pll_hsdiv_dispc_rate();
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
||||
return r / lcd;
|
||||
}
|
||||
|
||||
unsigned long dispc_pclk_rate(enum omap_channel channel)
|
||||
{
|
||||
int lcd, pcd;
|
||||
int pcd;
|
||||
unsigned long r;
|
||||
u32 l;
|
||||
|
||||
l = dispc_read_reg(DISPC_DIVISOR(channel));
|
||||
l = dispc_read_reg(DISPC_DIVISORo(channel));
|
||||
|
||||
lcd = FLD_GET(l, 23, 16);
|
||||
pcd = FLD_GET(l, 7, 0);
|
||||
|
||||
r = dispc_fclk_rate();
|
||||
r = dispc_lclk_rate(channel);
|
||||
|
||||
return r / lcd / pcd;
|
||||
return r / pcd;
|
||||
}
|
||||
|
||||
void dispc_dump_clocks(struct seq_file *s)
|
||||
{
|
||||
int lcd, pcd;
|
||||
u32 l;
|
||||
enum dss_clk_source dispc_clk_src = dss_get_dispc_clk_source();
|
||||
enum dss_clk_source lcd_clk_src;
|
||||
|
||||
enable_clocks(1);
|
||||
|
||||
seq_printf(s, "- DISPC -\n");
|
||||
|
||||
seq_printf(s, "dispc fclk source = %s\n",
|
||||
dss_get_dispc_clk_source() == DSS_SRC_DSS1_ALWON_FCLK ?
|
||||
"dss1_alwon_fclk" : "dsi1_pll_fclk");
|
||||
seq_printf(s, "dispc fclk source = %s (%s)\n",
|
||||
dss_get_generic_clk_source_name(dispc_clk_src),
|
||||
dss_feat_get_clk_source_name(dispc_clk_src));
|
||||
|
||||
seq_printf(s, "fck\t\t%-16lu\n", dispc_fclk_rate());
|
||||
|
||||
if (dss_has_feature(FEAT_CORE_CLK_DIV)) {
|
||||
seq_printf(s, "- DISPC-CORE-CLK -\n");
|
||||
l = dispc_read_reg(DISPC_DIVISOR);
|
||||
lcd = FLD_GET(l, 23, 16);
|
||||
|
||||
seq_printf(s, "lck\t\t%-16lulck div\t%u\n",
|
||||
(dispc_fclk_rate()/lcd), lcd);
|
||||
}
|
||||
seq_printf(s, "- LCD1 -\n");
|
||||
|
||||
lcd_clk_src = dss_get_lcd_clk_source(OMAP_DSS_CHANNEL_LCD);
|
||||
|
||||
seq_printf(s, "lcd1_clk source = %s (%s)\n",
|
||||
dss_get_generic_clk_source_name(lcd_clk_src),
|
||||
dss_feat_get_clk_source_name(lcd_clk_src));
|
||||
|
||||
dispc_get_lcd_divisor(OMAP_DSS_CHANNEL_LCD, &lcd, &pcd);
|
||||
|
||||
seq_printf(s, "lck\t\t%-16lulck div\t%u\n",
|
||||
@ -2378,6 +2450,12 @@ void dispc_dump_clocks(struct seq_file *s)
|
||||
if (dss_has_feature(FEAT_MGR_LCD2)) {
|
||||
seq_printf(s, "- LCD2 -\n");
|
||||
|
||||
lcd_clk_src = dss_get_lcd_clk_source(OMAP_DSS_CHANNEL_LCD2);
|
||||
|
||||
seq_printf(s, "lcd2_clk source = %s (%s)\n",
|
||||
dss_get_generic_clk_source_name(lcd_clk_src),
|
||||
dss_feat_get_clk_source_name(lcd_clk_src));
|
||||
|
||||
dispc_get_lcd_divisor(OMAP_DSS_CHANNEL_LCD2, &lcd, &pcd);
|
||||
|
||||
seq_printf(s, "lck\t\t%-16lulck div\t%u\n",
|
||||
@ -2440,7 +2518,7 @@ void dispc_dump_regs(struct seq_file *s)
|
||||
{
|
||||
#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dispc_read_reg(r))
|
||||
|
||||
dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
|
||||
dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
|
||||
|
||||
DUMPREG(DISPC_REVISION);
|
||||
DUMPREG(DISPC_SYSCONFIG);
|
||||
@ -2459,7 +2537,7 @@ void dispc_dump_regs(struct seq_file *s)
|
||||
DUMPREG(DISPC_TIMING_H(0));
|
||||
DUMPREG(DISPC_TIMING_V(0));
|
||||
DUMPREG(DISPC_POL_FREQ(0));
|
||||
DUMPREG(DISPC_DIVISOR(0));
|
||||
DUMPREG(DISPC_DIVISORo(0));
|
||||
DUMPREG(DISPC_GLOBAL_ALPHA);
|
||||
DUMPREG(DISPC_SIZE_DIG);
|
||||
DUMPREG(DISPC_SIZE_LCD(0));
|
||||
@ -2471,7 +2549,7 @@ void dispc_dump_regs(struct seq_file *s)
|
||||
DUMPREG(DISPC_TIMING_H(2));
|
||||
DUMPREG(DISPC_TIMING_V(2));
|
||||
DUMPREG(DISPC_POL_FREQ(2));
|
||||
DUMPREG(DISPC_DIVISOR(2));
|
||||
DUMPREG(DISPC_DIVISORo(2));
|
||||
DUMPREG(DISPC_SIZE_LCD(2));
|
||||
}
|
||||
|
||||
@ -2597,7 +2675,7 @@ void dispc_dump_regs(struct seq_file *s)
|
||||
DUMPREG(DISPC_VID_PRELOAD(0));
|
||||
DUMPREG(DISPC_VID_PRELOAD(1));
|
||||
|
||||
dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
|
||||
dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
|
||||
#undef DUMPREG
|
||||
}
|
||||
|
||||
@ -2713,8 +2791,8 @@ int dispc_get_clock_div(enum omap_channel channel,
|
||||
|
||||
fck = dispc_fclk_rate();
|
||||
|
||||
cinfo->lck_div = REG_GET(DISPC_DIVISOR(channel), 23, 16);
|
||||
cinfo->pck_div = REG_GET(DISPC_DIVISOR(channel), 7, 0);
|
||||
cinfo->lck_div = REG_GET(DISPC_DIVISORo(channel), 23, 16);
|
||||
cinfo->pck_div = REG_GET(DISPC_DIVISORo(channel), 7, 0);
|
||||
|
||||
cinfo->lck = fck / cinfo->lck_div;
|
||||
cinfo->pck = cinfo->lck / cinfo->pck_div;
|
||||
@ -2791,6 +2869,9 @@ int omap_dispc_register_isr(omap_dispc_isr_t isr, void *arg, u32 mask)
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
_omap_dispc_set_irqs();
|
||||
|
||||
spin_unlock_irqrestore(&dispc.irq_lock, flags);
|
||||
@ -2866,10 +2947,10 @@ static void print_irq_status(u32 status)
|
||||
* but we presume they are on because we got an IRQ. However,
|
||||
* an irq handler may turn the clocks off, so we may not have
|
||||
* clock later in the function. */
|
||||
void dispc_irq_handler(void)
|
||||
static irqreturn_t omap_dispc_irq_handler(int irq, void *arg)
|
||||
{
|
||||
int i;
|
||||
u32 irqstatus;
|
||||
u32 irqstatus, irqenable;
|
||||
u32 handledirqs = 0;
|
||||
u32 unhandled_errors;
|
||||
struct omap_dispc_isr_data *isr_data;
|
||||
@ -2878,6 +2959,13 @@ void dispc_irq_handler(void)
|
||||
spin_lock(&dispc.irq_lock);
|
||||
|
||||
irqstatus = dispc_read_reg(DISPC_IRQSTATUS);
|
||||
irqenable = dispc_read_reg(DISPC_IRQENABLE);
|
||||
|
||||
/* IRQ is not for us */
|
||||
if (!(irqstatus & irqenable)) {
|
||||
spin_unlock(&dispc.irq_lock);
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
|
||||
spin_lock(&dispc.irq_stats_lock);
|
||||
@ -2929,6 +3017,8 @@ void dispc_irq_handler(void)
|
||||
}
|
||||
|
||||
spin_unlock(&dispc.irq_lock);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static void dispc_error_worker(struct work_struct *work)
|
||||
@ -3253,6 +3343,15 @@ static void _omap_dispc_initial_config(void)
|
||||
l = FLD_MOD(l, 1, 0, 0); /* AUTOIDLE */
|
||||
dispc_write_reg(DISPC_SYSCONFIG, l);
|
||||
|
||||
/* Exclusively enable DISPC_CORE_CLK and set divider to 1 */
|
||||
if (dss_has_feature(FEAT_CORE_CLK_DIV)) {
|
||||
l = dispc_read_reg(DISPC_DIVISOR);
|
||||
/* Use DISPC_DIVISOR.LCD, instead of DISPC_DIVISOR1.LCD */
|
||||
l = FLD_MOD(l, 1, 0, 0);
|
||||
l = FLD_MOD(l, 1, 23, 16);
|
||||
dispc_write_reg(DISPC_DIVISOR, l);
|
||||
}
|
||||
|
||||
/* FUNCGATED */
|
||||
if (dss_has_feature(FEAT_FUNCGATED))
|
||||
REG_FLD_MOD(DISPC_CONFIG, 1, 9, 9);
|
||||
@ -3269,47 +3368,6 @@ static void _omap_dispc_initial_config(void)
|
||||
dispc_read_plane_fifo_sizes();
|
||||
}
|
||||
|
||||
int dispc_init(void)
|
||||
{
|
||||
u32 rev;
|
||||
|
||||
spin_lock_init(&dispc.irq_lock);
|
||||
|
||||
#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
|
||||
spin_lock_init(&dispc.irq_stats_lock);
|
||||
dispc.irq_stats.last_reset = jiffies;
|
||||
#endif
|
||||
|
||||
INIT_WORK(&dispc.error_work, dispc_error_worker);
|
||||
|
||||
dispc.base = ioremap(DISPC_BASE, DISPC_SZ_REGS);
|
||||
if (!dispc.base) {
|
||||
DSSERR("can't ioremap DISPC\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
enable_clocks(1);
|
||||
|
||||
_omap_dispc_initial_config();
|
||||
|
||||
_omap_dispc_initialize_irq();
|
||||
|
||||
dispc_save_context();
|
||||
|
||||
rev = dispc_read_reg(DISPC_REVISION);
|
||||
printk(KERN_INFO "OMAP DISPC rev %d.%d\n",
|
||||
FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
|
||||
|
||||
enable_clocks(0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void dispc_exit(void)
|
||||
{
|
||||
iounmap(dispc.base);
|
||||
}
|
||||
|
||||
int dispc_enable_plane(enum omap_plane plane, bool enable)
|
||||
{
|
||||
DSSDBG("dispc_enable_plane %d, %d\n", plane, enable);
|
||||
@ -3359,3 +3417,94 @@ int dispc_setup_plane(enum omap_plane plane,
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/* DISPC HW IP initialisation */
|
||||
static int omap_dispchw_probe(struct platform_device *pdev)
|
||||
{
|
||||
u32 rev;
|
||||
int r = 0;
|
||||
struct resource *dispc_mem;
|
||||
|
||||
dispc.pdev = pdev;
|
||||
|
||||
spin_lock_init(&dispc.irq_lock);
|
||||
|
||||
#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
|
||||
spin_lock_init(&dispc.irq_stats_lock);
|
||||
dispc.irq_stats.last_reset = jiffies;
|
||||
#endif
|
||||
|
||||
INIT_WORK(&dispc.error_work, dispc_error_worker);
|
||||
|
||||
dispc_mem = platform_get_resource(dispc.pdev, IORESOURCE_MEM, 0);
|
||||
if (!dispc_mem) {
|
||||
DSSERR("can't get IORESOURCE_MEM DISPC\n");
|
||||
r = -EINVAL;
|
||||
goto fail0;
|
||||
}
|
||||
dispc.base = ioremap(dispc_mem->start, resource_size(dispc_mem));
|
||||
if (!dispc.base) {
|
||||
DSSERR("can't ioremap DISPC\n");
|
||||
r = -ENOMEM;
|
||||
goto fail0;
|
||||
}
|
||||
dispc.irq = platform_get_irq(dispc.pdev, 0);
|
||||
if (dispc.irq < 0) {
|
||||
DSSERR("platform_get_irq failed\n");
|
||||
r = -ENODEV;
|
||||
goto fail1;
|
||||
}
|
||||
|
||||
r = request_irq(dispc.irq, omap_dispc_irq_handler, IRQF_SHARED,
|
||||
"OMAP DISPC", dispc.pdev);
|
||||
if (r < 0) {
|
||||
DSSERR("request_irq failed\n");
|
||||
goto fail1;
|
||||
}
|
||||
|
||||
enable_clocks(1);
|
||||
|
||||
_omap_dispc_initial_config();
|
||||
|
||||
_omap_dispc_initialize_irq();
|
||||
|
||||
dispc_save_context();
|
||||
|
||||
rev = dispc_read_reg(DISPC_REVISION);
|
||||
dev_dbg(&pdev->dev, "OMAP DISPC rev %d.%d\n",
|
||||
FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
|
||||
|
||||
enable_clocks(0);
|
||||
|
||||
return 0;
|
||||
fail1:
|
||||
iounmap(dispc.base);
|
||||
fail0:
|
||||
return r;
|
||||
}
|
||||
|
||||
static int omap_dispchw_remove(struct platform_device *pdev)
|
||||
{
|
||||
free_irq(dispc.irq, dispc.pdev);
|
||||
iounmap(dispc.base);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver omap_dispchw_driver = {
|
||||
.probe = omap_dispchw_probe,
|
||||
.remove = omap_dispchw_remove,
|
||||
.driver = {
|
||||
.name = "omapdss_dispc",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
int dispc_init_platform_driver(void)
|
||||
{
|
||||
return platform_driver_register(&omap_dispchw_driver);
|
||||
}
|
||||
|
||||
void dispc_uninit_platform_driver(void)
|
||||
{
|
||||
return platform_driver_unregister(&omap_dispchw_driver);
|
||||
}
|
||||
|
@ -25,14 +25,11 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include <plat/display.h>
|
||||
#include "dss.h"
|
||||
|
||||
static LIST_HEAD(display_list);
|
||||
|
||||
static ssize_t display_enabled_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
@ -345,6 +342,7 @@ int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev)
|
||||
return 16;
|
||||
case OMAP_DISPLAY_TYPE_VENC:
|
||||
case OMAP_DISPLAY_TYPE_SDI:
|
||||
case OMAP_DISPLAY_TYPE_HDMI:
|
||||
return 24;
|
||||
default:
|
||||
BUG();
|
||||
@ -371,6 +369,7 @@ bool dss_use_replication(struct omap_dss_device *dssdev,
|
||||
case OMAP_DISPLAY_TYPE_DPI:
|
||||
bpp = dssdev->phy.dpi.data_lines;
|
||||
break;
|
||||
case OMAP_DISPLAY_TYPE_HDMI:
|
||||
case OMAP_DISPLAY_TYPE_VENC:
|
||||
case OMAP_DISPLAY_TYPE_SDI:
|
||||
bpp = 24;
|
||||
@ -393,29 +392,6 @@ void dss_init_device(struct platform_device *pdev,
|
||||
int i;
|
||||
int r;
|
||||
|
||||
switch (dssdev->type) {
|
||||
#ifdef CONFIG_OMAP2_DSS_DPI
|
||||
case OMAP_DISPLAY_TYPE_DPI:
|
||||
#endif
|
||||
#ifdef CONFIG_OMAP2_DSS_RFBI
|
||||
case OMAP_DISPLAY_TYPE_DBI:
|
||||
#endif
|
||||
#ifdef CONFIG_OMAP2_DSS_SDI
|
||||
case OMAP_DISPLAY_TYPE_SDI:
|
||||
#endif
|
||||
#ifdef CONFIG_OMAP2_DSS_DSI
|
||||
case OMAP_DISPLAY_TYPE_DSI:
|
||||
#endif
|
||||
#ifdef CONFIG_OMAP2_DSS_VENC
|
||||
case OMAP_DISPLAY_TYPE_VENC:
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
DSSERR("Support for display '%s' not compiled in.\n",
|
||||
dssdev->name);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (dssdev->type) {
|
||||
#ifdef CONFIG_OMAP2_DSS_DPI
|
||||
case OMAP_DISPLAY_TYPE_DPI:
|
||||
@ -442,8 +418,13 @@ void dss_init_device(struct platform_device *pdev,
|
||||
r = dsi_init_display(dssdev);
|
||||
break;
|
||||
#endif
|
||||
case OMAP_DISPLAY_TYPE_HDMI:
|
||||
r = hdmi_init_display(dssdev);
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
DSSERR("Support for display '%s' not compiled in.\n",
|
||||
dssdev->name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (r) {
|
||||
|
@ -57,13 +57,13 @@ static int dpi_set_dsi_clk(struct omap_dss_device *dssdev, bool is_tft,
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
dss_select_dispc_clk_source(DSS_SRC_DSI1_PLL_FCLK);
|
||||
dss_select_dispc_clk_source(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC);
|
||||
|
||||
r = dispc_set_clock_div(dssdev->manager->id, &dispc_cinfo);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
*fck = dsi_cinfo.dsi1_pll_fclk;
|
||||
*fck = dsi_cinfo.dsi_pll_hsdiv_dispc_clk;
|
||||
*lck_div = dispc_cinfo.lck_div;
|
||||
*pck_div = dispc_cinfo.pck_div;
|
||||
|
||||
@ -107,7 +107,7 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
|
||||
bool is_tft;
|
||||
int r = 0;
|
||||
|
||||
dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
|
||||
dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
|
||||
|
||||
dispc_set_pol_freq(dssdev->manager->id, dssdev->panel.config,
|
||||
dssdev->panel.acbi, dssdev->panel.acb);
|
||||
@ -137,7 +137,7 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
|
||||
dispc_set_lcd_timings(dssdev->manager->id, t);
|
||||
|
||||
err0:
|
||||
dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
|
||||
dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -173,14 +173,14 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
|
||||
goto err1;
|
||||
}
|
||||
|
||||
dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
|
||||
dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
|
||||
|
||||
r = dpi_basic_init(dssdev);
|
||||
if (r)
|
||||
goto err2;
|
||||
|
||||
#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
|
||||
dss_clk_enable(DSS_CLK_FCK2);
|
||||
dss_clk_enable(DSS_CLK_SYSCK);
|
||||
r = dsi_pll_init(dssdev, 0, 1);
|
||||
if (r)
|
||||
goto err3;
|
||||
@ -199,10 +199,10 @@ err4:
|
||||
#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
|
||||
dsi_pll_uninit();
|
||||
err3:
|
||||
dss_clk_disable(DSS_CLK_FCK2);
|
||||
dss_clk_disable(DSS_CLK_SYSCK);
|
||||
#endif
|
||||
err2:
|
||||
dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
|
||||
dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
|
||||
if (cpu_is_omap34xx())
|
||||
regulator_disable(dpi.vdds_dsi_reg);
|
||||
err1:
|
||||
@ -217,12 +217,12 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
|
||||
dssdev->manager->disable(dssdev->manager);
|
||||
|
||||
#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
|
||||
dss_select_dispc_clk_source(DSS_SRC_DSS1_ALWON_FCLK);
|
||||
dss_select_dispc_clk_source(DSS_CLK_SRC_FCK);
|
||||
dsi_pll_uninit();
|
||||
dss_clk_disable(DSS_CLK_FCK2);
|
||||
dss_clk_disable(DSS_CLK_SYSCK);
|
||||
#endif
|
||||
|
||||
dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
|
||||
dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
|
||||
|
||||
if (cpu_is_omap34xx())
|
||||
regulator_disable(dpi.vdds_dsi_reg);
|
||||
@ -271,7 +271,7 @@ int dpi_check_timings(struct omap_dss_device *dssdev,
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
fck = dsi_cinfo.dsi1_pll_fclk;
|
||||
fck = dsi_cinfo.dsi_pll_hsdiv_dispc_clk;
|
||||
lck_div = dispc_cinfo.lck_div;
|
||||
pck_div = dispc_cinfo.pck_div;
|
||||
}
|
||||
@ -303,19 +303,24 @@ int dpi_init_display(struct omap_dss_device *dssdev)
|
||||
{
|
||||
DSSDBG("init_display\n");
|
||||
|
||||
if (cpu_is_omap34xx() && dpi.vdds_dsi_reg == NULL) {
|
||||
struct regulator *vdds_dsi;
|
||||
|
||||
vdds_dsi = dss_get_vdds_dsi();
|
||||
|
||||
if (IS_ERR(vdds_dsi)) {
|
||||
DSSERR("can't get VDDS_DSI regulator\n");
|
||||
return PTR_ERR(vdds_dsi);
|
||||
}
|
||||
|
||||
dpi.vdds_dsi_reg = vdds_dsi;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dpi_init(struct platform_device *pdev)
|
||||
int dpi_init(void)
|
||||
{
|
||||
if (cpu_is_omap34xx()) {
|
||||
dpi.vdds_dsi_reg = dss_get_vdds_dsi();
|
||||
if (IS_ERR(dpi.vdds_dsi_reg)) {
|
||||
DSSERR("can't get VDDS_DSI regulator\n");
|
||||
return PTR_ERR(dpi.vdds_dsi_reg);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -26,14 +26,13 @@
|
||||
#include <linux/io.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/clk.h>
|
||||
|
||||
#include <plat/display.h>
|
||||
#include <plat/clock.h>
|
||||
#include "dss.h"
|
||||
|
||||
#define DSS_BASE 0x48050000
|
||||
#include "dss_features.h"
|
||||
|
||||
#define DSS_SZ_REGS SZ_512
|
||||
|
||||
@ -59,9 +58,17 @@ struct dss_reg {
|
||||
dss_write_reg(idx, FLD_MOD(dss_read_reg(idx), val, start, end))
|
||||
|
||||
static struct {
|
||||
struct platform_device *pdev;
|
||||
void __iomem *base;
|
||||
int ctx_id;
|
||||
|
||||
struct clk *dpll4_m4_ck;
|
||||
struct clk *dss_ick;
|
||||
struct clk *dss_fck;
|
||||
struct clk *dss_sys_clk;
|
||||
struct clk *dss_tv_fck;
|
||||
struct clk *dss_video_fck;
|
||||
unsigned num_clks_enabled;
|
||||
|
||||
unsigned long cache_req_pck;
|
||||
unsigned long cache_prate;
|
||||
@ -70,10 +77,22 @@ static struct {
|
||||
|
||||
enum dss_clk_source dsi_clk_source;
|
||||
enum dss_clk_source dispc_clk_source;
|
||||
enum dss_clk_source lcd_clk_source[MAX_DSS_LCD_MANAGERS];
|
||||
|
||||
u32 ctx[DSS_SZ_REGS / sizeof(u32)];
|
||||
} dss;
|
||||
|
||||
static const char * const dss_generic_clk_source_names[] = {
|
||||
[DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "DSI_PLL_HSDIV_DISPC",
|
||||
[DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "DSI_PLL_HSDIV_DSI",
|
||||
[DSS_CLK_SRC_FCK] = "DSS_FCK",
|
||||
};
|
||||
|
||||
static void dss_clk_enable_all_no_ctx(void);
|
||||
static void dss_clk_disable_all_no_ctx(void);
|
||||
static void dss_clk_enable_no_ctx(enum dss_clock clks);
|
||||
static void dss_clk_disable_no_ctx(enum dss_clock clks);
|
||||
|
||||
static int _omap_dss_wait_reset(void);
|
||||
|
||||
static inline void dss_write_reg(const struct dss_reg idx, u32 val)
|
||||
@ -99,10 +118,11 @@ void dss_save_context(void)
|
||||
SR(SYSCONFIG);
|
||||
SR(CONTROL);
|
||||
|
||||
#ifdef CONFIG_OMAP2_DSS_SDI
|
||||
SR(SDI_CONTROL);
|
||||
SR(PLL_CONTROL);
|
||||
#endif
|
||||
if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) &
|
||||
OMAP_DISPLAY_TYPE_SDI) {
|
||||
SR(SDI_CONTROL);
|
||||
SR(PLL_CONTROL);
|
||||
}
|
||||
}
|
||||
|
||||
void dss_restore_context(void)
|
||||
@ -113,10 +133,11 @@ void dss_restore_context(void)
|
||||
RR(SYSCONFIG);
|
||||
RR(CONTROL);
|
||||
|
||||
#ifdef CONFIG_OMAP2_DSS_SDI
|
||||
RR(SDI_CONTROL);
|
||||
RR(PLL_CONTROL);
|
||||
#endif
|
||||
if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) &
|
||||
OMAP_DISPLAY_TYPE_SDI) {
|
||||
RR(SDI_CONTROL);
|
||||
RR(PLL_CONTROL);
|
||||
}
|
||||
}
|
||||
|
||||
#undef SR
|
||||
@ -209,66 +230,96 @@ void dss_sdi_disable(void)
|
||||
REG_FLD_MOD(DSS_PLL_CONTROL, 0, 18, 18); /* SDI_PLL_SYSRESET */
|
||||
}
|
||||
|
||||
const char *dss_get_generic_clk_source_name(enum dss_clk_source clk_src)
|
||||
{
|
||||
return dss_generic_clk_source_names[clk_src];
|
||||
}
|
||||
|
||||
void dss_dump_clocks(struct seq_file *s)
|
||||
{
|
||||
unsigned long dpll4_ck_rate;
|
||||
unsigned long dpll4_m4_ck_rate;
|
||||
const char *fclk_name, *fclk_real_name;
|
||||
unsigned long fclk_rate;
|
||||
|
||||
dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
|
||||
|
||||
dpll4_ck_rate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
|
||||
dpll4_m4_ck_rate = clk_get_rate(dss.dpll4_m4_ck);
|
||||
dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
|
||||
|
||||
seq_printf(s, "- DSS -\n");
|
||||
|
||||
seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate);
|
||||
fclk_name = dss_get_generic_clk_source_name(DSS_CLK_SRC_FCK);
|
||||
fclk_real_name = dss_feat_get_clk_source_name(DSS_CLK_SRC_FCK);
|
||||
fclk_rate = dss_clk_get_rate(DSS_CLK_FCK);
|
||||
|
||||
if (cpu_is_omap3630())
|
||||
seq_printf(s, "dss1_alwon_fclk = %lu / %lu = %lu\n",
|
||||
dpll4_ck_rate,
|
||||
dpll4_ck_rate / dpll4_m4_ck_rate,
|
||||
dss_clk_get_rate(DSS_CLK_FCK1));
|
||||
else
|
||||
seq_printf(s, "dss1_alwon_fclk = %lu / %lu * 2 = %lu\n",
|
||||
dpll4_ck_rate,
|
||||
dpll4_ck_rate / dpll4_m4_ck_rate,
|
||||
dss_clk_get_rate(DSS_CLK_FCK1));
|
||||
if (dss.dpll4_m4_ck) {
|
||||
dpll4_ck_rate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
|
||||
dpll4_m4_ck_rate = clk_get_rate(dss.dpll4_m4_ck);
|
||||
|
||||
dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
|
||||
seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate);
|
||||
|
||||
if (cpu_is_omap3630() || cpu_is_omap44xx())
|
||||
seq_printf(s, "%s (%s) = %lu / %lu = %lu\n",
|
||||
fclk_name, fclk_real_name,
|
||||
dpll4_ck_rate,
|
||||
dpll4_ck_rate / dpll4_m4_ck_rate,
|
||||
fclk_rate);
|
||||
else
|
||||
seq_printf(s, "%s (%s) = %lu / %lu * 2 = %lu\n",
|
||||
fclk_name, fclk_real_name,
|
||||
dpll4_ck_rate,
|
||||
dpll4_ck_rate / dpll4_m4_ck_rate,
|
||||
fclk_rate);
|
||||
} else {
|
||||
seq_printf(s, "%s (%s) = %lu\n",
|
||||
fclk_name, fclk_real_name,
|
||||
fclk_rate);
|
||||
}
|
||||
|
||||
dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
|
||||
}
|
||||
|
||||
void dss_dump_regs(struct seq_file *s)
|
||||
{
|
||||
#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dss_read_reg(r))
|
||||
|
||||
dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
|
||||
dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
|
||||
|
||||
DUMPREG(DSS_REVISION);
|
||||
DUMPREG(DSS_SYSCONFIG);
|
||||
DUMPREG(DSS_SYSSTATUS);
|
||||
DUMPREG(DSS_IRQSTATUS);
|
||||
DUMPREG(DSS_CONTROL);
|
||||
DUMPREG(DSS_SDI_CONTROL);
|
||||
DUMPREG(DSS_PLL_CONTROL);
|
||||
DUMPREG(DSS_SDI_STATUS);
|
||||
|
||||
dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
|
||||
if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) &
|
||||
OMAP_DISPLAY_TYPE_SDI) {
|
||||
DUMPREG(DSS_SDI_CONTROL);
|
||||
DUMPREG(DSS_PLL_CONTROL);
|
||||
DUMPREG(DSS_SDI_STATUS);
|
||||
}
|
||||
|
||||
dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
|
||||
#undef DUMPREG
|
||||
}
|
||||
|
||||
void dss_select_dispc_clk_source(enum dss_clk_source clk_src)
|
||||
{
|
||||
int b;
|
||||
u8 start, end;
|
||||
|
||||
BUG_ON(clk_src != DSS_SRC_DSI1_PLL_FCLK &&
|
||||
clk_src != DSS_SRC_DSS1_ALWON_FCLK);
|
||||
switch (clk_src) {
|
||||
case DSS_CLK_SRC_FCK:
|
||||
b = 0;
|
||||
break;
|
||||
case DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
|
||||
b = 1;
|
||||
dsi_wait_pll_hsdiv_dispc_active();
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
||||
b = clk_src == DSS_SRC_DSS1_ALWON_FCLK ? 0 : 1;
|
||||
dss_feat_get_reg_field(FEAT_REG_DISPC_CLK_SWITCH, &start, &end);
|
||||
|
||||
if (clk_src == DSS_SRC_DSI1_PLL_FCLK)
|
||||
dsi_wait_dsi1_pll_active();
|
||||
|
||||
REG_FLD_MOD(DSS_CONTROL, b, 0, 0); /* DISPC_CLK_SWITCH */
|
||||
REG_FLD_MOD(DSS_CONTROL, b, start, end); /* DISPC_CLK_SWITCH */
|
||||
|
||||
dss.dispc_clk_source = clk_src;
|
||||
}
|
||||
@ -277,19 +328,51 @@ void dss_select_dsi_clk_source(enum dss_clk_source clk_src)
|
||||
{
|
||||
int b;
|
||||
|
||||
BUG_ON(clk_src != DSS_SRC_DSI2_PLL_FCLK &&
|
||||
clk_src != DSS_SRC_DSS1_ALWON_FCLK);
|
||||
|
||||
b = clk_src == DSS_SRC_DSS1_ALWON_FCLK ? 0 : 1;
|
||||
|
||||
if (clk_src == DSS_SRC_DSI2_PLL_FCLK)
|
||||
dsi_wait_dsi2_pll_active();
|
||||
switch (clk_src) {
|
||||
case DSS_CLK_SRC_FCK:
|
||||
b = 0;
|
||||
break;
|
||||
case DSS_CLK_SRC_DSI_PLL_HSDIV_DSI:
|
||||
b = 1;
|
||||
dsi_wait_pll_hsdiv_dsi_active();
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
||||
REG_FLD_MOD(DSS_CONTROL, b, 1, 1); /* DSI_CLK_SWITCH */
|
||||
|
||||
dss.dsi_clk_source = clk_src;
|
||||
}
|
||||
|
||||
void dss_select_lcd_clk_source(enum omap_channel channel,
|
||||
enum dss_clk_source clk_src)
|
||||
{
|
||||
int b, ix, pos;
|
||||
|
||||
if (!dss_has_feature(FEAT_LCD_CLK_SRC))
|
||||
return;
|
||||
|
||||
switch (clk_src) {
|
||||
case DSS_CLK_SRC_FCK:
|
||||
b = 0;
|
||||
break;
|
||||
case DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
|
||||
BUG_ON(channel != OMAP_DSS_CHANNEL_LCD);
|
||||
b = 1;
|
||||
dsi_wait_pll_hsdiv_dispc_active();
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
||||
pos = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 12;
|
||||
REG_FLD_MOD(DSS_CONTROL, b, pos, pos); /* LCDx_CLK_SWITCH */
|
||||
|
||||
ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 1;
|
||||
dss.lcd_clk_source[ix] = clk_src;
|
||||
}
|
||||
|
||||
enum dss_clk_source dss_get_dispc_clk_source(void)
|
||||
{
|
||||
return dss.dispc_clk_source;
|
||||
@ -300,34 +383,52 @@ enum dss_clk_source dss_get_dsi_clk_source(void)
|
||||
return dss.dsi_clk_source;
|
||||
}
|
||||
|
||||
enum dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel)
|
||||
{
|
||||
int ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 1;
|
||||
return dss.lcd_clk_source[ix];
|
||||
}
|
||||
|
||||
/* calculate clock rates using dividers in cinfo */
|
||||
int dss_calc_clock_rates(struct dss_clock_info *cinfo)
|
||||
{
|
||||
unsigned long prate;
|
||||
if (dss.dpll4_m4_ck) {
|
||||
unsigned long prate;
|
||||
u16 fck_div_max = 16;
|
||||
|
||||
if (cinfo->fck_div > (cpu_is_omap3630() ? 32 : 16) ||
|
||||
cinfo->fck_div == 0)
|
||||
return -EINVAL;
|
||||
if (cpu_is_omap3630() || cpu_is_omap44xx())
|
||||
fck_div_max = 32;
|
||||
|
||||
prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
|
||||
if (cinfo->fck_div > fck_div_max || cinfo->fck_div == 0)
|
||||
return -EINVAL;
|
||||
|
||||
cinfo->fck = prate / cinfo->fck_div;
|
||||
prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
|
||||
|
||||
cinfo->fck = prate / cinfo->fck_div;
|
||||
} else {
|
||||
if (cinfo->fck_div != 0)
|
||||
return -EINVAL;
|
||||
cinfo->fck = dss_clk_get_rate(DSS_CLK_FCK);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dss_set_clock_div(struct dss_clock_info *cinfo)
|
||||
{
|
||||
unsigned long prate;
|
||||
int r;
|
||||
if (dss.dpll4_m4_ck) {
|
||||
unsigned long prate;
|
||||
int r;
|
||||
|
||||
if (cpu_is_omap34xx()) {
|
||||
prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
|
||||
DSSDBG("dpll4_m4 = %ld\n", prate);
|
||||
|
||||
r = clk_set_rate(dss.dpll4_m4_ck, prate / cinfo->fck_div);
|
||||
if (r)
|
||||
return r;
|
||||
} else {
|
||||
if (cinfo->fck_div != 0)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
DSSDBG("fck = %ld (%d)\n", cinfo->fck, cinfo->fck_div);
|
||||
@ -337,12 +438,14 @@ int dss_set_clock_div(struct dss_clock_info *cinfo)
|
||||
|
||||
int dss_get_clock_div(struct dss_clock_info *cinfo)
|
||||
{
|
||||
cinfo->fck = dss_clk_get_rate(DSS_CLK_FCK1);
|
||||
cinfo->fck = dss_clk_get_rate(DSS_CLK_FCK);
|
||||
|
||||
if (cpu_is_omap34xx()) {
|
||||
if (dss.dpll4_m4_ck) {
|
||||
unsigned long prate;
|
||||
|
||||
prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
|
||||
if (cpu_is_omap3630())
|
||||
|
||||
if (cpu_is_omap3630() || cpu_is_omap44xx())
|
||||
cinfo->fck_div = prate / (cinfo->fck);
|
||||
else
|
||||
cinfo->fck_div = prate / (cinfo->fck / 2);
|
||||
@ -355,7 +458,7 @@ int dss_get_clock_div(struct dss_clock_info *cinfo)
|
||||
|
||||
unsigned long dss_get_dpll4_rate(void)
|
||||
{
|
||||
if (cpu_is_omap34xx())
|
||||
if (dss.dpll4_m4_ck)
|
||||
return clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
|
||||
else
|
||||
return 0;
|
||||
@ -369,16 +472,18 @@ int dss_calc_clock_div(bool is_tft, unsigned long req_pck,
|
||||
struct dss_clock_info best_dss;
|
||||
struct dispc_clock_info best_dispc;
|
||||
|
||||
unsigned long fck;
|
||||
unsigned long fck, max_dss_fck;
|
||||
|
||||
u16 fck_div;
|
||||
u16 fck_div, fck_div_max = 16;
|
||||
|
||||
int match = 0;
|
||||
int min_fck_per_pck;
|
||||
|
||||
prate = dss_get_dpll4_rate();
|
||||
|
||||
fck = dss_clk_get_rate(DSS_CLK_FCK1);
|
||||
max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
|
||||
|
||||
fck = dss_clk_get_rate(DSS_CLK_FCK);
|
||||
if (req_pck == dss.cache_req_pck &&
|
||||
((cpu_is_omap34xx() && prate == dss.cache_prate) ||
|
||||
dss.cache_dss_cinfo.fck == fck)) {
|
||||
@ -391,7 +496,7 @@ int dss_calc_clock_div(bool is_tft, unsigned long req_pck,
|
||||
min_fck_per_pck = CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK;
|
||||
|
||||
if (min_fck_per_pck &&
|
||||
req_pck * min_fck_per_pck > DISPC_MAX_FCK) {
|
||||
req_pck * min_fck_per_pck > max_dss_fck) {
|
||||
DSSERR("Requested pixel clock not possible with the current "
|
||||
"OMAP2_DSS_MIN_FCK_PER_PCK setting. Turning "
|
||||
"the constraint off.\n");
|
||||
@ -402,10 +507,10 @@ retry:
|
||||
memset(&best_dss, 0, sizeof(best_dss));
|
||||
memset(&best_dispc, 0, sizeof(best_dispc));
|
||||
|
||||
if (cpu_is_omap24xx()) {
|
||||
if (dss.dpll4_m4_ck == NULL) {
|
||||
struct dispc_clock_info cur_dispc;
|
||||
/* XXX can we change the clock on omap2? */
|
||||
fck = dss_clk_get_rate(DSS_CLK_FCK1);
|
||||
fck = dss_clk_get_rate(DSS_CLK_FCK);
|
||||
fck_div = 1;
|
||||
|
||||
dispc_find_clk_divs(is_tft, req_pck, fck, &cur_dispc);
|
||||
@ -417,17 +522,19 @@ retry:
|
||||
best_dispc = cur_dispc;
|
||||
|
||||
goto found;
|
||||
} else if (cpu_is_omap34xx()) {
|
||||
for (fck_div = (cpu_is_omap3630() ? 32 : 16);
|
||||
fck_div > 0; --fck_div) {
|
||||
} else {
|
||||
if (cpu_is_omap3630() || cpu_is_omap44xx())
|
||||
fck_div_max = 32;
|
||||
|
||||
for (fck_div = fck_div_max; fck_div > 0; --fck_div) {
|
||||
struct dispc_clock_info cur_dispc;
|
||||
|
||||
if (cpu_is_omap3630())
|
||||
if (fck_div_max == 32)
|
||||
fck = prate / fck_div;
|
||||
else
|
||||
fck = prate / fck_div * 2;
|
||||
|
||||
if (fck > DISPC_MAX_FCK)
|
||||
if (fck > max_dss_fck)
|
||||
continue;
|
||||
|
||||
if (min_fck_per_pck &&
|
||||
@ -450,8 +557,6 @@ retry:
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
BUG();
|
||||
}
|
||||
|
||||
found:
|
||||
@ -482,31 +587,6 @@ found:
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static irqreturn_t dss_irq_handler_omap2(int irq, void *arg)
|
||||
{
|
||||
dispc_irq_handler();
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static irqreturn_t dss_irq_handler_omap3(int irq, void *arg)
|
||||
{
|
||||
u32 irqstatus;
|
||||
|
||||
irqstatus = dss_read_reg(DSS_IRQSTATUS);
|
||||
|
||||
if (irqstatus & (1<<0)) /* DISPC_IRQ */
|
||||
dispc_irq_handler();
|
||||
#ifdef CONFIG_OMAP2_DSS_DSI
|
||||
if (irqstatus & (1<<1)) /* DSI_IRQ */
|
||||
dsi_irq_handler();
|
||||
#endif
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int _omap_dss_wait_reset(void)
|
||||
{
|
||||
int t = 0;
|
||||
@ -549,34 +629,45 @@ void dss_set_dac_pwrdn_bgz(bool enable)
|
||||
REG_FLD_MOD(DSS_CONTROL, enable, 5, 5); /* DAC Power-Down Control */
|
||||
}
|
||||
|
||||
int dss_init(bool skip_init)
|
||||
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 */
|
||||
}
|
||||
|
||||
static int dss_init(void)
|
||||
{
|
||||
int r;
|
||||
u32 rev;
|
||||
struct resource *dss_mem;
|
||||
struct clk *dpll4_m4_ck;
|
||||
|
||||
dss.base = ioremap(DSS_BASE, DSS_SZ_REGS);
|
||||
dss_mem = platform_get_resource(dss.pdev, IORESOURCE_MEM, 0);
|
||||
if (!dss_mem) {
|
||||
DSSERR("can't get IORESOURCE_MEM DSS\n");
|
||||
r = -EINVAL;
|
||||
goto fail0;
|
||||
}
|
||||
dss.base = ioremap(dss_mem->start, resource_size(dss_mem));
|
||||
if (!dss.base) {
|
||||
DSSERR("can't ioremap DSS\n");
|
||||
r = -ENOMEM;
|
||||
goto fail0;
|
||||
}
|
||||
|
||||
if (!skip_init) {
|
||||
/* disable LCD and DIGIT output. This seems to fix the synclost
|
||||
* problem that we get, if the bootloader starts the DSS and
|
||||
* the kernel resets it */
|
||||
omap_writel(omap_readl(0x48050440) & ~0x3, 0x48050440);
|
||||
/* disable LCD and DIGIT output. This seems to fix the synclost
|
||||
* problem that we get, if the bootloader starts the DSS and
|
||||
* the kernel resets it */
|
||||
omap_writel(omap_readl(0x48050440) & ~0x3, 0x48050440);
|
||||
|
||||
/* We need to wait here a bit, otherwise we sometimes start to
|
||||
* get synclost errors, and after that only power cycle will
|
||||
* restore DSS functionality. I have no idea why this happens.
|
||||
* And we have to wait _before_ resetting the DSS, but after
|
||||
* enabling clocks.
|
||||
*/
|
||||
msleep(50);
|
||||
/* We need to wait here a bit, otherwise we sometimes start to
|
||||
* get synclost errors, and after that only power cycle will
|
||||
* restore DSS functionality. I have no idea why this happens.
|
||||
* And we have to wait _before_ resetting the DSS, but after
|
||||
* enabling clocks.
|
||||
*/
|
||||
msleep(50);
|
||||
|
||||
_omap_dss_reset();
|
||||
}
|
||||
_omap_dss_reset();
|
||||
|
||||
/* autoidle */
|
||||
REG_FLD_MOD(DSS_SYSCONFIG, 1, 0, 0);
|
||||
@ -589,29 +680,30 @@ int dss_init(bool skip_init)
|
||||
REG_FLD_MOD(DSS_CONTROL, 1, 3, 3); /* venc clock 4x enable */
|
||||
REG_FLD_MOD(DSS_CONTROL, 0, 2, 2); /* venc clock mode = normal */
|
||||
#endif
|
||||
|
||||
r = request_irq(INT_24XX_DSS_IRQ,
|
||||
cpu_is_omap24xx()
|
||||
? dss_irq_handler_omap2
|
||||
: dss_irq_handler_omap3,
|
||||
0, "OMAP DSS", NULL);
|
||||
|
||||
if (r < 0) {
|
||||
DSSERR("omap2 dss: request_irq failed\n");
|
||||
goto fail1;
|
||||
}
|
||||
|
||||
if (cpu_is_omap34xx()) {
|
||||
dss.dpll4_m4_ck = clk_get(NULL, "dpll4_m4_ck");
|
||||
if (IS_ERR(dss.dpll4_m4_ck)) {
|
||||
dpll4_m4_ck = clk_get(NULL, "dpll4_m4_ck");
|
||||
if (IS_ERR(dpll4_m4_ck)) {
|
||||
DSSERR("Failed to get dpll4_m4_ck\n");
|
||||
r = PTR_ERR(dss.dpll4_m4_ck);
|
||||
goto fail2;
|
||||
r = PTR_ERR(dpll4_m4_ck);
|
||||
goto fail1;
|
||||
}
|
||||
} else if (cpu_is_omap44xx()) {
|
||||
dpll4_m4_ck = clk_get(NULL, "dpll_per_m5x2_ck");
|
||||
if (IS_ERR(dpll4_m4_ck)) {
|
||||
DSSERR("Failed to get dpll4_m4_ck\n");
|
||||
r = PTR_ERR(dpll4_m4_ck);
|
||||
goto fail1;
|
||||
}
|
||||
} else { /* omap24xx */
|
||||
dpll4_m4_ck = NULL;
|
||||
}
|
||||
|
||||
dss.dsi_clk_source = DSS_SRC_DSS1_ALWON_FCLK;
|
||||
dss.dispc_clk_source = DSS_SRC_DSS1_ALWON_FCLK;
|
||||
dss.dpll4_m4_ck = dpll4_m4_ck;
|
||||
|
||||
dss.dsi_clk_source = DSS_CLK_SRC_FCK;
|
||||
dss.dispc_clk_source = DSS_CLK_SRC_FCK;
|
||||
dss.lcd_clk_source[0] = DSS_CLK_SRC_FCK;
|
||||
dss.lcd_clk_source[1] = DSS_CLK_SRC_FCK;
|
||||
|
||||
dss_save_context();
|
||||
|
||||
@ -621,21 +713,416 @@ int dss_init(bool skip_init)
|
||||
|
||||
return 0;
|
||||
|
||||
fail2:
|
||||
free_irq(INT_24XX_DSS_IRQ, NULL);
|
||||
fail1:
|
||||
iounmap(dss.base);
|
||||
fail0:
|
||||
return r;
|
||||
}
|
||||
|
||||
void dss_exit(void)
|
||||
static void dss_exit(void)
|
||||
{
|
||||
if (cpu_is_omap34xx())
|
||||
if (dss.dpll4_m4_ck)
|
||||
clk_put(dss.dpll4_m4_ck);
|
||||
|
||||
free_irq(INT_24XX_DSS_IRQ, NULL);
|
||||
|
||||
iounmap(dss.base);
|
||||
}
|
||||
|
||||
/* CONTEXT */
|
||||
static int dss_get_ctx_id(void)
|
||||
{
|
||||
struct omap_display_platform_data *pdata = dss.pdev->dev.platform_data;
|
||||
int r;
|
||||
|
||||
if (!pdata->board_data->get_last_off_on_transaction_id)
|
||||
return 0;
|
||||
r = pdata->board_data->get_last_off_on_transaction_id(&dss.pdev->dev);
|
||||
if (r < 0) {
|
||||
dev_err(&dss.pdev->dev, "getting transaction ID failed, "
|
||||
"will force context restore\n");
|
||||
r = -1;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
int dss_need_ctx_restore(void)
|
||||
{
|
||||
int id = dss_get_ctx_id();
|
||||
|
||||
if (id < 0 || id != dss.ctx_id) {
|
||||
DSSDBG("ctx id %d -> id %d\n",
|
||||
dss.ctx_id, id);
|
||||
dss.ctx_id = id;
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void save_all_ctx(void)
|
||||
{
|
||||
DSSDBG("save context\n");
|
||||
|
||||
dss_clk_enable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK);
|
||||
|
||||
dss_save_context();
|
||||
dispc_save_context();
|
||||
#ifdef CONFIG_OMAP2_DSS_DSI
|
||||
dsi_save_context();
|
||||
#endif
|
||||
|
||||
dss_clk_disable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK);
|
||||
}
|
||||
|
||||
static void restore_all_ctx(void)
|
||||
{
|
||||
DSSDBG("restore context\n");
|
||||
|
||||
dss_clk_enable_all_no_ctx();
|
||||
|
||||
dss_restore_context();
|
||||
dispc_restore_context();
|
||||
#ifdef CONFIG_OMAP2_DSS_DSI
|
||||
dsi_restore_context();
|
||||
#endif
|
||||
|
||||
dss_clk_disable_all_no_ctx();
|
||||
}
|
||||
|
||||
static int dss_get_clock(struct clk **clock, const char *clk_name)
|
||||
{
|
||||
struct clk *clk;
|
||||
|
||||
clk = clk_get(&dss.pdev->dev, clk_name);
|
||||
|
||||
if (IS_ERR(clk)) {
|
||||
DSSERR("can't get clock %s", clk_name);
|
||||
return PTR_ERR(clk);
|
||||
}
|
||||
|
||||
*clock = clk;
|
||||
|
||||
DSSDBG("clk %s, rate %ld\n", clk_name, clk_get_rate(clk));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dss_get_clocks(void)
|
||||
{
|
||||
int r;
|
||||
struct omap_display_platform_data *pdata = dss.pdev->dev.platform_data;
|
||||
|
||||
dss.dss_ick = NULL;
|
||||
dss.dss_fck = NULL;
|
||||
dss.dss_sys_clk = NULL;
|
||||
dss.dss_tv_fck = NULL;
|
||||
dss.dss_video_fck = NULL;
|
||||
|
||||
r = dss_get_clock(&dss.dss_ick, "ick");
|
||||
if (r)
|
||||
goto err;
|
||||
|
||||
r = dss_get_clock(&dss.dss_fck, "fck");
|
||||
if (r)
|
||||
goto err;
|
||||
|
||||
if (!pdata->opt_clock_available) {
|
||||
r = -ENODEV;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (pdata->opt_clock_available("sys_clk")) {
|
||||
r = dss_get_clock(&dss.dss_sys_clk, "sys_clk");
|
||||
if (r)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (pdata->opt_clock_available("tv_clk")) {
|
||||
r = dss_get_clock(&dss.dss_tv_fck, "tv_clk");
|
||||
if (r)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (pdata->opt_clock_available("video_clk")) {
|
||||
r = dss_get_clock(&dss.dss_video_fck, "video_clk");
|
||||
if (r)
|
||||
goto err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
if (dss.dss_ick)
|
||||
clk_put(dss.dss_ick);
|
||||
if (dss.dss_fck)
|
||||
clk_put(dss.dss_fck);
|
||||
if (dss.dss_sys_clk)
|
||||
clk_put(dss.dss_sys_clk);
|
||||
if (dss.dss_tv_fck)
|
||||
clk_put(dss.dss_tv_fck);
|
||||
if (dss.dss_video_fck)
|
||||
clk_put(dss.dss_video_fck);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static void dss_put_clocks(void)
|
||||
{
|
||||
if (dss.dss_video_fck)
|
||||
clk_put(dss.dss_video_fck);
|
||||
if (dss.dss_tv_fck)
|
||||
clk_put(dss.dss_tv_fck);
|
||||
if (dss.dss_sys_clk)
|
||||
clk_put(dss.dss_sys_clk);
|
||||
clk_put(dss.dss_fck);
|
||||
clk_put(dss.dss_ick);
|
||||
}
|
||||
|
||||
unsigned long dss_clk_get_rate(enum dss_clock clk)
|
||||
{
|
||||
switch (clk) {
|
||||
case DSS_CLK_ICK:
|
||||
return clk_get_rate(dss.dss_ick);
|
||||
case DSS_CLK_FCK:
|
||||
return clk_get_rate(dss.dss_fck);
|
||||
case DSS_CLK_SYSCK:
|
||||
return clk_get_rate(dss.dss_sys_clk);
|
||||
case DSS_CLK_TVFCK:
|
||||
return clk_get_rate(dss.dss_tv_fck);
|
||||
case DSS_CLK_VIDFCK:
|
||||
return clk_get_rate(dss.dss_video_fck);
|
||||
}
|
||||
|
||||
BUG();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned count_clk_bits(enum dss_clock clks)
|
||||
{
|
||||
unsigned num_clks = 0;
|
||||
|
||||
if (clks & DSS_CLK_ICK)
|
||||
++num_clks;
|
||||
if (clks & DSS_CLK_FCK)
|
||||
++num_clks;
|
||||
if (clks & DSS_CLK_SYSCK)
|
||||
++num_clks;
|
||||
if (clks & DSS_CLK_TVFCK)
|
||||
++num_clks;
|
||||
if (clks & DSS_CLK_VIDFCK)
|
||||
++num_clks;
|
||||
|
||||
return num_clks;
|
||||
}
|
||||
|
||||
static void dss_clk_enable_no_ctx(enum dss_clock clks)
|
||||
{
|
||||
unsigned num_clks = count_clk_bits(clks);
|
||||
|
||||
if (clks & DSS_CLK_ICK)
|
||||
clk_enable(dss.dss_ick);
|
||||
if (clks & DSS_CLK_FCK)
|
||||
clk_enable(dss.dss_fck);
|
||||
if ((clks & DSS_CLK_SYSCK) && dss.dss_sys_clk)
|
||||
clk_enable(dss.dss_sys_clk);
|
||||
if ((clks & DSS_CLK_TVFCK) && dss.dss_tv_fck)
|
||||
clk_enable(dss.dss_tv_fck);
|
||||
if ((clks & DSS_CLK_VIDFCK) && dss.dss_video_fck)
|
||||
clk_enable(dss.dss_video_fck);
|
||||
|
||||
dss.num_clks_enabled += num_clks;
|
||||
}
|
||||
|
||||
void dss_clk_enable(enum dss_clock clks)
|
||||
{
|
||||
bool check_ctx = dss.num_clks_enabled == 0;
|
||||
|
||||
dss_clk_enable_no_ctx(clks);
|
||||
|
||||
/*
|
||||
* HACK: On omap4 the registers may not be accessible right after
|
||||
* enabling the clocks. At some point this will be handled by
|
||||
* pm_runtime, but for the time begin this should make things work.
|
||||
*/
|
||||
if (cpu_is_omap44xx() && check_ctx)
|
||||
udelay(10);
|
||||
|
||||
if (check_ctx && cpu_is_omap34xx() && dss_need_ctx_restore())
|
||||
restore_all_ctx();
|
||||
}
|
||||
|
||||
static void dss_clk_disable_no_ctx(enum dss_clock clks)
|
||||
{
|
||||
unsigned num_clks = count_clk_bits(clks);
|
||||
|
||||
if (clks & DSS_CLK_ICK)
|
||||
clk_disable(dss.dss_ick);
|
||||
if (clks & DSS_CLK_FCK)
|
||||
clk_disable(dss.dss_fck);
|
||||
if ((clks & DSS_CLK_SYSCK) && dss.dss_sys_clk)
|
||||
clk_disable(dss.dss_sys_clk);
|
||||
if ((clks & DSS_CLK_TVFCK) && dss.dss_tv_fck)
|
||||
clk_disable(dss.dss_tv_fck);
|
||||
if ((clks & DSS_CLK_VIDFCK) && dss.dss_video_fck)
|
||||
clk_disable(dss.dss_video_fck);
|
||||
|
||||
dss.num_clks_enabled -= num_clks;
|
||||
}
|
||||
|
||||
void dss_clk_disable(enum dss_clock clks)
|
||||
{
|
||||
if (cpu_is_omap34xx()) {
|
||||
unsigned num_clks = count_clk_bits(clks);
|
||||
|
||||
BUG_ON(dss.num_clks_enabled < num_clks);
|
||||
|
||||
if (dss.num_clks_enabled == num_clks)
|
||||
save_all_ctx();
|
||||
}
|
||||
|
||||
dss_clk_disable_no_ctx(clks);
|
||||
}
|
||||
|
||||
static void dss_clk_enable_all_no_ctx(void)
|
||||
{
|
||||
enum dss_clock clks;
|
||||
|
||||
clks = DSS_CLK_ICK | DSS_CLK_FCK | DSS_CLK_SYSCK | DSS_CLK_TVFCK;
|
||||
if (cpu_is_omap34xx())
|
||||
clks |= DSS_CLK_VIDFCK;
|
||||
dss_clk_enable_no_ctx(clks);
|
||||
}
|
||||
|
||||
static void dss_clk_disable_all_no_ctx(void)
|
||||
{
|
||||
enum dss_clock clks;
|
||||
|
||||
clks = DSS_CLK_ICK | DSS_CLK_FCK | DSS_CLK_SYSCK | DSS_CLK_TVFCK;
|
||||
if (cpu_is_omap34xx())
|
||||
clks |= DSS_CLK_VIDFCK;
|
||||
dss_clk_disable_no_ctx(clks);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
|
||||
/* CLOCKS */
|
||||
static void core_dump_clocks(struct seq_file *s)
|
||||
{
|
||||
int i;
|
||||
struct clk *clocks[5] = {
|
||||
dss.dss_ick,
|
||||
dss.dss_fck,
|
||||
dss.dss_sys_clk,
|
||||
dss.dss_tv_fck,
|
||||
dss.dss_video_fck
|
||||
};
|
||||
|
||||
seq_printf(s, "- CORE -\n");
|
||||
|
||||
seq_printf(s, "internal clk count\t\t%u\n", dss.num_clks_enabled);
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
if (!clocks[i])
|
||||
continue;
|
||||
seq_printf(s, "%-15s\t%lu\t%d\n",
|
||||
clocks[i]->name,
|
||||
clk_get_rate(clocks[i]),
|
||||
clocks[i]->usecount);
|
||||
}
|
||||
}
|
||||
#endif /* defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) */
|
||||
|
||||
/* DEBUGFS */
|
||||
#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
|
||||
void dss_debug_dump_clocks(struct seq_file *s)
|
||||
{
|
||||
core_dump_clocks(s);
|
||||
dss_dump_clocks(s);
|
||||
dispc_dump_clocks(s);
|
||||
#ifdef CONFIG_OMAP2_DSS_DSI
|
||||
dsi_dump_clocks(s);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* DSS HW IP initialisation */
|
||||
static int omap_dsshw_probe(struct platform_device *pdev)
|
||||
{
|
||||
int r;
|
||||
|
||||
dss.pdev = pdev;
|
||||
|
||||
r = dss_get_clocks();
|
||||
if (r)
|
||||
goto err_clocks;
|
||||
|
||||
dss_clk_enable_all_no_ctx();
|
||||
|
||||
dss.ctx_id = dss_get_ctx_id();
|
||||
DSSDBG("initial ctx id %u\n", dss.ctx_id);
|
||||
|
||||
r = dss_init();
|
||||
if (r) {
|
||||
DSSERR("Failed to initialize DSS\n");
|
||||
goto err_dss;
|
||||
}
|
||||
|
||||
r = dpi_init();
|
||||
if (r) {
|
||||
DSSERR("Failed to initialize DPI\n");
|
||||
goto err_dpi;
|
||||
}
|
||||
|
||||
r = sdi_init();
|
||||
if (r) {
|
||||
DSSERR("Failed to initialize SDI\n");
|
||||
goto err_sdi;
|
||||
}
|
||||
|
||||
dss_clk_disable_all_no_ctx();
|
||||
return 0;
|
||||
err_sdi:
|
||||
dpi_exit();
|
||||
err_dpi:
|
||||
dss_exit();
|
||||
err_dss:
|
||||
dss_clk_disable_all_no_ctx();
|
||||
dss_put_clocks();
|
||||
err_clocks:
|
||||
return r;
|
||||
}
|
||||
|
||||
static int omap_dsshw_remove(struct platform_device *pdev)
|
||||
{
|
||||
|
||||
dss_exit();
|
||||
|
||||
/*
|
||||
* As part of hwmod changes, DSS is not the only controller of dss
|
||||
* clocks; hwmod framework itself will also enable clocks during hwmod
|
||||
* init for dss, and autoidle is set in h/w for DSS. Hence, there's no
|
||||
* need to disable clocks if their usecounts > 1.
|
||||
*/
|
||||
WARN_ON(dss.num_clks_enabled > 0);
|
||||
|
||||
dss_put_clocks();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver omap_dsshw_driver = {
|
||||
.probe = omap_dsshw_probe,
|
||||
.remove = omap_dsshw_remove,
|
||||
.driver = {
|
||||
.name = "omapdss_dss",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
int dss_init_platform_driver(void)
|
||||
{
|
||||
return platform_driver_register(&omap_dsshw_driver);
|
||||
}
|
||||
|
||||
void dss_uninit_platform_driver(void)
|
||||
{
|
||||
return platform_driver_unregister(&omap_dsshw_driver);
|
||||
}
|
||||
|
@ -97,8 +97,6 @@ extern unsigned int dss_debug;
|
||||
#define FLD_MOD(orig, val, start, end) \
|
||||
(((orig) & ~FLD_MASK(start, end)) | FLD_VAL(val, start, end))
|
||||
|
||||
#define DISPC_MAX_FCK 173000000
|
||||
|
||||
enum omap_burst_size {
|
||||
OMAP_DSS_BURST_4x32 = 0,
|
||||
OMAP_DSS_BURST_8x32 = 1,
|
||||
@ -112,17 +110,25 @@ enum omap_parallel_interface_mode {
|
||||
};
|
||||
|
||||
enum dss_clock {
|
||||
DSS_CLK_ICK = 1 << 0,
|
||||
DSS_CLK_FCK1 = 1 << 1,
|
||||
DSS_CLK_FCK2 = 1 << 2,
|
||||
DSS_CLK_54M = 1 << 3,
|
||||
DSS_CLK_96M = 1 << 4,
|
||||
DSS_CLK_ICK = 1 << 0, /* DSS_L3_ICLK and DSS_L4_ICLK */
|
||||
DSS_CLK_FCK = 1 << 1, /* DSS1_ALWON_FCLK */
|
||||
DSS_CLK_SYSCK = 1 << 2, /* DSS2_ALWON_FCLK */
|
||||
DSS_CLK_TVFCK = 1 << 3, /* DSS_TV_FCLK */
|
||||
DSS_CLK_VIDFCK = 1 << 4, /* DSS_96M_FCLK*/
|
||||
};
|
||||
|
||||
enum dss_clk_source {
|
||||
DSS_SRC_DSI1_PLL_FCLK,
|
||||
DSS_SRC_DSI2_PLL_FCLK,
|
||||
DSS_SRC_DSS1_ALWON_FCLK,
|
||||
DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC, /* OMAP3: DSI1_PLL_FCLK
|
||||
* OMAP4: PLL1_CLK1 */
|
||||
DSS_CLK_SRC_DSI_PLL_HSDIV_DSI, /* OMAP3: DSI2_PLL_FCLK
|
||||
* OMAP4: PLL1_CLK2 */
|
||||
DSS_CLK_SRC_FCK, /* OMAP2/3: DSS1_ALWON_FCLK
|
||||
* OMAP4: DSS_FCLK */
|
||||
};
|
||||
|
||||
enum dss_hdmi_venc_clk_source_select {
|
||||
DSS_VENC_TV_CLK = 0,
|
||||
DSS_HDMI_M_PCLK = 1,
|
||||
};
|
||||
|
||||
struct dss_clock_info {
|
||||
@ -148,36 +154,42 @@ struct dsi_clock_info {
|
||||
unsigned long fint;
|
||||
unsigned long clkin4ddr;
|
||||
unsigned long clkin;
|
||||
unsigned long dsi1_pll_fclk;
|
||||
unsigned long dsi2_pll_fclk;
|
||||
|
||||
unsigned long dsi_pll_hsdiv_dispc_clk; /* OMAP3: DSI1_PLL_CLK
|
||||
* OMAP4: PLLx_CLK1 */
|
||||
unsigned long dsi_pll_hsdiv_dsi_clk; /* OMAP3: DSI2_PLL_CLK
|
||||
* OMAP4: PLLx_CLK2 */
|
||||
unsigned long lp_clk;
|
||||
|
||||
/* dividers */
|
||||
u16 regn;
|
||||
u16 regm;
|
||||
u16 regm3;
|
||||
u16 regm4;
|
||||
|
||||
u16 regm_dispc; /* OMAP3: REGM3
|
||||
* OMAP4: REGM4 */
|
||||
u16 regm_dsi; /* OMAP3: REGM4
|
||||
* OMAP4: REGM5 */
|
||||
u16 lp_clk_div;
|
||||
|
||||
u8 highfreq;
|
||||
bool use_dss2_fck;
|
||||
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;
|
||||
|
||||
/* core */
|
||||
void dss_clk_enable(enum dss_clock clks);
|
||||
void dss_clk_disable(enum dss_clock clks);
|
||||
unsigned long dss_clk_get_rate(enum dss_clock clk);
|
||||
int dss_need_ctx_restore(void);
|
||||
void dss_dump_clocks(struct seq_file *s);
|
||||
struct bus_type *dss_get_bus(void);
|
||||
struct regulator *dss_get_vdds_dsi(void);
|
||||
struct regulator *dss_get_vdds_sdi(void);
|
||||
struct regulator *dss_get_vdda_dac(void);
|
||||
|
||||
/* display */
|
||||
int dss_suspend_all_devices(void);
|
||||
@ -214,13 +226,23 @@ void dss_overlay_setup_l4_manager(struct omap_overlay_manager *mgr);
|
||||
void dss_recheck_connections(struct omap_dss_device *dssdev, bool force);
|
||||
|
||||
/* DSS */
|
||||
int dss_init(bool skip_init);
|
||||
void dss_exit(void);
|
||||
int dss_init_platform_driver(void);
|
||||
void dss_uninit_platform_driver(void);
|
||||
|
||||
void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select);
|
||||
void dss_save_context(void);
|
||||
void dss_restore_context(void);
|
||||
void dss_clk_enable(enum dss_clock clks);
|
||||
void dss_clk_disable(enum dss_clock clks);
|
||||
unsigned long dss_clk_get_rate(enum dss_clock clk);
|
||||
int dss_need_ctx_restore(void);
|
||||
const char *dss_get_generic_clk_source_name(enum dss_clk_source clk_src);
|
||||
void dss_dump_clocks(struct seq_file *s);
|
||||
|
||||
void dss_dump_regs(struct seq_file *s);
|
||||
#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
|
||||
void dss_debug_dump_clocks(struct seq_file *s);
|
||||
#endif
|
||||
|
||||
void dss_sdi_init(u8 datapairs);
|
||||
int dss_sdi_enable(void);
|
||||
@ -228,8 +250,11 @@ void dss_sdi_disable(void);
|
||||
|
||||
void dss_select_dispc_clk_source(enum dss_clk_source clk_src);
|
||||
void dss_select_dsi_clk_source(enum dss_clk_source clk_src);
|
||||
void dss_select_lcd_clk_source(enum omap_channel channel,
|
||||
enum dss_clk_source clk_src);
|
||||
enum dss_clk_source dss_get_dispc_clk_source(void);
|
||||
enum dss_clk_source dss_get_dsi_clk_source(void);
|
||||
enum dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel);
|
||||
|
||||
void dss_set_venc_output(enum omap_dss_venc_type type);
|
||||
void dss_set_dac_pwrdn_bgz(bool enable);
|
||||
@ -244,11 +269,11 @@ int dss_calc_clock_div(bool is_tft, unsigned long req_pck,
|
||||
|
||||
/* SDI */
|
||||
#ifdef CONFIG_OMAP2_DSS_SDI
|
||||
int sdi_init(bool skip_init);
|
||||
int sdi_init(void);
|
||||
void sdi_exit(void);
|
||||
int sdi_init_display(struct omap_dss_device *display);
|
||||
#else
|
||||
static inline int sdi_init(bool skip_init)
|
||||
static inline int sdi_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@ -259,8 +284,8 @@ static inline void sdi_exit(void)
|
||||
|
||||
/* DSI */
|
||||
#ifdef CONFIG_OMAP2_DSS_DSI
|
||||
int dsi_init(struct platform_device *pdev);
|
||||
void dsi_exit(void);
|
||||
int dsi_init_platform_driver(void);
|
||||
void dsi_uninit_platform_driver(void);
|
||||
|
||||
void dsi_dump_clocks(struct seq_file *s);
|
||||
void dsi_dump_irqs(struct seq_file *s);
|
||||
@ -271,7 +296,7 @@ void dsi_restore_context(void);
|
||||
|
||||
int dsi_init_display(struct omap_dss_device *display);
|
||||
void dsi_irq_handler(void);
|
||||
unsigned long dsi_get_dsi1_pll_rate(void);
|
||||
unsigned long dsi_get_pll_hsdiv_dispc_rate(void);
|
||||
int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo);
|
||||
int dsi_pll_calc_clock_div_pck(bool is_tft, unsigned long req_pck,
|
||||
struct dsi_clock_info *cinfo,
|
||||
@ -282,31 +307,36 @@ void dsi_pll_uninit(void);
|
||||
void dsi_get_overlay_fifo_thresholds(enum omap_plane plane,
|
||||
u32 fifo_size, enum omap_burst_size *burst_size,
|
||||
u32 *fifo_low, u32 *fifo_high);
|
||||
void dsi_wait_dsi1_pll_active(void);
|
||||
void dsi_wait_dsi2_pll_active(void);
|
||||
void dsi_wait_pll_hsdiv_dispc_active(void);
|
||||
void dsi_wait_pll_hsdiv_dsi_active(void);
|
||||
#else
|
||||
static inline int dsi_init(struct platform_device *pdev)
|
||||
static inline int dsi_init_platform_driver(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline void dsi_exit(void)
|
||||
static inline void dsi_uninit_platform_driver(void)
|
||||
{
|
||||
}
|
||||
static inline void dsi_wait_dsi1_pll_active(void)
|
||||
static inline unsigned long dsi_get_pll_hsdiv_dispc_rate(void)
|
||||
{
|
||||
WARN("%s: DSI not compiled in, returning rate as 0\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
static inline void dsi_wait_pll_hsdiv_dispc_active(void)
|
||||
{
|
||||
}
|
||||
static inline void dsi_wait_dsi2_pll_active(void)
|
||||
static inline void dsi_wait_pll_hsdiv_dsi_active(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/* DPI */
|
||||
#ifdef CONFIG_OMAP2_DSS_DPI
|
||||
int dpi_init(struct platform_device *pdev);
|
||||
int dpi_init(void);
|
||||
void dpi_exit(void);
|
||||
int dpi_init_display(struct omap_dss_device *dssdev);
|
||||
#else
|
||||
static inline int dpi_init(struct platform_device *pdev)
|
||||
static inline int dpi_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@ -316,8 +346,8 @@ static inline void dpi_exit(void)
|
||||
#endif
|
||||
|
||||
/* DISPC */
|
||||
int dispc_init(void);
|
||||
void dispc_exit(void);
|
||||
int dispc_init_platform_driver(void);
|
||||
void dispc_uninit_platform_driver(void);
|
||||
void dispc_dump_clocks(struct seq_file *s);
|
||||
void dispc_dump_irqs(struct seq_file *s);
|
||||
void dispc_dump_regs(struct seq_file *s);
|
||||
@ -350,6 +380,7 @@ 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,
|
||||
@ -409,24 +440,50 @@ int dispc_get_clock_div(enum omap_channel channel,
|
||||
|
||||
/* VENC */
|
||||
#ifdef CONFIG_OMAP2_DSS_VENC
|
||||
int venc_init(struct platform_device *pdev);
|
||||
void venc_exit(void);
|
||||
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);
|
||||
#else
|
||||
static inline int venc_init(struct platform_device *pdev)
|
||||
static inline int venc_init_platform_driver(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline void venc_exit(void)
|
||||
static inline void venc_uninit_platform_driver(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/* HDMI */
|
||||
#ifdef CONFIG_OMAP4_DSS_HDMI
|
||||
int hdmi_init_platform_driver(void);
|
||||
void hdmi_uninit_platform_driver(void);
|
||||
int hdmi_init_display(struct omap_dss_device *dssdev);
|
||||
#else
|
||||
static inline int hdmi_init_display(struct omap_dss_device *dssdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline int hdmi_init_platform_driver(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline void hdmi_uninit_platform_driver(void)
|
||||
{
|
||||
}
|
||||
#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 hdmi_panel_init(void);
|
||||
void hdmi_panel_exit(void);
|
||||
|
||||
/* RFBI */
|
||||
#ifdef CONFIG_OMAP2_DSS_RFBI
|
||||
int rfbi_init(void);
|
||||
void rfbi_exit(void);
|
||||
int rfbi_init_platform_driver(void);
|
||||
void rfbi_uninit_platform_driver(void);
|
||||
void rfbi_dump_regs(struct seq_file *s);
|
||||
|
||||
int rfbi_configure(int rfbi_module, int bpp, int lines);
|
||||
@ -437,11 +494,11 @@ void rfbi_set_timings(int rfbi_module, struct rfbi_timings *t);
|
||||
unsigned long rfbi_get_max_tx_rate(void);
|
||||
int rfbi_init_display(struct omap_dss_device *display);
|
||||
#else
|
||||
static inline int rfbi_init(void)
|
||||
static inline int rfbi_init_platform_driver(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline void rfbi_exit(void)
|
||||
static inline void rfbi_uninit_platform_driver(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
@ -25,14 +25,18 @@
|
||||
#include <plat/display.h>
|
||||
#include <plat/cpu.h>
|
||||
|
||||
#include "dss.h"
|
||||
#include "dss_features.h"
|
||||
|
||||
/* Defines a generic omap register field */
|
||||
struct dss_reg_field {
|
||||
enum dss_feat_reg_field id;
|
||||
u8 start, end;
|
||||
};
|
||||
|
||||
struct dss_param_range {
|
||||
int min, max;
|
||||
};
|
||||
|
||||
struct omap_dss_features {
|
||||
const struct dss_reg_field *reg_fields;
|
||||
const int num_reg_fields;
|
||||
@ -43,28 +47,67 @@ struct omap_dss_features {
|
||||
const int num_ovls;
|
||||
const enum omap_display_type *supported_displays;
|
||||
const enum omap_color_mode *supported_color_modes;
|
||||
const char * const *clksrc_names;
|
||||
const struct dss_param_range *dss_params;
|
||||
};
|
||||
|
||||
/* This struct is assigned to one of the below during initialization */
|
||||
static struct omap_dss_features *omap_current_dss_features;
|
||||
|
||||
static const struct dss_reg_field omap2_dss_reg_fields[] = {
|
||||
{ FEAT_REG_FIRHINC, 11, 0 },
|
||||
{ FEAT_REG_FIRVINC, 27, 16 },
|
||||
{ FEAT_REG_FIFOLOWTHRESHOLD, 8, 0 },
|
||||
{ FEAT_REG_FIFOHIGHTHRESHOLD, 24, 16 },
|
||||
{ FEAT_REG_FIFOSIZE, 8, 0 },
|
||||
[FEAT_REG_FIRHINC] = { 11, 0 },
|
||||
[FEAT_REG_FIRVINC] = { 27, 16 },
|
||||
[FEAT_REG_FIFOLOWTHRESHOLD] = { 8, 0 },
|
||||
[FEAT_REG_FIFOHIGHTHRESHOLD] = { 24, 16 },
|
||||
[FEAT_REG_FIFOSIZE] = { 8, 0 },
|
||||
[FEAT_REG_HORIZONTALACCU] = { 9, 0 },
|
||||
[FEAT_REG_VERTICALACCU] = { 25, 16 },
|
||||
[FEAT_REG_DISPC_CLK_SWITCH] = { 0, 0 },
|
||||
[FEAT_REG_DSIPLL_REGN] = { 0, 0 },
|
||||
[FEAT_REG_DSIPLL_REGM] = { 0, 0 },
|
||||
[FEAT_REG_DSIPLL_REGM_DISPC] = { 0, 0 },
|
||||
[FEAT_REG_DSIPLL_REGM_DSI] = { 0, 0 },
|
||||
};
|
||||
|
||||
static const struct dss_reg_field omap3_dss_reg_fields[] = {
|
||||
{ FEAT_REG_FIRHINC, 12, 0 },
|
||||
{ FEAT_REG_FIRVINC, 28, 16 },
|
||||
{ FEAT_REG_FIFOLOWTHRESHOLD, 11, 0 },
|
||||
{ FEAT_REG_FIFOHIGHTHRESHOLD, 27, 16 },
|
||||
{ FEAT_REG_FIFOSIZE, 10, 0 },
|
||||
[FEAT_REG_FIRHINC] = { 12, 0 },
|
||||
[FEAT_REG_FIRVINC] = { 28, 16 },
|
||||
[FEAT_REG_FIFOLOWTHRESHOLD] = { 11, 0 },
|
||||
[FEAT_REG_FIFOHIGHTHRESHOLD] = { 27, 16 },
|
||||
[FEAT_REG_FIFOSIZE] = { 10, 0 },
|
||||
[FEAT_REG_HORIZONTALACCU] = { 9, 0 },
|
||||
[FEAT_REG_VERTICALACCU] = { 25, 16 },
|
||||
[FEAT_REG_DISPC_CLK_SWITCH] = { 0, 0 },
|
||||
[FEAT_REG_DSIPLL_REGN] = { 7, 1 },
|
||||
[FEAT_REG_DSIPLL_REGM] = { 18, 8 },
|
||||
[FEAT_REG_DSIPLL_REGM_DISPC] = { 22, 19 },
|
||||
[FEAT_REG_DSIPLL_REGM_DSI] = { 26, 23 },
|
||||
};
|
||||
|
||||
static const struct dss_reg_field omap4_dss_reg_fields[] = {
|
||||
[FEAT_REG_FIRHINC] = { 12, 0 },
|
||||
[FEAT_REG_FIRVINC] = { 28, 16 },
|
||||
[FEAT_REG_FIFOLOWTHRESHOLD] = { 15, 0 },
|
||||
[FEAT_REG_FIFOHIGHTHRESHOLD] = { 31, 16 },
|
||||
[FEAT_REG_FIFOSIZE] = { 15, 0 },
|
||||
[FEAT_REG_HORIZONTALACCU] = { 10, 0 },
|
||||
[FEAT_REG_VERTICALACCU] = { 26, 16 },
|
||||
[FEAT_REG_DISPC_CLK_SWITCH] = { 9, 8 },
|
||||
[FEAT_REG_DSIPLL_REGN] = { 8, 1 },
|
||||
[FEAT_REG_DSIPLL_REGM] = { 20, 9 },
|
||||
[FEAT_REG_DSIPLL_REGM_DISPC] = { 25, 21 },
|
||||
[FEAT_REG_DSIPLL_REGM_DSI] = { 30, 26 },
|
||||
};
|
||||
|
||||
static const enum omap_display_type omap2_dss_supported_displays[] = {
|
||||
/* OMAP_DSS_CHANNEL_LCD */
|
||||
OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI,
|
||||
|
||||
/* OMAP_DSS_CHANNEL_DIGIT */
|
||||
OMAP_DISPLAY_TYPE_VENC,
|
||||
};
|
||||
|
||||
static const enum omap_display_type omap3430_dss_supported_displays[] = {
|
||||
/* OMAP_DSS_CHANNEL_LCD */
|
||||
OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI |
|
||||
OMAP_DISPLAY_TYPE_SDI | OMAP_DISPLAY_TYPE_DSI,
|
||||
@ -73,10 +116,10 @@ static const enum omap_display_type omap2_dss_supported_displays[] = {
|
||||
OMAP_DISPLAY_TYPE_VENC,
|
||||
};
|
||||
|
||||
static const enum omap_display_type omap3_dss_supported_displays[] = {
|
||||
static const enum omap_display_type omap3630_dss_supported_displays[] = {
|
||||
/* OMAP_DSS_CHANNEL_LCD */
|
||||
OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI |
|
||||
OMAP_DISPLAY_TYPE_SDI | OMAP_DISPLAY_TYPE_DSI,
|
||||
OMAP_DISPLAY_TYPE_DSI,
|
||||
|
||||
/* OMAP_DSS_CHANNEL_DIGIT */
|
||||
OMAP_DISPLAY_TYPE_VENC,
|
||||
@ -87,7 +130,7 @@ static const enum omap_display_type omap4_dss_supported_displays[] = {
|
||||
OMAP_DISPLAY_TYPE_DBI | OMAP_DISPLAY_TYPE_DSI,
|
||||
|
||||
/* OMAP_DSS_CHANNEL_DIGIT */
|
||||
OMAP_DISPLAY_TYPE_VENC,
|
||||
OMAP_DISPLAY_TYPE_VENC | OMAP_DISPLAY_TYPE_HDMI,
|
||||
|
||||
/* OMAP_DSS_CHANNEL_LCD2 */
|
||||
OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI |
|
||||
@ -134,6 +177,54 @@ static const enum omap_color_mode omap3_dss_supported_color_modes[] = {
|
||||
OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_RGBX32,
|
||||
};
|
||||
|
||||
static const char * const omap2_dss_clk_source_names[] = {
|
||||
[DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "N/A",
|
||||
[DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "N/A",
|
||||
[DSS_CLK_SRC_FCK] = "DSS_FCLK1",
|
||||
};
|
||||
|
||||
static const char * const omap3_dss_clk_source_names[] = {
|
||||
[DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "DSI1_PLL_FCLK",
|
||||
[DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "DSI2_PLL_FCLK",
|
||||
[DSS_CLK_SRC_FCK] = "DSS1_ALWON_FCLK",
|
||||
};
|
||||
|
||||
static const char * const omap4_dss_clk_source_names[] = {
|
||||
[DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "PLL1_CLK1",
|
||||
[DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "PLL1_CLK2",
|
||||
[DSS_CLK_SRC_FCK] = "DSS_FCLK",
|
||||
};
|
||||
|
||||
static const struct dss_param_range omap2_dss_param_range[] = {
|
||||
[FEAT_PARAM_DSS_FCK] = { 0, 173000000 },
|
||||
[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 },
|
||||
};
|
||||
|
||||
static const struct dss_param_range omap3_dss_param_range[] = {
|
||||
[FEAT_PARAM_DSS_FCK] = { 0, 173000000 },
|
||||
[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},
|
||||
};
|
||||
|
||||
static const struct dss_param_range omap4_dss_param_range[] = {
|
||||
[FEAT_PARAM_DSS_FCK] = { 0, 186000000 },
|
||||
[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 },
|
||||
};
|
||||
|
||||
/* OMAP2 DSS Features */
|
||||
static struct omap_dss_features omap2_dss_features = {
|
||||
.reg_fields = omap2_dss_reg_fields,
|
||||
@ -141,12 +232,15 @@ static struct omap_dss_features omap2_dss_features = {
|
||||
|
||||
.has_feature =
|
||||
FEAT_LCDENABLEPOL | FEAT_LCDENABLESIGNAL |
|
||||
FEAT_PCKFREEENABLE | FEAT_FUNCGATED,
|
||||
FEAT_PCKFREEENABLE | FEAT_FUNCGATED |
|
||||
FEAT_ROWREPEATENABLE | FEAT_RESIZECONF,
|
||||
|
||||
.num_mgrs = 2,
|
||||
.num_ovls = 3,
|
||||
.supported_displays = omap2_dss_supported_displays,
|
||||
.supported_color_modes = omap2_dss_supported_color_modes,
|
||||
.clksrc_names = omap2_dss_clk_source_names,
|
||||
.dss_params = omap2_dss_param_range,
|
||||
};
|
||||
|
||||
/* OMAP3 DSS Features */
|
||||
@ -157,12 +251,15 @@ static struct omap_dss_features omap3430_dss_features = {
|
||||
.has_feature =
|
||||
FEAT_GLOBAL_ALPHA | FEAT_LCDENABLEPOL |
|
||||
FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE |
|
||||
FEAT_FUNCGATED,
|
||||
FEAT_FUNCGATED | FEAT_ROWREPEATENABLE |
|
||||
FEAT_LINEBUFFERSPLIT | FEAT_RESIZECONF,
|
||||
|
||||
.num_mgrs = 2,
|
||||
.num_ovls = 3,
|
||||
.supported_displays = omap3_dss_supported_displays,
|
||||
.supported_displays = omap3430_dss_supported_displays,
|
||||
.supported_color_modes = omap3_dss_supported_color_modes,
|
||||
.clksrc_names = omap3_dss_clk_source_names,
|
||||
.dss_params = omap3_dss_param_range,
|
||||
};
|
||||
|
||||
static struct omap_dss_features omap3630_dss_features = {
|
||||
@ -172,27 +269,34 @@ static struct omap_dss_features omap3630_dss_features = {
|
||||
.has_feature =
|
||||
FEAT_GLOBAL_ALPHA | FEAT_LCDENABLEPOL |
|
||||
FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE |
|
||||
FEAT_PRE_MULT_ALPHA | FEAT_FUNCGATED,
|
||||
FEAT_PRE_MULT_ALPHA | FEAT_FUNCGATED |
|
||||
FEAT_ROWREPEATENABLE | FEAT_LINEBUFFERSPLIT |
|
||||
FEAT_RESIZECONF,
|
||||
|
||||
.num_mgrs = 2,
|
||||
.num_ovls = 3,
|
||||
.supported_displays = omap3_dss_supported_displays,
|
||||
.supported_displays = omap3630_dss_supported_displays,
|
||||
.supported_color_modes = omap3_dss_supported_color_modes,
|
||||
.clksrc_names = omap3_dss_clk_source_names,
|
||||
.dss_params = omap3_dss_param_range,
|
||||
};
|
||||
|
||||
/* OMAP4 DSS Features */
|
||||
static struct omap_dss_features omap4_dss_features = {
|
||||
.reg_fields = omap3_dss_reg_fields,
|
||||
.num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields),
|
||||
.reg_fields = omap4_dss_reg_fields,
|
||||
.num_reg_fields = ARRAY_SIZE(omap4_dss_reg_fields),
|
||||
|
||||
.has_feature =
|
||||
FEAT_GLOBAL_ALPHA | FEAT_PRE_MULT_ALPHA |
|
||||
FEAT_MGR_LCD2,
|
||||
FEAT_MGR_LCD2 | FEAT_GLOBAL_ALPHA_VID1 |
|
||||
FEAT_CORE_CLK_DIV | FEAT_LCD_CLK_SRC,
|
||||
|
||||
.num_mgrs = 3,
|
||||
.num_ovls = 3,
|
||||
.supported_displays = omap4_dss_supported_displays,
|
||||
.supported_color_modes = omap3_dss_supported_color_modes,
|
||||
.clksrc_names = omap4_dss_clk_source_names,
|
||||
.dss_params = omap4_dss_param_range,
|
||||
};
|
||||
|
||||
/* Functions returning values related to a DSS feature */
|
||||
@ -206,6 +310,16 @@ int dss_feat_get_num_ovls(void)
|
||||
return omap_current_dss_features->num_ovls;
|
||||
}
|
||||
|
||||
unsigned long dss_feat_get_param_min(enum dss_range_param param)
|
||||
{
|
||||
return omap_current_dss_features->dss_params[param].min;
|
||||
}
|
||||
|
||||
unsigned long dss_feat_get_param_max(enum dss_range_param param)
|
||||
{
|
||||
return omap_current_dss_features->dss_params[param].max;
|
||||
}
|
||||
|
||||
enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel)
|
||||
{
|
||||
return omap_current_dss_features->supported_displays[channel];
|
||||
@ -223,6 +337,11 @@ bool dss_feat_color_mode_supported(enum omap_plane plane,
|
||||
color_mode;
|
||||
}
|
||||
|
||||
const char *dss_feat_get_clk_source_name(enum dss_clk_source id)
|
||||
{
|
||||
return omap_current_dss_features->clksrc_names[id];
|
||||
}
|
||||
|
||||
/* DSS has_feature check */
|
||||
bool dss_has_feature(enum dss_feat_id id)
|
||||
{
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
#define MAX_DSS_MANAGERS 3
|
||||
#define MAX_DSS_OVERLAYS 3
|
||||
#define MAX_DSS_LCD_MANAGERS 2
|
||||
|
||||
/* DSS has feature id */
|
||||
enum dss_feat_id {
|
||||
@ -33,6 +34,12 @@ enum dss_feat_id {
|
||||
FEAT_PCKFREEENABLE = 1 << 5,
|
||||
FEAT_FUNCGATED = 1 << 6,
|
||||
FEAT_MGR_LCD2 = 1 << 7,
|
||||
FEAT_LINEBUFFERSPLIT = 1 << 8,
|
||||
FEAT_ROWREPEATENABLE = 1 << 9,
|
||||
FEAT_RESIZECONF = 1 << 10,
|
||||
/* Independent core clk divider */
|
||||
FEAT_CORE_CLK_DIV = 1 << 11,
|
||||
FEAT_LCD_CLK_SRC = 1 << 12,
|
||||
};
|
||||
|
||||
/* DSS register field id */
|
||||
@ -42,15 +49,35 @@ enum dss_feat_reg_field {
|
||||
FEAT_REG_FIFOHIGHTHRESHOLD,
|
||||
FEAT_REG_FIFOLOWTHRESHOLD,
|
||||
FEAT_REG_FIFOSIZE,
|
||||
FEAT_REG_HORIZONTALACCU,
|
||||
FEAT_REG_VERTICALACCU,
|
||||
FEAT_REG_DISPC_CLK_SWITCH,
|
||||
FEAT_REG_DSIPLL_REGN,
|
||||
FEAT_REG_DSIPLL_REGM,
|
||||
FEAT_REG_DSIPLL_REGM_DISPC,
|
||||
FEAT_REG_DSIPLL_REGM_DSI,
|
||||
};
|
||||
|
||||
enum dss_range_param {
|
||||
FEAT_PARAM_DSS_FCK,
|
||||
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,
|
||||
};
|
||||
|
||||
/* DSS Feature Functions */
|
||||
int dss_feat_get_num_mgrs(void);
|
||||
int dss_feat_get_num_ovls(void);
|
||||
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);
|
||||
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 dss_clk_source id);
|
||||
|
||||
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);
|
||||
|
1332
drivers/video/omap2/dss/hdmi.c
Normal file
1332
drivers/video/omap2/dss/hdmi.c
Normal file
File diff suppressed because it is too large
Load Diff
415
drivers/video/omap2/dss/hdmi.h
Normal file
415
drivers/video/omap2/dss/hdmi.h
Normal file
@ -0,0 +1,415 @@
|
||||
/*
|
||||
* hdmi.h
|
||||
*
|
||||
* HDMI driver definition for TI OMAP4 processors.
|
||||
*
|
||||
* Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.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 _OMAP4_DSS_HDMI_H_
|
||||
#define _OMAP4_DSS_HDMI_H_
|
||||
|
||||
#include <linux/string.h>
|
||||
#include <plat/display.h>
|
||||
|
||||
#define HDMI_WP 0x0
|
||||
#define HDMI_CORE_SYS 0x400
|
||||
#define HDMI_CORE_AV 0x900
|
||||
#define HDMI_PLLCTRL 0x200
|
||||
#define HDMI_PHY 0x300
|
||||
|
||||
struct hdmi_reg { u16 idx; };
|
||||
|
||||
#define HDMI_REG(idx) ((const struct hdmi_reg) { idx })
|
||||
|
||||
/* HDMI Wrapper */
|
||||
#define HDMI_WP_REG(idx) HDMI_REG(HDMI_WP + idx)
|
||||
|
||||
#define HDMI_WP_REVISION HDMI_WP_REG(0x0)
|
||||
#define HDMI_WP_SYSCONFIG HDMI_WP_REG(0x10)
|
||||
#define HDMI_WP_IRQSTATUS_RAW HDMI_WP_REG(0x24)
|
||||
#define HDMI_WP_IRQSTATUS HDMI_WP_REG(0x28)
|
||||
#define HDMI_WP_PWR_CTRL HDMI_WP_REG(0x40)
|
||||
#define HDMI_WP_IRQENABLE_SET HDMI_WP_REG(0x2C)
|
||||
#define HDMI_WP_VIDEO_CFG HDMI_WP_REG(0x50)
|
||||
#define HDMI_WP_VIDEO_SIZE HDMI_WP_REG(0x60)
|
||||
#define HDMI_WP_VIDEO_TIMING_H HDMI_WP_REG(0x68)
|
||||
#define HDMI_WP_VIDEO_TIMING_V HDMI_WP_REG(0x6C)
|
||||
#define HDMI_WP_WP_CLK HDMI_WP_REG(0x70)
|
||||
|
||||
/* HDMI IP Core System */
|
||||
#define HDMI_CORE_SYS_REG(idx) HDMI_REG(HDMI_CORE_SYS + idx)
|
||||
|
||||
#define HDMI_CORE_SYS_VND_IDL HDMI_CORE_SYS_REG(0x0)
|
||||
#define HDMI_CORE_SYS_DEV_IDL HDMI_CORE_SYS_REG(0x8)
|
||||
#define HDMI_CORE_SYS_DEV_IDH HDMI_CORE_SYS_REG(0xC)
|
||||
#define HDMI_CORE_SYS_DEV_REV HDMI_CORE_SYS_REG(0x10)
|
||||
#define HDMI_CORE_SYS_SRST HDMI_CORE_SYS_REG(0x14)
|
||||
#define HDMI_CORE_CTRL1 HDMI_CORE_SYS_REG(0x20)
|
||||
#define HDMI_CORE_SYS_SYS_STAT HDMI_CORE_SYS_REG(0x24)
|
||||
#define HDMI_CORE_SYS_VID_ACEN HDMI_CORE_SYS_REG(0x124)
|
||||
#define HDMI_CORE_SYS_VID_MODE HDMI_CORE_SYS_REG(0x128)
|
||||
#define HDMI_CORE_SYS_INTR_STATE HDMI_CORE_SYS_REG(0x1C0)
|
||||
#define HDMI_CORE_SYS_INTR1 HDMI_CORE_SYS_REG(0x1C4)
|
||||
#define HDMI_CORE_SYS_INTR2 HDMI_CORE_SYS_REG(0x1C8)
|
||||
#define HDMI_CORE_SYS_INTR3 HDMI_CORE_SYS_REG(0x1CC)
|
||||
#define HDMI_CORE_SYS_INTR4 HDMI_CORE_SYS_REG(0x1D0)
|
||||
#define HDMI_CORE_SYS_UMASK1 HDMI_CORE_SYS_REG(0x1D4)
|
||||
#define HDMI_CORE_SYS_TMDS_CTRL HDMI_CORE_SYS_REG(0x208)
|
||||
#define HDMI_CORE_SYS_DE_DLY HDMI_CORE_SYS_REG(0xC8)
|
||||
#define HDMI_CORE_SYS_DE_CTRL HDMI_CORE_SYS_REG(0xCC)
|
||||
#define HDMI_CORE_SYS_DE_TOP HDMI_CORE_SYS_REG(0xD0)
|
||||
#define HDMI_CORE_SYS_DE_CNTL HDMI_CORE_SYS_REG(0xD8)
|
||||
#define HDMI_CORE_SYS_DE_CNTH HDMI_CORE_SYS_REG(0xDC)
|
||||
#define HDMI_CORE_SYS_DE_LINL HDMI_CORE_SYS_REG(0xE0)
|
||||
#define HDMI_CORE_SYS_DE_LINH_1 HDMI_CORE_SYS_REG(0xE4)
|
||||
#define HDMI_CORE_CTRL1_VEN_FOLLOWVSYNC 0x1
|
||||
#define HDMI_CORE_CTRL1_HEN_FOLLOWHSYNC 0x1
|
||||
#define HDMI_CORE_CTRL1_BSEL_24BITBUS 0x1
|
||||
#define HDMI_CORE_CTRL1_EDGE_RISINGEDGE 0x1
|
||||
|
||||
/* HDMI DDC E-DID */
|
||||
#define HDMI_CORE_DDC_CMD HDMI_CORE_SYS_REG(0x3CC)
|
||||
#define HDMI_CORE_DDC_STATUS HDMI_CORE_SYS_REG(0x3C8)
|
||||
#define HDMI_CORE_DDC_ADDR HDMI_CORE_SYS_REG(0x3B4)
|
||||
#define HDMI_CORE_DDC_OFFSET HDMI_CORE_SYS_REG(0x3BC)
|
||||
#define HDMI_CORE_DDC_COUNT1 HDMI_CORE_SYS_REG(0x3C0)
|
||||
#define HDMI_CORE_DDC_COUNT2 HDMI_CORE_SYS_REG(0x3C4)
|
||||
#define HDMI_CORE_DDC_DATA HDMI_CORE_SYS_REG(0x3D0)
|
||||
#define HDMI_CORE_DDC_SEGM HDMI_CORE_SYS_REG(0x3B8)
|
||||
|
||||
/* HDMI IP Core Audio Video */
|
||||
#define HDMI_CORE_AV_REG(idx) HDMI_REG(HDMI_CORE_AV + idx)
|
||||
|
||||
#define HDMI_CORE_AV_HDMI_CTRL HDMI_CORE_AV_REG(0xBC)
|
||||
#define HDMI_CORE_AV_DPD HDMI_CORE_AV_REG(0xF4)
|
||||
#define HDMI_CORE_AV_PB_CTRL1 HDMI_CORE_AV_REG(0xF8)
|
||||
#define HDMI_CORE_AV_PB_CTRL2 HDMI_CORE_AV_REG(0xFC)
|
||||
#define HDMI_CORE_AV_AVI_TYPE HDMI_CORE_AV_REG(0x100)
|
||||
#define HDMI_CORE_AV_AVI_VERS HDMI_CORE_AV_REG(0x104)
|
||||
#define HDMI_CORE_AV_AVI_LEN HDMI_CORE_AV_REG(0x108)
|
||||
#define HDMI_CORE_AV_AVI_CHSUM HDMI_CORE_AV_REG(0x10C)
|
||||
#define HDMI_CORE_AV_AVI_DBYTE(n) HDMI_CORE_AV_REG(n * 4 + 0x110)
|
||||
#define HDMI_CORE_AV_AVI_DBYTE_NELEMS HDMI_CORE_AV_REG(15)
|
||||
#define HDMI_CORE_AV_SPD_DBYTE HDMI_CORE_AV_REG(0x190)
|
||||
#define HDMI_CORE_AV_SPD_DBYTE_NELEMS HDMI_CORE_AV_REG(27)
|
||||
#define HDMI_CORE_AV_MPEG_DBYTE HDMI_CORE_AV_REG(0x290)
|
||||
#define HDMI_CORE_AV_MPEG_DBYTE_NELEMS HDMI_CORE_AV_REG(27)
|
||||
#define HDMI_CORE_AV_GEN_DBYTE HDMI_CORE_AV_REG(0x300)
|
||||
#define HDMI_CORE_AV_GEN_DBYTE_NELEMS HDMI_CORE_AV_REG(31)
|
||||
#define HDMI_CORE_AV_GEN2_DBYTE HDMI_CORE_AV_REG(0x380)
|
||||
#define HDMI_CORE_AV_GEN2_DBYTE_NELEMS HDMI_CORE_AV_REG(31)
|
||||
#define HDMI_CORE_AV_ACR_CTRL HDMI_CORE_AV_REG(0x4)
|
||||
#define HDMI_CORE_AV_FREQ_SVAL HDMI_CORE_AV_REG(0x8)
|
||||
#define HDMI_CORE_AV_N_SVAL1 HDMI_CORE_AV_REG(0xC)
|
||||
#define HDMI_CORE_AV_N_SVAL2 HDMI_CORE_AV_REG(0x10)
|
||||
#define HDMI_CORE_AV_N_SVAL3 HDMI_CORE_AV_REG(0x14)
|
||||
#define HDMI_CORE_AV_CTS_SVAL1 HDMI_CORE_AV_REG(0x18)
|
||||
#define HDMI_CORE_AV_CTS_SVAL2 HDMI_CORE_AV_REG(0x1C)
|
||||
#define HDMI_CORE_AV_CTS_SVAL3 HDMI_CORE_AV_REG(0x20)
|
||||
#define HDMI_CORE_AV_CTS_HVAL1 HDMI_CORE_AV_REG(0x24)
|
||||
#define HDMI_CORE_AV_CTS_HVAL2 HDMI_CORE_AV_REG(0x28)
|
||||
#define HDMI_CORE_AV_CTS_HVAL3 HDMI_CORE_AV_REG(0x2C)
|
||||
#define HDMI_CORE_AV_AUD_MODE HDMI_CORE_AV_REG(0x50)
|
||||
#define HDMI_CORE_AV_SPDIF_CTRL HDMI_CORE_AV_REG(0x54)
|
||||
#define HDMI_CORE_AV_HW_SPDIF_FS HDMI_CORE_AV_REG(0x60)
|
||||
#define HDMI_CORE_AV_SWAP_I2S HDMI_CORE_AV_REG(0x64)
|
||||
#define HDMI_CORE_AV_SPDIF_ERTH HDMI_CORE_AV_REG(0x6C)
|
||||
#define HDMI_CORE_AV_I2S_IN_MAP HDMI_CORE_AV_REG(0x70)
|
||||
#define HDMI_CORE_AV_I2S_IN_CTRL HDMI_CORE_AV_REG(0x74)
|
||||
#define HDMI_CORE_AV_I2S_CHST0 HDMI_CORE_AV_REG(0x78)
|
||||
#define HDMI_CORE_AV_I2S_CHST1 HDMI_CORE_AV_REG(0x7C)
|
||||
#define HDMI_CORE_AV_I2S_CHST2 HDMI_CORE_AV_REG(0x80)
|
||||
#define HDMI_CORE_AV_I2S_CHST4 HDMI_CORE_AV_REG(0x84)
|
||||
#define HDMI_CORE_AV_I2S_CHST5 HDMI_CORE_AV_REG(0x88)
|
||||
#define HDMI_CORE_AV_ASRC HDMI_CORE_AV_REG(0x8C)
|
||||
#define HDMI_CORE_AV_I2S_IN_LEN HDMI_CORE_AV_REG(0x90)
|
||||
#define HDMI_CORE_AV_HDMI_CTRL HDMI_CORE_AV_REG(0xBC)
|
||||
#define HDMI_CORE_AV_AUDO_TXSTAT HDMI_CORE_AV_REG(0xC0)
|
||||
#define HDMI_CORE_AV_AUD_PAR_BUSCLK_1 HDMI_CORE_AV_REG(0xCC)
|
||||
#define HDMI_CORE_AV_AUD_PAR_BUSCLK_2 HDMI_CORE_AV_REG(0xD0)
|
||||
#define HDMI_CORE_AV_AUD_PAR_BUSCLK_3 HDMI_CORE_AV_REG(0xD4)
|
||||
#define HDMI_CORE_AV_TEST_TXCTRL HDMI_CORE_AV_REG(0xF0)
|
||||
#define HDMI_CORE_AV_DPD HDMI_CORE_AV_REG(0xF4)
|
||||
#define HDMI_CORE_AV_PB_CTRL1 HDMI_CORE_AV_REG(0xF8)
|
||||
#define HDMI_CORE_AV_PB_CTRL2 HDMI_CORE_AV_REG(0xFC)
|
||||
#define HDMI_CORE_AV_AVI_TYPE HDMI_CORE_AV_REG(0x100)
|
||||
#define HDMI_CORE_AV_AVI_VERS HDMI_CORE_AV_REG(0x104)
|
||||
#define HDMI_CORE_AV_AVI_LEN HDMI_CORE_AV_REG(0x108)
|
||||
#define HDMI_CORE_AV_AVI_CHSUM HDMI_CORE_AV_REG(0x10C)
|
||||
#define HDMI_CORE_AV_SPD_TYPE HDMI_CORE_AV_REG(0x180)
|
||||
#define HDMI_CORE_AV_SPD_VERS HDMI_CORE_AV_REG(0x184)
|
||||
#define HDMI_CORE_AV_SPD_LEN HDMI_CORE_AV_REG(0x188)
|
||||
#define HDMI_CORE_AV_SPD_CHSUM HDMI_CORE_AV_REG(0x18C)
|
||||
#define HDMI_CORE_AV_MPEG_TYPE HDMI_CORE_AV_REG(0x280)
|
||||
#define HDMI_CORE_AV_MPEG_VERS HDMI_CORE_AV_REG(0x284)
|
||||
#define HDMI_CORE_AV_MPEG_LEN HDMI_CORE_AV_REG(0x288)
|
||||
#define HDMI_CORE_AV_MPEG_CHSUM HDMI_CORE_AV_REG(0x28C)
|
||||
#define HDMI_CORE_AV_CP_BYTE1 HDMI_CORE_AV_REG(0x37C)
|
||||
#define HDMI_CORE_AV_CEC_ADDR_ID HDMI_CORE_AV_REG(0x3FC)
|
||||
#define HDMI_CORE_AV_SPD_DBYTE_ELSIZE 0x4
|
||||
#define HDMI_CORE_AV_GEN2_DBYTE_ELSIZE 0x4
|
||||
#define HDMI_CORE_AV_MPEG_DBYTE_ELSIZE 0x4
|
||||
#define HDMI_CORE_AV_GEN_DBYTE_ELSIZE 0x4
|
||||
|
||||
/* PLL */
|
||||
#define HDMI_PLL_REG(idx) HDMI_REG(HDMI_PLLCTRL + idx)
|
||||
|
||||
#define PLLCTRL_PLL_CONTROL HDMI_PLL_REG(0x0)
|
||||
#define PLLCTRL_PLL_STATUS HDMI_PLL_REG(0x4)
|
||||
#define PLLCTRL_PLL_GO HDMI_PLL_REG(0x8)
|
||||
#define PLLCTRL_CFG1 HDMI_PLL_REG(0xC)
|
||||
#define PLLCTRL_CFG2 HDMI_PLL_REG(0x10)
|
||||
#define PLLCTRL_CFG3 HDMI_PLL_REG(0x14)
|
||||
#define PLLCTRL_CFG4 HDMI_PLL_REG(0x20)
|
||||
|
||||
/* HDMI PHY */
|
||||
#define HDMI_PHY_REG(idx) HDMI_REG(HDMI_PHY + idx)
|
||||
|
||||
#define HDMI_TXPHY_TX_CTRL HDMI_PHY_REG(0x0)
|
||||
#define HDMI_TXPHY_DIGITAL_CTRL HDMI_PHY_REG(0x4)
|
||||
#define HDMI_TXPHY_POWER_CTRL HDMI_PHY_REG(0x8)
|
||||
#define HDMI_TXPHY_PAD_CFG_CTRL HDMI_PHY_REG(0xC)
|
||||
|
||||
/* HDMI EDID Length */
|
||||
#define HDMI_EDID_MAX_LENGTH 256
|
||||
#define EDID_TIMING_DESCRIPTOR_SIZE 0x12
|
||||
#define EDID_DESCRIPTOR_BLOCK0_ADDRESS 0x36
|
||||
#define EDID_DESCRIPTOR_BLOCK1_ADDRESS 0x80
|
||||
#define EDID_SIZE_BLOCK0_TIMING_DESCRIPTOR 4
|
||||
#define EDID_SIZE_BLOCK1_TIMING_DESCRIPTOR 4
|
||||
|
||||
#define OMAP_HDMI_TIMINGS_NB 34
|
||||
|
||||
#define REG_FLD_MOD(idx, val, start, end) \
|
||||
hdmi_write_reg(idx, FLD_MOD(hdmi_read_reg(idx), val, start, end))
|
||||
#define REG_GET(idx, start, end) \
|
||||
FLD_GET(hdmi_read_reg(idx), start, end)
|
||||
|
||||
/* HDMI timing structure */
|
||||
struct hdmi_timings {
|
||||
struct omap_video_timings timings;
|
||||
int vsync_pol;
|
||||
int hsync_pol;
|
||||
};
|
||||
|
||||
enum hdmi_phy_pwr {
|
||||
HDMI_PHYPWRCMD_OFF = 0,
|
||||
HDMI_PHYPWRCMD_LDOON = 1,
|
||||
HDMI_PHYPWRCMD_TXON = 2
|
||||
};
|
||||
|
||||
enum hdmi_pll_pwr {
|
||||
HDMI_PLLPWRCMD_ALLOFF = 0,
|
||||
HDMI_PLLPWRCMD_PLLONLY = 1,
|
||||
HDMI_PLLPWRCMD_BOTHON_ALLCLKS = 2,
|
||||
HDMI_PLLPWRCMD_BOTHON_NOPHYCLK = 3
|
||||
};
|
||||
|
||||
enum hdmi_clk_refsel {
|
||||
HDMI_REFSEL_PCLK = 0,
|
||||
HDMI_REFSEL_REF1 = 1,
|
||||
HDMI_REFSEL_REF2 = 2,
|
||||
HDMI_REFSEL_SYSCLK = 3
|
||||
};
|
||||
|
||||
enum hdmi_core_inputbus_width {
|
||||
HDMI_INPUT_8BIT = 0,
|
||||
HDMI_INPUT_10BIT = 1,
|
||||
HDMI_INPUT_12BIT = 2
|
||||
};
|
||||
|
||||
enum hdmi_core_dither_trunc {
|
||||
HDMI_OUTPUTTRUNCATION_8BIT = 0,
|
||||
HDMI_OUTPUTTRUNCATION_10BIT = 1,
|
||||
HDMI_OUTPUTTRUNCATION_12BIT = 2,
|
||||
HDMI_OUTPUTDITHER_8BIT = 3,
|
||||
HDMI_OUTPUTDITHER_10BIT = 4,
|
||||
HDMI_OUTPUTDITHER_12BIT = 5
|
||||
};
|
||||
|
||||
enum hdmi_core_deepcolor_ed {
|
||||
HDMI_DEEPCOLORPACKECTDISABLE = 0,
|
||||
HDMI_DEEPCOLORPACKECTENABLE = 1
|
||||
};
|
||||
|
||||
enum hdmi_core_packet_mode {
|
||||
HDMI_PACKETMODERESERVEDVALUE = 0,
|
||||
HDMI_PACKETMODE24BITPERPIXEL = 4,
|
||||
HDMI_PACKETMODE30BITPERPIXEL = 5,
|
||||
HDMI_PACKETMODE36BITPERPIXEL = 6,
|
||||
HDMI_PACKETMODE48BITPERPIXEL = 7
|
||||
};
|
||||
|
||||
enum hdmi_core_hdmi_dvi {
|
||||
HDMI_DVI = 0,
|
||||
HDMI_HDMI = 1
|
||||
};
|
||||
|
||||
enum hdmi_core_tclkselclkmult {
|
||||
HDMI_FPLL05IDCK = 0,
|
||||
HDMI_FPLL10IDCK = 1,
|
||||
HDMI_FPLL20IDCK = 2,
|
||||
HDMI_FPLL40IDCK = 3
|
||||
};
|
||||
|
||||
enum hdmi_core_packet_ctrl {
|
||||
HDMI_PACKETENABLE = 1,
|
||||
HDMI_PACKETDISABLE = 0,
|
||||
HDMI_PACKETREPEATON = 1,
|
||||
HDMI_PACKETREPEATOFF = 0
|
||||
};
|
||||
|
||||
/* INFOFRAME_AVI_ definitions */
|
||||
enum hdmi_core_infoframe {
|
||||
HDMI_INFOFRAME_AVI_DB1Y_RGB = 0,
|
||||
HDMI_INFOFRAME_AVI_DB1Y_YUV422 = 1,
|
||||
HDMI_INFOFRAME_AVI_DB1Y_YUV444 = 2,
|
||||
HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF = 0,
|
||||
HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_ON = 1,
|
||||
HDMI_INFOFRAME_AVI_DB1B_NO = 0,
|
||||
HDMI_INFOFRAME_AVI_DB1B_VERT = 1,
|
||||
HDMI_INFOFRAME_AVI_DB1B_HORI = 2,
|
||||
HDMI_INFOFRAME_AVI_DB1B_VERTHORI = 3,
|
||||
HDMI_INFOFRAME_AVI_DB1S_0 = 0,
|
||||
HDMI_INFOFRAME_AVI_DB1S_1 = 1,
|
||||
HDMI_INFOFRAME_AVI_DB1S_2 = 2,
|
||||
HDMI_INFOFRAME_AVI_DB2C_NO = 0,
|
||||
HDMI_INFOFRAME_AVI_DB2C_ITU601 = 1,
|
||||
HDMI_INFOFRAME_AVI_DB2C_ITU709 = 2,
|
||||
HDMI_INFOFRAME_AVI_DB2C_EC_EXTENDED = 3,
|
||||
HDMI_INFOFRAME_AVI_DB2M_NO = 0,
|
||||
HDMI_INFOFRAME_AVI_DB2M_43 = 1,
|
||||
HDMI_INFOFRAME_AVI_DB2M_169 = 2,
|
||||
HDMI_INFOFRAME_AVI_DB2R_SAME = 8,
|
||||
HDMI_INFOFRAME_AVI_DB2R_43 = 9,
|
||||
HDMI_INFOFRAME_AVI_DB2R_169 = 10,
|
||||
HDMI_INFOFRAME_AVI_DB2R_149 = 11,
|
||||
HDMI_INFOFRAME_AVI_DB3ITC_NO = 0,
|
||||
HDMI_INFOFRAME_AVI_DB3ITC_YES = 1,
|
||||
HDMI_INFOFRAME_AVI_DB3EC_XVYUV601 = 0,
|
||||
HDMI_INFOFRAME_AVI_DB3EC_XVYUV709 = 1,
|
||||
HDMI_INFOFRAME_AVI_DB3Q_DEFAULT = 0,
|
||||
HDMI_INFOFRAME_AVI_DB3Q_LR = 1,
|
||||
HDMI_INFOFRAME_AVI_DB3Q_FR = 2,
|
||||
HDMI_INFOFRAME_AVI_DB3SC_NO = 0,
|
||||
HDMI_INFOFRAME_AVI_DB3SC_HORI = 1,
|
||||
HDMI_INFOFRAME_AVI_DB3SC_VERT = 2,
|
||||
HDMI_INFOFRAME_AVI_DB3SC_HORIVERT = 3,
|
||||
HDMI_INFOFRAME_AVI_DB5PR_NO = 0,
|
||||
HDMI_INFOFRAME_AVI_DB5PR_2 = 1,
|
||||
HDMI_INFOFRAME_AVI_DB5PR_3 = 2,
|
||||
HDMI_INFOFRAME_AVI_DB5PR_4 = 3,
|
||||
HDMI_INFOFRAME_AVI_DB5PR_5 = 4,
|
||||
HDMI_INFOFRAME_AVI_DB5PR_6 = 5,
|
||||
HDMI_INFOFRAME_AVI_DB5PR_7 = 6,
|
||||
HDMI_INFOFRAME_AVI_DB5PR_8 = 7,
|
||||
HDMI_INFOFRAME_AVI_DB5PR_9 = 8,
|
||||
HDMI_INFOFRAME_AVI_DB5PR_10 = 9
|
||||
};
|
||||
|
||||
enum hdmi_packing_mode {
|
||||
HDMI_PACK_10b_RGB_YUV444 = 0,
|
||||
HDMI_PACK_24b_RGB_YUV444_YUV422 = 1,
|
||||
HDMI_PACK_20b_YUV422 = 2,
|
||||
HDMI_PACK_ALREADYPACKED = 7
|
||||
};
|
||||
|
||||
struct hdmi_core_video_config {
|
||||
enum hdmi_core_inputbus_width ip_bus_width;
|
||||
enum hdmi_core_dither_trunc op_dither_truc;
|
||||
enum hdmi_core_deepcolor_ed deep_color_pkt;
|
||||
enum hdmi_core_packet_mode pkt_mode;
|
||||
enum hdmi_core_hdmi_dvi hdmi_dvi;
|
||||
enum hdmi_core_tclkselclkmult tclk_sel_clkmult;
|
||||
};
|
||||
|
||||
/*
|
||||
* Refer to section 8.2 in HDMI 1.3 specification for
|
||||
* details about infoframe databytes
|
||||
*/
|
||||
struct hdmi_core_infoframe_avi {
|
||||
u8 db1_format;
|
||||
/* Y0, Y1 rgb,yCbCr */
|
||||
u8 db1_active_info;
|
||||
/* A0 Active information Present */
|
||||
u8 db1_bar_info_dv;
|
||||
/* B0, B1 Bar info data valid */
|
||||
u8 db1_scan_info;
|
||||
/* S0, S1 scan information */
|
||||
u8 db2_colorimetry;
|
||||
/* C0, C1 colorimetry */
|
||||
u8 db2_aspect_ratio;
|
||||
/* M0, M1 Aspect ratio (4:3, 16:9) */
|
||||
u8 db2_active_fmt_ar;
|
||||
/* R0...R3 Active format aspect ratio */
|
||||
u8 db3_itc;
|
||||
/* ITC IT content. */
|
||||
u8 db3_ec;
|
||||
/* EC0, EC1, EC2 Extended colorimetry */
|
||||
u8 db3_q_range;
|
||||
/* Q1, Q0 Quantization range */
|
||||
u8 db3_nup_scaling;
|
||||
/* SC1, SC0 Non-uniform picture scaling */
|
||||
u8 db4_videocode;
|
||||
/* VIC0..6 Video format identification */
|
||||
u8 db5_pixel_repeat;
|
||||
/* PR0..PR3 Pixel repetition factor */
|
||||
u16 db6_7_line_eoftop;
|
||||
/* Line number end of top bar */
|
||||
u16 db8_9_line_sofbottom;
|
||||
/* Line number start of bottom bar */
|
||||
u16 db10_11_pixel_eofleft;
|
||||
/* Pixel number end of left bar */
|
||||
u16 db12_13_pixel_sofright;
|
||||
/* Pixel number start of right bar */
|
||||
};
|
||||
|
||||
struct hdmi_core_packet_enable_repeat {
|
||||
u32 audio_pkt;
|
||||
u32 audio_pkt_repeat;
|
||||
u32 avi_infoframe;
|
||||
u32 avi_infoframe_repeat;
|
||||
u32 gen_cntrl_pkt;
|
||||
u32 gen_cntrl_pkt_repeat;
|
||||
u32 generic_pkt;
|
||||
u32 generic_pkt_repeat;
|
||||
};
|
||||
|
||||
struct hdmi_video_format {
|
||||
enum hdmi_packing_mode packing_mode;
|
||||
u32 y_res; /* Line per panel */
|
||||
u32 x_res; /* pixel per line */
|
||||
};
|
||||
|
||||
struct hdmi_video_interface {
|
||||
int vsp; /* Vsync polarity */
|
||||
int hsp; /* Hsync polarity */
|
||||
int interlacing;
|
||||
int tm; /* Timing mode */
|
||||
};
|
||||
|
||||
struct hdmi_cm {
|
||||
int code;
|
||||
int mode;
|
||||
};
|
||||
|
||||
struct hdmi_config {
|
||||
struct hdmi_timings timings;
|
||||
u16 interlace;
|
||||
struct hdmi_cm cm;
|
||||
};
|
||||
|
||||
#endif
|
222
drivers/video/omap2/dss/hdmi_omap4_panel.c
Normal file
222
drivers/video/omap2/dss/hdmi_omap4_panel.c
Normal file
@ -0,0 +1,222 @@
|
||||
/*
|
||||
* hdmi_omap4_panel.c
|
||||
*
|
||||
* HDMI library support functions for TI OMAP4 processors.
|
||||
*
|
||||
* Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/
|
||||
* Authors: 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/>.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/module.h>
|
||||
#include <plat/display.h>
|
||||
|
||||
#include "dss.h"
|
||||
|
||||
static struct {
|
||||
struct mutex hdmi_lock;
|
||||
} hdmi;
|
||||
|
||||
|
||||
static int hdmi_panel_probe(struct omap_dss_device *dssdev)
|
||||
{
|
||||
DSSDBG("ENTER hdmi_panel_probe\n");
|
||||
|
||||
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;
|
||||
|
||||
DSSDBG("hdmi_panel_probe x_res= %d y_res = %d\n",
|
||||
dssdev->panel.timings.x_res,
|
||||
dssdev->panel.timings.y_res);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void hdmi_panel_remove(struct omap_dss_device *dssdev)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static int hdmi_panel_enable(struct omap_dss_device *dssdev)
|
||||
{
|
||||
int r = 0;
|
||||
DSSDBG("ENTER hdmi_panel_enable\n");
|
||||
|
||||
mutex_lock(&hdmi.hdmi_lock);
|
||||
|
||||
if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
|
||||
r = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
r = omapdss_hdmi_display_enable(dssdev);
|
||||
if (r) {
|
||||
DSSERR("failed to power on\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
|
||||
|
||||
err:
|
||||
mutex_unlock(&hdmi.hdmi_lock);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static void hdmi_panel_disable(struct omap_dss_device *dssdev)
|
||||
{
|
||||
mutex_lock(&hdmi.hdmi_lock);
|
||||
|
||||
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
|
||||
omapdss_hdmi_display_disable(dssdev);
|
||||
|
||||
dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
|
||||
|
||||
mutex_unlock(&hdmi.hdmi_lock);
|
||||
}
|
||||
|
||||
static int hdmi_panel_suspend(struct omap_dss_device *dssdev)
|
||||
{
|
||||
int r = 0;
|
||||
|
||||
mutex_lock(&hdmi.hdmi_lock);
|
||||
|
||||
if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
|
||||
r = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
|
||||
|
||||
omapdss_hdmi_display_disable(dssdev);
|
||||
|
||||
err:
|
||||
mutex_unlock(&hdmi.hdmi_lock);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int hdmi_panel_resume(struct omap_dss_device *dssdev)
|
||||
{
|
||||
int r = 0;
|
||||
|
||||
mutex_lock(&hdmi.hdmi_lock);
|
||||
|
||||
if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) {
|
||||
r = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
r = omapdss_hdmi_display_enable(dssdev);
|
||||
if (r) {
|
||||
DSSERR("failed to power on\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
|
||||
|
||||
err:
|
||||
mutex_unlock(&hdmi.hdmi_lock);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static void hdmi_get_timings(struct omap_dss_device *dssdev,
|
||||
struct omap_video_timings *timings)
|
||||
{
|
||||
mutex_lock(&hdmi.hdmi_lock);
|
||||
|
||||
*timings = dssdev->panel.timings;
|
||||
|
||||
mutex_unlock(&hdmi.hdmi_lock);
|
||||
}
|
||||
|
||||
static void hdmi_set_timings(struct omap_dss_device *dssdev,
|
||||
struct omap_video_timings *timings)
|
||||
{
|
||||
DSSDBG("hdmi_set_timings\n");
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
mutex_unlock(&hdmi.hdmi_lock);
|
||||
}
|
||||
|
||||
static int hdmi_check_timings(struct omap_dss_device *dssdev,
|
||||
struct omap_video_timings *timings)
|
||||
{
|
||||
int r = 0;
|
||||
|
||||
DSSDBG("hdmi_check_timings\n");
|
||||
|
||||
mutex_lock(&hdmi.hdmi_lock);
|
||||
|
||||
r = omapdss_hdmi_display_check_timing(dssdev, timings);
|
||||
if (r) {
|
||||
DSSERR("Timing cannot be applied\n");
|
||||
goto err;
|
||||
}
|
||||
err:
|
||||
mutex_unlock(&hdmi.hdmi_lock);
|
||||
return r;
|
||||
}
|
||||
|
||||
static struct omap_dss_driver hdmi_driver = {
|
||||
.probe = hdmi_panel_probe,
|
||||
.remove = hdmi_panel_remove,
|
||||
.enable = hdmi_panel_enable,
|
||||
.disable = hdmi_panel_disable,
|
||||
.suspend = hdmi_panel_suspend,
|
||||
.resume = hdmi_panel_resume,
|
||||
.get_timings = hdmi_get_timings,
|
||||
.set_timings = hdmi_set_timings,
|
||||
.check_timings = hdmi_check_timings,
|
||||
.driver = {
|
||||
.name = "hdmi_panel",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
int hdmi_panel_init(void)
|
||||
{
|
||||
mutex_init(&hdmi.hdmi_lock);
|
||||
|
||||
omap_dss_register_driver(&hdmi_driver);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void hdmi_panel_exit(void)
|
||||
{
|
||||
omap_dss_unregister_driver(&hdmi_driver);
|
||||
|
||||
}
|
@ -515,6 +515,8 @@ static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
|
||||
|
||||
if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC) {
|
||||
irq = DISPC_IRQ_EVSYNC_ODD;
|
||||
} else if (mgr->device->type == OMAP_DISPLAY_TYPE_HDMI) {
|
||||
irq = DISPC_IRQ_EVSYNC_EVEN;
|
||||
} else {
|
||||
if (mgr->id == OMAP_DSS_CHANNEL_LCD)
|
||||
irq = DISPC_IRQ_VSYNC;
|
||||
@ -536,7 +538,8 @@ static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
|
||||
if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
|
||||
return 0;
|
||||
|
||||
if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) {
|
||||
if (dssdev->type == OMAP_DISPLAY_TYPE_VENC
|
||||
|| dssdev->type == OMAP_DISPLAY_TYPE_HDMI) {
|
||||
irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
|
||||
} else {
|
||||
if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
|
||||
@ -613,7 +616,8 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
|
||||
if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
|
||||
return 0;
|
||||
|
||||
if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) {
|
||||
if (dssdev->type == OMAP_DISPLAY_TYPE_VENC
|
||||
|| dssdev->type == OMAP_DISPLAY_TYPE_HDMI) {
|
||||
irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
|
||||
} else {
|
||||
if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
|
||||
@ -1377,6 +1381,7 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
|
||||
case OMAP_DISPLAY_TYPE_DBI:
|
||||
case OMAP_DISPLAY_TYPE_SDI:
|
||||
case OMAP_DISPLAY_TYPE_VENC:
|
||||
case OMAP_DISPLAY_TYPE_HDMI:
|
||||
default_get_overlay_fifo_thresholds(ovl->id, size,
|
||||
&oc->burst_size, &oc->fifo_low,
|
||||
&oc->fifo_high);
|
||||
@ -1394,7 +1399,7 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
|
||||
}
|
||||
|
||||
r = 0;
|
||||
dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
|
||||
dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
|
||||
if (!dss_cache.irq_enabled) {
|
||||
u32 mask;
|
||||
|
||||
@ -1407,7 +1412,7 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
|
||||
dss_cache.irq_enabled = true;
|
||||
}
|
||||
configure_dispc();
|
||||
dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
|
||||
dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
|
||||
|
||||
spin_unlock_irqrestore(&dss_cache.lock, flags);
|
||||
|
||||
|
@ -490,7 +490,7 @@ static int omap_dss_set_manager(struct omap_overlay *ovl,
|
||||
|
||||
ovl->manager = mgr;
|
||||
|
||||
dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
|
||||
dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
|
||||
/* XXX: on manual update display, in auto update mode, a bug happens
|
||||
* here. When an overlay is first enabled on LCD, then it's disabled,
|
||||
* and the manager is changed to TV, we sometimes get SYNC_LOST_DIGIT
|
||||
@ -499,7 +499,7 @@ static int omap_dss_set_manager(struct omap_overlay *ovl,
|
||||
* but I don't understand how or why. */
|
||||
msleep(40);
|
||||
dispc_set_channel_out(ovl->id, mgr->id);
|
||||
dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
|
||||
dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -679,7 +679,8 @@ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
|
||||
lcd2_mgr->set_device(lcd2_mgr, dssdev);
|
||||
mgr = lcd2_mgr;
|
||||
}
|
||||
} else if (dssdev->type != OMAP_DISPLAY_TYPE_VENC) {
|
||||
} else if (dssdev->type != OMAP_DISPLAY_TYPE_VENC
|
||||
&& dssdev->type != OMAP_DISPLAY_TYPE_HDMI) {
|
||||
if (!lcd_mgr->device || force) {
|
||||
if (lcd_mgr->device)
|
||||
lcd_mgr->unset_device(lcd_mgr);
|
||||
@ -688,7 +689,8 @@ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
|
||||
}
|
||||
}
|
||||
|
||||
if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) {
|
||||
if (dssdev->type == OMAP_DISPLAY_TYPE_VENC
|
||||
|| dssdev->type == OMAP_DISPLAY_TYPE_HDMI) {
|
||||
if (!tv_mgr->device || force) {
|
||||
if (tv_mgr->device)
|
||||
tv_mgr->unset_device(tv_mgr);
|
||||
|
@ -36,8 +36,6 @@
|
||||
#include <plat/display.h>
|
||||
#include "dss.h"
|
||||
|
||||
#define RFBI_BASE 0x48050800
|
||||
|
||||
struct rfbi_reg { u16 idx; };
|
||||
|
||||
#define RFBI_REG(idx) ((const struct rfbi_reg) { idx })
|
||||
@ -100,6 +98,7 @@ static int rfbi_convert_timings(struct rfbi_timings *t);
|
||||
static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div);
|
||||
|
||||
static struct {
|
||||
struct platform_device *pdev;
|
||||
void __iomem *base;
|
||||
|
||||
unsigned long l4_khz;
|
||||
@ -142,9 +141,9 @@ static inline u32 rfbi_read_reg(const struct rfbi_reg idx)
|
||||
static void rfbi_enable_clocks(bool enable)
|
||||
{
|
||||
if (enable)
|
||||
dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
|
||||
dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
|
||||
else
|
||||
dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
|
||||
dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
|
||||
}
|
||||
|
||||
void omap_rfbi_write_command(const void *buf, u32 len)
|
||||
@ -497,7 +496,7 @@ unsigned long rfbi_get_max_tx_rate(void)
|
||||
};
|
||||
|
||||
l4_rate = rfbi.l4_khz / 1000;
|
||||
dss1_rate = dss_clk_get_rate(DSS_CLK_FCK1) / 1000000;
|
||||
dss1_rate = dss_clk_get_rate(DSS_CLK_FCK) / 1000000;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ftab); i++) {
|
||||
/* Use a window instead of an exact match, to account
|
||||
@ -922,7 +921,7 @@ void rfbi_dump_regs(struct seq_file *s)
|
||||
{
|
||||
#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, rfbi_read_reg(r))
|
||||
|
||||
dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
|
||||
dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
|
||||
|
||||
DUMPREG(RFBI_REVISION);
|
||||
DUMPREG(RFBI_SYSCONFIG);
|
||||
@ -953,54 +952,10 @@ void rfbi_dump_regs(struct seq_file *s)
|
||||
DUMPREG(RFBI_VSYNC_WIDTH);
|
||||
DUMPREG(RFBI_HSYNC_WIDTH);
|
||||
|
||||
dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
|
||||
dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
|
||||
#undef DUMPREG
|
||||
}
|
||||
|
||||
int rfbi_init(void)
|
||||
{
|
||||
u32 rev;
|
||||
u32 l;
|
||||
|
||||
spin_lock_init(&rfbi.cmd_lock);
|
||||
|
||||
init_completion(&rfbi.cmd_done);
|
||||
atomic_set(&rfbi.cmd_fifo_full, 0);
|
||||
atomic_set(&rfbi.cmd_pending, 0);
|
||||
|
||||
rfbi.base = ioremap(RFBI_BASE, SZ_256);
|
||||
if (!rfbi.base) {
|
||||
DSSERR("can't ioremap RFBI\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rfbi_enable_clocks(1);
|
||||
|
||||
msleep(10);
|
||||
|
||||
rfbi.l4_khz = dss_clk_get_rate(DSS_CLK_ICK) / 1000;
|
||||
|
||||
/* Enable autoidle and smart-idle */
|
||||
l = rfbi_read_reg(RFBI_SYSCONFIG);
|
||||
l |= (1 << 0) | (2 << 3);
|
||||
rfbi_write_reg(RFBI_SYSCONFIG, l);
|
||||
|
||||
rev = rfbi_read_reg(RFBI_REVISION);
|
||||
printk(KERN_INFO "OMAP RFBI rev %d.%d\n",
|
||||
FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
|
||||
|
||||
rfbi_enable_clocks(0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rfbi_exit(void)
|
||||
{
|
||||
DSSDBG("rfbi_exit\n");
|
||||
|
||||
iounmap(rfbi.base);
|
||||
}
|
||||
|
||||
int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
|
||||
{
|
||||
int r;
|
||||
@ -1056,3 +1011,74 @@ int rfbi_init_display(struct omap_dss_device *dssdev)
|
||||
dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* RFBI HW IP initialisation */
|
||||
static int omap_rfbihw_probe(struct platform_device *pdev)
|
||||
{
|
||||
u32 rev;
|
||||
u32 l;
|
||||
struct resource *rfbi_mem;
|
||||
|
||||
rfbi.pdev = pdev;
|
||||
|
||||
spin_lock_init(&rfbi.cmd_lock);
|
||||
|
||||
init_completion(&rfbi.cmd_done);
|
||||
atomic_set(&rfbi.cmd_fifo_full, 0);
|
||||
atomic_set(&rfbi.cmd_pending, 0);
|
||||
|
||||
rfbi_mem = platform_get_resource(rfbi.pdev, IORESOURCE_MEM, 0);
|
||||
if (!rfbi_mem) {
|
||||
DSSERR("can't get IORESOURCE_MEM RFBI\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
rfbi.base = ioremap(rfbi_mem->start, resource_size(rfbi_mem));
|
||||
if (!rfbi.base) {
|
||||
DSSERR("can't ioremap RFBI\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rfbi_enable_clocks(1);
|
||||
|
||||
msleep(10);
|
||||
|
||||
rfbi.l4_khz = dss_clk_get_rate(DSS_CLK_ICK) / 1000;
|
||||
|
||||
/* Enable autoidle and smart-idle */
|
||||
l = rfbi_read_reg(RFBI_SYSCONFIG);
|
||||
l |= (1 << 0) | (2 << 3);
|
||||
rfbi_write_reg(RFBI_SYSCONFIG, l);
|
||||
|
||||
rev = rfbi_read_reg(RFBI_REVISION);
|
||||
dev_dbg(&pdev->dev, "OMAP RFBI rev %d.%d\n",
|
||||
FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
|
||||
|
||||
rfbi_enable_clocks(0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap_rfbihw_remove(struct platform_device *pdev)
|
||||
{
|
||||
iounmap(rfbi.base);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver omap_rfbihw_driver = {
|
||||
.probe = omap_rfbihw_probe,
|
||||
.remove = omap_rfbihw_remove,
|
||||
.driver = {
|
||||
.name = "omapdss_rfbi",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
int rfbi_init_platform_driver(void)
|
||||
{
|
||||
return platform_driver_register(&omap_rfbihw_driver);
|
||||
}
|
||||
|
||||
void rfbi_uninit_platform_driver(void)
|
||||
{
|
||||
return platform_driver_unregister(&omap_rfbihw_driver);
|
||||
}
|
||||
|
@ -30,7 +30,6 @@
|
||||
#include "dss.h"
|
||||
|
||||
static struct {
|
||||
bool skip_init;
|
||||
bool update_enabled;
|
||||
struct regulator *vdds_sdi_reg;
|
||||
} sdi;
|
||||
@ -68,9 +67,7 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
|
||||
if (r)
|
||||
goto err1;
|
||||
|
||||
/* In case of skip_init sdi_init has already enabled the clocks */
|
||||
if (!sdi.skip_init)
|
||||
dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
|
||||
dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
|
||||
|
||||
sdi_basic_init(dssdev);
|
||||
|
||||
@ -80,14 +77,8 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
|
||||
dispc_set_pol_freq(dssdev->manager->id, dssdev->panel.config,
|
||||
dssdev->panel.acbi, dssdev->panel.acb);
|
||||
|
||||
if (!sdi.skip_init) {
|
||||
r = dss_calc_clock_div(1, t->pixel_clock * 1000,
|
||||
&dss_cinfo, &dispc_cinfo);
|
||||
} else {
|
||||
r = dss_get_clock_div(&dss_cinfo);
|
||||
r = dispc_get_clock_div(dssdev->manager->id, &dispc_cinfo);
|
||||
}
|
||||
|
||||
r = dss_calc_clock_div(1, t->pixel_clock * 1000,
|
||||
&dss_cinfo, &dispc_cinfo);
|
||||
if (r)
|
||||
goto err2;
|
||||
|
||||
@ -116,21 +107,17 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
|
||||
if (r)
|
||||
goto err2;
|
||||
|
||||
if (!sdi.skip_init) {
|
||||
dss_sdi_init(dssdev->phy.sdi.datapairs);
|
||||
r = dss_sdi_enable();
|
||||
if (r)
|
||||
goto err1;
|
||||
mdelay(2);
|
||||
}
|
||||
dss_sdi_init(dssdev->phy.sdi.datapairs);
|
||||
r = dss_sdi_enable();
|
||||
if (r)
|
||||
goto err1;
|
||||
mdelay(2);
|
||||
|
||||
dssdev->manager->enable(dssdev->manager);
|
||||
|
||||
sdi.skip_init = 0;
|
||||
|
||||
return 0;
|
||||
err2:
|
||||
dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
|
||||
dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
|
||||
regulator_disable(sdi.vdds_sdi_reg);
|
||||
err1:
|
||||
omap_dss_stop_device(dssdev);
|
||||
@ -145,7 +132,7 @@ void omapdss_sdi_display_disable(struct omap_dss_device *dssdev)
|
||||
|
||||
dss_sdi_disable();
|
||||
|
||||
dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
|
||||
dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
|
||||
|
||||
regulator_disable(sdi.vdds_sdi_reg);
|
||||
|
||||
@ -157,25 +144,24 @@ int sdi_init_display(struct omap_dss_device *dssdev)
|
||||
{
|
||||
DSSDBG("SDI init\n");
|
||||
|
||||
if (sdi.vdds_sdi_reg == NULL) {
|
||||
struct regulator *vdds_sdi;
|
||||
|
||||
vdds_sdi = dss_get_vdds_sdi();
|
||||
|
||||
if (IS_ERR(vdds_sdi)) {
|
||||
DSSERR("can't get VDDS_SDI regulator\n");
|
||||
return PTR_ERR(vdds_sdi);
|
||||
}
|
||||
|
||||
sdi.vdds_sdi_reg = vdds_sdi;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sdi_init(bool skip_init)
|
||||
int sdi_init(void)
|
||||
{
|
||||
/* we store this for first display enable, then clear it */
|
||||
sdi.skip_init = skip_init;
|
||||
|
||||
sdi.vdds_sdi_reg = dss_get_vdds_sdi();
|
||||
if (IS_ERR(sdi.vdds_sdi_reg)) {
|
||||
DSSERR("can't get VDDS_SDI regulator\n");
|
||||
return PTR_ERR(sdi.vdds_sdi_reg);
|
||||
}
|
||||
/*
|
||||
* Enable clocks already here, otherwise there would be a toggle
|
||||
* of them until sdi_display_enable is called.
|
||||
*/
|
||||
if (skip_init)
|
||||
dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -39,8 +39,6 @@
|
||||
|
||||
#include "dss.h"
|
||||
|
||||
#define VENC_BASE 0x48050C00
|
||||
|
||||
/* Venc registers */
|
||||
#define VENC_REV_ID 0x00
|
||||
#define VENC_STATUS 0x04
|
||||
@ -289,6 +287,7 @@ const struct omap_video_timings omap_dss_ntsc_timings = {
|
||||
EXPORT_SYMBOL(omap_dss_ntsc_timings);
|
||||
|
||||
static struct {
|
||||
struct platform_device *pdev;
|
||||
void __iomem *base;
|
||||
struct mutex venc_lock;
|
||||
u32 wss_data;
|
||||
@ -381,11 +380,11 @@ static void venc_reset(void)
|
||||
static void venc_enable_clocks(int enable)
|
||||
{
|
||||
if (enable)
|
||||
dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_54M |
|
||||
DSS_CLK_96M);
|
||||
dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK | DSS_CLK_TVFCK |
|
||||
DSS_CLK_VIDFCK);
|
||||
else
|
||||
dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_54M |
|
||||
DSS_CLK_96M);
|
||||
dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK | DSS_CLK_TVFCK |
|
||||
DSS_CLK_VIDFCK);
|
||||
}
|
||||
|
||||
static const struct venc_config *venc_timings_to_config(
|
||||
@ -641,50 +640,23 @@ static struct omap_dss_driver venc_driver = {
|
||||
};
|
||||
/* driver end */
|
||||
|
||||
|
||||
|
||||
int venc_init(struct platform_device *pdev)
|
||||
{
|
||||
u8 rev_id;
|
||||
|
||||
mutex_init(&venc.venc_lock);
|
||||
|
||||
venc.wss_data = 0;
|
||||
|
||||
venc.base = ioremap(VENC_BASE, SZ_1K);
|
||||
if (!venc.base) {
|
||||
DSSERR("can't ioremap VENC\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
venc.vdda_dac_reg = dss_get_vdda_dac();
|
||||
if (IS_ERR(venc.vdda_dac_reg)) {
|
||||
iounmap(venc.base);
|
||||
DSSERR("can't get VDDA_DAC regulator\n");
|
||||
return PTR_ERR(venc.vdda_dac_reg);
|
||||
}
|
||||
|
||||
venc_enable_clocks(1);
|
||||
|
||||
rev_id = (u8)(venc_read_reg(VENC_REV_ID) & 0xff);
|
||||
printk(KERN_INFO "OMAP VENC rev %d\n", rev_id);
|
||||
|
||||
venc_enable_clocks(0);
|
||||
|
||||
return omap_dss_register_driver(&venc_driver);
|
||||
}
|
||||
|
||||
void venc_exit(void)
|
||||
{
|
||||
omap_dss_unregister_driver(&venc_driver);
|
||||
|
||||
iounmap(venc.base);
|
||||
}
|
||||
|
||||
int venc_init_display(struct omap_dss_device *dssdev)
|
||||
{
|
||||
DSSDBG("init_display\n");
|
||||
|
||||
if (venc.vdda_dac_reg == NULL) {
|
||||
struct regulator *vdda_dac;
|
||||
|
||||
vdda_dac = regulator_get(&venc.pdev->dev, "vdda_dac");
|
||||
|
||||
if (IS_ERR(vdda_dac)) {
|
||||
DSSERR("can't get VDDA_DAC regulator\n");
|
||||
return PTR_ERR(vdda_dac);
|
||||
}
|
||||
|
||||
venc.vdda_dac_reg = vdda_dac;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -740,3 +712,73 @@ void venc_dump_regs(struct seq_file *s)
|
||||
|
||||
#undef DUMPREG
|
||||
}
|
||||
|
||||
/* VENC HW IP initialisation */
|
||||
static int omap_venchw_probe(struct platform_device *pdev)
|
||||
{
|
||||
u8 rev_id;
|
||||
struct resource *venc_mem;
|
||||
|
||||
venc.pdev = pdev;
|
||||
|
||||
mutex_init(&venc.venc_lock);
|
||||
|
||||
venc.wss_data = 0;
|
||||
|
||||
venc_mem = platform_get_resource(venc.pdev, IORESOURCE_MEM, 0);
|
||||
if (!venc_mem) {
|
||||
DSSERR("can't get IORESOURCE_MEM VENC\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
venc.base = ioremap(venc_mem->start, resource_size(venc_mem));
|
||||
if (!venc.base) {
|
||||
DSSERR("can't ioremap VENC\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
venc_enable_clocks(1);
|
||||
|
||||
rev_id = (u8)(venc_read_reg(VENC_REV_ID) & 0xff);
|
||||
dev_dbg(&pdev->dev, "OMAP VENC rev %d\n", rev_id);
|
||||
|
||||
venc_enable_clocks(0);
|
||||
|
||||
return omap_dss_register_driver(&venc_driver);
|
||||
}
|
||||
|
||||
static int omap_venchw_remove(struct platform_device *pdev)
|
||||
{
|
||||
if (venc.vdda_dac_reg != NULL) {
|
||||
regulator_put(venc.vdda_dac_reg);
|
||||
venc.vdda_dac_reg = NULL;
|
||||
}
|
||||
omap_dss_unregister_driver(&venc_driver);
|
||||
|
||||
iounmap(venc.base);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver omap_venchw_driver = {
|
||||
.probe = omap_venchw_probe,
|
||||
.remove = omap_venchw_remove,
|
||||
.driver = {
|
||||
.name = "omapdss_venc",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
int venc_init_platform_driver(void)
|
||||
{
|
||||
if (cpu_is_omap44xx())
|
||||
return 0;
|
||||
|
||||
return platform_driver_register(&omap_venchw_driver);
|
||||
}
|
||||
|
||||
void venc_uninit_platform_driver(void)
|
||||
{
|
||||
if (cpu_is_omap44xx())
|
||||
return;
|
||||
|
||||
return platform_driver_unregister(&omap_venchw_driver);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
menuconfig FB_OMAP2
|
||||
tristate "OMAP2/3 frame buffer support (EXPERIMENTAL)"
|
||||
tristate "OMAP2+ frame buffer support (EXPERIMENTAL)"
|
||||
depends on FB && OMAP2_DSS
|
||||
|
||||
select OMAP2_VRAM
|
||||
@ -8,10 +8,10 @@ menuconfig FB_OMAP2
|
||||
select FB_CFB_COPYAREA
|
||||
select FB_CFB_IMAGEBLIT
|
||||
help
|
||||
Frame buffer driver for OMAP2/3 based boards.
|
||||
Frame buffer driver for OMAP2+ based boards.
|
||||
|
||||
config FB_OMAP2_DEBUG_SUPPORT
|
||||
bool "Debug support for OMAP2/3 FB"
|
||||
bool "Debug support for OMAP2+ FB"
|
||||
default y
|
||||
depends on FB_OMAP2
|
||||
help
|
||||
|
@ -2090,7 +2090,7 @@ static int omapfb_set_def_mode(struct omapfb2_device *fbdev,
|
||||
{
|
||||
int r;
|
||||
u8 bpp;
|
||||
struct omap_video_timings timings;
|
||||
struct omap_video_timings timings, temp_timings;
|
||||
|
||||
r = omapfb_mode_to_timings(mode_str, &timings, &bpp);
|
||||
if (r)
|
||||
@ -2100,14 +2100,23 @@ static int omapfb_set_def_mode(struct omapfb2_device *fbdev,
|
||||
fbdev->bpp_overrides[fbdev->num_bpp_overrides].bpp = bpp;
|
||||
++fbdev->num_bpp_overrides;
|
||||
|
||||
if (!display->driver->check_timings || !display->driver->set_timings)
|
||||
return -EINVAL;
|
||||
if (display->driver->check_timings) {
|
||||
r = display->driver->check_timings(display, &timings);
|
||||
if (r)
|
||||
return r;
|
||||
} else {
|
||||
/* If check_timings is not present compare xres and yres */
|
||||
if (display->driver->get_timings) {
|
||||
display->driver->get_timings(display, &temp_timings);
|
||||
|
||||
r = display->driver->check_timings(display, &timings);
|
||||
if (r)
|
||||
return r;
|
||||
if (temp_timings.x_res != timings.x_res ||
|
||||
temp_timings.y_res != timings.y_res)
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
display->driver->set_timings(display, &timings);
|
||||
if (display->driver->set_timings)
|
||||
display->driver->set_timings(display, &timings);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1340,6 +1340,7 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev)
|
||||
sfb->bus_clk = clk_get(dev, "lcd");
|
||||
if (IS_ERR(sfb->bus_clk)) {
|
||||
dev_err(dev, "failed to get bus clock\n");
|
||||
ret = PTR_ERR(sfb->bus_clk);
|
||||
goto err_sfb;
|
||||
}
|
||||
|
||||
|
@ -64,6 +64,8 @@ static const struct svga_fb_format s3fb_formats[] = {
|
||||
|
||||
static const struct svga_pll s3_pll = {3, 129, 3, 33, 0, 3,
|
||||
35000, 240000, 14318};
|
||||
static const struct svga_pll s3_trio3d_pll = {3, 129, 3, 31, 0, 4,
|
||||
230000, 460000, 14318};
|
||||
|
||||
static const int s3_memsizes[] = {4096, 0, 3072, 8192, 2048, 6144, 1024, 512};
|
||||
|
||||
@ -72,7 +74,8 @@ static const char * const s3_names[] = {"S3 Unknown", "S3 Trio32", "S3 Trio64",
|
||||
"S3 Plato/PX", "S3 Aurora64VP", "S3 Virge",
|
||||
"S3 Virge/VX", "S3 Virge/DX", "S3 Virge/GX",
|
||||
"S3 Virge/GX2", "S3 Virge/GX2P", "S3 Virge/GX2P",
|
||||
"S3 Trio3D/1X", "S3 Trio3D/2X", "S3 Trio3D/2X"};
|
||||
"S3 Trio3D/1X", "S3 Trio3D/2X", "S3 Trio3D/2X",
|
||||
"S3 Trio3D"};
|
||||
|
||||
#define CHIP_UNKNOWN 0x00
|
||||
#define CHIP_732_TRIO32 0x01
|
||||
@ -93,6 +96,7 @@ static const char * const s3_names[] = {"S3 Unknown", "S3 Trio32", "S3 Trio64",
|
||||
#define CHIP_360_TRIO3D_1X 0x10
|
||||
#define CHIP_362_TRIO3D_2X 0x11
|
||||
#define CHIP_368_TRIO3D_2X 0x12
|
||||
#define CHIP_365_TRIO3D 0x13
|
||||
|
||||
#define CHIP_XXX_TRIO 0x80
|
||||
#define CHIP_XXX_TRIO64V2_DXGX 0x81
|
||||
@ -119,9 +123,11 @@ static const struct vga_regset s3_v_sync_start_regs[] = {{0x10, 0, 7}, {0x07,
|
||||
static const struct vga_regset s3_v_sync_end_regs[] = {{0x11, 0, 3}, VGA_REGSET_END};
|
||||
|
||||
static const struct vga_regset s3_line_compare_regs[] = {{0x18, 0, 7}, {0x07, 4, 4}, {0x09, 6, 6}, {0x5E, 6, 6}, VGA_REGSET_END};
|
||||
static const struct vga_regset s3_start_address_regs[] = {{0x0d, 0, 7}, {0x0c, 0, 7}, {0x31, 4, 5}, {0x51, 0, 1}, VGA_REGSET_END};
|
||||
static const struct vga_regset s3_start_address_regs[] = {{0x0d, 0, 7}, {0x0c, 0, 7}, {0x69, 0, 4}, VGA_REGSET_END};
|
||||
static const struct vga_regset s3_offset_regs[] = {{0x13, 0, 7}, {0x51, 4, 5}, VGA_REGSET_END}; /* set 0x43 bit 2 to 0 */
|
||||
|
||||
static const struct vga_regset s3_dtpc_regs[] = {{0x3B, 0, 7}, {0x5D, 6, 6}, VGA_REGSET_END};
|
||||
|
||||
static const struct svga_timing_regs s3_timing_regs = {
|
||||
s3_h_total_regs, s3_h_display_regs, s3_h_blank_start_regs,
|
||||
s3_h_blank_end_regs, s3_h_sync_start_regs, s3_h_sync_end_regs,
|
||||
@ -188,12 +194,19 @@ static void s3fb_settile_fast(struct fb_info *info, struct fb_tilemap *map)
|
||||
}
|
||||
}
|
||||
|
||||
static void s3fb_tilecursor(struct fb_info *info, struct fb_tilecursor *cursor)
|
||||
{
|
||||
struct s3fb_info *par = info->par;
|
||||
|
||||
svga_tilecursor(par->state.vgabase, info, cursor);
|
||||
}
|
||||
|
||||
static struct fb_tile_ops s3fb_tile_ops = {
|
||||
.fb_settile = svga_settile,
|
||||
.fb_tilecopy = svga_tilecopy,
|
||||
.fb_tilefill = svga_tilefill,
|
||||
.fb_tileblit = svga_tileblit,
|
||||
.fb_tilecursor = svga_tilecursor,
|
||||
.fb_tilecursor = s3fb_tilecursor,
|
||||
.fb_get_tilemax = svga_get_tilemax,
|
||||
};
|
||||
|
||||
@ -202,7 +215,7 @@ static struct fb_tile_ops s3fb_fast_tile_ops = {
|
||||
.fb_tilecopy = svga_tilecopy,
|
||||
.fb_tilefill = svga_tilefill,
|
||||
.fb_tileblit = svga_tileblit,
|
||||
.fb_tilecursor = svga_tilecursor,
|
||||
.fb_tilecursor = s3fb_tilecursor,
|
||||
.fb_get_tilemax = svga_get_tilemax,
|
||||
};
|
||||
|
||||
@ -334,33 +347,34 @@ static void s3_set_pixclock(struct fb_info *info, u32 pixclock)
|
||||
u8 regval;
|
||||
int rv;
|
||||
|
||||
rv = svga_compute_pll(&s3_pll, 1000000000 / pixclock, &m, &n, &r, info->node);
|
||||
rv = svga_compute_pll((par->chip == CHIP_365_TRIO3D) ? &s3_trio3d_pll : &s3_pll,
|
||||
1000000000 / pixclock, &m, &n, &r, info->node);
|
||||
if (rv < 0) {
|
||||
printk(KERN_ERR "fb%d: cannot set requested pixclock, keeping old value\n", info->node);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set VGA misc register */
|
||||
regval = vga_r(NULL, VGA_MIS_R);
|
||||
vga_w(NULL, VGA_MIS_W, regval | VGA_MIS_ENB_PLL_LOAD);
|
||||
regval = vga_r(par->state.vgabase, VGA_MIS_R);
|
||||
vga_w(par->state.vgabase, VGA_MIS_W, regval | VGA_MIS_ENB_PLL_LOAD);
|
||||
|
||||
/* Set S3 clock registers */
|
||||
if (par->chip == CHIP_360_TRIO3D_1X ||
|
||||
par->chip == CHIP_362_TRIO3D_2X ||
|
||||
par->chip == CHIP_368_TRIO3D_2X) {
|
||||
vga_wseq(NULL, 0x12, (n - 2) | ((r & 3) << 6)); /* n and two bits of r */
|
||||
vga_wseq(NULL, 0x29, r >> 2); /* remaining highest bit of r */
|
||||
vga_wseq(par->state.vgabase, 0x12, (n - 2) | ((r & 3) << 6)); /* n and two bits of r */
|
||||
vga_wseq(par->state.vgabase, 0x29, r >> 2); /* remaining highest bit of r */
|
||||
} else
|
||||
vga_wseq(NULL, 0x12, (n - 2) | (r << 5));
|
||||
vga_wseq(NULL, 0x13, m - 2);
|
||||
vga_wseq(par->state.vgabase, 0x12, (n - 2) | (r << 5));
|
||||
vga_wseq(par->state.vgabase, 0x13, m - 2);
|
||||
|
||||
udelay(1000);
|
||||
|
||||
/* Activate clock - write 0, 1, 0 to seq/15 bit 5 */
|
||||
regval = vga_rseq (NULL, 0x15); /* | 0x80; */
|
||||
vga_wseq(NULL, 0x15, regval & ~(1<<5));
|
||||
vga_wseq(NULL, 0x15, regval | (1<<5));
|
||||
vga_wseq(NULL, 0x15, regval & ~(1<<5));
|
||||
regval = vga_rseq (par->state.vgabase, 0x15); /* | 0x80; */
|
||||
vga_wseq(par->state.vgabase, 0x15, regval & ~(1<<5));
|
||||
vga_wseq(par->state.vgabase, 0x15, regval | (1<<5));
|
||||
vga_wseq(par->state.vgabase, 0x15, regval & ~(1<<5));
|
||||
}
|
||||
|
||||
|
||||
@ -372,7 +386,10 @@ static int s3fb_open(struct fb_info *info, int user)
|
||||
|
||||
mutex_lock(&(par->open_lock));
|
||||
if (par->ref_count == 0) {
|
||||
void __iomem *vgabase = par->state.vgabase;
|
||||
|
||||
memset(&(par->state), 0, sizeof(struct vgastate));
|
||||
par->state.vgabase = vgabase;
|
||||
par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS | VGA_SAVE_CMAP;
|
||||
par->state.num_crtc = 0x70;
|
||||
par->state.num_seq = 0x20;
|
||||
@ -470,6 +487,7 @@ static int s3fb_set_par(struct fb_info *info)
|
||||
struct s3fb_info *par = info->par;
|
||||
u32 value, mode, hmul, offset_value, screen_size, multiplex, dbytes;
|
||||
u32 bpp = info->var.bits_per_pixel;
|
||||
u32 htotal, hsstart;
|
||||
|
||||
if (bpp != 0) {
|
||||
info->fix.ypanstep = 1;
|
||||
@ -504,99 +522,112 @@ static int s3fb_set_par(struct fb_info *info)
|
||||
info->var.activate = FB_ACTIVATE_NOW;
|
||||
|
||||
/* Unlock registers */
|
||||
vga_wcrt(NULL, 0x38, 0x48);
|
||||
vga_wcrt(NULL, 0x39, 0xA5);
|
||||
vga_wseq(NULL, 0x08, 0x06);
|
||||
svga_wcrt_mask(0x11, 0x00, 0x80);
|
||||
vga_wcrt(par->state.vgabase, 0x38, 0x48);
|
||||
vga_wcrt(par->state.vgabase, 0x39, 0xA5);
|
||||
vga_wseq(par->state.vgabase, 0x08, 0x06);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x11, 0x00, 0x80);
|
||||
|
||||
/* Blank screen and turn off sync */
|
||||
svga_wseq_mask(0x01, 0x20, 0x20);
|
||||
svga_wcrt_mask(0x17, 0x00, 0x80);
|
||||
svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x17, 0x00, 0x80);
|
||||
|
||||
/* Set default values */
|
||||
svga_set_default_gfx_regs();
|
||||
svga_set_default_atc_regs();
|
||||
svga_set_default_seq_regs();
|
||||
svga_set_default_crt_regs();
|
||||
svga_wcrt_multi(s3_line_compare_regs, 0xFFFFFFFF);
|
||||
svga_wcrt_multi(s3_start_address_regs, 0);
|
||||
svga_set_default_gfx_regs(par->state.vgabase);
|
||||
svga_set_default_atc_regs(par->state.vgabase);
|
||||
svga_set_default_seq_regs(par->state.vgabase);
|
||||
svga_set_default_crt_regs(par->state.vgabase);
|
||||
svga_wcrt_multi(par->state.vgabase, s3_line_compare_regs, 0xFFFFFFFF);
|
||||
svga_wcrt_multi(par->state.vgabase, s3_start_address_regs, 0);
|
||||
|
||||
/* S3 specific initialization */
|
||||
svga_wcrt_mask(0x58, 0x10, 0x10); /* enable linear framebuffer */
|
||||
svga_wcrt_mask(0x31, 0x08, 0x08); /* enable sequencer access to framebuffer above 256 kB */
|
||||
svga_wcrt_mask(par->state.vgabase, 0x58, 0x10, 0x10); /* enable linear framebuffer */
|
||||
svga_wcrt_mask(par->state.vgabase, 0x31, 0x08, 0x08); /* enable sequencer access to framebuffer above 256 kB */
|
||||
|
||||
/* svga_wcrt_mask(0x33, 0x08, 0x08); */ /* DDR ? */
|
||||
/* svga_wcrt_mask(0x43, 0x01, 0x01); */ /* DDR ? */
|
||||
svga_wcrt_mask(0x33, 0x00, 0x08); /* no DDR ? */
|
||||
svga_wcrt_mask(0x43, 0x00, 0x01); /* no DDR ? */
|
||||
/* svga_wcrt_mask(par->state.vgabase, 0x33, 0x08, 0x08); */ /* DDR ? */
|
||||
/* svga_wcrt_mask(par->state.vgabase, 0x43, 0x01, 0x01); */ /* DDR ? */
|
||||
svga_wcrt_mask(par->state.vgabase, 0x33, 0x00, 0x08); /* no DDR ? */
|
||||
svga_wcrt_mask(par->state.vgabase, 0x43, 0x00, 0x01); /* no DDR ? */
|
||||
|
||||
svga_wcrt_mask(0x5D, 0x00, 0x28); /* Clear strange HSlen bits */
|
||||
svga_wcrt_mask(par->state.vgabase, 0x5D, 0x00, 0x28); /* Clear strange HSlen bits */
|
||||
|
||||
/* svga_wcrt_mask(0x58, 0x03, 0x03); */
|
||||
/* svga_wcrt_mask(par->state.vgabase, 0x58, 0x03, 0x03); */
|
||||
|
||||
/* svga_wcrt_mask(0x53, 0x12, 0x13); */ /* enable MMIO */
|
||||
/* svga_wcrt_mask(0x40, 0x08, 0x08); */ /* enable write buffer */
|
||||
/* svga_wcrt_mask(par->state.vgabase, 0x53, 0x12, 0x13); */ /* enable MMIO */
|
||||
/* svga_wcrt_mask(par->state.vgabase, 0x40, 0x08, 0x08); */ /* enable write buffer */
|
||||
|
||||
|
||||
/* Set the offset register */
|
||||
pr_debug("fb%d: offset register : %d\n", info->node, offset_value);
|
||||
svga_wcrt_multi(s3_offset_regs, offset_value);
|
||||
svga_wcrt_multi(par->state.vgabase, s3_offset_regs, offset_value);
|
||||
|
||||
if (par->chip != CHIP_360_TRIO3D_1X &&
|
||||
par->chip != CHIP_362_TRIO3D_2X &&
|
||||
par->chip != CHIP_368_TRIO3D_2X) {
|
||||
vga_wcrt(NULL, 0x54, 0x18); /* M parameter */
|
||||
vga_wcrt(NULL, 0x60, 0xff); /* N parameter */
|
||||
vga_wcrt(NULL, 0x61, 0xff); /* L parameter */
|
||||
vga_wcrt(NULL, 0x62, 0xff); /* L parameter */
|
||||
vga_wcrt(par->state.vgabase, 0x54, 0x18); /* M parameter */
|
||||
vga_wcrt(par->state.vgabase, 0x60, 0xff); /* N parameter */
|
||||
vga_wcrt(par->state.vgabase, 0x61, 0xff); /* L parameter */
|
||||
vga_wcrt(par->state.vgabase, 0x62, 0xff); /* L parameter */
|
||||
}
|
||||
|
||||
vga_wcrt(NULL, 0x3A, 0x35);
|
||||
svga_wattr(0x33, 0x00);
|
||||
vga_wcrt(par->state.vgabase, 0x3A, 0x35);
|
||||
svga_wattr(par->state.vgabase, 0x33, 0x00);
|
||||
|
||||
if (info->var.vmode & FB_VMODE_DOUBLE)
|
||||
svga_wcrt_mask(0x09, 0x80, 0x80);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x09, 0x80, 0x80);
|
||||
else
|
||||
svga_wcrt_mask(0x09, 0x00, 0x80);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x09, 0x00, 0x80);
|
||||
|
||||
if (info->var.vmode & FB_VMODE_INTERLACED)
|
||||
svga_wcrt_mask(0x42, 0x20, 0x20);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x42, 0x20, 0x20);
|
||||
else
|
||||
svga_wcrt_mask(0x42, 0x00, 0x20);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x42, 0x00, 0x20);
|
||||
|
||||
/* Disable hardware graphics cursor */
|
||||
svga_wcrt_mask(0x45, 0x00, 0x01);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x45, 0x00, 0x01);
|
||||
/* Disable Streams engine */
|
||||
svga_wcrt_mask(0x67, 0x00, 0x0C);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x67, 0x00, 0x0C);
|
||||
|
||||
mode = svga_match_format(s3fb_formats, &(info->var), &(info->fix));
|
||||
|
||||
/* S3 virge DX hack */
|
||||
if (par->chip == CHIP_375_VIRGE_DX) {
|
||||
vga_wcrt(NULL, 0x86, 0x80);
|
||||
vga_wcrt(NULL, 0x90, 0x00);
|
||||
vga_wcrt(par->state.vgabase, 0x86, 0x80);
|
||||
vga_wcrt(par->state.vgabase, 0x90, 0x00);
|
||||
}
|
||||
|
||||
/* S3 virge VX hack */
|
||||
if (par->chip == CHIP_988_VIRGE_VX) {
|
||||
vga_wcrt(NULL, 0x50, 0x00);
|
||||
vga_wcrt(NULL, 0x67, 0x50);
|
||||
vga_wcrt(par->state.vgabase, 0x50, 0x00);
|
||||
vga_wcrt(par->state.vgabase, 0x67, 0x50);
|
||||
|
||||
vga_wcrt(NULL, 0x63, (mode <= 2) ? 0x90 : 0x09);
|
||||
vga_wcrt(NULL, 0x66, 0x90);
|
||||
vga_wcrt(par->state.vgabase, 0x63, (mode <= 2) ? 0x90 : 0x09);
|
||||
vga_wcrt(par->state.vgabase, 0x66, 0x90);
|
||||
}
|
||||
|
||||
if (par->chip == CHIP_360_TRIO3D_1X ||
|
||||
par->chip == CHIP_362_TRIO3D_2X ||
|
||||
par->chip == CHIP_368_TRIO3D_2X) {
|
||||
par->chip == CHIP_368_TRIO3D_2X ||
|
||||
par->chip == CHIP_365_TRIO3D ||
|
||||
par->chip == CHIP_375_VIRGE_DX ||
|
||||
par->chip == CHIP_385_VIRGE_GX) {
|
||||
dbytes = info->var.xres * ((bpp+7)/8);
|
||||
vga_wcrt(NULL, 0x91, (dbytes + 7) / 8);
|
||||
vga_wcrt(NULL, 0x90, (((dbytes + 7) / 8) >> 8) | 0x80);
|
||||
vga_wcrt(par->state.vgabase, 0x91, (dbytes + 7) / 8);
|
||||
vga_wcrt(par->state.vgabase, 0x90, (((dbytes + 7) / 8) >> 8) | 0x80);
|
||||
|
||||
vga_wcrt(NULL, 0x66, 0x81);
|
||||
vga_wcrt(par->state.vgabase, 0x66, 0x81);
|
||||
}
|
||||
|
||||
svga_wcrt_mask(0x31, 0x00, 0x40);
|
||||
if (par->chip == CHIP_356_VIRGE_GX2 ||
|
||||
par->chip == CHIP_357_VIRGE_GX2P ||
|
||||
par->chip == CHIP_359_VIRGE_GX2P ||
|
||||
par->chip == CHIP_360_TRIO3D_1X ||
|
||||
par->chip == CHIP_362_TRIO3D_2X ||
|
||||
par->chip == CHIP_368_TRIO3D_2X)
|
||||
vga_wcrt(par->state.vgabase, 0x34, 0x00);
|
||||
else /* enable Data Transfer Position Control (DTPC) */
|
||||
vga_wcrt(par->state.vgabase, 0x34, 0x10);
|
||||
|
||||
svga_wcrt_mask(par->state.vgabase, 0x31, 0x00, 0x40);
|
||||
multiplex = 0;
|
||||
hmul = 1;
|
||||
|
||||
@ -604,51 +635,51 @@ static int s3fb_set_par(struct fb_info *info)
|
||||
switch (mode) {
|
||||
case 0:
|
||||
pr_debug("fb%d: text mode\n", info->node);
|
||||
svga_set_textmode_vga_regs();
|
||||
svga_set_textmode_vga_regs(par->state.vgabase);
|
||||
|
||||
/* Set additional registers like in 8-bit mode */
|
||||
svga_wcrt_mask(0x50, 0x00, 0x30);
|
||||
svga_wcrt_mask(0x67, 0x00, 0xF0);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x50, 0x00, 0x30);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x67, 0x00, 0xF0);
|
||||
|
||||
/* Disable enhanced mode */
|
||||
svga_wcrt_mask(0x3A, 0x00, 0x30);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x3A, 0x00, 0x30);
|
||||
|
||||
if (fasttext) {
|
||||
pr_debug("fb%d: high speed text mode set\n", info->node);
|
||||
svga_wcrt_mask(0x31, 0x40, 0x40);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x31, 0x40, 0x40);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
pr_debug("fb%d: 4 bit pseudocolor\n", info->node);
|
||||
vga_wgfx(NULL, VGA_GFX_MODE, 0x40);
|
||||
vga_wgfx(par->state.vgabase, VGA_GFX_MODE, 0x40);
|
||||
|
||||
/* Set additional registers like in 8-bit mode */
|
||||
svga_wcrt_mask(0x50, 0x00, 0x30);
|
||||
svga_wcrt_mask(0x67, 0x00, 0xF0);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x50, 0x00, 0x30);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x67, 0x00, 0xF0);
|
||||
|
||||
/* disable enhanced mode */
|
||||
svga_wcrt_mask(0x3A, 0x00, 0x30);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x3A, 0x00, 0x30);
|
||||
break;
|
||||
case 2:
|
||||
pr_debug("fb%d: 4 bit pseudocolor, planar\n", info->node);
|
||||
|
||||
/* Set additional registers like in 8-bit mode */
|
||||
svga_wcrt_mask(0x50, 0x00, 0x30);
|
||||
svga_wcrt_mask(0x67, 0x00, 0xF0);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x50, 0x00, 0x30);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x67, 0x00, 0xF0);
|
||||
|
||||
/* disable enhanced mode */
|
||||
svga_wcrt_mask(0x3A, 0x00, 0x30);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x3A, 0x00, 0x30);
|
||||
break;
|
||||
case 3:
|
||||
pr_debug("fb%d: 8 bit pseudocolor\n", info->node);
|
||||
svga_wcrt_mask(0x50, 0x00, 0x30);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x50, 0x00, 0x30);
|
||||
if (info->var.pixclock > 20000 ||
|
||||
par->chip == CHIP_360_TRIO3D_1X ||
|
||||
par->chip == CHIP_362_TRIO3D_2X ||
|
||||
par->chip == CHIP_368_TRIO3D_2X)
|
||||
svga_wcrt_mask(0x67, 0x00, 0xF0);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x67, 0x00, 0xF0);
|
||||
else {
|
||||
svga_wcrt_mask(0x67, 0x10, 0xF0);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x67, 0x10, 0xF0);
|
||||
multiplex = 1;
|
||||
}
|
||||
break;
|
||||
@ -656,12 +687,21 @@ static int s3fb_set_par(struct fb_info *info)
|
||||
pr_debug("fb%d: 5/5/5 truecolor\n", info->node);
|
||||
if (par->chip == CHIP_988_VIRGE_VX) {
|
||||
if (info->var.pixclock > 20000)
|
||||
svga_wcrt_mask(0x67, 0x20, 0xF0);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x67, 0x20, 0xF0);
|
||||
else
|
||||
svga_wcrt_mask(0x67, 0x30, 0xF0);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x67, 0x30, 0xF0);
|
||||
} else if (par->chip == CHIP_365_TRIO3D) {
|
||||
svga_wcrt_mask(par->state.vgabase, 0x50, 0x10, 0x30);
|
||||
if (info->var.pixclock > 8695) {
|
||||
svga_wcrt_mask(par->state.vgabase, 0x67, 0x30, 0xF0);
|
||||
hmul = 2;
|
||||
} else {
|
||||
svga_wcrt_mask(par->state.vgabase, 0x67, 0x20, 0xF0);
|
||||
multiplex = 1;
|
||||
}
|
||||
} else {
|
||||
svga_wcrt_mask(0x50, 0x10, 0x30);
|
||||
svga_wcrt_mask(0x67, 0x30, 0xF0);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x50, 0x10, 0x30);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x67, 0x30, 0xF0);
|
||||
if (par->chip != CHIP_360_TRIO3D_1X &&
|
||||
par->chip != CHIP_362_TRIO3D_2X &&
|
||||
par->chip != CHIP_368_TRIO3D_2X)
|
||||
@ -672,12 +712,21 @@ static int s3fb_set_par(struct fb_info *info)
|
||||
pr_debug("fb%d: 5/6/5 truecolor\n", info->node);
|
||||
if (par->chip == CHIP_988_VIRGE_VX) {
|
||||
if (info->var.pixclock > 20000)
|
||||
svga_wcrt_mask(0x67, 0x40, 0xF0);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x67, 0x40, 0xF0);
|
||||
else
|
||||
svga_wcrt_mask(0x67, 0x50, 0xF0);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x67, 0x50, 0xF0);
|
||||
} else if (par->chip == CHIP_365_TRIO3D) {
|
||||
svga_wcrt_mask(par->state.vgabase, 0x50, 0x10, 0x30);
|
||||
if (info->var.pixclock > 8695) {
|
||||
svga_wcrt_mask(par->state.vgabase, 0x67, 0x50, 0xF0);
|
||||
hmul = 2;
|
||||
} else {
|
||||
svga_wcrt_mask(par->state.vgabase, 0x67, 0x40, 0xF0);
|
||||
multiplex = 1;
|
||||
}
|
||||
} else {
|
||||
svga_wcrt_mask(0x50, 0x10, 0x30);
|
||||
svga_wcrt_mask(0x67, 0x50, 0xF0);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x50, 0x10, 0x30);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x67, 0x50, 0xF0);
|
||||
if (par->chip != CHIP_360_TRIO3D_1X &&
|
||||
par->chip != CHIP_362_TRIO3D_2X &&
|
||||
par->chip != CHIP_368_TRIO3D_2X)
|
||||
@ -687,12 +736,12 @@ static int s3fb_set_par(struct fb_info *info)
|
||||
case 6:
|
||||
/* VIRGE VX case */
|
||||
pr_debug("fb%d: 8/8/8 truecolor\n", info->node);
|
||||
svga_wcrt_mask(0x67, 0xD0, 0xF0);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x67, 0xD0, 0xF0);
|
||||
break;
|
||||
case 7:
|
||||
pr_debug("fb%d: 8/8/8/8 truecolor\n", info->node);
|
||||
svga_wcrt_mask(0x50, 0x30, 0x30);
|
||||
svga_wcrt_mask(0x67, 0xD0, 0xF0);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x50, 0x30, 0x30);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x67, 0xD0, 0xF0);
|
||||
break;
|
||||
default:
|
||||
printk(KERN_ERR "fb%d: unsupported mode - bug\n", info->node);
|
||||
@ -700,25 +749,30 @@ static int s3fb_set_par(struct fb_info *info)
|
||||
}
|
||||
|
||||
if (par->chip != CHIP_988_VIRGE_VX) {
|
||||
svga_wseq_mask(0x15, multiplex ? 0x10 : 0x00, 0x10);
|
||||
svga_wseq_mask(0x18, multiplex ? 0x80 : 0x00, 0x80);
|
||||
svga_wseq_mask(par->state.vgabase, 0x15, multiplex ? 0x10 : 0x00, 0x10);
|
||||
svga_wseq_mask(par->state.vgabase, 0x18, multiplex ? 0x80 : 0x00, 0x80);
|
||||
}
|
||||
|
||||
s3_set_pixclock(info, info->var.pixclock);
|
||||
svga_set_timings(&s3_timing_regs, &(info->var), hmul, 1,
|
||||
svga_set_timings(par->state.vgabase, &s3_timing_regs, &(info->var), hmul, 1,
|
||||
(info->var.vmode & FB_VMODE_DOUBLE) ? 2 : 1,
|
||||
(info->var.vmode & FB_VMODE_INTERLACED) ? 2 : 1,
|
||||
hmul, info->node);
|
||||
|
||||
/* Set interlaced mode start/end register */
|
||||
value = info->var.xres + info->var.left_margin + info->var.right_margin + info->var.hsync_len;
|
||||
value = ((value * hmul) / 8) - 5;
|
||||
vga_wcrt(NULL, 0x3C, (value + 1) / 2);
|
||||
htotal = info->var.xres + info->var.left_margin + info->var.right_margin + info->var.hsync_len;
|
||||
htotal = ((htotal * hmul) / 8) - 5;
|
||||
vga_wcrt(par->state.vgabase, 0x3C, (htotal + 1) / 2);
|
||||
|
||||
/* Set Data Transfer Position */
|
||||
hsstart = ((info->var.xres + info->var.right_margin) * hmul) / 8;
|
||||
value = clamp((htotal + hsstart + 1) / 2, hsstart + 4, htotal + 1);
|
||||
svga_wcrt_multi(par->state.vgabase, s3_dtpc_regs, value);
|
||||
|
||||
memset_io(info->screen_base, 0x00, screen_size);
|
||||
/* Device and screen back on */
|
||||
svga_wcrt_mask(0x17, 0x80, 0x80);
|
||||
svga_wseq_mask(0x01, 0x00, 0x20);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x17, 0x80, 0x80);
|
||||
svga_wseq_mask(par->state.vgabase, 0x01, 0x00, 0x20);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -788,31 +842,33 @@ static int s3fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
|
||||
|
||||
static int s3fb_blank(int blank_mode, struct fb_info *info)
|
||||
{
|
||||
struct s3fb_info *par = info->par;
|
||||
|
||||
switch (blank_mode) {
|
||||
case FB_BLANK_UNBLANK:
|
||||
pr_debug("fb%d: unblank\n", info->node);
|
||||
svga_wcrt_mask(0x56, 0x00, 0x06);
|
||||
svga_wseq_mask(0x01, 0x00, 0x20);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x56, 0x00, 0x06);
|
||||
svga_wseq_mask(par->state.vgabase, 0x01, 0x00, 0x20);
|
||||
break;
|
||||
case FB_BLANK_NORMAL:
|
||||
pr_debug("fb%d: blank\n", info->node);
|
||||
svga_wcrt_mask(0x56, 0x00, 0x06);
|
||||
svga_wseq_mask(0x01, 0x20, 0x20);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x56, 0x00, 0x06);
|
||||
svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
|
||||
break;
|
||||
case FB_BLANK_HSYNC_SUSPEND:
|
||||
pr_debug("fb%d: hsync\n", info->node);
|
||||
svga_wcrt_mask(0x56, 0x02, 0x06);
|
||||
svga_wseq_mask(0x01, 0x20, 0x20);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x56, 0x02, 0x06);
|
||||
svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
|
||||
break;
|
||||
case FB_BLANK_VSYNC_SUSPEND:
|
||||
pr_debug("fb%d: vsync\n", info->node);
|
||||
svga_wcrt_mask(0x56, 0x04, 0x06);
|
||||
svga_wseq_mask(0x01, 0x20, 0x20);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x56, 0x04, 0x06);
|
||||
svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
|
||||
break;
|
||||
case FB_BLANK_POWERDOWN:
|
||||
pr_debug("fb%d: sync down\n", info->node);
|
||||
svga_wcrt_mask(0x56, 0x06, 0x06);
|
||||
svga_wseq_mask(0x01, 0x20, 0x20);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x56, 0x06, 0x06);
|
||||
svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -822,8 +878,9 @@ static int s3fb_blank(int blank_mode, struct fb_info *info)
|
||||
|
||||
/* Pan the display */
|
||||
|
||||
static int s3fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) {
|
||||
|
||||
static int s3fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
|
||||
{
|
||||
struct s3fb_info *par = info->par;
|
||||
unsigned int offset;
|
||||
|
||||
/* Calculate the offset */
|
||||
@ -837,7 +894,7 @@ static int s3fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
|
||||
}
|
||||
|
||||
/* Set the offset */
|
||||
svga_wcrt_multi(s3_start_address_regs, offset);
|
||||
svga_wcrt_multi(par->state.vgabase, s3_start_address_regs, offset);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -863,12 +920,14 @@ static struct fb_ops s3fb_ops = {
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static int __devinit s3_identification(int chip)
|
||||
static int __devinit s3_identification(struct s3fb_info *par)
|
||||
{
|
||||
int chip = par->chip;
|
||||
|
||||
if (chip == CHIP_XXX_TRIO) {
|
||||
u8 cr30 = vga_rcrt(NULL, 0x30);
|
||||
u8 cr2e = vga_rcrt(NULL, 0x2e);
|
||||
u8 cr2f = vga_rcrt(NULL, 0x2f);
|
||||
u8 cr30 = vga_rcrt(par->state.vgabase, 0x30);
|
||||
u8 cr2e = vga_rcrt(par->state.vgabase, 0x2e);
|
||||
u8 cr2f = vga_rcrt(par->state.vgabase, 0x2f);
|
||||
|
||||
if ((cr30 == 0xE0) || (cr30 == 0xE1)) {
|
||||
if (cr2e == 0x10)
|
||||
@ -883,7 +942,7 @@ static int __devinit s3_identification(int chip)
|
||||
}
|
||||
|
||||
if (chip == CHIP_XXX_TRIO64V2_DXGX) {
|
||||
u8 cr6f = vga_rcrt(NULL, 0x6f);
|
||||
u8 cr6f = vga_rcrt(par->state.vgabase, 0x6f);
|
||||
|
||||
if (! (cr6f & 0x01))
|
||||
return CHIP_775_TRIO64V2_DX;
|
||||
@ -892,7 +951,7 @@ static int __devinit s3_identification(int chip)
|
||||
}
|
||||
|
||||
if (chip == CHIP_XXX_VIRGE_DXGX) {
|
||||
u8 cr6f = vga_rcrt(NULL, 0x6f);
|
||||
u8 cr6f = vga_rcrt(par->state.vgabase, 0x6f);
|
||||
|
||||
if (! (cr6f & 0x01))
|
||||
return CHIP_375_VIRGE_DX;
|
||||
@ -901,7 +960,7 @@ static int __devinit s3_identification(int chip)
|
||||
}
|
||||
|
||||
if (chip == CHIP_36X_TRIO3D_1X_2X) {
|
||||
switch (vga_rcrt(NULL, 0x2f)) {
|
||||
switch (vga_rcrt(par->state.vgabase, 0x2f)) {
|
||||
case 0x00:
|
||||
return CHIP_360_TRIO3D_1X;
|
||||
case 0x01:
|
||||
@ -919,6 +978,8 @@ static int __devinit s3_identification(int chip)
|
||||
|
||||
static int __devinit s3_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
||||
{
|
||||
struct pci_bus_region bus_reg;
|
||||
struct resource vga_res;
|
||||
struct fb_info *info;
|
||||
struct s3fb_info *par;
|
||||
int rc;
|
||||
@ -968,31 +1029,42 @@ static int __devinit s3_pci_probe(struct pci_dev *dev, const struct pci_device_i
|
||||
goto err_iomap;
|
||||
}
|
||||
|
||||
bus_reg.start = 0;
|
||||
bus_reg.end = 64 * 1024;
|
||||
|
||||
vga_res.flags = IORESOURCE_IO;
|
||||
|
||||
pcibios_bus_to_resource(dev, &vga_res, &bus_reg);
|
||||
|
||||
par->state.vgabase = (void __iomem *) vga_res.start;
|
||||
|
||||
/* Unlock regs */
|
||||
cr38 = vga_rcrt(NULL, 0x38);
|
||||
cr39 = vga_rcrt(NULL, 0x39);
|
||||
vga_wseq(NULL, 0x08, 0x06);
|
||||
vga_wcrt(NULL, 0x38, 0x48);
|
||||
vga_wcrt(NULL, 0x39, 0xA5);
|
||||
cr38 = vga_rcrt(par->state.vgabase, 0x38);
|
||||
cr39 = vga_rcrt(par->state.vgabase, 0x39);
|
||||
vga_wseq(par->state.vgabase, 0x08, 0x06);
|
||||
vga_wcrt(par->state.vgabase, 0x38, 0x48);
|
||||
vga_wcrt(par->state.vgabase, 0x39, 0xA5);
|
||||
|
||||
/* Identify chip type */
|
||||
par->chip = id->driver_data & CHIP_MASK;
|
||||
par->rev = vga_rcrt(NULL, 0x2f);
|
||||
par->rev = vga_rcrt(par->state.vgabase, 0x2f);
|
||||
if (par->chip & CHIP_UNDECIDED_FLAG)
|
||||
par->chip = s3_identification(par->chip);
|
||||
par->chip = s3_identification(par);
|
||||
|
||||
/* Find how many physical memory there is on card */
|
||||
/* 0x36 register is accessible even if other registers are locked */
|
||||
regval = vga_rcrt(NULL, 0x36);
|
||||
regval = vga_rcrt(par->state.vgabase, 0x36);
|
||||
if (par->chip == CHIP_360_TRIO3D_1X ||
|
||||
par->chip == CHIP_362_TRIO3D_2X ||
|
||||
par->chip == CHIP_368_TRIO3D_2X) {
|
||||
par->chip == CHIP_368_TRIO3D_2X ||
|
||||
par->chip == CHIP_365_TRIO3D) {
|
||||
switch ((regval & 0xE0) >> 5) {
|
||||
case 0: /* 8MB -- only 4MB usable for display */
|
||||
case 1: /* 4MB with 32-bit bus */
|
||||
case 2: /* 4MB */
|
||||
info->screen_size = 4 << 20;
|
||||
break;
|
||||
case 4: /* 2MB on 365 Trio3D */
|
||||
case 6: /* 2MB */
|
||||
info->screen_size = 2 << 20;
|
||||
break;
|
||||
@ -1002,13 +1074,13 @@ static int __devinit s3_pci_probe(struct pci_dev *dev, const struct pci_device_i
|
||||
info->fix.smem_len = info->screen_size;
|
||||
|
||||
/* Find MCLK frequency */
|
||||
regval = vga_rseq(NULL, 0x10);
|
||||
par->mclk_freq = ((vga_rseq(NULL, 0x11) + 2) * 14318) / ((regval & 0x1F) + 2);
|
||||
regval = vga_rseq(par->state.vgabase, 0x10);
|
||||
par->mclk_freq = ((vga_rseq(par->state.vgabase, 0x11) + 2) * 14318) / ((regval & 0x1F) + 2);
|
||||
par->mclk_freq = par->mclk_freq >> (regval >> 5);
|
||||
|
||||
/* Restore locks */
|
||||
vga_wcrt(NULL, 0x38, cr38);
|
||||
vga_wcrt(NULL, 0x39, cr39);
|
||||
vga_wcrt(par->state.vgabase, 0x38, cr38);
|
||||
vga_wcrt(par->state.vgabase, 0x39, cr39);
|
||||
|
||||
strcpy(info->fix.id, s3_names [par->chip]);
|
||||
info->fix.mmio_start = 0;
|
||||
@ -1027,6 +1099,14 @@ static int __devinit s3_pci_probe(struct pci_dev *dev, const struct pci_device_i
|
||||
goto err_find_mode;
|
||||
}
|
||||
|
||||
/* maximize virtual vertical size for fast scrolling */
|
||||
info->var.yres_virtual = info->fix.smem_len * 8 /
|
||||
(info->var.bits_per_pixel * info->var.xres_virtual);
|
||||
if (info->var.yres_virtual < info->var.yres) {
|
||||
dev_err(info->device, "virtual vertical size smaller than real\n");
|
||||
goto err_find_mode;
|
||||
}
|
||||
|
||||
rc = fb_alloc_cmap(&info->cmap, 256, 0);
|
||||
if (rc < 0) {
|
||||
dev_err(info->device, "cannot allocate colormap\n");
|
||||
@ -1044,8 +1124,8 @@ static int __devinit s3_pci_probe(struct pci_dev *dev, const struct pci_device_i
|
||||
|
||||
if (par->chip == CHIP_UNKNOWN)
|
||||
printk(KERN_INFO "fb%d: unknown chip, CR2D=%x, CR2E=%x, CRT2F=%x, CRT30=%x\n",
|
||||
info->node, vga_rcrt(NULL, 0x2d), vga_rcrt(NULL, 0x2e),
|
||||
vga_rcrt(NULL, 0x2f), vga_rcrt(NULL, 0x30));
|
||||
info->node, vga_rcrt(par->state.vgabase, 0x2d), vga_rcrt(par->state.vgabase, 0x2e),
|
||||
vga_rcrt(par->state.vgabase, 0x2f), vga_rcrt(par->state.vgabase, 0x30));
|
||||
|
||||
/* Record a reference to the driver data */
|
||||
pci_set_drvdata(dev, info);
|
||||
@ -1192,6 +1272,7 @@ static struct pci_device_id s3_devices[] __devinitdata = {
|
||||
{PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A11), .driver_data = CHIP_357_VIRGE_GX2P},
|
||||
{PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A12), .driver_data = CHIP_359_VIRGE_GX2P},
|
||||
{PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A13), .driver_data = CHIP_36X_TRIO3D_1X_2X},
|
||||
{PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8904), .driver_data = CHIP_365_TRIO3D},
|
||||
|
||||
{0, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
@ -459,14 +459,14 @@ static int __devinit sh7760fb_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
par->ioarea = request_mem_region(res->start,
|
||||
(res->end - res->start), pdev->name);
|
||||
resource_size(res), pdev->name);
|
||||
if (!par->ioarea) {
|
||||
dev_err(&pdev->dev, "mmio area busy\n");
|
||||
ret = -EBUSY;
|
||||
goto out_fb;
|
||||
}
|
||||
|
||||
par->base = ioremap_nocache(res->start, res->end - res->start + 1);
|
||||
par->base = ioremap_nocache(res->start, resource_size(res));
|
||||
if (!par->base) {
|
||||
dev_err(&pdev->dev, "cannot remap\n");
|
||||
ret = -ENODEV;
|
||||
|
@ -1088,8 +1088,9 @@ static struct backlight_device *sh_mobile_lcdc_bl_probe(struct device *parent,
|
||||
|
||||
bl = backlight_device_register(ch->cfg.bl_info.name, parent, ch,
|
||||
&sh_mobile_lcdc_bl_ops, NULL);
|
||||
if (!bl) {
|
||||
dev_err(parent, "unable to register backlight device\n");
|
||||
if (IS_ERR(bl)) {
|
||||
dev_err(parent, "unable to register backlight device: %ld\n",
|
||||
PTR_ERR(bl));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -495,6 +495,7 @@ struct sis_video_info {
|
||||
unsigned int refresh_rate;
|
||||
|
||||
unsigned int chip;
|
||||
unsigned int chip_real_id;
|
||||
u8 revision_id;
|
||||
int sisvga_enabled; /* PCI device was enabled */
|
||||
|
||||
|
@ -4563,6 +4563,11 @@ sisfb_post_sis315330(struct pci_dev *pdev)
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline int sisfb_xgi_is21(struct sis_video_info *ivideo)
|
||||
{
|
||||
return ivideo->chip_real_id == XGI_21;
|
||||
}
|
||||
|
||||
static void __devinit
|
||||
sisfb_post_xgi_delay(struct sis_video_info *ivideo, int delay)
|
||||
{
|
||||
@ -4627,11 +4632,11 @@ sisfb_post_xgi_rwtest(struct sis_video_info *ivideo, int starta,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void __devinit
|
||||
static int __devinit
|
||||
sisfb_post_xgi_ramsize(struct sis_video_info *ivideo)
|
||||
{
|
||||
unsigned int buswidth, ranksize, channelab, mapsize;
|
||||
int i, j, k, l;
|
||||
int i, j, k, l, status;
|
||||
u8 reg, sr14;
|
||||
static const u8 dramsr13[12 * 5] = {
|
||||
0x02, 0x0e, 0x0b, 0x80, 0x5d,
|
||||
@ -4673,7 +4678,7 @@ sisfb_post_xgi_ramsize(struct sis_video_info *ivideo)
|
||||
SiS_SetReg(SISSR, 0x13, 0x35);
|
||||
SiS_SetReg(SISSR, 0x14, 0x41);
|
||||
/* TODO */
|
||||
return;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Non-interleaving */
|
||||
@ -4835,6 +4840,7 @@ bail_out:
|
||||
|
||||
j = (ivideo->chip == XGI_20) ? 5 : 9;
|
||||
k = (ivideo->chip == XGI_20) ? 12 : 4;
|
||||
status = -EIO;
|
||||
|
||||
for(i = 0; i < k; i++) {
|
||||
|
||||
@ -4868,11 +4874,15 @@ bail_out:
|
||||
SiS_SetRegANDOR(SISSR, 0x14, 0x0f, (reg & 0xf0));
|
||||
sisfb_post_xgi_delay(ivideo, 1);
|
||||
|
||||
if(sisfb_post_xgi_rwtest(ivideo, j, ((reg >> 4) + channelab - 2 + 20), mapsize))
|
||||
if (sisfb_post_xgi_rwtest(ivideo, j, ((reg >> 4) + channelab - 2 + 20), mapsize)) {
|
||||
status = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
iounmap(ivideo->video_vbase);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void __devinit
|
||||
@ -4931,6 +4941,175 @@ sisfb_post_xgi_setclocks(struct sis_video_info *ivideo, u8 regb)
|
||||
sisfb_post_xgi_delay(ivideo, 0x43);
|
||||
}
|
||||
|
||||
static void __devinit
|
||||
sisfb_post_xgi_ddr2_mrs_default(struct sis_video_info *ivideo, u8 regb)
|
||||
{
|
||||
unsigned char *bios = ivideo->bios_abase;
|
||||
u8 v1;
|
||||
|
||||
SiS_SetReg(SISSR, 0x28, 0x64);
|
||||
SiS_SetReg(SISSR, 0x29, 0x63);
|
||||
sisfb_post_xgi_delay(ivideo, 15);
|
||||
SiS_SetReg(SISSR, 0x18, 0x00);
|
||||
SiS_SetReg(SISSR, 0x19, 0x20);
|
||||
SiS_SetReg(SISSR, 0x16, 0x00);
|
||||
SiS_SetReg(SISSR, 0x16, 0x80);
|
||||
SiS_SetReg(SISSR, 0x18, 0xc5);
|
||||
SiS_SetReg(SISSR, 0x19, 0x23);
|
||||
SiS_SetReg(SISSR, 0x16, 0x00);
|
||||
SiS_SetReg(SISSR, 0x16, 0x80);
|
||||
sisfb_post_xgi_delay(ivideo, 1);
|
||||
SiS_SetReg(SISCR, 0x97, 0x11);
|
||||
sisfb_post_xgi_setclocks(ivideo, regb);
|
||||
sisfb_post_xgi_delay(ivideo, 0x46);
|
||||
SiS_SetReg(SISSR, 0x18, 0xc5);
|
||||
SiS_SetReg(SISSR, 0x19, 0x23);
|
||||
SiS_SetReg(SISSR, 0x16, 0x00);
|
||||
SiS_SetReg(SISSR, 0x16, 0x80);
|
||||
sisfb_post_xgi_delay(ivideo, 1);
|
||||
SiS_SetReg(SISSR, 0x1b, 0x04);
|
||||
sisfb_post_xgi_delay(ivideo, 1);
|
||||
SiS_SetReg(SISSR, 0x1b, 0x00);
|
||||
sisfb_post_xgi_delay(ivideo, 1);
|
||||
v1 = 0x31;
|
||||
if (ivideo->haveXGIROM) {
|
||||
v1 = bios[0xf0];
|
||||
}
|
||||
SiS_SetReg(SISSR, 0x18, v1);
|
||||
SiS_SetReg(SISSR, 0x19, 0x06);
|
||||
SiS_SetReg(SISSR, 0x16, 0x04);
|
||||
SiS_SetReg(SISSR, 0x16, 0x84);
|
||||
sisfb_post_xgi_delay(ivideo, 1);
|
||||
}
|
||||
|
||||
static void __devinit
|
||||
sisfb_post_xgi_ddr2_mrs_xg21(struct sis_video_info *ivideo)
|
||||
{
|
||||
sisfb_post_xgi_setclocks(ivideo, 1);
|
||||
|
||||
SiS_SetReg(SISCR, 0x97, 0x11);
|
||||
sisfb_post_xgi_delay(ivideo, 0x46);
|
||||
|
||||
SiS_SetReg(SISSR, 0x18, 0x00); /* EMRS2 */
|
||||
SiS_SetReg(SISSR, 0x19, 0x80);
|
||||
SiS_SetReg(SISSR, 0x16, 0x05);
|
||||
SiS_SetReg(SISSR, 0x16, 0x85);
|
||||
|
||||
SiS_SetReg(SISSR, 0x18, 0x00); /* EMRS3 */
|
||||
SiS_SetReg(SISSR, 0x19, 0xc0);
|
||||
SiS_SetReg(SISSR, 0x16, 0x05);
|
||||
SiS_SetReg(SISSR, 0x16, 0x85);
|
||||
|
||||
SiS_SetReg(SISSR, 0x18, 0x00); /* EMRS1 */
|
||||
SiS_SetReg(SISSR, 0x19, 0x40);
|
||||
SiS_SetReg(SISSR, 0x16, 0x05);
|
||||
SiS_SetReg(SISSR, 0x16, 0x85);
|
||||
|
||||
SiS_SetReg(SISSR, 0x18, 0x42); /* MRS1 */
|
||||
SiS_SetReg(SISSR, 0x19, 0x02);
|
||||
SiS_SetReg(SISSR, 0x16, 0x05);
|
||||
SiS_SetReg(SISSR, 0x16, 0x85);
|
||||
sisfb_post_xgi_delay(ivideo, 1);
|
||||
|
||||
SiS_SetReg(SISSR, 0x1b, 0x04);
|
||||
sisfb_post_xgi_delay(ivideo, 1);
|
||||
|
||||
SiS_SetReg(SISSR, 0x1b, 0x00);
|
||||
sisfb_post_xgi_delay(ivideo, 1);
|
||||
|
||||
SiS_SetReg(SISSR, 0x18, 0x42); /* MRS1 */
|
||||
SiS_SetReg(SISSR, 0x19, 0x00);
|
||||
SiS_SetReg(SISSR, 0x16, 0x05);
|
||||
SiS_SetReg(SISSR, 0x16, 0x85);
|
||||
sisfb_post_xgi_delay(ivideo, 1);
|
||||
}
|
||||
|
||||
static void __devinit
|
||||
sisfb_post_xgi_ddr2(struct sis_video_info *ivideo, u8 regb)
|
||||
{
|
||||
unsigned char *bios = ivideo->bios_abase;
|
||||
static const u8 cs158[8] = {
|
||||
0x88, 0xaa, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
static const u8 cs160[8] = {
|
||||
0x44, 0x77, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
static const u8 cs168[8] = {
|
||||
0x48, 0x78, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
u8 reg;
|
||||
u8 v1;
|
||||
u8 v2;
|
||||
u8 v3;
|
||||
|
||||
SiS_SetReg(SISCR, 0xb0, 0x80); /* DDR2 dual frequency mode */
|
||||
SiS_SetReg(SISCR, 0x82, 0x77);
|
||||
SiS_SetReg(SISCR, 0x86, 0x00);
|
||||
reg = SiS_GetReg(SISCR, 0x86);
|
||||
SiS_SetReg(SISCR, 0x86, 0x88);
|
||||
reg = SiS_GetReg(SISCR, 0x86);
|
||||
v1 = cs168[regb]; v2 = cs160[regb]; v3 = cs158[regb];
|
||||
if (ivideo->haveXGIROM) {
|
||||
v1 = bios[regb + 0x168];
|
||||
v2 = bios[regb + 0x160];
|
||||
v3 = bios[regb + 0x158];
|
||||
}
|
||||
SiS_SetReg(SISCR, 0x86, v1);
|
||||
SiS_SetReg(SISCR, 0x82, 0x77);
|
||||
SiS_SetReg(SISCR, 0x85, 0x00);
|
||||
reg = SiS_GetReg(SISCR, 0x85);
|
||||
SiS_SetReg(SISCR, 0x85, 0x88);
|
||||
reg = SiS_GetReg(SISCR, 0x85);
|
||||
SiS_SetReg(SISCR, 0x85, v2);
|
||||
SiS_SetReg(SISCR, 0x82, v3);
|
||||
SiS_SetReg(SISCR, 0x98, 0x01);
|
||||
SiS_SetReg(SISCR, 0x9a, 0x02);
|
||||
if (sisfb_xgi_is21(ivideo))
|
||||
sisfb_post_xgi_ddr2_mrs_xg21(ivideo);
|
||||
else
|
||||
sisfb_post_xgi_ddr2_mrs_default(ivideo, regb);
|
||||
}
|
||||
|
||||
static u8 __devinit
|
||||
sisfb_post_xgi_ramtype(struct sis_video_info *ivideo)
|
||||
{
|
||||
unsigned char *bios = ivideo->bios_abase;
|
||||
u8 ramtype;
|
||||
u8 reg;
|
||||
u8 v1;
|
||||
|
||||
ramtype = 0x00; v1 = 0x10;
|
||||
if (ivideo->haveXGIROM) {
|
||||
ramtype = bios[0x62];
|
||||
v1 = bios[0x1d2];
|
||||
}
|
||||
if (!(ramtype & 0x80)) {
|
||||
if (sisfb_xgi_is21(ivideo)) {
|
||||
SiS_SetRegAND(SISCR, 0xb4, 0xfd); /* GPIO control */
|
||||
SiS_SetRegOR(SISCR, 0x4a, 0x80); /* GPIOH EN */
|
||||
reg = SiS_GetReg(SISCR, 0x48);
|
||||
SiS_SetRegOR(SISCR, 0xb4, 0x02);
|
||||
ramtype = reg & 0x01; /* GPIOH */
|
||||
} else if (ivideo->chip == XGI_20) {
|
||||
SiS_SetReg(SISCR, 0x97, v1);
|
||||
reg = SiS_GetReg(SISCR, 0x97);
|
||||
if (reg & 0x10) {
|
||||
ramtype = (reg & 0x01) << 1;
|
||||
}
|
||||
} else {
|
||||
reg = SiS_GetReg(SISSR, 0x39);
|
||||
ramtype = reg & 0x02;
|
||||
if (!(ramtype)) {
|
||||
reg = SiS_GetReg(SISSR, 0x3a);
|
||||
ramtype = (reg >> 1) & 0x01;
|
||||
}
|
||||
}
|
||||
}
|
||||
ramtype &= 0x07;
|
||||
|
||||
return ramtype;
|
||||
}
|
||||
|
||||
static int __devinit
|
||||
sisfb_post_xgi(struct pci_dev *pdev)
|
||||
{
|
||||
@ -5213,9 +5392,23 @@ sisfb_post_xgi(struct pci_dev *pdev)
|
||||
SiS_SetReg(SISCR, 0x77, v1);
|
||||
}
|
||||
|
||||
/* RAM type */
|
||||
|
||||
regb = 0; /* ! */
|
||||
/* RAM type:
|
||||
*
|
||||
* 0 == DDR1, 1 == DDR2, 2..7 == reserved?
|
||||
*
|
||||
* The code seems to written so that regb should equal ramtype,
|
||||
* however, so far it has been hardcoded to 0. Enable other values only
|
||||
* on XGI Z9, as it passes the POST, and add a warning for others.
|
||||
*/
|
||||
ramtype = sisfb_post_xgi_ramtype(ivideo);
|
||||
if (!sisfb_xgi_is21(ivideo) && ramtype) {
|
||||
dev_warn(&pdev->dev,
|
||||
"RAM type something else than expected: %d\n",
|
||||
ramtype);
|
||||
regb = 0;
|
||||
} else {
|
||||
regb = ramtype;
|
||||
}
|
||||
|
||||
v1 = 0xff;
|
||||
if(ivideo->haveXGIROM) {
|
||||
@ -5367,7 +5560,10 @@ sisfb_post_xgi(struct pci_dev *pdev)
|
||||
}
|
||||
}
|
||||
|
||||
SiS_SetReg(SISSR, 0x17, 0x00);
|
||||
if (regb == 1)
|
||||
SiS_SetReg(SISSR, 0x17, 0x80); /* DDR2 */
|
||||
else
|
||||
SiS_SetReg(SISSR, 0x17, 0x00); /* DDR1 */
|
||||
SiS_SetReg(SISSR, 0x1a, 0x87);
|
||||
|
||||
if(ivideo->chip == XGI_20) {
|
||||
@ -5375,31 +5571,6 @@ sisfb_post_xgi(struct pci_dev *pdev)
|
||||
SiS_SetReg(SISSR, 0x1c, 0x00);
|
||||
}
|
||||
|
||||
ramtype = 0x00; v1 = 0x10;
|
||||
if(ivideo->haveXGIROM) {
|
||||
ramtype = bios[0x62];
|
||||
v1 = bios[0x1d2];
|
||||
}
|
||||
if(!(ramtype & 0x80)) {
|
||||
if(ivideo->chip == XGI_20) {
|
||||
SiS_SetReg(SISCR, 0x97, v1);
|
||||
reg = SiS_GetReg(SISCR, 0x97);
|
||||
if(reg & 0x10) {
|
||||
ramtype = (reg & 0x01) << 1;
|
||||
}
|
||||
} else {
|
||||
reg = SiS_GetReg(SISSR, 0x39);
|
||||
ramtype = reg & 0x02;
|
||||
if(!(ramtype)) {
|
||||
reg = SiS_GetReg(SISSR, 0x3a);
|
||||
ramtype = (reg >> 1) & 0x01;
|
||||
}
|
||||
}
|
||||
}
|
||||
ramtype &= 0x07;
|
||||
|
||||
regb = 0; /* ! */
|
||||
|
||||
switch(ramtype) {
|
||||
case 0:
|
||||
sisfb_post_xgi_setclocks(ivideo, regb);
|
||||
@ -5485,61 +5656,7 @@ sisfb_post_xgi(struct pci_dev *pdev)
|
||||
SiS_SetReg(SISSR, 0x1b, 0x00);
|
||||
break;
|
||||
case 1:
|
||||
SiS_SetReg(SISCR, 0x82, 0x77);
|
||||
SiS_SetReg(SISCR, 0x86, 0x00);
|
||||
reg = SiS_GetReg(SISCR, 0x86);
|
||||
SiS_SetReg(SISCR, 0x86, 0x88);
|
||||
reg = SiS_GetReg(SISCR, 0x86);
|
||||
v1 = cs168[regb]; v2 = cs160[regb]; v3 = cs158[regb];
|
||||
if(ivideo->haveXGIROM) {
|
||||
v1 = bios[regb + 0x168];
|
||||
v2 = bios[regb + 0x160];
|
||||
v3 = bios[regb + 0x158];
|
||||
}
|
||||
SiS_SetReg(SISCR, 0x86, v1);
|
||||
SiS_SetReg(SISCR, 0x82, 0x77);
|
||||
SiS_SetReg(SISCR, 0x85, 0x00);
|
||||
reg = SiS_GetReg(SISCR, 0x85);
|
||||
SiS_SetReg(SISCR, 0x85, 0x88);
|
||||
reg = SiS_GetReg(SISCR, 0x85);
|
||||
SiS_SetReg(SISCR, 0x85, v2);
|
||||
SiS_SetReg(SISCR, 0x82, v3);
|
||||
SiS_SetReg(SISCR, 0x98, 0x01);
|
||||
SiS_SetReg(SISCR, 0x9a, 0x02);
|
||||
|
||||
SiS_SetReg(SISSR, 0x28, 0x64);
|
||||
SiS_SetReg(SISSR, 0x29, 0x63);
|
||||
sisfb_post_xgi_delay(ivideo, 15);
|
||||
SiS_SetReg(SISSR, 0x18, 0x00);
|
||||
SiS_SetReg(SISSR, 0x19, 0x20);
|
||||
SiS_SetReg(SISSR, 0x16, 0x00);
|
||||
SiS_SetReg(SISSR, 0x16, 0x80);
|
||||
SiS_SetReg(SISSR, 0x18, 0xc5);
|
||||
SiS_SetReg(SISSR, 0x19, 0x23);
|
||||
SiS_SetReg(SISSR, 0x16, 0x00);
|
||||
SiS_SetReg(SISSR, 0x16, 0x80);
|
||||
sisfb_post_xgi_delay(ivideo, 1);
|
||||
SiS_SetReg(SISCR, 0x97, 0x11);
|
||||
sisfb_post_xgi_setclocks(ivideo, regb);
|
||||
sisfb_post_xgi_delay(ivideo, 0x46);
|
||||
SiS_SetReg(SISSR, 0x18, 0xc5);
|
||||
SiS_SetReg(SISSR, 0x19, 0x23);
|
||||
SiS_SetReg(SISSR, 0x16, 0x00);
|
||||
SiS_SetReg(SISSR, 0x16, 0x80);
|
||||
sisfb_post_xgi_delay(ivideo, 1);
|
||||
SiS_SetReg(SISSR, 0x1b, 0x04);
|
||||
sisfb_post_xgi_delay(ivideo, 1);
|
||||
SiS_SetReg(SISSR, 0x1b, 0x00);
|
||||
sisfb_post_xgi_delay(ivideo, 1);
|
||||
v1 = 0x31;
|
||||
if(ivideo->haveXGIROM) {
|
||||
v1 = bios[0xf0];
|
||||
}
|
||||
SiS_SetReg(SISSR, 0x18, v1);
|
||||
SiS_SetReg(SISSR, 0x19, 0x06);
|
||||
SiS_SetReg(SISSR, 0x16, 0x04);
|
||||
SiS_SetReg(SISSR, 0x16, 0x84);
|
||||
sisfb_post_xgi_delay(ivideo, 1);
|
||||
sisfb_post_xgi_ddr2(ivideo, regb);
|
||||
break;
|
||||
default:
|
||||
sisfb_post_xgi_setclocks(ivideo, regb);
|
||||
@ -5648,6 +5765,7 @@ sisfb_post_xgi(struct pci_dev *pdev)
|
||||
SiS_SetReg(SISSR, 0x14, bios[regb + 0xe0 + 8]);
|
||||
|
||||
} else {
|
||||
int err;
|
||||
|
||||
/* Set default mode, don't clear screen */
|
||||
ivideo->SiS_Pr.SiS_UseOEM = false;
|
||||
@ -5661,10 +5779,16 @@ sisfb_post_xgi(struct pci_dev *pdev)
|
||||
|
||||
/* Disable read-cache */
|
||||
SiS_SetRegAND(SISSR, 0x21, 0xdf);
|
||||
sisfb_post_xgi_ramsize(ivideo);
|
||||
err = sisfb_post_xgi_ramsize(ivideo);
|
||||
/* Enable read-cache */
|
||||
SiS_SetRegOR(SISSR, 0x21, 0x20);
|
||||
|
||||
if (err) {
|
||||
dev_err(&pdev->dev,
|
||||
"%s: RAM size detection failed: %d\n",
|
||||
__func__, err);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
@ -5777,6 +5901,7 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
#endif
|
||||
|
||||
ivideo->chip = chipinfo->chip;
|
||||
ivideo->chip_real_id = chipinfo->chip;
|
||||
ivideo->sisvga_engine = chipinfo->vgaengine;
|
||||
ivideo->hwcursor_size = chipinfo->hwcursor_size;
|
||||
ivideo->CRT2_write_enable = chipinfo->CRT2_write_enable;
|
||||
@ -6010,6 +6135,18 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
sisfb_detect_custom_timing(ivideo);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FB_SIS_315
|
||||
if (ivideo->chip == XGI_20) {
|
||||
/* Check if our Z7 chip is actually Z9 */
|
||||
SiS_SetRegOR(SISCR, 0x4a, 0x40); /* GPIOG EN */
|
||||
reg = SiS_GetReg(SISCR, 0x48);
|
||||
if (reg & 0x02) { /* GPIOG */
|
||||
ivideo->chip_real_id = XGI_21;
|
||||
dev_info(&pdev->dev, "Z9 detected\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* POST card in case this has not been done by the BIOS */
|
||||
if( (!ivideo->sisvga_enabled)
|
||||
#if !defined(__i386__) && !defined(__x86_64__)
|
||||
|
@ -87,6 +87,7 @@ typedef enum _SIS_CHIP_TYPE {
|
||||
SIS_341,
|
||||
SIS_342,
|
||||
XGI_20 = 75,
|
||||
XGI_21,
|
||||
XGI_40,
|
||||
MAX_SIS_CHIP
|
||||
} SIS_CHIP_TYPE;
|
||||
|
@ -41,6 +41,26 @@
|
||||
#include <linux/sm501.h>
|
||||
#include <linux/sm501-regs.h>
|
||||
|
||||
#include "edid.h"
|
||||
|
||||
static char *fb_mode = "640x480-16@60";
|
||||
static unsigned long default_bpp = 16;
|
||||
|
||||
static struct fb_videomode __devinitdata sm501_default_mode = {
|
||||
.refresh = 60,
|
||||
.xres = 640,
|
||||
.yres = 480,
|
||||
.pixclock = 20833,
|
||||
.left_margin = 142,
|
||||
.right_margin = 13,
|
||||
.upper_margin = 21,
|
||||
.lower_margin = 1,
|
||||
.hsync_len = 69,
|
||||
.vsync_len = 3,
|
||||
.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
|
||||
.vmode = FB_VMODE_NONINTERLACED
|
||||
};
|
||||
|
||||
#define NR_PALETTE 256
|
||||
|
||||
enum sm501_controller {
|
||||
@ -77,6 +97,7 @@ struct sm501fb_info {
|
||||
void __iomem *regs2d; /* 2d remapped registers */
|
||||
void __iomem *fbmem; /* remapped framebuffer */
|
||||
size_t fbmem_len; /* length of remapped region */
|
||||
u8 *edid_data;
|
||||
};
|
||||
|
||||
/* per-framebuffer private data */
|
||||
@ -117,7 +138,7 @@ static inline int v_total(struct fb_var_screeninfo *var)
|
||||
|
||||
static inline void sm501fb_sync_regs(struct sm501fb_info *info)
|
||||
{
|
||||
readl(info->regs);
|
||||
smc501_readl(info->regs);
|
||||
}
|
||||
|
||||
/* sm501_alloc_mem
|
||||
@ -262,7 +283,7 @@ static void sm501fb_setup_gamma(struct sm501fb_info *fbi,
|
||||
|
||||
/* set gamma values */
|
||||
for (offset = 0; offset < 256 * 4; offset += 4) {
|
||||
writel(value, fbi->regs + palette + offset);
|
||||
smc501_writel(value, fbi->regs + palette + offset);
|
||||
value += 0x010101; /* Advance RGB by 1,1,1.*/
|
||||
}
|
||||
}
|
||||
@ -476,7 +497,8 @@ static int sm501fb_set_par_common(struct fb_info *info,
|
||||
|
||||
/* set start of framebuffer to the screen */
|
||||
|
||||
writel(par->screen.sm_addr | SM501_ADDR_FLIP, fbi->regs + head_addr);
|
||||
smc501_writel(par->screen.sm_addr | SM501_ADDR_FLIP,
|
||||
fbi->regs + head_addr);
|
||||
|
||||
/* program CRT clock */
|
||||
|
||||
@ -519,7 +541,7 @@ static void sm501fb_set_par_geometry(struct fb_info *info,
|
||||
reg = info->fix.line_length;
|
||||
reg |= ((var->xres * var->bits_per_pixel)/8) << 16;
|
||||
|
||||
writel(reg, fbi->regs + (par->head == HEAD_CRT ?
|
||||
smc501_writel(reg, fbi->regs + (par->head == HEAD_CRT ?
|
||||
SM501_DC_CRT_FB_OFFSET : SM501_DC_PANEL_FB_OFFSET));
|
||||
|
||||
/* program horizontal total */
|
||||
@ -527,27 +549,27 @@ static void sm501fb_set_par_geometry(struct fb_info *info,
|
||||
reg = (h_total(var) - 1) << 16;
|
||||
reg |= (var->xres - 1);
|
||||
|
||||
writel(reg, base + SM501_OFF_DC_H_TOT);
|
||||
smc501_writel(reg, base + SM501_OFF_DC_H_TOT);
|
||||
|
||||
/* program horizontal sync */
|
||||
|
||||
reg = var->hsync_len << 16;
|
||||
reg |= var->xres + var->right_margin - 1;
|
||||
|
||||
writel(reg, base + SM501_OFF_DC_H_SYNC);
|
||||
smc501_writel(reg, base + SM501_OFF_DC_H_SYNC);
|
||||
|
||||
/* program vertical total */
|
||||
|
||||
reg = (v_total(var) - 1) << 16;
|
||||
reg |= (var->yres - 1);
|
||||
|
||||
writel(reg, base + SM501_OFF_DC_V_TOT);
|
||||
smc501_writel(reg, base + SM501_OFF_DC_V_TOT);
|
||||
|
||||
/* program vertical sync */
|
||||
reg = var->vsync_len << 16;
|
||||
reg |= var->yres + var->lower_margin - 1;
|
||||
|
||||
writel(reg, base + SM501_OFF_DC_V_SYNC);
|
||||
smc501_writel(reg, base + SM501_OFF_DC_V_SYNC);
|
||||
}
|
||||
|
||||
/* sm501fb_pan_crt
|
||||
@ -566,15 +588,15 @@ static int sm501fb_pan_crt(struct fb_var_screeninfo *var,
|
||||
|
||||
xoffs = var->xoffset * bytes_pixel;
|
||||
|
||||
reg = readl(fbi->regs + SM501_DC_CRT_CONTROL);
|
||||
reg = smc501_readl(fbi->regs + SM501_DC_CRT_CONTROL);
|
||||
|
||||
reg &= ~SM501_DC_CRT_CONTROL_PIXEL_MASK;
|
||||
reg |= ((xoffs & 15) / bytes_pixel) << 4;
|
||||
writel(reg, fbi->regs + SM501_DC_CRT_CONTROL);
|
||||
smc501_writel(reg, fbi->regs + SM501_DC_CRT_CONTROL);
|
||||
|
||||
reg = (par->screen.sm_addr + xoffs +
|
||||
var->yoffset * info->fix.line_length);
|
||||
writel(reg | SM501_ADDR_FLIP, fbi->regs + SM501_DC_CRT_FB_ADDR);
|
||||
smc501_writel(reg | SM501_ADDR_FLIP, fbi->regs + SM501_DC_CRT_FB_ADDR);
|
||||
|
||||
sm501fb_sync_regs(fbi);
|
||||
return 0;
|
||||
@ -593,10 +615,10 @@ static int sm501fb_pan_pnl(struct fb_var_screeninfo *var,
|
||||
unsigned long reg;
|
||||
|
||||
reg = var->xoffset | (var->xres_virtual << 16);
|
||||
writel(reg, fbi->regs + SM501_DC_PANEL_FB_WIDTH);
|
||||
smc501_writel(reg, fbi->regs + SM501_DC_PANEL_FB_WIDTH);
|
||||
|
||||
reg = var->yoffset | (var->yres_virtual << 16);
|
||||
writel(reg, fbi->regs + SM501_DC_PANEL_FB_HEIGHT);
|
||||
smc501_writel(reg, fbi->regs + SM501_DC_PANEL_FB_HEIGHT);
|
||||
|
||||
sm501fb_sync_regs(fbi);
|
||||
return 0;
|
||||
@ -622,7 +644,7 @@ static int sm501fb_set_par_crt(struct fb_info *info)
|
||||
/* enable CRT DAC - note 0 is on!*/
|
||||
sm501_misc_control(fbi->dev->parent, 0, SM501_MISC_DAC_POWER);
|
||||
|
||||
control = readl(fbi->regs + SM501_DC_CRT_CONTROL);
|
||||
control = smc501_readl(fbi->regs + SM501_DC_CRT_CONTROL);
|
||||
|
||||
control &= (SM501_DC_CRT_CONTROL_PIXEL_MASK |
|
||||
SM501_DC_CRT_CONTROL_GAMMA |
|
||||
@ -684,7 +706,7 @@ static int sm501fb_set_par_crt(struct fb_info *info)
|
||||
out_update:
|
||||
dev_dbg(fbi->dev, "new control is %08lx\n", control);
|
||||
|
||||
writel(control, fbi->regs + SM501_DC_CRT_CONTROL);
|
||||
smc501_writel(control, fbi->regs + SM501_DC_CRT_CONTROL);
|
||||
sm501fb_sync_regs(fbi);
|
||||
|
||||
return 0;
|
||||
@ -696,18 +718,18 @@ static void sm501fb_panel_power(struct sm501fb_info *fbi, int to)
|
||||
void __iomem *ctrl_reg = fbi->regs + SM501_DC_PANEL_CONTROL;
|
||||
struct sm501_platdata_fbsub *pd = fbi->pdata->fb_pnl;
|
||||
|
||||
control = readl(ctrl_reg);
|
||||
control = smc501_readl(ctrl_reg);
|
||||
|
||||
if (to && (control & SM501_DC_PANEL_CONTROL_VDD) == 0) {
|
||||
/* enable panel power */
|
||||
|
||||
control |= SM501_DC_PANEL_CONTROL_VDD; /* FPVDDEN */
|
||||
writel(control, ctrl_reg);
|
||||
smc501_writel(control, ctrl_reg);
|
||||
sm501fb_sync_regs(fbi);
|
||||
mdelay(10);
|
||||
|
||||
control |= SM501_DC_PANEL_CONTROL_DATA; /* DATA */
|
||||
writel(control, ctrl_reg);
|
||||
smc501_writel(control, ctrl_reg);
|
||||
sm501fb_sync_regs(fbi);
|
||||
mdelay(10);
|
||||
|
||||
@ -719,7 +741,7 @@ static void sm501fb_panel_power(struct sm501fb_info *fbi, int to)
|
||||
else
|
||||
control |= SM501_DC_PANEL_CONTROL_BIAS;
|
||||
|
||||
writel(control, ctrl_reg);
|
||||
smc501_writel(control, ctrl_reg);
|
||||
sm501fb_sync_regs(fbi);
|
||||
mdelay(10);
|
||||
}
|
||||
@ -730,7 +752,7 @@ static void sm501fb_panel_power(struct sm501fb_info *fbi, int to)
|
||||
else
|
||||
control |= SM501_DC_PANEL_CONTROL_FPEN;
|
||||
|
||||
writel(control, ctrl_reg);
|
||||
smc501_writel(control, ctrl_reg);
|
||||
sm501fb_sync_regs(fbi);
|
||||
mdelay(10);
|
||||
}
|
||||
@ -742,7 +764,7 @@ static void sm501fb_panel_power(struct sm501fb_info *fbi, int to)
|
||||
else
|
||||
control &= ~SM501_DC_PANEL_CONTROL_FPEN;
|
||||
|
||||
writel(control, ctrl_reg);
|
||||
smc501_writel(control, ctrl_reg);
|
||||
sm501fb_sync_regs(fbi);
|
||||
mdelay(10);
|
||||
}
|
||||
@ -753,18 +775,18 @@ static void sm501fb_panel_power(struct sm501fb_info *fbi, int to)
|
||||
else
|
||||
control &= ~SM501_DC_PANEL_CONTROL_BIAS;
|
||||
|
||||
writel(control, ctrl_reg);
|
||||
smc501_writel(control, ctrl_reg);
|
||||
sm501fb_sync_regs(fbi);
|
||||
mdelay(10);
|
||||
}
|
||||
|
||||
control &= ~SM501_DC_PANEL_CONTROL_DATA;
|
||||
writel(control, ctrl_reg);
|
||||
smc501_writel(control, ctrl_reg);
|
||||
sm501fb_sync_regs(fbi);
|
||||
mdelay(10);
|
||||
|
||||
control &= ~SM501_DC_PANEL_CONTROL_VDD;
|
||||
writel(control, ctrl_reg);
|
||||
smc501_writel(control, ctrl_reg);
|
||||
sm501fb_sync_regs(fbi);
|
||||
mdelay(10);
|
||||
}
|
||||
@ -799,7 +821,7 @@ static int sm501fb_set_par_pnl(struct fb_info *info)
|
||||
|
||||
/* update control register */
|
||||
|
||||
control = readl(fbi->regs + SM501_DC_PANEL_CONTROL);
|
||||
control = smc501_readl(fbi->regs + SM501_DC_PANEL_CONTROL);
|
||||
control &= (SM501_DC_PANEL_CONTROL_GAMMA |
|
||||
SM501_DC_PANEL_CONTROL_VDD |
|
||||
SM501_DC_PANEL_CONTROL_DATA |
|
||||
@ -833,16 +855,16 @@ static int sm501fb_set_par_pnl(struct fb_info *info)
|
||||
BUG();
|
||||
}
|
||||
|
||||
writel(0x0, fbi->regs + SM501_DC_PANEL_PANNING_CONTROL);
|
||||
smc501_writel(0x0, fbi->regs + SM501_DC_PANEL_PANNING_CONTROL);
|
||||
|
||||
/* panel plane top left and bottom right location */
|
||||
|
||||
writel(0x00, fbi->regs + SM501_DC_PANEL_TL_LOC);
|
||||
smc501_writel(0x00, fbi->regs + SM501_DC_PANEL_TL_LOC);
|
||||
|
||||
reg = var->xres - 1;
|
||||
reg |= (var->yres - 1) << 16;
|
||||
|
||||
writel(reg, fbi->regs + SM501_DC_PANEL_BR_LOC);
|
||||
smc501_writel(reg, fbi->regs + SM501_DC_PANEL_BR_LOC);
|
||||
|
||||
/* program panel control register */
|
||||
|
||||
@ -855,7 +877,7 @@ static int sm501fb_set_par_pnl(struct fb_info *info)
|
||||
if ((var->sync & FB_SYNC_VERT_HIGH_ACT) == 0)
|
||||
control |= SM501_DC_PANEL_CONTROL_VSP;
|
||||
|
||||
writel(control, fbi->regs + SM501_DC_PANEL_CONTROL);
|
||||
smc501_writel(control, fbi->regs + SM501_DC_PANEL_CONTROL);
|
||||
sm501fb_sync_regs(fbi);
|
||||
|
||||
/* ensure the panel interface is not tristated at this point */
|
||||
@ -924,7 +946,7 @@ static int sm501fb_setcolreg(unsigned regno,
|
||||
val |= (green >> 8) << 8;
|
||||
val |= blue >> 8;
|
||||
|
||||
writel(val, base + (regno * 4));
|
||||
smc501_writel(val, base + (regno * 4));
|
||||
}
|
||||
|
||||
break;
|
||||
@ -980,7 +1002,7 @@ static int sm501fb_blank_crt(int blank_mode, struct fb_info *info)
|
||||
|
||||
dev_dbg(fbi->dev, "%s(mode=%d, %p)\n", __func__, blank_mode, info);
|
||||
|
||||
ctrl = readl(fbi->regs + SM501_DC_CRT_CONTROL);
|
||||
ctrl = smc501_readl(fbi->regs + SM501_DC_CRT_CONTROL);
|
||||
|
||||
switch (blank_mode) {
|
||||
case FB_BLANK_POWERDOWN:
|
||||
@ -1004,7 +1026,7 @@ static int sm501fb_blank_crt(int blank_mode, struct fb_info *info)
|
||||
|
||||
}
|
||||
|
||||
writel(ctrl, fbi->regs + SM501_DC_CRT_CONTROL);
|
||||
smc501_writel(ctrl, fbi->regs + SM501_DC_CRT_CONTROL);
|
||||
sm501fb_sync_regs(fbi);
|
||||
|
||||
return 0;
|
||||
@ -1041,12 +1063,14 @@ static int sm501fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
|
||||
if (cursor->image.depth > 1)
|
||||
return -EINVAL;
|
||||
|
||||
hwc_addr = readl(base + SM501_OFF_HWC_ADDR);
|
||||
hwc_addr = smc501_readl(base + SM501_OFF_HWC_ADDR);
|
||||
|
||||
if (cursor->enable)
|
||||
writel(hwc_addr | SM501_HWC_EN, base + SM501_OFF_HWC_ADDR);
|
||||
smc501_writel(hwc_addr | SM501_HWC_EN,
|
||||
base + SM501_OFF_HWC_ADDR);
|
||||
else
|
||||
writel(hwc_addr & ~SM501_HWC_EN, base + SM501_OFF_HWC_ADDR);
|
||||
smc501_writel(hwc_addr & ~SM501_HWC_EN,
|
||||
base + SM501_OFF_HWC_ADDR);
|
||||
|
||||
/* set data */
|
||||
if (cursor->set & FB_CUR_SETPOS) {
|
||||
@ -1060,7 +1084,7 @@ static int sm501fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
|
||||
|
||||
//y += cursor->image.height;
|
||||
|
||||
writel(x | (y << 16), base + SM501_OFF_HWC_LOC);
|
||||
smc501_writel(x | (y << 16), base + SM501_OFF_HWC_LOC);
|
||||
}
|
||||
|
||||
if (cursor->set & FB_CUR_SETCMAP) {
|
||||
@ -1080,8 +1104,8 @@ static int sm501fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
|
||||
|
||||
dev_dbg(fbi->dev, "fgcol %08lx, bgcol %08lx\n", fg, bg);
|
||||
|
||||
writel(bg, base + SM501_OFF_HWC_COLOR_1_2);
|
||||
writel(fg, base + SM501_OFF_HWC_COLOR_3);
|
||||
smc501_writel(bg, base + SM501_OFF_HWC_COLOR_1_2);
|
||||
smc501_writel(fg, base + SM501_OFF_HWC_COLOR_3);
|
||||
}
|
||||
|
||||
if (cursor->set & FB_CUR_SETSIZE ||
|
||||
@ -1102,7 +1126,7 @@ static int sm501fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
|
||||
__func__, cursor->image.width, cursor->image.height);
|
||||
|
||||
for (op = 0; op < (64*64*2)/8; op+=4)
|
||||
writel(0x0, dst + op);
|
||||
smc501_writel(0x0, dst + op);
|
||||
|
||||
for (y = 0; y < cursor->image.height; y++) {
|
||||
for (x = 0; x < cursor->image.width; x++) {
|
||||
@ -1141,7 +1165,7 @@ static ssize_t sm501fb_crtsrc_show(struct device *dev,
|
||||
struct sm501fb_info *info = dev_get_drvdata(dev);
|
||||
unsigned long ctrl;
|
||||
|
||||
ctrl = readl(info->regs + SM501_DC_CRT_CONTROL);
|
||||
ctrl = smc501_readl(info->regs + SM501_DC_CRT_CONTROL);
|
||||
ctrl &= SM501_DC_CRT_CONTROL_SEL;
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%s\n", ctrl ? "crt" : "panel");
|
||||
@ -1172,7 +1196,7 @@ static ssize_t sm501fb_crtsrc_store(struct device *dev,
|
||||
|
||||
dev_info(dev, "setting crt source to head %d\n", head);
|
||||
|
||||
ctrl = readl(info->regs + SM501_DC_CRT_CONTROL);
|
||||
ctrl = smc501_readl(info->regs + SM501_DC_CRT_CONTROL);
|
||||
|
||||
if (head == HEAD_CRT) {
|
||||
ctrl |= SM501_DC_CRT_CONTROL_SEL;
|
||||
@ -1184,7 +1208,7 @@ static ssize_t sm501fb_crtsrc_store(struct device *dev,
|
||||
ctrl &= ~SM501_DC_CRT_CONTROL_TE;
|
||||
}
|
||||
|
||||
writel(ctrl, info->regs + SM501_DC_CRT_CONTROL);
|
||||
smc501_writel(ctrl, info->regs + SM501_DC_CRT_CONTROL);
|
||||
sm501fb_sync_regs(info);
|
||||
|
||||
return len;
|
||||
@ -1205,7 +1229,8 @@ static int sm501fb_show_regs(struct sm501fb_info *info, char *ptr,
|
||||
unsigned int reg;
|
||||
|
||||
for (reg = start; reg < (len + start); reg += 4)
|
||||
ptr += sprintf(ptr, "%08x = %08x\n", reg, readl(mem + reg));
|
||||
ptr += sprintf(ptr, "%08x = %08x\n", reg,
|
||||
smc501_readl(mem + reg));
|
||||
|
||||
return ptr - buf;
|
||||
}
|
||||
@ -1257,7 +1282,7 @@ static int sm501fb_sync(struct fb_info *info)
|
||||
|
||||
/* wait for the 2d engine to be ready */
|
||||
while ((count > 0) &&
|
||||
(readl(fbi->regs + SM501_SYSTEM_CONTROL) &
|
||||
(smc501_readl(fbi->regs + SM501_SYSTEM_CONTROL) &
|
||||
SM501_SYSCTRL_2D_ENGINE_STATUS) != 0)
|
||||
count--;
|
||||
|
||||
@ -1312,45 +1337,46 @@ static void sm501fb_copyarea(struct fb_info *info, const struct fb_copyarea *are
|
||||
return;
|
||||
|
||||
/* set the base addresses */
|
||||
writel(par->screen.sm_addr, fbi->regs2d + SM501_2D_SOURCE_BASE);
|
||||
writel(par->screen.sm_addr, fbi->regs2d + SM501_2D_DESTINATION_BASE);
|
||||
smc501_writel(par->screen.sm_addr, fbi->regs2d + SM501_2D_SOURCE_BASE);
|
||||
smc501_writel(par->screen.sm_addr,
|
||||
fbi->regs2d + SM501_2D_DESTINATION_BASE);
|
||||
|
||||
/* set the window width */
|
||||
writel((info->var.xres << 16) | info->var.xres,
|
||||
smc501_writel((info->var.xres << 16) | info->var.xres,
|
||||
fbi->regs2d + SM501_2D_WINDOW_WIDTH);
|
||||
|
||||
/* set window stride */
|
||||
writel((info->var.xres_virtual << 16) | info->var.xres_virtual,
|
||||
smc501_writel((info->var.xres_virtual << 16) | info->var.xres_virtual,
|
||||
fbi->regs2d + SM501_2D_PITCH);
|
||||
|
||||
/* set data format */
|
||||
switch (info->var.bits_per_pixel) {
|
||||
case 8:
|
||||
writel(0, fbi->regs2d + SM501_2D_STRETCH);
|
||||
smc501_writel(0, fbi->regs2d + SM501_2D_STRETCH);
|
||||
break;
|
||||
case 16:
|
||||
writel(0x00100000, fbi->regs2d + SM501_2D_STRETCH);
|
||||
smc501_writel(0x00100000, fbi->regs2d + SM501_2D_STRETCH);
|
||||
break;
|
||||
case 32:
|
||||
writel(0x00200000, fbi->regs2d + SM501_2D_STRETCH);
|
||||
smc501_writel(0x00200000, fbi->regs2d + SM501_2D_STRETCH);
|
||||
break;
|
||||
}
|
||||
|
||||
/* 2d compare mask */
|
||||
writel(0xffffffff, fbi->regs2d + SM501_2D_COLOR_COMPARE_MASK);
|
||||
smc501_writel(0xffffffff, fbi->regs2d + SM501_2D_COLOR_COMPARE_MASK);
|
||||
|
||||
/* 2d mask */
|
||||
writel(0xffffffff, fbi->regs2d + SM501_2D_MASK);
|
||||
smc501_writel(0xffffffff, fbi->regs2d + SM501_2D_MASK);
|
||||
|
||||
/* source and destination x y */
|
||||
writel((sx << 16) | sy, fbi->regs2d + SM501_2D_SOURCE);
|
||||
writel((dx << 16) | dy, fbi->regs2d + SM501_2D_DESTINATION);
|
||||
smc501_writel((sx << 16) | sy, fbi->regs2d + SM501_2D_SOURCE);
|
||||
smc501_writel((dx << 16) | dy, fbi->regs2d + SM501_2D_DESTINATION);
|
||||
|
||||
/* w/h */
|
||||
writel((width << 16) | height, fbi->regs2d + SM501_2D_DIMENSION);
|
||||
smc501_writel((width << 16) | height, fbi->regs2d + SM501_2D_DIMENSION);
|
||||
|
||||
/* do area move */
|
||||
writel(0x800000cc | rtl, fbi->regs2d + SM501_2D_CONTROL);
|
||||
smc501_writel(0x800000cc | rtl, fbi->regs2d + SM501_2D_CONTROL);
|
||||
}
|
||||
|
||||
static void sm501fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
|
||||
@ -1372,47 +1398,49 @@ static void sm501fb_fillrect(struct fb_info *info, const struct fb_fillrect *rec
|
||||
return;
|
||||
|
||||
/* set the base addresses */
|
||||
writel(par->screen.sm_addr, fbi->regs2d + SM501_2D_SOURCE_BASE);
|
||||
writel(par->screen.sm_addr, fbi->regs2d + SM501_2D_DESTINATION_BASE);
|
||||
smc501_writel(par->screen.sm_addr, fbi->regs2d + SM501_2D_SOURCE_BASE);
|
||||
smc501_writel(par->screen.sm_addr,
|
||||
fbi->regs2d + SM501_2D_DESTINATION_BASE);
|
||||
|
||||
/* set the window width */
|
||||
writel((info->var.xres << 16) | info->var.xres,
|
||||
smc501_writel((info->var.xres << 16) | info->var.xres,
|
||||
fbi->regs2d + SM501_2D_WINDOW_WIDTH);
|
||||
|
||||
/* set window stride */
|
||||
writel((info->var.xres_virtual << 16) | info->var.xres_virtual,
|
||||
smc501_writel((info->var.xres_virtual << 16) | info->var.xres_virtual,
|
||||
fbi->regs2d + SM501_2D_PITCH);
|
||||
|
||||
/* set data format */
|
||||
switch (info->var.bits_per_pixel) {
|
||||
case 8:
|
||||
writel(0, fbi->regs2d + SM501_2D_STRETCH);
|
||||
smc501_writel(0, fbi->regs2d + SM501_2D_STRETCH);
|
||||
break;
|
||||
case 16:
|
||||
writel(0x00100000, fbi->regs2d + SM501_2D_STRETCH);
|
||||
smc501_writel(0x00100000, fbi->regs2d + SM501_2D_STRETCH);
|
||||
break;
|
||||
case 32:
|
||||
writel(0x00200000, fbi->regs2d + SM501_2D_STRETCH);
|
||||
smc501_writel(0x00200000, fbi->regs2d + SM501_2D_STRETCH);
|
||||
break;
|
||||
}
|
||||
|
||||
/* 2d compare mask */
|
||||
writel(0xffffffff, fbi->regs2d + SM501_2D_COLOR_COMPARE_MASK);
|
||||
smc501_writel(0xffffffff, fbi->regs2d + SM501_2D_COLOR_COMPARE_MASK);
|
||||
|
||||
/* 2d mask */
|
||||
writel(0xffffffff, fbi->regs2d + SM501_2D_MASK);
|
||||
smc501_writel(0xffffffff, fbi->regs2d + SM501_2D_MASK);
|
||||
|
||||
/* colour */
|
||||
writel(rect->color, fbi->regs2d + SM501_2D_FOREGROUND);
|
||||
smc501_writel(rect->color, fbi->regs2d + SM501_2D_FOREGROUND);
|
||||
|
||||
/* x y */
|
||||
writel((rect->dx << 16) | rect->dy, fbi->regs2d + SM501_2D_DESTINATION);
|
||||
smc501_writel((rect->dx << 16) | rect->dy,
|
||||
fbi->regs2d + SM501_2D_DESTINATION);
|
||||
|
||||
/* w/h */
|
||||
writel((width << 16) | height, fbi->regs2d + SM501_2D_DIMENSION);
|
||||
smc501_writel((width << 16) | height, fbi->regs2d + SM501_2D_DIMENSION);
|
||||
|
||||
/* do rectangle fill */
|
||||
writel(0x800100cc, fbi->regs2d + SM501_2D_CONTROL);
|
||||
smc501_writel(0x800100cc, fbi->regs2d + SM501_2D_CONTROL);
|
||||
}
|
||||
|
||||
|
||||
@ -1470,11 +1498,12 @@ static int sm501_init_cursor(struct fb_info *fbi, unsigned int reg_base)
|
||||
|
||||
/* initialise the colour registers */
|
||||
|
||||
writel(par->cursor.sm_addr, par->cursor_regs + SM501_OFF_HWC_ADDR);
|
||||
smc501_writel(par->cursor.sm_addr,
|
||||
par->cursor_regs + SM501_OFF_HWC_ADDR);
|
||||
|
||||
writel(0x00, par->cursor_regs + SM501_OFF_HWC_LOC);
|
||||
writel(0x00, par->cursor_regs + SM501_OFF_HWC_COLOR_1_2);
|
||||
writel(0x00, par->cursor_regs + SM501_OFF_HWC_COLOR_3);
|
||||
smc501_writel(0x00, par->cursor_regs + SM501_OFF_HWC_LOC);
|
||||
smc501_writel(0x00, par->cursor_regs + SM501_OFF_HWC_COLOR_1_2);
|
||||
smc501_writel(0x00, par->cursor_regs + SM501_OFF_HWC_COLOR_3);
|
||||
sm501fb_sync_regs(info);
|
||||
|
||||
return 0;
|
||||
@ -1581,7 +1610,7 @@ static int sm501fb_start(struct sm501fb_info *info,
|
||||
|
||||
/* clear palette ram - undefined at power on */
|
||||
for (k = 0; k < (256 * 3); k++)
|
||||
writel(0, info->regs + SM501_DC_PANEL_PALETTE + (k * 4));
|
||||
smc501_writel(0, info->regs + SM501_DC_PANEL_PALETTE + (k * 4));
|
||||
|
||||
/* enable display controller */
|
||||
sm501_unit_power(dev->parent, SM501_GATE_DISPLAY, 1);
|
||||
@ -1649,20 +1678,20 @@ static int sm501fb_init_fb(struct fb_info *fb,
|
||||
switch (head) {
|
||||
case HEAD_CRT:
|
||||
pd = info->pdata->fb_crt;
|
||||
ctrl = readl(info->regs + SM501_DC_CRT_CONTROL);
|
||||
ctrl = smc501_readl(info->regs + SM501_DC_CRT_CONTROL);
|
||||
enable = (ctrl & SM501_DC_CRT_CONTROL_ENABLE) ? 1 : 0;
|
||||
|
||||
/* ensure we set the correct source register */
|
||||
if (info->pdata->fb_route != SM501_FB_CRT_PANEL) {
|
||||
ctrl |= SM501_DC_CRT_CONTROL_SEL;
|
||||
writel(ctrl, info->regs + SM501_DC_CRT_CONTROL);
|
||||
smc501_writel(ctrl, info->regs + SM501_DC_CRT_CONTROL);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case HEAD_PANEL:
|
||||
pd = info->pdata->fb_pnl;
|
||||
ctrl = readl(info->regs + SM501_DC_PANEL_CONTROL);
|
||||
ctrl = smc501_readl(info->regs + SM501_DC_PANEL_CONTROL);
|
||||
enable = (ctrl & SM501_DC_PANEL_CONTROL_EN) ? 1 : 0;
|
||||
break;
|
||||
|
||||
@ -1680,7 +1709,7 @@ static int sm501fb_init_fb(struct fb_info *fb,
|
||||
|
||||
if (head == HEAD_CRT && info->pdata->fb_route == SM501_FB_CRT_PANEL) {
|
||||
ctrl &= ~SM501_DC_CRT_CONTROL_SEL;
|
||||
writel(ctrl, info->regs + SM501_DC_CRT_CONTROL);
|
||||
smc501_writel(ctrl, info->regs + SM501_DC_CRT_CONTROL);
|
||||
enable = 0;
|
||||
}
|
||||
|
||||
@ -1700,6 +1729,15 @@ static int sm501fb_init_fb(struct fb_info *fb,
|
||||
FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT |
|
||||
FBINFO_HWACCEL_XPAN | FBINFO_HWACCEL_YPAN;
|
||||
|
||||
#if defined(CONFIG_OF)
|
||||
#ifdef __BIG_ENDIAN
|
||||
if (of_get_property(info->dev->parent->of_node, "little-endian", NULL))
|
||||
fb->flags |= FBINFO_FOREIGN_ENDIAN;
|
||||
#else
|
||||
if (of_get_property(info->dev->parent->of_node, "big-endian", NULL))
|
||||
fb->flags |= FBINFO_FOREIGN_ENDIAN;
|
||||
#endif
|
||||
#endif
|
||||
/* fixed data */
|
||||
|
||||
fb->fix.type = FB_TYPE_PACKED_PIXELS;
|
||||
@ -1717,9 +1755,16 @@ static int sm501fb_init_fb(struct fb_info *fb,
|
||||
fb->var.vmode = FB_VMODE_NONINTERLACED;
|
||||
fb->var.bits_per_pixel = 16;
|
||||
|
||||
if (info->edid_data) {
|
||||
/* Now build modedb from EDID */
|
||||
fb_edid_to_monspecs(info->edid_data, &fb->monspecs);
|
||||
fb_videomode_to_modelist(fb->monspecs.modedb,
|
||||
fb->monspecs.modedb_len,
|
||||
&fb->modelist);
|
||||
}
|
||||
|
||||
if (enable && (pd->flags & SM501FB_FLAG_USE_INIT_MODE) && 0) {
|
||||
/* TODO read the mode from the current display */
|
||||
|
||||
} else {
|
||||
if (pd->def_mode) {
|
||||
dev_info(info->dev, "using supplied mode\n");
|
||||
@ -1729,12 +1774,37 @@ static int sm501fb_init_fb(struct fb_info *fb,
|
||||
fb->var.xres_virtual = fb->var.xres;
|
||||
fb->var.yres_virtual = fb->var.yres;
|
||||
} else {
|
||||
ret = fb_find_mode(&fb->var, fb,
|
||||
if (info->edid_data) {
|
||||
ret = fb_find_mode(&fb->var, fb, fb_mode,
|
||||
fb->monspecs.modedb,
|
||||
fb->monspecs.modedb_len,
|
||||
&sm501_default_mode, default_bpp);
|
||||
/* edid_data is no longer needed, free it */
|
||||
kfree(info->edid_data);
|
||||
} else {
|
||||
ret = fb_find_mode(&fb->var, fb,
|
||||
NULL, NULL, 0, NULL, 8);
|
||||
}
|
||||
|
||||
if (ret == 0 || ret == 4) {
|
||||
dev_err(info->dev,
|
||||
"failed to get initial mode\n");
|
||||
switch (ret) {
|
||||
case 1:
|
||||
dev_info(info->dev, "using mode specified in "
|
||||
"@mode\n");
|
||||
break;
|
||||
case 2:
|
||||
dev_info(info->dev, "using mode specified in "
|
||||
"@mode with ignored refresh rate\n");
|
||||
break;
|
||||
case 3:
|
||||
dev_info(info->dev, "using mode default "
|
||||
"mode\n");
|
||||
break;
|
||||
case 4:
|
||||
dev_info(info->dev, "using mode from list\n");
|
||||
break;
|
||||
default:
|
||||
dev_info(info->dev, "ret = %d\n", ret);
|
||||
dev_info(info->dev, "failed to find mode\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
@ -1875,8 +1945,32 @@ static int __devinit sm501fb_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
if (info->pdata == NULL) {
|
||||
dev_info(dev, "using default configuration data\n");
|
||||
int found = 0;
|
||||
#if defined(CONFIG_OF)
|
||||
struct device_node *np = pdev->dev.parent->of_node;
|
||||
const u8 *prop;
|
||||
const char *cp;
|
||||
int len;
|
||||
|
||||
info->pdata = &sm501fb_def_pdata;
|
||||
if (np) {
|
||||
/* Get EDID */
|
||||
cp = of_get_property(np, "mode", &len);
|
||||
if (cp)
|
||||
strcpy(fb_mode, cp);
|
||||
prop = of_get_property(np, "edid", &len);
|
||||
if (prop && len == EDID_LENGTH) {
|
||||
info->edid_data = kmemdup(prop, EDID_LENGTH,
|
||||
GFP_KERNEL);
|
||||
if (info->edid_data)
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (!found) {
|
||||
dev_info(dev, "using default configuration data\n");
|
||||
info->pdata = &sm501fb_def_pdata;
|
||||
}
|
||||
}
|
||||
|
||||
/* probe for the presence of each panel */
|
||||
@ -2085,7 +2179,7 @@ static int sm501fb_suspend(struct platform_device *pdev, pm_message_t state)
|
||||
struct sm501fb_info *info = platform_get_drvdata(pdev);
|
||||
|
||||
/* store crt control to resume with */
|
||||
info->pm_crt_ctrl = readl(info->regs + SM501_DC_CRT_CONTROL);
|
||||
info->pm_crt_ctrl = smc501_readl(info->regs + SM501_DC_CRT_CONTROL);
|
||||
|
||||
sm501fb_suspend_fb(info, HEAD_CRT);
|
||||
sm501fb_suspend_fb(info, HEAD_PANEL);
|
||||
@ -2109,10 +2203,10 @@ static int sm501fb_resume(struct platform_device *pdev)
|
||||
|
||||
/* restore the items we want to be saved for crt control */
|
||||
|
||||
crt_ctrl = readl(info->regs + SM501_DC_CRT_CONTROL);
|
||||
crt_ctrl = smc501_readl(info->regs + SM501_DC_CRT_CONTROL);
|
||||
crt_ctrl &= ~SM501_CRT_CTRL_SAVE;
|
||||
crt_ctrl |= info->pm_crt_ctrl & SM501_CRT_CTRL_SAVE;
|
||||
writel(crt_ctrl, info->regs + SM501_DC_CRT_CONTROL);
|
||||
smc501_writel(crt_ctrl, info->regs + SM501_DC_CRT_CONTROL);
|
||||
|
||||
sm501fb_resume_fb(info, HEAD_CRT);
|
||||
sm501fb_resume_fb(info, HEAD_PANEL);
|
||||
@ -2149,6 +2243,11 @@ static void __exit sm501fb_cleanup(void)
|
||||
module_init(sm501fb_init);
|
||||
module_exit(sm501fb_cleanup);
|
||||
|
||||
module_param_named(mode, fb_mode, charp, 0);
|
||||
MODULE_PARM_DESC(mode,
|
||||
"Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" ");
|
||||
module_param_named(bpp, default_bpp, ulong, 0);
|
||||
MODULE_PARM_DESC(bpp, "Specify bit-per-pixel if not specified mode");
|
||||
MODULE_AUTHOR("Ben Dooks, Vincent Sanders");
|
||||
MODULE_DESCRIPTION("SM501 Framebuffer driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
@ -20,12 +20,12 @@
|
||||
|
||||
|
||||
/* Write a CRT register value spread across multiple registers */
|
||||
void svga_wcrt_multi(const struct vga_regset *regset, u32 value) {
|
||||
|
||||
void svga_wcrt_multi(void __iomem *regbase, const struct vga_regset *regset, u32 value)
|
||||
{
|
||||
u8 regval, bitval, bitnum;
|
||||
|
||||
while (regset->regnum != VGA_REGSET_END_VAL) {
|
||||
regval = vga_rcrt(NULL, regset->regnum);
|
||||
regval = vga_rcrt(regbase, regset->regnum);
|
||||
bitnum = regset->lowbit;
|
||||
while (bitnum <= regset->highbit) {
|
||||
bitval = 1 << bitnum;
|
||||
@ -34,18 +34,18 @@ void svga_wcrt_multi(const struct vga_regset *regset, u32 value) {
|
||||
bitnum ++;
|
||||
value = value >> 1;
|
||||
}
|
||||
vga_wcrt(NULL, regset->regnum, regval);
|
||||
vga_wcrt(regbase, regset->regnum, regval);
|
||||
regset ++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Write a sequencer register value spread across multiple registers */
|
||||
void svga_wseq_multi(const struct vga_regset *regset, u32 value) {
|
||||
|
||||
void svga_wseq_multi(void __iomem *regbase, const struct vga_regset *regset, u32 value)
|
||||
{
|
||||
u8 regval, bitval, bitnum;
|
||||
|
||||
while (regset->regnum != VGA_REGSET_END_VAL) {
|
||||
regval = vga_rseq(NULL, regset->regnum);
|
||||
regval = vga_rseq(regbase, regset->regnum);
|
||||
bitnum = regset->lowbit;
|
||||
while (bitnum <= regset->highbit) {
|
||||
bitval = 1 << bitnum;
|
||||
@ -54,7 +54,7 @@ void svga_wseq_multi(const struct vga_regset *regset, u32 value) {
|
||||
bitnum ++;
|
||||
value = value >> 1;
|
||||
}
|
||||
vga_wseq(NULL, regset->regnum, regval);
|
||||
vga_wseq(regbase, regset->regnum, regval);
|
||||
regset ++;
|
||||
}
|
||||
}
|
||||
@ -75,95 +75,95 @@ static unsigned int svga_regset_size(const struct vga_regset *regset)
|
||||
|
||||
|
||||
/* Set graphics controller registers to sane values */
|
||||
void svga_set_default_gfx_regs(void)
|
||||
void svga_set_default_gfx_regs(void __iomem *regbase)
|
||||
{
|
||||
/* All standard GFX registers (GR00 - GR08) */
|
||||
vga_wgfx(NULL, VGA_GFX_SR_VALUE, 0x00);
|
||||
vga_wgfx(NULL, VGA_GFX_SR_ENABLE, 0x00);
|
||||
vga_wgfx(NULL, VGA_GFX_COMPARE_VALUE, 0x00);
|
||||
vga_wgfx(NULL, VGA_GFX_DATA_ROTATE, 0x00);
|
||||
vga_wgfx(NULL, VGA_GFX_PLANE_READ, 0x00);
|
||||
vga_wgfx(NULL, VGA_GFX_MODE, 0x00);
|
||||
/* vga_wgfx(NULL, VGA_GFX_MODE, 0x20); */
|
||||
/* vga_wgfx(NULL, VGA_GFX_MODE, 0x40); */
|
||||
vga_wgfx(NULL, VGA_GFX_MISC, 0x05);
|
||||
/* vga_wgfx(NULL, VGA_GFX_MISC, 0x01); */
|
||||
vga_wgfx(NULL, VGA_GFX_COMPARE_MASK, 0x0F);
|
||||
vga_wgfx(NULL, VGA_GFX_BIT_MASK, 0xFF);
|
||||
vga_wgfx(regbase, VGA_GFX_SR_VALUE, 0x00);
|
||||
vga_wgfx(regbase, VGA_GFX_SR_ENABLE, 0x00);
|
||||
vga_wgfx(regbase, VGA_GFX_COMPARE_VALUE, 0x00);
|
||||
vga_wgfx(regbase, VGA_GFX_DATA_ROTATE, 0x00);
|
||||
vga_wgfx(regbase, VGA_GFX_PLANE_READ, 0x00);
|
||||
vga_wgfx(regbase, VGA_GFX_MODE, 0x00);
|
||||
/* vga_wgfx(regbase, VGA_GFX_MODE, 0x20); */
|
||||
/* vga_wgfx(regbase, VGA_GFX_MODE, 0x40); */
|
||||
vga_wgfx(regbase, VGA_GFX_MISC, 0x05);
|
||||
/* vga_wgfx(regbase, VGA_GFX_MISC, 0x01); */
|
||||
vga_wgfx(regbase, VGA_GFX_COMPARE_MASK, 0x0F);
|
||||
vga_wgfx(regbase, VGA_GFX_BIT_MASK, 0xFF);
|
||||
}
|
||||
|
||||
/* Set attribute controller registers to sane values */
|
||||
void svga_set_default_atc_regs(void)
|
||||
void svga_set_default_atc_regs(void __iomem *regbase)
|
||||
{
|
||||
u8 count;
|
||||
|
||||
vga_r(NULL, 0x3DA);
|
||||
vga_w(NULL, VGA_ATT_W, 0x00);
|
||||
vga_r(regbase, 0x3DA);
|
||||
vga_w(regbase, VGA_ATT_W, 0x00);
|
||||
|
||||
/* All standard ATC registers (AR00 - AR14) */
|
||||
for (count = 0; count <= 0xF; count ++)
|
||||
svga_wattr(count, count);
|
||||
svga_wattr(regbase, count, count);
|
||||
|
||||
svga_wattr(VGA_ATC_MODE, 0x01);
|
||||
/* svga_wattr(VGA_ATC_MODE, 0x41); */
|
||||
svga_wattr(VGA_ATC_OVERSCAN, 0x00);
|
||||
svga_wattr(VGA_ATC_PLANE_ENABLE, 0x0F);
|
||||
svga_wattr(VGA_ATC_PEL, 0x00);
|
||||
svga_wattr(VGA_ATC_COLOR_PAGE, 0x00);
|
||||
svga_wattr(regbase, VGA_ATC_MODE, 0x01);
|
||||
/* svga_wattr(regbase, VGA_ATC_MODE, 0x41); */
|
||||
svga_wattr(regbase, VGA_ATC_OVERSCAN, 0x00);
|
||||
svga_wattr(regbase, VGA_ATC_PLANE_ENABLE, 0x0F);
|
||||
svga_wattr(regbase, VGA_ATC_PEL, 0x00);
|
||||
svga_wattr(regbase, VGA_ATC_COLOR_PAGE, 0x00);
|
||||
|
||||
vga_r(NULL, 0x3DA);
|
||||
vga_w(NULL, VGA_ATT_W, 0x20);
|
||||
vga_r(regbase, 0x3DA);
|
||||
vga_w(regbase, VGA_ATT_W, 0x20);
|
||||
}
|
||||
|
||||
/* Set sequencer registers to sane values */
|
||||
void svga_set_default_seq_regs(void)
|
||||
void svga_set_default_seq_regs(void __iomem *regbase)
|
||||
{
|
||||
/* Standard sequencer registers (SR01 - SR04), SR00 is not set */
|
||||
vga_wseq(NULL, VGA_SEQ_CLOCK_MODE, VGA_SR01_CHAR_CLK_8DOTS);
|
||||
vga_wseq(NULL, VGA_SEQ_PLANE_WRITE, VGA_SR02_ALL_PLANES);
|
||||
vga_wseq(NULL, VGA_SEQ_CHARACTER_MAP, 0x00);
|
||||
/* vga_wseq(NULL, VGA_SEQ_MEMORY_MODE, VGA_SR04_EXT_MEM | VGA_SR04_SEQ_MODE | VGA_SR04_CHN_4M); */
|
||||
vga_wseq(NULL, VGA_SEQ_MEMORY_MODE, VGA_SR04_EXT_MEM | VGA_SR04_SEQ_MODE);
|
||||
vga_wseq(regbase, VGA_SEQ_CLOCK_MODE, VGA_SR01_CHAR_CLK_8DOTS);
|
||||
vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, VGA_SR02_ALL_PLANES);
|
||||
vga_wseq(regbase, VGA_SEQ_CHARACTER_MAP, 0x00);
|
||||
/* vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, VGA_SR04_EXT_MEM | VGA_SR04_SEQ_MODE | VGA_SR04_CHN_4M); */
|
||||
vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, VGA_SR04_EXT_MEM | VGA_SR04_SEQ_MODE);
|
||||
}
|
||||
|
||||
/* Set CRTC registers to sane values */
|
||||
void svga_set_default_crt_regs(void)
|
||||
void svga_set_default_crt_regs(void __iomem *regbase)
|
||||
{
|
||||
/* Standard CRT registers CR03 CR08 CR09 CR14 CR17 */
|
||||
svga_wcrt_mask(0x03, 0x80, 0x80); /* Enable vertical retrace EVRA */
|
||||
vga_wcrt(NULL, VGA_CRTC_PRESET_ROW, 0);
|
||||
svga_wcrt_mask(VGA_CRTC_MAX_SCAN, 0, 0x1F);
|
||||
vga_wcrt(NULL, VGA_CRTC_UNDERLINE, 0);
|
||||
vga_wcrt(NULL, VGA_CRTC_MODE, 0xE3);
|
||||
svga_wcrt_mask(regbase, 0x03, 0x80, 0x80); /* Enable vertical retrace EVRA */
|
||||
vga_wcrt(regbase, VGA_CRTC_PRESET_ROW, 0);
|
||||
svga_wcrt_mask(regbase, VGA_CRTC_MAX_SCAN, 0, 0x1F);
|
||||
vga_wcrt(regbase, VGA_CRTC_UNDERLINE, 0);
|
||||
vga_wcrt(regbase, VGA_CRTC_MODE, 0xE3);
|
||||
}
|
||||
|
||||
void svga_set_textmode_vga_regs(void)
|
||||
void svga_set_textmode_vga_regs(void __iomem *regbase)
|
||||
{
|
||||
/* svga_wseq_mask(0x1, 0x00, 0x01); */ /* Switch 8/9 pixel per char */
|
||||
vga_wseq(NULL, VGA_SEQ_MEMORY_MODE, VGA_SR04_EXT_MEM);
|
||||
vga_wseq(NULL, VGA_SEQ_PLANE_WRITE, 0x03);
|
||||
/* svga_wseq_mask(regbase, 0x1, 0x00, 0x01); */ /* Switch 8/9 pixel per char */
|
||||
vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, VGA_SR04_EXT_MEM);
|
||||
vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0x03);
|
||||
|
||||
vga_wcrt(NULL, VGA_CRTC_MAX_SCAN, 0x0f); /* 0x4f */
|
||||
vga_wcrt(NULL, VGA_CRTC_UNDERLINE, 0x1f);
|
||||
svga_wcrt_mask(VGA_CRTC_MODE, 0x23, 0x7f);
|
||||
vga_wcrt(regbase, VGA_CRTC_MAX_SCAN, 0x0f); /* 0x4f */
|
||||
vga_wcrt(regbase, VGA_CRTC_UNDERLINE, 0x1f);
|
||||
svga_wcrt_mask(regbase, VGA_CRTC_MODE, 0x23, 0x7f);
|
||||
|
||||
vga_wcrt(NULL, VGA_CRTC_CURSOR_START, 0x0d);
|
||||
vga_wcrt(NULL, VGA_CRTC_CURSOR_END, 0x0e);
|
||||
vga_wcrt(NULL, VGA_CRTC_CURSOR_HI, 0x00);
|
||||
vga_wcrt(NULL, VGA_CRTC_CURSOR_LO, 0x00);
|
||||
vga_wcrt(regbase, VGA_CRTC_CURSOR_START, 0x0d);
|
||||
vga_wcrt(regbase, VGA_CRTC_CURSOR_END, 0x0e);
|
||||
vga_wcrt(regbase, VGA_CRTC_CURSOR_HI, 0x00);
|
||||
vga_wcrt(regbase, VGA_CRTC_CURSOR_LO, 0x00);
|
||||
|
||||
vga_wgfx(NULL, VGA_GFX_MODE, 0x10); /* Odd/even memory mode */
|
||||
vga_wgfx(NULL, VGA_GFX_MISC, 0x0E); /* Misc graphics register - text mode enable */
|
||||
vga_wgfx(NULL, VGA_GFX_COMPARE_MASK, 0x00);
|
||||
vga_wgfx(regbase, VGA_GFX_MODE, 0x10); /* Odd/even memory mode */
|
||||
vga_wgfx(regbase, VGA_GFX_MISC, 0x0E); /* Misc graphics register - text mode enable */
|
||||
vga_wgfx(regbase, VGA_GFX_COMPARE_MASK, 0x00);
|
||||
|
||||
vga_r(NULL, 0x3DA);
|
||||
vga_w(NULL, VGA_ATT_W, 0x00);
|
||||
vga_r(regbase, 0x3DA);
|
||||
vga_w(regbase, VGA_ATT_W, 0x00);
|
||||
|
||||
svga_wattr(0x10, 0x0C); /* Attribute Mode Control Register - text mode, blinking and line graphics */
|
||||
svga_wattr(0x13, 0x08); /* Horizontal Pixel Panning Register */
|
||||
svga_wattr(regbase, 0x10, 0x0C); /* Attribute Mode Control Register - text mode, blinking and line graphics */
|
||||
svga_wattr(regbase, 0x13, 0x08); /* Horizontal Pixel Panning Register */
|
||||
|
||||
vga_r(NULL, 0x3DA);
|
||||
vga_w(NULL, VGA_ATT_W, 0x20);
|
||||
vga_r(regbase, 0x3DA);
|
||||
vga_w(regbase, VGA_ATT_W, 0x20);
|
||||
}
|
||||
|
||||
#if 0
|
||||
@ -299,7 +299,7 @@ void svga_tileblit(struct fb_info *info, struct fb_tileblit *blit)
|
||||
}
|
||||
|
||||
/* Set cursor in text (tileblit) mode */
|
||||
void svga_tilecursor(struct fb_info *info, struct fb_tilecursor *cursor)
|
||||
void svga_tilecursor(void __iomem *regbase, struct fb_info *info, struct fb_tilecursor *cursor)
|
||||
{
|
||||
u8 cs = 0x0d;
|
||||
u8 ce = 0x0e;
|
||||
@ -310,7 +310,7 @@ void svga_tilecursor(struct fb_info *info, struct fb_tilecursor *cursor)
|
||||
if (! cursor -> mode)
|
||||
return;
|
||||
|
||||
svga_wcrt_mask(0x0A, 0x20, 0x20); /* disable cursor */
|
||||
svga_wcrt_mask(regbase, 0x0A, 0x20, 0x20); /* disable cursor */
|
||||
|
||||
if (cursor -> shape == FB_TILE_CURSOR_NONE)
|
||||
return;
|
||||
@ -334,11 +334,11 @@ void svga_tilecursor(struct fb_info *info, struct fb_tilecursor *cursor)
|
||||
}
|
||||
|
||||
/* set cursor position */
|
||||
vga_wcrt(NULL, 0x0E, pos >> 8);
|
||||
vga_wcrt(NULL, 0x0F, pos & 0xFF);
|
||||
vga_wcrt(regbase, 0x0E, pos >> 8);
|
||||
vga_wcrt(regbase, 0x0F, pos & 0xFF);
|
||||
|
||||
vga_wcrt(NULL, 0x0B, ce); /* set cursor end */
|
||||
vga_wcrt(NULL, 0x0A, cs); /* set cursor start and enable it */
|
||||
vga_wcrt(regbase, 0x0B, ce); /* set cursor end */
|
||||
vga_wcrt(regbase, 0x0A, cs); /* set cursor start and enable it */
|
||||
}
|
||||
|
||||
int svga_get_tilemax(struct fb_info *info)
|
||||
@ -507,8 +507,9 @@ int svga_check_timings(const struct svga_timing_regs *tm, struct fb_var_screenin
|
||||
}
|
||||
|
||||
/* Set CRT timing registers */
|
||||
void svga_set_timings(const struct svga_timing_regs *tm, struct fb_var_screeninfo *var,
|
||||
u32 hmul, u32 hdiv, u32 vmul, u32 vdiv, u32 hborder, int node)
|
||||
void svga_set_timings(void __iomem *regbase, const struct svga_timing_regs *tm,
|
||||
struct fb_var_screeninfo *var,
|
||||
u32 hmul, u32 hdiv, u32 vmul, u32 vdiv, u32 hborder, int node)
|
||||
{
|
||||
u8 regval;
|
||||
u32 value;
|
||||
@ -516,66 +517,66 @@ void svga_set_timings(const struct svga_timing_regs *tm, struct fb_var_screeninf
|
||||
value = var->xres + var->left_margin + var->right_margin + var->hsync_len;
|
||||
value = (value * hmul) / hdiv;
|
||||
pr_debug("fb%d: horizontal total : %d\n", node, value);
|
||||
svga_wcrt_multi(tm->h_total_regs, (value / 8) - 5);
|
||||
svga_wcrt_multi(regbase, tm->h_total_regs, (value / 8) - 5);
|
||||
|
||||
value = var->xres;
|
||||
value = (value * hmul) / hdiv;
|
||||
pr_debug("fb%d: horizontal display : %d\n", node, value);
|
||||
svga_wcrt_multi(tm->h_display_regs, (value / 8) - 1);
|
||||
svga_wcrt_multi(regbase, tm->h_display_regs, (value / 8) - 1);
|
||||
|
||||
value = var->xres;
|
||||
value = (value * hmul) / hdiv;
|
||||
pr_debug("fb%d: horizontal blank start: %d\n", node, value);
|
||||
svga_wcrt_multi(tm->h_blank_start_regs, (value / 8) - 1 + hborder);
|
||||
svga_wcrt_multi(regbase, tm->h_blank_start_regs, (value / 8) - 1 + hborder);
|
||||
|
||||
value = var->xres + var->left_margin + var->right_margin + var->hsync_len;
|
||||
value = (value * hmul) / hdiv;
|
||||
pr_debug("fb%d: horizontal blank end : %d\n", node, value);
|
||||
svga_wcrt_multi(tm->h_blank_end_regs, (value / 8) - 1 - hborder);
|
||||
svga_wcrt_multi(regbase, tm->h_blank_end_regs, (value / 8) - 1 - hborder);
|
||||
|
||||
value = var->xres + var->right_margin;
|
||||
value = (value * hmul) / hdiv;
|
||||
pr_debug("fb%d: horizontal sync start : %d\n", node, value);
|
||||
svga_wcrt_multi(tm->h_sync_start_regs, (value / 8));
|
||||
svga_wcrt_multi(regbase, tm->h_sync_start_regs, (value / 8));
|
||||
|
||||
value = var->xres + var->right_margin + var->hsync_len;
|
||||
value = (value * hmul) / hdiv;
|
||||
pr_debug("fb%d: horizontal sync end : %d\n", node, value);
|
||||
svga_wcrt_multi(tm->h_sync_end_regs, (value / 8));
|
||||
svga_wcrt_multi(regbase, tm->h_sync_end_regs, (value / 8));
|
||||
|
||||
value = var->yres + var->upper_margin + var->lower_margin + var->vsync_len;
|
||||
value = (value * vmul) / vdiv;
|
||||
pr_debug("fb%d: vertical total : %d\n", node, value);
|
||||
svga_wcrt_multi(tm->v_total_regs, value - 2);
|
||||
svga_wcrt_multi(regbase, tm->v_total_regs, value - 2);
|
||||
|
||||
value = var->yres;
|
||||
value = (value * vmul) / vdiv;
|
||||
pr_debug("fb%d: vertical display : %d\n", node, value);
|
||||
svga_wcrt_multi(tm->v_display_regs, value - 1);
|
||||
svga_wcrt_multi(regbase, tm->v_display_regs, value - 1);
|
||||
|
||||
value = var->yres;
|
||||
value = (value * vmul) / vdiv;
|
||||
pr_debug("fb%d: vertical blank start : %d\n", node, value);
|
||||
svga_wcrt_multi(tm->v_blank_start_regs, value);
|
||||
svga_wcrt_multi(regbase, tm->v_blank_start_regs, value);
|
||||
|
||||
value = var->yres + var->upper_margin + var->lower_margin + var->vsync_len;
|
||||
value = (value * vmul) / vdiv;
|
||||
pr_debug("fb%d: vertical blank end : %d\n", node, value);
|
||||
svga_wcrt_multi(tm->v_blank_end_regs, value - 2);
|
||||
svga_wcrt_multi(regbase, tm->v_blank_end_regs, value - 2);
|
||||
|
||||
value = var->yres + var->lower_margin;
|
||||
value = (value * vmul) / vdiv;
|
||||
pr_debug("fb%d: vertical sync start : %d\n", node, value);
|
||||
svga_wcrt_multi(tm->v_sync_start_regs, value);
|
||||
svga_wcrt_multi(regbase, tm->v_sync_start_regs, value);
|
||||
|
||||
value = var->yres + var->lower_margin + var->vsync_len;
|
||||
value = (value * vmul) / vdiv;
|
||||
pr_debug("fb%d: vertical sync end : %d\n", node, value);
|
||||
svga_wcrt_multi(tm->v_sync_end_regs, value);
|
||||
svga_wcrt_multi(regbase, tm->v_sync_end_regs, value);
|
||||
|
||||
/* Set horizontal and vertical sync pulse polarity in misc register */
|
||||
|
||||
regval = vga_r(NULL, VGA_MIS_R);
|
||||
regval = vga_r(regbase, VGA_MIS_R);
|
||||
if (var->sync & FB_SYNC_HOR_HIGH_ACT) {
|
||||
pr_debug("fb%d: positive horizontal sync\n", node);
|
||||
regval = regval & ~0x80;
|
||||
@ -590,7 +591,7 @@ void svga_set_timings(const struct svga_timing_regs *tm, struct fb_var_screeninf
|
||||
pr_debug("fb%d: negative vertical sync\n\n", node);
|
||||
regval = regval | 0x40;
|
||||
}
|
||||
vga_w(NULL, VGA_MIS_W, regval);
|
||||
vga_w(regbase, VGA_MIS_W, regval);
|
||||
}
|
||||
|
||||
|
||||
|
@ -480,6 +480,7 @@ out_dealloc_cmap:
|
||||
|
||||
out_unmap_regs:
|
||||
tcx_unmap_regs(op, info, par);
|
||||
framebuffer_release(info);
|
||||
|
||||
out_err:
|
||||
return err;
|
||||
|
@ -1552,8 +1552,7 @@ static void __devinit uvesafb_init_mtrr(struct fb_info *info)
|
||||
int rc;
|
||||
|
||||
/* Find the largest power-of-two */
|
||||
while (temp_size & (temp_size - 1))
|
||||
temp_size &= (temp_size - 1);
|
||||
temp_size = roundup_pow_of_two(temp_size);
|
||||
|
||||
/* Try and find a power of two to add */
|
||||
do {
|
||||
@ -1566,6 +1565,28 @@ static void __devinit uvesafb_init_mtrr(struct fb_info *info)
|
||||
#endif /* CONFIG_MTRR */
|
||||
}
|
||||
|
||||
static void __devinit uvesafb_ioremap(struct fb_info *info)
|
||||
{
|
||||
#ifdef CONFIG_X86
|
||||
switch (mtrr) {
|
||||
case 1: /* uncachable */
|
||||
info->screen_base = ioremap_nocache(info->fix.smem_start, info->fix.smem_len);
|
||||
break;
|
||||
case 2: /* write-back */
|
||||
info->screen_base = ioremap_cache(info->fix.smem_start, info->fix.smem_len);
|
||||
break;
|
||||
case 3: /* write-combining */
|
||||
info->screen_base = ioremap_wc(info->fix.smem_start, info->fix.smem_len);
|
||||
break;
|
||||
case 4: /* write-through */
|
||||
default:
|
||||
info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
|
||||
break;
|
||||
}
|
||||
#else
|
||||
info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
|
||||
#endif /* CONFIG_X86 */
|
||||
}
|
||||
|
||||
static ssize_t uvesafb_show_vbe_ver(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
@ -1736,15 +1757,22 @@ static int __devinit uvesafb_probe(struct platform_device *dev)
|
||||
|
||||
uvesafb_init_info(info, mode);
|
||||
|
||||
if (!request_region(0x3c0, 32, "uvesafb")) {
|
||||
printk(KERN_ERR "uvesafb: request region 0x3c0-0x3e0 failed\n");
|
||||
err = -EIO;
|
||||
goto out_mode;
|
||||
}
|
||||
|
||||
if (!request_mem_region(info->fix.smem_start, info->fix.smem_len,
|
||||
"uvesafb")) {
|
||||
printk(KERN_ERR "uvesafb: cannot reserve video memory at "
|
||||
"0x%lx\n", info->fix.smem_start);
|
||||
err = -EIO;
|
||||
goto out_mode;
|
||||
goto out_reg;
|
||||
}
|
||||
|
||||
info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
|
||||
uvesafb_init_mtrr(info);
|
||||
uvesafb_ioremap(info);
|
||||
|
||||
if (!info->screen_base) {
|
||||
printk(KERN_ERR
|
||||
@ -1755,20 +1783,13 @@ static int __devinit uvesafb_probe(struct platform_device *dev)
|
||||
goto out_mem;
|
||||
}
|
||||
|
||||
if (!request_region(0x3c0, 32, "uvesafb")) {
|
||||
printk(KERN_ERR "uvesafb: request region 0x3c0-0x3e0 failed\n");
|
||||
err = -EIO;
|
||||
goto out_unmap;
|
||||
}
|
||||
|
||||
uvesafb_init_mtrr(info);
|
||||
platform_set_drvdata(dev, info);
|
||||
|
||||
if (register_framebuffer(info) < 0) {
|
||||
printk(KERN_ERR
|
||||
"uvesafb: failed to register framebuffer device\n");
|
||||
err = -EINVAL;
|
||||
goto out_reg;
|
||||
goto out_unmap;
|
||||
}
|
||||
|
||||
printk(KERN_INFO "uvesafb: framebuffer at 0x%lx, mapped to 0x%p, "
|
||||
@ -1785,12 +1806,12 @@ static int __devinit uvesafb_probe(struct platform_device *dev)
|
||||
|
||||
return 0;
|
||||
|
||||
out_reg:
|
||||
release_region(0x3c0, 32);
|
||||
out_unmap:
|
||||
iounmap(info->screen_base);
|
||||
out_mem:
|
||||
release_mem_region(info->fix.smem_start, info->fix.smem_len);
|
||||
out_reg:
|
||||
release_region(0x3c0, 32);
|
||||
out_mode:
|
||||
if (!list_empty(&info->modelist))
|
||||
fb_destroy_modelist(&info->modelist);
|
||||
|
@ -891,8 +891,7 @@ static int vmlfb_set_par(struct fb_info *info)
|
||||
int ret;
|
||||
|
||||
mutex_lock(&vml_mutex);
|
||||
list_del(&vinfo->head);
|
||||
list_add(&vinfo->head, (subsys) ? &global_has_mode : &global_no_mode);
|
||||
list_move(&vinfo->head, (subsys) ? &global_has_mode : &global_no_mode);
|
||||
ret = vmlfb_set_par_locked(vinfo);
|
||||
|
||||
mutex_unlock(&vml_mutex);
|
||||
|
@ -303,19 +303,6 @@ static int __init vesafb_probe(struct platform_device *dev)
|
||||
info->apertures->ranges[0].base = screen_info.lfb_base;
|
||||
info->apertures->ranges[0].size = size_total;
|
||||
|
||||
info->screen_base = ioremap(vesafb_fix.smem_start, vesafb_fix.smem_len);
|
||||
if (!info->screen_base) {
|
||||
printk(KERN_ERR
|
||||
"vesafb: abort, cannot ioremap video memory 0x%x @ 0x%lx\n",
|
||||
vesafb_fix.smem_len, vesafb_fix.smem_start);
|
||||
err = -EIO;
|
||||
goto err;
|
||||
}
|
||||
|
||||
printk(KERN_INFO "vesafb: framebuffer at 0x%lx, mapped to 0x%p, "
|
||||
"using %dk, total %dk\n",
|
||||
vesafb_fix.smem_start, info->screen_base,
|
||||
size_remap/1024, size_total/1024);
|
||||
printk(KERN_INFO "vesafb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
|
||||
vesafb_defined.xres, vesafb_defined.yres, vesafb_defined.bits_per_pixel, vesafb_fix.line_length, screen_info.pages);
|
||||
|
||||
@ -438,8 +425,7 @@ static int __init vesafb_probe(struct platform_device *dev)
|
||||
int rc;
|
||||
|
||||
/* Find the largest power-of-two */
|
||||
while (temp_size & (temp_size - 1))
|
||||
temp_size &= (temp_size - 1);
|
||||
temp_size = roundup_pow_of_two(temp_size);
|
||||
|
||||
/* Try and find a power of two to add */
|
||||
do {
|
||||
@ -451,6 +437,34 @@ static int __init vesafb_probe(struct platform_device *dev)
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (mtrr) {
|
||||
case 1: /* uncachable */
|
||||
info->screen_base = ioremap_nocache(vesafb_fix.smem_start, vesafb_fix.smem_len);
|
||||
break;
|
||||
case 2: /* write-back */
|
||||
info->screen_base = ioremap_cache(vesafb_fix.smem_start, vesafb_fix.smem_len);
|
||||
break;
|
||||
case 3: /* write-combining */
|
||||
info->screen_base = ioremap_wc(vesafb_fix.smem_start, vesafb_fix.smem_len);
|
||||
break;
|
||||
case 4: /* write-through */
|
||||
default:
|
||||
info->screen_base = ioremap(vesafb_fix.smem_start, vesafb_fix.smem_len);
|
||||
break;
|
||||
}
|
||||
if (!info->screen_base) {
|
||||
printk(KERN_ERR
|
||||
"vesafb: abort, cannot ioremap video memory 0x%x @ 0x%lx\n",
|
||||
vesafb_fix.smem_len, vesafb_fix.smem_start);
|
||||
err = -EIO;
|
||||
goto err;
|
||||
}
|
||||
|
||||
printk(KERN_INFO "vesafb: framebuffer at 0x%lx, mapped to 0x%p, "
|
||||
"using %dk, total %dk\n",
|
||||
vesafb_fix.smem_start, info->screen_base,
|
||||
size_remap/1024, size_total/1024);
|
||||
|
||||
info->fbops = &vesafb_ops;
|
||||
info->var = vesafb_defined;
|
||||
info->fix = vesafb_fix;
|
||||
|
@ -121,13 +121,19 @@ MODULE_PARM_DESC(mtrr, "Enable write-combining with MTRR (1=enable, 0=disable, d
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static void vt8623fb_tilecursor(struct fb_info *info, struct fb_tilecursor *cursor)
|
||||
{
|
||||
struct vt8623fb_info *par = info->par;
|
||||
|
||||
svga_tilecursor(par->state.vgabase, info, cursor);
|
||||
}
|
||||
|
||||
static struct fb_tile_ops vt8623fb_tile_ops = {
|
||||
.fb_settile = svga_settile,
|
||||
.fb_tilecopy = svga_tilecopy,
|
||||
.fb_tilefill = svga_tilefill,
|
||||
.fb_tileblit = svga_tileblit,
|
||||
.fb_tilecursor = svga_tilecursor,
|
||||
.fb_tilecursor = vt8623fb_tilecursor,
|
||||
.fb_get_tilemax = svga_get_tilemax,
|
||||
};
|
||||
|
||||
@ -253,6 +259,7 @@ static void vt8623fb_fillrect(struct fb_info *info, const struct fb_fillrect *re
|
||||
|
||||
static void vt8623_set_pixclock(struct fb_info *info, u32 pixclock)
|
||||
{
|
||||
struct vt8623fb_info *par = info->par;
|
||||
u16 m, n, r;
|
||||
u8 regval;
|
||||
int rv;
|
||||
@ -264,18 +271,18 @@ static void vt8623_set_pixclock(struct fb_info *info, u32 pixclock)
|
||||
}
|
||||
|
||||
/* Set VGA misc register */
|
||||
regval = vga_r(NULL, VGA_MIS_R);
|
||||
vga_w(NULL, VGA_MIS_W, regval | VGA_MIS_ENB_PLL_LOAD);
|
||||
regval = vga_r(par->state.vgabase, VGA_MIS_R);
|
||||
vga_w(par->state.vgabase, VGA_MIS_W, regval | VGA_MIS_ENB_PLL_LOAD);
|
||||
|
||||
/* Set clock registers */
|
||||
vga_wseq(NULL, 0x46, (n | (r << 6)));
|
||||
vga_wseq(NULL, 0x47, m);
|
||||
vga_wseq(par->state.vgabase, 0x46, (n | (r << 6)));
|
||||
vga_wseq(par->state.vgabase, 0x47, m);
|
||||
|
||||
udelay(1000);
|
||||
|
||||
/* PLL reset */
|
||||
svga_wseq_mask(0x40, 0x02, 0x02);
|
||||
svga_wseq_mask(0x40, 0x00, 0x02);
|
||||
svga_wseq_mask(par->state.vgabase, 0x40, 0x02, 0x02);
|
||||
svga_wseq_mask(par->state.vgabase, 0x40, 0x00, 0x02);
|
||||
}
|
||||
|
||||
|
||||
@ -285,7 +292,10 @@ static int vt8623fb_open(struct fb_info *info, int user)
|
||||
|
||||
mutex_lock(&(par->open_lock));
|
||||
if (par->ref_count == 0) {
|
||||
void __iomem *vgabase = par->state.vgabase;
|
||||
|
||||
memset(&(par->state), 0, sizeof(struct vgastate));
|
||||
par->state.vgabase = vgabase;
|
||||
par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS | VGA_SAVE_CMAP;
|
||||
par->state.num_crtc = 0xA2;
|
||||
par->state.num_seq = 0x50;
|
||||
@ -373,6 +383,7 @@ static int vt8623fb_check_var(struct fb_var_screeninfo *var, struct fb_info *inf
|
||||
static int vt8623fb_set_par(struct fb_info *info)
|
||||
{
|
||||
u32 mode, offset_value, fetch_value, screen_size;
|
||||
struct vt8623fb_info *par = info->par;
|
||||
u32 bpp = info->var.bits_per_pixel;
|
||||
|
||||
if (bpp != 0) {
|
||||
@ -414,82 +425,82 @@ static int vt8623fb_set_par(struct fb_info *info)
|
||||
info->var.activate = FB_ACTIVATE_NOW;
|
||||
|
||||
/* Unlock registers */
|
||||
svga_wseq_mask(0x10, 0x01, 0x01);
|
||||
svga_wcrt_mask(0x11, 0x00, 0x80);
|
||||
svga_wcrt_mask(0x47, 0x00, 0x01);
|
||||
svga_wseq_mask(par->state.vgabase, 0x10, 0x01, 0x01);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x11, 0x00, 0x80);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x47, 0x00, 0x01);
|
||||
|
||||
/* Device, screen and sync off */
|
||||
svga_wseq_mask(0x01, 0x20, 0x20);
|
||||
svga_wcrt_mask(0x36, 0x30, 0x30);
|
||||
svga_wcrt_mask(0x17, 0x00, 0x80);
|
||||
svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x36, 0x30, 0x30);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x17, 0x00, 0x80);
|
||||
|
||||
/* Set default values */
|
||||
svga_set_default_gfx_regs();
|
||||
svga_set_default_atc_regs();
|
||||
svga_set_default_seq_regs();
|
||||
svga_set_default_crt_regs();
|
||||
svga_wcrt_multi(vt8623_line_compare_regs, 0xFFFFFFFF);
|
||||
svga_wcrt_multi(vt8623_start_address_regs, 0);
|
||||
svga_set_default_gfx_regs(par->state.vgabase);
|
||||
svga_set_default_atc_regs(par->state.vgabase);
|
||||
svga_set_default_seq_regs(par->state.vgabase);
|
||||
svga_set_default_crt_regs(par->state.vgabase);
|
||||
svga_wcrt_multi(par->state.vgabase, vt8623_line_compare_regs, 0xFFFFFFFF);
|
||||
svga_wcrt_multi(par->state.vgabase, vt8623_start_address_regs, 0);
|
||||
|
||||
svga_wcrt_multi(vt8623_offset_regs, offset_value);
|
||||
svga_wseq_multi(vt8623_fetch_count_regs, fetch_value);
|
||||
svga_wcrt_multi(par->state.vgabase, vt8623_offset_regs, offset_value);
|
||||
svga_wseq_multi(par->state.vgabase, vt8623_fetch_count_regs, fetch_value);
|
||||
|
||||
/* Clear H/V Skew */
|
||||
svga_wcrt_mask(0x03, 0x00, 0x60);
|
||||
svga_wcrt_mask(0x05, 0x00, 0x60);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x03, 0x00, 0x60);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x05, 0x00, 0x60);
|
||||
|
||||
if (info->var.vmode & FB_VMODE_DOUBLE)
|
||||
svga_wcrt_mask(0x09, 0x80, 0x80);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x09, 0x80, 0x80);
|
||||
else
|
||||
svga_wcrt_mask(0x09, 0x00, 0x80);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x09, 0x00, 0x80);
|
||||
|
||||
svga_wseq_mask(0x1E, 0xF0, 0xF0); // DI/DVP bus
|
||||
svga_wseq_mask(0x2A, 0x0F, 0x0F); // DI/DVP bus
|
||||
svga_wseq_mask(0x16, 0x08, 0xBF); // FIFO read threshold
|
||||
vga_wseq(NULL, 0x17, 0x1F); // FIFO depth
|
||||
vga_wseq(NULL, 0x18, 0x4E);
|
||||
svga_wseq_mask(0x1A, 0x08, 0x08); // enable MMIO ?
|
||||
svga_wseq_mask(par->state.vgabase, 0x1E, 0xF0, 0xF0); // DI/DVP bus
|
||||
svga_wseq_mask(par->state.vgabase, 0x2A, 0x0F, 0x0F); // DI/DVP bus
|
||||
svga_wseq_mask(par->state.vgabase, 0x16, 0x08, 0xBF); // FIFO read threshold
|
||||
vga_wseq(par->state.vgabase, 0x17, 0x1F); // FIFO depth
|
||||
vga_wseq(par->state.vgabase, 0x18, 0x4E);
|
||||
svga_wseq_mask(par->state.vgabase, 0x1A, 0x08, 0x08); // enable MMIO ?
|
||||
|
||||
vga_wcrt(NULL, 0x32, 0x00);
|
||||
vga_wcrt(NULL, 0x34, 0x00);
|
||||
vga_wcrt(NULL, 0x6A, 0x80);
|
||||
vga_wcrt(NULL, 0x6A, 0xC0);
|
||||
vga_wcrt(par->state.vgabase, 0x32, 0x00);
|
||||
vga_wcrt(par->state.vgabase, 0x34, 0x00);
|
||||
vga_wcrt(par->state.vgabase, 0x6A, 0x80);
|
||||
vga_wcrt(par->state.vgabase, 0x6A, 0xC0);
|
||||
|
||||
vga_wgfx(NULL, 0x20, 0x00);
|
||||
vga_wgfx(NULL, 0x21, 0x00);
|
||||
vga_wgfx(NULL, 0x22, 0x00);
|
||||
vga_wgfx(par->state.vgabase, 0x20, 0x00);
|
||||
vga_wgfx(par->state.vgabase, 0x21, 0x00);
|
||||
vga_wgfx(par->state.vgabase, 0x22, 0x00);
|
||||
|
||||
/* Set SR15 according to number of bits per pixel */
|
||||
mode = svga_match_format(vt8623fb_formats, &(info->var), &(info->fix));
|
||||
switch (mode) {
|
||||
case 0:
|
||||
pr_debug("fb%d: text mode\n", info->node);
|
||||
svga_set_textmode_vga_regs();
|
||||
svga_wseq_mask(0x15, 0x00, 0xFE);
|
||||
svga_wcrt_mask(0x11, 0x60, 0x70);
|
||||
svga_set_textmode_vga_regs(par->state.vgabase);
|
||||
svga_wseq_mask(par->state.vgabase, 0x15, 0x00, 0xFE);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x11, 0x60, 0x70);
|
||||
break;
|
||||
case 1:
|
||||
pr_debug("fb%d: 4 bit pseudocolor\n", info->node);
|
||||
vga_wgfx(NULL, VGA_GFX_MODE, 0x40);
|
||||
svga_wseq_mask(0x15, 0x20, 0xFE);
|
||||
svga_wcrt_mask(0x11, 0x00, 0x70);
|
||||
vga_wgfx(par->state.vgabase, VGA_GFX_MODE, 0x40);
|
||||
svga_wseq_mask(par->state.vgabase, 0x15, 0x20, 0xFE);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x11, 0x00, 0x70);
|
||||
break;
|
||||
case 2:
|
||||
pr_debug("fb%d: 4 bit pseudocolor, planar\n", info->node);
|
||||
svga_wseq_mask(0x15, 0x00, 0xFE);
|
||||
svga_wcrt_mask(0x11, 0x00, 0x70);
|
||||
svga_wseq_mask(par->state.vgabase, 0x15, 0x00, 0xFE);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x11, 0x00, 0x70);
|
||||
break;
|
||||
case 3:
|
||||
pr_debug("fb%d: 8 bit pseudocolor\n", info->node);
|
||||
svga_wseq_mask(0x15, 0x22, 0xFE);
|
||||
svga_wseq_mask(par->state.vgabase, 0x15, 0x22, 0xFE);
|
||||
break;
|
||||
case 4:
|
||||
pr_debug("fb%d: 5/6/5 truecolor\n", info->node);
|
||||
svga_wseq_mask(0x15, 0xB6, 0xFE);
|
||||
svga_wseq_mask(par->state.vgabase, 0x15, 0xB6, 0xFE);
|
||||
break;
|
||||
case 5:
|
||||
pr_debug("fb%d: 8/8/8 truecolor\n", info->node);
|
||||
svga_wseq_mask(0x15, 0xAE, 0xFE);
|
||||
svga_wseq_mask(par->state.vgabase, 0x15, 0xAE, 0xFE);
|
||||
break;
|
||||
default:
|
||||
printk(KERN_ERR "vt8623fb: unsupported mode - bug\n");
|
||||
@ -497,16 +508,16 @@ static int vt8623fb_set_par(struct fb_info *info)
|
||||
}
|
||||
|
||||
vt8623_set_pixclock(info, info->var.pixclock);
|
||||
svga_set_timings(&vt8623_timing_regs, &(info->var), 1, 1,
|
||||
svga_set_timings(par->state.vgabase, &vt8623_timing_regs, &(info->var), 1, 1,
|
||||
(info->var.vmode & FB_VMODE_DOUBLE) ? 2 : 1, 1,
|
||||
1, info->node);
|
||||
|
||||
memset_io(info->screen_base, 0x00, screen_size);
|
||||
|
||||
/* Device and screen back on */
|
||||
svga_wcrt_mask(0x17, 0x80, 0x80);
|
||||
svga_wcrt_mask(0x36, 0x00, 0x30);
|
||||
svga_wseq_mask(0x01, 0x00, 0x20);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x17, 0x80, 0x80);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x36, 0x00, 0x30);
|
||||
svga_wseq_mask(par->state.vgabase, 0x01, 0x00, 0x20);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -569,31 +580,33 @@ static int vt8623fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
|
||||
|
||||
static int vt8623fb_blank(int blank_mode, struct fb_info *info)
|
||||
{
|
||||
struct vt8623fb_info *par = info->par;
|
||||
|
||||
switch (blank_mode) {
|
||||
case FB_BLANK_UNBLANK:
|
||||
pr_debug("fb%d: unblank\n", info->node);
|
||||
svga_wcrt_mask(0x36, 0x00, 0x30);
|
||||
svga_wseq_mask(0x01, 0x00, 0x20);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x36, 0x00, 0x30);
|
||||
svga_wseq_mask(par->state.vgabase, 0x01, 0x00, 0x20);
|
||||
break;
|
||||
case FB_BLANK_NORMAL:
|
||||
pr_debug("fb%d: blank\n", info->node);
|
||||
svga_wcrt_mask(0x36, 0x00, 0x30);
|
||||
svga_wseq_mask(0x01, 0x20, 0x20);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x36, 0x00, 0x30);
|
||||
svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
|
||||
break;
|
||||
case FB_BLANK_HSYNC_SUSPEND:
|
||||
pr_debug("fb%d: DPMS standby (hsync off)\n", info->node);
|
||||
svga_wcrt_mask(0x36, 0x10, 0x30);
|
||||
svga_wseq_mask(0x01, 0x20, 0x20);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x36, 0x10, 0x30);
|
||||
svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
|
||||
break;
|
||||
case FB_BLANK_VSYNC_SUSPEND:
|
||||
pr_debug("fb%d: DPMS suspend (vsync off)\n", info->node);
|
||||
svga_wcrt_mask(0x36, 0x20, 0x30);
|
||||
svga_wseq_mask(0x01, 0x20, 0x20);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x36, 0x20, 0x30);
|
||||
svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
|
||||
break;
|
||||
case FB_BLANK_POWERDOWN:
|
||||
pr_debug("fb%d: DPMS off (no sync)\n", info->node);
|
||||
svga_wcrt_mask(0x36, 0x30, 0x30);
|
||||
svga_wseq_mask(0x01, 0x20, 0x20);
|
||||
svga_wcrt_mask(par->state.vgabase, 0x36, 0x30, 0x30);
|
||||
svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -603,6 +616,7 @@ static int vt8623fb_blank(int blank_mode, struct fb_info *info)
|
||||
|
||||
static int vt8623fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
|
||||
{
|
||||
struct vt8623fb_info *par = info->par;
|
||||
unsigned int offset;
|
||||
|
||||
/* Calculate the offset */
|
||||
@ -616,7 +630,7 @@ static int vt8623fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *i
|
||||
}
|
||||
|
||||
/* Set the offset */
|
||||
svga_wcrt_multi(vt8623_start_address_regs, offset);
|
||||
svga_wcrt_multi(par->state.vgabase, vt8623_start_address_regs, offset);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -647,6 +661,8 @@ static struct fb_ops vt8623fb_ops = {
|
||||
|
||||
static int __devinit vt8623_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
||||
{
|
||||
struct pci_bus_region bus_reg;
|
||||
struct resource vga_res;
|
||||
struct fb_info *info;
|
||||
struct vt8623fb_info *par;
|
||||
unsigned int memsize1, memsize2;
|
||||
@ -705,9 +721,18 @@ static int __devinit vt8623_pci_probe(struct pci_dev *dev, const struct pci_devi
|
||||
goto err_iomap_2;
|
||||
}
|
||||
|
||||
bus_reg.start = 0;
|
||||
bus_reg.end = 64 * 1024;
|
||||
|
||||
vga_res.flags = IORESOURCE_IO;
|
||||
|
||||
pcibios_bus_to_resource(dev, &vga_res, &bus_reg);
|
||||
|
||||
par->state.vgabase = (void __iomem *) vga_res.start;
|
||||
|
||||
/* Find how many physical memory there is on card */
|
||||
memsize1 = (vga_rseq(NULL, 0x34) + 1) >> 1;
|
||||
memsize2 = vga_rseq(NULL, 0x39) << 2;
|
||||
memsize1 = (vga_rseq(par->state.vgabase, 0x34) + 1) >> 1;
|
||||
memsize2 = vga_rseq(par->state.vgabase, 0x39) << 2;
|
||||
|
||||
if ((16 <= memsize1) && (memsize1 <= 64) && (memsize1 == memsize2))
|
||||
info->screen_size = memsize1 << 20;
|
||||
|
@ -172,3 +172,11 @@ struct sm501_platdata {
|
||||
struct sm501_platdata_gpio_i2c *gpio_i2c;
|
||||
unsigned int gpio_i2c_nr;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_PPC32)
|
||||
#define smc501_readl(addr) ioread32be((addr))
|
||||
#define smc501_writel(val, addr) iowrite32be((val), (addr))
|
||||
#else
|
||||
#define smc501_readl(addr) readl(addr)
|
||||
#define smc501_writel(val, addr) writel(val, addr)
|
||||
#endif
|
||||
|
@ -67,25 +67,25 @@ struct svga_pll {
|
||||
|
||||
/* Write a value to the attribute register */
|
||||
|
||||
static inline void svga_wattr(u8 index, u8 data)
|
||||
static inline void svga_wattr(void __iomem *regbase, u8 index, u8 data)
|
||||
{
|
||||
inb(0x3DA);
|
||||
outb(index, 0x3C0);
|
||||
outb(data, 0x3C0);
|
||||
vga_r(regbase, VGA_IS1_RC);
|
||||
vga_w(regbase, VGA_ATT_IW, index);
|
||||
vga_w(regbase, VGA_ATT_W, data);
|
||||
}
|
||||
|
||||
/* Write a value to a sequence register with a mask */
|
||||
|
||||
static inline void svga_wseq_mask(u8 index, u8 data, u8 mask)
|
||||
static inline void svga_wseq_mask(void __iomem *regbase, u8 index, u8 data, u8 mask)
|
||||
{
|
||||
vga_wseq(NULL, index, (data & mask) | (vga_rseq(NULL, index) & ~mask));
|
||||
vga_wseq(regbase, index, (data & mask) | (vga_rseq(regbase, index) & ~mask));
|
||||
}
|
||||
|
||||
/* Write a value to a CRT register with a mask */
|
||||
|
||||
static inline void svga_wcrt_mask(u8 index, u8 data, u8 mask)
|
||||
static inline void svga_wcrt_mask(void __iomem *regbase, u8 index, u8 data, u8 mask)
|
||||
{
|
||||
vga_wcrt(NULL, index, (data & mask) | (vga_rcrt(NULL, index) & ~mask));
|
||||
vga_wcrt(regbase, index, (data & mask) | (vga_rcrt(regbase, index) & ~mask));
|
||||
}
|
||||
|
||||
static inline int svga_primary_device(struct pci_dev *dev)
|
||||
@ -96,27 +96,27 @@ static inline int svga_primary_device(struct pci_dev *dev)
|
||||
}
|
||||
|
||||
|
||||
void svga_wcrt_multi(const struct vga_regset *regset, u32 value);
|
||||
void svga_wseq_multi(const struct vga_regset *regset, u32 value);
|
||||
void svga_wcrt_multi(void __iomem *regbase, const struct vga_regset *regset, u32 value);
|
||||
void svga_wseq_multi(void __iomem *regbase, const struct vga_regset *regset, u32 value);
|
||||
|
||||
void svga_set_default_gfx_regs(void);
|
||||
void svga_set_default_atc_regs(void);
|
||||
void svga_set_default_seq_regs(void);
|
||||
void svga_set_default_crt_regs(void);
|
||||
void svga_set_textmode_vga_regs(void);
|
||||
void svga_set_default_gfx_regs(void __iomem *regbase);
|
||||
void svga_set_default_atc_regs(void __iomem *regbase);
|
||||
void svga_set_default_seq_regs(void __iomem *regbase);
|
||||
void svga_set_default_crt_regs(void __iomem *regbase);
|
||||
void svga_set_textmode_vga_regs(void __iomem *regbase);
|
||||
|
||||
void svga_settile(struct fb_info *info, struct fb_tilemap *map);
|
||||
void svga_tilecopy(struct fb_info *info, struct fb_tilearea *area);
|
||||
void svga_tilefill(struct fb_info *info, struct fb_tilerect *rect);
|
||||
void svga_tileblit(struct fb_info *info, struct fb_tileblit *blit);
|
||||
void svga_tilecursor(struct fb_info *info, struct fb_tilecursor *cursor);
|
||||
void svga_tilecursor(void __iomem *regbase, struct fb_info *info, struct fb_tilecursor *cursor);
|
||||
int svga_get_tilemax(struct fb_info *info);
|
||||
void svga_get_caps(struct fb_info *info, struct fb_blit_caps *caps,
|
||||
struct fb_var_screeninfo *var);
|
||||
|
||||
int svga_compute_pll(const struct svga_pll *pll, u32 f_wanted, u16 *m, u16 *n, u16 *r, int node);
|
||||
int svga_check_timings(const struct svga_timing_regs *tm, struct fb_var_screeninfo *var, int node);
|
||||
void svga_set_timings(const struct svga_timing_regs *tm, struct fb_var_screeninfo *var, u32 hmul, u32 hdiv, u32 vmul, u32 vdiv, u32 hborder, int node);
|
||||
void svga_set_timings(void __iomem *regbase, const struct svga_timing_regs *tm, struct fb_var_screeninfo *var, u32 hmul, u32 hdiv, u32 vmul, u32 vdiv, u32 hborder, int node);
|
||||
|
||||
int svga_match_format(const struct svga_fb_format *frm, struct fb_var_screeninfo *var, struct fb_fix_screeninfo *fix);
|
||||
|
||||
|
@ -52,6 +52,7 @@ struct atmel_lcdfb_info {
|
||||
u8 bl_power;
|
||||
#endif
|
||||
bool lcdcon_is_backlight;
|
||||
bool lcdcon_pol_negative;
|
||||
u8 saved_lcdcon;
|
||||
|
||||
u8 default_bpp;
|
||||
|
Loading…
Reference in New Issue
Block a user