提交 5f76945a 编写于 作者: L Linus Torvalds

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
  ...
......@@ -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>
......
/* 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];
/* get the display device attached to the overlay */
dssdev = ovl->get_device(ovl);
if (!ovl->manager || !ovl->manager->device)
if (!dssdev)
return -EINVAL;
/* get the display device attached to the overlay */
timing = &ovl->manager->device->panel.timings;
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 @@ static int __init omap_vout_probe(struct platform_device *pdev)
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 @@ static int __devinit bfin_lq035_probe(struct platform_device *pdev)
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 @@ static int __devinit bfin_bf54x_probe(struct platform_device *pdev)
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 (regno == 0)
pal |= 0x2000;
palette[regno] = pal;
} else if (info->var.bits_per_pixel == 8) {
red >>= 4;
green >>= 8;
blue >>= 12;
pal = (red & 0x0f00);
pal |= (green & 0x00f0);
pal |= (blue & 0x000f);
if (palette[regno] != pal) {
update_hw = 1;
palette[regno] = pal;
if (palette[regno] != pal) {
update_hw = 1;
palette[regno] = pal;
}
break;
}
} else if ((info->var.bits_per_pixel == 16) && regno < 16) {
red >>= (16 - info->var.red.length);
red <<= info->var.red.offset;
break;
}
green >>= (16 - info->var.green.length);
green <<= info->var.green.offset;
/* Truecolor has hardware independent palette */
if (info->fix.visual == FB_VISUAL_TRUECOLOR) {
u32 v;
blue >>= (16 - info->var.blue.length);
blue <<= info->var.blue.offset;
if (regno > 15)
return -EINVAL;
par->pseudo_palette[regno] = red | green | blue;
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;
}
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 @@ static int __devinit fb_probe(struct platform_device *device)
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 @@ static int __devinit fb_probe(struct platform_device *device)
}
#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];
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);
exynos_dp_get_adjust_train(dp, adjust_request);
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;
buf[0] = DPCD_SCRAMBLING_DISABLED |
DPCD_TRAINING_PATTERN_2;
exynos_dp_write_byte_to_dpcd(dp,
DPCD_ADDR_TRAINING_PATTERN_SET,
buf[0]);
dp->link_train.training_lane[lane] = training_lane;
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;
exynos_dp_write_byte_to_dpcd(dp,
DPCD_ADDR_TRAINING_PATTERN_SET,
DPCD_SCRAMBLING_DISABLED |
DPCD_TRAINING_PATTERN_2);
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 ((DPCD_VOLTAGE_SWING_GET(training_lane) == voltage_swing) &&
(DPCD_PRE_EMPHASIS_GET(training_lane) == pre_emphasis))
dp->link_train.cr_loop[lane]++;
dp->link_train.training_lane[lane] = training_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);
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;
}
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]);
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;
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) {
adjust_request[0] = link_status[4];
adjust_request[1] = link_status[5];
link_align[0] = link_status[0];
link_align[1] = link_status[1];
if (exynos_dp_channel_eq_ok(link_status, lane_count) == 0) {
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 @@ static int __devinit fsl_diu_probe(struct platform_device *pdev)
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 @@ static int __devinit jzfb_probe(struct platform_device *pdev)
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 @@ static int taal_enter_ulps(struct omap_dss_device *dssdev)
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 @@ static int taal_exit_ulps(struct omap_dss_device *dssdev)
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);
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;
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;
}
}
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(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 (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;
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");
return -ENOMEM;
}
INIT_DEFERRABLE_WORK(&td->esd_work, taal_esd_work);
INIT_DELAYED_WORK(&td->ulps_work, taal_ulps_work);
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.
......
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)
spin_lock_irqsave(&data_lock, flags);
if (mgr_manual_update(mgr)) {
spin_unlock_irqrestore(&data_lock, flags);
return 0;
}
if (mgr_manual_update(mgr))
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);
spin_lock_irqsave(&data_lock, flags);
if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
if (ovl_manual_update(ovl)) {
spin_unlock_irqrestore(&data_lock, flags);
return 0;
}
if (ovl_manual_update(ovl))
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,94 +990,19 @@ 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);
}
static void dss_setup_fifos(bool use_fifo_merge)
{
const int num_mgrs = omap_dss_get_num_overlay_managers();
struct omap_overlay_manager *mgr;
int i;
for (i = 0; i < num_mgrs; ++i) {
mgr = omap_dss_get_overlay_manager(i);
dss_mgr_setup_fifos(mgr, use_fifo_merge);
}
dss_ovl_setup_fifo(ovl);
}
static int get_num_used_managers(void)
static void dss_setup_fifos(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++;
dss_mgr_setup_fifos(mgr);
}
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)
......@@ -1115,7 +1010,6 @@ 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 @@ int dss_mgr_set_device(struct omap_overlay_manager *mgr,
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);
dss_apply_mgr_timings(mgr, timings);
dss_write_regs();
dss_set_go_bits();
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);
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)
static int disp_num_counter;
struct omap_dss_device *dss_alloc_and_init_device(struct device *parent)
{
WARN_ON(!dssdev->driver_name);
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;
}
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 omap_dss_unregister_device(struct omap_dss_device *dssdev)
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)
{
......
此差异已折叠。
......@@ -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)
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
......@@ -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);
......
......@@ -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,
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册