mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 14:11:52 +00:00
Merge branch 'for-paul' of git://gitorious.org/linux-omap-dss2/linux
Conflicts: arch/arm/mach-omap2/board-overo.c Signed-off-by: Paul Mundt <lethal@linux-sh.org>
This commit is contained in:
commit
da49252fb0
@ -4542,14 +4542,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);
|
||||
|
@ -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"
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
@ -774,14 +777,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:
|
||||
@ -808,6 +826,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;
|
||||
@ -846,13 +865,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;
|
||||
|
||||
@ -861,30 +880,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;
|
||||
|
||||
@ -903,7 +922,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:
|
||||
@ -921,7 +940,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 */
|
||||
@ -1089,7 +1108,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,
|
||||
@ -1139,7 +1158,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;
|
||||
|
||||
@ -1153,7 +1172,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;
|
||||
@ -1191,9 +1210,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);
|
||||
@ -1263,7 +1282,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;
|
||||
}
|
||||
@ -1306,7 +1325,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;
|
||||
}
|
||||
@ -1350,13 +1369,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;
|
||||
|
||||
@ -1404,9 +1423,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;
|
||||
|
||||
@ -1414,7 +1433,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) {
|
||||
@ -1440,7 +1459,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:
|
||||
@ -1466,7 +1485,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;
|
||||
@ -1479,7 +1498,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;
|
||||
@ -1495,7 +1514,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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user