forked from Minki/linux
fbdev updates for 3.7
It includes: - large updates for OMAP - basic OMAP5 DSS support for DPI and DSI outputs - large cleanups and restructuring - some update to Exynos and da8xx-fb - removal of the pnx4008 driver (arch removed) - various other small patches -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.12 (GNU/Linux) iQIcBAABAgAGBQJQdz+EAAoJECSVL5KnPj1PyiMP/R84rSfGUbDIh0Cr6g1Snk76 h2/1i19TuEgJAWH1q0lnwhqMC3yYmkA1Hz3ulT35KS+/L3IEgUosOESrxZIJhxHI f55pk3v8dueN0rx3OhCknLT7hGpVsI4vSN+3yf9LetDp3qt8UVwKLFzVij1VF/MS b1wA+RBe1IYMR0bB6pK0AgMZZiBkQMta5rKs5IfDDi8kMgMT4+V8l/iFmt2Ue833 VxdPw+3reKshBXKTkQt1Usv4JRtG7OgwpRmFhxOo+ag0dxPLeUe/3wZG54qfOywF 7jK+mnxmW8oZxLkGBvygrmzd40MH6H09N7i/IKVQ0GZoHgAqWWe7VvWahpg8LzwB ynktwWZ3Va98p5u/BIafBr0ZOU30mPL8N0aqR3HU7H12Wq21HtwcF+ewiT4vnMc8 CKzt6VL0qY1tOOdzJzmICzvXGkbBGfj9YOUptJALCIa3bLwZodyQ/bKq8V/bHdTg 2yyUmVhVf/r5qLermjQN8TjFMpRf2SNwTUUYvhUNwZ4yZMVWZgjjhtAlGGFCA/Bs qMRuNpbHMedhzNV4py418Xe3Hwg6TLPuWSWGJ67SG8hxsYy2hq7GebSsXXdC7xG9 N5DMpA88IQR2nLwkr/pslFqjRsUI6ULvIfxibHEoNjQ0GOY9f+hEWbdHBZPI+0Gv Ea9d7nyhmYTZgvRcd9U0 =EJUS -----END PGP SIGNATURE----- Merge tag 'fbdev-updates-for-3.7' of git://github.com/schandinat/linux-2.6 Pull fbdev updates from Florian Tobias Schandinat: "This includes: - large updates for OMAP - basic OMAP5 DSS support for DPI and DSI outputs - large cleanups and restructuring - some update to Exynos and da8xx-fb - removal of the pnx4008 driver (arch removed) - various other small patches" Fix up some trivial conflicts (mostly just include line changes, but also some due to the renaming of the deferred work functions by Tejun). * tag 'fbdev-updates-for-3.7' of git://github.com/schandinat/linux-2.6: (193 commits) gbefb: fix compile error video: mark nuc900fb_map_video_memory as __devinit video/mx3fb: set .owner to prevent module unloading while being used video: exynos_dp: use clk_prepare_enable and clk_disable_unprepare drivers/video/exynos/exynos_mipi_dsi.c: fix error return code drivers/video/savage/savagefb_driver.c: fix error return code video: s3c-fb: use clk_prepare_enable and clk_disable_unprepare da8xx-fb: save and restore LCDC context across suspend/resume cycle da8xx-fb: add pm_runtime support video/udlfb: fix line counting in fb_write OMAPDSS: add missing include for string.h OMAPDSS: DISPC: Configure color conversion coefficients for writeback OMAPDSS: DISPC: Add manager like functions for writeback OMAPDSS: DISPC: Configure writeback FIFOs OMAPDSS: DISPC: Configure writeback specific parameters in dispc_wb_setup() OMAPDSS: DISPC: Configure overlay-like parameters in dispc_wb_setup OMAPDSS: DISPC: Add function to set channel in for writeback OMAPDSS: DISPC: Don't set chroma resampling bit for writeback OMAPDSS: DISPC: Downscale chroma if plane is writeback OMAPDSS: DISPC: Configure input and output sizes for writeback ...
This commit is contained in:
commit
5f76945a9c
@ -29,6 +29,7 @@
|
||||
#include <drm/exynos_drm.h>
|
||||
|
||||
#include <video/platform_lcd.h>
|
||||
#include <video/samsung_fimd.h>
|
||||
#include <media/m5mols.h>
|
||||
#include <media/s5k6aa.h>
|
||||
#include <media/s5p_fimc.h>
|
||||
@ -39,7 +40,6 @@
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
#include <plat/adc.h>
|
||||
#include <plat/regs-fb-v4.h>
|
||||
#include <plat/regs-serial.h>
|
||||
#include <plat/cpu.h>
|
||||
#include <plat/devs.h>
|
||||
|
@ -30,9 +30,9 @@
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
#include <video/platform_lcd.h>
|
||||
#include <video/samsung_fimd.h>
|
||||
|
||||
#include <plat/regs-serial.h>
|
||||
#include <plat/regs-fb-v4.h>
|
||||
#include <plat/cpu.h>
|
||||
#include <plat/devs.h>
|
||||
#include <plat/sdhci.h>
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include <asm/hardware/gic.h>
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
#include <video/samsung_fimd.h>
|
||||
#include <plat/backlight.h>
|
||||
#include <plat/clock.h>
|
||||
#include <plat/cpu.h>
|
||||
@ -36,7 +37,6 @@
|
||||
#include <linux/platform_data/i2c-s3c2410.h>
|
||||
#include <plat/keypad.h>
|
||||
#include <plat/mfc.h>
|
||||
#include <plat/regs-fb.h>
|
||||
#include <plat/regs-serial.h>
|
||||
#include <plat/sdhci.h>
|
||||
|
||||
|
@ -27,9 +27,9 @@
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
#include <video/platform_lcd.h>
|
||||
#include <video/samsung_fimd.h>
|
||||
#include <plat/regs-serial.h>
|
||||
#include <plat/regs-srom.h>
|
||||
#include <plat/regs-fb-v4.h>
|
||||
#include <plat/cpu.h>
|
||||
#include <plat/devs.h>
|
||||
#include <plat/fb.h>
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include <asm/hardware/gic.h>
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
#include <video/samsung_fimd.h>
|
||||
#include <plat/regs-serial.h>
|
||||
#include <plat/clock.h>
|
||||
#include <plat/cpu.h>
|
||||
@ -39,7 +40,6 @@
|
||||
#include <plat/fb.h>
|
||||
#include <plat/mfc.h>
|
||||
#include <plat/sdhci.h>
|
||||
#include <plat/regs-fb-v4.h>
|
||||
#include <plat/fimc-core.h>
|
||||
#include <plat/s5p-time.h>
|
||||
#include <plat/camport.h>
|
||||
|
@ -13,8 +13,8 @@
|
||||
#include <linux/fb.h>
|
||||
#include <linux/gpio.h>
|
||||
|
||||
#include <video/samsung_fimd.h>
|
||||
#include <plat/gpio-cfg.h>
|
||||
#include <plat/regs-fb-v4.h>
|
||||
|
||||
#include <mach/map.h>
|
||||
|
||||
|
@ -607,29 +607,6 @@ static void __init omap_sfh7741prox_init(void)
|
||||
__func__, OMAP4_SFH7741_ENABLE_GPIO, error);
|
||||
}
|
||||
|
||||
static struct gpio sdp4430_hdmi_gpios[] = {
|
||||
{ HDMI_GPIO_CT_CP_HPD, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ct_cp_hpd" },
|
||||
{ HDMI_GPIO_LS_OE, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ls_oe" },
|
||||
{ HDMI_GPIO_HPD, GPIOF_DIR_IN, "hdmi_gpio_hpd" },
|
||||
};
|
||||
|
||||
static int sdp4430_panel_enable_hdmi(struct omap_dss_device *dssdev)
|
||||
{
|
||||
int status;
|
||||
|
||||
status = gpio_request_array(sdp4430_hdmi_gpios,
|
||||
ARRAY_SIZE(sdp4430_hdmi_gpios));
|
||||
if (status)
|
||||
pr_err("%s: Cannot request HDMI GPIOs\n", __func__);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void sdp4430_panel_disable_hdmi(struct omap_dss_device *dssdev)
|
||||
{
|
||||
gpio_free_array(sdp4430_hdmi_gpios, ARRAY_SIZE(sdp4430_hdmi_gpios));
|
||||
}
|
||||
|
||||
static struct nokia_dsi_panel_data dsi1_panel = {
|
||||
.name = "taal",
|
||||
.reset_gpio = 102,
|
||||
@ -650,29 +627,6 @@ static struct omap_dss_device sdp4430_lcd_device = {
|
||||
.phy.dsi = {
|
||||
.module = 0,
|
||||
},
|
||||
|
||||
.clocks = {
|
||||
.dispc = {
|
||||
.channel = {
|
||||
/* Logic Clock = 172.8 MHz */
|
||||
.lck_div = 1,
|
||||
/* Pixel Clock = 34.56 MHz */
|
||||
.pck_div = 5,
|
||||
.lcd_clk_src = OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC,
|
||||
},
|
||||
.dispc_fclk_src = OMAP_DSS_CLK_SRC_FCK,
|
||||
},
|
||||
|
||||
.dsi = {
|
||||
.regn = 16, /* Fint = 2.4 MHz */
|
||||
.regm = 180, /* DDR Clock = 216 MHz */
|
||||
.regm_dispc = 5, /* PLL1_CLK1 = 172.8 MHz */
|
||||
.regm_dsi = 5, /* PLL1_CLK2 = 172.8 MHz */
|
||||
|
||||
.lp_clk_div = 10, /* LP Clock = 8.64 MHz */
|
||||
.dsi_fclk_src = OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI,
|
||||
},
|
||||
},
|
||||
.channel = OMAP_DSS_CHANNEL_LCD,
|
||||
};
|
||||
|
||||
@ -697,33 +651,12 @@ static struct omap_dss_device sdp4430_lcd2_device = {
|
||||
|
||||
.module = 1,
|
||||
},
|
||||
|
||||
.clocks = {
|
||||
.dispc = {
|
||||
.channel = {
|
||||
/* Logic Clock = 172.8 MHz */
|
||||
.lck_div = 1,
|
||||
/* Pixel Clock = 34.56 MHz */
|
||||
.pck_div = 5,
|
||||
.lcd_clk_src = OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC,
|
||||
},
|
||||
.dispc_fclk_src = OMAP_DSS_CLK_SRC_FCK,
|
||||
},
|
||||
|
||||
.dsi = {
|
||||
.regn = 16, /* Fint = 2.4 MHz */
|
||||
.regm = 180, /* DDR Clock = 216 MHz */
|
||||
.regm_dispc = 5, /* PLL1_CLK1 = 172.8 MHz */
|
||||
.regm_dsi = 5, /* PLL1_CLK2 = 172.8 MHz */
|
||||
|
||||
.lp_clk_div = 10, /* LP Clock = 8.64 MHz */
|
||||
.dsi_fclk_src = OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI,
|
||||
},
|
||||
},
|
||||
.channel = OMAP_DSS_CHANNEL_LCD2,
|
||||
};
|
||||
|
||||
static struct omap_dss_hdmi_data sdp4430_hdmi_data = {
|
||||
.ct_cp_hpd_gpio = HDMI_GPIO_CT_CP_HPD,
|
||||
.ls_oe_gpio = HDMI_GPIO_LS_OE,
|
||||
.hpd_gpio = HDMI_GPIO_HPD,
|
||||
};
|
||||
|
||||
@ -731,8 +664,6 @@ 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,
|
||||
.data = &sdp4430_hdmi_data,
|
||||
};
|
||||
|
@ -428,30 +428,9 @@ static struct omap_dss_device omap4_panda_dvi_device = {
|
||||
.channel = OMAP_DSS_CHANNEL_LCD2,
|
||||
};
|
||||
|
||||
static struct gpio panda_hdmi_gpios[] = {
|
||||
{ HDMI_GPIO_CT_CP_HPD, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ct_cp_hpd" },
|
||||
{ HDMI_GPIO_LS_OE, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ls_oe" },
|
||||
{ HDMI_GPIO_HPD, GPIOF_DIR_IN, "hdmi_gpio_hpd" },
|
||||
};
|
||||
|
||||
static int omap4_panda_panel_enable_hdmi(struct omap_dss_device *dssdev)
|
||||
{
|
||||
int status;
|
||||
|
||||
status = gpio_request_array(panda_hdmi_gpios,
|
||||
ARRAY_SIZE(panda_hdmi_gpios));
|
||||
if (status)
|
||||
pr_err("Cannot request HDMI GPIOs\n");
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void omap4_panda_panel_disable_hdmi(struct omap_dss_device *dssdev)
|
||||
{
|
||||
gpio_free_array(panda_hdmi_gpios, ARRAY_SIZE(panda_hdmi_gpios));
|
||||
}
|
||||
|
||||
static struct omap_dss_hdmi_data omap4_panda_hdmi_data = {
|
||||
.ct_cp_hpd_gpio = HDMI_GPIO_CT_CP_HPD,
|
||||
.ls_oe_gpio = HDMI_GPIO_LS_OE,
|
||||
.hpd_gpio = HDMI_GPIO_HPD,
|
||||
};
|
||||
|
||||
@ -459,8 +438,6 @@ 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,
|
||||
.data = &omap4_panda_hdmi_data,
|
||||
};
|
||||
|
@ -95,7 +95,6 @@ static const struct omap_dss_hwmod_data omap4_dss_hwmod_data[] __initconst = {
|
||||
{ "dss_core", "omapdss_dss", -1 },
|
||||
{ "dss_dispc", "omapdss_dispc", -1 },
|
||||
{ "dss_rfbi", "omapdss_rfbi", -1 },
|
||||
{ "dss_venc", "omapdss_venc", -1 },
|
||||
{ "dss_dsi1", "omapdss_dsi", 0 },
|
||||
{ "dss_dsi2", "omapdss_dsi", 1 },
|
||||
{ "dss_hdmi", "omapdss_hdmi", -1 },
|
||||
|
@ -239,6 +239,10 @@ void __init omap3_pmic_get_config(struct twl4030_platform_data *pmic_data,
|
||||
static struct twl4030_usb_data omap4_usb_pdata = {
|
||||
};
|
||||
|
||||
static struct regulator_consumer_supply omap4_vdda_hdmi_dac_supplies[] = {
|
||||
REGULATOR_SUPPLY("vdda_hdmi_dac", "omapdss_hdmi"),
|
||||
};
|
||||
|
||||
static struct regulator_init_data omap4_vdac_idata = {
|
||||
.constraints = {
|
||||
.min_uV = 1800000,
|
||||
@ -248,6 +252,8 @@ static struct regulator_init_data omap4_vdac_idata = {
|
||||
.valid_ops_mask = REGULATOR_CHANGE_MODE
|
||||
| REGULATOR_CHANGE_STATUS,
|
||||
},
|
||||
.num_consumer_supplies = ARRAY_SIZE(omap4_vdda_hdmi_dac_supplies),
|
||||
.consumer_supplies = omap4_vdda_hdmi_dac_supplies,
|
||||
.supply_regulator = "V2V1",
|
||||
};
|
||||
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include <asm/mach/map.h>
|
||||
#include <asm/mach/irq.h>
|
||||
|
||||
#include <video/samsung_fimd.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/mach-types.h>
|
||||
@ -52,7 +53,6 @@
|
||||
#include <linux/platform_data/usb-s3c2410_udc.h>
|
||||
#include <linux/platform_data/s3c-hsudc.h>
|
||||
|
||||
#include <plat/regs-fb-v4.h>
|
||||
#include <plat/fb.h>
|
||||
|
||||
#include <plat/common-smdk.h>
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include <linux/dm9000.h>
|
||||
|
||||
#include <video/platform_lcd.h>
|
||||
#include <video/samsung_fimd.h>
|
||||
|
||||
#include <asm/hardware/vic.h>
|
||||
#include <asm/mach/arch.h>
|
||||
@ -44,7 +45,6 @@
|
||||
#include <plat/regs-serial.h>
|
||||
#include <linux/platform_data/i2c-s3c2410.h>
|
||||
#include <plat/fb.h>
|
||||
#include <plat/regs-fb-v4.h>
|
||||
|
||||
#include <plat/clock.h>
|
||||
#include <plat/devs.h>
|
||||
|
@ -46,6 +46,7 @@
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
#include <video/samsung_fimd.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/map.h>
|
||||
|
||||
@ -57,7 +58,6 @@
|
||||
#include <mach/regs-gpio-memport.h>
|
||||
|
||||
#include <plat/regs-serial.h>
|
||||
#include <plat/regs-fb-v4.h>
|
||||
#include <plat/fb.h>
|
||||
#include <plat/sdhci.h>
|
||||
#include <plat/gpio-cfg.h>
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <asm/mach/map.h>
|
||||
#include <asm/mach/irq.h>
|
||||
|
||||
#include <video/samsung_fimd.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/map.h>
|
||||
|
||||
@ -41,7 +42,6 @@
|
||||
#include <plat/clock.h>
|
||||
#include <plat/devs.h>
|
||||
#include <plat/cpu.h>
|
||||
#include <plat/regs-fb-v4.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
|
@ -41,9 +41,9 @@
|
||||
#include <linux/platform_data/mtd-nand-s3c2410.h>
|
||||
#include <plat/regs-serial.h>
|
||||
#include <linux/platform_data/touchscreen-s3c2410.h>
|
||||
#include <plat/regs-fb-v4.h>
|
||||
|
||||
#include <video/platform_lcd.h>
|
||||
#include <video/samsung_fimd.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include <video/platform_lcd.h>
|
||||
#include <video/samsung_fimd.h>
|
||||
|
||||
#include <asm/hardware/vic.h>
|
||||
#include <asm/mach/arch.h>
|
||||
@ -43,7 +44,6 @@
|
||||
#include <plat/clock.h>
|
||||
#include <plat/devs.h>
|
||||
#include <plat/cpu.h>
|
||||
#include <plat/regs-fb-v4.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
|
@ -42,9 +42,9 @@
|
||||
#include <linux/platform_data/mtd-nand-s3c2410.h>
|
||||
#include <plat/regs-serial.h>
|
||||
#include <linux/platform_data/touchscreen-s3c2410.h>
|
||||
#include <plat/regs-fb-v4.h>
|
||||
|
||||
#include <video/platform_lcd.h>
|
||||
#include <video/samsung_fimd.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
|
||||
#include <video/samsung_fimd.h>
|
||||
#include <mach/map.h>
|
||||
#include <mach/regs-gpio.h>
|
||||
|
||||
@ -28,7 +29,6 @@
|
||||
#include <plat/devs.h>
|
||||
#include <plat/fb.h>
|
||||
#include <plat/gpio-cfg.h>
|
||||
#include <plat/regs-fb-v4.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "mach-smartq.h"
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
|
||||
#include <video/samsung_fimd.h>
|
||||
#include <mach/map.h>
|
||||
#include <mach/regs-gpio.h>
|
||||
|
||||
@ -28,7 +29,6 @@
|
||||
#include <plat/devs.h>
|
||||
#include <plat/fb.h>
|
||||
#include <plat/gpio-cfg.h>
|
||||
#include <plat/regs-fb-v4.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "mach-smartq.h"
|
||||
|
@ -43,6 +43,7 @@
|
||||
#endif
|
||||
|
||||
#include <video/platform_lcd.h>
|
||||
#include <video/samsung_fimd.h>
|
||||
|
||||
#include <asm/hardware/vic.h>
|
||||
#include <asm/mach/arch.h>
|
||||
@ -72,7 +73,6 @@
|
||||
#include <linux/platform_data/touchscreen-s3c2410.h>
|
||||
#include <plat/keypad.h>
|
||||
#include <plat/backlight.h>
|
||||
#include <plat/regs-fb-v4.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include <linux/mmc/host.h>
|
||||
|
||||
#include <video/platform_lcd.h>
|
||||
#include <video/samsung_fimd.h>
|
||||
|
||||
#include <asm/hardware/vic.h>
|
||||
#include <asm/mach/arch.h>
|
||||
@ -52,7 +53,6 @@
|
||||
#include <plat/s5p-time.h>
|
||||
#include <plat/backlight.h>
|
||||
#include <plat/fb.h>
|
||||
#include <plat/regs-fb.h>
|
||||
#include <plat/sdhci.h>
|
||||
|
||||
#include "common.h"
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include <linux/mmc/host.h>
|
||||
|
||||
#include <video/platform_lcd.h>
|
||||
#include <video/samsung_fimd.h>
|
||||
|
||||
#include <asm/hardware/vic.h>
|
||||
#include <asm/mach/arch.h>
|
||||
@ -52,7 +53,6 @@
|
||||
#include <plat/s5p-time.h>
|
||||
#include <plat/backlight.h>
|
||||
#include <plat/fb.h>
|
||||
#include <plat/regs-fb.h>
|
||||
#include <plat/sdhci.h>
|
||||
|
||||
#include "common.h"
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include <mach/regs-gpio.h>
|
||||
|
||||
#include <video/platform_lcd.h>
|
||||
#include <video/samsung_fimd.h>
|
||||
|
||||
#include <asm/irq.h>
|
||||
#include <asm/mach-types.h>
|
||||
@ -51,7 +52,6 @@
|
||||
#include <linux/platform_data/touchscreen-s3c2410.h>
|
||||
#include <linux/platform_data/asoc-s3c.h>
|
||||
#include <plat/backlight.h>
|
||||
#include <plat/regs-fb-v4.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include <asm/setup.h>
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
#include <video/samsung_fimd.h>
|
||||
#include <mach/map.h>
|
||||
#include <mach/regs-clock.h>
|
||||
|
||||
@ -39,7 +40,6 @@
|
||||
#include <plat/fimc-core.h>
|
||||
#include <plat/sdhci.h>
|
||||
#include <plat/s5p-time.h>
|
||||
#include <plat/regs-fb-v4.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include <asm/setup.h>
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
#include <video/samsung_fimd.h>
|
||||
#include <mach/map.h>
|
||||
#include <mach/regs-clock.h>
|
||||
|
||||
@ -49,7 +50,6 @@
|
||||
#include <plat/clock.h>
|
||||
#include <plat/s5p-time.h>
|
||||
#include <plat/mfc.h>
|
||||
#include <plat/regs-fb-v4.h>
|
||||
#include <plat/camport.h>
|
||||
|
||||
#include <media/v4l2-mediabus.h>
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
#include <video/platform_lcd.h>
|
||||
#include <video/samsung_fimd.h>
|
||||
|
||||
#include <mach/map.h>
|
||||
#include <mach/regs-clock.h>
|
||||
@ -46,7 +47,6 @@
|
||||
#include <plat/fb.h>
|
||||
#include <plat/s5p-time.h>
|
||||
#include <plat/backlight.h>
|
||||
#include <plat/regs-fb-v4.h>
|
||||
#include <plat/mfc.h>
|
||||
#include <plat/clock.h>
|
||||
|
||||
|
@ -1,159 +0,0 @@
|
||||
/* arch/arm/plat-samsung/include/plat/regs-fb-v4.h
|
||||
*
|
||||
* Copyright 2008 Openmoko, Inc.
|
||||
* Copyright 2008 Simtec Electronics
|
||||
* http://armlinux.simtec.co.uk/
|
||||
* Ben Dooks <ben@simtec.co.uk>
|
||||
*
|
||||
* S3C64XX - new-style framebuffer register definitions
|
||||
*
|
||||
* This is the register set for the new style framebuffer interface
|
||||
* found from the S3C2443 onwards and specifically the S3C64XX series
|
||||
* S3C6400 and S3C6410.
|
||||
*
|
||||
* The file contains the cpu specific items which change between whichever
|
||||
* architecture is selected. See <plat/regs-fb.h> for the core definitions
|
||||
* that are the same.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* include the core definitions here, in case we really do need to
|
||||
* override them at a later date.
|
||||
*/
|
||||
|
||||
#include <plat/regs-fb.h>
|
||||
|
||||
#define S3C_FB_MAX_WIN (5) /* number of hardware windows available. */
|
||||
#define VIDCON1_FSTATUS_EVEN (1 << 15)
|
||||
|
||||
/* Video timing controls */
|
||||
#define VIDTCON0 (0x10)
|
||||
#define VIDTCON1 (0x14)
|
||||
#define VIDTCON2 (0x18)
|
||||
|
||||
/* Window position controls */
|
||||
|
||||
#define WINCON(_win) (0x20 + ((_win) * 4))
|
||||
|
||||
/* OSD1 and OSD4 do not have register D */
|
||||
|
||||
#define VIDOSD_BASE (0x40)
|
||||
|
||||
#define VIDINTCON0 (0x130)
|
||||
|
||||
/* WINCONx */
|
||||
|
||||
#define WINCONx_CSCWIDTH_MASK (0x3 << 26)
|
||||
#define WINCONx_CSCWIDTH_SHIFT (26)
|
||||
#define WINCONx_CSCWIDTH_WIDE (0x0 << 26)
|
||||
#define WINCONx_CSCWIDTH_NARROW (0x3 << 26)
|
||||
|
||||
#define WINCONx_ENLOCAL (1 << 22)
|
||||
#define WINCONx_BUFSTATUS (1 << 21)
|
||||
#define WINCONx_BUFSEL (1 << 20)
|
||||
#define WINCONx_BUFAUTOEN (1 << 19)
|
||||
#define WINCONx_YCbCr (1 << 13)
|
||||
|
||||
#define WINCON1_LOCALSEL_CAMIF (1 << 23)
|
||||
|
||||
#define WINCON2_LOCALSEL_CAMIF (1 << 23)
|
||||
#define WINCON2_BLD_PIX (1 << 6)
|
||||
|
||||
#define WINCON2_ALPHA_SEL (1 << 1)
|
||||
#define WINCON2_BPPMODE_MASK (0xf << 2)
|
||||
#define WINCON2_BPPMODE_SHIFT (2)
|
||||
#define WINCON2_BPPMODE_1BPP (0x0 << 2)
|
||||
#define WINCON2_BPPMODE_2BPP (0x1 << 2)
|
||||
#define WINCON2_BPPMODE_4BPP (0x2 << 2)
|
||||
#define WINCON2_BPPMODE_8BPP_1232 (0x4 << 2)
|
||||
#define WINCON2_BPPMODE_16BPP_565 (0x5 << 2)
|
||||
#define WINCON2_BPPMODE_16BPP_A1555 (0x6 << 2)
|
||||
#define WINCON2_BPPMODE_16BPP_I1555 (0x7 << 2)
|
||||
#define WINCON2_BPPMODE_18BPP_666 (0x8 << 2)
|
||||
#define WINCON2_BPPMODE_18BPP_A1665 (0x9 << 2)
|
||||
#define WINCON2_BPPMODE_19BPP_A1666 (0xa << 2)
|
||||
#define WINCON2_BPPMODE_24BPP_888 (0xb << 2)
|
||||
#define WINCON2_BPPMODE_24BPP_A1887 (0xc << 2)
|
||||
#define WINCON2_BPPMODE_25BPP_A1888 (0xd << 2)
|
||||
#define WINCON2_BPPMODE_28BPP_A4888 (0xd << 2)
|
||||
|
||||
#define WINCON3_BLD_PIX (1 << 6)
|
||||
|
||||
#define WINCON3_ALPHA_SEL (1 << 1)
|
||||
#define WINCON3_BPPMODE_MASK (0xf << 2)
|
||||
#define WINCON3_BPPMODE_SHIFT (2)
|
||||
#define WINCON3_BPPMODE_1BPP (0x0 << 2)
|
||||
#define WINCON3_BPPMODE_2BPP (0x1 << 2)
|
||||
#define WINCON3_BPPMODE_4BPP (0x2 << 2)
|
||||
#define WINCON3_BPPMODE_16BPP_565 (0x5 << 2)
|
||||
#define WINCON3_BPPMODE_16BPP_A1555 (0x6 << 2)
|
||||
#define WINCON3_BPPMODE_16BPP_I1555 (0x7 << 2)
|
||||
#define WINCON3_BPPMODE_18BPP_666 (0x8 << 2)
|
||||
#define WINCON3_BPPMODE_18BPP_A1665 (0x9 << 2)
|
||||
#define WINCON3_BPPMODE_19BPP_A1666 (0xa << 2)
|
||||
#define WINCON3_BPPMODE_24BPP_888 (0xb << 2)
|
||||
#define WINCON3_BPPMODE_24BPP_A1887 (0xc << 2)
|
||||
#define WINCON3_BPPMODE_25BPP_A1888 (0xd << 2)
|
||||
#define WINCON3_BPPMODE_28BPP_A4888 (0xd << 2)
|
||||
|
||||
#define VIDINTCON0_FIFIOSEL_WINDOW2 (0x10 << 5)
|
||||
#define VIDINTCON0_FIFIOSEL_WINDOW3 (0x20 << 5)
|
||||
#define VIDINTCON0_FIFIOSEL_WINDOW4 (0x40 << 5)
|
||||
|
||||
#define DITHMODE (0x170)
|
||||
#define WINxMAP(_win) (0x180 + ((_win) * 4))
|
||||
|
||||
|
||||
#define DITHMODE_R_POS_MASK (0x3 << 5)
|
||||
#define DITHMODE_R_POS_SHIFT (5)
|
||||
#define DITHMODE_R_POS_8BIT (0x0 << 5)
|
||||
#define DITHMODE_R_POS_6BIT (0x1 << 5)
|
||||
#define DITHMODE_R_POS_5BIT (0x2 << 5)
|
||||
|
||||
#define DITHMODE_G_POS_MASK (0x3 << 3)
|
||||
#define DITHMODE_G_POS_SHIFT (3)
|
||||
#define DITHMODE_G_POS_8BIT (0x0 << 3)
|
||||
#define DITHMODE_G_POS_6BIT (0x1 << 3)
|
||||
#define DITHMODE_G_POS_5BIT (0x2 << 3)
|
||||
|
||||
#define DITHMODE_B_POS_MASK (0x3 << 1)
|
||||
#define DITHMODE_B_POS_SHIFT (1)
|
||||
#define DITHMODE_B_POS_8BIT (0x0 << 1)
|
||||
#define DITHMODE_B_POS_6BIT (0x1 << 1)
|
||||
#define DITHMODE_B_POS_5BIT (0x2 << 1)
|
||||
|
||||
#define DITHMODE_DITH_EN (1 << 0)
|
||||
|
||||
#define WPALCON (0x1A0)
|
||||
|
||||
/* Palette control */
|
||||
/* Note for S5PC100: you can still use those macros on WPALCON (aka WPALCON_L),
|
||||
* but make sure that WPALCON_H W2PAL-W4PAL entries are zeroed out */
|
||||
#define WPALCON_W4PAL_16BPP_A555 (1 << 8)
|
||||
#define WPALCON_W3PAL_16BPP_A555 (1 << 7)
|
||||
#define WPALCON_W2PAL_16BPP_A555 (1 << 6)
|
||||
|
||||
|
||||
/* Notes on per-window bpp settings
|
||||
*
|
||||
* Value Win0 Win1 Win2 Win3 Win 4
|
||||
* 0000 1(P) 1(P) 1(P) 1(P) 1(P)
|
||||
* 0001 2(P) 2(P) 2(P) 2(P) 2(P)
|
||||
* 0010 4(P) 4(P) 4(P) 4(P) -none-
|
||||
* 0011 8(P) 8(P) -none- -none- -none-
|
||||
* 0100 -none- 8(A232) 8(A232) -none- -none-
|
||||
* 0101 16(565) 16(565) 16(565) 16(565) 16(565)
|
||||
* 0110 -none- 16(A555) 16(A555) 16(A555) 16(A555)
|
||||
* 0111 16(I555) 16(I565) 16(I555) 16(I555) 16(I555)
|
||||
* 1000 18(666) 18(666) 18(666) 18(666) 18(666)
|
||||
* 1001 -none- 18(A665) 18(A665) 18(A665) 16(A665)
|
||||
* 1010 -none- 19(A666) 19(A666) 19(A666) 19(A666)
|
||||
* 1011 24(888) 24(888) 24(888) 24(888) 24(888)
|
||||
* 1100 -none- 24(A887) 24(A887) 24(A887) 24(A887)
|
||||
* 1101 -none- 25(A888) 25(A888) 25(A888) 25(A888)
|
||||
* 1110 -none- -none- -none- -none- -none-
|
||||
* 1111 -none- -none- -none- -none- -none-
|
||||
*/
|
@ -19,8 +19,8 @@
|
||||
#include <linux/clk.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
|
||||
#include <video/samsung_fimd.h>
|
||||
#include <drm/exynos_drm.h>
|
||||
#include <plat/regs-fb-v4.h>
|
||||
|
||||
#include "exynos_drm_drv.h"
|
||||
#include "exynos_drm_fbdev.h"
|
||||
|
@ -455,11 +455,15 @@ static int omapvid_init(struct omap_vout_device *vout, u32 addr)
|
||||
|
||||
win = &vout->win;
|
||||
for (i = 0; i < ovid->num_overlays; i++) {
|
||||
struct omap_dss_device *dssdev;
|
||||
|
||||
ovl = ovid->overlays[i];
|
||||
if (!ovl->manager || !ovl->manager->device)
|
||||
dssdev = ovl->get_device(ovl);
|
||||
|
||||
if (!dssdev)
|
||||
return -EINVAL;
|
||||
|
||||
timing = &ovl->manager->device->panel.timings;
|
||||
timing = &dssdev->panel.timings;
|
||||
|
||||
outw = win->w.width;
|
||||
outh = win->w.height;
|
||||
@ -516,8 +520,11 @@ static int omapvid_apply_changes(struct omap_vout_device *vout)
|
||||
struct omapvideo_info *ovid = &vout->vid_info;
|
||||
|
||||
for (i = 0; i < ovid->num_overlays; i++) {
|
||||
struct omap_dss_device *dssdev;
|
||||
|
||||
ovl = ovid->overlays[i];
|
||||
if (!ovl->manager || !ovl->manager->device)
|
||||
dssdev = ovl->get_device(ovl);
|
||||
if (!dssdev)
|
||||
return -EINVAL;
|
||||
ovl->manager->apply(ovl->manager);
|
||||
}
|
||||
@ -580,12 +587,14 @@ static void omap_vout_isr(void *arg, unsigned int irqstatus)
|
||||
|
||||
ovid = &vout->vid_info;
|
||||
ovl = ovid->overlays[0];
|
||||
/* get the display device attached to the overlay */
|
||||
if (!ovl->manager || !ovl->manager->device)
|
||||
return;
|
||||
|
||||
mgr_id = ovl->manager->id;
|
||||
cur_display = ovl->manager->device;
|
||||
|
||||
/* get the display device attached to the overlay */
|
||||
cur_display = ovl->get_device(ovl);
|
||||
|
||||
if (!cur_display)
|
||||
return;
|
||||
|
||||
spin_lock(&vout->vbq_lock);
|
||||
do_gettimeofday(&timevalue);
|
||||
@ -949,7 +958,9 @@ static int omap_vout_release(struct file *file)
|
||||
/* Disable all the overlay managers connected with this interface */
|
||||
for (i = 0; i < ovid->num_overlays; i++) {
|
||||
struct omap_overlay *ovl = ovid->overlays[i];
|
||||
if (ovl->manager && ovl->manager->device)
|
||||
struct omap_dss_device *dssdev = ovl->get_device(ovl);
|
||||
|
||||
if (dssdev)
|
||||
ovl->disable(ovl);
|
||||
}
|
||||
/* Turn off the pipeline */
|
||||
@ -1082,14 +1093,17 @@ static int vidioc_try_fmt_vid_out(struct file *file, void *fh,
|
||||
struct omapvideo_info *ovid;
|
||||
struct omap_video_timings *timing;
|
||||
struct omap_vout_device *vout = fh;
|
||||
struct omap_dss_device *dssdev;
|
||||
|
||||
ovid = &vout->vid_info;
|
||||
ovl = ovid->overlays[0];
|
||||
|
||||
if (!ovl->manager || !ovl->manager->device)
|
||||
return -EINVAL;
|
||||
/* get the display device attached to the overlay */
|
||||
timing = &ovl->manager->device->panel.timings;
|
||||
dssdev = ovl->get_device(ovl);
|
||||
|
||||
if (!dssdev)
|
||||
return -EINVAL;
|
||||
|
||||
timing = &dssdev->panel.timings;
|
||||
|
||||
vout->fbuf.fmt.height = timing->y_res;
|
||||
vout->fbuf.fmt.width = timing->x_res;
|
||||
@ -1106,6 +1120,7 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *fh,
|
||||
struct omapvideo_info *ovid;
|
||||
struct omap_video_timings *timing;
|
||||
struct omap_vout_device *vout = fh;
|
||||
struct omap_dss_device *dssdev;
|
||||
|
||||
if (vout->streaming)
|
||||
return -EBUSY;
|
||||
@ -1114,13 +1129,14 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *fh,
|
||||
|
||||
ovid = &vout->vid_info;
|
||||
ovl = ovid->overlays[0];
|
||||
dssdev = ovl->get_device(ovl);
|
||||
|
||||
/* get the display device attached to the overlay */
|
||||
if (!ovl->manager || !ovl->manager->device) {
|
||||
if (!dssdev) {
|
||||
ret = -EINVAL;
|
||||
goto s_fmt_vid_out_exit;
|
||||
}
|
||||
timing = &ovl->manager->device->panel.timings;
|
||||
timing = &dssdev->panel.timings;
|
||||
|
||||
/* We dont support RGB24-packed mode if vrfb rotation
|
||||
* is enabled*/
|
||||
@ -1299,6 +1315,7 @@ static int vidioc_s_crop(struct file *file, void *fh, const struct v4l2_crop *cr
|
||||
struct omapvideo_info *ovid;
|
||||
struct omap_overlay *ovl;
|
||||
struct omap_video_timings *timing;
|
||||
struct omap_dss_device *dssdev;
|
||||
|
||||
if (vout->streaming)
|
||||
return -EBUSY;
|
||||
@ -1306,13 +1323,15 @@ static int vidioc_s_crop(struct file *file, void *fh, const struct v4l2_crop *cr
|
||||
mutex_lock(&vout->lock);
|
||||
ovid = &vout->vid_info;
|
||||
ovl = ovid->overlays[0];
|
||||
/* get the display device attached to the overlay */
|
||||
dssdev = ovl->get_device(ovl);
|
||||
|
||||
if (!ovl->manager || !ovl->manager->device) {
|
||||
if (!dssdev) {
|
||||
ret = -EINVAL;
|
||||
goto s_crop_err;
|
||||
}
|
||||
/* get the display device attached to the overlay */
|
||||
timing = &ovl->manager->device->panel.timings;
|
||||
|
||||
timing = &dssdev->panel.timings;
|
||||
|
||||
if (is_rotation_90_or_270(vout)) {
|
||||
vout->fbuf.fmt.height = timing->x_res;
|
||||
@ -1668,7 +1687,7 @@ static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
|
||||
for (j = 0; j < ovid->num_overlays; j++) {
|
||||
struct omap_overlay *ovl = ovid->overlays[j];
|
||||
|
||||
if (ovl->manager && ovl->manager->device) {
|
||||
if (ovl->get_device(ovl)) {
|
||||
struct omap_overlay_info info;
|
||||
ovl->get_overlay_info(ovl, &info);
|
||||
info.paddr = addr;
|
||||
@ -1691,8 +1710,9 @@ static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
|
||||
|
||||
for (j = 0; j < ovid->num_overlays; j++) {
|
||||
struct omap_overlay *ovl = ovid->overlays[j];
|
||||
struct omap_dss_device *dssdev = ovl->get_device(ovl);
|
||||
|
||||
if (ovl->manager && ovl->manager->device) {
|
||||
if (dssdev) {
|
||||
ret = ovl->enable(ovl);
|
||||
if (ret)
|
||||
goto streamon_err1;
|
||||
@ -1727,8 +1747,9 @@ static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i)
|
||||
|
||||
for (j = 0; j < ovid->num_overlays; j++) {
|
||||
struct omap_overlay *ovl = ovid->overlays[j];
|
||||
struct omap_dss_device *dssdev = ovl->get_device(ovl);
|
||||
|
||||
if (ovl->manager && ovl->manager->device)
|
||||
if (dssdev)
|
||||
ovl->disable(ovl);
|
||||
}
|
||||
|
||||
@ -1891,8 +1912,8 @@ static int __init omap_vout_setup_video_data(struct omap_vout_device *vout)
|
||||
struct video_device *vfd;
|
||||
struct v4l2_pix_format *pix;
|
||||
struct v4l2_control *control;
|
||||
struct omap_dss_device *display =
|
||||
vout->vid_info.overlays[0]->manager->device;
|
||||
struct omap_overlay *ovl = vout->vid_info.overlays[0];
|
||||
struct omap_dss_device *display = ovl->get_device(ovl);
|
||||
|
||||
/* set the default pix */
|
||||
pix = &vout->pix;
|
||||
@ -2207,8 +2228,10 @@ static int __init omap_vout_probe(struct platform_device *pdev)
|
||||
*/
|
||||
for (i = 1; i < vid_dev->num_overlays; i++) {
|
||||
ovl = omap_dss_get_overlay(i);
|
||||
if (ovl->manager && ovl->manager->device) {
|
||||
def_display = ovl->manager->device;
|
||||
dssdev = ovl->get_device(ovl);
|
||||
|
||||
if (dssdev) {
|
||||
def_display = dssdev;
|
||||
} else {
|
||||
dev_warn(&pdev->dev, "cannot find display\n");
|
||||
def_display = NULL;
|
||||
@ -2255,8 +2278,10 @@ probe_err1:
|
||||
for (i = 1; i < vid_dev->num_overlays; i++) {
|
||||
def_display = NULL;
|
||||
ovl = omap_dss_get_overlay(i);
|
||||
if (ovl->manager && ovl->manager->device)
|
||||
def_display = ovl->manager->device;
|
||||
dssdev = ovl->get_device(ovl);
|
||||
|
||||
if (dssdev)
|
||||
def_display = dssdev;
|
||||
|
||||
if (def_display && def_display->driver)
|
||||
def_display->driver->disable(def_display);
|
||||
|
@ -106,7 +106,8 @@ static void dump_video_chains(void)
|
||||
for (i = 0; i < omap_dss_get_num_overlays(); i++) {
|
||||
struct omap_overlay *ovl = omap_dss_get_overlay(i);
|
||||
struct omap_overlay_manager *mgr = ovl->manager;
|
||||
struct omap_dss_device *dssdev = mgr ? mgr->device : NULL;
|
||||
struct omap_dss_device *dssdev = mgr ?
|
||||
mgr->get_device(mgr) : NULL;
|
||||
if (dssdev) {
|
||||
DBG("%d: %s -> %s -> %s", i, ovl->name, mgr->name,
|
||||
dssdev->name);
|
||||
@ -185,7 +186,7 @@ static int create_connector(struct drm_device *dev,
|
||||
for (j = 0; j < priv->num_encoders; j++) {
|
||||
struct omap_overlay_manager *mgr =
|
||||
omap_encoder_get_manager(priv->encoders[j]);
|
||||
if (mgr->device == dssdev) {
|
||||
if (mgr->get_device(mgr) == dssdev) {
|
||||
drm_mode_connector_attach_encoder(connector,
|
||||
priv->encoders[j]);
|
||||
}
|
||||
|
@ -2139,21 +2139,6 @@ config FB_UDL
|
||||
mplayer -vo fbdev. Supports all USB 2.0 era DisplayLink devices.
|
||||
To compile as a module, choose M here: the module name is udlfb.
|
||||
|
||||
config FB_PNX4008_DUM
|
||||
tristate "Display Update Module support on Philips PNX4008 board"
|
||||
depends on FB && ARCH_PNX4008
|
||||
---help---
|
||||
Say Y here to enable support for PNX4008 Display Update Module (DUM)
|
||||
|
||||
config FB_PNX4008_DUM_RGB
|
||||
tristate "RGB Framebuffer support on Philips PNX4008 board"
|
||||
depends on FB_PNX4008_DUM
|
||||
select FB_CFB_FILLRECT
|
||||
select FB_CFB_COPYAREA
|
||||
select FB_CFB_IMAGEBLIT
|
||||
---help---
|
||||
Say Y here to enable support for PNX4008 RGB Framebuffer
|
||||
|
||||
config FB_IBM_GXT4500
|
||||
tristate "Framebuffer support for IBM GXT4500P adaptor"
|
||||
depends on FB && PPC
|
||||
|
@ -127,8 +127,6 @@ obj-$(CONFIG_FB_S3C) += s3c-fb.o
|
||||
obj-$(CONFIG_FB_S3C2410) += s3c2410fb.o
|
||||
obj-$(CONFIG_FB_FSL_DIU) += fsl-diu-fb.o
|
||||
obj-$(CONFIG_FB_COBALT) += cobalt_lcdfb.o
|
||||
obj-$(CONFIG_FB_PNX4008_DUM) += pnx4008/
|
||||
obj-$(CONFIG_FB_PNX4008_DUM_RGB) += pnx4008/
|
||||
obj-$(CONFIG_FB_IBM_GXT4500) += gxt4500.o
|
||||
obj-$(CONFIG_FB_PS3) += ps3fb.o
|
||||
obj-$(CONFIG_FB_SM501) += sm501fb.o
|
||||
|
@ -949,7 +949,6 @@ static int round_down_bpp = 1; /* for mode probing */
|
||||
|
||||
|
||||
static int amifb_ilbm = 0; /* interleaved or normal bitplanes */
|
||||
static int amifb_inverse = 0;
|
||||
|
||||
static u32 amifb_hfmin __initdata; /* monitor hfreq lower limit (Hz) */
|
||||
static u32 amifb_hfmax __initdata; /* monitor hfreq upper limit (Hz) */
|
||||
@ -2355,7 +2354,6 @@ static int __init amifb_setup(char *options)
|
||||
if (!*this_opt)
|
||||
continue;
|
||||
if (!strcmp(this_opt, "inverse")) {
|
||||
amifb_inverse = 1;
|
||||
fb_invert_cmaps();
|
||||
} else if (!strcmp(this_opt, "ilbm"))
|
||||
amifb_ilbm = 1;
|
||||
|
@ -552,6 +552,7 @@ static int __devinit arcfb_probe(struct platform_device *dev)
|
||||
"arcfb", info)) {
|
||||
printk(KERN_INFO
|
||||
"arcfb: Failed req IRQ %d\n", par->irq);
|
||||
retval = -EBUSY;
|
||||
goto err1;
|
||||
}
|
||||
}
|
||||
|
@ -931,8 +931,10 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
|
||||
if (!info->screen_base)
|
||||
if (!info->screen_base) {
|
||||
ret = -ENOMEM;
|
||||
goto release_intmem;
|
||||
}
|
||||
|
||||
/*
|
||||
* Don't clear the framebuffer -- someone may have set
|
||||
@ -960,6 +962,7 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)
|
||||
sinfo->mmio = ioremap(info->fix.mmio_start, info->fix.mmio_len);
|
||||
if (!sinfo->mmio) {
|
||||
dev_err(dev, "cannot map LCDC registers\n");
|
||||
ret = -ENOMEM;
|
||||
goto release_mem;
|
||||
}
|
||||
|
||||
|
@ -760,18 +760,20 @@ static int __devinit bfin_lq035_probe(struct platform_device *pdev)
|
||||
bfin_lq035_fb.flags = FBINFO_DEFAULT;
|
||||
|
||||
|
||||
bfin_lq035_fb.pseudo_palette = kzalloc(sizeof(u32) * 16, GFP_KERNEL);
|
||||
bfin_lq035_fb.pseudo_palette = devm_kzalloc(&pdev->dev,
|
||||
sizeof(u32) * 16,
|
||||
GFP_KERNEL);
|
||||
if (bfin_lq035_fb.pseudo_palette == NULL) {
|
||||
pr_err("failed to allocate pseudo_palette\n");
|
||||
ret = -ENOMEM;
|
||||
goto out_palette;
|
||||
goto out_table;
|
||||
}
|
||||
|
||||
if (fb_alloc_cmap(&bfin_lq035_fb.cmap, NBR_PALETTE, 0) < 0) {
|
||||
pr_err("failed to allocate colormap (%d entries)\n",
|
||||
NBR_PALETTE);
|
||||
ret = -EFAULT;
|
||||
goto out_cmap;
|
||||
goto out_table;
|
||||
}
|
||||
|
||||
if (register_framebuffer(&bfin_lq035_fb) < 0) {
|
||||
@ -804,9 +806,6 @@ out_lcd:
|
||||
unregister_framebuffer(&bfin_lq035_fb);
|
||||
out_reg:
|
||||
fb_dealloc_cmap(&bfin_lq035_fb.cmap);
|
||||
out_cmap:
|
||||
kfree(bfin_lq035_fb.pseudo_palette);
|
||||
out_palette:
|
||||
out_table:
|
||||
dma_free_coherent(NULL, TOTAL_VIDEO_MEM_SIZE, fb_buffer, 0);
|
||||
fb_buffer = NULL;
|
||||
@ -834,7 +833,6 @@ static int __devexit bfin_lq035_remove(struct platform_device *pdev)
|
||||
free_dma(CH_PPI);
|
||||
|
||||
|
||||
kfree(bfin_lq035_fb.pseudo_palette);
|
||||
fb_dealloc_cmap(&bfin_lq035_fb.cmap);
|
||||
|
||||
|
||||
|
@ -525,6 +525,7 @@ static int __devinit bfin_bf54x_probe(struct platform_device *pdev)
|
||||
info = fbinfo->par;
|
||||
info->fb = fbinfo;
|
||||
info->dev = &pdev->dev;
|
||||
spin_lock_init(&info->lock);
|
||||
|
||||
platform_set_drvdata(pdev, fbinfo);
|
||||
|
||||
@ -601,7 +602,8 @@ static int __devinit bfin_bf54x_probe(struct platform_device *pdev)
|
||||
|
||||
fbinfo->fbops = &bfin_bf54x_fb_ops;
|
||||
|
||||
fbinfo->pseudo_palette = kzalloc(sizeof(u32) * 16, GFP_KERNEL);
|
||||
fbinfo->pseudo_palette = devm_kzalloc(&pdev->dev, sizeof(u32) * 16,
|
||||
GFP_KERNEL);
|
||||
if (!fbinfo->pseudo_palette) {
|
||||
printk(KERN_ERR DRIVER_NAME
|
||||
"Fail to allocate pseudo_palette\n");
|
||||
@ -616,7 +618,7 @@ static int __devinit bfin_bf54x_probe(struct platform_device *pdev)
|
||||
"Fail to allocate colormap (%d entries)\n",
|
||||
BFIN_LCD_NBR_PALETTE_ENTRIES);
|
||||
ret = -EFAULT;
|
||||
goto out5;
|
||||
goto out4;
|
||||
}
|
||||
|
||||
if (request_ports(info)) {
|
||||
@ -671,8 +673,6 @@ out7:
|
||||
free_ports(info);
|
||||
out6:
|
||||
fb_dealloc_cmap(&fbinfo->cmap);
|
||||
out5:
|
||||
kfree(fbinfo->pseudo_palette);
|
||||
out4:
|
||||
dma_free_coherent(NULL, fbinfo->fix.smem_len, info->fb_buffer,
|
||||
info->dma_handle);
|
||||
@ -699,7 +699,6 @@ static int __devexit bfin_bf54x_remove(struct platform_device *pdev)
|
||||
dma_free_coherent(NULL, fbinfo->fix.smem_len, info->fb_buffer,
|
||||
info->dma_handle);
|
||||
|
||||
kfree(fbinfo->pseudo_palette);
|
||||
fb_dealloc_cmap(&fbinfo->cmap);
|
||||
|
||||
#ifndef NO_BL_SUPPORT
|
||||
|
@ -577,6 +577,7 @@ static int __devinit bfin_lq035q1_probe(struct platform_device *pdev)
|
||||
info = fbinfo->par;
|
||||
info->fb = fbinfo;
|
||||
info->dev = &pdev->dev;
|
||||
spin_lock_init(&info->lock);
|
||||
|
||||
info->disp_info = pdev->dev.platform_data;
|
||||
|
||||
@ -853,17 +854,7 @@ static struct platform_driver bfin_lq035q1_driver = {
|
||||
},
|
||||
};
|
||||
|
||||
static int __init bfin_lq035q1_driver_init(void)
|
||||
{
|
||||
return platform_driver_register(&bfin_lq035q1_driver);
|
||||
}
|
||||
module_init(bfin_lq035q1_driver_init);
|
||||
|
||||
static void __exit bfin_lq035q1_driver_cleanup(void)
|
||||
{
|
||||
platform_driver_unregister(&bfin_lq035q1_driver);
|
||||
}
|
||||
module_exit(bfin_lq035q1_driver_cleanup);
|
||||
module_platform_driver(bfin_lq035q1_driver);
|
||||
|
||||
MODULE_DESCRIPTION("Blackfin TFT LCD Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -447,6 +447,7 @@ static int __devinit bfin_t350mcqb_probe(struct platform_device *pdev)
|
||||
info = fbinfo->par;
|
||||
info->fb = fbinfo;
|
||||
info->dev = &pdev->dev;
|
||||
spin_lock_init(&info->lock);
|
||||
|
||||
platform_set_drvdata(pdev, fbinfo);
|
||||
|
||||
|
@ -319,8 +319,10 @@ static int __devinit bw2_probe(struct platform_device *op)
|
||||
|
||||
info->screen_base = of_ioremap(&op->resource[0], 0,
|
||||
info->fix.smem_len, "bw2 ram");
|
||||
if (!info->screen_base)
|
||||
if (!info->screen_base) {
|
||||
err = -ENOMEM;
|
||||
goto out_unmap_regs;
|
||||
}
|
||||
|
||||
bw2_blank(FB_BLANK_UNBLANK, info);
|
||||
|
||||
|
@ -398,7 +398,8 @@ static int __devinit cg3_probe(struct platform_device *op)
|
||||
goto out_unmap_screen;
|
||||
}
|
||||
|
||||
if (fb_alloc_cmap(&info->cmap, 256, 0))
|
||||
err = fb_alloc_cmap(&info->cmap, 256, 0);
|
||||
if (err)
|
||||
goto out_unmap_screen;
|
||||
|
||||
fb_set_cmap(&info->cmap, info);
|
||||
|
@ -348,7 +348,8 @@ static int __devinit cobalt_lcdfb_probe(struct platform_device *dev)
|
||||
}
|
||||
|
||||
info->screen_size = resource_size(res);
|
||||
info->screen_base = ioremap(res->start, info->screen_size);
|
||||
info->screen_base = devm_ioremap(&dev->dev, res->start,
|
||||
info->screen_size);
|
||||
info->fbops = &cobalt_lcd_fbops;
|
||||
info->fix = cobalt_lcdfb_fix;
|
||||
info->fix.smem_start = res->start;
|
||||
@ -359,7 +360,6 @@ static int __devinit cobalt_lcdfb_probe(struct platform_device *dev)
|
||||
|
||||
retval = register_framebuffer(info);
|
||||
if (retval < 0) {
|
||||
iounmap(info->screen_base);
|
||||
framebuffer_release(info);
|
||||
return retval;
|
||||
}
|
||||
@ -380,7 +380,6 @@ static int __devexit cobalt_lcdfb_remove(struct platform_device *dev)
|
||||
|
||||
info = platform_get_drvdata(dev);
|
||||
if (info) {
|
||||
iounmap(info->screen_base);
|
||||
unregister_framebuffer(info);
|
||||
framebuffer_release(info);
|
||||
}
|
||||
|
@ -1092,7 +1092,7 @@ static const unsigned char fontdata_mini_4x6[FONTDATAMAX] = {
|
||||
/*{*/ /* Char 124: '|' */
|
||||
0x44, /*= [ * ] */
|
||||
0x44, /*= [ * ] */
|
||||
0x00, /*= [ ] */
|
||||
0x44, /*= [ * ] */
|
||||
0x44, /*= [ * ] */
|
||||
0x44, /*= [ * ] */
|
||||
0x00, /*= [ ] */
|
||||
|
@ -127,7 +127,7 @@ static const unsigned char fontdata_sun8x16[FONTDATAMAX] = {
|
||||
/*y*/ 0x00,0x00,0x00,0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7e,0x06,0x0c,0xf8,0x00,
|
||||
/*z*/ 0x00,0x00,0x00,0x00,0x00,0xfe,0xcc,0x18,0x30,0x60,0xc6,0xfe,0x00,0x00,0x00,0x00,
|
||||
/*{*/ 0x00,0x00,0x0e,0x18,0x18,0x18,0x70,0x18,0x18,0x18,0x18,0x0e,0x00,0x00,0x00,0x00,
|
||||
/*|*/ 0x00,0x00,0x18,0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,
|
||||
/*|*/ 0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,
|
||||
/*}*/ 0x00,0x00,0x70,0x18,0x18,0x18,0x0e,0x18,0x18,0x18,0x18,0x70,0x00,0x00,0x00,0x00,
|
||||
/*~*/ 0x00,0x00,0x76,0xdc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
/* */ 0x00,0x00,0x00,0x00,0x10,0x38,0x6c,0xc6,0xc6,0xc6,0xfe,0x00,0x00,0x00,0x00,0x00,
|
||||
|
@ -1804,8 +1804,10 @@ cyberpro_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
||||
|
||||
cfb->irq = dev->irq;
|
||||
cfb->region = pci_ioremap_bar(dev, 0);
|
||||
if (!cfb->region)
|
||||
if (!cfb->region) {
|
||||
err = -ENOMEM;
|
||||
goto failed_ioremap;
|
||||
}
|
||||
|
||||
cfb->regs = cfb->region + MMIO_OFFSET;
|
||||
cfb->fb.device = &dev->dev;
|
||||
|
@ -26,7 +26,9 @@
|
||||
#include <linux/device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/cpufreq.h>
|
||||
#include <linux/console.h>
|
||||
@ -48,6 +50,7 @@
|
||||
#define LCD_PL_LOAD_DONE BIT(6)
|
||||
#define LCD_FIFO_UNDERFLOW BIT(5)
|
||||
#define LCD_SYNC_LOST BIT(2)
|
||||
#define LCD_FRAME_DONE BIT(0)
|
||||
|
||||
/* LCD DMA Control Register */
|
||||
#define LCD_DMA_BURST_SIZE(x) ((x) << 4)
|
||||
@ -86,6 +89,8 @@
|
||||
#define LCD_V2_LIDD_CLK_EN BIT(1)
|
||||
#define LCD_V2_CORE_CLK_EN BIT(0)
|
||||
#define LCD_V2_LPP_B10 26
|
||||
#define LCD_V2_TFT_24BPP_MODE BIT(25)
|
||||
#define LCD_V2_TFT_24BPP_UNPACK BIT(26)
|
||||
|
||||
/* LCD Raster Timing 2 Register */
|
||||
#define LCD_AC_BIAS_TRANSITIONS_PER_INT(x) ((x) << 16)
|
||||
@ -135,6 +140,8 @@ static void __iomem *da8xx_fb_reg_base;
|
||||
static struct resource *lcdc_regs;
|
||||
static unsigned int lcd_revision;
|
||||
static irq_handler_t lcdc_irq_handler;
|
||||
static wait_queue_head_t frame_done_wq;
|
||||
static int frame_done_flag;
|
||||
|
||||
static inline unsigned int lcdc_read(unsigned int addr)
|
||||
{
|
||||
@ -156,7 +163,6 @@ struct da8xx_fb_par {
|
||||
unsigned int dma_end;
|
||||
struct clk *lcdc_clk;
|
||||
int irq;
|
||||
unsigned short pseudo_palette[16];
|
||||
unsigned int palette_sz;
|
||||
unsigned int pxl_clk;
|
||||
int blank;
|
||||
@ -175,6 +181,7 @@ struct da8xx_fb_par {
|
||||
unsigned int lcd_fck_rate;
|
||||
#endif
|
||||
void (*panel_power_ctrl)(int);
|
||||
u32 pseudo_palette[16];
|
||||
};
|
||||
|
||||
/* Variable Screen Information */
|
||||
@ -288,13 +295,26 @@ static inline void lcd_enable_raster(void)
|
||||
}
|
||||
|
||||
/* Disable the Raster Engine of the LCD Controller */
|
||||
static inline void lcd_disable_raster(void)
|
||||
static inline void lcd_disable_raster(bool wait_for_frame_done)
|
||||
{
|
||||
u32 reg;
|
||||
int ret;
|
||||
|
||||
reg = lcdc_read(LCD_RASTER_CTRL_REG);
|
||||
if (reg & LCD_RASTER_ENABLE)
|
||||
lcdc_write(reg & ~LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG);
|
||||
else
|
||||
/* return if already disabled */
|
||||
return;
|
||||
|
||||
if ((wait_for_frame_done == true) && (lcd_revision == LCD_VERSION_2)) {
|
||||
frame_done_flag = 0;
|
||||
ret = wait_event_interruptible_timeout(frame_done_wq,
|
||||
frame_done_flag != 0,
|
||||
msecs_to_jiffies(50));
|
||||
if (ret == 0)
|
||||
pr_err("LCD Controller timed out\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
|
||||
@ -321,7 +341,8 @@ static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
|
||||
} else {
|
||||
reg_int = lcdc_read(LCD_INT_ENABLE_SET_REG) |
|
||||
LCD_V2_END_OF_FRAME0_INT_ENA |
|
||||
LCD_V2_END_OF_FRAME1_INT_ENA;
|
||||
LCD_V2_END_OF_FRAME1_INT_ENA |
|
||||
LCD_FRAME_DONE;
|
||||
lcdc_write(reg_int, LCD_INT_ENABLE_SET_REG);
|
||||
}
|
||||
reg_dma |= LCD_DUAL_FRAME_BUFFER_ENABLE;
|
||||
@ -499,6 +520,9 @@ static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height,
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
if (bpp > 16 && lcd_revision == LCD_VERSION_1)
|
||||
return -EINVAL;
|
||||
|
||||
/* Set the Panel Width */
|
||||
/* Pixels per line = (PPL + 1)*16 */
|
||||
if (lcd_revision == LCD_VERSION_1) {
|
||||
@ -542,14 +566,19 @@ static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height,
|
||||
reg = lcdc_read(LCD_RASTER_CTRL_REG) & ~(1 << 8);
|
||||
if (raster_order)
|
||||
reg |= LCD_RASTER_ORDER;
|
||||
lcdc_write(reg, LCD_RASTER_CTRL_REG);
|
||||
|
||||
par->palette_sz = 16 * 2;
|
||||
|
||||
switch (bpp) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 4:
|
||||
case 16:
|
||||
par->palette_sz = 16 * 2;
|
||||
break;
|
||||
case 24:
|
||||
reg |= LCD_V2_TFT_24BPP_MODE;
|
||||
case 32:
|
||||
reg |= LCD_V2_TFT_24BPP_UNPACK;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
@ -560,9 +589,12 @@ static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
lcdc_write(reg, LCD_RASTER_CTRL_REG);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define CNVT_TOHW(val, width) ((((val) << (width)) + 0x7FFF - (val)) >> 16)
|
||||
static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,
|
||||
unsigned blue, unsigned transp,
|
||||
struct fb_info *info)
|
||||
@ -578,13 +610,38 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,
|
||||
if (info->fix.visual == FB_VISUAL_DIRECTCOLOR)
|
||||
return 1;
|
||||
|
||||
if (info->var.bits_per_pixel == 4) {
|
||||
if (regno > 15)
|
||||
return 1;
|
||||
if (info->var.bits_per_pixel > 16 && lcd_revision == LCD_VERSION_1)
|
||||
return -EINVAL;
|
||||
|
||||
if (info->var.grayscale) {
|
||||
pal = regno;
|
||||
} else {
|
||||
switch (info->fix.visual) {
|
||||
case FB_VISUAL_TRUECOLOR:
|
||||
red = CNVT_TOHW(red, info->var.red.length);
|
||||
green = CNVT_TOHW(green, info->var.green.length);
|
||||
blue = CNVT_TOHW(blue, info->var.blue.length);
|
||||
break;
|
||||
case FB_VISUAL_PSEUDOCOLOR:
|
||||
switch (info->var.bits_per_pixel) {
|
||||
case 4:
|
||||
if (regno > 15)
|
||||
return -EINVAL;
|
||||
|
||||
if (info->var.grayscale) {
|
||||
pal = regno;
|
||||
} else {
|
||||
red >>= 4;
|
||||
green >>= 8;
|
||||
blue >>= 12;
|
||||
|
||||
pal = red & 0x0f00;
|
||||
pal |= green & 0x00f0;
|
||||
pal |= blue & 0x000f;
|
||||
}
|
||||
if (regno == 0)
|
||||
pal |= 0x2000;
|
||||
palette[regno] = pal;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
red >>= 4;
|
||||
green >>= 8;
|
||||
blue >>= 12;
|
||||
@ -592,36 +649,36 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,
|
||||
pal = (red & 0x0f00);
|
||||
pal |= (green & 0x00f0);
|
||||
pal |= (blue & 0x000f);
|
||||
|
||||
if (palette[regno] != pal) {
|
||||
update_hw = 1;
|
||||
palette[regno] = pal;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (regno == 0)
|
||||
pal |= 0x2000;
|
||||
palette[regno] = pal;
|
||||
break;
|
||||
}
|
||||
|
||||
} else if (info->var.bits_per_pixel == 8) {
|
||||
red >>= 4;
|
||||
green >>= 8;
|
||||
blue >>= 12;
|
||||
/* Truecolor has hardware independent palette */
|
||||
if (info->fix.visual == FB_VISUAL_TRUECOLOR) {
|
||||
u32 v;
|
||||
|
||||
pal = (red & 0x0f00);
|
||||
pal |= (green & 0x00f0);
|
||||
pal |= (blue & 0x000f);
|
||||
if (regno > 15)
|
||||
return -EINVAL;
|
||||
|
||||
if (palette[regno] != pal) {
|
||||
update_hw = 1;
|
||||
palette[regno] = pal;
|
||||
v = (red << info->var.red.offset) |
|
||||
(green << info->var.green.offset) |
|
||||
(blue << info->var.blue.offset);
|
||||
|
||||
switch (info->var.bits_per_pixel) {
|
||||
case 16:
|
||||
((u16 *) (info->pseudo_palette))[regno] = v;
|
||||
break;
|
||||
case 24:
|
||||
case 32:
|
||||
((u32 *) (info->pseudo_palette))[regno] = v;
|
||||
break;
|
||||
}
|
||||
} else if ((info->var.bits_per_pixel == 16) && regno < 16) {
|
||||
red >>= (16 - info->var.red.length);
|
||||
red <<= info->var.red.offset;
|
||||
|
||||
green >>= (16 - info->var.green.length);
|
||||
green <<= info->var.green.offset;
|
||||
|
||||
blue >>= (16 - info->var.blue.length);
|
||||
blue <<= info->var.blue.offset;
|
||||
|
||||
par->pseudo_palette[regno] = red | green | blue;
|
||||
|
||||
if (palette[0] != 0x4000) {
|
||||
update_hw = 1;
|
||||
palette[0] = 0x4000;
|
||||
@ -634,11 +691,12 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,
|
||||
|
||||
return 0;
|
||||
}
|
||||
#undef CNVT_TOHW
|
||||
|
||||
static void lcd_reset(struct da8xx_fb_par *par)
|
||||
{
|
||||
/* Disable the Raster if previously Enabled */
|
||||
lcd_disable_raster();
|
||||
lcd_disable_raster(false);
|
||||
|
||||
/* DMA has to be disabled */
|
||||
lcdc_write(0, LCD_DMA_CTRL_REG);
|
||||
@ -734,7 +792,7 @@ static irqreturn_t lcdc_irq_handler_rev02(int irq, void *arg)
|
||||
u32 stat = lcdc_read(LCD_MASKED_STAT_REG);
|
||||
|
||||
if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) {
|
||||
lcd_disable_raster();
|
||||
lcd_disable_raster(false);
|
||||
lcdc_write(stat, LCD_MASKED_STAT_REG);
|
||||
lcd_enable_raster();
|
||||
} else if (stat & LCD_PL_LOAD_DONE) {
|
||||
@ -744,7 +802,7 @@ static irqreturn_t lcdc_irq_handler_rev02(int irq, void *arg)
|
||||
* interrupt via the following write to the status register. If
|
||||
* this is done after then one gets multiple PL done interrupts.
|
||||
*/
|
||||
lcd_disable_raster();
|
||||
lcd_disable_raster(false);
|
||||
|
||||
lcdc_write(stat, LCD_MASKED_STAT_REG);
|
||||
|
||||
@ -775,6 +833,14 @@ static irqreturn_t lcdc_irq_handler_rev02(int irq, void *arg)
|
||||
par->vsync_flag = 1;
|
||||
wake_up_interruptible(&par->vsync_wait);
|
||||
}
|
||||
|
||||
/* Set only when controller is disabled and at the end of
|
||||
* active frame
|
||||
*/
|
||||
if (stat & BIT(0)) {
|
||||
frame_done_flag = 1;
|
||||
wake_up_interruptible(&frame_done_wq);
|
||||
}
|
||||
}
|
||||
|
||||
lcdc_write(0, LCD_END_OF_INT_IND_REG);
|
||||
@ -789,7 +855,7 @@ static irqreturn_t lcdc_irq_handler_rev01(int irq, void *arg)
|
||||
u32 reg_ras;
|
||||
|
||||
if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) {
|
||||
lcd_disable_raster();
|
||||
lcd_disable_raster(false);
|
||||
lcdc_write(stat, LCD_STAT_REG);
|
||||
lcd_enable_raster();
|
||||
} else if (stat & LCD_PL_LOAD_DONE) {
|
||||
@ -799,7 +865,7 @@ static irqreturn_t lcdc_irq_handler_rev01(int irq, void *arg)
|
||||
* interrupt via the following write to the status register. If
|
||||
* this is done after then one gets multiple PL done interrupts.
|
||||
*/
|
||||
lcd_disable_raster();
|
||||
lcd_disable_raster(false);
|
||||
|
||||
lcdc_write(stat, LCD_STAT_REG);
|
||||
|
||||
@ -842,6 +908,9 @@ static int fb_check_var(struct fb_var_screeninfo *var,
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
if (var->bits_per_pixel > 16 && lcd_revision == LCD_VERSION_1)
|
||||
return -EINVAL;
|
||||
|
||||
switch (var->bits_per_pixel) {
|
||||
case 1:
|
||||
case 8:
|
||||
@ -877,6 +946,26 @@ static int fb_check_var(struct fb_var_screeninfo *var,
|
||||
var->transp.length = 0;
|
||||
var->nonstd = 0;
|
||||
break;
|
||||
case 24:
|
||||
var->red.offset = 16;
|
||||
var->red.length = 8;
|
||||
var->green.offset = 8;
|
||||
var->green.length = 8;
|
||||
var->blue.offset = 0;
|
||||
var->blue.length = 8;
|
||||
var->nonstd = 0;
|
||||
break;
|
||||
case 32:
|
||||
var->transp.offset = 24;
|
||||
var->transp.length = 8;
|
||||
var->red.offset = 16;
|
||||
var->red.length = 8;
|
||||
var->green.offset = 8;
|
||||
var->green.length = 8;
|
||||
var->blue.offset = 0;
|
||||
var->blue.length = 8;
|
||||
var->nonstd = 0;
|
||||
break;
|
||||
default:
|
||||
err = -EINVAL;
|
||||
}
|
||||
@ -898,9 +987,10 @@ static int lcd_da8xx_cpufreq_transition(struct notifier_block *nb,
|
||||
if (val == CPUFREQ_POSTCHANGE) {
|
||||
if (par->lcd_fck_rate != clk_get_rate(par->lcdc_clk)) {
|
||||
par->lcd_fck_rate = clk_get_rate(par->lcdc_clk);
|
||||
lcd_disable_raster();
|
||||
lcd_disable_raster(true);
|
||||
lcd_calc_clk_divider(par);
|
||||
lcd_enable_raster();
|
||||
if (par->blank == FB_BLANK_UNBLANK)
|
||||
lcd_enable_raster();
|
||||
}
|
||||
}
|
||||
|
||||
@ -935,7 +1025,7 @@ static int __devexit fb_remove(struct platform_device *dev)
|
||||
if (par->panel_power_ctrl)
|
||||
par->panel_power_ctrl(0);
|
||||
|
||||
lcd_disable_raster();
|
||||
lcd_disable_raster(true);
|
||||
lcdc_write(0, LCD_RASTER_CTRL_REG);
|
||||
|
||||
/* disable DMA */
|
||||
@ -948,8 +1038,8 @@ static int __devexit fb_remove(struct platform_device *dev)
|
||||
dma_free_coherent(NULL, par->vram_size, par->vram_virt,
|
||||
par->vram_phys);
|
||||
free_irq(par->irq, par);
|
||||
clk_disable(par->lcdc_clk);
|
||||
clk_put(par->lcdc_clk);
|
||||
pm_runtime_put_sync(&dev->dev);
|
||||
pm_runtime_disable(&dev->dev);
|
||||
framebuffer_release(info);
|
||||
iounmap(da8xx_fb_reg_base);
|
||||
release_mem_region(lcdc_regs->start, resource_size(lcdc_regs));
|
||||
@ -1051,7 +1141,7 @@ static int cfb_blank(int blank, struct fb_info *info)
|
||||
if (par->panel_power_ctrl)
|
||||
par->panel_power_ctrl(0);
|
||||
|
||||
lcd_disable_raster();
|
||||
lcd_disable_raster(true);
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
@ -1183,9 +1273,9 @@ static int __devinit fb_probe(struct platform_device *device)
|
||||
ret = -ENODEV;
|
||||
goto err_ioremap;
|
||||
}
|
||||
ret = clk_enable(fb_clk);
|
||||
if (ret)
|
||||
goto err_clk_put;
|
||||
|
||||
pm_runtime_enable(&device->dev);
|
||||
pm_runtime_get_sync(&device->dev);
|
||||
|
||||
/* Determine LCD IP Version */
|
||||
switch (lcdc_read(LCD_PID_REG)) {
|
||||
@ -1213,7 +1303,7 @@ static int __devinit fb_probe(struct platform_device *device)
|
||||
if (i == ARRAY_SIZE(known_lcd_panels)) {
|
||||
dev_err(&device->dev, "GLCD: No valid panel found\n");
|
||||
ret = -ENODEV;
|
||||
goto err_clk_disable;
|
||||
goto err_pm_runtime_disable;
|
||||
} else
|
||||
dev_info(&device->dev, "GLCD: Found %s panel\n",
|
||||
fb_pdata->type);
|
||||
@ -1225,7 +1315,7 @@ static int __devinit fb_probe(struct platform_device *device)
|
||||
if (!da8xx_fb_info) {
|
||||
dev_dbg(&device->dev, "Memory allocation failed for fb_info\n");
|
||||
ret = -ENOMEM;
|
||||
goto err_clk_disable;
|
||||
goto err_pm_runtime_disable;
|
||||
}
|
||||
|
||||
par = da8xx_fb_info->par;
|
||||
@ -1356,8 +1446,10 @@ static int __devinit fb_probe(struct platform_device *device)
|
||||
|
||||
if (lcd_revision == LCD_VERSION_1)
|
||||
lcdc_irq_handler = lcdc_irq_handler_rev01;
|
||||
else
|
||||
else {
|
||||
init_waitqueue_head(&frame_done_wq);
|
||||
lcdc_irq_handler = lcdc_irq_handler_rev02;
|
||||
}
|
||||
|
||||
ret = request_irq(par->irq, lcdc_irq_handler, 0,
|
||||
DRIVER_NAME, par);
|
||||
@ -1385,11 +1477,9 @@ err_release_fb_mem:
|
||||
err_release_fb:
|
||||
framebuffer_release(da8xx_fb_info);
|
||||
|
||||
err_clk_disable:
|
||||
clk_disable(fb_clk);
|
||||
|
||||
err_clk_put:
|
||||
clk_put(fb_clk);
|
||||
err_pm_runtime_disable:
|
||||
pm_runtime_put_sync(&device->dev);
|
||||
pm_runtime_disable(&device->dev);
|
||||
|
||||
err_ioremap:
|
||||
iounmap(da8xx_fb_reg_base);
|
||||
@ -1401,6 +1491,69 @@ err_request_mem:
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
struct lcdc_context {
|
||||
u32 clk_enable;
|
||||
u32 ctrl;
|
||||
u32 dma_ctrl;
|
||||
u32 raster_timing_0;
|
||||
u32 raster_timing_1;
|
||||
u32 raster_timing_2;
|
||||
u32 int_enable_set;
|
||||
u32 dma_frm_buf_base_addr_0;
|
||||
u32 dma_frm_buf_ceiling_addr_0;
|
||||
u32 dma_frm_buf_base_addr_1;
|
||||
u32 dma_frm_buf_ceiling_addr_1;
|
||||
u32 raster_ctrl;
|
||||
} reg_context;
|
||||
|
||||
static void lcd_context_save(void)
|
||||
{
|
||||
if (lcd_revision == LCD_VERSION_2) {
|
||||
reg_context.clk_enable = lcdc_read(LCD_CLK_ENABLE_REG);
|
||||
reg_context.int_enable_set = lcdc_read(LCD_INT_ENABLE_SET_REG);
|
||||
}
|
||||
|
||||
reg_context.ctrl = lcdc_read(LCD_CTRL_REG);
|
||||
reg_context.dma_ctrl = lcdc_read(LCD_DMA_CTRL_REG);
|
||||
reg_context.raster_timing_0 = lcdc_read(LCD_RASTER_TIMING_0_REG);
|
||||
reg_context.raster_timing_1 = lcdc_read(LCD_RASTER_TIMING_1_REG);
|
||||
reg_context.raster_timing_2 = lcdc_read(LCD_RASTER_TIMING_2_REG);
|
||||
reg_context.dma_frm_buf_base_addr_0 =
|
||||
lcdc_read(LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
|
||||
reg_context.dma_frm_buf_ceiling_addr_0 =
|
||||
lcdc_read(LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG);
|
||||
reg_context.dma_frm_buf_base_addr_1 =
|
||||
lcdc_read(LCD_DMA_FRM_BUF_BASE_ADDR_1_REG);
|
||||
reg_context.dma_frm_buf_ceiling_addr_1 =
|
||||
lcdc_read(LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG);
|
||||
reg_context.raster_ctrl = lcdc_read(LCD_RASTER_CTRL_REG);
|
||||
return;
|
||||
}
|
||||
|
||||
static void lcd_context_restore(void)
|
||||
{
|
||||
if (lcd_revision == LCD_VERSION_2) {
|
||||
lcdc_write(reg_context.clk_enable, LCD_CLK_ENABLE_REG);
|
||||
lcdc_write(reg_context.int_enable_set, LCD_INT_ENABLE_SET_REG);
|
||||
}
|
||||
|
||||
lcdc_write(reg_context.ctrl, LCD_CTRL_REG);
|
||||
lcdc_write(reg_context.dma_ctrl, LCD_DMA_CTRL_REG);
|
||||
lcdc_write(reg_context.raster_timing_0, LCD_RASTER_TIMING_0_REG);
|
||||
lcdc_write(reg_context.raster_timing_1, LCD_RASTER_TIMING_1_REG);
|
||||
lcdc_write(reg_context.raster_timing_2, LCD_RASTER_TIMING_2_REG);
|
||||
lcdc_write(reg_context.dma_frm_buf_base_addr_0,
|
||||
LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
|
||||
lcdc_write(reg_context.dma_frm_buf_ceiling_addr_0,
|
||||
LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG);
|
||||
lcdc_write(reg_context.dma_frm_buf_base_addr_1,
|
||||
LCD_DMA_FRM_BUF_BASE_ADDR_1_REG);
|
||||
lcdc_write(reg_context.dma_frm_buf_ceiling_addr_1,
|
||||
LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG);
|
||||
lcdc_write(reg_context.raster_ctrl, LCD_RASTER_CTRL_REG);
|
||||
return;
|
||||
}
|
||||
|
||||
static int fb_suspend(struct platform_device *dev, pm_message_t state)
|
||||
{
|
||||
struct fb_info *info = platform_get_drvdata(dev);
|
||||
@ -1411,8 +1564,9 @@ static int fb_suspend(struct platform_device *dev, pm_message_t state)
|
||||
par->panel_power_ctrl(0);
|
||||
|
||||
fb_set_suspend(info, 1);
|
||||
lcd_disable_raster();
|
||||
clk_disable(par->lcdc_clk);
|
||||
lcd_disable_raster(true);
|
||||
lcd_context_save();
|
||||
pm_runtime_put_sync(&dev->dev);
|
||||
console_unlock();
|
||||
|
||||
return 0;
|
||||
@ -1423,11 +1577,14 @@ static int fb_resume(struct platform_device *dev)
|
||||
struct da8xx_fb_par *par = info->par;
|
||||
|
||||
console_lock();
|
||||
clk_enable(par->lcdc_clk);
|
||||
lcd_enable_raster();
|
||||
pm_runtime_get_sync(&dev->dev);
|
||||
lcd_context_restore();
|
||||
if (par->blank == FB_BLANK_UNBLANK) {
|
||||
lcd_enable_raster();
|
||||
|
||||
if (par->panel_power_ctrl)
|
||||
par->panel_power_ctrl(1);
|
||||
if (par->panel_power_ctrl)
|
||||
par->panel_power_ctrl(1);
|
||||
}
|
||||
|
||||
fb_set_suspend(info, 0);
|
||||
console_unlock();
|
||||
|
@ -529,7 +529,8 @@ static int __devinit ep93xxfb_probe(struct platform_device *pdev)
|
||||
* any of the framebuffer registers.
|
||||
*/
|
||||
fbi->res = res;
|
||||
fbi->mmio_base = ioremap(res->start, resource_size(res));
|
||||
fbi->mmio_base = devm_ioremap(&pdev->dev, res->start,
|
||||
resource_size(res));
|
||||
if (!fbi->mmio_base) {
|
||||
err = -ENXIO;
|
||||
goto failed_resource;
|
||||
@ -553,20 +554,20 @@ static int __devinit ep93xxfb_probe(struct platform_device *pdev)
|
||||
if (err == 0) {
|
||||
dev_err(info->dev, "No suitable video mode found\n");
|
||||
err = -EINVAL;
|
||||
goto failed_mode;
|
||||
goto failed_resource;
|
||||
}
|
||||
|
||||
if (mach_info->setup) {
|
||||
err = mach_info->setup(pdev);
|
||||
if (err)
|
||||
goto failed_mode;
|
||||
goto failed_resource;
|
||||
}
|
||||
|
||||
err = ep93xxfb_check_var(&info->var, info);
|
||||
if (err)
|
||||
goto failed_check;
|
||||
|
||||
fbi->clk = clk_get(info->dev, NULL);
|
||||
fbi->clk = devm_clk_get(&pdev->dev, NULL);
|
||||
if (IS_ERR(fbi->clk)) {
|
||||
err = PTR_ERR(fbi->clk);
|
||||
fbi->clk = NULL;
|
||||
@ -578,19 +579,15 @@ static int __devinit ep93xxfb_probe(struct platform_device *pdev)
|
||||
|
||||
err = register_framebuffer(info);
|
||||
if (err)
|
||||
goto failed;
|
||||
goto failed_check;
|
||||
|
||||
dev_info(info->dev, "registered. Mode = %dx%d-%d\n",
|
||||
info->var.xres, info->var.yres, info->var.bits_per_pixel);
|
||||
return 0;
|
||||
|
||||
failed:
|
||||
clk_put(fbi->clk);
|
||||
failed_check:
|
||||
if (fbi->mach_info->teardown)
|
||||
fbi->mach_info->teardown(pdev);
|
||||
failed_mode:
|
||||
iounmap(fbi->mmio_base);
|
||||
failed_resource:
|
||||
ep93xxfb_dealloc_videomem(info);
|
||||
failed_videomem:
|
||||
@ -609,8 +606,6 @@ static int __devexit ep93xxfb_remove(struct platform_device *pdev)
|
||||
|
||||
unregister_framebuffer(info);
|
||||
clk_disable(fbi->clk);
|
||||
clk_put(fbi->clk);
|
||||
iounmap(fbi->mmio_base);
|
||||
ep93xxfb_dealloc_videomem(info);
|
||||
fb_dealloc_cmap(&info->cmap);
|
||||
|
||||
|
@ -29,6 +29,9 @@ static int exynos_dp_init_dp(struct exynos_dp_device *dp)
|
||||
|
||||
exynos_dp_swreset(dp);
|
||||
|
||||
exynos_dp_init_analog_param(dp);
|
||||
exynos_dp_init_interrupt(dp);
|
||||
|
||||
/* SW defined function Normal operation */
|
||||
exynos_dp_enable_sw_function(dp);
|
||||
|
||||
@ -260,7 +263,7 @@ static void exynos_dp_set_lane_lane_pre_emphasis(struct exynos_dp_device *dp,
|
||||
|
||||
static void exynos_dp_link_start(struct exynos_dp_device *dp)
|
||||
{
|
||||
u8 buf[5];
|
||||
u8 buf[4];
|
||||
int lane;
|
||||
int lane_count;
|
||||
|
||||
@ -295,10 +298,10 @@ static void exynos_dp_link_start(struct exynos_dp_device *dp)
|
||||
exynos_dp_set_training_pattern(dp, TRAINING_PTN1);
|
||||
|
||||
/* Set RX training pattern */
|
||||
buf[0] = DPCD_SCRAMBLING_DISABLED |
|
||||
DPCD_TRAINING_PATTERN_1;
|
||||
exynos_dp_write_byte_to_dpcd(dp,
|
||||
DPCD_ADDR_TRAINING_PATTERN_SET, buf[0]);
|
||||
DPCD_ADDR_TRAINING_PATTERN_SET,
|
||||
DPCD_SCRAMBLING_DISABLED |
|
||||
DPCD_TRAINING_PATTERN_1);
|
||||
|
||||
for (lane = 0; lane < lane_count; lane++)
|
||||
buf[lane] = DPCD_PRE_EMPHASIS_PATTERN2_LEVEL0 |
|
||||
@ -308,7 +311,7 @@ static void exynos_dp_link_start(struct exynos_dp_device *dp)
|
||||
lane_count, buf);
|
||||
}
|
||||
|
||||
static unsigned char exynos_dp_get_lane_status(u8 link_status[6], int lane)
|
||||
static unsigned char exynos_dp_get_lane_status(u8 link_status[2], int lane)
|
||||
{
|
||||
int shift = (lane & 1) * 4;
|
||||
u8 link_value = link_status[lane>>1];
|
||||
@ -316,7 +319,7 @@ static unsigned char exynos_dp_get_lane_status(u8 link_status[6], int lane)
|
||||
return (link_value >> shift) & 0xf;
|
||||
}
|
||||
|
||||
static int exynos_dp_clock_recovery_ok(u8 link_status[6], int lane_count)
|
||||
static int exynos_dp_clock_recovery_ok(u8 link_status[2], int lane_count)
|
||||
{
|
||||
int lane;
|
||||
u8 lane_status;
|
||||
@ -329,22 +332,23 @@ static int exynos_dp_clock_recovery_ok(u8 link_status[6], int lane_count)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int exynos_dp_channel_eq_ok(u8 link_status[6], int lane_count)
|
||||
static int exynos_dp_channel_eq_ok(u8 link_align[3], int lane_count)
|
||||
{
|
||||
int lane;
|
||||
u8 lane_align;
|
||||
u8 lane_status;
|
||||
|
||||
lane_align = link_status[2];
|
||||
lane_align = link_align[2];
|
||||
if ((lane_align & DPCD_INTERLANE_ALIGN_DONE) == 0)
|
||||
return -EINVAL;
|
||||
|
||||
for (lane = 0; lane < lane_count; lane++) {
|
||||
lane_status = exynos_dp_get_lane_status(link_status, lane);
|
||||
lane_status = exynos_dp_get_lane_status(link_align, lane);
|
||||
lane_status &= DPCD_CHANNEL_EQ_BITS;
|
||||
if (lane_status != DPCD_CHANNEL_EQ_BITS)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -417,69 +421,17 @@ static unsigned int exynos_dp_get_lane_link_training(
|
||||
|
||||
static void exynos_dp_reduce_link_rate(struct exynos_dp_device *dp)
|
||||
{
|
||||
if (dp->link_train.link_rate == LINK_RATE_2_70GBPS) {
|
||||
/* set to reduced bit rate */
|
||||
dp->link_train.link_rate = LINK_RATE_1_62GBPS;
|
||||
dev_err(dp->dev, "set to bandwidth %.2x\n",
|
||||
dp->link_train.link_rate);
|
||||
dp->link_train.lt_state = START;
|
||||
} else {
|
||||
exynos_dp_training_pattern_dis(dp);
|
||||
/* set enhanced mode if available */
|
||||
exynos_dp_set_enhanced_mode(dp);
|
||||
dp->link_train.lt_state = FAILED;
|
||||
}
|
||||
}
|
||||
exynos_dp_training_pattern_dis(dp);
|
||||
exynos_dp_set_enhanced_mode(dp);
|
||||
|
||||
static void exynos_dp_get_adjust_train(struct exynos_dp_device *dp,
|
||||
u8 adjust_request[2])
|
||||
{
|
||||
int lane;
|
||||
int lane_count;
|
||||
u8 voltage_swing;
|
||||
u8 pre_emphasis;
|
||||
u8 training_lane;
|
||||
|
||||
lane_count = dp->link_train.lane_count;
|
||||
for (lane = 0; lane < lane_count; lane++) {
|
||||
voltage_swing = exynos_dp_get_adjust_request_voltage(
|
||||
adjust_request, lane);
|
||||
pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
|
||||
adjust_request, lane);
|
||||
training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) |
|
||||
DPCD_PRE_EMPHASIS_SET(pre_emphasis);
|
||||
|
||||
if (voltage_swing == VOLTAGE_LEVEL_3 ||
|
||||
pre_emphasis == PRE_EMPHASIS_LEVEL_3) {
|
||||
training_lane |= DPCD_MAX_SWING_REACHED;
|
||||
training_lane |= DPCD_MAX_PRE_EMPHASIS_REACHED;
|
||||
}
|
||||
dp->link_train.training_lane[lane] = training_lane;
|
||||
}
|
||||
}
|
||||
|
||||
static int exynos_dp_check_max_cr_loop(struct exynos_dp_device *dp,
|
||||
u8 voltage_swing)
|
||||
{
|
||||
int lane;
|
||||
int lane_count;
|
||||
|
||||
lane_count = dp->link_train.lane_count;
|
||||
for (lane = 0; lane < lane_count; lane++) {
|
||||
if (voltage_swing == VOLTAGE_LEVEL_3 ||
|
||||
dp->link_train.cr_loop[lane] == MAX_CR_LOOP)
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
dp->link_train.lt_state = FAILED;
|
||||
}
|
||||
|
||||
static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
|
||||
{
|
||||
u8 data;
|
||||
u8 link_status[6];
|
||||
u8 link_status[2];
|
||||
int lane;
|
||||
int lane_count;
|
||||
u8 buf[5];
|
||||
|
||||
u8 adjust_request[2];
|
||||
u8 voltage_swing;
|
||||
@ -488,100 +440,154 @@ static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
|
||||
|
||||
usleep_range(100, 101);
|
||||
|
||||
exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_LANE0_1_STATUS,
|
||||
6, link_status);
|
||||
lane_count = dp->link_train.lane_count;
|
||||
|
||||
exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_LANE0_1_STATUS,
|
||||
2, link_status);
|
||||
|
||||
if (exynos_dp_clock_recovery_ok(link_status, lane_count) == 0) {
|
||||
/* set training pattern 2 for EQ */
|
||||
exynos_dp_set_training_pattern(dp, TRAINING_PTN2);
|
||||
|
||||
adjust_request[0] = link_status[4];
|
||||
adjust_request[1] = link_status[5];
|
||||
|
||||
exynos_dp_get_adjust_train(dp, adjust_request);
|
||||
|
||||
buf[0] = DPCD_SCRAMBLING_DISABLED |
|
||||
DPCD_TRAINING_PATTERN_2;
|
||||
exynos_dp_write_byte_to_dpcd(dp,
|
||||
DPCD_ADDR_TRAINING_PATTERN_SET,
|
||||
buf[0]);
|
||||
|
||||
for (lane = 0; lane < lane_count; lane++) {
|
||||
exynos_dp_set_lane_link_training(dp,
|
||||
dp->link_train.training_lane[lane],
|
||||
lane);
|
||||
buf[lane] = dp->link_train.training_lane[lane];
|
||||
exynos_dp_write_byte_to_dpcd(dp,
|
||||
DPCD_ADDR_TRAINING_LANE0_SET + lane,
|
||||
buf[lane]);
|
||||
}
|
||||
dp->link_train.lt_state = EQUALIZER_TRAINING;
|
||||
} else {
|
||||
exynos_dp_read_byte_from_dpcd(dp,
|
||||
DPCD_ADDR_ADJUST_REQUEST_LANE0_1,
|
||||
&data);
|
||||
adjust_request[0] = data;
|
||||
|
||||
exynos_dp_read_byte_from_dpcd(dp,
|
||||
DPCD_ADDR_ADJUST_REQUEST_LANE2_3,
|
||||
&data);
|
||||
adjust_request[1] = data;
|
||||
|
||||
for (lane = 0; lane < lane_count; lane++) {
|
||||
training_lane = exynos_dp_get_lane_link_training(
|
||||
dp, lane);
|
||||
exynos_dp_read_bytes_from_dpcd(dp,
|
||||
DPCD_ADDR_ADJUST_REQUEST_LANE0_1,
|
||||
2, adjust_request);
|
||||
voltage_swing = exynos_dp_get_adjust_request_voltage(
|
||||
adjust_request, lane);
|
||||
pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
|
||||
adjust_request, lane);
|
||||
if ((DPCD_VOLTAGE_SWING_GET(training_lane) == voltage_swing) &&
|
||||
(DPCD_PRE_EMPHASIS_GET(training_lane) == pre_emphasis))
|
||||
dp->link_train.cr_loop[lane]++;
|
||||
training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) |
|
||||
DPCD_PRE_EMPHASIS_SET(pre_emphasis);
|
||||
|
||||
if (voltage_swing == VOLTAGE_LEVEL_3)
|
||||
training_lane |= DPCD_MAX_SWING_REACHED;
|
||||
if (pre_emphasis == PRE_EMPHASIS_LEVEL_3)
|
||||
training_lane |= DPCD_MAX_PRE_EMPHASIS_REACHED;
|
||||
|
||||
dp->link_train.training_lane[lane] = training_lane;
|
||||
|
||||
exynos_dp_set_lane_link_training(dp,
|
||||
dp->link_train.training_lane[lane],
|
||||
lane);
|
||||
}
|
||||
|
||||
if (exynos_dp_check_max_cr_loop(dp, voltage_swing) != 0) {
|
||||
exynos_dp_reduce_link_rate(dp);
|
||||
} else {
|
||||
exynos_dp_get_adjust_train(dp, adjust_request);
|
||||
exynos_dp_write_byte_to_dpcd(dp,
|
||||
DPCD_ADDR_TRAINING_PATTERN_SET,
|
||||
DPCD_SCRAMBLING_DISABLED |
|
||||
DPCD_TRAINING_PATTERN_2);
|
||||
|
||||
for (lane = 0; lane < lane_count; lane++) {
|
||||
exynos_dp_set_lane_link_training(dp,
|
||||
dp->link_train.training_lane[lane],
|
||||
lane);
|
||||
buf[lane] = dp->link_train.training_lane[lane];
|
||||
exynos_dp_write_byte_to_dpcd(dp,
|
||||
DPCD_ADDR_TRAINING_LANE0_SET + lane,
|
||||
buf[lane]);
|
||||
exynos_dp_write_bytes_to_dpcd(dp,
|
||||
DPCD_ADDR_TRAINING_LANE0_SET,
|
||||
lane_count,
|
||||
dp->link_train.training_lane);
|
||||
|
||||
dev_info(dp->dev, "Link Training Clock Recovery success\n");
|
||||
dp->link_train.lt_state = EQUALIZER_TRAINING;
|
||||
} else {
|
||||
for (lane = 0; lane < lane_count; lane++) {
|
||||
training_lane = exynos_dp_get_lane_link_training(
|
||||
dp, lane);
|
||||
exynos_dp_read_bytes_from_dpcd(dp,
|
||||
DPCD_ADDR_ADJUST_REQUEST_LANE0_1,
|
||||
2, adjust_request);
|
||||
voltage_swing = exynos_dp_get_adjust_request_voltage(
|
||||
adjust_request, lane);
|
||||
pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
|
||||
adjust_request, lane);
|
||||
|
||||
if (voltage_swing == VOLTAGE_LEVEL_3 ||
|
||||
pre_emphasis == PRE_EMPHASIS_LEVEL_3) {
|
||||
dev_err(dp->dev, "voltage or pre emphasis reached max level\n");
|
||||
goto reduce_link_rate;
|
||||
}
|
||||
|
||||
if ((DPCD_VOLTAGE_SWING_GET(training_lane) ==
|
||||
voltage_swing) &&
|
||||
(DPCD_PRE_EMPHASIS_GET(training_lane) ==
|
||||
pre_emphasis)) {
|
||||
dp->link_train.cr_loop[lane]++;
|
||||
if (dp->link_train.cr_loop[lane] == MAX_CR_LOOP) {
|
||||
dev_err(dp->dev, "CR Max loop\n");
|
||||
goto reduce_link_rate;
|
||||
}
|
||||
}
|
||||
|
||||
training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) |
|
||||
DPCD_PRE_EMPHASIS_SET(pre_emphasis);
|
||||
|
||||
if (voltage_swing == VOLTAGE_LEVEL_3)
|
||||
training_lane |= DPCD_MAX_SWING_REACHED;
|
||||
if (pre_emphasis == PRE_EMPHASIS_LEVEL_3)
|
||||
training_lane |= DPCD_MAX_PRE_EMPHASIS_REACHED;
|
||||
|
||||
dp->link_train.training_lane[lane] = training_lane;
|
||||
|
||||
exynos_dp_set_lane_link_training(dp,
|
||||
dp->link_train.training_lane[lane], lane);
|
||||
}
|
||||
|
||||
exynos_dp_write_bytes_to_dpcd(dp,
|
||||
DPCD_ADDR_TRAINING_LANE0_SET,
|
||||
lane_count,
|
||||
dp->link_train.training_lane);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
reduce_link_rate:
|
||||
exynos_dp_reduce_link_rate(dp);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)
|
||||
{
|
||||
u8 link_status[6];
|
||||
u8 link_status[2];
|
||||
u8 link_align[3];
|
||||
int lane;
|
||||
int lane_count;
|
||||
u8 buf[5];
|
||||
u32 reg;
|
||||
|
||||
u8 adjust_request[2];
|
||||
u8 voltage_swing;
|
||||
u8 pre_emphasis;
|
||||
u8 training_lane;
|
||||
|
||||
usleep_range(400, 401);
|
||||
|
||||
exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_LANE0_1_STATUS,
|
||||
6, link_status);
|
||||
lane_count = dp->link_train.lane_count;
|
||||
|
||||
if (exynos_dp_clock_recovery_ok(link_status, lane_count) == 0) {
|
||||
adjust_request[0] = link_status[4];
|
||||
adjust_request[1] = link_status[5];
|
||||
exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_LANE0_1_STATUS,
|
||||
2, link_status);
|
||||
|
||||
if (exynos_dp_channel_eq_ok(link_status, lane_count) == 0) {
|
||||
if (exynos_dp_clock_recovery_ok(link_status, lane_count) == 0) {
|
||||
link_align[0] = link_status[0];
|
||||
link_align[1] = link_status[1];
|
||||
|
||||
exynos_dp_read_byte_from_dpcd(dp,
|
||||
DPCD_ADDR_LANE_ALIGN_STATUS_UPDATED,
|
||||
&link_align[2]);
|
||||
|
||||
for (lane = 0; lane < lane_count; lane++) {
|
||||
exynos_dp_read_bytes_from_dpcd(dp,
|
||||
DPCD_ADDR_ADJUST_REQUEST_LANE0_1,
|
||||
2, adjust_request);
|
||||
voltage_swing = exynos_dp_get_adjust_request_voltage(
|
||||
adjust_request, lane);
|
||||
pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
|
||||
adjust_request, lane);
|
||||
training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) |
|
||||
DPCD_PRE_EMPHASIS_SET(pre_emphasis);
|
||||
|
||||
if (voltage_swing == VOLTAGE_LEVEL_3)
|
||||
training_lane |= DPCD_MAX_SWING_REACHED;
|
||||
if (pre_emphasis == PRE_EMPHASIS_LEVEL_3)
|
||||
training_lane |= DPCD_MAX_PRE_EMPHASIS_REACHED;
|
||||
|
||||
dp->link_train.training_lane[lane] = training_lane;
|
||||
}
|
||||
|
||||
if (exynos_dp_channel_eq_ok(link_align, lane_count) == 0) {
|
||||
/* traing pattern Set to Normal */
|
||||
exynos_dp_training_pattern_dis(dp);
|
||||
|
||||
@ -596,39 +602,42 @@ static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)
|
||||
dp->link_train.lane_count = reg;
|
||||
dev_dbg(dp->dev, "final lane count = %.2x\n",
|
||||
dp->link_train.lane_count);
|
||||
|
||||
/* set enhanced mode if available */
|
||||
exynos_dp_set_enhanced_mode(dp);
|
||||
|
||||
dp->link_train.lt_state = FINISHED;
|
||||
} else {
|
||||
/* not all locked */
|
||||
dp->link_train.eq_loop++;
|
||||
|
||||
if (dp->link_train.eq_loop > MAX_EQ_LOOP) {
|
||||
exynos_dp_reduce_link_rate(dp);
|
||||
} else {
|
||||
exynos_dp_get_adjust_train(dp, adjust_request);
|
||||
|
||||
for (lane = 0; lane < lane_count; lane++) {
|
||||
exynos_dp_set_lane_link_training(dp,
|
||||
dp->link_train.training_lane[lane],
|
||||
lane);
|
||||
buf[lane] = dp->link_train.training_lane[lane];
|
||||
exynos_dp_write_byte_to_dpcd(dp,
|
||||
DPCD_ADDR_TRAINING_LANE0_SET + lane,
|
||||
buf[lane]);
|
||||
}
|
||||
dev_err(dp->dev, "EQ Max loop\n");
|
||||
goto reduce_link_rate;
|
||||
}
|
||||
|
||||
for (lane = 0; lane < lane_count; lane++)
|
||||
exynos_dp_set_lane_link_training(dp,
|
||||
dp->link_train.training_lane[lane],
|
||||
lane);
|
||||
|
||||
exynos_dp_write_bytes_to_dpcd(dp,
|
||||
DPCD_ADDR_TRAINING_LANE0_SET,
|
||||
lane_count,
|
||||
dp->link_train.training_lane);
|
||||
}
|
||||
} else {
|
||||
exynos_dp_reduce_link_rate(dp);
|
||||
goto reduce_link_rate;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
reduce_link_rate:
|
||||
exynos_dp_reduce_link_rate(dp);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
static void exynos_dp_get_max_rx_bandwidth(struct exynos_dp_device *dp,
|
||||
u8 *bandwidth)
|
||||
u8 *bandwidth)
|
||||
{
|
||||
u8 data;
|
||||
|
||||
@ -641,7 +650,7 @@ static void exynos_dp_get_max_rx_bandwidth(struct exynos_dp_device *dp,
|
||||
}
|
||||
|
||||
static void exynos_dp_get_max_rx_lane_count(struct exynos_dp_device *dp,
|
||||
u8 *lane_count)
|
||||
u8 *lane_count)
|
||||
{
|
||||
u8 data;
|
||||
|
||||
@ -693,13 +702,7 @@ static void exynos_dp_init_training(struct exynos_dp_device *dp,
|
||||
static int exynos_dp_sw_link_training(struct exynos_dp_device *dp)
|
||||
{
|
||||
int retval = 0;
|
||||
int training_finished;
|
||||
|
||||
/* Turn off unnecessary lane */
|
||||
if (dp->link_train.lane_count == 1)
|
||||
exynos_dp_set_analog_power_down(dp, CH1_BLOCK, 1);
|
||||
|
||||
training_finished = 0;
|
||||
int training_finished = 0;
|
||||
|
||||
dp->link_train.lt_state = START;
|
||||
|
||||
@ -710,10 +713,14 @@ static int exynos_dp_sw_link_training(struct exynos_dp_device *dp)
|
||||
exynos_dp_link_start(dp);
|
||||
break;
|
||||
case CLOCK_RECOVERY:
|
||||
exynos_dp_process_clock_recovery(dp);
|
||||
retval = exynos_dp_process_clock_recovery(dp);
|
||||
if (retval)
|
||||
dev_err(dp->dev, "LT CR failed!\n");
|
||||
break;
|
||||
case EQUALIZER_TRAINING:
|
||||
exynos_dp_process_equalizer_training(dp);
|
||||
retval = exynos_dp_process_equalizer_training(dp);
|
||||
if (retval)
|
||||
dev_err(dp->dev, "LT EQ failed!\n");
|
||||
break;
|
||||
case FINISHED:
|
||||
training_finished = 1;
|
||||
@ -872,40 +879,33 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
|
||||
|
||||
dp->dev = &pdev->dev;
|
||||
|
||||
dp->clock = clk_get(&pdev->dev, "dp");
|
||||
dp->clock = devm_clk_get(&pdev->dev, "dp");
|
||||
if (IS_ERR(dp->clock)) {
|
||||
dev_err(&pdev->dev, "failed to get clock\n");
|
||||
return PTR_ERR(dp->clock);
|
||||
}
|
||||
|
||||
clk_enable(dp->clock);
|
||||
clk_prepare_enable(dp->clock);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res) {
|
||||
dev_err(&pdev->dev, "failed to get registers\n");
|
||||
ret = -EINVAL;
|
||||
goto err_clock;
|
||||
}
|
||||
|
||||
dp->reg_base = devm_request_and_ioremap(&pdev->dev, res);
|
||||
if (!dp->reg_base) {
|
||||
dev_err(&pdev->dev, "failed to ioremap\n");
|
||||
ret = -ENOMEM;
|
||||
goto err_clock;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
dp->irq = platform_get_irq(pdev, 0);
|
||||
if (!dp->irq) {
|
||||
dev_err(&pdev->dev, "failed to get irq\n");
|
||||
ret = -ENODEV;
|
||||
goto err_clock;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ret = devm_request_irq(&pdev->dev, dp->irq, exynos_dp_irq_handler, 0,
|
||||
"exynos-dp", dp);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to request irq\n");
|
||||
goto err_clock;
|
||||
return ret;
|
||||
}
|
||||
|
||||
dp->video_info = pdata->video_info;
|
||||
@ -917,7 +917,7 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
|
||||
ret = exynos_dp_detect_hpd(dp);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "unable to detect hpd\n");
|
||||
goto err_clock;
|
||||
return ret;
|
||||
}
|
||||
|
||||
exynos_dp_handle_edid(dp);
|
||||
@ -926,7 +926,7 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
|
||||
dp->video_info->link_rate);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "unable to do link train\n");
|
||||
goto err_clock;
|
||||
return ret;
|
||||
}
|
||||
|
||||
exynos_dp_enable_scramble(dp, 1);
|
||||
@ -940,17 +940,12 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
|
||||
ret = exynos_dp_config_video(dp, dp->video_info);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "unable to config video\n");
|
||||
goto err_clock;
|
||||
return ret;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, dp);
|
||||
|
||||
return 0;
|
||||
|
||||
err_clock:
|
||||
clk_put(dp->clock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __devexit exynos_dp_remove(struct platform_device *pdev)
|
||||
@ -961,8 +956,7 @@ static int __devexit exynos_dp_remove(struct platform_device *pdev)
|
||||
if (pdata && pdata->phy_exit)
|
||||
pdata->phy_exit();
|
||||
|
||||
clk_disable(dp->clock);
|
||||
clk_put(dp->clock);
|
||||
clk_disable_unprepare(dp->clock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -977,7 +971,7 @@ static int exynos_dp_suspend(struct device *dev)
|
||||
if (pdata && pdata->phy_exit)
|
||||
pdata->phy_exit();
|
||||
|
||||
clk_disable(dp->clock);
|
||||
clk_disable_unprepare(dp->clock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -991,7 +985,7 @@ static int exynos_dp_resume(struct device *dev)
|
||||
if (pdata && pdata->phy_init)
|
||||
pdata->phy_init();
|
||||
|
||||
clk_enable(dp->clock);
|
||||
clk_prepare_enable(dp->clock);
|
||||
|
||||
exynos_dp_init_dp(dp);
|
||||
|
||||
|
@ -43,7 +43,7 @@ void exynos_dp_init_interrupt(struct exynos_dp_device *dp);
|
||||
void exynos_dp_reset(struct exynos_dp_device *dp);
|
||||
void exynos_dp_swreset(struct exynos_dp_device *dp);
|
||||
void exynos_dp_config_interrupt(struct exynos_dp_device *dp);
|
||||
u32 exynos_dp_get_pll_lock_status(struct exynos_dp_device *dp);
|
||||
enum pll_status exynos_dp_get_pll_lock_status(struct exynos_dp_device *dp);
|
||||
void exynos_dp_set_pll_power_down(struct exynos_dp_device *dp, bool enable);
|
||||
void exynos_dp_set_analog_power_down(struct exynos_dp_device *dp,
|
||||
enum analog_power_block block,
|
||||
@ -105,7 +105,7 @@ u32 exynos_dp_get_lane1_link_training(struct exynos_dp_device *dp);
|
||||
u32 exynos_dp_get_lane2_link_training(struct exynos_dp_device *dp);
|
||||
u32 exynos_dp_get_lane3_link_training(struct exynos_dp_device *dp);
|
||||
void exynos_dp_reset_macro(struct exynos_dp_device *dp);
|
||||
int exynos_dp_init_video(struct exynos_dp_device *dp);
|
||||
void exynos_dp_init_video(struct exynos_dp_device *dp);
|
||||
|
||||
void exynos_dp_set_video_color_format(struct exynos_dp_device *dp,
|
||||
u32 color_depth,
|
||||
@ -144,7 +144,7 @@ void exynos_dp_disable_scrambling(struct exynos_dp_device *dp);
|
||||
#define DPCD_ADDR_TRAINING_PATTERN_SET 0x0102
|
||||
#define DPCD_ADDR_TRAINING_LANE0_SET 0x0103
|
||||
#define DPCD_ADDR_LANE0_1_STATUS 0x0202
|
||||
#define DPCD_ADDR_LANE_ALIGN__STATUS_UPDATED 0x0204
|
||||
#define DPCD_ADDR_LANE_ALIGN_STATUS_UPDATED 0x0204
|
||||
#define DPCD_ADDR_ADJUST_REQUEST_LANE0_1 0x0206
|
||||
#define DPCD_ADDR_ADJUST_REQUEST_LANE2_3 0x0207
|
||||
#define DPCD_ADDR_TEST_REQUEST 0x0218
|
||||
|
@ -77,7 +77,7 @@ void exynos_dp_init_analog_param(struct exynos_dp_device *dp)
|
||||
writel(reg, dp->reg_base + EXYNOS_DP_ANALOG_CTL_3);
|
||||
|
||||
reg = PD_RING_OSC | AUX_TERMINAL_CTRL_50_OHM |
|
||||
TX_CUR1_2X | TX_CUR_8_MA;
|
||||
TX_CUR1_2X | TX_CUR_16_MA;
|
||||
writel(reg, dp->reg_base + EXYNOS_DP_PLL_FILTER_CTL_1);
|
||||
|
||||
reg = CH3_AMP_400_MV | CH2_AMP_400_MV |
|
||||
@ -148,9 +148,6 @@ void exynos_dp_reset(struct exynos_dp_device *dp)
|
||||
writel(0x2, dp->reg_base + EXYNOS_DP_M_AUD_GEN_FILTER_TH);
|
||||
|
||||
writel(0x00000101, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL);
|
||||
|
||||
exynos_dp_init_analog_param(dp);
|
||||
exynos_dp_init_interrupt(dp);
|
||||
}
|
||||
|
||||
void exynos_dp_swreset(struct exynos_dp_device *dp)
|
||||
@ -179,7 +176,7 @@ void exynos_dp_config_interrupt(struct exynos_dp_device *dp)
|
||||
writel(reg, dp->reg_base + EXYNOS_DP_INT_STA_MASK);
|
||||
}
|
||||
|
||||
u32 exynos_dp_get_pll_lock_status(struct exynos_dp_device *dp)
|
||||
enum pll_status exynos_dp_get_pll_lock_status(struct exynos_dp_device *dp)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
@ -401,6 +398,7 @@ int exynos_dp_start_aux_transaction(struct exynos_dp_device *dp)
|
||||
{
|
||||
int reg;
|
||||
int retval = 0;
|
||||
int timeout_loop = 0;
|
||||
|
||||
/* Enable AUX CH operation */
|
||||
reg = readl(dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2);
|
||||
@ -409,8 +407,15 @@ int exynos_dp_start_aux_transaction(struct exynos_dp_device *dp)
|
||||
|
||||
/* Is AUX CH command reply received? */
|
||||
reg = readl(dp->reg_base + EXYNOS_DP_INT_STA);
|
||||
while (!(reg & RPLY_RECEIV))
|
||||
while (!(reg & RPLY_RECEIV)) {
|
||||
timeout_loop++;
|
||||
if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
|
||||
dev_err(dp->dev, "AUX CH command reply failed!\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
reg = readl(dp->reg_base + EXYNOS_DP_INT_STA);
|
||||
usleep_range(10, 11);
|
||||
}
|
||||
|
||||
/* Clear interrupt source for AUX CH command reply */
|
||||
writel(RPLY_RECEIV, dp->reg_base + EXYNOS_DP_INT_STA);
|
||||
@ -471,7 +476,8 @@ int exynos_dp_write_byte_to_dpcd(struct exynos_dp_device *dp,
|
||||
if (retval == 0)
|
||||
break;
|
||||
else
|
||||
dev_err(dp->dev, "Aux Transaction fail!\n");
|
||||
dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
|
||||
__func__);
|
||||
}
|
||||
|
||||
return retval;
|
||||
@ -511,7 +517,8 @@ int exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp,
|
||||
if (retval == 0)
|
||||
break;
|
||||
else
|
||||
dev_err(dp->dev, "Aux Transaction fail!\n");
|
||||
dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
|
||||
__func__);
|
||||
}
|
||||
|
||||
/* Read data buffer */
|
||||
@ -575,7 +582,8 @@ int exynos_dp_write_bytes_to_dpcd(struct exynos_dp_device *dp,
|
||||
if (retval == 0)
|
||||
break;
|
||||
else
|
||||
dev_err(dp->dev, "Aux Transaction fail!\n");
|
||||
dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
|
||||
__func__);
|
||||
}
|
||||
|
||||
start_offset += cur_data_count;
|
||||
@ -632,7 +640,8 @@ int exynos_dp_read_bytes_from_dpcd(struct exynos_dp_device *dp,
|
||||
if (retval == 0)
|
||||
break;
|
||||
else
|
||||
dev_err(dp->dev, "Aux Transaction fail!\n");
|
||||
dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
|
||||
__func__);
|
||||
}
|
||||
|
||||
for (cur_data_idx = 0; cur_data_idx < cur_data_count;
|
||||
@ -677,7 +686,7 @@ int exynos_dp_select_i2c_device(struct exynos_dp_device *dp,
|
||||
/* Start AUX transaction */
|
||||
retval = exynos_dp_start_aux_transaction(dp);
|
||||
if (retval != 0)
|
||||
dev_err(dp->dev, "Aux Transaction fail!\n");
|
||||
dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__);
|
||||
|
||||
return retval;
|
||||
}
|
||||
@ -717,7 +726,8 @@ int exynos_dp_read_byte_from_i2c(struct exynos_dp_device *dp,
|
||||
if (retval == 0)
|
||||
break;
|
||||
else
|
||||
dev_err(dp->dev, "Aux Transaction fail!\n");
|
||||
dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
|
||||
__func__);
|
||||
}
|
||||
|
||||
/* Read data */
|
||||
@ -777,7 +787,9 @@ int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp,
|
||||
if (retval == 0)
|
||||
break;
|
||||
else
|
||||
dev_err(dp->dev, "Aux Transaction fail!\n");
|
||||
dev_dbg(dp->dev,
|
||||
"%s: Aux Transaction fail!\n",
|
||||
__func__);
|
||||
}
|
||||
/* Check if Rx sends defer */
|
||||
reg = readl(dp->reg_base + EXYNOS_DP_AUX_RX_COMM);
|
||||
@ -883,7 +895,9 @@ void exynos_dp_set_lane0_pre_emphasis(struct exynos_dp_device *dp, u32 level)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
reg = level << PRE_EMPHASIS_SET_SHIFT;
|
||||
reg = readl(dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL);
|
||||
reg &= ~PRE_EMPHASIS_SET_MASK;
|
||||
reg |= level << PRE_EMPHASIS_SET_SHIFT;
|
||||
writel(reg, dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL);
|
||||
}
|
||||
|
||||
@ -891,7 +905,9 @@ void exynos_dp_set_lane1_pre_emphasis(struct exynos_dp_device *dp, u32 level)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
reg = level << PRE_EMPHASIS_SET_SHIFT;
|
||||
reg = readl(dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL);
|
||||
reg &= ~PRE_EMPHASIS_SET_MASK;
|
||||
reg |= level << PRE_EMPHASIS_SET_SHIFT;
|
||||
writel(reg, dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL);
|
||||
}
|
||||
|
||||
@ -899,7 +915,9 @@ void exynos_dp_set_lane2_pre_emphasis(struct exynos_dp_device *dp, u32 level)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
reg = level << PRE_EMPHASIS_SET_SHIFT;
|
||||
reg = readl(dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL);
|
||||
reg &= ~PRE_EMPHASIS_SET_MASK;
|
||||
reg |= level << PRE_EMPHASIS_SET_SHIFT;
|
||||
writel(reg, dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL);
|
||||
}
|
||||
|
||||
@ -907,7 +925,9 @@ void exynos_dp_set_lane3_pre_emphasis(struct exynos_dp_device *dp, u32 level)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
reg = level << PRE_EMPHASIS_SET_SHIFT;
|
||||
reg = readl(dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL);
|
||||
reg &= ~PRE_EMPHASIS_SET_MASK;
|
||||
reg |= level << PRE_EMPHASIS_SET_SHIFT;
|
||||
writel(reg, dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL);
|
||||
}
|
||||
|
||||
@ -994,7 +1014,7 @@ void exynos_dp_reset_macro(struct exynos_dp_device *dp)
|
||||
writel(reg, dp->reg_base + EXYNOS_DP_PHY_TEST);
|
||||
}
|
||||
|
||||
int exynos_dp_init_video(struct exynos_dp_device *dp)
|
||||
void exynos_dp_init_video(struct exynos_dp_device *dp)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
@ -1012,8 +1032,6 @@ int exynos_dp_init_video(struct exynos_dp_device *dp)
|
||||
|
||||
reg = VID_HRES_TH(2) | VID_VRES_TH(0);
|
||||
writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_8);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void exynos_dp_set_video_color_format(struct exynos_dp_device *dp,
|
||||
|
@ -187,7 +187,7 @@
|
||||
#define PD_RING_OSC (0x1 << 6)
|
||||
#define AUX_TERMINAL_CTRL_50_OHM (0x2 << 4)
|
||||
#define TX_CUR1_2X (0x1 << 2)
|
||||
#define TX_CUR_8_MA (0x2 << 0)
|
||||
#define TX_CUR_16_MA (0x3 << 0)
|
||||
|
||||
/* EXYNOS_DP_TX_AMP_TUNING_CTL */
|
||||
#define CH3_AMP_400_MV (0x0 << 24)
|
||||
@ -285,6 +285,7 @@
|
||||
#define SW_TRAINING_PATTERN_SET_NORMAL (0x0 << 0)
|
||||
|
||||
/* EXYNOS_DP_LN0_LINK_TRAINING_CTL */
|
||||
#define PRE_EMPHASIS_SET_MASK (0x3 << 3)
|
||||
#define PRE_EMPHASIS_SET_SHIFT (3)
|
||||
|
||||
/* EXYNOS_DP_DEBUG_CTL */
|
||||
|
@ -205,7 +205,8 @@ int exynos_mipi_dsi_register_lcd_device(struct mipi_dsim_lcd_device *lcd_dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct mipi_dsim_ddi *exynos_mipi_dsi_find_lcd_device(struct mipi_dsim_lcd_driver *lcd_drv)
|
||||
static struct mipi_dsim_ddi *exynos_mipi_dsi_find_lcd_device(
|
||||
struct mipi_dsim_lcd_driver *lcd_drv)
|
||||
{
|
||||
struct mipi_dsim_ddi *dsim_ddi, *next;
|
||||
struct mipi_dsim_lcd_device *lcd_dev;
|
||||
@ -265,7 +266,8 @@ int exynos_mipi_dsi_register_lcd_driver(struct mipi_dsim_lcd_driver *lcd_drv)
|
||||
|
||||
}
|
||||
|
||||
struct mipi_dsim_ddi *exynos_mipi_dsi_bind_lcd_ddi(struct mipi_dsim_device *dsim,
|
||||
static struct mipi_dsim_ddi *exynos_mipi_dsi_bind_lcd_ddi(
|
||||
struct mipi_dsim_device *dsim,
|
||||
const char *name)
|
||||
{
|
||||
struct mipi_dsim_ddi *dsim_ddi, *next;
|
||||
@ -373,6 +375,7 @@ static int exynos_mipi_dsi_probe(struct platform_device *pdev)
|
||||
dsim->clock = clk_get(&pdev->dev, "dsim0");
|
||||
if (IS_ERR(dsim->clock)) {
|
||||
dev_err(&pdev->dev, "failed to get dsim clock source\n");
|
||||
ret = -ENODEV;
|
||||
goto err_clock_get;
|
||||
}
|
||||
|
||||
@ -381,6 +384,7 @@ static int exynos_mipi_dsi_probe(struct platform_device *pdev)
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res) {
|
||||
dev_err(&pdev->dev, "failed to get io memory region\n");
|
||||
ret = -ENODEV;
|
||||
goto err_platform_get;
|
||||
}
|
||||
|
||||
@ -405,6 +409,7 @@ static int exynos_mipi_dsi_probe(struct platform_device *pdev)
|
||||
dsim_ddi = exynos_mipi_dsi_bind_lcd_ddi(dsim, dsim_pd->lcd_panel_name);
|
||||
if (!dsim_ddi) {
|
||||
dev_err(&pdev->dev, "mipi_dsim_ddi object not found.\n");
|
||||
ret = -EINVAL;
|
||||
goto err_bind;
|
||||
}
|
||||
|
||||
|
@ -79,11 +79,6 @@ irqreturn_t exynos_mipi_dsi_interrupt_handler(int irq, void *dev_id)
|
||||
struct mipi_dsim_device *dsim = dev_id;
|
||||
unsigned int intsrc, intmsk;
|
||||
|
||||
if (dsim == NULL) {
|
||||
dev_err(dsim->dev, "%s: wrong parameter\n", __func__);
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
intsrc = exynos_mipi_dsi_read_interrupt(dsim);
|
||||
intmsk = exynos_mipi_dsi_read_interrupt_mask(dsim);
|
||||
intmsk = ~intmsk & intsrc;
|
||||
@ -288,9 +283,6 @@ int exynos_mipi_dsi_wr_data(struct mipi_dsim_device *dsim, unsigned int data_id,
|
||||
mutex_unlock(&dsim->lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_unlock(&dsim->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int exynos_mipi_dsi_long_data_rd(struct mipi_dsim_device *dsim,
|
||||
|
@ -1501,8 +1501,8 @@ static int __devinit fsl_diu_probe(struct platform_device *pdev)
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
data = dma_alloc_coherent(&pdev->dev, sizeof(struct fsl_diu_data),
|
||||
&dma_addr, GFP_DMA | __GFP_ZERO);
|
||||
data = dmam_alloc_coherent(&pdev->dev, sizeof(struct fsl_diu_data),
|
||||
&dma_addr, GFP_DMA | __GFP_ZERO);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
data->dma_addr = dma_addr;
|
||||
@ -1628,9 +1628,6 @@ error:
|
||||
|
||||
iounmap(data->diu_reg);
|
||||
|
||||
dma_free_coherent(&pdev->dev, sizeof(struct fsl_diu_data), data,
|
||||
data->dma_addr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1648,9 +1645,6 @@ static int fsl_diu_remove(struct platform_device *pdev)
|
||||
|
||||
iounmap(data->diu_reg);
|
||||
|
||||
dma_free_coherent(&pdev->dev, sizeof(struct fsl_diu_data), data,
|
||||
data->dma_addr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
#include <asm/mtrr.h>
|
||||
@ -28,7 +29,6 @@
|
||||
#include <asm/addrspace.h>
|
||||
#endif
|
||||
#include <asm/byteorder.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/tlbflush.h>
|
||||
|
||||
#include <video/gbe.h>
|
||||
@ -1156,7 +1156,8 @@ static int __devinit gbefb_probe(struct platform_device *p_dev)
|
||||
goto out_release_framebuffer;
|
||||
}
|
||||
|
||||
gbe = (struct sgi_gbe *) ioremap(GBE_BASE, sizeof(struct sgi_gbe));
|
||||
gbe = (struct sgi_gbe *) devm_ioremap(&p_dev->dev, GBE_BASE,
|
||||
sizeof(struct sgi_gbe));
|
||||
if (!gbe) {
|
||||
printk(KERN_ERR "gbefb: couldn't map mmio region\n");
|
||||
ret = -ENXIO;
|
||||
@ -1170,12 +1171,13 @@ static int __devinit gbefb_probe(struct platform_device *p_dev)
|
||||
if (!gbe_tiles.cpu) {
|
||||
printk(KERN_ERR "gbefb: couldn't allocate tiles table\n");
|
||||
ret = -ENOMEM;
|
||||
goto out_unmap;
|
||||
goto out_release_mem_region;
|
||||
}
|
||||
|
||||
if (gbe_mem_phys) {
|
||||
/* memory was allocated at boot time */
|
||||
gbe_mem = ioremap_nocache(gbe_mem_phys, gbe_mem_size);
|
||||
gbe_mem = devm_ioremap_nocache(&p_dev->dev, gbe_mem_phys,
|
||||
gbe_mem_size);
|
||||
if (!gbe_mem) {
|
||||
printk(KERN_ERR "gbefb: couldn't map framebuffer\n");
|
||||
ret = -ENOMEM;
|
||||
@ -1241,13 +1243,9 @@ static int __devinit gbefb_probe(struct platform_device *p_dev)
|
||||
out_gbe_unmap:
|
||||
if (gbe_dma_addr)
|
||||
dma_free_coherent(NULL, gbe_mem_size, gbe_mem, gbe_mem_phys);
|
||||
else
|
||||
iounmap(gbe_mem);
|
||||
out_tiles_free:
|
||||
dma_free_coherent(NULL, GBE_TLB_SIZE * sizeof(uint16_t),
|
||||
(void *)gbe_tiles.cpu, gbe_tiles.dma);
|
||||
out_unmap:
|
||||
iounmap(gbe);
|
||||
out_release_mem_region:
|
||||
release_mem_region(GBE_BASE, sizeof(struct sgi_gbe));
|
||||
out_release_framebuffer:
|
||||
@ -1264,12 +1262,9 @@ static int __devexit gbefb_remove(struct platform_device* p_dev)
|
||||
gbe_turn_off();
|
||||
if (gbe_dma_addr)
|
||||
dma_free_coherent(NULL, gbe_mem_size, gbe_mem, gbe_mem_phys);
|
||||
else
|
||||
iounmap(gbe_mem);
|
||||
dma_free_coherent(NULL, GBE_TLB_SIZE * sizeof(uint16_t),
|
||||
(void *)gbe_tiles.cpu, gbe_tiles.dma);
|
||||
release_mem_region(GBE_BASE, sizeof(struct sgi_gbe));
|
||||
iounmap(gbe);
|
||||
gbefb_remove_sysfs(&p_dev->dev);
|
||||
framebuffer_release(info);
|
||||
|
||||
|
@ -210,6 +210,7 @@ static int __devinit hpfb_init_one(unsigned long phys_base,
|
||||
unsigned long virt_base)
|
||||
{
|
||||
unsigned long fboff, fb_width, fb_height, fb_start;
|
||||
int ret;
|
||||
|
||||
fb_regs = virt_base;
|
||||
fboff = (in_8(fb_regs + HPFB_FBOMSB) << 8) | in_8(fb_regs + HPFB_FBOLSB);
|
||||
@ -290,19 +291,29 @@ static int __devinit hpfb_init_one(unsigned long phys_base,
|
||||
fb_info.var = hpfb_defined;
|
||||
fb_info.screen_base = (char *)fb_start;
|
||||
|
||||
fb_alloc_cmap(&fb_info.cmap, 1 << hpfb_defined.bits_per_pixel, 0);
|
||||
ret = fb_alloc_cmap(&fb_info.cmap, 1 << hpfb_defined.bits_per_pixel, 0);
|
||||
if (ret < 0)
|
||||
goto unmap_screen_base;
|
||||
|
||||
if (register_framebuffer(&fb_info) < 0) {
|
||||
fb_dealloc_cmap(&fb_info.cmap);
|
||||
iounmap(fb_info.screen_base);
|
||||
fb_info.screen_base = NULL;
|
||||
return 1;
|
||||
}
|
||||
ret = register_framebuffer(&fb_info);
|
||||
if (ret < 0)
|
||||
goto dealloc_cmap;
|
||||
|
||||
printk(KERN_INFO "fb%d: %s frame buffer device\n",
|
||||
fb_info.node, fb_info.fix.id);
|
||||
|
||||
return 0;
|
||||
|
||||
dealloc_cmap:
|
||||
fb_dealloc_cmap(&fb_info.cmap);
|
||||
|
||||
unmap_screen_base:
|
||||
if (fb_info.screen_base) {
|
||||
iounmap(fb_info.screen_base);
|
||||
fb_info.screen_base = NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -345,6 +356,9 @@ static void __devexit hpfb_remove_one(struct dio_dev *d)
|
||||
if (d->scode >= DIOII_SCBASE)
|
||||
iounmap((void *)fb_regs);
|
||||
release_mem_region(d->resource.start, resource_size(&d->resource));
|
||||
fb_dealloc_cmap(&fb_info.cmap);
|
||||
if (fb_info.screen_base)
|
||||
iounmap(fb_info.screen_base);
|
||||
}
|
||||
|
||||
static struct dio_device_id hpfb_dio_tbl[] = {
|
||||
|
@ -803,6 +803,7 @@ static int __init imxfb_probe(struct platform_device *pdev)
|
||||
fbi->regs = ioremap(res->start, resource_size(res));
|
||||
if (fbi->regs == NULL) {
|
||||
dev_err(&pdev->dev, "Cannot map frame buffer registers\n");
|
||||
ret = -ENOMEM;
|
||||
goto failed_ioremap;
|
||||
}
|
||||
|
||||
|
@ -632,23 +632,10 @@ static int __devinit jzfb_probe(struct platform_device *pdev)
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!mem) {
|
||||
dev_err(&pdev->dev, "Failed to get register memory resource\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
mem = request_mem_region(mem->start, resource_size(mem), pdev->name);
|
||||
if (!mem) {
|
||||
dev_err(&pdev->dev, "Failed to request register memory region\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
fb = framebuffer_alloc(sizeof(struct jzfb), &pdev->dev);
|
||||
if (!fb) {
|
||||
dev_err(&pdev->dev, "Failed to allocate framebuffer device\n");
|
||||
ret = -ENOMEM;
|
||||
goto err_release_mem_region;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
fb->fbops = &jzfb_ops;
|
||||
@ -657,27 +644,26 @@ static int __devinit jzfb_probe(struct platform_device *pdev)
|
||||
jzfb = fb->par;
|
||||
jzfb->pdev = pdev;
|
||||
jzfb->pdata = pdata;
|
||||
jzfb->mem = mem;
|
||||
|
||||
jzfb->ldclk = clk_get(&pdev->dev, "lcd");
|
||||
jzfb->ldclk = devm_clk_get(&pdev->dev, "lcd");
|
||||
if (IS_ERR(jzfb->ldclk)) {
|
||||
ret = PTR_ERR(jzfb->ldclk);
|
||||
dev_err(&pdev->dev, "Failed to get lcd clock: %d\n", ret);
|
||||
goto err_framebuffer_release;
|
||||
}
|
||||
|
||||
jzfb->lpclk = clk_get(&pdev->dev, "lcd_pclk");
|
||||
jzfb->lpclk = devm_clk_get(&pdev->dev, "lcd_pclk");
|
||||
if (IS_ERR(jzfb->lpclk)) {
|
||||
ret = PTR_ERR(jzfb->lpclk);
|
||||
dev_err(&pdev->dev, "Failed to get lcd pixel clock: %d\n", ret);
|
||||
goto err_put_ldclk;
|
||||
goto err_framebuffer_release;
|
||||
}
|
||||
|
||||
jzfb->base = ioremap(mem->start, resource_size(mem));
|
||||
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
jzfb->base = devm_request_and_ioremap(&pdev->dev, mem);
|
||||
if (!jzfb->base) {
|
||||
dev_err(&pdev->dev, "Failed to ioremap register memory region\n");
|
||||
ret = -EBUSY;
|
||||
goto err_put_lpclk;
|
||||
goto err_framebuffer_release;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, jzfb);
|
||||
@ -693,7 +679,7 @@ static int __devinit jzfb_probe(struct platform_device *pdev)
|
||||
ret = jzfb_alloc_devmem(jzfb);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Failed to allocate video memory\n");
|
||||
goto err_iounmap;
|
||||
goto err_framebuffer_release;
|
||||
}
|
||||
|
||||
fb->fix = jzfb_fix;
|
||||
@ -734,16 +720,8 @@ err_free_devmem:
|
||||
|
||||
fb_dealloc_cmap(&fb->cmap);
|
||||
jzfb_free_devmem(jzfb);
|
||||
err_iounmap:
|
||||
iounmap(jzfb->base);
|
||||
err_put_lpclk:
|
||||
clk_put(jzfb->lpclk);
|
||||
err_put_ldclk:
|
||||
clk_put(jzfb->ldclk);
|
||||
err_framebuffer_release:
|
||||
framebuffer_release(fb);
|
||||
err_release_mem_region:
|
||||
release_mem_region(mem->start, resource_size(mem));
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -756,17 +734,11 @@ static int __devexit jzfb_remove(struct platform_device *pdev)
|
||||
jz_gpio_bulk_free(jz_lcd_ctrl_pins, jzfb_num_ctrl_pins(jzfb));
|
||||
jz_gpio_bulk_free(jz_lcd_data_pins, jzfb_num_data_pins(jzfb));
|
||||
|
||||
iounmap(jzfb->base);
|
||||
release_mem_region(jzfb->mem->start, resource_size(jzfb->mem));
|
||||
|
||||
fb_dealloc_cmap(&jzfb->fb->cmap);
|
||||
jzfb_free_devmem(jzfb);
|
||||
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
|
||||
clk_put(jzfb->lpclk);
|
||||
clk_put(jzfb->ldclk);
|
||||
|
||||
framebuffer_release(jzfb->fb);
|
||||
|
||||
return 0;
|
||||
|
@ -1052,12 +1052,14 @@ static int __devinit mb862xx_pci_probe(struct pci_dev *pdev,
|
||||
break;
|
||||
default:
|
||||
/* should never occur */
|
||||
ret = -EIO;
|
||||
goto rel_reg;
|
||||
}
|
||||
|
||||
par->fb_base = ioremap(par->fb_base_phys, par->mapped_vram);
|
||||
if (par->fb_base == NULL) {
|
||||
dev_err(dev, "Cannot map framebuffer\n");
|
||||
ret = -EIO;
|
||||
goto rel_reg;
|
||||
}
|
||||
|
||||
@ -1073,11 +1075,13 @@ static int __devinit mb862xx_pci_probe(struct pci_dev *pdev,
|
||||
dev_dbg(dev, "mmio phys 0x%llx 0x%lx\n",
|
||||
(unsigned long long)par->mmio_base_phys, (ulong)par->mmio_len);
|
||||
|
||||
if (mb862xx_pci_gdc_init(par))
|
||||
ret = mb862xx_pci_gdc_init(par);
|
||||
if (ret)
|
||||
goto io_unmap;
|
||||
|
||||
if (request_irq(par->irq, mb862xx_intr, IRQF_SHARED,
|
||||
DRV_NAME, (void *)par)) {
|
||||
ret = request_irq(par->irq, mb862xx_intr, IRQF_SHARED,
|
||||
DRV_NAME, (void *)par);
|
||||
if (ret) {
|
||||
dev_err(dev, "Cannot request irq\n");
|
||||
goto io_unmap;
|
||||
}
|
||||
|
@ -26,8 +26,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <video/mbxfb.h>
|
||||
|
||||
@ -939,8 +938,9 @@ static int __devinit mbxfb_probe(struct platform_device *dev)
|
||||
}
|
||||
mfbi->reg_phys_addr = mfbi->reg_res->start;
|
||||
|
||||
mfbi->reg_virt_addr = ioremap_nocache(mfbi->reg_phys_addr,
|
||||
res_size(mfbi->reg_req));
|
||||
mfbi->reg_virt_addr = devm_ioremap_nocache(&dev->dev,
|
||||
mfbi->reg_phys_addr,
|
||||
res_size(mfbi->reg_req));
|
||||
if (!mfbi->reg_virt_addr) {
|
||||
dev_err(&dev->dev, "failed to ioremap Marathon registers\n");
|
||||
ret = -EINVAL;
|
||||
@ -948,12 +948,12 @@ static int __devinit mbxfb_probe(struct platform_device *dev)
|
||||
}
|
||||
virt_base_2700 = mfbi->reg_virt_addr;
|
||||
|
||||
mfbi->fb_virt_addr = ioremap_nocache(mfbi->fb_phys_addr,
|
||||
res_size(mfbi->fb_req));
|
||||
mfbi->fb_virt_addr = devm_ioremap_nocache(&dev->dev, mfbi->fb_phys_addr,
|
||||
res_size(mfbi->fb_req));
|
||||
if (!mfbi->fb_virt_addr) {
|
||||
dev_err(&dev->dev, "failed to ioremap frame buffer\n");
|
||||
ret = -EINVAL;
|
||||
goto err4;
|
||||
goto err3;
|
||||
}
|
||||
|
||||
fbi->screen_base = (char __iomem *)(mfbi->fb_virt_addr + 0x60000);
|
||||
@ -971,7 +971,7 @@ static int __devinit mbxfb_probe(struct platform_device *dev)
|
||||
if (ret < 0) {
|
||||
dev_err(&dev->dev, "fb_alloc_cmap failed\n");
|
||||
ret = -EINVAL;
|
||||
goto err5;
|
||||
goto err3;
|
||||
}
|
||||
|
||||
platform_set_drvdata(dev, fbi);
|
||||
@ -996,10 +996,6 @@ static int __devinit mbxfb_probe(struct platform_device *dev)
|
||||
|
||||
err6:
|
||||
fb_dealloc_cmap(&fbi->cmap);
|
||||
err5:
|
||||
iounmap(mfbi->fb_virt_addr);
|
||||
err4:
|
||||
iounmap(mfbi->reg_virt_addr);
|
||||
err3:
|
||||
release_mem_region(mfbi->reg_res->start, res_size(mfbi->reg_res));
|
||||
err2:
|
||||
@ -1026,10 +1022,7 @@ static int __devexit mbxfb_remove(struct platform_device *dev)
|
||||
if (mfbi->platform_remove)
|
||||
mfbi->platform_remove(fbi);
|
||||
|
||||
if (mfbi->fb_virt_addr)
|
||||
iounmap(mfbi->fb_virt_addr);
|
||||
if (mfbi->reg_virt_addr)
|
||||
iounmap(mfbi->reg_virt_addr);
|
||||
|
||||
if (mfbi->reg_req)
|
||||
release_mem_region(mfbi->reg_req->start,
|
||||
res_size(mfbi->reg_req));
|
||||
|
@ -26,9 +26,6 @@
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/sched.h>
|
||||
#include <mach/msm_iomap.h>
|
||||
#include <mach/irqs.h>
|
||||
#include <mach/board.h>
|
||||
#include <linux/platform_data/video-msm_fb.h>
|
||||
#include "mddi_hw.h"
|
||||
|
||||
|
@ -189,8 +189,9 @@ static int mddi_nt35399_probe(struct platform_device *pdev)
|
||||
|
||||
int ret;
|
||||
|
||||
struct panel_info *panel = kzalloc(sizeof(struct panel_info),
|
||||
GFP_KERNEL);
|
||||
struct panel_info *panel = devm_kzalloc(&pdev->dev,
|
||||
sizeof(struct panel_info),
|
||||
GFP_KERNEL);
|
||||
|
||||
printk(KERN_DEBUG "%s: enter.\n", __func__);
|
||||
|
||||
@ -233,7 +234,6 @@ static int mddi_nt35399_remove(struct platform_device *pdev)
|
||||
struct panel_info *panel = platform_get_drvdata(pdev);
|
||||
|
||||
setup_vsync(panel, 0);
|
||||
kfree(panel);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,6 @@
|
||||
#include <linux/major.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <mach/msm_iomap.h>
|
||||
#include <linux/platform_data/video-msm_fb.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/export.h>
|
||||
|
@ -15,7 +15,6 @@
|
||||
#ifndef _MDP_HW_H_
|
||||
#define _MDP_HW_H_
|
||||
|
||||
#include <mach/msm_iomap.h>
|
||||
#include <linux/platform_data/video-msm_fb.h>
|
||||
|
||||
struct mdp_info {
|
||||
|
@ -1568,7 +1568,8 @@ static int mx3fb_remove(struct platform_device *dev)
|
||||
|
||||
static struct platform_driver mx3fb_driver = {
|
||||
.driver = {
|
||||
.name = MX3FB_NAME,
|
||||
.name = MX3FB_NAME,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = mx3fb_probe,
|
||||
.remove = mx3fb_remove,
|
||||
|
@ -387,7 +387,7 @@ static int nuc900fb_init_registers(struct fb_info *info)
|
||||
* The buffer should be a non-cached, non-buffered, memory region
|
||||
* to allow palette and pixel writes without flushing the cache.
|
||||
*/
|
||||
static int __init nuc900fb_map_video_memory(struct fb_info *info)
|
||||
static int __devinit nuc900fb_map_video_memory(struct fb_info *info)
|
||||
{
|
||||
struct nuc900fb_info *fbi = info->par;
|
||||
dma_addr_t map_dma;
|
||||
|
@ -27,7 +27,6 @@
|
||||
#include <linux/clk.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include <plat/dma.h>
|
||||
#include "omapfb.h"
|
||||
|
||||
#define HWA742_REV_CODE_REG 0x0
|
||||
|
@ -23,7 +23,6 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <plat/fpga.h>
|
||||
#include "omapfb.h"
|
||||
|
||||
static int palmte_panel_init(struct lcd_panel *panel,
|
||||
|
@ -131,15 +131,6 @@ static void omapfb_rqueue_unlock(struct omapfb_device *fbdev)
|
||||
* LCD controller and LCD DMA
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
/* Lookup table to map elem size to elem type. */
|
||||
static const int dma_elem_type[] = {
|
||||
0,
|
||||
OMAP_DMA_DATA_TYPE_S8,
|
||||
OMAP_DMA_DATA_TYPE_S16,
|
||||
0,
|
||||
OMAP_DMA_DATA_TYPE_S32,
|
||||
};
|
||||
|
||||
/*
|
||||
* Allocate resources needed for LCD controller and LCD DMA operations. Video
|
||||
* memory is allocated from system memory according to the virtual display
|
||||
|
@ -600,6 +600,9 @@ static int acx_panel_power_on(struct omap_dss_device *dssdev)
|
||||
|
||||
mutex_lock(&md->mutex);
|
||||
|
||||
omapdss_sdi_set_timings(dssdev, &dssdev->panel.timings);
|
||||
omapdss_sdi_set_datapairs(dssdev, dssdev->phy.sdi.datapairs);
|
||||
|
||||
r = omapdss_sdi_display_enable(dssdev);
|
||||
if (r) {
|
||||
pr_err("%s sdi enable failed\n", __func__);
|
||||
@ -731,18 +734,9 @@ static int acx_panel_resume(struct omap_dss_device *dssdev)
|
||||
static void acx_panel_set_timings(struct omap_dss_device *dssdev,
|
||||
struct omap_video_timings *timings)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
|
||||
omapdss_sdi_display_disable(dssdev);
|
||||
omapdss_sdi_set_timings(dssdev, timings);
|
||||
|
||||
dssdev->panel.timings = *timings;
|
||||
|
||||
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
|
||||
r = omapdss_sdi_display_enable(dssdev);
|
||||
if (r)
|
||||
dev_err(&dssdev->dev, "%s enable failed\n", __func__);
|
||||
}
|
||||
}
|
||||
|
||||
static int acx_panel_check_timings(struct omap_dss_device *dssdev,
|
||||
|
@ -545,6 +545,8 @@ struct panel_drv_data {
|
||||
struct omap_dss_device *dssdev;
|
||||
|
||||
struct panel_config *panel_config;
|
||||
|
||||
struct mutex lock;
|
||||
};
|
||||
|
||||
static inline struct panel_generic_dpi_data
|
||||
@ -563,6 +565,9 @@ static int generic_dpi_panel_power_on(struct omap_dss_device *dssdev)
|
||||
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
|
||||
return 0;
|
||||
|
||||
omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
|
||||
omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
|
||||
|
||||
r = omapdss_dpi_display_enable(dssdev);
|
||||
if (r)
|
||||
goto err0;
|
||||
@ -634,6 +639,8 @@ static int generic_dpi_panel_probe(struct omap_dss_device *dssdev)
|
||||
drv_data->dssdev = dssdev;
|
||||
drv_data->panel_config = panel_config;
|
||||
|
||||
mutex_init(&drv_data->lock);
|
||||
|
||||
dev_set_drvdata(&dssdev->dev, drv_data);
|
||||
|
||||
return 0;
|
||||
@ -652,56 +659,108 @@ static void __exit generic_dpi_panel_remove(struct omap_dss_device *dssdev)
|
||||
|
||||
static int generic_dpi_panel_enable(struct omap_dss_device *dssdev)
|
||||
{
|
||||
int r = 0;
|
||||
struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
|
||||
int r;
|
||||
|
||||
mutex_lock(&drv_data->lock);
|
||||
|
||||
r = generic_dpi_panel_power_on(dssdev);
|
||||
if (r)
|
||||
return r;
|
||||
goto err;
|
||||
|
||||
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
|
||||
err:
|
||||
mutex_unlock(&drv_data->lock);
|
||||
|
||||
return 0;
|
||||
return r;
|
||||
}
|
||||
|
||||
static void generic_dpi_panel_disable(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
|
||||
|
||||
mutex_lock(&drv_data->lock);
|
||||
|
||||
generic_dpi_panel_power_off(dssdev);
|
||||
|
||||
dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
|
||||
|
||||
mutex_unlock(&drv_data->lock);
|
||||
}
|
||||
|
||||
static int generic_dpi_panel_suspend(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
|
||||
|
||||
mutex_lock(&drv_data->lock);
|
||||
|
||||
generic_dpi_panel_power_off(dssdev);
|
||||
|
||||
dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
|
||||
|
||||
mutex_unlock(&drv_data->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int generic_dpi_panel_resume(struct omap_dss_device *dssdev)
|
||||
{
|
||||
int r = 0;
|
||||
struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
|
||||
int r;
|
||||
|
||||
mutex_lock(&drv_data->lock);
|
||||
|
||||
r = generic_dpi_panel_power_on(dssdev);
|
||||
if (r)
|
||||
return r;
|
||||
goto err;
|
||||
|
||||
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
|
||||
|
||||
return 0;
|
||||
err:
|
||||
mutex_unlock(&drv_data->lock);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static void generic_dpi_panel_set_timings(struct omap_dss_device *dssdev,
|
||||
struct omap_video_timings *timings)
|
||||
{
|
||||
dpi_set_timings(dssdev, timings);
|
||||
struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
|
||||
|
||||
mutex_lock(&drv_data->lock);
|
||||
|
||||
omapdss_dpi_set_timings(dssdev, timings);
|
||||
|
||||
dssdev->panel.timings = *timings;
|
||||
|
||||
mutex_unlock(&drv_data->lock);
|
||||
}
|
||||
|
||||
static void generic_dpi_panel_get_timings(struct omap_dss_device *dssdev,
|
||||
struct omap_video_timings *timings)
|
||||
{
|
||||
struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
|
||||
|
||||
mutex_lock(&drv_data->lock);
|
||||
|
||||
*timings = dssdev->panel.timings;
|
||||
|
||||
mutex_unlock(&drv_data->lock);
|
||||
}
|
||||
|
||||
static int generic_dpi_panel_check_timings(struct omap_dss_device *dssdev,
|
||||
struct omap_video_timings *timings)
|
||||
{
|
||||
return dpi_check_timings(dssdev, timings);
|
||||
struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
|
||||
int r;
|
||||
|
||||
mutex_lock(&drv_data->lock);
|
||||
|
||||
r = dpi_check_timings(dssdev, timings);
|
||||
|
||||
mutex_unlock(&drv_data->lock);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static struct omap_dss_driver dpi_driver = {
|
||||
@ -714,6 +773,7 @@ static struct omap_dss_driver dpi_driver = {
|
||||
.resume = generic_dpi_panel_resume,
|
||||
|
||||
.set_timings = generic_dpi_panel_set_timings,
|
||||
.get_timings = generic_dpi_panel_get_timings,
|
||||
.check_timings = generic_dpi_panel_check_timings,
|
||||
|
||||
.driver = {
|
||||
|
@ -55,6 +55,9 @@ static int lb035q02_panel_power_on(struct omap_dss_device *dssdev)
|
||||
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
|
||||
return 0;
|
||||
|
||||
omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
|
||||
omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
|
||||
|
||||
r = omapdss_dpi_display_enable(dssdev);
|
||||
if (r)
|
||||
goto err0;
|
||||
|
@ -150,11 +150,17 @@ static void blizzard_ctrl_setup_update(struct omap_dss_device *dssdev,
|
||||
BLIZZARD_SRC_WRITE_LCD :
|
||||
BLIZZARD_SRC_WRITE_LCD_DESTRUCTIVE;
|
||||
|
||||
omap_rfbi_configure(dssdev, 16, 8);
|
||||
omapdss_rfbi_set_pixel_size(dssdev, 16);
|
||||
omapdss_rfbi_set_data_lines(dssdev, 8);
|
||||
|
||||
omap_rfbi_configure(dssdev);
|
||||
|
||||
blizzard_write(BLIZZARD_INPUT_WIN_X_START_0, tmp, 18);
|
||||
|
||||
omap_rfbi_configure(dssdev, 16, 16);
|
||||
omapdss_rfbi_set_pixel_size(dssdev, 16);
|
||||
omapdss_rfbi_set_data_lines(dssdev, 16);
|
||||
|
||||
omap_rfbi_configure(dssdev);
|
||||
}
|
||||
|
||||
static void mipid_transfer(struct spi_device *spi, int cmd, const u8 *wbuf,
|
||||
@ -297,6 +303,12 @@ static int n8x0_panel_power_on(struct omap_dss_device *dssdev)
|
||||
goto err_plat_en;
|
||||
}
|
||||
|
||||
omapdss_rfbi_set_size(dssdev, dssdev->panel.timings.x_res,
|
||||
dssdev->panel.timings.y_res);
|
||||
omapdss_rfbi_set_pixel_size(dssdev, dssdev->ctrl.pixel_size);
|
||||
omapdss_rfbi_set_data_lines(dssdev, dssdev->phy.rfbi.data_lines);
|
||||
omapdss_rfbi_set_interface_timings(dssdev, &dssdev->ctrl.rfbi_timings);
|
||||
|
||||
r = omapdss_rfbi_display_enable(dssdev);
|
||||
if (r)
|
||||
goto err_rfbi_en;
|
||||
@ -477,6 +489,7 @@ static int n8x0_panel_probe(struct omap_dss_device *dssdev)
|
||||
dssdev->panel.timings.y_res = 480;
|
||||
dssdev->ctrl.pixel_size = 16;
|
||||
dssdev->ctrl.rfbi_timings = n8x0_panel_timings;
|
||||
dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
|
||||
|
||||
memset(&props, 0, sizeof(props));
|
||||
props.max_brightness = 127;
|
||||
@ -625,17 +638,25 @@ static int n8x0_panel_update(struct omap_dss_device *dssdev,
|
||||
u16 x, u16 y, u16 w, u16 h)
|
||||
{
|
||||
struct panel_drv_data *ddata = get_drv_data(dssdev);
|
||||
u16 dw, dh;
|
||||
|
||||
dev_dbg(&dssdev->dev, "update\n");
|
||||
|
||||
dw = dssdev->panel.timings.x_res;
|
||||
dh = dssdev->panel.timings.y_res;
|
||||
|
||||
if (x != 0 || y != 0 || w != dw || h != dh) {
|
||||
dev_err(&dssdev->dev, "invaid update region %d, %d, %d, %d\n",
|
||||
x, y, w, h);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_lock(&ddata->lock);
|
||||
rfbi_bus_lock();
|
||||
|
||||
omap_rfbi_prepare_update(dssdev, &x, &y, &w, &h);
|
||||
|
||||
blizzard_ctrl_setup_update(dssdev, x, y, w, h);
|
||||
|
||||
omap_rfbi_update(dssdev, x, y, w, h, update_done, NULL);
|
||||
omap_rfbi_update(dssdev, update_done, NULL);
|
||||
|
||||
mutex_unlock(&ddata->lock);
|
||||
|
||||
|
@ -175,6 +175,9 @@ static int nec_8048_panel_power_on(struct omap_dss_device *dssdev)
|
||||
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
|
||||
return 0;
|
||||
|
||||
omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
|
||||
omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
|
||||
|
||||
r = omapdss_dpi_display_enable(dssdev);
|
||||
if (r)
|
||||
goto err0;
|
||||
|
@ -377,6 +377,10 @@ static int picodlp_panel_power_on(struct omap_dss_device *dssdev)
|
||||
* then only i2c commands can be successfully sent to dpp2600
|
||||
*/
|
||||
msleep(1000);
|
||||
|
||||
omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
|
||||
omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
|
||||
|
||||
r = omapdss_dpi_display_enable(dssdev);
|
||||
if (r) {
|
||||
dev_err(&dssdev->dev, "failed to enable DPI\n");
|
||||
|
@ -142,6 +142,9 @@ static int sharp_ls_power_on(struct omap_dss_device *dssdev)
|
||||
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
|
||||
return 0;
|
||||
|
||||
omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
|
||||
omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
|
||||
|
||||
r = omapdss_dpi_display_enable(dssdev);
|
||||
if (r)
|
||||
goto err0;
|
||||
|
@ -121,6 +121,18 @@ struct taal_data {
|
||||
|
||||
struct omap_dss_device *dssdev;
|
||||
|
||||
/* panel specific HW info */
|
||||
struct panel_config *panel_config;
|
||||
|
||||
/* panel HW configuration from DT or platform data */
|
||||
int reset_gpio;
|
||||
int ext_te_gpio;
|
||||
|
||||
bool use_dsi_backlight;
|
||||
|
||||
struct omap_dsi_pin_config pin_config;
|
||||
|
||||
/* runtime variables */
|
||||
bool enabled;
|
||||
u8 rotate;
|
||||
bool mirror;
|
||||
@ -145,16 +157,8 @@ struct taal_data {
|
||||
bool ulps_enabled;
|
||||
unsigned ulps_timeout;
|
||||
struct delayed_work ulps_work;
|
||||
|
||||
struct panel_config *panel_config;
|
||||
};
|
||||
|
||||
static inline struct nokia_dsi_panel_data
|
||||
*get_panel_data(const struct omap_dss_device *dssdev)
|
||||
{
|
||||
return (struct nokia_dsi_panel_data *) dssdev->data;
|
||||
}
|
||||
|
||||
static void taal_esd_work(struct work_struct *work);
|
||||
static void taal_ulps_work(struct work_struct *work);
|
||||
|
||||
@ -371,7 +375,6 @@ static void taal_cancel_ulps_work(struct omap_dss_device *dssdev)
|
||||
static int taal_enter_ulps(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct taal_data *td = dev_get_drvdata(&dssdev->dev);
|
||||
struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
|
||||
int r;
|
||||
|
||||
if (td->ulps_enabled)
|
||||
@ -383,7 +386,8 @@ static int taal_enter_ulps(struct omap_dss_device *dssdev)
|
||||
if (r)
|
||||
goto err;
|
||||
|
||||
disable_irq(gpio_to_irq(panel_data->ext_te_gpio));
|
||||
if (gpio_is_valid(td->ext_te_gpio))
|
||||
disable_irq(gpio_to_irq(td->ext_te_gpio));
|
||||
|
||||
omapdss_dsi_display_disable(dssdev, false, true);
|
||||
|
||||
@ -405,7 +409,6 @@ err:
|
||||
static int taal_exit_ulps(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct taal_data *td = dev_get_drvdata(&dssdev->dev);
|
||||
struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
|
||||
int r;
|
||||
|
||||
if (!td->ulps_enabled)
|
||||
@ -425,7 +428,8 @@ static int taal_exit_ulps(struct omap_dss_device *dssdev)
|
||||
goto err2;
|
||||
}
|
||||
|
||||
enable_irq(gpio_to_irq(panel_data->ext_te_gpio));
|
||||
if (gpio_is_valid(td->ext_te_gpio))
|
||||
enable_irq(gpio_to_irq(td->ext_te_gpio));
|
||||
|
||||
taal_queue_ulps_work(dssdev);
|
||||
|
||||
@ -438,7 +442,8 @@ err2:
|
||||
|
||||
r = taal_panel_reset(dssdev);
|
||||
if (!r) {
|
||||
enable_irq(gpio_to_irq(panel_data->ext_te_gpio));
|
||||
if (gpio_is_valid(td->ext_te_gpio))
|
||||
enable_irq(gpio_to_irq(td->ext_te_gpio));
|
||||
td->ulps_enabled = false;
|
||||
}
|
||||
err1:
|
||||
@ -835,94 +840,135 @@ static struct attribute_group taal_attr_group = {
|
||||
static void taal_hw_reset(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct taal_data *td = dev_get_drvdata(&dssdev->dev);
|
||||
struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
|
||||
|
||||
if (panel_data->reset_gpio == -1)
|
||||
if (!gpio_is_valid(td->reset_gpio))
|
||||
return;
|
||||
|
||||
gpio_set_value(panel_data->reset_gpio, 1);
|
||||
gpio_set_value(td->reset_gpio, 1);
|
||||
if (td->panel_config->reset_sequence.high)
|
||||
udelay(td->panel_config->reset_sequence.high);
|
||||
/* reset the panel */
|
||||
gpio_set_value(panel_data->reset_gpio, 0);
|
||||
gpio_set_value(td->reset_gpio, 0);
|
||||
/* assert reset */
|
||||
if (td->panel_config->reset_sequence.low)
|
||||
udelay(td->panel_config->reset_sequence.low);
|
||||
gpio_set_value(panel_data->reset_gpio, 1);
|
||||
gpio_set_value(td->reset_gpio, 1);
|
||||
/* wait after releasing reset */
|
||||
if (td->panel_config->sleep.hw_reset)
|
||||
msleep(td->panel_config->sleep.hw_reset);
|
||||
}
|
||||
|
||||
static void taal_probe_pdata(struct taal_data *td,
|
||||
const struct nokia_dsi_panel_data *pdata)
|
||||
{
|
||||
td->reset_gpio = pdata->reset_gpio;
|
||||
|
||||
if (pdata->use_ext_te)
|
||||
td->ext_te_gpio = pdata->ext_te_gpio;
|
||||
else
|
||||
td->ext_te_gpio = -1;
|
||||
|
||||
td->esd_interval = pdata->esd_interval;
|
||||
td->ulps_timeout = pdata->ulps_timeout;
|
||||
|
||||
td->use_dsi_backlight = pdata->use_dsi_backlight;
|
||||
|
||||
td->pin_config = pdata->pin_config;
|
||||
}
|
||||
|
||||
static int taal_probe(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct backlight_properties props;
|
||||
struct taal_data *td;
|
||||
struct backlight_device *bldev = NULL;
|
||||
struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
|
||||
struct panel_config *panel_config = NULL;
|
||||
int r, i;
|
||||
const char *panel_name;
|
||||
|
||||
dev_dbg(&dssdev->dev, "probe\n");
|
||||
|
||||
if (!panel_data || !panel_data->name) {
|
||||
r = -EINVAL;
|
||||
goto err;
|
||||
td = devm_kzalloc(&dssdev->dev, sizeof(*td), GFP_KERNEL);
|
||||
if (!td)
|
||||
return -ENOMEM;
|
||||
|
||||
dev_set_drvdata(&dssdev->dev, td);
|
||||
td->dssdev = dssdev;
|
||||
|
||||
if (dssdev->data) {
|
||||
const struct nokia_dsi_panel_data *pdata = dssdev->data;
|
||||
|
||||
taal_probe_pdata(td, pdata);
|
||||
|
||||
panel_name = pdata->name;
|
||||
} else {
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (panel_name == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(panel_configs); i++) {
|
||||
if (strcmp(panel_data->name, panel_configs[i].name) == 0) {
|
||||
panel_config = &panel_configs[i];
|
||||
if (strcmp(panel_name, panel_configs[i].name) == 0) {
|
||||
td->panel_config = &panel_configs[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!panel_config) {
|
||||
r = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
if (!td->panel_config)
|
||||
return -EINVAL;
|
||||
|
||||
dssdev->panel.timings = panel_config->timings;
|
||||
dssdev->panel.timings = td->panel_config->timings;
|
||||
dssdev->panel.dsi_pix_fmt = OMAP_DSS_DSI_FMT_RGB888;
|
||||
|
||||
td = kzalloc(sizeof(*td), GFP_KERNEL);
|
||||
if (!td) {
|
||||
r = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
td->dssdev = dssdev;
|
||||
td->panel_config = panel_config;
|
||||
td->esd_interval = panel_data->esd_interval;
|
||||
td->ulps_enabled = false;
|
||||
td->ulps_timeout = panel_data->ulps_timeout;
|
||||
dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE |
|
||||
OMAP_DSS_DISPLAY_CAP_TEAR_ELIM;
|
||||
|
||||
mutex_init(&td->lock);
|
||||
|
||||
atomic_set(&td->do_update, 0);
|
||||
|
||||
if (gpio_is_valid(td->reset_gpio)) {
|
||||
r = devm_gpio_request_one(&dssdev->dev, td->reset_gpio,
|
||||
GPIOF_OUT_INIT_LOW, "taal rst");
|
||||
if (r) {
|
||||
dev_err(&dssdev->dev, "failed to request reset gpio\n");
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
if (gpio_is_valid(td->ext_te_gpio)) {
|
||||
r = devm_gpio_request_one(&dssdev->dev, td->ext_te_gpio,
|
||||
GPIOF_IN, "taal irq");
|
||||
if (r) {
|
||||
dev_err(&dssdev->dev, "GPIO request failed\n");
|
||||
return r;
|
||||
}
|
||||
|
||||
r = devm_request_irq(&dssdev->dev, gpio_to_irq(td->ext_te_gpio),
|
||||
taal_te_isr,
|
||||
IRQF_TRIGGER_RISING,
|
||||
"taal vsync", dssdev);
|
||||
|
||||
if (r) {
|
||||
dev_err(&dssdev->dev, "IRQ request failed\n");
|
||||
return r;
|
||||
}
|
||||
|
||||
INIT_DEFERRABLE_WORK(&td->te_timeout_work,
|
||||
taal_te_timeout_work_callback);
|
||||
|
||||
dev_dbg(&dssdev->dev, "Using GPIO TE\n");
|
||||
}
|
||||
|
||||
td->workqueue = create_singlethread_workqueue("taal_esd");
|
||||
if (td->workqueue == NULL) {
|
||||
dev_err(&dssdev->dev, "can't create ESD workqueue\n");
|
||||
r = -ENOMEM;
|
||||
goto err_wq;
|
||||
return -ENOMEM;
|
||||
}
|
||||
INIT_DEFERRABLE_WORK(&td->esd_work, taal_esd_work);
|
||||
INIT_DELAYED_WORK(&td->ulps_work, taal_ulps_work);
|
||||
|
||||
dev_set_drvdata(&dssdev->dev, td);
|
||||
|
||||
if (gpio_is_valid(panel_data->reset_gpio)) {
|
||||
r = gpio_request_one(panel_data->reset_gpio, GPIOF_OUT_INIT_LOW,
|
||||
"taal rst");
|
||||
if (r) {
|
||||
dev_err(&dssdev->dev, "failed to request reset gpio\n");
|
||||
goto err_rst_gpio;
|
||||
}
|
||||
}
|
||||
|
||||
taal_hw_reset(dssdev);
|
||||
|
||||
if (panel_data->use_dsi_backlight) {
|
||||
if (td->use_dsi_backlight) {
|
||||
memset(&props, 0, sizeof(struct backlight_properties));
|
||||
props.max_brightness = 255;
|
||||
|
||||
@ -943,31 +989,6 @@ static int taal_probe(struct omap_dss_device *dssdev)
|
||||
taal_bl_update_status(bldev);
|
||||
}
|
||||
|
||||
if (panel_data->use_ext_te) {
|
||||
int gpio = panel_data->ext_te_gpio;
|
||||
|
||||
r = gpio_request_one(gpio, GPIOF_IN, "taal irq");
|
||||
if (r) {
|
||||
dev_err(&dssdev->dev, "GPIO request failed\n");
|
||||
goto err_gpio;
|
||||
}
|
||||
|
||||
r = request_irq(gpio_to_irq(gpio), taal_te_isr,
|
||||
IRQF_TRIGGER_RISING,
|
||||
"taal vsync", dssdev);
|
||||
|
||||
if (r) {
|
||||
dev_err(&dssdev->dev, "IRQ request failed\n");
|
||||
gpio_free(gpio);
|
||||
goto err_irq;
|
||||
}
|
||||
|
||||
INIT_DEFERRABLE_WORK(&td->te_timeout_work,
|
||||
taal_te_timeout_work_callback);
|
||||
|
||||
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");
|
||||
@ -991,29 +1012,16 @@ static int taal_probe(struct omap_dss_device *dssdev)
|
||||
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:
|
||||
if (panel_data->use_ext_te)
|
||||
gpio_free(panel_data->ext_te_gpio);
|
||||
err_gpio:
|
||||
if (bldev != NULL)
|
||||
backlight_device_unregister(bldev);
|
||||
err_bl:
|
||||
if (gpio_is_valid(panel_data->reset_gpio))
|
||||
gpio_free(panel_data->reset_gpio);
|
||||
err_rst_gpio:
|
||||
destroy_workqueue(td->workqueue);
|
||||
err_wq:
|
||||
kfree(td);
|
||||
err:
|
||||
return r;
|
||||
}
|
||||
|
||||
static void __exit taal_remove(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct taal_data *td = dev_get_drvdata(&dssdev->dev);
|
||||
struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
|
||||
struct backlight_device *bldev;
|
||||
|
||||
dev_dbg(&dssdev->dev, "remove\n");
|
||||
@ -1021,12 +1029,6 @@ static void __exit taal_remove(struct omap_dss_device *dssdev)
|
||||
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;
|
||||
free_irq(gpio_to_irq(gpio), dssdev);
|
||||
gpio_free(gpio);
|
||||
}
|
||||
|
||||
bldev = td->bldev;
|
||||
if (bldev != NULL) {
|
||||
bldev->props.power = FB_BLANK_POWERDOWN;
|
||||
@ -1040,26 +1042,31 @@ static void __exit taal_remove(struct omap_dss_device *dssdev)
|
||||
|
||||
/* reset, to be sure that the panel is in a valid state */
|
||||
taal_hw_reset(dssdev);
|
||||
|
||||
if (gpio_is_valid(panel_data->reset_gpio))
|
||||
gpio_free(panel_data->reset_gpio);
|
||||
|
||||
kfree(td);
|
||||
}
|
||||
|
||||
static int taal_power_on(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct taal_data *td = dev_get_drvdata(&dssdev->dev);
|
||||
struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
|
||||
u8 id1, id2, id3;
|
||||
int r;
|
||||
|
||||
r = omapdss_dsi_configure_pins(dssdev, &panel_data->pin_config);
|
||||
r = omapdss_dsi_configure_pins(dssdev, &td->pin_config);
|
||||
if (r) {
|
||||
dev_err(&dssdev->dev, "failed to configure DSI pins\n");
|
||||
goto err0;
|
||||
};
|
||||
|
||||
omapdss_dsi_set_size(dssdev, dssdev->panel.timings.x_res,
|
||||
dssdev->panel.timings.y_res);
|
||||
omapdss_dsi_set_pixel_format(dssdev, OMAP_DSS_DSI_FMT_RGB888);
|
||||
omapdss_dsi_set_operation_mode(dssdev, OMAP_DSS_DSI_CMD_MODE);
|
||||
|
||||
r = omapdss_dsi_set_clocks(dssdev, 216000000, 10000000);
|
||||
if (r) {
|
||||
dev_err(&dssdev->dev, "failed to set HS and LP clocks\n");
|
||||
goto err0;
|
||||
}
|
||||
|
||||
r = omapdss_dsi_display_enable(dssdev);
|
||||
if (r) {
|
||||
dev_err(&dssdev->dev, "failed to enable DSI\n");
|
||||
@ -1356,7 +1363,6 @@ static int taal_update(struct omap_dss_device *dssdev,
|
||||
u16 x, u16 y, u16 w, u16 h)
|
||||
{
|
||||
struct taal_data *td = dev_get_drvdata(&dssdev->dev);
|
||||
struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
|
||||
int r;
|
||||
|
||||
dev_dbg(&dssdev->dev, "update %d, %d, %d x %d\n", x, y, w, h);
|
||||
@ -1380,7 +1386,7 @@ static int taal_update(struct omap_dss_device *dssdev,
|
||||
if (r)
|
||||
goto err;
|
||||
|
||||
if (td->te_enabled && panel_data->use_ext_te) {
|
||||
if (td->te_enabled && gpio_is_valid(td->ext_te_gpio)) {
|
||||
schedule_delayed_work(&td->te_timeout_work,
|
||||
msecs_to_jiffies(250));
|
||||
atomic_set(&td->do_update, 1);
|
||||
@ -1419,7 +1425,6 @@ static int taal_sync(struct omap_dss_device *dssdev)
|
||||
static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable)
|
||||
{
|
||||
struct taal_data *td = dev_get_drvdata(&dssdev->dev);
|
||||
struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
|
||||
int r;
|
||||
|
||||
if (enable)
|
||||
@ -1427,7 +1432,7 @@ static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable)
|
||||
else
|
||||
r = taal_dcs_write_0(td, MIPI_DCS_SET_TEAR_OFF);
|
||||
|
||||
if (!panel_data->use_ext_te)
|
||||
if (!gpio_is_valid(td->ext_te_gpio))
|
||||
omapdss_dsi_enable_te(dssdev, enable);
|
||||
|
||||
if (td->panel_config->sleep.enable_te)
|
||||
@ -1487,6 +1492,7 @@ static int taal_get_te(struct omap_dss_device *dssdev)
|
||||
static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate)
|
||||
{
|
||||
struct taal_data *td = dev_get_drvdata(&dssdev->dev);
|
||||
u16 dw, dh;
|
||||
int r;
|
||||
|
||||
dev_dbg(&dssdev->dev, "rotate %d\n", rotate);
|
||||
@ -1508,6 +1514,16 @@ static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (rotate == 0 || rotate == 2) {
|
||||
dw = dssdev->panel.timings.x_res;
|
||||
dh = dssdev->panel.timings.y_res;
|
||||
} else {
|
||||
dw = dssdev->panel.timings.y_res;
|
||||
dh = dssdev->panel.timings.x_res;
|
||||
}
|
||||
|
||||
omapdss_dsi_set_size(dssdev, dw, dh);
|
||||
|
||||
td->rotate = rotate;
|
||||
|
||||
dsi_bus_unlock(dssdev);
|
||||
@ -1726,7 +1742,6 @@ static void taal_esd_work(struct work_struct *work)
|
||||
struct taal_data *td = container_of(work, struct taal_data,
|
||||
esd_work.work);
|
||||
struct omap_dss_device *dssdev = td->dssdev;
|
||||
struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
|
||||
u8 state1, state2;
|
||||
int r;
|
||||
|
||||
@ -1773,7 +1788,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) {
|
||||
if (td->te_enabled && gpio_is_valid(td->ext_te_gpio)) {
|
||||
r = taal_dcs_write_1(td, MIPI_DCS_SET_TEAR_ON, 0);
|
||||
if (r)
|
||||
goto err;
|
||||
|
@ -65,6 +65,9 @@ static int tfp410_power_on(struct omap_dss_device *dssdev)
|
||||
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
|
||||
return 0;
|
||||
|
||||
omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
|
||||
omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
|
||||
|
||||
r = omapdss_dpi_display_enable(dssdev);
|
||||
if (r)
|
||||
goto err0;
|
||||
@ -116,8 +119,8 @@ static int tfp410_probe(struct omap_dss_device *dssdev)
|
||||
}
|
||||
|
||||
if (gpio_is_valid(ddata->pd_gpio)) {
|
||||
r = gpio_request_one(ddata->pd_gpio, GPIOF_OUT_INIT_LOW,
|
||||
"tfp410 pd");
|
||||
r = devm_gpio_request_one(&dssdev->dev, ddata->pd_gpio,
|
||||
GPIOF_OUT_INIT_LOW, "tfp410 pd");
|
||||
if (r) {
|
||||
dev_err(&dssdev->dev, "Failed to request PD GPIO %d\n",
|
||||
ddata->pd_gpio);
|
||||
@ -132,8 +135,7 @@ static int tfp410_probe(struct omap_dss_device *dssdev)
|
||||
if (!adapter) {
|
||||
dev_err(&dssdev->dev, "Failed to get I2C adapter, bus %d\n",
|
||||
i2c_bus_num);
|
||||
r = -EINVAL;
|
||||
goto err_i2c;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ddata->i2c_adapter = adapter;
|
||||
@ -142,10 +144,6 @@ static int tfp410_probe(struct omap_dss_device *dssdev)
|
||||
dev_set_drvdata(&dssdev->dev, ddata);
|
||||
|
||||
return 0;
|
||||
err_i2c:
|
||||
if (gpio_is_valid(ddata->pd_gpio))
|
||||
gpio_free(ddata->pd_gpio);
|
||||
return r;
|
||||
}
|
||||
|
||||
static void __exit tfp410_remove(struct omap_dss_device *dssdev)
|
||||
@ -157,9 +155,6 @@ static void __exit tfp410_remove(struct omap_dss_device *dssdev)
|
||||
if (ddata->i2c_adapter)
|
||||
i2c_put_adapter(ddata->i2c_adapter);
|
||||
|
||||
if (gpio_is_valid(ddata->pd_gpio))
|
||||
gpio_free(ddata->pd_gpio);
|
||||
|
||||
dev_set_drvdata(&dssdev->dev, NULL);
|
||||
|
||||
mutex_unlock(&ddata->lock);
|
||||
@ -231,7 +226,8 @@ static void tfp410_set_timings(struct omap_dss_device *dssdev,
|
||||
struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
|
||||
|
||||
mutex_lock(&ddata->lock);
|
||||
dpi_set_timings(dssdev, timings);
|
||||
omapdss_dpi_set_timings(dssdev, timings);
|
||||
dssdev->panel.timings = *timings;
|
||||
mutex_unlock(&ddata->lock);
|
||||
}
|
||||
|
||||
|
@ -337,6 +337,9 @@ static int tpo_td043_enable_dss(struct omap_dss_device *dssdev)
|
||||
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
|
||||
return 0;
|
||||
|
||||
omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
|
||||
omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
|
||||
|
||||
r = omapdss_dpi_display_enable(dssdev);
|
||||
if (r)
|
||||
goto err0;
|
||||
@ -480,7 +483,9 @@ static void tpo_td043_remove(struct omap_dss_device *dssdev)
|
||||
static void tpo_td043_set_timings(struct omap_dss_device *dssdev,
|
||||
struct omap_video_timings *timings)
|
||||
{
|
||||
dpi_set_timings(dssdev, timings);
|
||||
omapdss_dpi_set_timings(dssdev, timings);
|
||||
|
||||
dssdev->panel.timings = *timings;
|
||||
}
|
||||
|
||||
static int tpo_td043_check_timings(struct omap_dss_device *dssdev,
|
||||
|
@ -84,7 +84,7 @@ config OMAP2_DSS_SDI
|
||||
|
||||
config OMAP2_DSS_DSI
|
||||
bool "DSI support"
|
||||
depends on ARCH_OMAP3 || ARCH_OMAP4
|
||||
depends on ARCH_OMAP3 || ARCH_OMAP4 || ARCH_OMAP5
|
||||
default n
|
||||
help
|
||||
MIPI DSI (Display Serial Interface) support.
|
||||
|
@ -1,9 +1,9 @@
|
||||
obj-$(CONFIG_OMAP2_DSS) += omapdss.o
|
||||
omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \
|
||||
manager.o overlay.o apply.o
|
||||
manager.o manager-sysfs.o overlay.o overlay-sysfs.o output.o apply.o
|
||||
omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o
|
||||
omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o
|
||||
omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o
|
||||
omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o venc_panel.o
|
||||
omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o
|
||||
omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o
|
||||
omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi.o \
|
||||
|
@ -111,9 +111,6 @@ static struct {
|
||||
struct ovl_priv_data ovl_priv_data_array[MAX_DSS_OVERLAYS];
|
||||
struct mgr_priv_data mgr_priv_data_array[MAX_DSS_MANAGERS];
|
||||
|
||||
bool fifo_merge_dirty;
|
||||
bool fifo_merge;
|
||||
|
||||
bool irq_enabled;
|
||||
} dss_data;
|
||||
|
||||
@ -424,17 +421,25 @@ static void wait_pending_extra_info_updates(void)
|
||||
int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
|
||||
{
|
||||
unsigned long timeout = msecs_to_jiffies(500);
|
||||
struct mgr_priv_data *mp;
|
||||
struct mgr_priv_data *mp = get_mgr_priv(mgr);
|
||||
u32 irq;
|
||||
unsigned long flags;
|
||||
int r;
|
||||
int i;
|
||||
struct omap_dss_device *dssdev = mgr->device;
|
||||
|
||||
if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
|
||||
return 0;
|
||||
spin_lock_irqsave(&data_lock, flags);
|
||||
|
||||
if (mgr_manual_update(mgr))
|
||||
if (mgr_manual_update(mgr)) {
|
||||
spin_unlock_irqrestore(&data_lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!mp->enabled) {
|
||||
spin_unlock_irqrestore(&data_lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&data_lock, flags);
|
||||
|
||||
r = dispc_runtime_get();
|
||||
if (r)
|
||||
@ -442,10 +447,8 @@ int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
|
||||
|
||||
irq = dispc_mgr_get_vsync_irq(mgr->id);
|
||||
|
||||
mp = get_mgr_priv(mgr);
|
||||
i = 0;
|
||||
while (1) {
|
||||
unsigned long flags;
|
||||
bool shadow_dirty, dirty;
|
||||
|
||||
spin_lock_irqsave(&data_lock, flags);
|
||||
@ -489,21 +492,30 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
|
||||
{
|
||||
unsigned long timeout = msecs_to_jiffies(500);
|
||||
struct ovl_priv_data *op;
|
||||
struct omap_dss_device *dssdev;
|
||||
struct mgr_priv_data *mp;
|
||||
u32 irq;
|
||||
unsigned long flags;
|
||||
int r;
|
||||
int i;
|
||||
|
||||
if (!ovl->manager)
|
||||
return 0;
|
||||
|
||||
dssdev = ovl->manager->device;
|
||||
mp = get_mgr_priv(ovl->manager);
|
||||
|
||||
if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
|
||||
return 0;
|
||||
spin_lock_irqsave(&data_lock, flags);
|
||||
|
||||
if (ovl_manual_update(ovl))
|
||||
if (ovl_manual_update(ovl)) {
|
||||
spin_unlock_irqrestore(&data_lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!mp->enabled) {
|
||||
spin_unlock_irqrestore(&data_lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&data_lock, flags);
|
||||
|
||||
r = dispc_runtime_get();
|
||||
if (r)
|
||||
@ -514,7 +526,6 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
|
||||
op = get_ovl_priv(ovl);
|
||||
i = 0;
|
||||
while (1) {
|
||||
unsigned long flags;
|
||||
bool shadow_dirty, dirty;
|
||||
|
||||
spin_lock_irqsave(&data_lock, flags);
|
||||
@ -573,7 +584,7 @@ static void dss_ovl_write_regs(struct omap_overlay *ovl)
|
||||
|
||||
replication = dss_ovl_use_replication(mp->lcd_config, oi->color_mode);
|
||||
|
||||
r = dispc_ovl_setup(ovl->id, oi, replication, &mp->timings);
|
||||
r = dispc_ovl_setup(ovl->id, oi, replication, &mp->timings, false);
|
||||
if (r) {
|
||||
/*
|
||||
* We can't do much here, as this function can be called from
|
||||
@ -677,40 +688,11 @@ static void dss_mgr_write_regs_extra(struct omap_overlay_manager *mgr)
|
||||
mp->shadow_extra_info_dirty = true;
|
||||
}
|
||||
|
||||
static void dss_write_regs_common(void)
|
||||
{
|
||||
const int num_mgrs = omap_dss_get_num_overlay_managers();
|
||||
int i;
|
||||
|
||||
if (!dss_data.fifo_merge_dirty)
|
||||
return;
|
||||
|
||||
for (i = 0; i < num_mgrs; ++i) {
|
||||
struct omap_overlay_manager *mgr;
|
||||
struct mgr_priv_data *mp;
|
||||
|
||||
mgr = omap_dss_get_overlay_manager(i);
|
||||
mp = get_mgr_priv(mgr);
|
||||
|
||||
if (mp->enabled) {
|
||||
if (dss_data.fifo_merge_dirty) {
|
||||
dispc_enable_fifomerge(dss_data.fifo_merge);
|
||||
dss_data.fifo_merge_dirty = false;
|
||||
}
|
||||
|
||||
if (mp->updating)
|
||||
mp->shadow_info_dirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void dss_write_regs(void)
|
||||
{
|
||||
const int num_mgrs = omap_dss_get_num_overlay_managers();
|
||||
int i;
|
||||
|
||||
dss_write_regs_common();
|
||||
|
||||
for (i = 0; i < num_mgrs; ++i) {
|
||||
struct omap_overlay_manager *mgr;
|
||||
struct mgr_priv_data *mp;
|
||||
@ -799,8 +781,6 @@ void dss_mgr_start_update(struct omap_overlay_manager *mgr)
|
||||
dss_mgr_write_regs(mgr);
|
||||
dss_mgr_write_regs_extra(mgr);
|
||||
|
||||
dss_write_regs_common();
|
||||
|
||||
mp->updating = true;
|
||||
|
||||
if (!dss_data.irq_enabled && need_isr())
|
||||
@ -984,20 +964,11 @@ static void dss_apply_ovl_fifo_thresholds(struct omap_overlay *ovl,
|
||||
op->extra_info_dirty = true;
|
||||
}
|
||||
|
||||
static void dss_apply_fifo_merge(bool use_fifo_merge)
|
||||
{
|
||||
if (dss_data.fifo_merge == use_fifo_merge)
|
||||
return;
|
||||
|
||||
dss_data.fifo_merge = use_fifo_merge;
|
||||
dss_data.fifo_merge_dirty = true;
|
||||
}
|
||||
|
||||
static void dss_ovl_setup_fifo(struct omap_overlay *ovl,
|
||||
bool use_fifo_merge)
|
||||
static void dss_ovl_setup_fifo(struct omap_overlay *ovl)
|
||||
{
|
||||
struct ovl_priv_data *op = get_ovl_priv(ovl);
|
||||
u32 fifo_low, fifo_high;
|
||||
bool use_fifo_merge = false;
|
||||
|
||||
if (!op->enabled && !op->enabling)
|
||||
return;
|
||||
@ -1008,8 +979,7 @@ static void dss_ovl_setup_fifo(struct omap_overlay *ovl,
|
||||
dss_apply_ovl_fifo_thresholds(ovl, fifo_low, fifo_high);
|
||||
}
|
||||
|
||||
static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr,
|
||||
bool use_fifo_merge)
|
||||
static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr)
|
||||
{
|
||||
struct omap_overlay *ovl;
|
||||
struct mgr_priv_data *mp;
|
||||
@ -1020,10 +990,10 @@ static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr,
|
||||
return;
|
||||
|
||||
list_for_each_entry(ovl, &mgr->overlays, list)
|
||||
dss_ovl_setup_fifo(ovl, use_fifo_merge);
|
||||
dss_ovl_setup_fifo(ovl);
|
||||
}
|
||||
|
||||
static void dss_setup_fifos(bool use_fifo_merge)
|
||||
static void dss_setup_fifos(void)
|
||||
{
|
||||
const int num_mgrs = omap_dss_get_num_overlay_managers();
|
||||
struct omap_overlay_manager *mgr;
|
||||
@ -1031,91 +1001,15 @@ static void dss_setup_fifos(bool use_fifo_merge)
|
||||
|
||||
for (i = 0; i < num_mgrs; ++i) {
|
||||
mgr = omap_dss_get_overlay_manager(i);
|
||||
dss_mgr_setup_fifos(mgr, use_fifo_merge);
|
||||
dss_mgr_setup_fifos(mgr);
|
||||
}
|
||||
}
|
||||
|
||||
static int get_num_used_managers(void)
|
||||
{
|
||||
const int num_mgrs = omap_dss_get_num_overlay_managers();
|
||||
struct omap_overlay_manager *mgr;
|
||||
struct mgr_priv_data *mp;
|
||||
int i;
|
||||
int enabled_mgrs;
|
||||
|
||||
enabled_mgrs = 0;
|
||||
|
||||
for (i = 0; i < num_mgrs; ++i) {
|
||||
mgr = omap_dss_get_overlay_manager(i);
|
||||
mp = get_mgr_priv(mgr);
|
||||
|
||||
if (!mp->enabled)
|
||||
continue;
|
||||
|
||||
enabled_mgrs++;
|
||||
}
|
||||
|
||||
return enabled_mgrs;
|
||||
}
|
||||
|
||||
static int get_num_used_overlays(void)
|
||||
{
|
||||
const int num_ovls = omap_dss_get_num_overlays();
|
||||
struct omap_overlay *ovl;
|
||||
struct ovl_priv_data *op;
|
||||
struct mgr_priv_data *mp;
|
||||
int i;
|
||||
int enabled_ovls;
|
||||
|
||||
enabled_ovls = 0;
|
||||
|
||||
for (i = 0; i < num_ovls; ++i) {
|
||||
ovl = omap_dss_get_overlay(i);
|
||||
op = get_ovl_priv(ovl);
|
||||
|
||||
if (!op->enabled && !op->enabling)
|
||||
continue;
|
||||
|
||||
mp = get_mgr_priv(ovl->manager);
|
||||
|
||||
if (!mp->enabled)
|
||||
continue;
|
||||
|
||||
enabled_ovls++;
|
||||
}
|
||||
|
||||
return enabled_ovls;
|
||||
}
|
||||
|
||||
static bool get_use_fifo_merge(void)
|
||||
{
|
||||
int enabled_mgrs = get_num_used_managers();
|
||||
int enabled_ovls = get_num_used_overlays();
|
||||
|
||||
if (!dss_has_feature(FEAT_FIFO_MERGE))
|
||||
return false;
|
||||
|
||||
/*
|
||||
* In theory the only requirement for fifomerge is enabled_ovls <= 1.
|
||||
* However, if we have two managers enabled and set/unset the fifomerge,
|
||||
* we need to set the GO bits in particular sequence for the managers,
|
||||
* and wait in between.
|
||||
*
|
||||
* This is rather difficult as new apply calls can happen at any time,
|
||||
* so we simplify the problem by requiring also that enabled_mgrs <= 1.
|
||||
* In practice this shouldn't matter, because when only one overlay is
|
||||
* enabled, most likely only one output is enabled.
|
||||
*/
|
||||
|
||||
return enabled_mgrs <= 1 && enabled_ovls <= 1;
|
||||
}
|
||||
|
||||
int dss_mgr_enable(struct omap_overlay_manager *mgr)
|
||||
{
|
||||
struct mgr_priv_data *mp = get_mgr_priv(mgr);
|
||||
unsigned long flags;
|
||||
int r;
|
||||
bool fifo_merge;
|
||||
|
||||
mutex_lock(&apply_lock);
|
||||
|
||||
@ -1133,23 +1027,11 @@ int dss_mgr_enable(struct omap_overlay_manager *mgr)
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* step 1: setup fifos/fifomerge before enabling the manager */
|
||||
|
||||
fifo_merge = get_use_fifo_merge();
|
||||
dss_setup_fifos(fifo_merge);
|
||||
dss_apply_fifo_merge(fifo_merge);
|
||||
dss_setup_fifos();
|
||||
|
||||
dss_write_regs();
|
||||
dss_set_go_bits();
|
||||
|
||||
spin_unlock_irqrestore(&data_lock, flags);
|
||||
|
||||
/* wait until fifo config is in */
|
||||
wait_pending_extra_info_updates();
|
||||
|
||||
/* step 2: enable the manager */
|
||||
spin_lock_irqsave(&data_lock, flags);
|
||||
|
||||
if (!mgr_manual_update(mgr))
|
||||
mp->updating = true;
|
||||
|
||||
@ -1174,7 +1056,6 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr)
|
||||
{
|
||||
struct mgr_priv_data *mp = get_mgr_priv(mgr);
|
||||
unsigned long flags;
|
||||
bool fifo_merge;
|
||||
|
||||
mutex_lock(&apply_lock);
|
||||
|
||||
@ -1189,16 +1070,8 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr)
|
||||
mp->updating = false;
|
||||
mp->enabled = false;
|
||||
|
||||
fifo_merge = get_use_fifo_merge();
|
||||
dss_setup_fifos(fifo_merge);
|
||||
dss_apply_fifo_merge(fifo_merge);
|
||||
|
||||
dss_write_regs();
|
||||
dss_set_go_bits();
|
||||
|
||||
spin_unlock_irqrestore(&data_lock, flags);
|
||||
|
||||
wait_pending_extra_info_updates();
|
||||
out:
|
||||
mutex_unlock(&apply_lock);
|
||||
}
|
||||
@ -1237,29 +1110,29 @@ void dss_mgr_get_info(struct omap_overlay_manager *mgr,
|
||||
spin_unlock_irqrestore(&data_lock, flags);
|
||||
}
|
||||
|
||||
int dss_mgr_set_device(struct omap_overlay_manager *mgr,
|
||||
struct omap_dss_device *dssdev)
|
||||
int dss_mgr_set_output(struct omap_overlay_manager *mgr,
|
||||
struct omap_dss_output *output)
|
||||
{
|
||||
int r;
|
||||
|
||||
mutex_lock(&apply_lock);
|
||||
|
||||
if (dssdev->manager) {
|
||||
DSSERR("display '%s' already has a manager '%s'\n",
|
||||
dssdev->name, dssdev->manager->name);
|
||||
if (mgr->output) {
|
||||
DSSERR("manager %s is already connected to an output\n",
|
||||
mgr->name);
|
||||
r = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if ((mgr->supported_displays & dssdev->type) == 0) {
|
||||
DSSERR("display '%s' does not support manager '%s'\n",
|
||||
dssdev->name, mgr->name);
|
||||
if ((mgr->supported_outputs & output->id) == 0) {
|
||||
DSSERR("output does not support manager %s\n",
|
||||
mgr->name);
|
||||
r = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
dssdev->manager = mgr;
|
||||
mgr->device = dssdev;
|
||||
output->manager = mgr;
|
||||
mgr->output = output;
|
||||
|
||||
mutex_unlock(&apply_lock);
|
||||
|
||||
@ -1269,40 +1142,46 @@ err:
|
||||
return r;
|
||||
}
|
||||
|
||||
int dss_mgr_unset_device(struct omap_overlay_manager *mgr)
|
||||
int dss_mgr_unset_output(struct omap_overlay_manager *mgr)
|
||||
{
|
||||
int r;
|
||||
struct mgr_priv_data *mp = get_mgr_priv(mgr);
|
||||
unsigned long flags;
|
||||
|
||||
mutex_lock(&apply_lock);
|
||||
|
||||
if (!mgr->device) {
|
||||
DSSERR("failed to unset display, display not set.\n");
|
||||
if (!mgr->output) {
|
||||
DSSERR("failed to unset output, output not set\n");
|
||||
r = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Don't allow currently enabled displays to have the overlay manager
|
||||
* pulled out from underneath them
|
||||
*/
|
||||
if (mgr->device->state != OMAP_DSS_DISPLAY_DISABLED) {
|
||||
spin_lock_irqsave(&data_lock, flags);
|
||||
|
||||
if (mp->enabled) {
|
||||
DSSERR("output can't be unset when manager is enabled\n");
|
||||
r = -EINVAL;
|
||||
goto err;
|
||||
goto err1;
|
||||
}
|
||||
|
||||
mgr->device->manager = NULL;
|
||||
mgr->device = NULL;
|
||||
spin_unlock_irqrestore(&data_lock, flags);
|
||||
|
||||
mgr->output->manager = NULL;
|
||||
mgr->output = NULL;
|
||||
|
||||
mutex_unlock(&apply_lock);
|
||||
|
||||
return 0;
|
||||
err1:
|
||||
spin_unlock_irqrestore(&data_lock, flags);
|
||||
err:
|
||||
mutex_unlock(&apply_lock);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static void dss_apply_mgr_timings(struct omap_overlay_manager *mgr,
|
||||
struct omap_video_timings *timings)
|
||||
const struct omap_video_timings *timings)
|
||||
{
|
||||
struct mgr_priv_data *mp = get_mgr_priv(mgr);
|
||||
|
||||
@ -1311,24 +1190,22 @@ static void dss_apply_mgr_timings(struct omap_overlay_manager *mgr,
|
||||
}
|
||||
|
||||
void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
|
||||
struct omap_video_timings *timings)
|
||||
const struct omap_video_timings *timings)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
mutex_lock(&apply_lock);
|
||||
struct mgr_priv_data *mp = get_mgr_priv(mgr);
|
||||
|
||||
spin_lock_irqsave(&data_lock, flags);
|
||||
|
||||
if (mp->updating) {
|
||||
DSSERR("cannot set timings for %s: manager needs to be disabled\n",
|
||||
mgr->name);
|
||||
goto out;
|
||||
}
|
||||
|
||||
dss_apply_mgr_timings(mgr, timings);
|
||||
|
||||
dss_write_regs();
|
||||
dss_set_go_bits();
|
||||
|
||||
out:
|
||||
spin_unlock_irqrestore(&data_lock, flags);
|
||||
|
||||
wait_pending_extra_info_updates();
|
||||
|
||||
mutex_unlock(&apply_lock);
|
||||
}
|
||||
|
||||
static void dss_apply_mgr_lcd_config(struct omap_overlay_manager *mgr,
|
||||
@ -1346,7 +1223,7 @@ void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr,
|
||||
unsigned long flags;
|
||||
struct mgr_priv_data *mp = get_mgr_priv(mgr);
|
||||
|
||||
mutex_lock(&apply_lock);
|
||||
spin_lock_irqsave(&data_lock, flags);
|
||||
|
||||
if (mp->enabled) {
|
||||
DSSERR("cannot apply lcd config for %s: manager needs to be disabled\n",
|
||||
@ -1354,19 +1231,9 @@ void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr,
|
||||
goto out;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&data_lock, flags);
|
||||
|
||||
dss_apply_mgr_lcd_config(mgr, config);
|
||||
|
||||
dss_write_regs();
|
||||
dss_set_go_bits();
|
||||
|
||||
spin_unlock_irqrestore(&data_lock, flags);
|
||||
|
||||
wait_pending_extra_info_updates();
|
||||
|
||||
out:
|
||||
mutex_unlock(&apply_lock);
|
||||
spin_unlock_irqrestore(&data_lock, flags);
|
||||
}
|
||||
|
||||
int dss_ovl_set_info(struct omap_overlay *ovl,
|
||||
@ -1483,6 +1350,13 @@ int dss_ovl_unset_manager(struct omap_overlay *ovl)
|
||||
goto err;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&data_lock, flags);
|
||||
|
||||
/* wait for pending extra_info updates to ensure the ovl is disabled */
|
||||
wait_pending_extra_info_updates();
|
||||
|
||||
spin_lock_irqsave(&data_lock, flags);
|
||||
|
||||
op->channel = -1;
|
||||
|
||||
ovl->manager = NULL;
|
||||
@ -1517,7 +1391,6 @@ int dss_ovl_enable(struct omap_overlay *ovl)
|
||||
{
|
||||
struct ovl_priv_data *op = get_ovl_priv(ovl);
|
||||
unsigned long flags;
|
||||
bool fifo_merge;
|
||||
int r;
|
||||
|
||||
mutex_lock(&apply_lock);
|
||||
@ -1527,7 +1400,7 @@ int dss_ovl_enable(struct omap_overlay *ovl)
|
||||
goto err1;
|
||||
}
|
||||
|
||||
if (ovl->manager == NULL || ovl->manager->device == NULL) {
|
||||
if (ovl->manager == NULL || ovl->manager->output == NULL) {
|
||||
r = -EINVAL;
|
||||
goto err1;
|
||||
}
|
||||
@ -1543,22 +1416,7 @@ int dss_ovl_enable(struct omap_overlay *ovl)
|
||||
goto err2;
|
||||
}
|
||||
|
||||
/* step 1: configure fifos/fifomerge for currently enabled ovls */
|
||||
|
||||
fifo_merge = get_use_fifo_merge();
|
||||
dss_setup_fifos(fifo_merge);
|
||||
dss_apply_fifo_merge(fifo_merge);
|
||||
|
||||
dss_write_regs();
|
||||
dss_set_go_bits();
|
||||
|
||||
spin_unlock_irqrestore(&data_lock, flags);
|
||||
|
||||
/* wait for fifo configs to go in */
|
||||
wait_pending_extra_info_updates();
|
||||
|
||||
/* step 2: enable the overlay */
|
||||
spin_lock_irqsave(&data_lock, flags);
|
||||
dss_setup_fifos();
|
||||
|
||||
op->enabling = false;
|
||||
dss_apply_ovl_enable(ovl, true);
|
||||
@ -1568,9 +1426,6 @@ int dss_ovl_enable(struct omap_overlay *ovl)
|
||||
|
||||
spin_unlock_irqrestore(&data_lock, flags);
|
||||
|
||||
/* wait for overlay to be enabled */
|
||||
wait_pending_extra_info_updates();
|
||||
|
||||
mutex_unlock(&apply_lock);
|
||||
|
||||
return 0;
|
||||
@ -1586,7 +1441,6 @@ int dss_ovl_disable(struct omap_overlay *ovl)
|
||||
{
|
||||
struct ovl_priv_data *op = get_ovl_priv(ovl);
|
||||
unsigned long flags;
|
||||
bool fifo_merge;
|
||||
int r;
|
||||
|
||||
mutex_lock(&apply_lock);
|
||||
@ -1596,39 +1450,19 @@ int dss_ovl_disable(struct omap_overlay *ovl)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (ovl->manager == NULL || ovl->manager->device == NULL) {
|
||||
if (ovl->manager == NULL || ovl->manager->output == NULL) {
|
||||
r = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* step 1: disable the overlay */
|
||||
spin_lock_irqsave(&data_lock, flags);
|
||||
|
||||
dss_apply_ovl_enable(ovl, false);
|
||||
|
||||
dss_write_regs();
|
||||
dss_set_go_bits();
|
||||
|
||||
spin_unlock_irqrestore(&data_lock, flags);
|
||||
|
||||
/* wait for the overlay to be disabled */
|
||||
wait_pending_extra_info_updates();
|
||||
|
||||
/* step 2: configure fifos/fifomerge */
|
||||
spin_lock_irqsave(&data_lock, flags);
|
||||
|
||||
fifo_merge = get_use_fifo_merge();
|
||||
dss_setup_fifos(fifo_merge);
|
||||
dss_apply_fifo_merge(fifo_merge);
|
||||
|
||||
dss_write_regs();
|
||||
dss_set_go_bits();
|
||||
|
||||
spin_unlock_irqrestore(&data_lock, flags);
|
||||
|
||||
/* wait for fifo config to go in */
|
||||
wait_pending_extra_info_updates();
|
||||
|
||||
mutex_unlock(&apply_lock);
|
||||
|
||||
return 0;
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include <linux/device.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/suspend.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <video/omapdss.h>
|
||||
|
||||
@ -57,6 +58,11 @@ bool dss_debug;
|
||||
module_param_named(debug, dss_debug, bool, 0644);
|
||||
#endif
|
||||
|
||||
const char *dss_get_default_display_name(void)
|
||||
{
|
||||
return core.default_display_name;
|
||||
}
|
||||
|
||||
/* REGULATORS */
|
||||
|
||||
struct regulator *dss_get_vdds_dsi(void)
|
||||
@ -347,17 +353,14 @@ static int dss_driver_probe(struct device *dev)
|
||||
int r;
|
||||
struct omap_dss_driver *dssdrv = to_dss_driver(dev->driver);
|
||||
struct omap_dss_device *dssdev = to_dss_device(dev);
|
||||
bool force;
|
||||
|
||||
DSSDBG("driver_probe: dev %s/%s, drv %s\n",
|
||||
dev_name(dev), dssdev->driver_name,
|
||||
dssdrv->driver.name);
|
||||
|
||||
dss_init_device(core.pdev, dssdev);
|
||||
|
||||
force = core.default_display_name &&
|
||||
strcmp(core.default_display_name, dssdev->name) == 0;
|
||||
dss_recheck_connections(dssdev, force);
|
||||
r = dss_init_device(core.pdev, dssdev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = dssdrv->probe(dssdev);
|
||||
|
||||
@ -416,54 +419,44 @@ void omap_dss_unregister_driver(struct omap_dss_driver *dssdriver)
|
||||
EXPORT_SYMBOL(omap_dss_unregister_driver);
|
||||
|
||||
/* DEVICE */
|
||||
static void reset_device(struct device *dev, int check)
|
||||
{
|
||||
u8 *dev_p = (u8 *)dev;
|
||||
u8 *dev_end = dev_p + sizeof(*dev);
|
||||
void *saved_pdata;
|
||||
|
||||
saved_pdata = dev->platform_data;
|
||||
if (check) {
|
||||
/*
|
||||
* Check if there is any other setting than platform_data
|
||||
* in struct device; warn that these will be reset by our
|
||||
* init.
|
||||
*/
|
||||
dev->platform_data = NULL;
|
||||
while (dev_p < dev_end) {
|
||||
if (*dev_p) {
|
||||
WARN("%s: struct device fields will be "
|
||||
"discarded\n",
|
||||
__func__);
|
||||
break;
|
||||
}
|
||||
dev_p++;
|
||||
}
|
||||
}
|
||||
memset(dev, 0, sizeof(*dev));
|
||||
dev->platform_data = saved_pdata;
|
||||
}
|
||||
|
||||
|
||||
static void omap_dss_dev_release(struct device *dev)
|
||||
{
|
||||
reset_device(dev, 0);
|
||||
struct omap_dss_device *dssdev = to_dss_device(dev);
|
||||
kfree(dssdev);
|
||||
}
|
||||
|
||||
int omap_dss_register_device(struct omap_dss_device *dssdev,
|
||||
struct device *parent, int disp_num)
|
||||
{
|
||||
WARN_ON(!dssdev->driver_name);
|
||||
static int disp_num_counter;
|
||||
|
||||
struct omap_dss_device *dss_alloc_and_init_device(struct device *parent)
|
||||
{
|
||||
struct omap_dss_device *dssdev;
|
||||
|
||||
dssdev = kzalloc(sizeof(*dssdev), GFP_KERNEL);
|
||||
if (!dssdev)
|
||||
return NULL;
|
||||
|
||||
reset_device(&dssdev->dev, 1);
|
||||
dssdev->dev.bus = &dss_bus_type;
|
||||
dssdev->dev.parent = parent;
|
||||
dssdev->dev.release = omap_dss_dev_release;
|
||||
dev_set_name(&dssdev->dev, "display%d", disp_num);
|
||||
return device_register(&dssdev->dev);
|
||||
dev_set_name(&dssdev->dev, "display%d", disp_num_counter++);
|
||||
|
||||
device_initialize(&dssdev->dev);
|
||||
|
||||
return dssdev;
|
||||
}
|
||||
|
||||
void omap_dss_unregister_device(struct omap_dss_device *dssdev)
|
||||
int dss_add_device(struct omap_dss_device *dssdev)
|
||||
{
|
||||
return device_add(&dssdev->dev);
|
||||
}
|
||||
|
||||
void dss_put_device(struct omap_dss_device *dssdev)
|
||||
{
|
||||
put_device(&dssdev->dev);
|
||||
}
|
||||
|
||||
void dss_unregister_device(struct omap_dss_device *dssdev)
|
||||
{
|
||||
device_unregister(&dssdev->dev);
|
||||
}
|
||||
@ -471,15 +464,25 @@ void omap_dss_unregister_device(struct omap_dss_device *dssdev)
|
||||
static int dss_unregister_dss_dev(struct device *dev, void *data)
|
||||
{
|
||||
struct omap_dss_device *dssdev = to_dss_device(dev);
|
||||
omap_dss_unregister_device(dssdev);
|
||||
dss_unregister_device(dssdev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void omap_dss_unregister_child_devices(struct device *parent)
|
||||
void dss_unregister_child_devices(struct device *parent)
|
||||
{
|
||||
device_for_each_child(parent, NULL, dss_unregister_dss_dev);
|
||||
}
|
||||
|
||||
void dss_copy_device_pdata(struct omap_dss_device *dst,
|
||||
const struct omap_dss_device *src)
|
||||
{
|
||||
u8 *d = (u8 *)dst;
|
||||
u8 *s = (u8 *)src;
|
||||
size_t dsize = sizeof(struct device);
|
||||
|
||||
memcpy(d + dsize, s + dsize, sizeof(struct omap_dss_device) - dsize);
|
||||
}
|
||||
|
||||
/* BUS */
|
||||
static int __init omap_dss_bus_register(void)
|
||||
{
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -36,6 +36,7 @@
|
||||
#define DISPC_CONTROL2 0x0238
|
||||
#define DISPC_CONFIG2 0x0620
|
||||
#define DISPC_DIVISOR 0x0804
|
||||
#define DISPC_GLOBAL_BUFFER 0x0800
|
||||
#define DISPC_CONTROL3 0x0848
|
||||
#define DISPC_CONFIG3 0x084C
|
||||
|
||||
@ -355,6 +356,8 @@ static inline u16 DISPC_OVL_BASE(enum omap_plane plane)
|
||||
return 0x014C;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
return 0x0300;
|
||||
case OMAP_DSS_WB:
|
||||
return 0x0500;
|
||||
default:
|
||||
BUG();
|
||||
return 0;
|
||||
@ -370,6 +373,7 @@ static inline u16 DISPC_BA0_OFFSET(enum omap_plane plane)
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x0000;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
case OMAP_DSS_WB:
|
||||
return 0x0008;
|
||||
default:
|
||||
BUG();
|
||||
@ -385,6 +389,7 @@ static inline u16 DISPC_BA1_OFFSET(enum omap_plane plane)
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x0004;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
case OMAP_DSS_WB:
|
||||
return 0x000C;
|
||||
default:
|
||||
BUG();
|
||||
@ -404,6 +409,8 @@ static inline u16 DISPC_BA0_UV_OFFSET(enum omap_plane plane)
|
||||
return 0x04BC;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
return 0x0310;
|
||||
case OMAP_DSS_WB:
|
||||
return 0x0118;
|
||||
default:
|
||||
BUG();
|
||||
return 0;
|
||||
@ -422,6 +429,8 @@ static inline u16 DISPC_BA1_UV_OFFSET(enum omap_plane plane)
|
||||
return 0x04C0;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
return 0x0314;
|
||||
case OMAP_DSS_WB:
|
||||
return 0x011C;
|
||||
default:
|
||||
BUG();
|
||||
return 0;
|
||||
@ -451,6 +460,7 @@ static inline u16 DISPC_SIZE_OFFSET(enum omap_plane plane)
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x000C;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
case OMAP_DSS_WB:
|
||||
return 0x00A8;
|
||||
default:
|
||||
BUG();
|
||||
@ -467,6 +477,7 @@ static inline u16 DISPC_ATTR_OFFSET(enum omap_plane plane)
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x0010;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
case OMAP_DSS_WB:
|
||||
return 0x0070;
|
||||
default:
|
||||
BUG();
|
||||
@ -486,6 +497,8 @@ static inline u16 DISPC_ATTR2_OFFSET(enum omap_plane plane)
|
||||
return 0x04DC;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
return 0x032C;
|
||||
case OMAP_DSS_WB:
|
||||
return 0x0310;
|
||||
default:
|
||||
BUG();
|
||||
return 0;
|
||||
@ -501,6 +514,7 @@ static inline u16 DISPC_FIFO_THRESH_OFFSET(enum omap_plane plane)
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x0014;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
case OMAP_DSS_WB:
|
||||
return 0x008C;
|
||||
default:
|
||||
BUG();
|
||||
@ -517,6 +531,7 @@ static inline u16 DISPC_FIFO_SIZE_STATUS_OFFSET(enum omap_plane plane)
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x0018;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
case OMAP_DSS_WB:
|
||||
return 0x0088;
|
||||
default:
|
||||
BUG();
|
||||
@ -533,6 +548,7 @@ static inline u16 DISPC_ROW_INC_OFFSET(enum omap_plane plane)
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x001C;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
case OMAP_DSS_WB:
|
||||
return 0x00A4;
|
||||
default:
|
||||
BUG();
|
||||
@ -549,6 +565,7 @@ static inline u16 DISPC_PIX_INC_OFFSET(enum omap_plane plane)
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x0020;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
case OMAP_DSS_WB:
|
||||
return 0x0098;
|
||||
default:
|
||||
BUG();
|
||||
@ -598,6 +615,7 @@ static inline u16 DISPC_FIR_OFFSET(enum omap_plane plane)
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x0024;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
case OMAP_DSS_WB:
|
||||
return 0x0090;
|
||||
default:
|
||||
BUG();
|
||||
@ -617,6 +635,8 @@ static inline u16 DISPC_FIR2_OFFSET(enum omap_plane plane)
|
||||
return 0x055C;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
return 0x0424;
|
||||
case OMAP_DSS_WB:
|
||||
return 0x290;
|
||||
default:
|
||||
BUG();
|
||||
return 0;
|
||||
@ -633,6 +653,7 @@ static inline u16 DISPC_PIC_SIZE_OFFSET(enum omap_plane plane)
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x0028;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
case OMAP_DSS_WB:
|
||||
return 0x0094;
|
||||
default:
|
||||
BUG();
|
||||
@ -651,6 +672,7 @@ static inline u16 DISPC_ACCU0_OFFSET(enum omap_plane plane)
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x002C;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
case OMAP_DSS_WB:
|
||||
return 0x0000;
|
||||
default:
|
||||
BUG();
|
||||
@ -670,6 +692,8 @@ static inline u16 DISPC_ACCU2_0_OFFSET(enum omap_plane plane)
|
||||
return 0x0560;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
return 0x0428;
|
||||
case OMAP_DSS_WB:
|
||||
return 0x0294;
|
||||
default:
|
||||
BUG();
|
||||
return 0;
|
||||
@ -686,6 +710,7 @@ static inline u16 DISPC_ACCU1_OFFSET(enum omap_plane plane)
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x0030;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
case OMAP_DSS_WB:
|
||||
return 0x0004;
|
||||
default:
|
||||
BUG();
|
||||
@ -705,6 +730,8 @@ static inline u16 DISPC_ACCU2_1_OFFSET(enum omap_plane plane)
|
||||
return 0x0564;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
return 0x042C;
|
||||
case OMAP_DSS_WB:
|
||||
return 0x0298;
|
||||
default:
|
||||
BUG();
|
||||
return 0;
|
||||
@ -722,6 +749,7 @@ static inline u16 DISPC_FIR_COEF_H_OFFSET(enum omap_plane plane, u16 i)
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x0034 + i * 0x8;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
case OMAP_DSS_WB:
|
||||
return 0x0010 + i * 0x8;
|
||||
default:
|
||||
BUG();
|
||||
@ -742,6 +770,8 @@ static inline u16 DISPC_FIR_COEF_H2_OFFSET(enum omap_plane plane, u16 i)
|
||||
return 0x0568 + i * 0x8;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
return 0x0430 + i * 0x8;
|
||||
case OMAP_DSS_WB:
|
||||
return 0x02A0 + i * 0x8;
|
||||
default:
|
||||
BUG();
|
||||
return 0;
|
||||
@ -759,6 +789,7 @@ static inline u16 DISPC_FIR_COEF_HV_OFFSET(enum omap_plane plane, u16 i)
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x0038 + i * 0x8;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
case OMAP_DSS_WB:
|
||||
return 0x0014 + i * 0x8;
|
||||
default:
|
||||
BUG();
|
||||
@ -779,6 +810,8 @@ static inline u16 DISPC_FIR_COEF_HV2_OFFSET(enum omap_plane plane, u16 i)
|
||||
return 0x056C + i * 0x8;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
return 0x0434 + i * 0x8;
|
||||
case OMAP_DSS_WB:
|
||||
return 0x02A4 + i * 0x8;
|
||||
default:
|
||||
BUG();
|
||||
return 0;
|
||||
@ -795,6 +828,7 @@ static inline u16 DISPC_CONV_COEF_OFFSET(enum omap_plane plane, u16 i)
|
||||
case OMAP_DSS_VIDEO1:
|
||||
case OMAP_DSS_VIDEO2:
|
||||
case OMAP_DSS_VIDEO3:
|
||||
case OMAP_DSS_WB:
|
||||
return 0x0074 + i * 0x4;
|
||||
default:
|
||||
BUG();
|
||||
@ -814,6 +848,7 @@ static inline u16 DISPC_FIR_COEF_V_OFFSET(enum omap_plane plane, u16 i)
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x00B4 + i * 0x4;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
case OMAP_DSS_WB:
|
||||
return 0x0050 + i * 0x4;
|
||||
default:
|
||||
BUG();
|
||||
@ -834,6 +869,8 @@ static inline u16 DISPC_FIR_COEF_V2_OFFSET(enum omap_plane plane, u16 i)
|
||||
return 0x05A8 + i * 0x4;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
return 0x0470 + i * 0x4;
|
||||
case OMAP_DSS_WB:
|
||||
return 0x02E0 + i * 0x4;
|
||||
default:
|
||||
BUG();
|
||||
return 0;
|
||||
|
@ -142,7 +142,11 @@ static ssize_t display_timings_store(struct device *dev,
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
dssdev->driver->disable(dssdev);
|
||||
dssdev->driver->set_timings(dssdev, &t);
|
||||
r = dssdev->driver->enable(dssdev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return size;
|
||||
}
|
||||
@ -316,26 +320,117 @@ void omapdss_default_get_timings(struct omap_dss_device *dssdev,
|
||||
}
|
||||
EXPORT_SYMBOL(omapdss_default_get_timings);
|
||||
|
||||
void dss_init_device(struct platform_device *pdev,
|
||||
/*
|
||||
* Connect dssdev to a manager if the manager is free or if force is specified.
|
||||
* Connect all overlays to that manager if they are free or if force is
|
||||
* specified.
|
||||
*/
|
||||
static int dss_init_connections(struct omap_dss_device *dssdev, bool force)
|
||||
{
|
||||
struct omap_dss_output *out;
|
||||
struct omap_overlay_manager *mgr;
|
||||
int i, r;
|
||||
|
||||
out = omapdss_get_output_from_dssdev(dssdev);
|
||||
|
||||
WARN_ON(dssdev->output);
|
||||
WARN_ON(out->device);
|
||||
|
||||
r = omapdss_output_set_device(out, dssdev);
|
||||
if (r) {
|
||||
DSSERR("failed to connect output to new device\n");
|
||||
return r;
|
||||
}
|
||||
|
||||
mgr = omap_dss_get_overlay_manager(dssdev->channel);
|
||||
|
||||
if (mgr->output && !force)
|
||||
return 0;
|
||||
|
||||
if (mgr->output)
|
||||
mgr->unset_output(mgr);
|
||||
|
||||
r = mgr->set_output(mgr, out);
|
||||
if (r) {
|
||||
DSSERR("failed to connect manager to output of new device\n");
|
||||
|
||||
/* remove the output-device connection we just made */
|
||||
omapdss_output_unset_device(out);
|
||||
return r;
|
||||
}
|
||||
|
||||
for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
|
||||
struct omap_overlay *ovl = omap_dss_get_overlay(i);
|
||||
|
||||
if (!ovl->manager || force) {
|
||||
if (ovl->manager)
|
||||
ovl->unset_manager(ovl);
|
||||
|
||||
r = ovl->set_manager(ovl, mgr);
|
||||
if (r) {
|
||||
DSSERR("failed to set initial overlay\n");
|
||||
return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dss_uninit_connections(struct omap_dss_device *dssdev)
|
||||
{
|
||||
if (dssdev->output) {
|
||||
struct omap_overlay_manager *mgr = dssdev->output->manager;
|
||||
|
||||
if (mgr)
|
||||
mgr->unset_output(mgr);
|
||||
|
||||
omapdss_output_unset_device(dssdev->output);
|
||||
}
|
||||
}
|
||||
|
||||
int dss_init_device(struct platform_device *pdev,
|
||||
struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct device_attribute *attr;
|
||||
int i;
|
||||
int r;
|
||||
int i, r;
|
||||
const char *def_disp_name = dss_get_default_display_name();
|
||||
bool force;
|
||||
|
||||
force = def_disp_name && strcmp(def_disp_name, dssdev->name) == 0;
|
||||
dss_init_connections(dssdev, force);
|
||||
|
||||
/* create device sysfs files */
|
||||
i = 0;
|
||||
while ((attr = display_sysfs_attrs[i++]) != NULL) {
|
||||
r = device_create_file(&dssdev->dev, attr);
|
||||
if (r)
|
||||
if (r) {
|
||||
for (i = i - 2; i >= 0; i--) {
|
||||
attr = display_sysfs_attrs[i];
|
||||
device_remove_file(&dssdev->dev, attr);
|
||||
}
|
||||
|
||||
dss_uninit_connections(dssdev);
|
||||
|
||||
DSSERR("failed to create sysfs file\n");
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
/* create display? sysfs links */
|
||||
r = sysfs_create_link(&pdev->dev.kobj, &dssdev->dev.kobj,
|
||||
dev_name(&dssdev->dev));
|
||||
if (r)
|
||||
if (r) {
|
||||
while ((attr = display_sysfs_attrs[i++]) != NULL)
|
||||
device_remove_file(&dssdev->dev, attr);
|
||||
|
||||
dss_uninit_connections(dssdev);
|
||||
|
||||
DSSERR("failed to create sysfs display link\n");
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void dss_uninit_device(struct platform_device *pdev,
|
||||
@ -349,8 +444,7 @@ void dss_uninit_device(struct platform_device *pdev,
|
||||
while ((attr = display_sysfs_attrs[i++]) != NULL)
|
||||
device_remove_file(&dssdev->dev, attr);
|
||||
|
||||
if (dssdev->manager)
|
||||
dssdev->manager->unset_device(dssdev->manager);
|
||||
dss_uninit_connections(dssdev);
|
||||
}
|
||||
|
||||
static int dss_suspend_device(struct device *dev, void *data)
|
||||
|
@ -29,17 +29,24 @@
|
||||
#include <linux/errno.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
#include <video/omapdss.h>
|
||||
#include <plat/cpu.h>
|
||||
|
||||
#include "dss.h"
|
||||
#include "dss_features.h"
|
||||
|
||||
static struct {
|
||||
struct regulator *vdds_dsi_reg;
|
||||
struct platform_device *dsidev;
|
||||
|
||||
struct mutex lock;
|
||||
|
||||
struct omap_video_timings timings;
|
||||
struct dss_lcd_mgr_config mgr_config;
|
||||
int data_lines;
|
||||
|
||||
struct omap_dss_output output;
|
||||
} dpi;
|
||||
|
||||
static struct platform_device *dpi_get_dsidev(enum omap_dss_clk_source clk)
|
||||
@ -121,7 +128,8 @@ static int dpi_set_dispc_clk(struct omap_dss_device *dssdev,
|
||||
|
||||
static int dpi_set_mode(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct omap_video_timings *t = &dssdev->panel.timings;
|
||||
struct omap_video_timings *t = &dpi.timings;
|
||||
struct omap_overlay_manager *mgr = dssdev->output->manager;
|
||||
int lck_div = 0, pck_div = 0;
|
||||
unsigned long fck = 0;
|
||||
unsigned long pck;
|
||||
@ -146,37 +154,44 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
|
||||
t->pixel_clock = pck;
|
||||
}
|
||||
|
||||
dss_mgr_set_timings(dssdev->manager, t);
|
||||
dss_mgr_set_timings(mgr, t);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dpi_config_lcd_manager(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct omap_overlay_manager *mgr = dssdev->output->manager;
|
||||
|
||||
dpi.mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS;
|
||||
|
||||
dpi.mgr_config.stallmode = false;
|
||||
dpi.mgr_config.fifohandcheck = false;
|
||||
|
||||
dpi.mgr_config.video_port_width = dssdev->phy.dpi.data_lines;
|
||||
dpi.mgr_config.video_port_width = dpi.data_lines;
|
||||
|
||||
dpi.mgr_config.lcden_sig_polarity = 0;
|
||||
|
||||
dss_mgr_set_lcd_config(dssdev->manager, &dpi.mgr_config);
|
||||
dss_mgr_set_lcd_config(mgr, &dpi.mgr_config);
|
||||
}
|
||||
|
||||
int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct omap_dss_output *out = dssdev->output;
|
||||
int r;
|
||||
|
||||
if (cpu_is_omap34xx() && !dpi.vdds_dsi_reg) {
|
||||
mutex_lock(&dpi.lock);
|
||||
|
||||
if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI) && !dpi.vdds_dsi_reg) {
|
||||
DSSERR("no VDSS_DSI regulator\n");
|
||||
return -ENODEV;
|
||||
r = -ENODEV;
|
||||
goto err_no_reg;
|
||||
}
|
||||
|
||||
if (dssdev->manager == NULL) {
|
||||
DSSERR("failed to enable display: no manager\n");
|
||||
return -ENODEV;
|
||||
if (out == NULL || out->manager == NULL) {
|
||||
DSSERR("failed to enable display: no output/manager\n");
|
||||
r = -ENODEV;
|
||||
goto err_no_out_mgr;
|
||||
}
|
||||
|
||||
r = omap_dss_start_device(dssdev);
|
||||
@ -185,7 +200,7 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
|
||||
goto err_start_dev;
|
||||
}
|
||||
|
||||
if (cpu_is_omap34xx()) {
|
||||
if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) {
|
||||
r = regulator_enable(dpi.vdds_dsi_reg);
|
||||
if (r)
|
||||
goto err_reg_enable;
|
||||
@ -195,6 +210,10 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
|
||||
if (r)
|
||||
goto err_get_dispc;
|
||||
|
||||
r = dss_dpi_select_source(dssdev->channel);
|
||||
if (r)
|
||||
goto err_src_sel;
|
||||
|
||||
if (dpi_use_dsi_pll(dssdev)) {
|
||||
r = dsi_runtime_get(dpi.dsidev);
|
||||
if (r)
|
||||
@ -213,10 +232,12 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
|
||||
|
||||
mdelay(2);
|
||||
|
||||
r = dss_mgr_enable(dssdev->manager);
|
||||
r = dss_mgr_enable(out->manager);
|
||||
if (r)
|
||||
goto err_mgr_enable;
|
||||
|
||||
mutex_unlock(&dpi.lock);
|
||||
|
||||
return 0;
|
||||
|
||||
err_mgr_enable:
|
||||
@ -227,20 +248,28 @@ err_dsi_pll_init:
|
||||
if (dpi_use_dsi_pll(dssdev))
|
||||
dsi_runtime_put(dpi.dsidev);
|
||||
err_get_dsi:
|
||||
err_src_sel:
|
||||
dispc_runtime_put();
|
||||
err_get_dispc:
|
||||
if (cpu_is_omap34xx())
|
||||
if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI))
|
||||
regulator_disable(dpi.vdds_dsi_reg);
|
||||
err_reg_enable:
|
||||
omap_dss_stop_device(dssdev);
|
||||
err_start_dev:
|
||||
err_no_out_mgr:
|
||||
err_no_reg:
|
||||
mutex_unlock(&dpi.lock);
|
||||
return r;
|
||||
}
|
||||
EXPORT_SYMBOL(omapdss_dpi_display_enable);
|
||||
|
||||
void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
|
||||
{
|
||||
dss_mgr_disable(dssdev->manager);
|
||||
struct omap_overlay_manager *mgr = dssdev->output->manager;
|
||||
|
||||
mutex_lock(&dpi.lock);
|
||||
|
||||
dss_mgr_disable(mgr);
|
||||
|
||||
if (dpi_use_dsi_pll(dssdev)) {
|
||||
dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
|
||||
@ -250,44 +279,39 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
|
||||
|
||||
dispc_runtime_put();
|
||||
|
||||
if (cpu_is_omap34xx())
|
||||
if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI))
|
||||
regulator_disable(dpi.vdds_dsi_reg);
|
||||
|
||||
omap_dss_stop_device(dssdev);
|
||||
|
||||
mutex_unlock(&dpi.lock);
|
||||
}
|
||||
EXPORT_SYMBOL(omapdss_dpi_display_disable);
|
||||
|
||||
void dpi_set_timings(struct omap_dss_device *dssdev,
|
||||
struct omap_video_timings *timings)
|
||||
void omapdss_dpi_set_timings(struct omap_dss_device *dssdev,
|
||||
struct omap_video_timings *timings)
|
||||
{
|
||||
int r;
|
||||
|
||||
DSSDBG("dpi_set_timings\n");
|
||||
dssdev->panel.timings = *timings;
|
||||
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
|
||||
r = dispc_runtime_get();
|
||||
if (r)
|
||||
return;
|
||||
|
||||
dpi_set_mode(dssdev);
|
||||
mutex_lock(&dpi.lock);
|
||||
|
||||
dispc_runtime_put();
|
||||
} else {
|
||||
dss_mgr_set_timings(dssdev->manager, timings);
|
||||
}
|
||||
dpi.timings = *timings;
|
||||
|
||||
mutex_unlock(&dpi.lock);
|
||||
}
|
||||
EXPORT_SYMBOL(dpi_set_timings);
|
||||
EXPORT_SYMBOL(omapdss_dpi_set_timings);
|
||||
|
||||
int dpi_check_timings(struct omap_dss_device *dssdev,
|
||||
struct omap_video_timings *timings)
|
||||
{
|
||||
int r;
|
||||
struct omap_overlay_manager *mgr = dssdev->output->manager;
|
||||
int lck_div, pck_div;
|
||||
unsigned long fck;
|
||||
unsigned long pck;
|
||||
struct dispc_clock_info dispc_cinfo;
|
||||
|
||||
if (dss_mgr_check_timings(dssdev->manager, timings))
|
||||
if (dss_mgr_check_timings(mgr, timings))
|
||||
return -EINVAL;
|
||||
|
||||
if (timings->pixel_clock == 0)
|
||||
@ -325,11 +349,22 @@ int dpi_check_timings(struct omap_dss_device *dssdev,
|
||||
}
|
||||
EXPORT_SYMBOL(dpi_check_timings);
|
||||
|
||||
void omapdss_dpi_set_data_lines(struct omap_dss_device *dssdev, int data_lines)
|
||||
{
|
||||
mutex_lock(&dpi.lock);
|
||||
|
||||
dpi.data_lines = data_lines;
|
||||
|
||||
mutex_unlock(&dpi.lock);
|
||||
}
|
||||
EXPORT_SYMBOL(omapdss_dpi_set_data_lines);
|
||||
|
||||
static int __init dpi_init_display(struct omap_dss_device *dssdev)
|
||||
{
|
||||
DSSDBG("init_display\n");
|
||||
|
||||
if (cpu_is_omap34xx() && dpi.vdds_dsi_reg == NULL) {
|
||||
if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI) &&
|
||||
dpi.vdds_dsi_reg == NULL) {
|
||||
struct regulator *vdds_dsi;
|
||||
|
||||
vdds_dsi = dss_get_vdds_dsi();
|
||||
@ -351,10 +386,14 @@ static int __init dpi_init_display(struct omap_dss_device *dssdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __init dpi_probe_pdata(struct platform_device *pdev)
|
||||
static struct omap_dss_device * __init dpi_find_dssdev(struct platform_device *pdev)
|
||||
{
|
||||
struct omap_dss_board_info *pdata = pdev->dev.platform_data;
|
||||
int i, r;
|
||||
const char *def_disp_name = dss_get_default_display_name();
|
||||
struct omap_dss_device *def_dssdev;
|
||||
int i;
|
||||
|
||||
def_dssdev = NULL;
|
||||
|
||||
for (i = 0; i < pdata->num_devices; ++i) {
|
||||
struct omap_dss_device *dssdev = pdata->devices[i];
|
||||
@ -362,21 +401,75 @@ static void __init dpi_probe_pdata(struct platform_device *pdev)
|
||||
if (dssdev->type != OMAP_DISPLAY_TYPE_DPI)
|
||||
continue;
|
||||
|
||||
r = dpi_init_display(dssdev);
|
||||
if (r) {
|
||||
DSSERR("device %s init failed: %d\n", dssdev->name, r);
|
||||
continue;
|
||||
}
|
||||
if (def_dssdev == NULL)
|
||||
def_dssdev = dssdev;
|
||||
|
||||
r = omap_dss_register_device(dssdev, &pdev->dev, i);
|
||||
if (r)
|
||||
DSSERR("device %s register failed: %d\n",
|
||||
dssdev->name, r);
|
||||
if (def_disp_name != NULL &&
|
||||
strcmp(dssdev->name, def_disp_name) == 0) {
|
||||
def_dssdev = dssdev;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return def_dssdev;
|
||||
}
|
||||
|
||||
static void __init dpi_probe_pdata(struct platform_device *dpidev)
|
||||
{
|
||||
struct omap_dss_device *plat_dssdev;
|
||||
struct omap_dss_device *dssdev;
|
||||
int r;
|
||||
|
||||
plat_dssdev = dpi_find_dssdev(dpidev);
|
||||
|
||||
if (!plat_dssdev)
|
||||
return;
|
||||
|
||||
dssdev = dss_alloc_and_init_device(&dpidev->dev);
|
||||
if (!dssdev)
|
||||
return;
|
||||
|
||||
dss_copy_device_pdata(dssdev, plat_dssdev);
|
||||
|
||||
r = dpi_init_display(dssdev);
|
||||
if (r) {
|
||||
DSSERR("device %s init failed: %d\n", dssdev->name, r);
|
||||
dss_put_device(dssdev);
|
||||
return;
|
||||
}
|
||||
|
||||
r = dss_add_device(dssdev);
|
||||
if (r) {
|
||||
DSSERR("device %s register failed: %d\n", dssdev->name, r);
|
||||
dss_put_device(dssdev);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void __init dpi_init_output(struct platform_device *pdev)
|
||||
{
|
||||
struct omap_dss_output *out = &dpi.output;
|
||||
|
||||
out->pdev = pdev;
|
||||
out->id = OMAP_DSS_OUTPUT_DPI;
|
||||
out->type = OMAP_DISPLAY_TYPE_DPI;
|
||||
|
||||
dss_register_output(out);
|
||||
}
|
||||
|
||||
static void __exit dpi_uninit_output(struct platform_device *pdev)
|
||||
{
|
||||
struct omap_dss_output *out = &dpi.output;
|
||||
|
||||
dss_unregister_output(out);
|
||||
}
|
||||
|
||||
static int __init omap_dpi_probe(struct platform_device *pdev)
|
||||
{
|
||||
mutex_init(&dpi.lock);
|
||||
|
||||
dpi_init_output(pdev);
|
||||
|
||||
dpi_probe_pdata(pdev);
|
||||
|
||||
return 0;
|
||||
@ -384,7 +477,9 @@ static int __init omap_dpi_probe(struct platform_device *pdev)
|
||||
|
||||
static int __exit omap_dpi_remove(struct platform_device *pdev)
|
||||
{
|
||||
omap_dss_unregister_child_devices(&pdev->dev);
|
||||
dss_unregister_child_devices(&pdev->dev);
|
||||
|
||||
dpi_uninit_output(pdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -31,11 +31,11 @@
|
||||
#include <linux/clk.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/gfp.h>
|
||||
|
||||
#include <video/omapdss.h>
|
||||
|
||||
#include <plat/cpu.h>
|
||||
#include <plat/clock.h>
|
||||
|
||||
#include "dss.h"
|
||||
#include "dss_features.h"
|
||||
@ -65,6 +65,13 @@ struct dss_reg {
|
||||
static int dss_runtime_get(void);
|
||||
static void dss_runtime_put(void);
|
||||
|
||||
struct dss_features {
|
||||
u8 fck_div_max;
|
||||
u8 dss_fck_multiplier;
|
||||
const char *clk_name;
|
||||
int (*dpi_select_source)(enum omap_channel channel);
|
||||
};
|
||||
|
||||
static struct {
|
||||
struct platform_device *pdev;
|
||||
void __iomem *base;
|
||||
@ -83,6 +90,8 @@ static struct {
|
||||
|
||||
bool ctx_valid;
|
||||
u32 ctx[DSS_SZ_REGS / sizeof(u32)];
|
||||
|
||||
const struct dss_features *feat;
|
||||
} dss;
|
||||
|
||||
static const char * const dss_generic_clk_source_names[] = {
|
||||
@ -144,7 +153,7 @@ static void dss_restore_context(void)
|
||||
#undef SR
|
||||
#undef RR
|
||||
|
||||
void dss_sdi_init(u8 datapairs)
|
||||
void dss_sdi_init(int datapairs)
|
||||
{
|
||||
u32 l;
|
||||
|
||||
@ -236,7 +245,6 @@ const char *dss_get_generic_clk_source_name(enum omap_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;
|
||||
@ -259,18 +267,10 @@ void dss_dump_clocks(struct seq_file *s)
|
||||
|
||||
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);
|
||||
seq_printf(s, "%s (%s) = %lu / %lu * %d = %lu\n",
|
||||
fclk_name, fclk_real_name, dpll4_ck_rate,
|
||||
dpll4_ck_rate / dpll4_m4_ck_rate,
|
||||
dss.feat->dss_fck_multiplier, fclk_rate);
|
||||
} else {
|
||||
seq_printf(s, "%s (%s) = %lu\n",
|
||||
fclk_name, fclk_real_name,
|
||||
@ -431,31 +431,6 @@ enum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel)
|
||||
}
|
||||
}
|
||||
|
||||
/* calculate clock rates using dividers in cinfo */
|
||||
int dss_calc_clock_rates(struct dss_clock_info *cinfo)
|
||||
{
|
||||
if (dss.dpll4_m4_ck) {
|
||||
unsigned long prate;
|
||||
u16 fck_div_max = 16;
|
||||
|
||||
if (cpu_is_omap3630() || cpu_is_omap44xx())
|
||||
fck_div_max = 32;
|
||||
|
||||
if (cinfo->fck_div > fck_div_max || cinfo->fck_div == 0)
|
||||
return -EINVAL;
|
||||
|
||||
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 = clk_get_rate(dss.dss_clk);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dss_set_clock_div(struct dss_clock_info *cinfo)
|
||||
{
|
||||
if (dss.dpll4_m4_ck) {
|
||||
@ -478,26 +453,6 @@ int dss_set_clock_div(struct dss_clock_info *cinfo)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dss_get_clock_div(struct dss_clock_info *cinfo)
|
||||
{
|
||||
cinfo->fck = clk_get_rate(dss.dss_clk);
|
||||
|
||||
if (dss.dpll4_m4_ck) {
|
||||
unsigned long prate;
|
||||
|
||||
prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
|
||||
|
||||
if (cpu_is_omap3630() || cpu_is_omap44xx())
|
||||
cinfo->fck_div = prate / (cinfo->fck);
|
||||
else
|
||||
cinfo->fck_div = prate / (cinfo->fck / 2);
|
||||
} else {
|
||||
cinfo->fck_div = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long dss_get_dpll4_rate(void)
|
||||
{
|
||||
if (dss.dpll4_m4_ck)
|
||||
@ -515,7 +470,7 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
|
||||
|
||||
unsigned long fck, max_dss_fck;
|
||||
|
||||
u16 fck_div, fck_div_max = 16;
|
||||
u16 fck_div;
|
||||
|
||||
int match = 0;
|
||||
int min_fck_per_pck;
|
||||
@ -525,9 +480,8 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
|
||||
max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
|
||||
|
||||
fck = clk_get_rate(dss.dss_clk);
|
||||
if (req_pck == dss.cache_req_pck &&
|
||||
((cpu_is_omap34xx() && prate == dss.cache_prate) ||
|
||||
dss.cache_dss_cinfo.fck == fck)) {
|
||||
if (req_pck == dss.cache_req_pck && prate == dss.cache_prate &&
|
||||
dss.cache_dss_cinfo.fck == fck) {
|
||||
DSSDBG("dispc clock info found from cache.\n");
|
||||
*dss_cinfo = dss.cache_dss_cinfo;
|
||||
*dispc_cinfo = dss.cache_dispc_cinfo;
|
||||
@ -564,16 +518,10 @@ retry:
|
||||
|
||||
goto found;
|
||||
} else {
|
||||
if (cpu_is_omap3630() || cpu_is_omap44xx())
|
||||
fck_div_max = 32;
|
||||
|
||||
for (fck_div = fck_div_max; fck_div > 0; --fck_div) {
|
||||
for (fck_div = dss.feat->fck_div_max; fck_div > 0; --fck_div) {
|
||||
struct dispc_clock_info cur_dispc;
|
||||
|
||||
if (fck_div_max == 32)
|
||||
fck = prate / fck_div;
|
||||
else
|
||||
fck = prate / fck_div * 2;
|
||||
fck = prate / fck_div * dss.feat->dss_fck_multiplier;
|
||||
|
||||
if (fck > max_dss_fck)
|
||||
continue;
|
||||
@ -648,9 +596,18 @@ void dss_set_dac_pwrdn_bgz(bool enable)
|
||||
REG_FLD_MOD(DSS_CONTROL, enable, 5, 5); /* DAC Power-Down Control */
|
||||
}
|
||||
|
||||
void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select hdmi)
|
||||
void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select src)
|
||||
{
|
||||
REG_FLD_MOD(DSS_CONTROL, hdmi, 15, 15); /* VENC_HDMI_SWITCH */
|
||||
enum omap_display_type dp;
|
||||
dp = dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_DIGIT);
|
||||
|
||||
/* Complain about invalid selections */
|
||||
WARN_ON((src == DSS_VENC_TV_CLK) && !(dp & OMAP_DISPLAY_TYPE_VENC));
|
||||
WARN_ON((src == DSS_HDMI_M_PCLK) && !(dp & OMAP_DISPLAY_TYPE_HDMI));
|
||||
|
||||
/* Select only if we have options */
|
||||
if ((dp & OMAP_DISPLAY_TYPE_VENC) && (dp & OMAP_DISPLAY_TYPE_HDMI))
|
||||
REG_FLD_MOD(DSS_CONTROL, src, 15, 15); /* VENC_HDMI_SWITCH */
|
||||
}
|
||||
|
||||
enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void)
|
||||
@ -661,9 +618,71 @@ enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void)
|
||||
if ((displays & OMAP_DISPLAY_TYPE_HDMI) == 0)
|
||||
return DSS_VENC_TV_CLK;
|
||||
|
||||
if ((displays & OMAP_DISPLAY_TYPE_VENC) == 0)
|
||||
return DSS_HDMI_M_PCLK;
|
||||
|
||||
return REG_GET(DSS_CONTROL, 15, 15);
|
||||
}
|
||||
|
||||
static int dss_dpi_select_source_omap2_omap3(enum omap_channel channel)
|
||||
{
|
||||
if (channel != OMAP_DSS_CHANNEL_LCD)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dss_dpi_select_source_omap4(enum omap_channel channel)
|
||||
{
|
||||
int val;
|
||||
|
||||
switch (channel) {
|
||||
case OMAP_DSS_CHANNEL_LCD2:
|
||||
val = 0;
|
||||
break;
|
||||
case OMAP_DSS_CHANNEL_DIGIT:
|
||||
val = 1;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
REG_FLD_MOD(DSS_CONTROL, val, 17, 17);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dss_dpi_select_source_omap5(enum omap_channel channel)
|
||||
{
|
||||
int val;
|
||||
|
||||
switch (channel) {
|
||||
case OMAP_DSS_CHANNEL_LCD:
|
||||
val = 1;
|
||||
break;
|
||||
case OMAP_DSS_CHANNEL_LCD2:
|
||||
val = 2;
|
||||
break;
|
||||
case OMAP_DSS_CHANNEL_LCD3:
|
||||
val = 3;
|
||||
break;
|
||||
case OMAP_DSS_CHANNEL_DIGIT:
|
||||
val = 0;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
REG_FLD_MOD(DSS_CONTROL, val, 17, 16);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dss_dpi_select_source(enum omap_channel channel)
|
||||
{
|
||||
return dss.feat->dpi_select_source(channel);
|
||||
}
|
||||
|
||||
static int dss_get_clocks(void)
|
||||
{
|
||||
struct clk *clk;
|
||||
@ -678,22 +697,11 @@ static int dss_get_clocks(void)
|
||||
|
||||
dss.dss_clk = clk;
|
||||
|
||||
if (cpu_is_omap34xx()) {
|
||||
clk = clk_get(NULL, "dpll4_m4_ck");
|
||||
if (IS_ERR(clk)) {
|
||||
DSSERR("Failed to get dpll4_m4_ck\n");
|
||||
r = PTR_ERR(clk);
|
||||
goto err;
|
||||
}
|
||||
} else if (cpu_is_omap44xx()) {
|
||||
clk = clk_get(NULL, "dpll_per_m5x2_ck");
|
||||
if (IS_ERR(clk)) {
|
||||
DSSERR("Failed to get dpll_per_m5x2_ck\n");
|
||||
r = PTR_ERR(clk);
|
||||
goto err;
|
||||
}
|
||||
} else { /* omap24xx */
|
||||
clk = NULL;
|
||||
clk = clk_get(NULL, dss.feat->clk_name);
|
||||
if (IS_ERR(clk)) {
|
||||
DSSERR("Failed to get %s\n", dss.feat->clk_name);
|
||||
r = PTR_ERR(clk);
|
||||
goto err;
|
||||
}
|
||||
|
||||
dss.dpll4_m4_ck = clk;
|
||||
@ -749,6 +757,71 @@ void dss_debug_dump_clocks(struct seq_file *s)
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct dss_features omap24xx_dss_feats __initconst = {
|
||||
.fck_div_max = 16,
|
||||
.dss_fck_multiplier = 2,
|
||||
.clk_name = NULL,
|
||||
.dpi_select_source = &dss_dpi_select_source_omap2_omap3,
|
||||
};
|
||||
|
||||
static const struct dss_features omap34xx_dss_feats __initconst = {
|
||||
.fck_div_max = 16,
|
||||
.dss_fck_multiplier = 2,
|
||||
.clk_name = "dpll4_m4_ck",
|
||||
.dpi_select_source = &dss_dpi_select_source_omap2_omap3,
|
||||
};
|
||||
|
||||
static const struct dss_features omap3630_dss_feats __initconst = {
|
||||
.fck_div_max = 32,
|
||||
.dss_fck_multiplier = 1,
|
||||
.clk_name = "dpll4_m4_ck",
|
||||
.dpi_select_source = &dss_dpi_select_source_omap2_omap3,
|
||||
};
|
||||
|
||||
static const struct dss_features omap44xx_dss_feats __initconst = {
|
||||
.fck_div_max = 32,
|
||||
.dss_fck_multiplier = 1,
|
||||
.clk_name = "dpll_per_m5x2_ck",
|
||||
.dpi_select_source = &dss_dpi_select_source_omap4,
|
||||
};
|
||||
|
||||
static const struct dss_features omap54xx_dss_feats __initconst = {
|
||||
.fck_div_max = 64,
|
||||
.dss_fck_multiplier = 1,
|
||||
.clk_name = "dpll_per_h12x2_ck",
|
||||
.dpi_select_source = &dss_dpi_select_source_omap5,
|
||||
};
|
||||
|
||||
static int __init dss_init_features(struct device *dev)
|
||||
{
|
||||
const struct dss_features *src;
|
||||
struct dss_features *dst;
|
||||
|
||||
dst = devm_kzalloc(dev, sizeof(*dst), GFP_KERNEL);
|
||||
if (!dst) {
|
||||
dev_err(dev, "Failed to allocate local DSS Features\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (cpu_is_omap24xx())
|
||||
src = &omap24xx_dss_feats;
|
||||
else if (cpu_is_omap34xx())
|
||||
src = &omap34xx_dss_feats;
|
||||
else if (cpu_is_omap3630())
|
||||
src = &omap3630_dss_feats;
|
||||
else if (cpu_is_omap44xx())
|
||||
src = &omap44xx_dss_feats;
|
||||
else if (soc_is_omap54xx())
|
||||
src = &omap54xx_dss_feats;
|
||||
else
|
||||
return -ENODEV;
|
||||
|
||||
memcpy(dst, src, sizeof(*dst));
|
||||
dss.feat = dst;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* DSS HW IP initialisation */
|
||||
static int __init omap_dsshw_probe(struct platform_device *pdev)
|
||||
{
|
||||
@ -758,6 +831,10 @@ static int __init omap_dsshw_probe(struct platform_device *pdev)
|
||||
|
||||
dss.pdev = pdev;
|
||||
|
||||
r = dss_init_features(&dss.pdev->dev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
dss_mem = platform_get_resource(dss.pdev, IORESOURCE_MEM, 0);
|
||||
if (!dss_mem) {
|
||||
DSSERR("can't get IORESOURCE_MEM DSS\n");
|
||||
|
@ -113,6 +113,17 @@ enum dss_dsi_content_type {
|
||||
DSS_DSI_CONTENT_GENERIC,
|
||||
};
|
||||
|
||||
enum dss_writeback_channel {
|
||||
DSS_WB_LCD1_MGR = 0,
|
||||
DSS_WB_LCD2_MGR = 1,
|
||||
DSS_WB_TV_MGR = 2,
|
||||
DSS_WB_OVL0 = 3,
|
||||
DSS_WB_OVL1 = 4,
|
||||
DSS_WB_OVL2 = 5,
|
||||
DSS_WB_OVL3 = 6,
|
||||
DSS_WB_LCD3_MGR = 7,
|
||||
};
|
||||
|
||||
struct dss_clock_info {
|
||||
/* rates that we get with dividers below */
|
||||
unsigned long fck;
|
||||
@ -175,6 +186,7 @@ struct seq_file;
|
||||
struct platform_device;
|
||||
|
||||
/* core */
|
||||
const char *dss_get_default_display_name(void);
|
||||
struct bus_type *dss_get_bus(void);
|
||||
struct regulator *dss_get_vdds_dsi(void);
|
||||
struct regulator *dss_get_vdds_sdi(void);
|
||||
@ -184,10 +196,13 @@ void dss_dsi_disable_pads(int dsi_id, unsigned lane_mask);
|
||||
int dss_set_min_bus_tput(struct device *dev, unsigned long tput);
|
||||
int dss_debugfs_create_file(const char *name, void (*write)(struct seq_file *));
|
||||
|
||||
int omap_dss_register_device(struct omap_dss_device *dssdev,
|
||||
struct device *parent, int disp_num);
|
||||
void omap_dss_unregister_device(struct omap_dss_device *dssdev);
|
||||
void omap_dss_unregister_child_devices(struct device *parent);
|
||||
struct omap_dss_device *dss_alloc_and_init_device(struct device *parent);
|
||||
int dss_add_device(struct omap_dss_device *dssdev);
|
||||
void dss_unregister_device(struct omap_dss_device *dssdev);
|
||||
void dss_unregister_child_devices(struct device *parent);
|
||||
void dss_put_device(struct omap_dss_device *dssdev);
|
||||
void dss_copy_device_pdata(struct omap_dss_device *dst,
|
||||
const struct omap_dss_device *src);
|
||||
|
||||
/* apply */
|
||||
void dss_apply_init(void);
|
||||
@ -205,8 +220,11 @@ void dss_mgr_get_info(struct omap_overlay_manager *mgr,
|
||||
int dss_mgr_set_device(struct omap_overlay_manager *mgr,
|
||||
struct omap_dss_device *dssdev);
|
||||
int dss_mgr_unset_device(struct omap_overlay_manager *mgr);
|
||||
int dss_mgr_set_output(struct omap_overlay_manager *mgr,
|
||||
struct omap_dss_output *output);
|
||||
int dss_mgr_unset_output(struct omap_overlay_manager *mgr);
|
||||
void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
|
||||
struct omap_video_timings *timings);
|
||||
const struct omap_video_timings *timings);
|
||||
void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr,
|
||||
const struct dss_lcd_mgr_config *config);
|
||||
const struct omap_video_timings *dss_mgr_get_timings(struct omap_overlay_manager *mgr);
|
||||
@ -222,12 +240,17 @@ int dss_ovl_set_manager(struct omap_overlay *ovl,
|
||||
struct omap_overlay_manager *mgr);
|
||||
int dss_ovl_unset_manager(struct omap_overlay *ovl);
|
||||
|
||||
/* output */
|
||||
void dss_register_output(struct omap_dss_output *out);
|
||||
void dss_unregister_output(struct omap_dss_output *out);
|
||||
struct omap_dss_output *omapdss_get_output_from_dssdev(struct omap_dss_device *dssdev);
|
||||
|
||||
/* display */
|
||||
int dss_suspend_all_devices(void);
|
||||
int dss_resume_all_devices(void);
|
||||
void dss_disable_all_devices(void);
|
||||
|
||||
void dss_init_device(struct platform_device *pdev,
|
||||
int dss_init_device(struct platform_device *pdev,
|
||||
struct omap_dss_device *dssdev);
|
||||
void dss_uninit_device(struct platform_device *pdev,
|
||||
struct omap_dss_device *dssdev);
|
||||
@ -254,22 +277,29 @@ static inline bool dss_mgr_is_lcd(enum omap_channel id)
|
||||
return false;
|
||||
}
|
||||
|
||||
int dss_manager_kobj_init(struct omap_overlay_manager *mgr,
|
||||
struct platform_device *pdev);
|
||||
void dss_manager_kobj_uninit(struct omap_overlay_manager *mgr);
|
||||
|
||||
/* overlay */
|
||||
void dss_init_overlays(struct platform_device *pdev);
|
||||
void dss_uninit_overlays(struct platform_device *pdev);
|
||||
void dss_overlay_setup_dispc_manager(struct omap_overlay_manager *mgr);
|
||||
void dss_recheck_connections(struct omap_dss_device *dssdev, bool force);
|
||||
int dss_ovl_simple_check(struct omap_overlay *ovl,
|
||||
const struct omap_overlay_info *info);
|
||||
int dss_ovl_check(struct omap_overlay *ovl, struct omap_overlay_info *info,
|
||||
const struct omap_video_timings *mgr_timings);
|
||||
bool dss_ovl_use_replication(struct dss_lcd_mgr_config config,
|
||||
enum omap_color_mode mode);
|
||||
int dss_overlay_kobj_init(struct omap_overlay *ovl,
|
||||
struct platform_device *pdev);
|
||||
void dss_overlay_kobj_uninit(struct omap_overlay *ovl);
|
||||
|
||||
/* DSS */
|
||||
int dss_init_platform_driver(void) __init;
|
||||
void dss_uninit_platform_driver(void);
|
||||
|
||||
int dss_dpi_select_source(enum omap_channel channel);
|
||||
void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select);
|
||||
enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void);
|
||||
const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src);
|
||||
@ -279,7 +309,7 @@ void dss_dump_clocks(struct seq_file *s);
|
||||
void dss_debug_dump_clocks(struct seq_file *s);
|
||||
#endif
|
||||
|
||||
void dss_sdi_init(u8 datapairs);
|
||||
void dss_sdi_init(int datapairs);
|
||||
int dss_sdi_enable(void);
|
||||
void dss_sdi_disable(void);
|
||||
|
||||
@ -296,9 +326,7 @@ void dss_set_venc_output(enum omap_dss_venc_type type);
|
||||
void dss_set_dac_pwrdn_bgz(bool enable);
|
||||
|
||||
unsigned long dss_get_dpll4_rate(void);
|
||||
int dss_calc_clock_rates(struct dss_clock_info *cinfo);
|
||||
int dss_set_clock_div(struct dss_clock_info *cinfo);
|
||||
int dss_get_clock_div(struct dss_clock_info *cinfo);
|
||||
int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
|
||||
struct dispc_clock_info *dispc_cinfo);
|
||||
|
||||
@ -427,8 +455,9 @@ void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high);
|
||||
void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane,
|
||||
u32 *fifo_low, u32 *fifo_high, bool use_fifomerge,
|
||||
bool manual_update);
|
||||
int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
|
||||
bool replication, const struct omap_video_timings *mgr_timings);
|
||||
int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
|
||||
bool replication, const struct omap_video_timings *mgr_timings,
|
||||
bool mem_to_mem);
|
||||
int dispc_ovl_enable(enum omap_plane plane, bool enable);
|
||||
void dispc_ovl_set_channel_out(enum omap_plane plane,
|
||||
enum omap_channel channel);
|
||||
@ -457,6 +486,15 @@ int dispc_mgr_get_clock_div(enum omap_channel channel,
|
||||
void dispc_mgr_setup(enum omap_channel channel,
|
||||
struct omap_overlay_manager_info *info);
|
||||
|
||||
u32 dispc_wb_get_framedone_irq(void);
|
||||
bool dispc_wb_go_busy(void);
|
||||
void dispc_wb_go(void);
|
||||
void dispc_wb_enable(bool enable);
|
||||
bool dispc_wb_is_enabled(void);
|
||||
void dispc_wb_set_channel_in(enum dss_writeback_channel channel);
|
||||
int dispc_wb_setup(const struct omap_dss_writeback_info *wi,
|
||||
bool mem_to_mem, const struct omap_video_timings *timings);
|
||||
|
||||
/* VENC */
|
||||
#ifdef CONFIG_OMAP2_DSS_VENC
|
||||
int venc_init_platform_driver(void) __init;
|
||||
@ -469,6 +507,20 @@ static inline unsigned long venc_get_pixel_clock(void)
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
int omapdss_venc_display_enable(struct omap_dss_device *dssdev);
|
||||
void omapdss_venc_display_disable(struct omap_dss_device *dssdev);
|
||||
void omapdss_venc_set_timings(struct omap_dss_device *dssdev,
|
||||
struct omap_video_timings *timings);
|
||||
int omapdss_venc_check_timings(struct omap_dss_device *dssdev,
|
||||
struct omap_video_timings *timings);
|
||||
u32 omapdss_venc_get_wss(struct omap_dss_device *dssdev);
|
||||
int omapdss_venc_set_wss(struct omap_dss_device *dssdev, u32 wss);
|
||||
void omapdss_venc_set_type(struct omap_dss_device *dssdev,
|
||||
enum omap_dss_venc_type type);
|
||||
void omapdss_venc_invert_vid_out_polarity(struct omap_dss_device *dssdev,
|
||||
bool invert_polarity);
|
||||
int venc_panel_init(void);
|
||||
void venc_panel_exit(void);
|
||||
|
||||
/* HDMI */
|
||||
#ifdef CONFIG_OMAP4_DSS_HDMI
|
||||
@ -484,7 +536,8 @@ static inline unsigned long hdmi_get_pixel_clock(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);
|
||||
void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev,
|
||||
struct omap_video_timings *timings);
|
||||
int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
|
||||
struct omap_video_timings *timings);
|
||||
int omapdss_hdmi_read_edid(u8 *buf, int len);
|
||||
|
@ -46,7 +46,9 @@ struct omap_dss_features {
|
||||
|
||||
const int num_mgrs;
|
||||
const int num_ovls;
|
||||
const int num_wbs;
|
||||
const enum omap_display_type *supported_displays;
|
||||
const enum omap_dss_output_id *supported_outputs;
|
||||
const enum omap_color_mode *supported_color_modes;
|
||||
const enum omap_overlay_caps *overlay_caps;
|
||||
const char * const *clksrc_names;
|
||||
@ -106,6 +108,21 @@ static const struct dss_reg_field omap4_dss_reg_fields[] = {
|
||||
[FEAT_REG_DSIPLL_REGM_DSI] = { 30, 26 },
|
||||
};
|
||||
|
||||
static const struct dss_reg_field omap5_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, 7 },
|
||||
[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,
|
||||
@ -144,6 +161,76 @@ static const enum omap_display_type omap4_dss_supported_displays[] = {
|
||||
OMAP_DISPLAY_TYPE_DSI,
|
||||
};
|
||||
|
||||
static const enum omap_display_type omap5_dss_supported_displays[] = {
|
||||
/* OMAP_DSS_CHANNEL_LCD */
|
||||
OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI |
|
||||
OMAP_DISPLAY_TYPE_DSI,
|
||||
|
||||
/* OMAP_DSS_CHANNEL_DIGIT */
|
||||
OMAP_DISPLAY_TYPE_HDMI | OMAP_DISPLAY_TYPE_DPI,
|
||||
|
||||
/* OMAP_DSS_CHANNEL_LCD2 */
|
||||
OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI |
|
||||
OMAP_DISPLAY_TYPE_DSI,
|
||||
};
|
||||
|
||||
static const enum omap_dss_output_id omap2_dss_supported_outputs[] = {
|
||||
/* OMAP_DSS_CHANNEL_LCD */
|
||||
OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI,
|
||||
|
||||
/* OMAP_DSS_CHANNEL_DIGIT */
|
||||
OMAP_DSS_OUTPUT_VENC,
|
||||
};
|
||||
|
||||
static const enum omap_dss_output_id omap3430_dss_supported_outputs[] = {
|
||||
/* OMAP_DSS_CHANNEL_LCD */
|
||||
OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
|
||||
OMAP_DSS_OUTPUT_SDI | OMAP_DSS_OUTPUT_DSI1,
|
||||
|
||||
/* OMAP_DSS_CHANNEL_DIGIT */
|
||||
OMAP_DSS_OUTPUT_VENC,
|
||||
};
|
||||
|
||||
static const enum omap_dss_output_id omap3630_dss_supported_outputs[] = {
|
||||
/* OMAP_DSS_CHANNEL_LCD */
|
||||
OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
|
||||
OMAP_DSS_OUTPUT_DSI1,
|
||||
|
||||
/* OMAP_DSS_CHANNEL_DIGIT */
|
||||
OMAP_DSS_OUTPUT_VENC,
|
||||
};
|
||||
|
||||
static const enum omap_dss_output_id omap4_dss_supported_outputs[] = {
|
||||
/* OMAP_DSS_CHANNEL_LCD */
|
||||
OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
|
||||
OMAP_DSS_OUTPUT_DSI1,
|
||||
|
||||
/* OMAP_DSS_CHANNEL_DIGIT */
|
||||
OMAP_DSS_OUTPUT_VENC | OMAP_DSS_OUTPUT_HDMI |
|
||||
OMAP_DSS_OUTPUT_DPI,
|
||||
|
||||
/* OMAP_DSS_CHANNEL_LCD2 */
|
||||
OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
|
||||
OMAP_DSS_OUTPUT_DSI2,
|
||||
};
|
||||
|
||||
static const enum omap_dss_output_id omap5_dss_supported_outputs[] = {
|
||||
/* OMAP_DSS_CHANNEL_LCD */
|
||||
OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
|
||||
OMAP_DSS_OUTPUT_DSI1 | OMAP_DSS_OUTPUT_DSI2,
|
||||
|
||||
/* OMAP_DSS_CHANNEL_DIGIT */
|
||||
OMAP_DSS_OUTPUT_HDMI | OMAP_DSS_OUTPUT_DPI,
|
||||
|
||||
/* OMAP_DSS_CHANNEL_LCD2 */
|
||||
OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
|
||||
OMAP_DSS_OUTPUT_DSI1,
|
||||
|
||||
/* OMAP_DSS_CHANNEL_LCD3 */
|
||||
OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
|
||||
OMAP_DSS_OUTPUT_DSI2,
|
||||
};
|
||||
|
||||
static const enum omap_color_mode omap2_dss_supported_color_modes[] = {
|
||||
/* OMAP_DSS_GFX */
|
||||
OMAP_DSS_COLOR_CLUT1 | OMAP_DSS_COLOR_CLUT2 |
|
||||
@ -224,58 +311,80 @@ static const enum omap_color_mode omap4_dss_supported_color_modes[] = {
|
||||
OMAP_DSS_COLOR_ARGB16 | OMAP_DSS_COLOR_XRGB16_1555 |
|
||||
OMAP_DSS_COLOR_ARGB32 | OMAP_DSS_COLOR_RGBX16 |
|
||||
OMAP_DSS_COLOR_RGBX32,
|
||||
|
||||
/* OMAP_DSS_WB */
|
||||
OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB12U |
|
||||
OMAP_DSS_COLOR_YUV2 | OMAP_DSS_COLOR_ARGB16_1555 |
|
||||
OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_NV12 |
|
||||
OMAP_DSS_COLOR_RGBA16 | OMAP_DSS_COLOR_RGB24U |
|
||||
OMAP_DSS_COLOR_RGB24P | OMAP_DSS_COLOR_UYVY |
|
||||
OMAP_DSS_COLOR_ARGB16 | OMAP_DSS_COLOR_XRGB16_1555 |
|
||||
OMAP_DSS_COLOR_ARGB32 | OMAP_DSS_COLOR_RGBX16 |
|
||||
OMAP_DSS_COLOR_RGBX32,
|
||||
};
|
||||
|
||||
static const enum omap_overlay_caps omap2_dss_overlay_caps[] = {
|
||||
/* OMAP_DSS_GFX */
|
||||
0,
|
||||
OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
|
||||
|
||||
/* OMAP_DSS_VIDEO1 */
|
||||
OMAP_DSS_OVL_CAP_SCALE,
|
||||
OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_POS |
|
||||
OMAP_DSS_OVL_CAP_REPLICATION,
|
||||
|
||||
/* OMAP_DSS_VIDEO2 */
|
||||
OMAP_DSS_OVL_CAP_SCALE,
|
||||
OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_POS |
|
||||
OMAP_DSS_OVL_CAP_REPLICATION,
|
||||
};
|
||||
|
||||
static const enum omap_overlay_caps omap3430_dss_overlay_caps[] = {
|
||||
/* OMAP_DSS_GFX */
|
||||
OMAP_DSS_OVL_CAP_GLOBAL_ALPHA,
|
||||
OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_POS |
|
||||
OMAP_DSS_OVL_CAP_REPLICATION,
|
||||
|
||||
/* OMAP_DSS_VIDEO1 */
|
||||
OMAP_DSS_OVL_CAP_SCALE,
|
||||
OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_POS |
|
||||
OMAP_DSS_OVL_CAP_REPLICATION,
|
||||
|
||||
/* OMAP_DSS_VIDEO2 */
|
||||
OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA,
|
||||
OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
|
||||
OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
|
||||
};
|
||||
|
||||
static const enum omap_overlay_caps omap3630_dss_overlay_caps[] = {
|
||||
/* OMAP_DSS_GFX */
|
||||
OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA,
|
||||
OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA |
|
||||
OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
|
||||
|
||||
/* OMAP_DSS_VIDEO1 */
|
||||
OMAP_DSS_OVL_CAP_SCALE,
|
||||
OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_POS |
|
||||
OMAP_DSS_OVL_CAP_REPLICATION,
|
||||
|
||||
/* OMAP_DSS_VIDEO2 */
|
||||
OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
|
||||
OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA,
|
||||
OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_POS |
|
||||
OMAP_DSS_OVL_CAP_REPLICATION,
|
||||
};
|
||||
|
||||
static const enum omap_overlay_caps omap4_dss_overlay_caps[] = {
|
||||
/* OMAP_DSS_GFX */
|
||||
OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA |
|
||||
OMAP_DSS_OVL_CAP_ZORDER,
|
||||
OMAP_DSS_OVL_CAP_ZORDER | OMAP_DSS_OVL_CAP_POS |
|
||||
OMAP_DSS_OVL_CAP_REPLICATION,
|
||||
|
||||
/* OMAP_DSS_VIDEO1 */
|
||||
OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
|
||||
OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER,
|
||||
OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER |
|
||||
OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
|
||||
|
||||
/* OMAP_DSS_VIDEO2 */
|
||||
OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
|
||||
OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER,
|
||||
OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER |
|
||||
OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
|
||||
|
||||
/* OMAP_DSS_VIDEO3 */
|
||||
OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
|
||||
OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER,
|
||||
OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER |
|
||||
OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
|
||||
};
|
||||
|
||||
static const char * const omap2_dss_clk_source_names[] = {
|
||||
@ -298,6 +407,14 @@ static const char * const omap4_dss_clk_source_names[] = {
|
||||
[OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI] = "PLL2_CLK2",
|
||||
};
|
||||
|
||||
static const char * const omap5_dss_clk_source_names[] = {
|
||||
[OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "DPLL_DSI1_A_CLK1",
|
||||
[OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "DPLL_DSI1_A_CLK2",
|
||||
[OMAP_DSS_CLK_SRC_FCK] = "DSS_CLK",
|
||||
[OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC] = "DPLL_DSI1_C_CLK1",
|
||||
[OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI] = "DPLL_DSI1_C_CLK2",
|
||||
};
|
||||
|
||||
static const struct dss_param_range omap2_dss_param_range[] = {
|
||||
[FEAT_PARAM_DSS_FCK] = { 0, 173000000 },
|
||||
[FEAT_PARAM_DSS_PCD] = { 2, 255 },
|
||||
@ -326,6 +443,7 @@ static const struct dss_param_range omap3_dss_param_range[] = {
|
||||
[FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, (1 << 4) - 1 },
|
||||
[FEAT_PARAM_DSIPLL_FINT] = { 750000, 2100000 },
|
||||
[FEAT_PARAM_DSIPLL_LPDIV] = { 1, (1 << 13) - 1},
|
||||
[FEAT_PARAM_DSI_FCK] = { 0, 173000000 },
|
||||
[FEAT_PARAM_DOWNSCALE] = { 1, 4 },
|
||||
[FEAT_PARAM_LINEWIDTH] = { 1, 1024 },
|
||||
[FEAT_PARAM_MGR_WIDTH] = { 1, 2048 },
|
||||
@ -341,6 +459,23 @@ static const struct dss_param_range omap4_dss_param_range[] = {
|
||||
[FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, (1 << 5) - 1 },
|
||||
[FEAT_PARAM_DSIPLL_FINT] = { 500000, 2500000 },
|
||||
[FEAT_PARAM_DSIPLL_LPDIV] = { 0, (1 << 13) - 1 },
|
||||
[FEAT_PARAM_DSI_FCK] = { 0, 170000000 },
|
||||
[FEAT_PARAM_DOWNSCALE] = { 1, 4 },
|
||||
[FEAT_PARAM_LINEWIDTH] = { 1, 2048 },
|
||||
[FEAT_PARAM_MGR_WIDTH] = { 1, 2048 },
|
||||
[FEAT_PARAM_MGR_HEIGHT] = { 1, 2048 },
|
||||
};
|
||||
|
||||
static const struct dss_param_range omap5_dss_param_range[] = {
|
||||
[FEAT_PARAM_DSS_FCK] = { 0, 200000000 },
|
||||
[FEAT_PARAM_DSS_PCD] = { 1, 255 },
|
||||
[FEAT_PARAM_DSIPLL_REGN] = { 0, (1 << 8) - 1 },
|
||||
[FEAT_PARAM_DSIPLL_REGM] = { 0, (1 << 12) - 1 },
|
||||
[FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, (1 << 5) - 1 },
|
||||
[FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, (1 << 5) - 1 },
|
||||
[FEAT_PARAM_DSIPLL_FINT] = { 500000, 2500000 },
|
||||
[FEAT_PARAM_DSIPLL_LPDIV] = { 0, (1 << 13) - 1 },
|
||||
[FEAT_PARAM_DSI_FCK] = { 0, 170000000 },
|
||||
[FEAT_PARAM_DOWNSCALE] = { 1, 4 },
|
||||
[FEAT_PARAM_LINEWIDTH] = { 1, 2048 },
|
||||
[FEAT_PARAM_MGR_WIDTH] = { 1, 2048 },
|
||||
@ -373,6 +508,26 @@ static const enum dss_feat_id omap3430_dss_feat_list[] = {
|
||||
FEAT_ALPHA_FIXED_ZORDER,
|
||||
FEAT_FIFO_MERGE,
|
||||
FEAT_OMAP3_DSI_FIFO_BUG,
|
||||
FEAT_DPI_USES_VDDS_DSI,
|
||||
};
|
||||
|
||||
static const enum dss_feat_id am35xx_dss_feat_list[] = {
|
||||
FEAT_LCDENABLEPOL,
|
||||
FEAT_LCDENABLESIGNAL,
|
||||
FEAT_PCKFREEENABLE,
|
||||
FEAT_FUNCGATED,
|
||||
FEAT_LINEBUFFERSPLIT,
|
||||
FEAT_ROWREPEATENABLE,
|
||||
FEAT_RESIZECONF,
|
||||
FEAT_DSI_PLL_FREQSEL,
|
||||
FEAT_DSI_REVERSE_TXCLKESC,
|
||||
FEAT_VENC_REQUIRES_TV_DAC_CLK,
|
||||
FEAT_CPR,
|
||||
FEAT_PRELOAD,
|
||||
FEAT_FIR_COEF_V,
|
||||
FEAT_ALPHA_FIXED_ZORDER,
|
||||
FEAT_FIFO_MERGE,
|
||||
FEAT_OMAP3_DSI_FIFO_BUG,
|
||||
};
|
||||
|
||||
static const enum dss_feat_id omap3630_dss_feat_list[] = {
|
||||
@ -447,6 +602,28 @@ static const enum dss_feat_id omap4_dss_feat_list[] = {
|
||||
FEAT_BURST_2D,
|
||||
};
|
||||
|
||||
static const enum dss_feat_id omap5_dss_feat_list[] = {
|
||||
FEAT_MGR_LCD2,
|
||||
FEAT_CORE_CLK_DIV,
|
||||
FEAT_LCD_CLK_SRC,
|
||||
FEAT_DSI_DCS_CMD_CONFIG_VC,
|
||||
FEAT_DSI_VC_OCP_WIDTH,
|
||||
FEAT_DSI_GNQ,
|
||||
FEAT_HDMI_CTS_SWMODE,
|
||||
FEAT_HDMI_AUDIO_USE_MCLK,
|
||||
FEAT_HANDLE_UV_SEPARATE,
|
||||
FEAT_ATTR2,
|
||||
FEAT_CPR,
|
||||
FEAT_PRELOAD,
|
||||
FEAT_FIR_COEF_V,
|
||||
FEAT_ALPHA_FREE_ZORDER,
|
||||
FEAT_FIFO_MERGE,
|
||||
FEAT_BURST_2D,
|
||||
FEAT_DSI_PLL_SELFREQDCO,
|
||||
FEAT_DSI_PLL_REFSEL,
|
||||
FEAT_DSI_PHY_DCC,
|
||||
};
|
||||
|
||||
/* OMAP2 DSS Features */
|
||||
static const struct omap_dss_features omap2_dss_features = {
|
||||
.reg_fields = omap2_dss_reg_fields,
|
||||
@ -458,6 +635,7 @@ static const struct omap_dss_features omap2_dss_features = {
|
||||
.num_mgrs = 2,
|
||||
.num_ovls = 3,
|
||||
.supported_displays = omap2_dss_supported_displays,
|
||||
.supported_outputs = omap2_dss_supported_outputs,
|
||||
.supported_color_modes = omap2_dss_supported_color_modes,
|
||||
.overlay_caps = omap2_dss_overlay_caps,
|
||||
.clksrc_names = omap2_dss_clk_source_names,
|
||||
@ -478,6 +656,31 @@ static const struct omap_dss_features omap3430_dss_features = {
|
||||
.num_mgrs = 2,
|
||||
.num_ovls = 3,
|
||||
.supported_displays = omap3430_dss_supported_displays,
|
||||
.supported_outputs = omap3430_dss_supported_outputs,
|
||||
.supported_color_modes = omap3_dss_supported_color_modes,
|
||||
.overlay_caps = omap3430_dss_overlay_caps,
|
||||
.clksrc_names = omap3_dss_clk_source_names,
|
||||
.dss_params = omap3_dss_param_range,
|
||||
.supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_VRFB,
|
||||
.buffer_size_unit = 1,
|
||||
.burst_size_unit = 8,
|
||||
};
|
||||
|
||||
/*
|
||||
* AM35xx DSS Features. This is basically OMAP3 DSS Features without the
|
||||
* vdds_dsi regulator.
|
||||
*/
|
||||
static const struct omap_dss_features am35xx_dss_features = {
|
||||
.reg_fields = omap3_dss_reg_fields,
|
||||
.num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields),
|
||||
|
||||
.features = am35xx_dss_feat_list,
|
||||
.num_features = ARRAY_SIZE(am35xx_dss_feat_list),
|
||||
|
||||
.num_mgrs = 2,
|
||||
.num_ovls = 3,
|
||||
.supported_displays = omap3430_dss_supported_displays,
|
||||
.supported_outputs = omap3430_dss_supported_outputs,
|
||||
.supported_color_modes = omap3_dss_supported_color_modes,
|
||||
.overlay_caps = omap3430_dss_overlay_caps,
|
||||
.clksrc_names = omap3_dss_clk_source_names,
|
||||
@ -497,6 +700,7 @@ static const struct omap_dss_features omap3630_dss_features = {
|
||||
.num_mgrs = 2,
|
||||
.num_ovls = 3,
|
||||
.supported_displays = omap3630_dss_supported_displays,
|
||||
.supported_outputs = omap3630_dss_supported_outputs,
|
||||
.supported_color_modes = omap3_dss_supported_color_modes,
|
||||
.overlay_caps = omap3630_dss_overlay_caps,
|
||||
.clksrc_names = omap3_dss_clk_source_names,
|
||||
@ -517,7 +721,9 @@ static const struct omap_dss_features omap4430_es1_0_dss_features = {
|
||||
|
||||
.num_mgrs = 3,
|
||||
.num_ovls = 4,
|
||||
.num_wbs = 1,
|
||||
.supported_displays = omap4_dss_supported_displays,
|
||||
.supported_outputs = omap4_dss_supported_outputs,
|
||||
.supported_color_modes = omap4_dss_supported_color_modes,
|
||||
.overlay_caps = omap4_dss_overlay_caps,
|
||||
.clksrc_names = omap4_dss_clk_source_names,
|
||||
@ -537,7 +743,9 @@ static const struct omap_dss_features omap4430_es2_0_1_2_dss_features = {
|
||||
|
||||
.num_mgrs = 3,
|
||||
.num_ovls = 4,
|
||||
.num_wbs = 1,
|
||||
.supported_displays = omap4_dss_supported_displays,
|
||||
.supported_outputs = omap4_dss_supported_outputs,
|
||||
.supported_color_modes = omap4_dss_supported_color_modes,
|
||||
.overlay_caps = omap4_dss_overlay_caps,
|
||||
.clksrc_names = omap4_dss_clk_source_names,
|
||||
@ -557,7 +765,9 @@ static const struct omap_dss_features omap4_dss_features = {
|
||||
|
||||
.num_mgrs = 3,
|
||||
.num_ovls = 4,
|
||||
.num_wbs = 1,
|
||||
.supported_displays = omap4_dss_supported_displays,
|
||||
.supported_outputs = omap4_dss_supported_outputs,
|
||||
.supported_color_modes = omap4_dss_supported_color_modes,
|
||||
.overlay_caps = omap4_dss_overlay_caps,
|
||||
.clksrc_names = omap4_dss_clk_source_names,
|
||||
@ -567,6 +777,27 @@ static const struct omap_dss_features omap4_dss_features = {
|
||||
.burst_size_unit = 16,
|
||||
};
|
||||
|
||||
/* OMAP5 DSS Features */
|
||||
static const struct omap_dss_features omap5_dss_features = {
|
||||
.reg_fields = omap5_dss_reg_fields,
|
||||
.num_reg_fields = ARRAY_SIZE(omap5_dss_reg_fields),
|
||||
|
||||
.features = omap5_dss_feat_list,
|
||||
.num_features = ARRAY_SIZE(omap5_dss_feat_list),
|
||||
|
||||
.num_mgrs = 3,
|
||||
.num_ovls = 4,
|
||||
.supported_displays = omap5_dss_supported_displays,
|
||||
.supported_outputs = omap5_dss_supported_outputs,
|
||||
.supported_color_modes = omap4_dss_supported_color_modes,
|
||||
.overlay_caps = omap4_dss_overlay_caps,
|
||||
.clksrc_names = omap5_dss_clk_source_names,
|
||||
.dss_params = omap5_dss_param_range,
|
||||
.supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_TILER,
|
||||
.buffer_size_unit = 16,
|
||||
.burst_size_unit = 16,
|
||||
};
|
||||
|
||||
#if defined(CONFIG_OMAP4_DSS_HDMI)
|
||||
/* HDMI OMAP4 Functions*/
|
||||
static const struct ti_hdmi_ip_ops omap4_hdmi_functions = {
|
||||
@ -612,6 +843,11 @@ int dss_feat_get_num_ovls(void)
|
||||
return omap_current_dss_features->num_ovls;
|
||||
}
|
||||
|
||||
int dss_feat_get_num_wbs(void)
|
||||
{
|
||||
return omap_current_dss_features->num_wbs;
|
||||
}
|
||||
|
||||
unsigned long dss_feat_get_param_min(enum dss_range_param param)
|
||||
{
|
||||
return omap_current_dss_features->dss_params[param].min;
|
||||
@ -627,6 +863,11 @@ enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel
|
||||
return omap_current_dss_features->supported_displays[channel];
|
||||
}
|
||||
|
||||
enum omap_dss_output_id dss_feat_get_supported_outputs(enum omap_channel channel)
|
||||
{
|
||||
return omap_current_dss_features->supported_outputs[channel];
|
||||
}
|
||||
|
||||
enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane)
|
||||
{
|
||||
return omap_current_dss_features->supported_color_modes[plane];
|
||||
@ -694,8 +935,13 @@ void dss_features_init(void)
|
||||
omap_current_dss_features = &omap2_dss_features;
|
||||
else if (cpu_is_omap3630())
|
||||
omap_current_dss_features = &omap3630_dss_features;
|
||||
else if (cpu_is_omap34xx())
|
||||
omap_current_dss_features = &omap3430_dss_features;
|
||||
else if (cpu_is_omap34xx()) {
|
||||
if (soc_is_am35xx()) {
|
||||
omap_current_dss_features = &am35xx_dss_features;
|
||||
} else {
|
||||
omap_current_dss_features = &omap3430_dss_features;
|
||||
}
|
||||
}
|
||||
else if (omap_rev() == OMAP4430_REV_ES1_0)
|
||||
omap_current_dss_features = &omap4430_es1_0_dss_features;
|
||||
else if (omap_rev() == OMAP4430_REV_ES2_0 ||
|
||||
@ -704,6 +950,8 @@ void dss_features_init(void)
|
||||
omap_current_dss_features = &omap4430_es2_0_1_2_dss_features;
|
||||
else if (cpu_is_omap44xx())
|
||||
omap_current_dss_features = &omap4_dss_features;
|
||||
else if (soc_is_omap54xx())
|
||||
omap_current_dss_features = &omap5_dss_features;
|
||||
else
|
||||
DSSWARN("Unsupported OMAP version");
|
||||
}
|
||||
|
@ -50,6 +50,7 @@ enum dss_feat_id {
|
||||
FEAT_DSI_VC_OCP_WIDTH,
|
||||
FEAT_DSI_REVERSE_TXCLKESC,
|
||||
FEAT_DSI_GNQ,
|
||||
FEAT_DPI_USES_VDDS_DSI,
|
||||
FEAT_HDMI_CTS_SWMODE,
|
||||
FEAT_HDMI_AUDIO_USE_MCLK,
|
||||
FEAT_HANDLE_UV_SEPARATE,
|
||||
@ -64,6 +65,9 @@ enum dss_feat_id {
|
||||
/* An unknown HW bug causing the normal FIFO thresholds not to work */
|
||||
FEAT_OMAP3_DSI_FIFO_BUG,
|
||||
FEAT_BURST_2D,
|
||||
FEAT_DSI_PLL_SELFREQDCO,
|
||||
FEAT_DSI_PLL_REFSEL,
|
||||
FEAT_DSI_PHY_DCC,
|
||||
};
|
||||
|
||||
/* DSS register field id */
|
||||
@ -91,6 +95,7 @@ enum dss_range_param {
|
||||
FEAT_PARAM_DSIPLL_REGM_DSI,
|
||||
FEAT_PARAM_DSIPLL_FINT,
|
||||
FEAT_PARAM_DSIPLL_LPDIV,
|
||||
FEAT_PARAM_DSI_FCK,
|
||||
FEAT_PARAM_DOWNSCALE,
|
||||
FEAT_PARAM_LINEWIDTH,
|
||||
FEAT_PARAM_MGR_WIDTH,
|
||||
@ -100,9 +105,11 @@ enum dss_range_param {
|
||||
/* DSS Feature Functions */
|
||||
int dss_feat_get_num_mgrs(void);
|
||||
int dss_feat_get_num_ovls(void);
|
||||
int dss_feat_get_num_wbs(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_dss_output_id dss_feat_get_supported_outputs(enum omap_channel channel);
|
||||
enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane);
|
||||
enum omap_overlay_caps dss_feat_get_overlay_caps(enum omap_plane plane);
|
||||
bool dss_feat_color_mode_supported(enum omap_plane plane,
|
||||
|
@ -32,6 +32,8 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <video/omapdss.h>
|
||||
|
||||
#include "ti_hdmi.h"
|
||||
@ -61,6 +63,13 @@ static struct {
|
||||
struct hdmi_ip_data ip_data;
|
||||
|
||||
struct clk *sys_clk;
|
||||
struct regulator *vdda_hdmi_dac_reg;
|
||||
|
||||
int ct_cp_hpd_gpio;
|
||||
int ls_oe_gpio;
|
||||
int hpd_gpio;
|
||||
|
||||
struct omap_dss_output output;
|
||||
} hdmi;
|
||||
|
||||
/*
|
||||
@ -314,12 +323,47 @@ static void hdmi_runtime_put(void)
|
||||
|
||||
static int __init hdmi_init_display(struct omap_dss_device *dssdev)
|
||||
{
|
||||
int r;
|
||||
|
||||
struct gpio gpios[] = {
|
||||
{ hdmi.ct_cp_hpd_gpio, GPIOF_OUT_INIT_LOW, "hdmi_ct_cp_hpd" },
|
||||
{ hdmi.ls_oe_gpio, GPIOF_OUT_INIT_LOW, "hdmi_ls_oe" },
|
||||
{ hdmi.hpd_gpio, GPIOF_DIR_IN, "hdmi_hpd" },
|
||||
};
|
||||
|
||||
DSSDBG("init_display\n");
|
||||
|
||||
dss_init_hdmi_ip_ops(&hdmi.ip_data);
|
||||
|
||||
if (hdmi.vdda_hdmi_dac_reg == NULL) {
|
||||
struct regulator *reg;
|
||||
|
||||
reg = devm_regulator_get(&hdmi.pdev->dev, "vdda_hdmi_dac");
|
||||
|
||||
if (IS_ERR(reg)) {
|
||||
DSSERR("can't get VDDA_HDMI_DAC regulator\n");
|
||||
return PTR_ERR(reg);
|
||||
}
|
||||
|
||||
hdmi.vdda_hdmi_dac_reg = reg;
|
||||
}
|
||||
|
||||
r = gpio_request_array(gpios, ARRAY_SIZE(gpios));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit hdmi_uninit_display(struct omap_dss_device *dssdev)
|
||||
{
|
||||
DSSDBG("uninit_display\n");
|
||||
|
||||
gpio_free(hdmi.ct_cp_hpd_gpio);
|
||||
gpio_free(hdmi.ls_oe_gpio);
|
||||
gpio_free(hdmi.hpd_gpio);
|
||||
}
|
||||
|
||||
static const struct hdmi_config *hdmi_find_timing(
|
||||
const struct hdmi_config *timings_arr,
|
||||
int len)
|
||||
@ -459,32 +503,30 @@ static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy,
|
||||
static int hdmi_power_on(struct omap_dss_device *dssdev)
|
||||
{
|
||||
int r;
|
||||
const struct hdmi_config *timing;
|
||||
struct omap_video_timings *p;
|
||||
struct omap_overlay_manager *mgr = dssdev->output->manager;
|
||||
unsigned long phy;
|
||||
|
||||
gpio_set_value(hdmi.ct_cp_hpd_gpio, 1);
|
||||
gpio_set_value(hdmi.ls_oe_gpio, 1);
|
||||
|
||||
/* wait 300us after CT_CP_HPD for the 5V power output to reach 90% */
|
||||
udelay(300);
|
||||
|
||||
r = regulator_enable(hdmi.vdda_hdmi_dac_reg);
|
||||
if (r)
|
||||
goto err_vdac_enable;
|
||||
|
||||
r = hdmi_runtime_get();
|
||||
if (r)
|
||||
return r;
|
||||
goto err_runtime_get;
|
||||
|
||||
dss_mgr_disable(dssdev->manager);
|
||||
dss_mgr_disable(mgr);
|
||||
|
||||
p = &dssdev->panel.timings;
|
||||
p = &hdmi.ip_data.cfg.timings;
|
||||
|
||||
DSSDBG("hdmi_power_on x_res= %d y_res = %d\n",
|
||||
dssdev->panel.timings.x_res,
|
||||
dssdev->panel.timings.y_res);
|
||||
DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res);
|
||||
|
||||
timing = hdmi_get_timings();
|
||||
if (timing == NULL) {
|
||||
/* HDMI code 4 corresponds to 640 * 480 VGA */
|
||||
hdmi.ip_data.cfg.cm.code = 4;
|
||||
/* DVI mode 1 corresponds to HDMI 0 to DVI */
|
||||
hdmi.ip_data.cfg.cm.mode = HDMI_DVI;
|
||||
hdmi.ip_data.cfg = vesa_timings[0];
|
||||
} else {
|
||||
hdmi.ip_data.cfg = *timing;
|
||||
}
|
||||
phy = p->pixel_clock;
|
||||
|
||||
hdmi_compute_pll(dssdev, phy, &hdmi.ip_data.pll_data);
|
||||
@ -495,13 +537,13 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
|
||||
r = hdmi.ip_data.ops->pll_enable(&hdmi.ip_data);
|
||||
if (r) {
|
||||
DSSDBG("Failed to lock PLL\n");
|
||||
goto err;
|
||||
goto err_pll_enable;
|
||||
}
|
||||
|
||||
r = hdmi.ip_data.ops->phy_enable(&hdmi.ip_data);
|
||||
if (r) {
|
||||
DSSDBG("Failed to start PHY\n");
|
||||
goto err;
|
||||
goto err_phy_enable;
|
||||
}
|
||||
|
||||
hdmi.ip_data.ops->video_configure(&hdmi.ip_data);
|
||||
@ -521,13 +563,13 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
|
||||
dispc_enable_gamma_table(0);
|
||||
|
||||
/* tv size */
|
||||
dss_mgr_set_timings(dssdev->manager, &dssdev->panel.timings);
|
||||
dss_mgr_set_timings(mgr, p);
|
||||
|
||||
r = hdmi.ip_data.ops->video_enable(&hdmi.ip_data);
|
||||
if (r)
|
||||
goto err_vid_enable;
|
||||
|
||||
r = dss_mgr_enable(dssdev->manager);
|
||||
r = dss_mgr_enable(mgr);
|
||||
if (r)
|
||||
goto err_mgr_enable;
|
||||
|
||||
@ -537,20 +579,33 @@ err_mgr_enable:
|
||||
hdmi.ip_data.ops->video_disable(&hdmi.ip_data);
|
||||
err_vid_enable:
|
||||
hdmi.ip_data.ops->phy_disable(&hdmi.ip_data);
|
||||
err_phy_enable:
|
||||
hdmi.ip_data.ops->pll_disable(&hdmi.ip_data);
|
||||
err:
|
||||
err_pll_enable:
|
||||
hdmi_runtime_put();
|
||||
err_runtime_get:
|
||||
regulator_disable(hdmi.vdda_hdmi_dac_reg);
|
||||
err_vdac_enable:
|
||||
gpio_set_value(hdmi.ct_cp_hpd_gpio, 0);
|
||||
gpio_set_value(hdmi.ls_oe_gpio, 0);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
static void hdmi_power_off(struct omap_dss_device *dssdev)
|
||||
{
|
||||
dss_mgr_disable(dssdev->manager);
|
||||
struct omap_overlay_manager *mgr = dssdev->output->manager;
|
||||
|
||||
dss_mgr_disable(mgr);
|
||||
|
||||
hdmi.ip_data.ops->video_disable(&hdmi.ip_data);
|
||||
hdmi.ip_data.ops->phy_disable(&hdmi.ip_data);
|
||||
hdmi.ip_data.ops->pll_disable(&hdmi.ip_data);
|
||||
hdmi_runtime_put();
|
||||
|
||||
regulator_disable(hdmi.vdda_hdmi_dac_reg);
|
||||
|
||||
gpio_set_value(hdmi.ct_cp_hpd_gpio, 0);
|
||||
gpio_set_value(hdmi.ls_oe_gpio, 0);
|
||||
}
|
||||
|
||||
int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
|
||||
@ -567,25 +622,22 @@ int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
|
||||
|
||||
}
|
||||
|
||||
void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev)
|
||||
void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev,
|
||||
struct omap_video_timings *timings)
|
||||
{
|
||||
struct hdmi_cm cm;
|
||||
const struct hdmi_config *t;
|
||||
|
||||
cm = hdmi_get_code(&dssdev->panel.timings);
|
||||
hdmi.ip_data.cfg.cm.code = cm.code;
|
||||
hdmi.ip_data.cfg.cm.mode = cm.mode;
|
||||
mutex_lock(&hdmi.lock);
|
||||
|
||||
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
|
||||
int r;
|
||||
cm = hdmi_get_code(timings);
|
||||
hdmi.ip_data.cfg.cm = cm;
|
||||
|
||||
hdmi_power_off(dssdev);
|
||||
t = hdmi_get_timings();
|
||||
if (t != NULL)
|
||||
hdmi.ip_data.cfg = *t;
|
||||
|
||||
r = hdmi_power_on(dssdev);
|
||||
if (r)
|
||||
DSSERR("failed to power on device\n");
|
||||
} else {
|
||||
dss_mgr_set_timings(dssdev->manager, &dssdev->panel.timings);
|
||||
}
|
||||
mutex_unlock(&hdmi.lock);
|
||||
}
|
||||
|
||||
static void hdmi_dump_regs(struct seq_file *s)
|
||||
@ -640,20 +692,20 @@ bool omapdss_hdmi_detect(void)
|
||||
|
||||
int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct omap_dss_hdmi_data *priv = dssdev->data;
|
||||
struct omap_dss_output *out = dssdev->output;
|
||||
int r = 0;
|
||||
|
||||
DSSDBG("ENTER hdmi_display_enable\n");
|
||||
|
||||
mutex_lock(&hdmi.lock);
|
||||
|
||||
if (dssdev->manager == NULL) {
|
||||
DSSERR("failed to enable display: no manager\n");
|
||||
if (out == NULL || out->manager == NULL) {
|
||||
DSSERR("failed to enable display: no output/manager\n");
|
||||
r = -ENODEV;
|
||||
goto err0;
|
||||
}
|
||||
|
||||
hdmi.ip_data.hpd_gpio = priv->hpd_gpio;
|
||||
hdmi.ip_data.hpd_gpio = hdmi.hpd_gpio;
|
||||
|
||||
r = omap_dss_start_device(dssdev);
|
||||
if (r) {
|
||||
@ -661,26 +713,15 @@ int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
|
||||
goto err0;
|
||||
}
|
||||
|
||||
if (dssdev->platform_enable) {
|
||||
r = dssdev->platform_enable(dssdev);
|
||||
if (r) {
|
||||
DSSERR("failed to enable GPIO's\n");
|
||||
goto err1;
|
||||
}
|
||||
}
|
||||
|
||||
r = hdmi_power_on(dssdev);
|
||||
if (r) {
|
||||
DSSERR("failed to power on device\n");
|
||||
goto err2;
|
||||
goto err1;
|
||||
}
|
||||
|
||||
mutex_unlock(&hdmi.lock);
|
||||
return 0;
|
||||
|
||||
err2:
|
||||
if (dssdev->platform_disable)
|
||||
dssdev->platform_disable(dssdev);
|
||||
err1:
|
||||
omap_dss_stop_device(dssdev);
|
||||
err0:
|
||||
@ -696,9 +737,6 @@ void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev)
|
||||
|
||||
hdmi_power_off(dssdev);
|
||||
|
||||
if (dssdev->platform_disable)
|
||||
dssdev->platform_disable(dssdev);
|
||||
|
||||
omap_dss_stop_device(dssdev);
|
||||
|
||||
mutex_unlock(&hdmi.lock);
|
||||
@ -869,10 +907,14 @@ int hdmi_audio_config(struct omap_dss_audio *audio)
|
||||
|
||||
#endif
|
||||
|
||||
static void __init hdmi_probe_pdata(struct platform_device *pdev)
|
||||
static struct omap_dss_device * __init hdmi_find_dssdev(struct platform_device *pdev)
|
||||
{
|
||||
struct omap_dss_board_info *pdata = pdev->dev.platform_data;
|
||||
int r, i;
|
||||
const char *def_disp_name = dss_get_default_display_name();
|
||||
struct omap_dss_device *def_dssdev;
|
||||
int i;
|
||||
|
||||
def_dssdev = NULL;
|
||||
|
||||
for (i = 0; i < pdata->num_devices; ++i) {
|
||||
struct omap_dss_device *dssdev = pdata->devices[i];
|
||||
@ -880,17 +922,76 @@ static void __init hdmi_probe_pdata(struct platform_device *pdev)
|
||||
if (dssdev->type != OMAP_DISPLAY_TYPE_HDMI)
|
||||
continue;
|
||||
|
||||
r = hdmi_init_display(dssdev);
|
||||
if (r) {
|
||||
DSSERR("device %s init failed: %d\n", dssdev->name, r);
|
||||
continue;
|
||||
}
|
||||
if (def_dssdev == NULL)
|
||||
def_dssdev = dssdev;
|
||||
|
||||
r = omap_dss_register_device(dssdev, &pdev->dev, i);
|
||||
if (r)
|
||||
DSSERR("device %s register failed: %d\n",
|
||||
dssdev->name, r);
|
||||
if (def_disp_name != NULL &&
|
||||
strcmp(dssdev->name, def_disp_name) == 0) {
|
||||
def_dssdev = dssdev;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return def_dssdev;
|
||||
}
|
||||
|
||||
static void __init hdmi_probe_pdata(struct platform_device *pdev)
|
||||
{
|
||||
struct omap_dss_device *plat_dssdev;
|
||||
struct omap_dss_device *dssdev;
|
||||
struct omap_dss_hdmi_data *priv;
|
||||
int r;
|
||||
|
||||
plat_dssdev = hdmi_find_dssdev(pdev);
|
||||
|
||||
if (!plat_dssdev)
|
||||
return;
|
||||
|
||||
dssdev = dss_alloc_and_init_device(&pdev->dev);
|
||||
if (!dssdev)
|
||||
return;
|
||||
|
||||
dss_copy_device_pdata(dssdev, plat_dssdev);
|
||||
|
||||
priv = dssdev->data;
|
||||
|
||||
hdmi.ct_cp_hpd_gpio = priv->ct_cp_hpd_gpio;
|
||||
hdmi.ls_oe_gpio = priv->ls_oe_gpio;
|
||||
hdmi.hpd_gpio = priv->hpd_gpio;
|
||||
|
||||
dssdev->channel = OMAP_DSS_CHANNEL_DIGIT;
|
||||
|
||||
r = hdmi_init_display(dssdev);
|
||||
if (r) {
|
||||
DSSERR("device %s init failed: %d\n", dssdev->name, r);
|
||||
dss_put_device(dssdev);
|
||||
return;
|
||||
}
|
||||
|
||||
r = dss_add_device(dssdev);
|
||||
if (r) {
|
||||
DSSERR("device %s register failed: %d\n", dssdev->name, r);
|
||||
dss_put_device(dssdev);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void __init hdmi_init_output(struct platform_device *pdev)
|
||||
{
|
||||
struct omap_dss_output *out = &hdmi.output;
|
||||
|
||||
out->pdev = pdev;
|
||||
out->id = OMAP_DSS_OUTPUT_HDMI;
|
||||
out->type = OMAP_DISPLAY_TYPE_HDMI;
|
||||
|
||||
dss_register_output(out);
|
||||
}
|
||||
|
||||
static void __exit hdmi_uninit_output(struct platform_device *pdev)
|
||||
{
|
||||
struct omap_dss_output *out = &hdmi.output;
|
||||
|
||||
dss_unregister_output(out);
|
||||
}
|
||||
|
||||
/* HDMI HW IP initialisation */
|
||||
@ -929,23 +1030,37 @@ static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
|
||||
hdmi.ip_data.core_av_offset = HDMI_CORE_AV;
|
||||
hdmi.ip_data.pll_offset = HDMI_PLLCTRL;
|
||||
hdmi.ip_data.phy_offset = HDMI_PHY;
|
||||
|
||||
mutex_init(&hdmi.ip_data.lock);
|
||||
|
||||
hdmi_panel_init();
|
||||
|
||||
dss_debugfs_create_file("hdmi", hdmi_dump_regs);
|
||||
|
||||
hdmi_init_output(pdev);
|
||||
|
||||
hdmi_probe_pdata(pdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __exit hdmi_remove_child(struct device *dev, void *data)
|
||||
{
|
||||
struct omap_dss_device *dssdev = to_dss_device(dev);
|
||||
hdmi_uninit_display(dssdev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
|
||||
{
|
||||
omap_dss_unregister_child_devices(&pdev->dev);
|
||||
device_for_each_child(&pdev->dev, NULL, hdmi_remove_child);
|
||||
|
||||
dss_unregister_child_devices(&pdev->dev);
|
||||
|
||||
hdmi_panel_exit();
|
||||
|
||||
hdmi_uninit_output(pdev);
|
||||
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
hdmi_put_clocks();
|
||||
|
@ -41,17 +41,34 @@ static struct {
|
||||
|
||||
static int hdmi_panel_probe(struct omap_dss_device *dssdev)
|
||||
{
|
||||
/* Initialize default timings to VGA in DVI mode */
|
||||
const struct omap_video_timings default_timings = {
|
||||
.x_res = 640,
|
||||
.y_res = 480,
|
||||
.pixel_clock = 25175,
|
||||
.hsw = 96,
|
||||
.hfp = 16,
|
||||
.hbp = 48,
|
||||
.vsw = 2,
|
||||
.vfp = 11,
|
||||
.vbp = 31,
|
||||
|
||||
.vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
|
||||
.hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
|
||||
|
||||
.interlace = false,
|
||||
};
|
||||
|
||||
DSSDBG("ENTER hdmi_panel_probe\n");
|
||||
|
||||
dssdev->panel.timings = (struct omap_video_timings)
|
||||
{ 640, 480, 25175, 96, 16, 48, 2, 11, 31,
|
||||
OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
|
||||
false,
|
||||
};
|
||||
dssdev->panel.timings = default_timings;
|
||||
|
||||
DSSDBG("hdmi_panel_probe x_res= %d y_res = %d\n",
|
||||
dssdev->panel.timings.x_res,
|
||||
dssdev->panel.timings.y_res);
|
||||
|
||||
omapdss_hdmi_display_set_timing(dssdev, &dssdev->panel.timings);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -228,6 +245,8 @@ static int hdmi_panel_enable(struct omap_dss_device *dssdev)
|
||||
goto err;
|
||||
}
|
||||
|
||||
omapdss_hdmi_display_set_timing(dssdev, &dssdev->panel.timings);
|
||||
|
||||
r = omapdss_hdmi_display_enable(dssdev);
|
||||
if (r) {
|
||||
DSSERR("failed to power on\n");
|
||||
@ -336,8 +355,8 @@ static void hdmi_set_timings(struct omap_dss_device *dssdev,
|
||||
*/
|
||||
hdmi_panel_audio_disable(dssdev);
|
||||
|
||||
omapdss_hdmi_display_set_timing(dssdev, timings);
|
||||
dssdev->panel.timings = *timings;
|
||||
omapdss_hdmi_display_set_timing(dssdev);
|
||||
|
||||
mutex_unlock(&hdmi.lock);
|
||||
}
|
||||
|
512
drivers/video/omap2/dss/manager-sysfs.c
Normal file
512
drivers/video/omap2/dss/manager-sysfs.c
Normal file
@ -0,0 +1,512 @@
|
||||
/*
|
||||
* Copyright (C) 2009 Nokia Corporation
|
||||
* Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
|
||||
*
|
||||
* Some code and ideas taken from drivers/video/omap/ driver
|
||||
* by Imre Deak.
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#define DSS_SUBSYS_NAME "MANAGER"
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/jiffies.h>
|
||||
|
||||
#include <video/omapdss.h>
|
||||
|
||||
#include "dss.h"
|
||||
#include "dss_features.h"
|
||||
|
||||
static ssize_t manager_name_show(struct omap_overlay_manager *mgr, char *buf)
|
||||
{
|
||||
return snprintf(buf, PAGE_SIZE, "%s\n", mgr->name);
|
||||
}
|
||||
|
||||
static ssize_t manager_display_show(struct omap_overlay_manager *mgr, char *buf)
|
||||
{
|
||||
struct omap_dss_device *dssdev = mgr->get_device(mgr);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%s\n", dssdev ?
|
||||
dssdev->name : "<none>");
|
||||
}
|
||||
|
||||
static ssize_t manager_display_store(struct omap_overlay_manager *mgr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
int r = 0;
|
||||
size_t len = size;
|
||||
struct omap_dss_device *dssdev = NULL;
|
||||
|
||||
int match(struct omap_dss_device *dssdev, void *data)
|
||||
{
|
||||
const char *str = data;
|
||||
return sysfs_streq(dssdev->name, str);
|
||||
}
|
||||
|
||||
if (buf[size-1] == '\n')
|
||||
--len;
|
||||
|
||||
if (len > 0)
|
||||
dssdev = omap_dss_find_device((void *)buf, match);
|
||||
|
||||
if (len > 0 && dssdev == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
if (dssdev)
|
||||
DSSDBG("display %s found\n", dssdev->name);
|
||||
|
||||
if (mgr->output) {
|
||||
r = mgr->unset_output(mgr);
|
||||
if (r) {
|
||||
DSSERR("failed to unset current output\n");
|
||||
goto put_device;
|
||||
}
|
||||
}
|
||||
|
||||
if (dssdev) {
|
||||
struct omap_dss_output *out = dssdev->output;
|
||||
|
||||
/*
|
||||
* a registered device should have an output connected to it
|
||||
* already
|
||||
*/
|
||||
if (!out) {
|
||||
DSSERR("device has no output connected to it\n");
|
||||
goto put_device;
|
||||
}
|
||||
|
||||
r = mgr->set_output(mgr, out);
|
||||
if (r) {
|
||||
DSSERR("failed to set manager output\n");
|
||||
goto put_device;
|
||||
}
|
||||
|
||||
r = mgr->apply(mgr);
|
||||
if (r) {
|
||||
DSSERR("failed to apply dispc config\n");
|
||||
goto put_device;
|
||||
}
|
||||
}
|
||||
|
||||
put_device:
|
||||
if (dssdev)
|
||||
omap_dss_put_device(dssdev);
|
||||
|
||||
return r ? r : size;
|
||||
}
|
||||
|
||||
static ssize_t manager_default_color_show(struct omap_overlay_manager *mgr,
|
||||
char *buf)
|
||||
{
|
||||
struct omap_overlay_manager_info info;
|
||||
|
||||
mgr->get_manager_info(mgr, &info);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%#x\n", info.default_color);
|
||||
}
|
||||
|
||||
static ssize_t manager_default_color_store(struct omap_overlay_manager *mgr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
struct omap_overlay_manager_info info;
|
||||
u32 color;
|
||||
int r;
|
||||
|
||||
r = kstrtouint(buf, 0, &color);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
mgr->get_manager_info(mgr, &info);
|
||||
|
||||
info.default_color = color;
|
||||
|
||||
r = mgr->set_manager_info(mgr, &info);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = mgr->apply(mgr);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static const char *trans_key_type_str[] = {
|
||||
"gfx-destination",
|
||||
"video-source",
|
||||
};
|
||||
|
||||
static ssize_t manager_trans_key_type_show(struct omap_overlay_manager *mgr,
|
||||
char *buf)
|
||||
{
|
||||
enum omap_dss_trans_key_type key_type;
|
||||
struct omap_overlay_manager_info info;
|
||||
|
||||
mgr->get_manager_info(mgr, &info);
|
||||
|
||||
key_type = info.trans_key_type;
|
||||
BUG_ON(key_type >= ARRAY_SIZE(trans_key_type_str));
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%s\n", trans_key_type_str[key_type]);
|
||||
}
|
||||
|
||||
static ssize_t manager_trans_key_type_store(struct omap_overlay_manager *mgr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
enum omap_dss_trans_key_type key_type;
|
||||
struct omap_overlay_manager_info info;
|
||||
int r;
|
||||
|
||||
for (key_type = OMAP_DSS_COLOR_KEY_GFX_DST;
|
||||
key_type < ARRAY_SIZE(trans_key_type_str); key_type++) {
|
||||
if (sysfs_streq(buf, trans_key_type_str[key_type]))
|
||||
break;
|
||||
}
|
||||
|
||||
if (key_type == ARRAY_SIZE(trans_key_type_str))
|
||||
return -EINVAL;
|
||||
|
||||
mgr->get_manager_info(mgr, &info);
|
||||
|
||||
info.trans_key_type = key_type;
|
||||
|
||||
r = mgr->set_manager_info(mgr, &info);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = mgr->apply(mgr);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static ssize_t manager_trans_key_value_show(struct omap_overlay_manager *mgr,
|
||||
char *buf)
|
||||
{
|
||||
struct omap_overlay_manager_info info;
|
||||
|
||||
mgr->get_manager_info(mgr, &info);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%#x\n", info.trans_key);
|
||||
}
|
||||
|
||||
static ssize_t manager_trans_key_value_store(struct omap_overlay_manager *mgr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
struct omap_overlay_manager_info info;
|
||||
u32 key_value;
|
||||
int r;
|
||||
|
||||
r = kstrtouint(buf, 0, &key_value);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
mgr->get_manager_info(mgr, &info);
|
||||
|
||||
info.trans_key = key_value;
|
||||
|
||||
r = mgr->set_manager_info(mgr, &info);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = mgr->apply(mgr);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static ssize_t manager_trans_key_enabled_show(struct omap_overlay_manager *mgr,
|
||||
char *buf)
|
||||
{
|
||||
struct omap_overlay_manager_info info;
|
||||
|
||||
mgr->get_manager_info(mgr, &info);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", info.trans_enabled);
|
||||
}
|
||||
|
||||
static ssize_t manager_trans_key_enabled_store(struct omap_overlay_manager *mgr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
struct omap_overlay_manager_info info;
|
||||
bool enable;
|
||||
int r;
|
||||
|
||||
r = strtobool(buf, &enable);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
mgr->get_manager_info(mgr, &info);
|
||||
|
||||
info.trans_enabled = enable;
|
||||
|
||||
r = mgr->set_manager_info(mgr, &info);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = mgr->apply(mgr);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static ssize_t manager_alpha_blending_enabled_show(
|
||||
struct omap_overlay_manager *mgr, char *buf)
|
||||
{
|
||||
struct omap_overlay_manager_info info;
|
||||
|
||||
mgr->get_manager_info(mgr, &info);
|
||||
|
||||
WARN_ON(!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER));
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n",
|
||||
info.partial_alpha_enabled);
|
||||
}
|
||||
|
||||
static ssize_t manager_alpha_blending_enabled_store(
|
||||
struct omap_overlay_manager *mgr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
struct omap_overlay_manager_info info;
|
||||
bool enable;
|
||||
int r;
|
||||
|
||||
WARN_ON(!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER));
|
||||
|
||||
r = strtobool(buf, &enable);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
mgr->get_manager_info(mgr, &info);
|
||||
|
||||
info.partial_alpha_enabled = enable;
|
||||
|
||||
r = mgr->set_manager_info(mgr, &info);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = mgr->apply(mgr);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static ssize_t manager_cpr_enable_show(struct omap_overlay_manager *mgr,
|
||||
char *buf)
|
||||
{
|
||||
struct omap_overlay_manager_info info;
|
||||
|
||||
mgr->get_manager_info(mgr, &info);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", info.cpr_enable);
|
||||
}
|
||||
|
||||
static ssize_t manager_cpr_enable_store(struct omap_overlay_manager *mgr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
struct omap_overlay_manager_info info;
|
||||
int r;
|
||||
bool enable;
|
||||
|
||||
if (!dss_has_feature(FEAT_CPR))
|
||||
return -ENODEV;
|
||||
|
||||
r = strtobool(buf, &enable);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
mgr->get_manager_info(mgr, &info);
|
||||
|
||||
if (info.cpr_enable == enable)
|
||||
return size;
|
||||
|
||||
info.cpr_enable = enable;
|
||||
|
||||
r = mgr->set_manager_info(mgr, &info);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = mgr->apply(mgr);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static ssize_t manager_cpr_coef_show(struct omap_overlay_manager *mgr,
|
||||
char *buf)
|
||||
{
|
||||
struct omap_overlay_manager_info info;
|
||||
|
||||
mgr->get_manager_info(mgr, &info);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE,
|
||||
"%d %d %d %d %d %d %d %d %d\n",
|
||||
info.cpr_coefs.rr,
|
||||
info.cpr_coefs.rg,
|
||||
info.cpr_coefs.rb,
|
||||
info.cpr_coefs.gr,
|
||||
info.cpr_coefs.gg,
|
||||
info.cpr_coefs.gb,
|
||||
info.cpr_coefs.br,
|
||||
info.cpr_coefs.bg,
|
||||
info.cpr_coefs.bb);
|
||||
}
|
||||
|
||||
static ssize_t manager_cpr_coef_store(struct omap_overlay_manager *mgr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
struct omap_overlay_manager_info info;
|
||||
struct omap_dss_cpr_coefs coefs;
|
||||
int r, i;
|
||||
s16 *arr;
|
||||
|
||||
if (!dss_has_feature(FEAT_CPR))
|
||||
return -ENODEV;
|
||||
|
||||
if (sscanf(buf, "%hd %hd %hd %hd %hd %hd %hd %hd %hd",
|
||||
&coefs.rr, &coefs.rg, &coefs.rb,
|
||||
&coefs.gr, &coefs.gg, &coefs.gb,
|
||||
&coefs.br, &coefs.bg, &coefs.bb) != 9)
|
||||
return -EINVAL;
|
||||
|
||||
arr = (s16[]){ coefs.rr, coefs.rg, coefs.rb,
|
||||
coefs.gr, coefs.gg, coefs.gb,
|
||||
coefs.br, coefs.bg, coefs.bb };
|
||||
|
||||
for (i = 0; i < 9; ++i) {
|
||||
if (arr[i] < -512 || arr[i] > 511)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mgr->get_manager_info(mgr, &info);
|
||||
|
||||
info.cpr_coefs = coefs;
|
||||
|
||||
r = mgr->set_manager_info(mgr, &info);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = mgr->apply(mgr);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
struct manager_attribute {
|
||||
struct attribute attr;
|
||||
ssize_t (*show)(struct omap_overlay_manager *, char *);
|
||||
ssize_t (*store)(struct omap_overlay_manager *, const char *, size_t);
|
||||
};
|
||||
|
||||
#define MANAGER_ATTR(_name, _mode, _show, _store) \
|
||||
struct manager_attribute manager_attr_##_name = \
|
||||
__ATTR(_name, _mode, _show, _store)
|
||||
|
||||
static MANAGER_ATTR(name, S_IRUGO, manager_name_show, NULL);
|
||||
static MANAGER_ATTR(display, S_IRUGO|S_IWUSR,
|
||||
manager_display_show, manager_display_store);
|
||||
static MANAGER_ATTR(default_color, S_IRUGO|S_IWUSR,
|
||||
manager_default_color_show, manager_default_color_store);
|
||||
static MANAGER_ATTR(trans_key_type, S_IRUGO|S_IWUSR,
|
||||
manager_trans_key_type_show, manager_trans_key_type_store);
|
||||
static MANAGER_ATTR(trans_key_value, S_IRUGO|S_IWUSR,
|
||||
manager_trans_key_value_show, manager_trans_key_value_store);
|
||||
static MANAGER_ATTR(trans_key_enabled, S_IRUGO|S_IWUSR,
|
||||
manager_trans_key_enabled_show,
|
||||
manager_trans_key_enabled_store);
|
||||
static MANAGER_ATTR(alpha_blending_enabled, S_IRUGO|S_IWUSR,
|
||||
manager_alpha_blending_enabled_show,
|
||||
manager_alpha_blending_enabled_store);
|
||||
static MANAGER_ATTR(cpr_enable, S_IRUGO|S_IWUSR,
|
||||
manager_cpr_enable_show,
|
||||
manager_cpr_enable_store);
|
||||
static MANAGER_ATTR(cpr_coef, S_IRUGO|S_IWUSR,
|
||||
manager_cpr_coef_show,
|
||||
manager_cpr_coef_store);
|
||||
|
||||
|
||||
static struct attribute *manager_sysfs_attrs[] = {
|
||||
&manager_attr_name.attr,
|
||||
&manager_attr_display.attr,
|
||||
&manager_attr_default_color.attr,
|
||||
&manager_attr_trans_key_type.attr,
|
||||
&manager_attr_trans_key_value.attr,
|
||||
&manager_attr_trans_key_enabled.attr,
|
||||
&manager_attr_alpha_blending_enabled.attr,
|
||||
&manager_attr_cpr_enable.attr,
|
||||
&manager_attr_cpr_coef.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
static ssize_t manager_attr_show(struct kobject *kobj, struct attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct omap_overlay_manager *manager;
|
||||
struct manager_attribute *manager_attr;
|
||||
|
||||
manager = container_of(kobj, struct omap_overlay_manager, kobj);
|
||||
manager_attr = container_of(attr, struct manager_attribute, attr);
|
||||
|
||||
if (!manager_attr->show)
|
||||
return -ENOENT;
|
||||
|
||||
return manager_attr->show(manager, buf);
|
||||
}
|
||||
|
||||
static ssize_t manager_attr_store(struct kobject *kobj, struct attribute *attr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
struct omap_overlay_manager *manager;
|
||||
struct manager_attribute *manager_attr;
|
||||
|
||||
manager = container_of(kobj, struct omap_overlay_manager, kobj);
|
||||
manager_attr = container_of(attr, struct manager_attribute, attr);
|
||||
|
||||
if (!manager_attr->store)
|
||||
return -ENOENT;
|
||||
|
||||
return manager_attr->store(manager, buf, size);
|
||||
}
|
||||
|
||||
static const struct sysfs_ops manager_sysfs_ops = {
|
||||
.show = manager_attr_show,
|
||||
.store = manager_attr_store,
|
||||
};
|
||||
|
||||
static struct kobj_type manager_ktype = {
|
||||
.sysfs_ops = &manager_sysfs_ops,
|
||||
.default_attrs = manager_sysfs_attrs,
|
||||
};
|
||||
|
||||
int dss_manager_kobj_init(struct omap_overlay_manager *mgr,
|
||||
struct platform_device *pdev)
|
||||
{
|
||||
return kobject_init_and_add(&mgr->kobj, &manager_ktype,
|
||||
&pdev->dev.kobj, "manager%d", mgr->id);
|
||||
}
|
||||
|
||||
void dss_manager_kobj_uninit(struct omap_overlay_manager *mgr)
|
||||
{
|
||||
kobject_del(&mgr->kobj);
|
||||
kobject_put(&mgr->kobj);
|
||||
}
|
@ -36,463 +36,15 @@
|
||||
static int num_managers;
|
||||
static struct omap_overlay_manager *managers;
|
||||
|
||||
static ssize_t manager_name_show(struct omap_overlay_manager *mgr, char *buf)
|
||||
static inline struct omap_dss_device *dss_mgr_get_device(struct omap_overlay_manager *mgr)
|
||||
{
|
||||
return snprintf(buf, PAGE_SIZE, "%s\n", mgr->name);
|
||||
return mgr->output ? mgr->output->device : NULL;
|
||||
}
|
||||
|
||||
static ssize_t manager_display_show(struct omap_overlay_manager *mgr, char *buf)
|
||||
{
|
||||
return snprintf(buf, PAGE_SIZE, "%s\n",
|
||||
mgr->device ? mgr->device->name : "<none>");
|
||||
}
|
||||
|
||||
static ssize_t manager_display_store(struct omap_overlay_manager *mgr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
int r = 0;
|
||||
size_t len = size;
|
||||
struct omap_dss_device *dssdev = NULL;
|
||||
|
||||
int match(struct omap_dss_device *dssdev, void *data)
|
||||
{
|
||||
const char *str = data;
|
||||
return sysfs_streq(dssdev->name, str);
|
||||
}
|
||||
|
||||
if (buf[size-1] == '\n')
|
||||
--len;
|
||||
|
||||
if (len > 0)
|
||||
dssdev = omap_dss_find_device((void *)buf, match);
|
||||
|
||||
if (len > 0 && dssdev == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
if (dssdev)
|
||||
DSSDBG("display %s found\n", dssdev->name);
|
||||
|
||||
if (mgr->device) {
|
||||
r = mgr->unset_device(mgr);
|
||||
if (r) {
|
||||
DSSERR("failed to unset display\n");
|
||||
goto put_device;
|
||||
}
|
||||
}
|
||||
|
||||
if (dssdev) {
|
||||
r = mgr->set_device(mgr, dssdev);
|
||||
if (r) {
|
||||
DSSERR("failed to set manager\n");
|
||||
goto put_device;
|
||||
}
|
||||
|
||||
r = mgr->apply(mgr);
|
||||
if (r) {
|
||||
DSSERR("failed to apply dispc config\n");
|
||||
goto put_device;
|
||||
}
|
||||
}
|
||||
|
||||
put_device:
|
||||
if (dssdev)
|
||||
omap_dss_put_device(dssdev);
|
||||
|
||||
return r ? r : size;
|
||||
}
|
||||
|
||||
static ssize_t manager_default_color_show(struct omap_overlay_manager *mgr,
|
||||
char *buf)
|
||||
{
|
||||
struct omap_overlay_manager_info info;
|
||||
|
||||
mgr->get_manager_info(mgr, &info);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%#x\n", info.default_color);
|
||||
}
|
||||
|
||||
static ssize_t manager_default_color_store(struct omap_overlay_manager *mgr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
struct omap_overlay_manager_info info;
|
||||
u32 color;
|
||||
int r;
|
||||
|
||||
r = kstrtouint(buf, 0, &color);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
mgr->get_manager_info(mgr, &info);
|
||||
|
||||
info.default_color = color;
|
||||
|
||||
r = mgr->set_manager_info(mgr, &info);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = mgr->apply(mgr);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static const char *trans_key_type_str[] = {
|
||||
"gfx-destination",
|
||||
"video-source",
|
||||
};
|
||||
|
||||
static ssize_t manager_trans_key_type_show(struct omap_overlay_manager *mgr,
|
||||
char *buf)
|
||||
{
|
||||
enum omap_dss_trans_key_type key_type;
|
||||
struct omap_overlay_manager_info info;
|
||||
|
||||
mgr->get_manager_info(mgr, &info);
|
||||
|
||||
key_type = info.trans_key_type;
|
||||
BUG_ON(key_type >= ARRAY_SIZE(trans_key_type_str));
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%s\n", trans_key_type_str[key_type]);
|
||||
}
|
||||
|
||||
static ssize_t manager_trans_key_type_store(struct omap_overlay_manager *mgr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
enum omap_dss_trans_key_type key_type;
|
||||
struct omap_overlay_manager_info info;
|
||||
int r;
|
||||
|
||||
for (key_type = OMAP_DSS_COLOR_KEY_GFX_DST;
|
||||
key_type < ARRAY_SIZE(trans_key_type_str); key_type++) {
|
||||
if (sysfs_streq(buf, trans_key_type_str[key_type]))
|
||||
break;
|
||||
}
|
||||
|
||||
if (key_type == ARRAY_SIZE(trans_key_type_str))
|
||||
return -EINVAL;
|
||||
|
||||
mgr->get_manager_info(mgr, &info);
|
||||
|
||||
info.trans_key_type = key_type;
|
||||
|
||||
r = mgr->set_manager_info(mgr, &info);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = mgr->apply(mgr);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static ssize_t manager_trans_key_value_show(struct omap_overlay_manager *mgr,
|
||||
char *buf)
|
||||
{
|
||||
struct omap_overlay_manager_info info;
|
||||
|
||||
mgr->get_manager_info(mgr, &info);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%#x\n", info.trans_key);
|
||||
}
|
||||
|
||||
static ssize_t manager_trans_key_value_store(struct omap_overlay_manager *mgr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
struct omap_overlay_manager_info info;
|
||||
u32 key_value;
|
||||
int r;
|
||||
|
||||
r = kstrtouint(buf, 0, &key_value);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
mgr->get_manager_info(mgr, &info);
|
||||
|
||||
info.trans_key = key_value;
|
||||
|
||||
r = mgr->set_manager_info(mgr, &info);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = mgr->apply(mgr);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static ssize_t manager_trans_key_enabled_show(struct omap_overlay_manager *mgr,
|
||||
char *buf)
|
||||
{
|
||||
struct omap_overlay_manager_info info;
|
||||
|
||||
mgr->get_manager_info(mgr, &info);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", info.trans_enabled);
|
||||
}
|
||||
|
||||
static ssize_t manager_trans_key_enabled_store(struct omap_overlay_manager *mgr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
struct omap_overlay_manager_info info;
|
||||
bool enable;
|
||||
int r;
|
||||
|
||||
r = strtobool(buf, &enable);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
mgr->get_manager_info(mgr, &info);
|
||||
|
||||
info.trans_enabled = enable;
|
||||
|
||||
r = mgr->set_manager_info(mgr, &info);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = mgr->apply(mgr);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static ssize_t manager_alpha_blending_enabled_show(
|
||||
struct omap_overlay_manager *mgr, char *buf)
|
||||
{
|
||||
struct omap_overlay_manager_info info;
|
||||
|
||||
mgr->get_manager_info(mgr, &info);
|
||||
|
||||
WARN_ON(!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER));
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n",
|
||||
info.partial_alpha_enabled);
|
||||
}
|
||||
|
||||
static ssize_t manager_alpha_blending_enabled_store(
|
||||
struct omap_overlay_manager *mgr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
struct omap_overlay_manager_info info;
|
||||
bool enable;
|
||||
int r;
|
||||
|
||||
WARN_ON(!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER));
|
||||
|
||||
r = strtobool(buf, &enable);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
mgr->get_manager_info(mgr, &info);
|
||||
|
||||
info.partial_alpha_enabled = enable;
|
||||
|
||||
r = mgr->set_manager_info(mgr, &info);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = mgr->apply(mgr);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static ssize_t manager_cpr_enable_show(struct omap_overlay_manager *mgr,
|
||||
char *buf)
|
||||
{
|
||||
struct omap_overlay_manager_info info;
|
||||
|
||||
mgr->get_manager_info(mgr, &info);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", info.cpr_enable);
|
||||
}
|
||||
|
||||
static ssize_t manager_cpr_enable_store(struct omap_overlay_manager *mgr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
struct omap_overlay_manager_info info;
|
||||
int r;
|
||||
bool enable;
|
||||
|
||||
if (!dss_has_feature(FEAT_CPR))
|
||||
return -ENODEV;
|
||||
|
||||
r = strtobool(buf, &enable);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
mgr->get_manager_info(mgr, &info);
|
||||
|
||||
if (info.cpr_enable == enable)
|
||||
return size;
|
||||
|
||||
info.cpr_enable = enable;
|
||||
|
||||
r = mgr->set_manager_info(mgr, &info);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = mgr->apply(mgr);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static ssize_t manager_cpr_coef_show(struct omap_overlay_manager *mgr,
|
||||
char *buf)
|
||||
{
|
||||
struct omap_overlay_manager_info info;
|
||||
|
||||
mgr->get_manager_info(mgr, &info);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE,
|
||||
"%d %d %d %d %d %d %d %d %d\n",
|
||||
info.cpr_coefs.rr,
|
||||
info.cpr_coefs.rg,
|
||||
info.cpr_coefs.rb,
|
||||
info.cpr_coefs.gr,
|
||||
info.cpr_coefs.gg,
|
||||
info.cpr_coefs.gb,
|
||||
info.cpr_coefs.br,
|
||||
info.cpr_coefs.bg,
|
||||
info.cpr_coefs.bb);
|
||||
}
|
||||
|
||||
static ssize_t manager_cpr_coef_store(struct omap_overlay_manager *mgr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
struct omap_overlay_manager_info info;
|
||||
struct omap_dss_cpr_coefs coefs;
|
||||
int r, i;
|
||||
s16 *arr;
|
||||
|
||||
if (!dss_has_feature(FEAT_CPR))
|
||||
return -ENODEV;
|
||||
|
||||
if (sscanf(buf, "%hd %hd %hd %hd %hd %hd %hd %hd %hd",
|
||||
&coefs.rr, &coefs.rg, &coefs.rb,
|
||||
&coefs.gr, &coefs.gg, &coefs.gb,
|
||||
&coefs.br, &coefs.bg, &coefs.bb) != 9)
|
||||
return -EINVAL;
|
||||
|
||||
arr = (s16[]){ coefs.rr, coefs.rg, coefs.rb,
|
||||
coefs.gr, coefs.gg, coefs.gb,
|
||||
coefs.br, coefs.bg, coefs.bb };
|
||||
|
||||
for (i = 0; i < 9; ++i) {
|
||||
if (arr[i] < -512 || arr[i] > 511)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mgr->get_manager_info(mgr, &info);
|
||||
|
||||
info.cpr_coefs = coefs;
|
||||
|
||||
r = mgr->set_manager_info(mgr, &info);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = mgr->apply(mgr);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
struct manager_attribute {
|
||||
struct attribute attr;
|
||||
ssize_t (*show)(struct omap_overlay_manager *, char *);
|
||||
ssize_t (*store)(struct omap_overlay_manager *, const char *, size_t);
|
||||
};
|
||||
|
||||
#define MANAGER_ATTR(_name, _mode, _show, _store) \
|
||||
struct manager_attribute manager_attr_##_name = \
|
||||
__ATTR(_name, _mode, _show, _store)
|
||||
|
||||
static MANAGER_ATTR(name, S_IRUGO, manager_name_show, NULL);
|
||||
static MANAGER_ATTR(display, S_IRUGO|S_IWUSR,
|
||||
manager_display_show, manager_display_store);
|
||||
static MANAGER_ATTR(default_color, S_IRUGO|S_IWUSR,
|
||||
manager_default_color_show, manager_default_color_store);
|
||||
static MANAGER_ATTR(trans_key_type, S_IRUGO|S_IWUSR,
|
||||
manager_trans_key_type_show, manager_trans_key_type_store);
|
||||
static MANAGER_ATTR(trans_key_value, S_IRUGO|S_IWUSR,
|
||||
manager_trans_key_value_show, manager_trans_key_value_store);
|
||||
static MANAGER_ATTR(trans_key_enabled, S_IRUGO|S_IWUSR,
|
||||
manager_trans_key_enabled_show,
|
||||
manager_trans_key_enabled_store);
|
||||
static MANAGER_ATTR(alpha_blending_enabled, S_IRUGO|S_IWUSR,
|
||||
manager_alpha_blending_enabled_show,
|
||||
manager_alpha_blending_enabled_store);
|
||||
static MANAGER_ATTR(cpr_enable, S_IRUGO|S_IWUSR,
|
||||
manager_cpr_enable_show,
|
||||
manager_cpr_enable_store);
|
||||
static MANAGER_ATTR(cpr_coef, S_IRUGO|S_IWUSR,
|
||||
manager_cpr_coef_show,
|
||||
manager_cpr_coef_store);
|
||||
|
||||
|
||||
static struct attribute *manager_sysfs_attrs[] = {
|
||||
&manager_attr_name.attr,
|
||||
&manager_attr_display.attr,
|
||||
&manager_attr_default_color.attr,
|
||||
&manager_attr_trans_key_type.attr,
|
||||
&manager_attr_trans_key_value.attr,
|
||||
&manager_attr_trans_key_enabled.attr,
|
||||
&manager_attr_alpha_blending_enabled.attr,
|
||||
&manager_attr_cpr_enable.attr,
|
||||
&manager_attr_cpr_coef.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
static ssize_t manager_attr_show(struct kobject *kobj, struct attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct omap_overlay_manager *manager;
|
||||
struct manager_attribute *manager_attr;
|
||||
|
||||
manager = container_of(kobj, struct omap_overlay_manager, kobj);
|
||||
manager_attr = container_of(attr, struct manager_attribute, attr);
|
||||
|
||||
if (!manager_attr->show)
|
||||
return -ENOENT;
|
||||
|
||||
return manager_attr->show(manager, buf);
|
||||
}
|
||||
|
||||
static ssize_t manager_attr_store(struct kobject *kobj, struct attribute *attr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
struct omap_overlay_manager *manager;
|
||||
struct manager_attribute *manager_attr;
|
||||
|
||||
manager = container_of(kobj, struct omap_overlay_manager, kobj);
|
||||
manager_attr = container_of(attr, struct manager_attribute, attr);
|
||||
|
||||
if (!manager_attr->store)
|
||||
return -ENOENT;
|
||||
|
||||
return manager_attr->store(manager, buf, size);
|
||||
}
|
||||
|
||||
static const struct sysfs_ops manager_sysfs_ops = {
|
||||
.show = manager_attr_show,
|
||||
.store = manager_attr_store,
|
||||
};
|
||||
|
||||
static struct kobj_type manager_ktype = {
|
||||
.sysfs_ops = &manager_sysfs_ops,
|
||||
.default_attrs = manager_sysfs_attrs,
|
||||
};
|
||||
|
||||
static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
|
||||
{
|
||||
unsigned long timeout = msecs_to_jiffies(500);
|
||||
struct omap_dss_device *dssdev = mgr->get_device(mgr);
|
||||
u32 irq;
|
||||
int r;
|
||||
|
||||
@ -500,9 +52,9 @@ static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC)
|
||||
if (dssdev->type == OMAP_DISPLAY_TYPE_VENC)
|
||||
irq = DISPC_IRQ_EVSYNC_ODD;
|
||||
else if (mgr->device->type == OMAP_DISPLAY_TYPE_HDMI)
|
||||
else if (dssdev->type == OMAP_DISPLAY_TYPE_HDMI)
|
||||
irq = DISPC_IRQ_EVSYNC_EVEN;
|
||||
else
|
||||
irq = dispc_mgr_get_vsync_irq(mgr->id);
|
||||
@ -547,23 +99,24 @@ int dss_init_overlay_managers(struct platform_device *pdev)
|
||||
break;
|
||||
}
|
||||
|
||||
mgr->set_device = &dss_mgr_set_device;
|
||||
mgr->unset_device = &dss_mgr_unset_device;
|
||||
mgr->set_output = &dss_mgr_set_output;
|
||||
mgr->unset_output = &dss_mgr_unset_output;
|
||||
mgr->apply = &omap_dss_mgr_apply;
|
||||
mgr->set_manager_info = &dss_mgr_set_info;
|
||||
mgr->get_manager_info = &dss_mgr_get_info;
|
||||
mgr->wait_for_go = &dss_mgr_wait_for_go;
|
||||
mgr->wait_for_vsync = &dss_mgr_wait_for_vsync;
|
||||
mgr->get_device = &dss_mgr_get_device;
|
||||
|
||||
mgr->caps = 0;
|
||||
mgr->supported_displays =
|
||||
dss_feat_get_supported_displays(mgr->id);
|
||||
mgr->supported_outputs =
|
||||
dss_feat_get_supported_outputs(mgr->id);
|
||||
|
||||
INIT_LIST_HEAD(&mgr->overlays);
|
||||
|
||||
r = kobject_init_and_add(&mgr->kobj, &manager_ktype,
|
||||
&pdev->dev.kobj, "manager%d", i);
|
||||
|
||||
r = dss_manager_kobj_init(mgr, pdev);
|
||||
if (r)
|
||||
DSSERR("failed to create sysfs file\n");
|
||||
}
|
||||
@ -577,9 +130,7 @@ void dss_uninit_overlay_managers(struct platform_device *pdev)
|
||||
|
||||
for (i = 0; i < num_managers; ++i) {
|
||||
struct omap_overlay_manager *mgr = &managers[i];
|
||||
|
||||
kobject_del(&mgr->kobj);
|
||||
kobject_put(&mgr->kobj);
|
||||
dss_manager_kobj_uninit(mgr);
|
||||
}
|
||||
|
||||
kfree(managers);
|
||||
|
148
drivers/video/omap2/dss/output.c
Normal file
148
drivers/video/omap2/dss/output.c
Normal file
@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Texas Instruments Ltd
|
||||
* Author: Archit Taneja <archit@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/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <video/omapdss.h>
|
||||
|
||||
#include "dss.h"
|
||||
|
||||
static LIST_HEAD(output_list);
|
||||
static DEFINE_MUTEX(output_lock);
|
||||
|
||||
int omapdss_output_set_device(struct omap_dss_output *out,
|
||||
struct omap_dss_device *dssdev)
|
||||
{
|
||||
int r;
|
||||
|
||||
mutex_lock(&output_lock);
|
||||
|
||||
if (out->device) {
|
||||
DSSERR("output already has device %s connected to it\n",
|
||||
out->device->name);
|
||||
r = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (out->type != dssdev->type) {
|
||||
DSSERR("output type and display type don't match\n");
|
||||
r = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
out->device = dssdev;
|
||||
dssdev->output = out;
|
||||
|
||||
mutex_unlock(&output_lock);
|
||||
|
||||
return 0;
|
||||
err:
|
||||
mutex_unlock(&output_lock);
|
||||
|
||||
return r;
|
||||
}
|
||||
EXPORT_SYMBOL(omapdss_output_set_device);
|
||||
|
||||
int omapdss_output_unset_device(struct omap_dss_output *out)
|
||||
{
|
||||
int r;
|
||||
|
||||
mutex_lock(&output_lock);
|
||||
|
||||
if (!out->device) {
|
||||
DSSERR("output doesn't have a device connected to it\n");
|
||||
r = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (out->device->state != OMAP_DSS_DISPLAY_DISABLED) {
|
||||
DSSERR("device %s is not disabled, cannot unset device\n",
|
||||
out->device->name);
|
||||
r = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
out->device->output = NULL;
|
||||
out->device = NULL;
|
||||
|
||||
mutex_unlock(&output_lock);
|
||||
|
||||
return 0;
|
||||
err:
|
||||
mutex_unlock(&output_lock);
|
||||
|
||||
return r;
|
||||
}
|
||||
EXPORT_SYMBOL(omapdss_output_unset_device);
|
||||
|
||||
void dss_register_output(struct omap_dss_output *out)
|
||||
{
|
||||
list_add_tail(&out->list, &output_list);
|
||||
}
|
||||
|
||||
void dss_unregister_output(struct omap_dss_output *out)
|
||||
{
|
||||
list_del(&out->list);
|
||||
}
|
||||
|
||||
struct omap_dss_output *omap_dss_get_output(enum omap_dss_output_id id)
|
||||
{
|
||||
struct omap_dss_output *out;
|
||||
|
||||
list_for_each_entry(out, &output_list, list) {
|
||||
if (out->id == id)
|
||||
return out;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct omap_dss_output *omapdss_get_output_from_dssdev(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct omap_dss_output *out = NULL;
|
||||
enum omap_dss_output_id id;
|
||||
|
||||
switch (dssdev->type) {
|
||||
case OMAP_DISPLAY_TYPE_DPI:
|
||||
out = omap_dss_get_output(OMAP_DSS_OUTPUT_DPI);
|
||||
break;
|
||||
case OMAP_DISPLAY_TYPE_DBI:
|
||||
out = omap_dss_get_output(OMAP_DSS_OUTPUT_DBI);
|
||||
break;
|
||||
case OMAP_DISPLAY_TYPE_SDI:
|
||||
out = omap_dss_get_output(OMAP_DSS_OUTPUT_SDI);
|
||||
break;
|
||||
case OMAP_DISPLAY_TYPE_VENC:
|
||||
out = omap_dss_get_output(OMAP_DSS_OUTPUT_VENC);
|
||||
break;
|
||||
case OMAP_DISPLAY_TYPE_HDMI:
|
||||
out = omap_dss_get_output(OMAP_DSS_OUTPUT_HDMI);
|
||||
break;
|
||||
case OMAP_DISPLAY_TYPE_DSI:
|
||||
id = dssdev->phy.dsi.module == 0 ? OMAP_DSS_OUTPUT_DSI1 :
|
||||
OMAP_DSS_OUTPUT_DSI2;
|
||||
out = omap_dss_get_output(id);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
456
drivers/video/omap2/dss/overlay-sysfs.c
Normal file
456
drivers/video/omap2/dss/overlay-sysfs.c
Normal file
@ -0,0 +1,456 @@
|
||||
/*
|
||||
* Copyright (C) 2009 Nokia Corporation
|
||||
* Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
|
||||
*
|
||||
* Some code and ideas taken from drivers/video/omap/ driver
|
||||
* by Imre Deak.
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#define DSS_SUBSYS_NAME "OVERLAY"
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/kobject.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include <video/omapdss.h>
|
||||
|
||||
#include "dss.h"
|
||||
#include "dss_features.h"
|
||||
|
||||
static ssize_t overlay_name_show(struct omap_overlay *ovl, char *buf)
|
||||
{
|
||||
return snprintf(buf, PAGE_SIZE, "%s\n", ovl->name);
|
||||
}
|
||||
|
||||
static ssize_t overlay_manager_show(struct omap_overlay *ovl, char *buf)
|
||||
{
|
||||
return snprintf(buf, PAGE_SIZE, "%s\n",
|
||||
ovl->manager ? ovl->manager->name : "<none>");
|
||||
}
|
||||
|
||||
static ssize_t overlay_manager_store(struct omap_overlay *ovl, const char *buf,
|
||||
size_t size)
|
||||
{
|
||||
int i, r;
|
||||
struct omap_overlay_manager *mgr = NULL;
|
||||
struct omap_overlay_manager *old_mgr;
|
||||
int len = size;
|
||||
|
||||
if (buf[size-1] == '\n')
|
||||
--len;
|
||||
|
||||
if (len > 0) {
|
||||
for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
|
||||
mgr = omap_dss_get_overlay_manager(i);
|
||||
|
||||
if (sysfs_streq(buf, mgr->name))
|
||||
break;
|
||||
|
||||
mgr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (len > 0 && mgr == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
if (mgr)
|
||||
DSSDBG("manager %s found\n", mgr->name);
|
||||
|
||||
if (mgr == ovl->manager)
|
||||
return size;
|
||||
|
||||
old_mgr = ovl->manager;
|
||||
|
||||
r = dispc_runtime_get();
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* detach old manager */
|
||||
if (old_mgr) {
|
||||
r = ovl->unset_manager(ovl);
|
||||
if (r) {
|
||||
DSSERR("detach failed\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
r = old_mgr->apply(old_mgr);
|
||||
if (r)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (mgr) {
|
||||
r = ovl->set_manager(ovl, mgr);
|
||||
if (r) {
|
||||
DSSERR("Failed to attach overlay\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
r = mgr->apply(mgr);
|
||||
if (r)
|
||||
goto err;
|
||||
}
|
||||
|
||||
dispc_runtime_put();
|
||||
|
||||
return size;
|
||||
|
||||
err:
|
||||
dispc_runtime_put();
|
||||
return r;
|
||||
}
|
||||
|
||||
static ssize_t overlay_input_size_show(struct omap_overlay *ovl, char *buf)
|
||||
{
|
||||
struct omap_overlay_info info;
|
||||
|
||||
ovl->get_overlay_info(ovl, &info);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%d,%d\n",
|
||||
info.width, info.height);
|
||||
}
|
||||
|
||||
static ssize_t overlay_screen_width_show(struct omap_overlay *ovl, char *buf)
|
||||
{
|
||||
struct omap_overlay_info info;
|
||||
|
||||
ovl->get_overlay_info(ovl, &info);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", info.screen_width);
|
||||
}
|
||||
|
||||
static ssize_t overlay_position_show(struct omap_overlay *ovl, char *buf)
|
||||
{
|
||||
struct omap_overlay_info info;
|
||||
|
||||
ovl->get_overlay_info(ovl, &info);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%d,%d\n",
|
||||
info.pos_x, info.pos_y);
|
||||
}
|
||||
|
||||
static ssize_t overlay_position_store(struct omap_overlay *ovl,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
int r;
|
||||
char *last;
|
||||
struct omap_overlay_info info;
|
||||
|
||||
ovl->get_overlay_info(ovl, &info);
|
||||
|
||||
info.pos_x = simple_strtoul(buf, &last, 10);
|
||||
++last;
|
||||
if (last - buf >= size)
|
||||
return -EINVAL;
|
||||
|
||||
info.pos_y = simple_strtoul(last, &last, 10);
|
||||
|
||||
r = ovl->set_overlay_info(ovl, &info);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (ovl->manager) {
|
||||
r = ovl->manager->apply(ovl->manager);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static ssize_t overlay_output_size_show(struct omap_overlay *ovl, char *buf)
|
||||
{
|
||||
struct omap_overlay_info info;
|
||||
|
||||
ovl->get_overlay_info(ovl, &info);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%d,%d\n",
|
||||
info.out_width, info.out_height);
|
||||
}
|
||||
|
||||
static ssize_t overlay_output_size_store(struct omap_overlay *ovl,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
int r;
|
||||
char *last;
|
||||
struct omap_overlay_info info;
|
||||
|
||||
ovl->get_overlay_info(ovl, &info);
|
||||
|
||||
info.out_width = simple_strtoul(buf, &last, 10);
|
||||
++last;
|
||||
if (last - buf >= size)
|
||||
return -EINVAL;
|
||||
|
||||
info.out_height = simple_strtoul(last, &last, 10);
|
||||
|
||||
r = ovl->set_overlay_info(ovl, &info);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (ovl->manager) {
|
||||
r = ovl->manager->apply(ovl->manager);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static ssize_t overlay_enabled_show(struct omap_overlay *ovl, char *buf)
|
||||
{
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", ovl->is_enabled(ovl));
|
||||
}
|
||||
|
||||
static ssize_t overlay_enabled_store(struct omap_overlay *ovl, const char *buf,
|
||||
size_t size)
|
||||
{
|
||||
int r;
|
||||
bool enable;
|
||||
|
||||
r = strtobool(buf, &enable);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (enable)
|
||||
r = ovl->enable(ovl);
|
||||
else
|
||||
r = ovl->disable(ovl);
|
||||
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static ssize_t overlay_global_alpha_show(struct omap_overlay *ovl, char *buf)
|
||||
{
|
||||
struct omap_overlay_info info;
|
||||
|
||||
ovl->get_overlay_info(ovl, &info);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n",
|
||||
info.global_alpha);
|
||||
}
|
||||
|
||||
static ssize_t overlay_global_alpha_store(struct omap_overlay *ovl,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
int r;
|
||||
u8 alpha;
|
||||
struct omap_overlay_info info;
|
||||
|
||||
if ((ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0)
|
||||
return -ENODEV;
|
||||
|
||||
r = kstrtou8(buf, 0, &alpha);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
ovl->get_overlay_info(ovl, &info);
|
||||
|
||||
info.global_alpha = alpha;
|
||||
|
||||
r = ovl->set_overlay_info(ovl, &info);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (ovl->manager) {
|
||||
r = ovl->manager->apply(ovl->manager);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static ssize_t overlay_pre_mult_alpha_show(struct omap_overlay *ovl,
|
||||
char *buf)
|
||||
{
|
||||
struct omap_overlay_info info;
|
||||
|
||||
ovl->get_overlay_info(ovl, &info);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n",
|
||||
info.pre_mult_alpha);
|
||||
}
|
||||
|
||||
static ssize_t overlay_pre_mult_alpha_store(struct omap_overlay *ovl,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
int r;
|
||||
u8 alpha;
|
||||
struct omap_overlay_info info;
|
||||
|
||||
if ((ovl->caps & OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA) == 0)
|
||||
return -ENODEV;
|
||||
|
||||
r = kstrtou8(buf, 0, &alpha);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
ovl->get_overlay_info(ovl, &info);
|
||||
|
||||
info.pre_mult_alpha = alpha;
|
||||
|
||||
r = ovl->set_overlay_info(ovl, &info);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (ovl->manager) {
|
||||
r = ovl->manager->apply(ovl->manager);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static ssize_t overlay_zorder_show(struct omap_overlay *ovl, char *buf)
|
||||
{
|
||||
struct omap_overlay_info info;
|
||||
|
||||
ovl->get_overlay_info(ovl, &info);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", info.zorder);
|
||||
}
|
||||
|
||||
static ssize_t overlay_zorder_store(struct omap_overlay *ovl,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
int r;
|
||||
u8 zorder;
|
||||
struct omap_overlay_info info;
|
||||
|
||||
if ((ovl->caps & OMAP_DSS_OVL_CAP_ZORDER) == 0)
|
||||
return -ENODEV;
|
||||
|
||||
r = kstrtou8(buf, 0, &zorder);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
ovl->get_overlay_info(ovl, &info);
|
||||
|
||||
info.zorder = zorder;
|
||||
|
||||
r = ovl->set_overlay_info(ovl, &info);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (ovl->manager) {
|
||||
r = ovl->manager->apply(ovl->manager);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
struct overlay_attribute {
|
||||
struct attribute attr;
|
||||
ssize_t (*show)(struct omap_overlay *, char *);
|
||||
ssize_t (*store)(struct omap_overlay *, const char *, size_t);
|
||||
};
|
||||
|
||||
#define OVERLAY_ATTR(_name, _mode, _show, _store) \
|
||||
struct overlay_attribute overlay_attr_##_name = \
|
||||
__ATTR(_name, _mode, _show, _store)
|
||||
|
||||
static OVERLAY_ATTR(name, S_IRUGO, overlay_name_show, NULL);
|
||||
static OVERLAY_ATTR(manager, S_IRUGO|S_IWUSR,
|
||||
overlay_manager_show, overlay_manager_store);
|
||||
static OVERLAY_ATTR(input_size, S_IRUGO, overlay_input_size_show, NULL);
|
||||
static OVERLAY_ATTR(screen_width, S_IRUGO, overlay_screen_width_show, NULL);
|
||||
static OVERLAY_ATTR(position, S_IRUGO|S_IWUSR,
|
||||
overlay_position_show, overlay_position_store);
|
||||
static OVERLAY_ATTR(output_size, S_IRUGO|S_IWUSR,
|
||||
overlay_output_size_show, overlay_output_size_store);
|
||||
static OVERLAY_ATTR(enabled, S_IRUGO|S_IWUSR,
|
||||
overlay_enabled_show, overlay_enabled_store);
|
||||
static OVERLAY_ATTR(global_alpha, S_IRUGO|S_IWUSR,
|
||||
overlay_global_alpha_show, overlay_global_alpha_store);
|
||||
static OVERLAY_ATTR(pre_mult_alpha, S_IRUGO|S_IWUSR,
|
||||
overlay_pre_mult_alpha_show,
|
||||
overlay_pre_mult_alpha_store);
|
||||
static OVERLAY_ATTR(zorder, S_IRUGO|S_IWUSR,
|
||||
overlay_zorder_show, overlay_zorder_store);
|
||||
|
||||
static struct attribute *overlay_sysfs_attrs[] = {
|
||||
&overlay_attr_name.attr,
|
||||
&overlay_attr_manager.attr,
|
||||
&overlay_attr_input_size.attr,
|
||||
&overlay_attr_screen_width.attr,
|
||||
&overlay_attr_position.attr,
|
||||
&overlay_attr_output_size.attr,
|
||||
&overlay_attr_enabled.attr,
|
||||
&overlay_attr_global_alpha.attr,
|
||||
&overlay_attr_pre_mult_alpha.attr,
|
||||
&overlay_attr_zorder.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
static ssize_t overlay_attr_show(struct kobject *kobj, struct attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct omap_overlay *overlay;
|
||||
struct overlay_attribute *overlay_attr;
|
||||
|
||||
overlay = container_of(kobj, struct omap_overlay, kobj);
|
||||
overlay_attr = container_of(attr, struct overlay_attribute, attr);
|
||||
|
||||
if (!overlay_attr->show)
|
||||
return -ENOENT;
|
||||
|
||||
return overlay_attr->show(overlay, buf);
|
||||
}
|
||||
|
||||
static ssize_t overlay_attr_store(struct kobject *kobj, struct attribute *attr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
struct omap_overlay *overlay;
|
||||
struct overlay_attribute *overlay_attr;
|
||||
|
||||
overlay = container_of(kobj, struct omap_overlay, kobj);
|
||||
overlay_attr = container_of(attr, struct overlay_attribute, attr);
|
||||
|
||||
if (!overlay_attr->store)
|
||||
return -ENOENT;
|
||||
|
||||
return overlay_attr->store(overlay, buf, size);
|
||||
}
|
||||
|
||||
static const struct sysfs_ops overlay_sysfs_ops = {
|
||||
.show = overlay_attr_show,
|
||||
.store = overlay_attr_store,
|
||||
};
|
||||
|
||||
static struct kobj_type overlay_ktype = {
|
||||
.sysfs_ops = &overlay_sysfs_ops,
|
||||
.default_attrs = overlay_sysfs_attrs,
|
||||
};
|
||||
|
||||
int dss_overlay_kobj_init(struct omap_overlay *ovl,
|
||||
struct platform_device *pdev)
|
||||
{
|
||||
return kobject_init_and_add(&ovl->kobj, &overlay_ktype,
|
||||
&pdev->dev.kobj, "overlay%d", ovl->id);
|
||||
}
|
||||
|
||||
void dss_overlay_kobj_uninit(struct omap_overlay *ovl)
|
||||
{
|
||||
kobject_del(&ovl->kobj);
|
||||
kobject_put(&ovl->kobj);
|
||||
}
|
@ -26,13 +26,11 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/kobject.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <video/omapdss.h>
|
||||
#include <plat/cpu.h>
|
||||
|
||||
#include "dss.h"
|
||||
#include "dss_features.h"
|
||||
@ -40,417 +38,13 @@
|
||||
static int num_overlays;
|
||||
static struct omap_overlay *overlays;
|
||||
|
||||
static ssize_t overlay_name_show(struct omap_overlay *ovl, char *buf)
|
||||
static inline struct omap_dss_device *dss_ovl_get_device(struct omap_overlay *ovl)
|
||||
{
|
||||
return snprintf(buf, PAGE_SIZE, "%s\n", ovl->name);
|
||||
return ovl->manager ?
|
||||
(ovl->manager->output ? ovl->manager->output->device : NULL) :
|
||||
NULL;
|
||||
}
|
||||
|
||||
static ssize_t overlay_manager_show(struct omap_overlay *ovl, char *buf)
|
||||
{
|
||||
return snprintf(buf, PAGE_SIZE, "%s\n",
|
||||
ovl->manager ? ovl->manager->name : "<none>");
|
||||
}
|
||||
|
||||
static ssize_t overlay_manager_store(struct omap_overlay *ovl, const char *buf,
|
||||
size_t size)
|
||||
{
|
||||
int i, r;
|
||||
struct omap_overlay_manager *mgr = NULL;
|
||||
struct omap_overlay_manager *old_mgr;
|
||||
int len = size;
|
||||
|
||||
if (buf[size-1] == '\n')
|
||||
--len;
|
||||
|
||||
if (len > 0) {
|
||||
for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
|
||||
mgr = omap_dss_get_overlay_manager(i);
|
||||
|
||||
if (sysfs_streq(buf, mgr->name))
|
||||
break;
|
||||
|
||||
mgr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (len > 0 && mgr == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
if (mgr)
|
||||
DSSDBG("manager %s found\n", mgr->name);
|
||||
|
||||
if (mgr == ovl->manager)
|
||||
return size;
|
||||
|
||||
old_mgr = ovl->manager;
|
||||
|
||||
r = dispc_runtime_get();
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* detach old manager */
|
||||
if (old_mgr) {
|
||||
r = ovl->unset_manager(ovl);
|
||||
if (r) {
|
||||
DSSERR("detach failed\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
r = old_mgr->apply(old_mgr);
|
||||
if (r)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (mgr) {
|
||||
r = ovl->set_manager(ovl, mgr);
|
||||
if (r) {
|
||||
DSSERR("Failed to attach overlay\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
r = mgr->apply(mgr);
|
||||
if (r)
|
||||
goto err;
|
||||
}
|
||||
|
||||
dispc_runtime_put();
|
||||
|
||||
return size;
|
||||
|
||||
err:
|
||||
dispc_runtime_put();
|
||||
return r;
|
||||
}
|
||||
|
||||
static ssize_t overlay_input_size_show(struct omap_overlay *ovl, char *buf)
|
||||
{
|
||||
struct omap_overlay_info info;
|
||||
|
||||
ovl->get_overlay_info(ovl, &info);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%d,%d\n",
|
||||
info.width, info.height);
|
||||
}
|
||||
|
||||
static ssize_t overlay_screen_width_show(struct omap_overlay *ovl, char *buf)
|
||||
{
|
||||
struct omap_overlay_info info;
|
||||
|
||||
ovl->get_overlay_info(ovl, &info);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", info.screen_width);
|
||||
}
|
||||
|
||||
static ssize_t overlay_position_show(struct omap_overlay *ovl, char *buf)
|
||||
{
|
||||
struct omap_overlay_info info;
|
||||
|
||||
ovl->get_overlay_info(ovl, &info);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%d,%d\n",
|
||||
info.pos_x, info.pos_y);
|
||||
}
|
||||
|
||||
static ssize_t overlay_position_store(struct omap_overlay *ovl,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
int r;
|
||||
char *last;
|
||||
struct omap_overlay_info info;
|
||||
|
||||
ovl->get_overlay_info(ovl, &info);
|
||||
|
||||
info.pos_x = simple_strtoul(buf, &last, 10);
|
||||
++last;
|
||||
if (last - buf >= size)
|
||||
return -EINVAL;
|
||||
|
||||
info.pos_y = simple_strtoul(last, &last, 10);
|
||||
|
||||
r = ovl->set_overlay_info(ovl, &info);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (ovl->manager) {
|
||||
r = ovl->manager->apply(ovl->manager);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static ssize_t overlay_output_size_show(struct omap_overlay *ovl, char *buf)
|
||||
{
|
||||
struct omap_overlay_info info;
|
||||
|
||||
ovl->get_overlay_info(ovl, &info);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%d,%d\n",
|
||||
info.out_width, info.out_height);
|
||||
}
|
||||
|
||||
static ssize_t overlay_output_size_store(struct omap_overlay *ovl,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
int r;
|
||||
char *last;
|
||||
struct omap_overlay_info info;
|
||||
|
||||
ovl->get_overlay_info(ovl, &info);
|
||||
|
||||
info.out_width = simple_strtoul(buf, &last, 10);
|
||||
++last;
|
||||
if (last - buf >= size)
|
||||
return -EINVAL;
|
||||
|
||||
info.out_height = simple_strtoul(last, &last, 10);
|
||||
|
||||
r = ovl->set_overlay_info(ovl, &info);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (ovl->manager) {
|
||||
r = ovl->manager->apply(ovl->manager);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static ssize_t overlay_enabled_show(struct omap_overlay *ovl, char *buf)
|
||||
{
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", ovl->is_enabled(ovl));
|
||||
}
|
||||
|
||||
static ssize_t overlay_enabled_store(struct omap_overlay *ovl, const char *buf,
|
||||
size_t size)
|
||||
{
|
||||
int r;
|
||||
bool enable;
|
||||
|
||||
r = strtobool(buf, &enable);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (enable)
|
||||
r = ovl->enable(ovl);
|
||||
else
|
||||
r = ovl->disable(ovl);
|
||||
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static ssize_t overlay_global_alpha_show(struct omap_overlay *ovl, char *buf)
|
||||
{
|
||||
struct omap_overlay_info info;
|
||||
|
||||
ovl->get_overlay_info(ovl, &info);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n",
|
||||
info.global_alpha);
|
||||
}
|
||||
|
||||
static ssize_t overlay_global_alpha_store(struct omap_overlay *ovl,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
int r;
|
||||
u8 alpha;
|
||||
struct omap_overlay_info info;
|
||||
|
||||
if ((ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0)
|
||||
return -ENODEV;
|
||||
|
||||
r = kstrtou8(buf, 0, &alpha);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
ovl->get_overlay_info(ovl, &info);
|
||||
|
||||
info.global_alpha = alpha;
|
||||
|
||||
r = ovl->set_overlay_info(ovl, &info);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (ovl->manager) {
|
||||
r = ovl->manager->apply(ovl->manager);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static ssize_t overlay_pre_mult_alpha_show(struct omap_overlay *ovl,
|
||||
char *buf)
|
||||
{
|
||||
struct omap_overlay_info info;
|
||||
|
||||
ovl->get_overlay_info(ovl, &info);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n",
|
||||
info.pre_mult_alpha);
|
||||
}
|
||||
|
||||
static ssize_t overlay_pre_mult_alpha_store(struct omap_overlay *ovl,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
int r;
|
||||
u8 alpha;
|
||||
struct omap_overlay_info info;
|
||||
|
||||
if ((ovl->caps & OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA) == 0)
|
||||
return -ENODEV;
|
||||
|
||||
r = kstrtou8(buf, 0, &alpha);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
ovl->get_overlay_info(ovl, &info);
|
||||
|
||||
info.pre_mult_alpha = alpha;
|
||||
|
||||
r = ovl->set_overlay_info(ovl, &info);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (ovl->manager) {
|
||||
r = ovl->manager->apply(ovl->manager);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static ssize_t overlay_zorder_show(struct omap_overlay *ovl, char *buf)
|
||||
{
|
||||
struct omap_overlay_info info;
|
||||
|
||||
ovl->get_overlay_info(ovl, &info);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", info.zorder);
|
||||
}
|
||||
|
||||
static ssize_t overlay_zorder_store(struct omap_overlay *ovl,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
int r;
|
||||
u8 zorder;
|
||||
struct omap_overlay_info info;
|
||||
|
||||
if ((ovl->caps & OMAP_DSS_OVL_CAP_ZORDER) == 0)
|
||||
return -ENODEV;
|
||||
|
||||
r = kstrtou8(buf, 0, &zorder);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
ovl->get_overlay_info(ovl, &info);
|
||||
|
||||
info.zorder = zorder;
|
||||
|
||||
r = ovl->set_overlay_info(ovl, &info);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (ovl->manager) {
|
||||
r = ovl->manager->apply(ovl->manager);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
struct overlay_attribute {
|
||||
struct attribute attr;
|
||||
ssize_t (*show)(struct omap_overlay *, char *);
|
||||
ssize_t (*store)(struct omap_overlay *, const char *, size_t);
|
||||
};
|
||||
|
||||
#define OVERLAY_ATTR(_name, _mode, _show, _store) \
|
||||
struct overlay_attribute overlay_attr_##_name = \
|
||||
__ATTR(_name, _mode, _show, _store)
|
||||
|
||||
static OVERLAY_ATTR(name, S_IRUGO, overlay_name_show, NULL);
|
||||
static OVERLAY_ATTR(manager, S_IRUGO|S_IWUSR,
|
||||
overlay_manager_show, overlay_manager_store);
|
||||
static OVERLAY_ATTR(input_size, S_IRUGO, overlay_input_size_show, NULL);
|
||||
static OVERLAY_ATTR(screen_width, S_IRUGO, overlay_screen_width_show, NULL);
|
||||
static OVERLAY_ATTR(position, S_IRUGO|S_IWUSR,
|
||||
overlay_position_show, overlay_position_store);
|
||||
static OVERLAY_ATTR(output_size, S_IRUGO|S_IWUSR,
|
||||
overlay_output_size_show, overlay_output_size_store);
|
||||
static OVERLAY_ATTR(enabled, S_IRUGO|S_IWUSR,
|
||||
overlay_enabled_show, overlay_enabled_store);
|
||||
static OVERLAY_ATTR(global_alpha, S_IRUGO|S_IWUSR,
|
||||
overlay_global_alpha_show, overlay_global_alpha_store);
|
||||
static OVERLAY_ATTR(pre_mult_alpha, S_IRUGO|S_IWUSR,
|
||||
overlay_pre_mult_alpha_show,
|
||||
overlay_pre_mult_alpha_store);
|
||||
static OVERLAY_ATTR(zorder, S_IRUGO|S_IWUSR,
|
||||
overlay_zorder_show, overlay_zorder_store);
|
||||
|
||||
static struct attribute *overlay_sysfs_attrs[] = {
|
||||
&overlay_attr_name.attr,
|
||||
&overlay_attr_manager.attr,
|
||||
&overlay_attr_input_size.attr,
|
||||
&overlay_attr_screen_width.attr,
|
||||
&overlay_attr_position.attr,
|
||||
&overlay_attr_output_size.attr,
|
||||
&overlay_attr_enabled.attr,
|
||||
&overlay_attr_global_alpha.attr,
|
||||
&overlay_attr_pre_mult_alpha.attr,
|
||||
&overlay_attr_zorder.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
static ssize_t overlay_attr_show(struct kobject *kobj, struct attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct omap_overlay *overlay;
|
||||
struct overlay_attribute *overlay_attr;
|
||||
|
||||
overlay = container_of(kobj, struct omap_overlay, kobj);
|
||||
overlay_attr = container_of(attr, struct overlay_attribute, attr);
|
||||
|
||||
if (!overlay_attr->show)
|
||||
return -ENOENT;
|
||||
|
||||
return overlay_attr->show(overlay, buf);
|
||||
}
|
||||
|
||||
static ssize_t overlay_attr_store(struct kobject *kobj, struct attribute *attr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
struct omap_overlay *overlay;
|
||||
struct overlay_attribute *overlay_attr;
|
||||
|
||||
overlay = container_of(kobj, struct omap_overlay, kobj);
|
||||
overlay_attr = container_of(attr, struct overlay_attribute, attr);
|
||||
|
||||
if (!overlay_attr->store)
|
||||
return -ENOENT;
|
||||
|
||||
return overlay_attr->store(overlay, buf, size);
|
||||
}
|
||||
|
||||
static const struct sysfs_ops overlay_sysfs_ops = {
|
||||
.show = overlay_attr_show,
|
||||
.store = overlay_attr_store,
|
||||
};
|
||||
|
||||
static struct kobj_type overlay_ktype = {
|
||||
.sysfs_ops = &overlay_sysfs_ops,
|
||||
.default_attrs = overlay_sysfs_attrs,
|
||||
};
|
||||
|
||||
int omap_dss_get_num_overlays(void)
|
||||
{
|
||||
return num_overlays;
|
||||
@ -507,97 +101,25 @@ void dss_init_overlays(struct platform_device *pdev)
|
||||
ovl->set_overlay_info = &dss_ovl_set_info;
|
||||
ovl->get_overlay_info = &dss_ovl_get_info;
|
||||
ovl->wait_for_go = &dss_mgr_wait_for_go_ovl;
|
||||
ovl->get_device = &dss_ovl_get_device;
|
||||
|
||||
ovl->caps = dss_feat_get_overlay_caps(ovl->id);
|
||||
ovl->supported_modes =
|
||||
dss_feat_get_supported_color_modes(ovl->id);
|
||||
|
||||
r = kobject_init_and_add(&ovl->kobj, &overlay_ktype,
|
||||
&pdev->dev.kobj, "overlay%d", i);
|
||||
|
||||
r = dss_overlay_kobj_init(ovl, pdev);
|
||||
if (r)
|
||||
DSSERR("failed to create sysfs file\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* connect overlays to the new device, if not already connected. if force
|
||||
* selected, connect always. */
|
||||
void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
|
||||
{
|
||||
int i;
|
||||
struct omap_overlay_manager *lcd_mgr;
|
||||
struct omap_overlay_manager *tv_mgr;
|
||||
struct omap_overlay_manager *lcd2_mgr = NULL;
|
||||
struct omap_overlay_manager *lcd3_mgr = NULL;
|
||||
struct omap_overlay_manager *mgr = NULL;
|
||||
|
||||
lcd_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD);
|
||||
tv_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_DIGIT);
|
||||
if (dss_has_feature(FEAT_MGR_LCD3))
|
||||
lcd3_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD3);
|
||||
if (dss_has_feature(FEAT_MGR_LCD2))
|
||||
lcd2_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD2);
|
||||
|
||||
if (dssdev->channel == OMAP_DSS_CHANNEL_LCD3) {
|
||||
if (!lcd3_mgr->device || force) {
|
||||
if (lcd3_mgr->device)
|
||||
lcd3_mgr->unset_device(lcd3_mgr);
|
||||
lcd3_mgr->set_device(lcd3_mgr, dssdev);
|
||||
mgr = lcd3_mgr;
|
||||
}
|
||||
} else if (dssdev->channel == OMAP_DSS_CHANNEL_LCD2) {
|
||||
if (!lcd2_mgr->device || force) {
|
||||
if (lcd2_mgr->device)
|
||||
lcd2_mgr->unset_device(lcd2_mgr);
|
||||
lcd2_mgr->set_device(lcd2_mgr, dssdev);
|
||||
mgr = lcd2_mgr;
|
||||
}
|
||||
} 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);
|
||||
lcd_mgr->set_device(lcd_mgr, dssdev);
|
||||
mgr = lcd_mgr;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
tv_mgr->set_device(tv_mgr, dssdev);
|
||||
mgr = tv_mgr;
|
||||
}
|
||||
}
|
||||
|
||||
if (mgr) {
|
||||
dispc_runtime_get();
|
||||
|
||||
for (i = 0; i < dss_feat_get_num_ovls(); i++) {
|
||||
struct omap_overlay *ovl;
|
||||
ovl = omap_dss_get_overlay(i);
|
||||
if (!ovl->manager || force) {
|
||||
if (ovl->manager)
|
||||
ovl->unset_manager(ovl);
|
||||
ovl->set_manager(ovl, mgr);
|
||||
}
|
||||
}
|
||||
|
||||
dispc_runtime_put();
|
||||
}
|
||||
}
|
||||
|
||||
void dss_uninit_overlays(struct platform_device *pdev)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < num_overlays; ++i) {
|
||||
struct omap_overlay *ovl = &overlays[i];
|
||||
|
||||
kobject_del(&ovl->kobj);
|
||||
kobject_put(&ovl->kobj);
|
||||
dss_overlay_kobj_uninit(ovl);
|
||||
}
|
||||
|
||||
kfree(overlays);
|
||||
|
@ -111,6 +111,13 @@ static struct {
|
||||
struct omap_dss_device *dssdev[2];
|
||||
|
||||
struct semaphore bus_lock;
|
||||
|
||||
struct omap_video_timings timings;
|
||||
int pixel_size;
|
||||
int data_lines;
|
||||
struct rfbi_timings intf_timings;
|
||||
|
||||
struct omap_dss_output output;
|
||||
} rfbi;
|
||||
|
||||
static inline void rfbi_write_reg(const struct rfbi_reg idx, u32 val)
|
||||
@ -300,30 +307,23 @@ void omap_rfbi_write_pixels(const void __iomem *buf, int scr_width,
|
||||
}
|
||||
EXPORT_SYMBOL(omap_rfbi_write_pixels);
|
||||
|
||||
static int rfbi_transfer_area(struct omap_dss_device *dssdev, u16 width,
|
||||
u16 height, void (*callback)(void *data), void *data)
|
||||
static int rfbi_transfer_area(struct omap_dss_device *dssdev,
|
||||
void (*callback)(void *data), void *data)
|
||||
{
|
||||
u32 l;
|
||||
int r;
|
||||
struct omap_video_timings timings = {
|
||||
.hsw = 1,
|
||||
.hfp = 1,
|
||||
.hbp = 1,
|
||||
.vsw = 1,
|
||||
.vfp = 0,
|
||||
.vbp = 0,
|
||||
.x_res = width,
|
||||
.y_res = height,
|
||||
};
|
||||
struct omap_overlay_manager *mgr = dssdev->output->manager;
|
||||
u16 width = rfbi.timings.x_res;
|
||||
u16 height = rfbi.timings.y_res;
|
||||
|
||||
/*BUG_ON(callback == 0);*/
|
||||
BUG_ON(rfbi.framedone_callback != NULL);
|
||||
|
||||
DSSDBG("rfbi_transfer_area %dx%d\n", width, height);
|
||||
|
||||
dss_mgr_set_timings(dssdev->manager, &timings);
|
||||
dss_mgr_set_timings(mgr, &rfbi.timings);
|
||||
|
||||
r = dss_mgr_enable(dssdev->manager);
|
||||
r = dss_mgr_enable(mgr);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
@ -770,63 +770,46 @@ static int rfbi_configure(int rfbi_module, int bpp, int lines)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int omap_rfbi_configure(struct omap_dss_device *dssdev, int pixel_size,
|
||||
int data_lines)
|
||||
int omap_rfbi_configure(struct omap_dss_device *dssdev)
|
||||
{
|
||||
return rfbi_configure(dssdev->phy.rfbi.channel, pixel_size, data_lines);
|
||||
return rfbi_configure(dssdev->phy.rfbi.channel, rfbi.pixel_size,
|
||||
rfbi.data_lines);
|
||||
}
|
||||
EXPORT_SYMBOL(omap_rfbi_configure);
|
||||
|
||||
int omap_rfbi_prepare_update(struct omap_dss_device *dssdev,
|
||||
u16 *x, u16 *y, u16 *w, u16 *h)
|
||||
int omap_rfbi_update(struct omap_dss_device *dssdev, void (*callback)(void *),
|
||||
void *data)
|
||||
{
|
||||
u16 dw, dh;
|
||||
struct omap_video_timings timings = {
|
||||
.hsw = 1,
|
||||
.hfp = 1,
|
||||
.hbp = 1,
|
||||
.vsw = 1,
|
||||
.vfp = 0,
|
||||
.vbp = 0,
|
||||
.x_res = *w,
|
||||
.y_res = *h,
|
||||
};
|
||||
|
||||
dssdev->driver->get_resolution(dssdev, &dw, &dh);
|
||||
|
||||
if (*x > dw || *y > dh)
|
||||
return -EINVAL;
|
||||
|
||||
if (*x + *w > dw)
|
||||
return -EINVAL;
|
||||
|
||||
if (*y + *h > dh)
|
||||
return -EINVAL;
|
||||
|
||||
if (*w == 1)
|
||||
return -EINVAL;
|
||||
|
||||
if (*w == 0 || *h == 0)
|
||||
return -EINVAL;
|
||||
|
||||
dss_mgr_set_timings(dssdev->manager, &timings);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(omap_rfbi_prepare_update);
|
||||
|
||||
int omap_rfbi_update(struct omap_dss_device *dssdev,
|
||||
u16 x, u16 y, u16 w, u16 h,
|
||||
void (*callback)(void *), void *data)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = rfbi_transfer_area(dssdev, w, h, callback, data);
|
||||
|
||||
return r;
|
||||
return rfbi_transfer_area(dssdev, callback, data);
|
||||
}
|
||||
EXPORT_SYMBOL(omap_rfbi_update);
|
||||
|
||||
void omapdss_rfbi_set_size(struct omap_dss_device *dssdev, u16 w, u16 h)
|
||||
{
|
||||
rfbi.timings.x_res = w;
|
||||
rfbi.timings.y_res = h;
|
||||
}
|
||||
EXPORT_SYMBOL(omapdss_rfbi_set_size);
|
||||
|
||||
void omapdss_rfbi_set_pixel_size(struct omap_dss_device *dssdev, int pixel_size)
|
||||
{
|
||||
rfbi.pixel_size = pixel_size;
|
||||
}
|
||||
EXPORT_SYMBOL(omapdss_rfbi_set_pixel_size);
|
||||
|
||||
void omapdss_rfbi_set_data_lines(struct omap_dss_device *dssdev, int data_lines)
|
||||
{
|
||||
rfbi.data_lines = data_lines;
|
||||
}
|
||||
EXPORT_SYMBOL(omapdss_rfbi_set_data_lines);
|
||||
|
||||
void omapdss_rfbi_set_interface_timings(struct omap_dss_device *dssdev,
|
||||
struct rfbi_timings *timings)
|
||||
{
|
||||
rfbi.intf_timings = *timings;
|
||||
}
|
||||
EXPORT_SYMBOL(omapdss_rfbi_set_interface_timings);
|
||||
|
||||
static void rfbi_dump_regs(struct seq_file *s)
|
||||
{
|
||||
#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, rfbi_read_reg(r))
|
||||
@ -869,6 +852,7 @@ static void rfbi_dump_regs(struct seq_file *s)
|
||||
|
||||
static void rfbi_config_lcd_manager(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct omap_overlay_manager *mgr = dssdev->output->manager;
|
||||
struct dss_lcd_mgr_config mgr_config;
|
||||
|
||||
mgr_config.io_pad_mode = DSS_IO_PAD_MODE_RFBI;
|
||||
@ -877,18 +861,40 @@ static void rfbi_config_lcd_manager(struct omap_dss_device *dssdev)
|
||||
/* Do we need fifohandcheck for RFBI? */
|
||||
mgr_config.fifohandcheck = false;
|
||||
|
||||
mgr_config.video_port_width = dssdev->ctrl.pixel_size;
|
||||
mgr_config.video_port_width = rfbi.pixel_size;
|
||||
mgr_config.lcden_sig_polarity = 0;
|
||||
|
||||
dss_mgr_set_lcd_config(dssdev->manager, &mgr_config);
|
||||
dss_mgr_set_lcd_config(mgr, &mgr_config);
|
||||
|
||||
/*
|
||||
* Set rfbi.timings with default values, the x_res and y_res fields
|
||||
* are expected to be already configured by the panel driver via
|
||||
* omapdss_rfbi_set_size()
|
||||
*/
|
||||
rfbi.timings.hsw = 1;
|
||||
rfbi.timings.hfp = 1;
|
||||
rfbi.timings.hbp = 1;
|
||||
rfbi.timings.vsw = 1;
|
||||
rfbi.timings.vfp = 0;
|
||||
rfbi.timings.vbp = 0;
|
||||
|
||||
rfbi.timings.interlace = false;
|
||||
rfbi.timings.hsync_level = OMAPDSS_SIG_ACTIVE_HIGH;
|
||||
rfbi.timings.vsync_level = OMAPDSS_SIG_ACTIVE_HIGH;
|
||||
rfbi.timings.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
|
||||
rfbi.timings.de_level = OMAPDSS_SIG_ACTIVE_HIGH;
|
||||
rfbi.timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES;
|
||||
|
||||
dss_mgr_set_timings(mgr, &rfbi.timings);
|
||||
}
|
||||
|
||||
int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct omap_dss_output *out = dssdev->output;
|
||||
int r;
|
||||
|
||||
if (dssdev->manager == NULL) {
|
||||
DSSERR("failed to enable display: no manager\n");
|
||||
if (out == NULL || out->manager == NULL) {
|
||||
DSSERR("failed to enable display: no output/manager\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
@ -911,13 +917,10 @@ int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
|
||||
|
||||
rfbi_config_lcd_manager(dssdev);
|
||||
|
||||
rfbi_configure(dssdev->phy.rfbi.channel,
|
||||
dssdev->ctrl.pixel_size,
|
||||
dssdev->phy.rfbi.data_lines);
|
||||
|
||||
rfbi_set_timings(dssdev->phy.rfbi.channel,
|
||||
&dssdev->ctrl.rfbi_timings);
|
||||
rfbi_configure(dssdev->phy.rfbi.channel, rfbi.pixel_size,
|
||||
rfbi.data_lines);
|
||||
|
||||
rfbi_set_timings(dssdev->phy.rfbi.channel, &rfbi.intf_timings);
|
||||
|
||||
return 0;
|
||||
err1:
|
||||
@ -941,14 +944,17 @@ EXPORT_SYMBOL(omapdss_rfbi_display_disable);
|
||||
static int __init rfbi_init_display(struct omap_dss_device *dssdev)
|
||||
{
|
||||
rfbi.dssdev[dssdev->phy.rfbi.channel] = dssdev;
|
||||
dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __init rfbi_probe_pdata(struct platform_device *pdev)
|
||||
static struct omap_dss_device * __init rfbi_find_dssdev(struct platform_device *pdev)
|
||||
{
|
||||
struct omap_dss_board_info *pdata = pdev->dev.platform_data;
|
||||
int i, r;
|
||||
const char *def_disp_name = dss_get_default_display_name();
|
||||
struct omap_dss_device *def_dssdev;
|
||||
int i;
|
||||
|
||||
def_dssdev = NULL;
|
||||
|
||||
for (i = 0; i < pdata->num_devices; ++i) {
|
||||
struct omap_dss_device *dssdev = pdata->devices[i];
|
||||
@ -956,17 +962,67 @@ static void __init rfbi_probe_pdata(struct platform_device *pdev)
|
||||
if (dssdev->type != OMAP_DISPLAY_TYPE_DBI)
|
||||
continue;
|
||||
|
||||
r = rfbi_init_display(dssdev);
|
||||
if (r) {
|
||||
DSSERR("device %s init failed: %d\n", dssdev->name, r);
|
||||
continue;
|
||||
}
|
||||
if (def_dssdev == NULL)
|
||||
def_dssdev = dssdev;
|
||||
|
||||
r = omap_dss_register_device(dssdev, &pdev->dev, i);
|
||||
if (r)
|
||||
DSSERR("device %s register failed: %d\n",
|
||||
dssdev->name, r);
|
||||
if (def_disp_name != NULL &&
|
||||
strcmp(dssdev->name, def_disp_name) == 0) {
|
||||
def_dssdev = dssdev;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return def_dssdev;
|
||||
}
|
||||
|
||||
static void __init rfbi_probe_pdata(struct platform_device *rfbidev)
|
||||
{
|
||||
struct omap_dss_device *plat_dssdev;
|
||||
struct omap_dss_device *dssdev;
|
||||
int r;
|
||||
|
||||
plat_dssdev = rfbi_find_dssdev(rfbidev);
|
||||
|
||||
if (!plat_dssdev)
|
||||
return;
|
||||
|
||||
dssdev = dss_alloc_and_init_device(&rfbidev->dev);
|
||||
if (!dssdev)
|
||||
return;
|
||||
|
||||
dss_copy_device_pdata(dssdev, plat_dssdev);
|
||||
|
||||
r = rfbi_init_display(dssdev);
|
||||
if (r) {
|
||||
DSSERR("device %s init failed: %d\n", dssdev->name, r);
|
||||
dss_put_device(dssdev);
|
||||
return;
|
||||
}
|
||||
|
||||
r = dss_add_device(dssdev);
|
||||
if (r) {
|
||||
DSSERR("device %s register failed: %d\n", dssdev->name, r);
|
||||
dss_put_device(dssdev);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void __init rfbi_init_output(struct platform_device *pdev)
|
||||
{
|
||||
struct omap_dss_output *out = &rfbi.output;
|
||||
|
||||
out->pdev = pdev;
|
||||
out->id = OMAP_DSS_OUTPUT_DBI;
|
||||
out->type = OMAP_DISPLAY_TYPE_DBI;
|
||||
|
||||
dss_register_output(out);
|
||||
}
|
||||
|
||||
static void __exit rfbi_uninit_output(struct platform_device *pdev)
|
||||
{
|
||||
struct omap_dss_output *out = &rfbi.output;
|
||||
|
||||
dss_unregister_output(out);
|
||||
}
|
||||
|
||||
/* RFBI HW IP initialisation */
|
||||
@ -1020,6 +1076,8 @@ static int __init omap_rfbihw_probe(struct platform_device *pdev)
|
||||
|
||||
dss_debugfs_create_file("rfbi", rfbi_dump_regs);
|
||||
|
||||
rfbi_init_output(pdev);
|
||||
|
||||
rfbi_probe_pdata(pdev);
|
||||
|
||||
return 0;
|
||||
@ -1031,8 +1089,12 @@ err_runtime_get:
|
||||
|
||||
static int __exit omap_rfbihw_remove(struct platform_device *pdev)
|
||||
{
|
||||
omap_dss_unregister_child_devices(&pdev->dev);
|
||||
dss_unregister_child_devices(&pdev->dev);
|
||||
|
||||
rfbi_uninit_output(pdev);
|
||||
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user