mirror of https://gitee.com/openkylin/linux.git
Merge branch 'for-paul' of git://gitorious.org/linux-omap-dss2/linux
Conflicts: drivers/video/omap2/dss/dsi.c drivers/video/omap2/dss/dss_features.c drivers/video/omap2/dss/dss_features.h Signed-off-by: Paul Mundt <lethal@linux-sh.org>
This commit is contained in:
commit
a6b5825aa7
|
@ -37,8 +37,8 @@
|
|||
#include <plat/common.h>
|
||||
#include <plat/dma.h>
|
||||
#include <plat/gpmc.h>
|
||||
#include <plat/display.h>
|
||||
#include <plat/panel-generic-dpi.h>
|
||||
#include <video/omapdss.h>
|
||||
#include <video/omap-panel-generic-dpi.h>
|
||||
|
||||
#include <plat/gpmc-smc91x.h>
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
#include <plat/usb.h>
|
||||
#include <plat/mmc.h>
|
||||
#include <plat/omap4-keypad.h>
|
||||
#include <plat/display.h>
|
||||
#include <video/omapdss.h>
|
||||
|
||||
#include "mux.h"
|
||||
#include "hsmmc.h"
|
||||
|
@ -680,6 +680,15 @@ static struct omap_dss_device sdp4430_hdmi_device = {
|
|||
.name = "hdmi",
|
||||
.driver_name = "hdmi_panel",
|
||||
.type = OMAP_DISPLAY_TYPE_HDMI,
|
||||
.clocks = {
|
||||
.dispc = {
|
||||
.dispc_fclk_src = OMAP_DSS_CLK_SRC_FCK,
|
||||
},
|
||||
.hdmi = {
|
||||
.regn = 15,
|
||||
.regm2 = 1,
|
||||
},
|
||||
},
|
||||
.platform_enable = sdp4430_panel_enable_hdmi,
|
||||
.platform_disable = sdp4430_panel_disable_hdmi,
|
||||
.channel = OMAP_DSS_CHANNEL_DIGIT,
|
||||
|
|
|
@ -34,8 +34,8 @@
|
|||
#include <plat/board.h>
|
||||
#include <plat/common.h>
|
||||
#include <plat/usb.h>
|
||||
#include <plat/display.h>
|
||||
#include <plat/panel-generic-dpi.h>
|
||||
#include <video/omapdss.h>
|
||||
#include <video/omap-panel-generic-dpi.h>
|
||||
|
||||
#include "mux.h"
|
||||
#include "control.h"
|
||||
|
|
|
@ -45,8 +45,8 @@
|
|||
#include <plat/nand.h>
|
||||
#include <plat/gpmc.h>
|
||||
#include <plat/usb.h>
|
||||
#include <plat/display.h>
|
||||
#include <plat/panel-generic-dpi.h>
|
||||
#include <video/omapdss.h>
|
||||
#include <video/omap-panel-generic-dpi.h>
|
||||
#include <plat/mcspi.h>
|
||||
|
||||
#include <mach/hardware.h>
|
||||
|
|
|
@ -45,8 +45,8 @@
|
|||
#include <plat/gpmc.h>
|
||||
#include <plat/nand.h>
|
||||
#include <plat/usb.h>
|
||||
#include <plat/display.h>
|
||||
#include <plat/panel-generic-dpi.h>
|
||||
#include <video/omapdss.h>
|
||||
#include <video/omap-panel-generic-dpi.h>
|
||||
|
||||
#include <plat/mcspi.h>
|
||||
#include <linux/input/matrix_keypad.h>
|
||||
|
|
|
@ -31,8 +31,8 @@
|
|||
#include <plat/common.h>
|
||||
#include <plat/gpmc.h>
|
||||
#include <plat/usb.h>
|
||||
#include <plat/display.h>
|
||||
#include <plat/panel-generic-dpi.h>
|
||||
#include <video/omapdss.h>
|
||||
#include <video/omap-panel-generic-dpi.h>
|
||||
#include <plat/onenand.h>
|
||||
|
||||
#include "mux.h"
|
||||
|
|
|
@ -41,8 +41,8 @@
|
|||
|
||||
#include <plat/board.h>
|
||||
#include <plat/common.h>
|
||||
#include <plat/display.h>
|
||||
#include <plat/panel-generic-dpi.h>
|
||||
#include <video/omapdss.h>
|
||||
#include <video/omap-panel-generic-dpi.h>
|
||||
#include <plat/gpmc.h>
|
||||
#include <plat/nand.h>
|
||||
#include <plat/usb.h>
|
||||
|
|
|
@ -44,8 +44,8 @@
|
|||
#include <plat/usb.h>
|
||||
#include <plat/common.h>
|
||||
#include <plat/mcspi.h>
|
||||
#include <plat/display.h>
|
||||
#include <plat/panel-generic-dpi.h>
|
||||
#include <video/omapdss.h>
|
||||
#include <video/omap-panel-generic-dpi.h>
|
||||
|
||||
#include "mux.h"
|
||||
#include "sdram-micron-mt46h32m32lf-6.h"
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
#include <mach/hardware.h>
|
||||
#include <plat/mcspi.h>
|
||||
#include <plat/usb.h>
|
||||
#include <plat/display.h>
|
||||
#include <video/omapdss.h>
|
||||
#include <plat/nand.h>
|
||||
|
||||
#include "mux.h"
|
||||
|
|
|
@ -39,8 +39,8 @@
|
|||
#include <plat/gpmc.h>
|
||||
#include <plat/nand.h>
|
||||
#include <plat/usb.h>
|
||||
#include <plat/display.h>
|
||||
#include <plat/panel-generic-dpi.h>
|
||||
#include <video/omapdss.h>
|
||||
#include <video/omap-panel-generic-dpi.h>
|
||||
|
||||
#include <plat/mcspi.h>
|
||||
#include <linux/input/matrix_keypad.h>
|
||||
|
|
|
@ -34,13 +34,13 @@
|
|||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/map.h>
|
||||
#include <plat/display.h>
|
||||
#include <video/omapdss.h>
|
||||
|
||||
#include <plat/board.h>
|
||||
#include <plat/common.h>
|
||||
#include <plat/usb.h>
|
||||
#include <plat/mmc.h>
|
||||
#include <plat/panel-generic-dpi.h>
|
||||
#include <video/omap-panel-generic-dpi.h>
|
||||
#include "timer-gp.h"
|
||||
|
||||
#include "hsmmc.h"
|
||||
|
|
|
@ -43,8 +43,8 @@
|
|||
|
||||
#include <plat/board.h>
|
||||
#include <plat/common.h>
|
||||
#include <plat/display.h>
|
||||
#include <plat/panel-generic-dpi.h>
|
||||
#include <video/omapdss.h>
|
||||
#include <video/omap-panel-generic-dpi.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <plat/gpmc.h>
|
||||
#include <mach/hardware.h>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#include <linux/spi/spi.h>
|
||||
#include <linux/mm.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <plat/display.h>
|
||||
#include <video/omapdss.h>
|
||||
#include <plat/vram.h>
|
||||
#include <plat/mcspi.h>
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#include <linux/i2c/twl.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <plat/mcspi.h>
|
||||
#include <plat/display.h>
|
||||
#include <video/omapdss.h>
|
||||
|
||||
#define LCD_PANEL_RESET_GPIO_PROD 96
|
||||
#define LCD_PANEL_RESET_GPIO_PILOT 55
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include <linux/clk.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
#include <plat/display.h>
|
||||
#include <video/omapdss.h>
|
||||
#include <plat/omap_hwmod.h>
|
||||
#include <plat/omap_device.h>
|
||||
|
||||
|
@ -56,37 +56,58 @@ static bool opt_clock_available(const char *clk_role)
|
|||
return false;
|
||||
}
|
||||
|
||||
struct omap_dss_hwmod_data {
|
||||
const char *oh_name;
|
||||
const char *dev_name;
|
||||
const int id;
|
||||
};
|
||||
|
||||
static const struct omap_dss_hwmod_data omap2_dss_hwmod_data[] __initdata = {
|
||||
{ "dss_core", "omapdss_dss", -1 },
|
||||
{ "dss_dispc", "omapdss_dispc", -1 },
|
||||
{ "dss_rfbi", "omapdss_rfbi", -1 },
|
||||
{ "dss_venc", "omapdss_venc", -1 },
|
||||
};
|
||||
|
||||
static const struct omap_dss_hwmod_data omap3_dss_hwmod_data[] __initdata = {
|
||||
{ "dss_core", "omapdss_dss", -1 },
|
||||
{ "dss_dispc", "omapdss_dispc", -1 },
|
||||
{ "dss_rfbi", "omapdss_rfbi", -1 },
|
||||
{ "dss_venc", "omapdss_venc", -1 },
|
||||
{ "dss_dsi1", "omapdss_dsi1", -1 },
|
||||
};
|
||||
|
||||
static const struct omap_dss_hwmod_data omap4_dss_hwmod_data[] __initdata = {
|
||||
{ "dss_core", "omapdss_dss", -1 },
|
||||
{ "dss_dispc", "omapdss_dispc", -1 },
|
||||
{ "dss_rfbi", "omapdss_rfbi", -1 },
|
||||
{ "dss_venc", "omapdss_venc", -1 },
|
||||
{ "dss_dsi1", "omapdss_dsi1", -1 },
|
||||
{ "dss_dsi2", "omapdss_dsi2", -1 },
|
||||
{ "dss_hdmi", "omapdss_hdmi", -1 },
|
||||
};
|
||||
|
||||
int __init omap_display_init(struct omap_dss_board_info *board_data)
|
||||
{
|
||||
int r = 0;
|
||||
struct omap_hwmod *oh;
|
||||
struct omap_device *od;
|
||||
int i;
|
||||
int i, oh_count;
|
||||
struct omap_display_platform_data pdata;
|
||||
|
||||
/*
|
||||
* omap: valid DSS hwmod names
|
||||
* omap2,3,4: dss_core, dss_dispc, dss_rfbi, dss_venc
|
||||
* omap3,4: dss_dsi1
|
||||
* omap4: dss_dsi2, dss_hdmi
|
||||
*/
|
||||
char *oh_name[] = { "dss_core", "dss_dispc", "dss_rfbi", "dss_venc",
|
||||
"dss_dsi1", "dss_dsi2", "dss_hdmi" };
|
||||
char *dev_name[] = { "omapdss_dss", "omapdss_dispc", "omapdss_rfbi",
|
||||
"omapdss_venc", "omapdss_dsi1", "omapdss_dsi2",
|
||||
"omapdss_hdmi" };
|
||||
int oh_count;
|
||||
const struct omap_dss_hwmod_data *curr_dss_hwmod;
|
||||
|
||||
memset(&pdata, 0, sizeof(pdata));
|
||||
|
||||
if (cpu_is_omap24xx())
|
||||
oh_count = ARRAY_SIZE(oh_name) - 3;
|
||||
/* last 3 hwmod dev in oh_name are not available for omap2 */
|
||||
else if (cpu_is_omap44xx())
|
||||
oh_count = ARRAY_SIZE(oh_name);
|
||||
else
|
||||
oh_count = ARRAY_SIZE(oh_name) - 2;
|
||||
/* last 2 hwmod dev in oh_name are not available for omap3 */
|
||||
if (cpu_is_omap24xx()) {
|
||||
curr_dss_hwmod = omap2_dss_hwmod_data;
|
||||
oh_count = ARRAY_SIZE(omap2_dss_hwmod_data);
|
||||
} else if (cpu_is_omap34xx()) {
|
||||
curr_dss_hwmod = omap3_dss_hwmod_data;
|
||||
oh_count = ARRAY_SIZE(omap3_dss_hwmod_data);
|
||||
} else {
|
||||
curr_dss_hwmod = omap4_dss_hwmod_data;
|
||||
oh_count = ARRAY_SIZE(omap4_dss_hwmod_data);
|
||||
}
|
||||
|
||||
/* opt_clks are always associated with dss hwmod */
|
||||
oh_core = omap_hwmod_lookup("dss_core");
|
||||
|
@ -100,19 +121,21 @@ int __init omap_display_init(struct omap_dss_board_info *board_data)
|
|||
pdata.opt_clock_available = opt_clock_available;
|
||||
|
||||
for (i = 0; i < oh_count; i++) {
|
||||
oh = omap_hwmod_lookup(oh_name[i]);
|
||||
oh = omap_hwmod_lookup(curr_dss_hwmod[i].oh_name);
|
||||
if (!oh) {
|
||||
pr_err("Could not look up %s\n", oh_name[i]);
|
||||
pr_err("Could not look up %s\n",
|
||||
curr_dss_hwmod[i].oh_name);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
od = omap_device_build(dev_name[i], -1, oh, &pdata,
|
||||
od = omap_device_build(curr_dss_hwmod[i].dev_name,
|
||||
curr_dss_hwmod[i].id, oh, &pdata,
|
||||
sizeof(struct omap_display_platform_data),
|
||||
omap_dss_latency,
|
||||
ARRAY_SIZE(omap_dss_latency), 0);
|
||||
|
||||
if (WARN((IS_ERR(od)), "Could not build omap_device for %s\n",
|
||||
oh_name[i]))
|
||||
curr_dss_hwmod[i].oh_name))
|
||||
return -ENODEV;
|
||||
}
|
||||
omap_display_device.dev.platform_data = board_data;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Defines for zoom boards
|
||||
*/
|
||||
#include <plat/display.h>
|
||||
#include <video/omapdss.h>
|
||||
|
||||
#define ZOOM_NAND_CS 0
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
#include <plat/dma.h>
|
||||
#include <plat/vram.h>
|
||||
#include <plat/vrfb.h>
|
||||
#include <plat/display.h>
|
||||
#include <video/omapdss.h>
|
||||
|
||||
#include "omap_voutlib.h"
|
||||
#include "omap_voutdef.h"
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#ifndef OMAP_VOUTDEF_H
|
||||
#define OMAP_VOUTDEF_H
|
||||
|
||||
#include <plat/display.h>
|
||||
#include <video/omapdss.h>
|
||||
|
||||
#define YUYV_BPP 2
|
||||
#define RGB565_BPP 2
|
||||
|
|
|
@ -922,14 +922,14 @@ static int get_dss_clocks(void)
|
|||
return PTR_ERR(dispc.dss_ick);
|
||||
}
|
||||
|
||||
dispc.dss1_fck = clk_get(&dispc.fbdev->dssdev->dev, "dss1_fck");
|
||||
dispc.dss1_fck = clk_get(&dispc.fbdev->dssdev->dev, "fck");
|
||||
if (IS_ERR(dispc.dss1_fck)) {
|
||||
dev_err(dispc.fbdev->dev, "can't get dss1_fck\n");
|
||||
clk_put(dispc.dss_ick);
|
||||
return PTR_ERR(dispc.dss1_fck);
|
||||
}
|
||||
|
||||
dispc.dss_54m_fck = clk_get(&dispc.fbdev->dssdev->dev, "tv_fck");
|
||||
dispc.dss_54m_fck = clk_get(&dispc.fbdev->dssdev->dev, "tv_clk");
|
||||
if (IS_ERR(dispc.dss_54m_fck)) {
|
||||
dev_err(dispc.fbdev->dev, "can't get tv_fck\n");
|
||||
clk_put(dispc.dss_ick);
|
||||
|
|
|
@ -90,7 +90,7 @@ static void omapdss_release(struct device *dev)
|
|||
|
||||
/* dummy device for clocks */
|
||||
static struct platform_device omapdss_device = {
|
||||
.name = "omapdss",
|
||||
.name = "omapdss_dss",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.release = omapdss_release,
|
||||
|
|
|
@ -90,7 +90,7 @@ static int rfbi_get_clocks(void)
|
|||
return PTR_ERR(rfbi.dss_ick);
|
||||
}
|
||||
|
||||
rfbi.dss1_fck = clk_get(&rfbi.fbdev->dssdev->dev, "dss1_fck");
|
||||
rfbi.dss1_fck = clk_get(&rfbi.fbdev->dssdev->dev, "fck");
|
||||
if (IS_ERR(rfbi.dss1_fck)) {
|
||||
dev_err(rfbi.fbdev->dev, "can't get dss1_fck\n");
|
||||
clk_put(rfbi.dss_ick);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
obj-$(CONFIG_OMAP2_VRAM) += vram.o
|
||||
obj-$(CONFIG_OMAP2_VRFB) += vrfb.o
|
||||
|
||||
obj-y += dss/
|
||||
obj-y += omapfb/
|
||||
obj-$(CONFIG_OMAP2_DSS) += dss/
|
||||
obj-$(CONFIG_FB_OMAP2) += omapfb/
|
||||
obj-y += displays/
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
#include <linux/backlight.h>
|
||||
#include <linux/fb.h>
|
||||
|
||||
#include <plat/display.h>
|
||||
#include <video/omapdss.h>
|
||||
|
||||
#define MIPID_CMD_READ_DISP_ID 0x04
|
||||
#define MIPID_CMD_READ_RED 0x06
|
||||
|
|
|
@ -33,8 +33,9 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/slab.h>
|
||||
#include <video/omapdss.h>
|
||||
|
||||
#include <plat/panel-generic-dpi.h>
|
||||
#include <video/omap-panel-generic-dpi.h>
|
||||
|
||||
struct panel_config {
|
||||
struct omap_video_timings timings;
|
||||
|
@ -181,6 +182,56 @@ static struct panel_config generic_dpi_panels[] = {
|
|||
.power_off_delay = 0,
|
||||
.name = "samsung_lte430wq_f0c",
|
||||
},
|
||||
|
||||
/* Seiko 70WVW1TZ3Z3 */
|
||||
{
|
||||
{
|
||||
.x_res = 800,
|
||||
.y_res = 480,
|
||||
|
||||
.pixel_clock = 33000,
|
||||
|
||||
.hsw = 128,
|
||||
.hfp = 10,
|
||||
.hbp = 10,
|
||||
|
||||
.vsw = 2,
|
||||
.vfp = 4,
|
||||
.vbp = 11,
|
||||
},
|
||||
.acbi = 0x0,
|
||||
.acb = 0x0,
|
||||
.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
|
||||
OMAP_DSS_LCD_IHS,
|
||||
.power_on_delay = 0,
|
||||
.power_off_delay = 0,
|
||||
.name = "seiko_70wvw1tz3",
|
||||
},
|
||||
|
||||
/* Powertip PH480272T */
|
||||
{
|
||||
{
|
||||
.x_res = 480,
|
||||
.y_res = 272,
|
||||
|
||||
.pixel_clock = 9000,
|
||||
|
||||
.hsw = 40,
|
||||
.hfp = 2,
|
||||
.hbp = 2,
|
||||
|
||||
.vsw = 10,
|
||||
.vfp = 2,
|
||||
.vbp = 2,
|
||||
},
|
||||
.acbi = 0x0,
|
||||
.acb = 0x0,
|
||||
.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
|
||||
OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IEO,
|
||||
.power_on_delay = 0,
|
||||
.power_off_delay = 0,
|
||||
.name = "powertip_ph480272t",
|
||||
},
|
||||
};
|
||||
|
||||
struct panel_drv_data {
|
||||
|
@ -285,7 +336,7 @@ static int generic_dpi_panel_probe(struct omap_dss_device *dssdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void generic_dpi_panel_remove(struct omap_dss_device *dssdev)
|
||||
static void __exit generic_dpi_panel_remove(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
|
||||
|
||||
|
@ -358,7 +409,7 @@ static int generic_dpi_panel_check_timings(struct omap_dss_device *dssdev,
|
|||
|
||||
static struct omap_dss_driver dpi_driver = {
|
||||
.probe = generic_dpi_panel_probe,
|
||||
.remove = generic_dpi_panel_remove,
|
||||
.remove = __exit_p(generic_dpi_panel_remove),
|
||||
|
||||
.enable = generic_dpi_panel_enable,
|
||||
.disable = generic_dpi_panel_disable,
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include <linux/spi/spi.h>
|
||||
#include <linux/mutex.h>
|
||||
|
||||
#include <plat/display.h>
|
||||
#include <video/omapdss.h>
|
||||
|
||||
struct lb035q02_data {
|
||||
struct mutex lock;
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include <linux/backlight.h>
|
||||
#include <linux/fb.h>
|
||||
|
||||
#include <plat/display.h>
|
||||
#include <video/omapdss.h>
|
||||
|
||||
#define LCD_XRES 800
|
||||
#define LCD_YRES 480
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include <linux/err.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <plat/display.h>
|
||||
#include <video/omapdss.h>
|
||||
|
||||
struct sharp_data {
|
||||
struct backlight_device *bl;
|
||||
|
@ -120,7 +120,7 @@ static int sharp_ls_panel_probe(struct omap_dss_device *dssdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void sharp_ls_panel_remove(struct omap_dss_device *dssdev)
|
||||
static void __exit sharp_ls_panel_remove(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct sharp_data *sd = dev_get_drvdata(&dssdev->dev);
|
||||
struct backlight_device *bl = sd->bl;
|
||||
|
@ -205,7 +205,7 @@ static int sharp_ls_panel_resume(struct omap_dss_device *dssdev)
|
|||
|
||||
static struct omap_dss_driver sharp_ls_driver = {
|
||||
.probe = sharp_ls_panel_probe,
|
||||
.remove = sharp_ls_panel_remove,
|
||||
.remove = __exit_p(sharp_ls_panel_remove),
|
||||
|
||||
.enable = sharp_ls_panel_enable,
|
||||
.disable = sharp_ls_panel_disable,
|
||||
|
|
|
@ -33,8 +33,8 @@
|
|||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/mutex.h>
|
||||
|
||||
#include <plat/display.h>
|
||||
#include <plat/nokia-dsi-panel.h>
|
||||
#include <video/omapdss.h>
|
||||
#include <video/omap-panel-nokia-dsi.h>
|
||||
|
||||
/* DSI Virtual channel. Hardcoded for now. */
|
||||
#define TCH 0
|
||||
|
@ -63,12 +63,12 @@
|
|||
#define DCS_GET_ID2 0xdb
|
||||
#define DCS_GET_ID3 0xdc
|
||||
|
||||
#define TAAL_ESD_CHECK_PERIOD msecs_to_jiffies(5000)
|
||||
|
||||
static irqreturn_t taal_te_isr(int irq, void *data);
|
||||
static void taal_te_timeout_work_callback(struct work_struct *work);
|
||||
static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable);
|
||||
|
||||
static int taal_panel_reset(struct omap_dss_device *dssdev);
|
||||
|
||||
struct panel_regulator {
|
||||
struct regulator *regulator;
|
||||
const char *name;
|
||||
|
@ -229,8 +229,14 @@ struct taal_data {
|
|||
|
||||
bool intro_printed;
|
||||
|
||||
struct workqueue_struct *esd_wq;
|
||||
struct workqueue_struct *workqueue;
|
||||
|
||||
struct delayed_work esd_work;
|
||||
unsigned esd_interval;
|
||||
|
||||
bool ulps_enabled;
|
||||
unsigned ulps_timeout;
|
||||
struct delayed_work ulps_work;
|
||||
|
||||
struct panel_config *panel_config;
|
||||
};
|
||||
|
@ -242,6 +248,7 @@ static inline struct nokia_dsi_panel_data
|
|||
}
|
||||
|
||||
static void taal_esd_work(struct work_struct *work);
|
||||
static void taal_ulps_work(struct work_struct *work);
|
||||
|
||||
static void hw_guard_start(struct taal_data *td, int guard_msec)
|
||||
{
|
||||
|
@ -264,7 +271,7 @@ static int taal_dcs_read_1(struct taal_data *td, u8 dcs_cmd, u8 *data)
|
|||
int r;
|
||||
u8 buf[1];
|
||||
|
||||
r = dsi_vc_dcs_read(td->channel, dcs_cmd, buf, 1);
|
||||
r = dsi_vc_dcs_read(td->dssdev, td->channel, dcs_cmd, buf, 1);
|
||||
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
@ -276,7 +283,7 @@ static int taal_dcs_read_1(struct taal_data *td, u8 dcs_cmd, u8 *data)
|
|||
|
||||
static int taal_dcs_write_0(struct taal_data *td, u8 dcs_cmd)
|
||||
{
|
||||
return dsi_vc_dcs_write(td->channel, &dcs_cmd, 1);
|
||||
return dsi_vc_dcs_write(td->dssdev, td->channel, &dcs_cmd, 1);
|
||||
}
|
||||
|
||||
static int taal_dcs_write_1(struct taal_data *td, u8 dcs_cmd, u8 param)
|
||||
|
@ -284,7 +291,7 @@ static int taal_dcs_write_1(struct taal_data *td, u8 dcs_cmd, u8 param)
|
|||
u8 buf[2];
|
||||
buf[0] = dcs_cmd;
|
||||
buf[1] = param;
|
||||
return dsi_vc_dcs_write(td->channel, buf, 2);
|
||||
return dsi_vc_dcs_write(td->dssdev, td->channel, buf, 2);
|
||||
}
|
||||
|
||||
static int taal_sleep_in(struct taal_data *td)
|
||||
|
@ -296,7 +303,7 @@ static int taal_sleep_in(struct taal_data *td)
|
|||
hw_guard_wait(td);
|
||||
|
||||
cmd = DCS_SLEEP_IN;
|
||||
r = dsi_vc_dcs_write_nosync(td->channel, &cmd, 1);
|
||||
r = dsi_vc_dcs_write_nosync(td->dssdev, td->channel, &cmd, 1);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
@ -402,7 +409,7 @@ static int taal_set_update_window(struct taal_data *td,
|
|||
buf[3] = (x2 >> 8) & 0xff;
|
||||
buf[4] = (x2 >> 0) & 0xff;
|
||||
|
||||
r = dsi_vc_dcs_write_nosync(td->channel, buf, sizeof(buf));
|
||||
r = dsi_vc_dcs_write_nosync(td->dssdev, td->channel, buf, sizeof(buf));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
@ -412,15 +419,132 @@ static int taal_set_update_window(struct taal_data *td,
|
|||
buf[3] = (y2 >> 8) & 0xff;
|
||||
buf[4] = (y2 >> 0) & 0xff;
|
||||
|
||||
r = dsi_vc_dcs_write_nosync(td->channel, buf, sizeof(buf));
|
||||
r = dsi_vc_dcs_write_nosync(td->dssdev, td->channel, buf, sizeof(buf));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
dsi_vc_send_bta_sync(td->channel);
|
||||
dsi_vc_send_bta_sync(td->dssdev, td->channel);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static void taal_queue_esd_work(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct taal_data *td = dev_get_drvdata(&dssdev->dev);
|
||||
|
||||
if (td->esd_interval > 0)
|
||||
queue_delayed_work(td->workqueue, &td->esd_work,
|
||||
msecs_to_jiffies(td->esd_interval));
|
||||
}
|
||||
|
||||
static void taal_cancel_esd_work(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct taal_data *td = dev_get_drvdata(&dssdev->dev);
|
||||
|
||||
cancel_delayed_work(&td->esd_work);
|
||||
}
|
||||
|
||||
static void taal_queue_ulps_work(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct taal_data *td = dev_get_drvdata(&dssdev->dev);
|
||||
|
||||
if (td->ulps_timeout > 0)
|
||||
queue_delayed_work(td->workqueue, &td->ulps_work,
|
||||
msecs_to_jiffies(td->ulps_timeout));
|
||||
}
|
||||
|
||||
static void taal_cancel_ulps_work(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct taal_data *td = dev_get_drvdata(&dssdev->dev);
|
||||
|
||||
cancel_delayed_work(&td->ulps_work);
|
||||
}
|
||||
|
||||
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)
|
||||
return 0;
|
||||
|
||||
taal_cancel_ulps_work(dssdev);
|
||||
|
||||
r = _taal_enable_te(dssdev, false);
|
||||
if (r)
|
||||
goto err;
|
||||
|
||||
disable_irq(gpio_to_irq(panel_data->ext_te_gpio));
|
||||
|
||||
omapdss_dsi_display_disable(dssdev, false, true);
|
||||
|
||||
td->ulps_enabled = true;
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
dev_err(&dssdev->dev, "enter ULPS failed");
|
||||
taal_panel_reset(dssdev);
|
||||
|
||||
td->ulps_enabled = false;
|
||||
|
||||
taal_queue_ulps_work(dssdev);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
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)
|
||||
return 0;
|
||||
|
||||
r = omapdss_dsi_display_enable(dssdev);
|
||||
if (r)
|
||||
goto err;
|
||||
|
||||
omapdss_dsi_vc_enable_hs(dssdev, td->channel, true);
|
||||
|
||||
r = _taal_enable_te(dssdev, true);
|
||||
if (r)
|
||||
goto err;
|
||||
|
||||
enable_irq(gpio_to_irq(panel_data->ext_te_gpio));
|
||||
|
||||
taal_queue_ulps_work(dssdev);
|
||||
|
||||
td->ulps_enabled = false;
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
dev_err(&dssdev->dev, "exit ULPS failed");
|
||||
r = taal_panel_reset(dssdev);
|
||||
|
||||
enable_irq(gpio_to_irq(panel_data->ext_te_gpio));
|
||||
td->ulps_enabled = false;
|
||||
|
||||
taal_queue_ulps_work(dssdev);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int taal_wake_up(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct taal_data *td = dev_get_drvdata(&dssdev->dev);
|
||||
|
||||
if (td->ulps_enabled)
|
||||
return taal_exit_ulps(dssdev);
|
||||
|
||||
taal_cancel_ulps_work(dssdev);
|
||||
taal_queue_ulps_work(dssdev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int taal_bl_update_status(struct backlight_device *dev)
|
||||
{
|
||||
struct omap_dss_device *dssdev = dev_get_drvdata(&dev->dev);
|
||||
|
@ -441,9 +565,13 @@ static int taal_bl_update_status(struct backlight_device *dev)
|
|||
|
||||
if (td->use_dsi_bl) {
|
||||
if (td->enabled) {
|
||||
dsi_bus_lock();
|
||||
r = taal_dcs_write_1(td, DCS_BRIGHTNESS, level);
|
||||
dsi_bus_unlock();
|
||||
dsi_bus_lock(dssdev);
|
||||
|
||||
r = taal_wake_up(dssdev);
|
||||
if (!r)
|
||||
r = taal_dcs_write_1(td, DCS_BRIGHTNESS, level);
|
||||
|
||||
dsi_bus_unlock(dssdev);
|
||||
} else {
|
||||
r = 0;
|
||||
}
|
||||
|
@ -504,9 +632,13 @@ static ssize_t taal_num_errors_show(struct device *dev,
|
|||
mutex_lock(&td->lock);
|
||||
|
||||
if (td->enabled) {
|
||||
dsi_bus_lock();
|
||||
r = taal_dcs_read_1(td, DCS_READ_NUM_ERRORS, &errors);
|
||||
dsi_bus_unlock();
|
||||
dsi_bus_lock(dssdev);
|
||||
|
||||
r = taal_wake_up(dssdev);
|
||||
if (!r)
|
||||
r = taal_dcs_read_1(td, DCS_READ_NUM_ERRORS, &errors);
|
||||
|
||||
dsi_bus_unlock(dssdev);
|
||||
} else {
|
||||
r = -ENODEV;
|
||||
}
|
||||
|
@ -530,9 +662,13 @@ static ssize_t taal_hw_revision_show(struct device *dev,
|
|||
mutex_lock(&td->lock);
|
||||
|
||||
if (td->enabled) {
|
||||
dsi_bus_lock();
|
||||
r = taal_get_id(td, &id1, &id2, &id3);
|
||||
dsi_bus_unlock();
|
||||
dsi_bus_lock(dssdev);
|
||||
|
||||
r = taal_wake_up(dssdev);
|
||||
if (!r)
|
||||
r = taal_get_id(td, &id1, &id2, &id3);
|
||||
|
||||
dsi_bus_unlock(dssdev);
|
||||
} else {
|
||||
r = -ENODEV;
|
||||
}
|
||||
|
@ -579,6 +715,7 @@ static ssize_t store_cabc_mode(struct device *dev,
|
|||
struct omap_dss_device *dssdev = to_dss_device(dev);
|
||||
struct taal_data *td = dev_get_drvdata(&dssdev->dev);
|
||||
int i;
|
||||
int r;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(cabc_modes); i++) {
|
||||
if (sysfs_streq(cabc_modes[i], buf))
|
||||
|
@ -591,10 +728,19 @@ static ssize_t store_cabc_mode(struct device *dev,
|
|||
mutex_lock(&td->lock);
|
||||
|
||||
if (td->enabled) {
|
||||
dsi_bus_lock();
|
||||
if (!td->cabc_broken)
|
||||
taal_dcs_write_1(td, DCS_WRITE_CABC, i);
|
||||
dsi_bus_unlock();
|
||||
dsi_bus_lock(dssdev);
|
||||
|
||||
if (!td->cabc_broken) {
|
||||
r = taal_wake_up(dssdev);
|
||||
if (r)
|
||||
goto err;
|
||||
|
||||
r = taal_dcs_write_1(td, DCS_WRITE_CABC, i);
|
||||
if (r)
|
||||
goto err;
|
||||
}
|
||||
|
||||
dsi_bus_unlock(dssdev);
|
||||
}
|
||||
|
||||
td->cabc_mode = i;
|
||||
|
@ -602,6 +748,10 @@ static ssize_t store_cabc_mode(struct device *dev,
|
|||
mutex_unlock(&td->lock);
|
||||
|
||||
return count;
|
||||
err:
|
||||
dsi_bus_unlock(dssdev);
|
||||
mutex_unlock(&td->lock);
|
||||
return r;
|
||||
}
|
||||
|
||||
static ssize_t show_cabc_available_modes(struct device *dev,
|
||||
|
@ -620,18 +770,161 @@ static ssize_t show_cabc_available_modes(struct device *dev,
|
|||
return len < PAGE_SIZE ? len : PAGE_SIZE - 1;
|
||||
}
|
||||
|
||||
static ssize_t taal_store_esd_interval(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct omap_dss_device *dssdev = to_dss_device(dev);
|
||||
struct taal_data *td = dev_get_drvdata(&dssdev->dev);
|
||||
|
||||
unsigned long t;
|
||||
int r;
|
||||
|
||||
r = strict_strtoul(buf, 10, &t);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
mutex_lock(&td->lock);
|
||||
taal_cancel_esd_work(dssdev);
|
||||
td->esd_interval = t;
|
||||
if (td->enabled)
|
||||
taal_queue_esd_work(dssdev);
|
||||
mutex_unlock(&td->lock);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t taal_show_esd_interval(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct omap_dss_device *dssdev = to_dss_device(dev);
|
||||
struct taal_data *td = dev_get_drvdata(&dssdev->dev);
|
||||
unsigned t;
|
||||
|
||||
mutex_lock(&td->lock);
|
||||
t = td->esd_interval;
|
||||
mutex_unlock(&td->lock);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%u\n", t);
|
||||
}
|
||||
|
||||
static ssize_t taal_store_ulps(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct omap_dss_device *dssdev = to_dss_device(dev);
|
||||
struct taal_data *td = dev_get_drvdata(&dssdev->dev);
|
||||
unsigned long t;
|
||||
int r;
|
||||
|
||||
r = strict_strtoul(buf, 10, &t);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
mutex_lock(&td->lock);
|
||||
|
||||
if (td->enabled) {
|
||||
dsi_bus_lock(dssdev);
|
||||
|
||||
if (t)
|
||||
r = taal_enter_ulps(dssdev);
|
||||
else
|
||||
r = taal_wake_up(dssdev);
|
||||
|
||||
dsi_bus_unlock(dssdev);
|
||||
}
|
||||
|
||||
mutex_unlock(&td->lock);
|
||||
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t taal_show_ulps(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct omap_dss_device *dssdev = to_dss_device(dev);
|
||||
struct taal_data *td = dev_get_drvdata(&dssdev->dev);
|
||||
unsigned t;
|
||||
|
||||
mutex_lock(&td->lock);
|
||||
t = td->ulps_enabled;
|
||||
mutex_unlock(&td->lock);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%u\n", t);
|
||||
}
|
||||
|
||||
static ssize_t taal_store_ulps_timeout(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct omap_dss_device *dssdev = to_dss_device(dev);
|
||||
struct taal_data *td = dev_get_drvdata(&dssdev->dev);
|
||||
unsigned long t;
|
||||
int r;
|
||||
|
||||
r = strict_strtoul(buf, 10, &t);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
mutex_lock(&td->lock);
|
||||
td->ulps_timeout = t;
|
||||
|
||||
if (td->enabled) {
|
||||
/* taal_wake_up will restart the timer */
|
||||
dsi_bus_lock(dssdev);
|
||||
r = taal_wake_up(dssdev);
|
||||
dsi_bus_unlock(dssdev);
|
||||
}
|
||||
|
||||
mutex_unlock(&td->lock);
|
||||
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t taal_show_ulps_timeout(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct omap_dss_device *dssdev = to_dss_device(dev);
|
||||
struct taal_data *td = dev_get_drvdata(&dssdev->dev);
|
||||
unsigned t;
|
||||
|
||||
mutex_lock(&td->lock);
|
||||
t = td->ulps_timeout;
|
||||
mutex_unlock(&td->lock);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%u\n", t);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(num_dsi_errors, S_IRUGO, taal_num_errors_show, NULL);
|
||||
static DEVICE_ATTR(hw_revision, S_IRUGO, taal_hw_revision_show, NULL);
|
||||
static DEVICE_ATTR(cabc_mode, S_IRUGO | S_IWUSR,
|
||||
show_cabc_mode, store_cabc_mode);
|
||||
static DEVICE_ATTR(cabc_available_modes, S_IRUGO,
|
||||
show_cabc_available_modes, NULL);
|
||||
static DEVICE_ATTR(esd_interval, S_IRUGO | S_IWUSR,
|
||||
taal_show_esd_interval, taal_store_esd_interval);
|
||||
static DEVICE_ATTR(ulps, S_IRUGO | S_IWUSR,
|
||||
taal_show_ulps, taal_store_ulps);
|
||||
static DEVICE_ATTR(ulps_timeout, S_IRUGO | S_IWUSR,
|
||||
taal_show_ulps_timeout, taal_store_ulps_timeout);
|
||||
|
||||
static struct attribute *taal_attrs[] = {
|
||||
&dev_attr_num_dsi_errors.attr,
|
||||
&dev_attr_hw_revision.attr,
|
||||
&dev_attr_cabc_mode.attr,
|
||||
&dev_attr_cabc_available_modes.attr,
|
||||
&dev_attr_esd_interval.attr,
|
||||
&dev_attr_ulps.attr,
|
||||
&dev_attr_ulps_timeout.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
@ -700,6 +993,9 @@ static int taal_probe(struct omap_dss_device *dssdev)
|
|||
}
|
||||
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;
|
||||
|
||||
mutex_init(&td->lock);
|
||||
|
||||
|
@ -710,13 +1006,14 @@ static int taal_probe(struct omap_dss_device *dssdev)
|
|||
if (r)
|
||||
goto err_reg;
|
||||
|
||||
td->esd_wq = create_singlethread_workqueue("taal_esd");
|
||||
if (td->esd_wq == NULL) {
|
||||
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;
|
||||
}
|
||||
INIT_DELAYED_WORK_DEFERRABLE(&td->esd_work, taal_esd_work);
|
||||
INIT_DELAYED_WORK(&td->ulps_work, taal_ulps_work);
|
||||
|
||||
dev_set_drvdata(&dssdev->dev, td);
|
||||
|
||||
|
@ -734,8 +1031,8 @@ static int taal_probe(struct omap_dss_device *dssdev)
|
|||
props.max_brightness = 127;
|
||||
|
||||
props.type = BACKLIGHT_RAW;
|
||||
bldev = backlight_device_register("taal", &dssdev->dev, dssdev,
|
||||
&taal_bl_ops, &props);
|
||||
bldev = backlight_device_register(dev_name(&dssdev->dev), &dssdev->dev,
|
||||
dssdev, &taal_bl_ops, &props);
|
||||
if (IS_ERR(bldev)) {
|
||||
r = PTR_ERR(bldev);
|
||||
goto err_bl;
|
||||
|
@ -810,7 +1107,7 @@ static int taal_probe(struct omap_dss_device *dssdev)
|
|||
err_gpio:
|
||||
backlight_device_unregister(bldev);
|
||||
err_bl:
|
||||
destroy_workqueue(td->esd_wq);
|
||||
destroy_workqueue(td->workqueue);
|
||||
err_wq:
|
||||
free_regulators(panel_config->regulators, panel_config->num_regulators);
|
||||
err_reg:
|
||||
|
@ -819,7 +1116,7 @@ static int taal_probe(struct omap_dss_device *dssdev)
|
|||
return r;
|
||||
}
|
||||
|
||||
static void taal_remove(struct omap_dss_device *dssdev)
|
||||
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);
|
||||
|
@ -841,8 +1138,9 @@ static void taal_remove(struct omap_dss_device *dssdev)
|
|||
taal_bl_update_status(bldev);
|
||||
backlight_device_unregister(bldev);
|
||||
|
||||
cancel_delayed_work(&td->esd_work);
|
||||
destroy_workqueue(td->esd_wq);
|
||||
taal_cancel_ulps_work(dssdev);
|
||||
taal_cancel_esd_work(dssdev);
|
||||
destroy_workqueue(td->workqueue);
|
||||
|
||||
/* reset, to be sure that the panel is in a valid state */
|
||||
taal_hw_reset(dssdev);
|
||||
|
@ -867,7 +1165,7 @@ static int taal_power_on(struct omap_dss_device *dssdev)
|
|||
|
||||
taal_hw_reset(dssdev);
|
||||
|
||||
omapdss_dsi_vc_enable_hs(td->channel, false);
|
||||
omapdss_dsi_vc_enable_hs(dssdev, td->channel, false);
|
||||
|
||||
r = taal_sleep_out(td);
|
||||
if (r)
|
||||
|
@ -924,7 +1222,7 @@ static int taal_power_on(struct omap_dss_device *dssdev)
|
|||
td->intro_printed = true;
|
||||
}
|
||||
|
||||
omapdss_dsi_vc_enable_hs(td->channel, true);
|
||||
omapdss_dsi_vc_enable_hs(dssdev, td->channel, true);
|
||||
|
||||
return 0;
|
||||
err:
|
||||
|
@ -932,7 +1230,7 @@ static int taal_power_on(struct omap_dss_device *dssdev)
|
|||
|
||||
taal_hw_reset(dssdev);
|
||||
|
||||
omapdss_dsi_display_disable(dssdev);
|
||||
omapdss_dsi_display_disable(dssdev, true, false);
|
||||
err0:
|
||||
return r;
|
||||
}
|
||||
|
@ -955,15 +1253,23 @@ static void taal_power_off(struct omap_dss_device *dssdev)
|
|||
taal_hw_reset(dssdev);
|
||||
}
|
||||
|
||||
omapdss_dsi_display_disable(dssdev);
|
||||
omapdss_dsi_display_disable(dssdev, true, false);
|
||||
|
||||
td->enabled = 0;
|
||||
}
|
||||
|
||||
static int taal_panel_reset(struct omap_dss_device *dssdev)
|
||||
{
|
||||
dev_err(&dssdev->dev, "performing LCD reset\n");
|
||||
|
||||
taal_power_off(dssdev);
|
||||
taal_hw_reset(dssdev);
|
||||
return taal_power_on(dssdev);
|
||||
}
|
||||
|
||||
static int taal_enable(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;
|
||||
|
||||
dev_dbg(&dssdev->dev, "enable\n");
|
||||
|
@ -975,18 +1281,16 @@ static int taal_enable(struct omap_dss_device *dssdev)
|
|||
goto err;
|
||||
}
|
||||
|
||||
dsi_bus_lock();
|
||||
dsi_bus_lock(dssdev);
|
||||
|
||||
r = taal_power_on(dssdev);
|
||||
|
||||
dsi_bus_unlock();
|
||||
dsi_bus_unlock(dssdev);
|
||||
|
||||
if (r)
|
||||
goto err;
|
||||
|
||||
if (panel_data->use_esd_check)
|
||||
queue_delayed_work(td->esd_wq, &td->esd_work,
|
||||
TAAL_ESD_CHECK_PERIOD);
|
||||
taal_queue_esd_work(dssdev);
|
||||
|
||||
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
|
||||
|
||||
|
@ -1007,14 +1311,17 @@ static void taal_disable(struct omap_dss_device *dssdev)
|
|||
|
||||
mutex_lock(&td->lock);
|
||||
|
||||
cancel_delayed_work(&td->esd_work);
|
||||
taal_cancel_ulps_work(dssdev);
|
||||
taal_cancel_esd_work(dssdev);
|
||||
|
||||
dsi_bus_lock();
|
||||
dsi_bus_lock(dssdev);
|
||||
|
||||
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
|
||||
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
|
||||
taal_wake_up(dssdev);
|
||||
taal_power_off(dssdev);
|
||||
}
|
||||
|
||||
dsi_bus_unlock();
|
||||
dsi_bus_unlock(dssdev);
|
||||
|
||||
dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
|
||||
|
||||
|
@ -1035,13 +1342,16 @@ static int taal_suspend(struct omap_dss_device *dssdev)
|
|||
goto err;
|
||||
}
|
||||
|
||||
cancel_delayed_work(&td->esd_work);
|
||||
taal_cancel_ulps_work(dssdev);
|
||||
taal_cancel_esd_work(dssdev);
|
||||
|
||||
dsi_bus_lock();
|
||||
dsi_bus_lock(dssdev);
|
||||
|
||||
taal_power_off(dssdev);
|
||||
r = taal_wake_up(dssdev);
|
||||
if (!r)
|
||||
taal_power_off(dssdev);
|
||||
|
||||
dsi_bus_unlock();
|
||||
dsi_bus_unlock(dssdev);
|
||||
|
||||
dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
|
||||
|
||||
|
@ -1056,7 +1366,6 @@ static int taal_suspend(struct omap_dss_device *dssdev)
|
|||
static int taal_resume(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;
|
||||
|
||||
dev_dbg(&dssdev->dev, "resume\n");
|
||||
|
@ -1068,19 +1377,17 @@ static int taal_resume(struct omap_dss_device *dssdev)
|
|||
goto err;
|
||||
}
|
||||
|
||||
dsi_bus_lock();
|
||||
dsi_bus_lock(dssdev);
|
||||
|
||||
r = taal_power_on(dssdev);
|
||||
|
||||
dsi_bus_unlock();
|
||||
dsi_bus_unlock(dssdev);
|
||||
|
||||
if (r) {
|
||||
dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
|
||||
} else {
|
||||
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
|
||||
if (panel_data->use_esd_check)
|
||||
queue_delayed_work(td->esd_wq, &td->esd_work,
|
||||
TAAL_ESD_CHECK_PERIOD);
|
||||
taal_queue_esd_work(dssdev);
|
||||
}
|
||||
|
||||
mutex_unlock(&td->lock);
|
||||
|
@ -1095,7 +1402,7 @@ static void taal_framedone_cb(int err, void *data)
|
|||
{
|
||||
struct omap_dss_device *dssdev = data;
|
||||
dev_dbg(&dssdev->dev, "framedone, err %d\n", err);
|
||||
dsi_bus_unlock();
|
||||
dsi_bus_unlock(dssdev);
|
||||
}
|
||||
|
||||
static irqreturn_t taal_te_isr(int irq, void *data)
|
||||
|
@ -1123,7 +1430,7 @@ static irqreturn_t taal_te_isr(int irq, void *data)
|
|||
return IRQ_HANDLED;
|
||||
err:
|
||||
dev_err(&dssdev->dev, "start update failed\n");
|
||||
dsi_bus_unlock();
|
||||
dsi_bus_unlock(dssdev);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
|
@ -1136,7 +1443,7 @@ static void taal_te_timeout_work_callback(struct work_struct *work)
|
|||
dev_err(&dssdev->dev, "TE not received for 250ms!\n");
|
||||
|
||||
atomic_set(&td->do_update, 0);
|
||||
dsi_bus_unlock();
|
||||
dsi_bus_unlock(dssdev);
|
||||
}
|
||||
|
||||
static int taal_update(struct omap_dss_device *dssdev,
|
||||
|
@ -1149,7 +1456,11 @@ static int taal_update(struct omap_dss_device *dssdev,
|
|||
dev_dbg(&dssdev->dev, "update %d, %d, %d x %d\n", x, y, w, h);
|
||||
|
||||
mutex_lock(&td->lock);
|
||||
dsi_bus_lock();
|
||||
dsi_bus_lock(dssdev);
|
||||
|
||||
r = taal_wake_up(dssdev);
|
||||
if (r)
|
||||
goto err;
|
||||
|
||||
if (!td->enabled) {
|
||||
r = 0;
|
||||
|
@ -1184,7 +1495,7 @@ static int taal_update(struct omap_dss_device *dssdev,
|
|||
mutex_unlock(&td->lock);
|
||||
return 0;
|
||||
err:
|
||||
dsi_bus_unlock();
|
||||
dsi_bus_unlock(dssdev);
|
||||
mutex_unlock(&td->lock);
|
||||
return r;
|
||||
}
|
||||
|
@ -1196,8 +1507,8 @@ static int taal_sync(struct omap_dss_device *dssdev)
|
|||
dev_dbg(&dssdev->dev, "sync\n");
|
||||
|
||||
mutex_lock(&td->lock);
|
||||
dsi_bus_lock();
|
||||
dsi_bus_unlock();
|
||||
dsi_bus_lock(dssdev);
|
||||
dsi_bus_unlock(dssdev);
|
||||
mutex_unlock(&td->lock);
|
||||
|
||||
dev_dbg(&dssdev->dev, "sync done\n");
|
||||
|
@ -1235,9 +1546,13 @@ static int taal_enable_te(struct omap_dss_device *dssdev, bool enable)
|
|||
if (td->te_enabled == enable)
|
||||
goto end;
|
||||
|
||||
dsi_bus_lock();
|
||||
dsi_bus_lock(dssdev);
|
||||
|
||||
if (td->enabled) {
|
||||
r = taal_wake_up(dssdev);
|
||||
if (r)
|
||||
goto err;
|
||||
|
||||
r = _taal_enable_te(dssdev, enable);
|
||||
if (r)
|
||||
goto err;
|
||||
|
@ -1245,13 +1560,13 @@ static int taal_enable_te(struct omap_dss_device *dssdev, bool enable)
|
|||
|
||||
td->te_enabled = enable;
|
||||
|
||||
dsi_bus_unlock();
|
||||
dsi_bus_unlock(dssdev);
|
||||
end:
|
||||
mutex_unlock(&td->lock);
|
||||
|
||||
return 0;
|
||||
err:
|
||||
dsi_bus_unlock();
|
||||
dsi_bus_unlock(dssdev);
|
||||
mutex_unlock(&td->lock);
|
||||
|
||||
return r;
|
||||
|
@ -1281,9 +1596,13 @@ static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate)
|
|||
if (td->rotate == rotate)
|
||||
goto end;
|
||||
|
||||
dsi_bus_lock();
|
||||
dsi_bus_lock(dssdev);
|
||||
|
||||
if (td->enabled) {
|
||||
r = taal_wake_up(dssdev);
|
||||
if (r)
|
||||
goto err;
|
||||
|
||||
r = taal_set_addr_mode(td, rotate, td->mirror);
|
||||
if (r)
|
||||
goto err;
|
||||
|
@ -1291,12 +1610,12 @@ static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate)
|
|||
|
||||
td->rotate = rotate;
|
||||
|
||||
dsi_bus_unlock();
|
||||
dsi_bus_unlock(dssdev);
|
||||
end:
|
||||
mutex_unlock(&td->lock);
|
||||
return 0;
|
||||
err:
|
||||
dsi_bus_unlock();
|
||||
dsi_bus_unlock(dssdev);
|
||||
mutex_unlock(&td->lock);
|
||||
return r;
|
||||
}
|
||||
|
@ -1325,8 +1644,12 @@ static int taal_mirror(struct omap_dss_device *dssdev, bool enable)
|
|||
if (td->mirror == enable)
|
||||
goto end;
|
||||
|
||||
dsi_bus_lock();
|
||||
dsi_bus_lock(dssdev);
|
||||
if (td->enabled) {
|
||||
r = taal_wake_up(dssdev);
|
||||
if (r)
|
||||
goto err;
|
||||
|
||||
r = taal_set_addr_mode(td, td->rotate, enable);
|
||||
if (r)
|
||||
goto err;
|
||||
|
@ -1334,12 +1657,12 @@ static int taal_mirror(struct omap_dss_device *dssdev, bool enable)
|
|||
|
||||
td->mirror = enable;
|
||||
|
||||
dsi_bus_unlock();
|
||||
dsi_bus_unlock(dssdev);
|
||||
end:
|
||||
mutex_unlock(&td->lock);
|
||||
return 0;
|
||||
err:
|
||||
dsi_bus_unlock();
|
||||
dsi_bus_unlock(dssdev);
|
||||
mutex_unlock(&td->lock);
|
||||
return r;
|
||||
}
|
||||
|
@ -1369,7 +1692,11 @@ static int taal_run_test(struct omap_dss_device *dssdev, int test_num)
|
|||
goto err1;
|
||||
}
|
||||
|
||||
dsi_bus_lock();
|
||||
dsi_bus_lock(dssdev);
|
||||
|
||||
r = taal_wake_up(dssdev);
|
||||
if (r)
|
||||
goto err2;
|
||||
|
||||
r = taal_dcs_read_1(td, DCS_GET_ID1, &id1);
|
||||
if (r)
|
||||
|
@ -1381,11 +1708,11 @@ static int taal_run_test(struct omap_dss_device *dssdev, int test_num)
|
|||
if (r)
|
||||
goto err2;
|
||||
|
||||
dsi_bus_unlock();
|
||||
dsi_bus_unlock(dssdev);
|
||||
mutex_unlock(&td->lock);
|
||||
return 0;
|
||||
err2:
|
||||
dsi_bus_unlock();
|
||||
dsi_bus_unlock(dssdev);
|
||||
err1:
|
||||
mutex_unlock(&td->lock);
|
||||
return r;
|
||||
|
@ -1415,7 +1742,11 @@ static int taal_memory_read(struct omap_dss_device *dssdev,
|
|||
dssdev->panel.timings.x_res *
|
||||
dssdev->panel.timings.y_res * 3);
|
||||
|
||||
dsi_bus_lock();
|
||||
dsi_bus_lock(dssdev);
|
||||
|
||||
r = taal_wake_up(dssdev);
|
||||
if (r)
|
||||
goto err2;
|
||||
|
||||
/* plen 1 or 2 goes into short packet. until checksum error is fixed,
|
||||
* use short packets. plen 32 works, but bigger packets seem to cause
|
||||
|
@ -1427,7 +1758,7 @@ static int taal_memory_read(struct omap_dss_device *dssdev,
|
|||
|
||||
taal_set_update_window(td, x, y, w, h);
|
||||
|
||||
r = dsi_vc_set_max_rx_packet_size(td->channel, plen);
|
||||
r = dsi_vc_set_max_rx_packet_size(dssdev, td->channel, plen);
|
||||
if (r)
|
||||
goto err2;
|
||||
|
||||
|
@ -1435,7 +1766,7 @@ static int taal_memory_read(struct omap_dss_device *dssdev,
|
|||
u8 dcs_cmd = first ? 0x2e : 0x3e;
|
||||
first = 0;
|
||||
|
||||
r = dsi_vc_dcs_read(td->channel, dcs_cmd,
|
||||
r = dsi_vc_dcs_read(dssdev, td->channel, dcs_cmd,
|
||||
buf + buf_used, size - buf_used);
|
||||
|
||||
if (r < 0) {
|
||||
|
@ -1461,14 +1792,35 @@ static int taal_memory_read(struct omap_dss_device *dssdev,
|
|||
r = buf_used;
|
||||
|
||||
err3:
|
||||
dsi_vc_set_max_rx_packet_size(td->channel, 1);
|
||||
dsi_vc_set_max_rx_packet_size(dssdev, td->channel, 1);
|
||||
err2:
|
||||
dsi_bus_unlock();
|
||||
dsi_bus_unlock(dssdev);
|
||||
err1:
|
||||
mutex_unlock(&td->lock);
|
||||
return r;
|
||||
}
|
||||
|
||||
static void taal_ulps_work(struct work_struct *work)
|
||||
{
|
||||
struct taal_data *td = container_of(work, struct taal_data,
|
||||
ulps_work.work);
|
||||
struct omap_dss_device *dssdev = td->dssdev;
|
||||
|
||||
mutex_lock(&td->lock);
|
||||
|
||||
if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE || !td->enabled) {
|
||||
mutex_unlock(&td->lock);
|
||||
return;
|
||||
}
|
||||
|
||||
dsi_bus_lock(dssdev);
|
||||
|
||||
taal_enter_ulps(dssdev);
|
||||
|
||||
dsi_bus_unlock(dssdev);
|
||||
mutex_unlock(&td->lock);
|
||||
}
|
||||
|
||||
static void taal_esd_work(struct work_struct *work)
|
||||
{
|
||||
struct taal_data *td = container_of(work, struct taal_data,
|
||||
|
@ -1485,7 +1837,13 @@ static void taal_esd_work(struct work_struct *work)
|
|||
return;
|
||||
}
|
||||
|
||||
dsi_bus_lock();
|
||||
dsi_bus_lock(dssdev);
|
||||
|
||||
r = taal_wake_up(dssdev);
|
||||
if (r) {
|
||||
dev_err(&dssdev->dev, "failed to exit ULPS\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
r = taal_dcs_read_1(td, DCS_RDDSDR, &state1);
|
||||
if (r) {
|
||||
|
@ -1521,22 +1879,20 @@ static void taal_esd_work(struct work_struct *work)
|
|||
goto err;
|
||||
}
|
||||
|
||||
dsi_bus_unlock();
|
||||
dsi_bus_unlock(dssdev);
|
||||
|
||||
queue_delayed_work(td->esd_wq, &td->esd_work, TAAL_ESD_CHECK_PERIOD);
|
||||
taal_queue_esd_work(dssdev);
|
||||
|
||||
mutex_unlock(&td->lock);
|
||||
return;
|
||||
err:
|
||||
dev_err(&dssdev->dev, "performing LCD reset\n");
|
||||
|
||||
taal_power_off(dssdev);
|
||||
taal_hw_reset(dssdev);
|
||||
taal_power_on(dssdev);
|
||||
taal_panel_reset(dssdev);
|
||||
|
||||
dsi_bus_unlock();
|
||||
dsi_bus_unlock(dssdev);
|
||||
|
||||
queue_delayed_work(td->esd_wq, &td->esd_work, TAAL_ESD_CHECK_PERIOD);
|
||||
taal_queue_esd_work(dssdev);
|
||||
|
||||
mutex_unlock(&td->lock);
|
||||
}
|
||||
|
@ -1557,7 +1913,7 @@ static enum omap_dss_update_mode taal_get_update_mode(
|
|||
|
||||
static struct omap_dss_driver taal_driver = {
|
||||
.probe = taal_probe,
|
||||
.remove = taal_remove,
|
||||
.remove = __exit_p(taal_remove),
|
||||
|
||||
.enable = taal_enable,
|
||||
.disable = taal_disable,
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#include <linux/err.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <plat/display.h>
|
||||
#include <video/omapdss.h>
|
||||
|
||||
#define TPO_R02_MODE(x) ((x) & 7)
|
||||
#define TPO_R02_MODE_800x480 7
|
||||
|
@ -144,13 +144,15 @@ static ssize_t tpo_td043_vmirror_store(struct device *dev,
|
|||
struct device_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);
|
||||
long val;
|
||||
int val;
|
||||
int ret;
|
||||
|
||||
ret = strict_strtol(buf, 0, &val);
|
||||
ret = kstrtoint(buf, 0, &val);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
val = !!val;
|
||||
|
||||
ret = tpo_td043_write_mirror(tpo_td043->spi, tpo_td043->hmirror, val);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
@ -175,7 +177,7 @@ static ssize_t tpo_td043_mode_store(struct device *dev,
|
|||
long val;
|
||||
int ret;
|
||||
|
||||
ret = strict_strtol(buf, 0, &val);
|
||||
ret = kstrtol(buf, 0, &val);
|
||||
if (ret != 0 || val & ~7)
|
||||
return -EINVAL;
|
||||
|
||||
|
|
|
@ -80,7 +80,7 @@ config OMAP2_DSS_SDI
|
|||
|
||||
config OMAP2_DSS_DSI
|
||||
bool "DSI support"
|
||||
depends on ARCH_OMAP3
|
||||
depends on ARCH_OMAP3 || ARCH_OMAP4
|
||||
default n
|
||||
help
|
||||
MIPI DSI (Display Serial Interface) support.
|
||||
|
@ -90,14 +90,6 @@ config OMAP2_DSS_DSI
|
|||
|
||||
See http://www.mipi.org/ for DSI spesifications.
|
||||
|
||||
config OMAP2_DSS_USE_DSI_PLL
|
||||
bool "Use DSI PLL for PCLK (EXPERIMENTAL)"
|
||||
default n
|
||||
depends on OMAP2_DSS_DSI
|
||||
help
|
||||
Use DSI PLL to generate pixel clock. Currently only for DPI output.
|
||||
DSI PLL can be used to generate higher and more precise pixel clocks.
|
||||
|
||||
config OMAP2_DSS_FAKE_VSYNC
|
||||
bool "Fake VSYNC irq from manual update displays"
|
||||
default n
|
||||
|
@ -125,4 +117,27 @@ config OMAP2_DSS_MIN_FCK_PER_PCK
|
|||
Max FCK is 173MHz, so this doesn't work if your PCK
|
||||
is very high.
|
||||
|
||||
config OMAP2_DSS_SLEEP_BEFORE_RESET
|
||||
bool "Sleep 50ms before DSS reset"
|
||||
default y
|
||||
help
|
||||
For some unknown reason we may get SYNC_LOST errors from the display
|
||||
subsystem at initialization time if we don't sleep before resetting
|
||||
the DSS. See the source (dss.c) for more comments.
|
||||
|
||||
However, 50ms is quite long time to sleep, and with some
|
||||
configurations the SYNC_LOST may never happen, so the sleep can
|
||||
be disabled here.
|
||||
|
||||
config OMAP2_DSS_SLEEP_AFTER_VENC_RESET
|
||||
bool "Sleep 20ms after VENC reset"
|
||||
default y
|
||||
help
|
||||
There is a 20ms sleep after VENC reset which seemed to fix the
|
||||
reset. The reason for the bug is unclear, and it's also unclear
|
||||
on what platforms this happens.
|
||||
|
||||
This option enables the sleep, and is enabled by default. You can
|
||||
disable the sleep if it doesn't cause problems on your platform.
|
||||
|
||||
endif
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
#include <linux/device.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
||||
#include <plat/display.h>
|
||||
#include <video/omapdss.h>
|
||||
|
||||
#include "dss.h"
|
||||
#include "dss_features.h"
|
||||
|
@ -54,6 +54,9 @@ unsigned int dss_debug;
|
|||
module_param_named(debug, dss_debug, bool, 0644);
|
||||
#endif
|
||||
|
||||
static int omap_dss_register_device(struct omap_dss_device *);
|
||||
static void omap_dss_unregister_device(struct omap_dss_device *);
|
||||
|
||||
/* REGULATORS */
|
||||
|
||||
struct regulator *dss_get_vdds_dsi(void)
|
||||
|
@ -124,8 +127,7 @@ static int dss_initialize_debugfs(void)
|
|||
#endif
|
||||
|
||||
#if defined(CONFIG_OMAP2_DSS_DSI) && defined(CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS)
|
||||
debugfs_create_file("dsi_irq", S_IRUGO, dss_debugfs_dir,
|
||||
&dsi_dump_irqs, &dss_debug_fops);
|
||||
dsi_create_debugfs_files_irq(dss_debugfs_dir, &dss_debug_fops);
|
||||
#endif
|
||||
|
||||
debugfs_create_file("dss", S_IRUGO, dss_debugfs_dir,
|
||||
|
@ -137,8 +139,7 @@ static int dss_initialize_debugfs(void)
|
|||
&rfbi_dump_regs, &dss_debug_fops);
|
||||
#endif
|
||||
#ifdef CONFIG_OMAP2_DSS_DSI
|
||||
debugfs_create_file("dsi", S_IRUGO, dss_debugfs_dir,
|
||||
&dsi_dump_regs, &dss_debug_fops);
|
||||
dsi_create_debugfs_files_reg(dss_debugfs_dir, &dss_debug_fops);
|
||||
#endif
|
||||
#ifdef CONFIG_OMAP2_DSS_VENC
|
||||
debugfs_create_file("venc", S_IRUGO, dss_debugfs_dir,
|
||||
|
@ -480,7 +481,7 @@ static void omap_dss_dev_release(struct device *dev)
|
|||
reset_device(dev, 0);
|
||||
}
|
||||
|
||||
int omap_dss_register_device(struct omap_dss_device *dssdev)
|
||||
static int omap_dss_register_device(struct omap_dss_device *dssdev)
|
||||
{
|
||||
static int dev_num;
|
||||
|
||||
|
@ -494,7 +495,7 @@ int omap_dss_register_device(struct omap_dss_device *dssdev)
|
|||
return device_register(&dssdev->dev);
|
||||
}
|
||||
|
||||
void omap_dss_unregister_device(struct omap_dss_device *dssdev)
|
||||
static void omap_dss_unregister_device(struct omap_dss_device *dssdev)
|
||||
{
|
||||
device_unregister(&dssdev->dev);
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,691 @@
|
|||
/*
|
||||
* linux/drivers/video/omap2/dss/dispc.h
|
||||
*
|
||||
* Copyright (C) 2011 Texas Instruments
|
||||
* Author: Archit Taneja <archit@ti.com>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published by
|
||||
* the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __OMAP2_DISPC_REG_H
|
||||
#define __OMAP2_DISPC_REG_H
|
||||
|
||||
/* DISPC common registers */
|
||||
#define DISPC_REVISION 0x0000
|
||||
#define DISPC_SYSCONFIG 0x0010
|
||||
#define DISPC_SYSSTATUS 0x0014
|
||||
#define DISPC_IRQSTATUS 0x0018
|
||||
#define DISPC_IRQENABLE 0x001C
|
||||
#define DISPC_CONTROL 0x0040
|
||||
#define DISPC_CONFIG 0x0044
|
||||
#define DISPC_CAPABLE 0x0048
|
||||
#define DISPC_LINE_STATUS 0x005C
|
||||
#define DISPC_LINE_NUMBER 0x0060
|
||||
#define DISPC_GLOBAL_ALPHA 0x0074
|
||||
#define DISPC_CONTROL2 0x0238
|
||||
#define DISPC_CONFIG2 0x0620
|
||||
#define DISPC_DIVISOR 0x0804
|
||||
|
||||
/* DISPC overlay registers */
|
||||
#define DISPC_OVL_BA0(n) (DISPC_OVL_BASE(n) + \
|
||||
DISPC_BA0_OFFSET(n))
|
||||
#define DISPC_OVL_BA1(n) (DISPC_OVL_BASE(n) + \
|
||||
DISPC_BA1_OFFSET(n))
|
||||
#define DISPC_OVL_BA0_UV(n) (DISPC_OVL_BASE(n) + \
|
||||
DISPC_BA0_UV_OFFSET(n))
|
||||
#define DISPC_OVL_BA1_UV(n) (DISPC_OVL_BASE(n) + \
|
||||
DISPC_BA1_UV_OFFSET(n))
|
||||
#define DISPC_OVL_POSITION(n) (DISPC_OVL_BASE(n) + \
|
||||
DISPC_POS_OFFSET(n))
|
||||
#define DISPC_OVL_SIZE(n) (DISPC_OVL_BASE(n) + \
|
||||
DISPC_SIZE_OFFSET(n))
|
||||
#define DISPC_OVL_ATTRIBUTES(n) (DISPC_OVL_BASE(n) + \
|
||||
DISPC_ATTR_OFFSET(n))
|
||||
#define DISPC_OVL_ATTRIBUTES2(n) (DISPC_OVL_BASE(n) + \
|
||||
DISPC_ATTR2_OFFSET(n))
|
||||
#define DISPC_OVL_FIFO_THRESHOLD(n) (DISPC_OVL_BASE(n) + \
|
||||
DISPC_FIFO_THRESH_OFFSET(n))
|
||||
#define DISPC_OVL_FIFO_SIZE_STATUS(n) (DISPC_OVL_BASE(n) + \
|
||||
DISPC_FIFO_SIZE_STATUS_OFFSET(n))
|
||||
#define DISPC_OVL_ROW_INC(n) (DISPC_OVL_BASE(n) + \
|
||||
DISPC_ROW_INC_OFFSET(n))
|
||||
#define DISPC_OVL_PIXEL_INC(n) (DISPC_OVL_BASE(n) + \
|
||||
DISPC_PIX_INC_OFFSET(n))
|
||||
#define DISPC_OVL_WINDOW_SKIP(n) (DISPC_OVL_BASE(n) + \
|
||||
DISPC_WINDOW_SKIP_OFFSET(n))
|
||||
#define DISPC_OVL_TABLE_BA(n) (DISPC_OVL_BASE(n) + \
|
||||
DISPC_TABLE_BA_OFFSET(n))
|
||||
#define DISPC_OVL_FIR(n) (DISPC_OVL_BASE(n) + \
|
||||
DISPC_FIR_OFFSET(n))
|
||||
#define DISPC_OVL_FIR2(n) (DISPC_OVL_BASE(n) + \
|
||||
DISPC_FIR2_OFFSET(n))
|
||||
#define DISPC_OVL_PICTURE_SIZE(n) (DISPC_OVL_BASE(n) + \
|
||||
DISPC_PIC_SIZE_OFFSET(n))
|
||||
#define DISPC_OVL_ACCU0(n) (DISPC_OVL_BASE(n) + \
|
||||
DISPC_ACCU0_OFFSET(n))
|
||||
#define DISPC_OVL_ACCU1(n) (DISPC_OVL_BASE(n) + \
|
||||
DISPC_ACCU1_OFFSET(n))
|
||||
#define DISPC_OVL_ACCU2_0(n) (DISPC_OVL_BASE(n) + \
|
||||
DISPC_ACCU2_0_OFFSET(n))
|
||||
#define DISPC_OVL_ACCU2_1(n) (DISPC_OVL_BASE(n) + \
|
||||
DISPC_ACCU2_1_OFFSET(n))
|
||||
#define DISPC_OVL_FIR_COEF_H(n, i) (DISPC_OVL_BASE(n) + \
|
||||
DISPC_FIR_COEF_H_OFFSET(n, i))
|
||||
#define DISPC_OVL_FIR_COEF_HV(n, i) (DISPC_OVL_BASE(n) + \
|
||||
DISPC_FIR_COEF_HV_OFFSET(n, i))
|
||||
#define DISPC_OVL_FIR_COEF_H2(n, i) (DISPC_OVL_BASE(n) + \
|
||||
DISPC_FIR_COEF_H2_OFFSET(n, i))
|
||||
#define DISPC_OVL_FIR_COEF_HV2(n, i) (DISPC_OVL_BASE(n) + \
|
||||
DISPC_FIR_COEF_HV2_OFFSET(n, i))
|
||||
#define DISPC_OVL_CONV_COEF(n, i) (DISPC_OVL_BASE(n) + \
|
||||
DISPC_CONV_COEF_OFFSET(n, i))
|
||||
#define DISPC_OVL_FIR_COEF_V(n, i) (DISPC_OVL_BASE(n) + \
|
||||
DISPC_FIR_COEF_V_OFFSET(n, i))
|
||||
#define DISPC_OVL_FIR_COEF_V2(n, i) (DISPC_OVL_BASE(n) + \
|
||||
DISPC_FIR_COEF_V2_OFFSET(n, i))
|
||||
#define DISPC_OVL_PRELOAD(n) (DISPC_OVL_BASE(n) + \
|
||||
DISPC_PRELOAD_OFFSET(n))
|
||||
|
||||
/* DISPC manager/channel specific registers */
|
||||
static inline u16 DISPC_DEFAULT_COLOR(enum omap_channel channel)
|
||||
{
|
||||
switch (channel) {
|
||||
case OMAP_DSS_CHANNEL_LCD:
|
||||
return 0x004C;
|
||||
case OMAP_DSS_CHANNEL_DIGIT:
|
||||
return 0x0050;
|
||||
case OMAP_DSS_CHANNEL_LCD2:
|
||||
return 0x03AC;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
static inline u16 DISPC_TRANS_COLOR(enum omap_channel channel)
|
||||
{
|
||||
switch (channel) {
|
||||
case OMAP_DSS_CHANNEL_LCD:
|
||||
return 0x0054;
|
||||
case OMAP_DSS_CHANNEL_DIGIT:
|
||||
return 0x0058;
|
||||
case OMAP_DSS_CHANNEL_LCD2:
|
||||
return 0x03B0;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
static inline u16 DISPC_TIMING_H(enum omap_channel channel)
|
||||
{
|
||||
switch (channel) {
|
||||
case OMAP_DSS_CHANNEL_LCD:
|
||||
return 0x0064;
|
||||
case OMAP_DSS_CHANNEL_DIGIT:
|
||||
BUG();
|
||||
case OMAP_DSS_CHANNEL_LCD2:
|
||||
return 0x0400;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
static inline u16 DISPC_TIMING_V(enum omap_channel channel)
|
||||
{
|
||||
switch (channel) {
|
||||
case OMAP_DSS_CHANNEL_LCD:
|
||||
return 0x0068;
|
||||
case OMAP_DSS_CHANNEL_DIGIT:
|
||||
BUG();
|
||||
case OMAP_DSS_CHANNEL_LCD2:
|
||||
return 0x0404;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
static inline u16 DISPC_POL_FREQ(enum omap_channel channel)
|
||||
{
|
||||
switch (channel) {
|
||||
case OMAP_DSS_CHANNEL_LCD:
|
||||
return 0x006C;
|
||||
case OMAP_DSS_CHANNEL_DIGIT:
|
||||
BUG();
|
||||
case OMAP_DSS_CHANNEL_LCD2:
|
||||
return 0x0408;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
static inline u16 DISPC_DIVISORo(enum omap_channel channel)
|
||||
{
|
||||
switch (channel) {
|
||||
case OMAP_DSS_CHANNEL_LCD:
|
||||
return 0x0070;
|
||||
case OMAP_DSS_CHANNEL_DIGIT:
|
||||
BUG();
|
||||
case OMAP_DSS_CHANNEL_LCD2:
|
||||
return 0x040C;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
/* Named as DISPC_SIZE_LCD, DISPC_SIZE_DIGIT and DISPC_SIZE_LCD2 in TRM */
|
||||
static inline u16 DISPC_SIZE_MGR(enum omap_channel channel)
|
||||
{
|
||||
switch (channel) {
|
||||
case OMAP_DSS_CHANNEL_LCD:
|
||||
return 0x007C;
|
||||
case OMAP_DSS_CHANNEL_DIGIT:
|
||||
return 0x0078;
|
||||
case OMAP_DSS_CHANNEL_LCD2:
|
||||
return 0x03CC;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
static inline u16 DISPC_DATA_CYCLE1(enum omap_channel channel)
|
||||
{
|
||||
switch (channel) {
|
||||
case OMAP_DSS_CHANNEL_LCD:
|
||||
return 0x01D4;
|
||||
case OMAP_DSS_CHANNEL_DIGIT:
|
||||
BUG();
|
||||
case OMAP_DSS_CHANNEL_LCD2:
|
||||
return 0x03C0;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
static inline u16 DISPC_DATA_CYCLE2(enum omap_channel channel)
|
||||
{
|
||||
switch (channel) {
|
||||
case OMAP_DSS_CHANNEL_LCD:
|
||||
return 0x01D8;
|
||||
case OMAP_DSS_CHANNEL_DIGIT:
|
||||
BUG();
|
||||
case OMAP_DSS_CHANNEL_LCD2:
|
||||
return 0x03C4;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
static inline u16 DISPC_DATA_CYCLE3(enum omap_channel channel)
|
||||
{
|
||||
switch (channel) {
|
||||
case OMAP_DSS_CHANNEL_LCD:
|
||||
return 0x01DC;
|
||||
case OMAP_DSS_CHANNEL_DIGIT:
|
||||
BUG();
|
||||
case OMAP_DSS_CHANNEL_LCD2:
|
||||
return 0x03C8;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
static inline u16 DISPC_CPR_COEF_R(enum omap_channel channel)
|
||||
{
|
||||
switch (channel) {
|
||||
case OMAP_DSS_CHANNEL_LCD:
|
||||
return 0x0220;
|
||||
case OMAP_DSS_CHANNEL_DIGIT:
|
||||
BUG();
|
||||
case OMAP_DSS_CHANNEL_LCD2:
|
||||
return 0x03BC;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
static inline u16 DISPC_CPR_COEF_G(enum omap_channel channel)
|
||||
{
|
||||
switch (channel) {
|
||||
case OMAP_DSS_CHANNEL_LCD:
|
||||
return 0x0224;
|
||||
case OMAP_DSS_CHANNEL_DIGIT:
|
||||
BUG();
|
||||
case OMAP_DSS_CHANNEL_LCD2:
|
||||
return 0x03B8;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
static inline u16 DISPC_CPR_COEF_B(enum omap_channel channel)
|
||||
{
|
||||
switch (channel) {
|
||||
case OMAP_DSS_CHANNEL_LCD:
|
||||
return 0x0228;
|
||||
case OMAP_DSS_CHANNEL_DIGIT:
|
||||
BUG();
|
||||
case OMAP_DSS_CHANNEL_LCD2:
|
||||
return 0x03B4;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
/* DISPC overlay register base addresses */
|
||||
static inline u16 DISPC_OVL_BASE(enum omap_plane plane)
|
||||
{
|
||||
switch (plane) {
|
||||
case OMAP_DSS_GFX:
|
||||
return 0x0080;
|
||||
case OMAP_DSS_VIDEO1:
|
||||
return 0x00BC;
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x014C;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
/* DISPC overlay register offsets */
|
||||
static inline u16 DISPC_BA0_OFFSET(enum omap_plane plane)
|
||||
{
|
||||
switch (plane) {
|
||||
case OMAP_DSS_GFX:
|
||||
case OMAP_DSS_VIDEO1:
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x0000;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
static inline u16 DISPC_BA1_OFFSET(enum omap_plane plane)
|
||||
{
|
||||
switch (plane) {
|
||||
case OMAP_DSS_GFX:
|
||||
case OMAP_DSS_VIDEO1:
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x0004;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
static inline u16 DISPC_BA0_UV_OFFSET(enum omap_plane plane)
|
||||
{
|
||||
switch (plane) {
|
||||
case OMAP_DSS_GFX:
|
||||
BUG();
|
||||
case OMAP_DSS_VIDEO1:
|
||||
return 0x0544;
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x04BC;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
static inline u16 DISPC_BA1_UV_OFFSET(enum omap_plane plane)
|
||||
{
|
||||
switch (plane) {
|
||||
case OMAP_DSS_GFX:
|
||||
BUG();
|
||||
case OMAP_DSS_VIDEO1:
|
||||
return 0x0548;
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x04C0;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
static inline u16 DISPC_POS_OFFSET(enum omap_plane plane)
|
||||
{
|
||||
switch (plane) {
|
||||
case OMAP_DSS_GFX:
|
||||
case OMAP_DSS_VIDEO1:
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x0008;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
static inline u16 DISPC_SIZE_OFFSET(enum omap_plane plane)
|
||||
{
|
||||
switch (plane) {
|
||||
case OMAP_DSS_GFX:
|
||||
case OMAP_DSS_VIDEO1:
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x000C;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
static inline u16 DISPC_ATTR_OFFSET(enum omap_plane plane)
|
||||
{
|
||||
switch (plane) {
|
||||
case OMAP_DSS_GFX:
|
||||
return 0x0020;
|
||||
case OMAP_DSS_VIDEO1:
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x0010;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
static inline u16 DISPC_ATTR2_OFFSET(enum omap_plane plane)
|
||||
{
|
||||
switch (plane) {
|
||||
case OMAP_DSS_GFX:
|
||||
BUG();
|
||||
case OMAP_DSS_VIDEO1:
|
||||
return 0x0568;
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x04DC;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
static inline u16 DISPC_FIFO_THRESH_OFFSET(enum omap_plane plane)
|
||||
{
|
||||
switch (plane) {
|
||||
case OMAP_DSS_GFX:
|
||||
return 0x0024;
|
||||
case OMAP_DSS_VIDEO1:
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x0014;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
static inline u16 DISPC_FIFO_SIZE_STATUS_OFFSET(enum omap_plane plane)
|
||||
{
|
||||
switch (plane) {
|
||||
case OMAP_DSS_GFX:
|
||||
return 0x0028;
|
||||
case OMAP_DSS_VIDEO1:
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x0018;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
static inline u16 DISPC_ROW_INC_OFFSET(enum omap_plane plane)
|
||||
{
|
||||
switch (plane) {
|
||||
case OMAP_DSS_GFX:
|
||||
return 0x002C;
|
||||
case OMAP_DSS_VIDEO1:
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x001C;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
static inline u16 DISPC_PIX_INC_OFFSET(enum omap_plane plane)
|
||||
{
|
||||
switch (plane) {
|
||||
case OMAP_DSS_GFX:
|
||||
return 0x0030;
|
||||
case OMAP_DSS_VIDEO1:
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x0020;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
static inline u16 DISPC_WINDOW_SKIP_OFFSET(enum omap_plane plane)
|
||||
{
|
||||
switch (plane) {
|
||||
case OMAP_DSS_GFX:
|
||||
return 0x0034;
|
||||
case OMAP_DSS_VIDEO1:
|
||||
case OMAP_DSS_VIDEO2:
|
||||
BUG();
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
static inline u16 DISPC_TABLE_BA_OFFSET(enum omap_plane plane)
|
||||
{
|
||||
switch (plane) {
|
||||
case OMAP_DSS_GFX:
|
||||
return 0x0038;
|
||||
case OMAP_DSS_VIDEO1:
|
||||
case OMAP_DSS_VIDEO2:
|
||||
BUG();
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
static inline u16 DISPC_FIR_OFFSET(enum omap_plane plane)
|
||||
{
|
||||
switch (plane) {
|
||||
case OMAP_DSS_GFX:
|
||||
BUG();
|
||||
case OMAP_DSS_VIDEO1:
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x0024;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
static inline u16 DISPC_FIR2_OFFSET(enum omap_plane plane)
|
||||
{
|
||||
switch (plane) {
|
||||
case OMAP_DSS_GFX:
|
||||
BUG();
|
||||
case OMAP_DSS_VIDEO1:
|
||||
return 0x0580;
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x055C;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
static inline u16 DISPC_PIC_SIZE_OFFSET(enum omap_plane plane)
|
||||
{
|
||||
switch (plane) {
|
||||
case OMAP_DSS_GFX:
|
||||
BUG();
|
||||
case OMAP_DSS_VIDEO1:
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x0028;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static inline u16 DISPC_ACCU0_OFFSET(enum omap_plane plane)
|
||||
{
|
||||
switch (plane) {
|
||||
case OMAP_DSS_GFX:
|
||||
BUG();
|
||||
case OMAP_DSS_VIDEO1:
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x002C;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
static inline u16 DISPC_ACCU2_0_OFFSET(enum omap_plane plane)
|
||||
{
|
||||
switch (plane) {
|
||||
case OMAP_DSS_GFX:
|
||||
BUG();
|
||||
case OMAP_DSS_VIDEO1:
|
||||
return 0x0584;
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x0560;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
static inline u16 DISPC_ACCU1_OFFSET(enum omap_plane plane)
|
||||
{
|
||||
switch (plane) {
|
||||
case OMAP_DSS_GFX:
|
||||
BUG();
|
||||
case OMAP_DSS_VIDEO1:
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x0030;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
static inline u16 DISPC_ACCU2_1_OFFSET(enum omap_plane plane)
|
||||
{
|
||||
switch (plane) {
|
||||
case OMAP_DSS_GFX:
|
||||
BUG();
|
||||
case OMAP_DSS_VIDEO1:
|
||||
return 0x0588;
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x0564;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
/* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */
|
||||
static inline u16 DISPC_FIR_COEF_H_OFFSET(enum omap_plane plane, u16 i)
|
||||
{
|
||||
switch (plane) {
|
||||
case OMAP_DSS_GFX:
|
||||
BUG();
|
||||
case OMAP_DSS_VIDEO1:
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x0034 + i * 0x8;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
/* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */
|
||||
static inline u16 DISPC_FIR_COEF_H2_OFFSET(enum omap_plane plane, u16 i)
|
||||
{
|
||||
switch (plane) {
|
||||
case OMAP_DSS_GFX:
|
||||
BUG();
|
||||
case OMAP_DSS_VIDEO1:
|
||||
return 0x058C + i * 0x8;
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x0568 + i * 0x8;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
/* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */
|
||||
static inline u16 DISPC_FIR_COEF_HV_OFFSET(enum omap_plane plane, u16 i)
|
||||
{
|
||||
switch (plane) {
|
||||
case OMAP_DSS_GFX:
|
||||
BUG();
|
||||
case OMAP_DSS_VIDEO1:
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x0038 + i * 0x8;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
/* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */
|
||||
static inline u16 DISPC_FIR_COEF_HV2_OFFSET(enum omap_plane plane, u16 i)
|
||||
{
|
||||
switch (plane) {
|
||||
case OMAP_DSS_GFX:
|
||||
BUG();
|
||||
case OMAP_DSS_VIDEO1:
|
||||
return 0x0590 + i * 8;
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x056C + i * 0x8;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
/* coef index i = {0, 1, 2, 3, 4,} */
|
||||
static inline u16 DISPC_CONV_COEF_OFFSET(enum omap_plane plane, u16 i)
|
||||
{
|
||||
switch (plane) {
|
||||
case OMAP_DSS_GFX:
|
||||
BUG();
|
||||
case OMAP_DSS_VIDEO1:
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x0074 + i * 0x4;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
/* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */
|
||||
static inline u16 DISPC_FIR_COEF_V_OFFSET(enum omap_plane plane, u16 i)
|
||||
{
|
||||
switch (plane) {
|
||||
case OMAP_DSS_GFX:
|
||||
BUG();
|
||||
case OMAP_DSS_VIDEO1:
|
||||
return 0x0124 + i * 0x4;
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x00B4 + i * 0x4;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
/* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */
|
||||
static inline u16 DISPC_FIR_COEF_V2_OFFSET(enum omap_plane plane, u16 i)
|
||||
{
|
||||
switch (plane) {
|
||||
case OMAP_DSS_GFX:
|
||||
BUG();
|
||||
case OMAP_DSS_VIDEO1:
|
||||
return 0x05CC + i * 0x4;
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x05A8 + i * 0x4;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
static inline u16 DISPC_PRELOAD_OFFSET(enum omap_plane plane)
|
||||
{
|
||||
switch (plane) {
|
||||
case OMAP_DSS_GFX:
|
||||
return 0x01AC;
|
||||
case OMAP_DSS_VIDEO1:
|
||||
return 0x0174;
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x00E8;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -27,7 +27,7 @@
|
|||
#include <linux/jiffies.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include <plat/display.h>
|
||||
#include <video/omapdss.h>
|
||||
#include "dss.h"
|
||||
|
||||
static ssize_t display_enabled_show(struct device *dev,
|
||||
|
@ -44,9 +44,13 @@ static ssize_t display_enabled_store(struct device *dev,
|
|||
const char *buf, size_t size)
|
||||
{
|
||||
struct omap_dss_device *dssdev = to_dss_device(dev);
|
||||
bool enabled, r;
|
||||
int r, enabled;
|
||||
|
||||
enabled = simple_strtoul(buf, NULL, 10);
|
||||
r = kstrtoint(buf, 0, &enabled);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
enabled = !!enabled;
|
||||
|
||||
if (enabled != (dssdev->state != OMAP_DSS_DISPLAY_DISABLED)) {
|
||||
if (enabled) {
|
||||
|
@ -82,7 +86,9 @@ static ssize_t display_upd_mode_store(struct device *dev,
|
|||
if (!dssdev->driver->set_update_mode)
|
||||
return -EINVAL;
|
||||
|
||||
val = simple_strtoul(buf, NULL, 10);
|
||||
r = kstrtoint(buf, 0, &val);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
switch (val) {
|
||||
case OMAP_DSS_UPDATE_DISABLED:
|
||||
|
@ -114,13 +120,16 @@ static ssize_t display_tear_store(struct device *dev,
|
|||
struct device_attribute *attr, const char *buf, size_t size)
|
||||
{
|
||||
struct omap_dss_device *dssdev = to_dss_device(dev);
|
||||
unsigned long te;
|
||||
int r;
|
||||
int te, r;
|
||||
|
||||
if (!dssdev->driver->enable_te || !dssdev->driver->get_te)
|
||||
return -ENOENT;
|
||||
|
||||
te = simple_strtoul(buf, NULL, 0);
|
||||
r = kstrtoint(buf, 0, &te);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
te = !!te;
|
||||
|
||||
r = dssdev->driver->enable_te(dssdev, te);
|
||||
if (r)
|
||||
|
@ -196,13 +205,14 @@ static ssize_t display_rotate_store(struct device *dev,
|
|||
struct device_attribute *attr, const char *buf, size_t size)
|
||||
{
|
||||
struct omap_dss_device *dssdev = to_dss_device(dev);
|
||||
unsigned long rot;
|
||||
int r;
|
||||
int rot, r;
|
||||
|
||||
if (!dssdev->driver->set_rotate || !dssdev->driver->get_rotate)
|
||||
return -ENOENT;
|
||||
|
||||
rot = simple_strtoul(buf, NULL, 0);
|
||||
r = kstrtoint(buf, 0, &rot);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = dssdev->driver->set_rotate(dssdev, rot);
|
||||
if (r)
|
||||
|
@ -226,13 +236,16 @@ static ssize_t display_mirror_store(struct device *dev,
|
|||
struct device_attribute *attr, const char *buf, size_t size)
|
||||
{
|
||||
struct omap_dss_device *dssdev = to_dss_device(dev);
|
||||
unsigned long mirror;
|
||||
int r;
|
||||
int mirror, r;
|
||||
|
||||
if (!dssdev->driver->set_mirror || !dssdev->driver->get_mirror)
|
||||
return -ENOENT;
|
||||
|
||||
mirror = simple_strtoul(buf, NULL, 0);
|
||||
r = kstrtoint(buf, 0, &mirror);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
mirror = !!mirror;
|
||||
|
||||
r = dssdev->driver->set_mirror(dssdev, mirror);
|
||||
if (r)
|
||||
|
@ -259,14 +272,15 @@ static ssize_t display_wss_store(struct device *dev,
|
|||
struct device_attribute *attr, const char *buf, size_t size)
|
||||
{
|
||||
struct omap_dss_device *dssdev = to_dss_device(dev);
|
||||
unsigned long wss;
|
||||
u32 wss;
|
||||
int r;
|
||||
|
||||
if (!dssdev->driver->get_wss || !dssdev->driver->set_wss)
|
||||
return -ENOENT;
|
||||
|
||||
if (strict_strtoul(buf, 0, &wss))
|
||||
return -EINVAL;
|
||||
r = kstrtou32(buf, 0, &wss);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (wss > 0xfffff)
|
||||
return -EINVAL;
|
||||
|
|
|
@ -30,16 +30,40 @@
|
|||
#include <linux/platform_device.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
||||
#include <plat/display.h>
|
||||
#include <video/omapdss.h>
|
||||
#include <plat/cpu.h>
|
||||
|
||||
#include "dss.h"
|
||||
|
||||
static struct {
|
||||
struct regulator *vdds_dsi_reg;
|
||||
struct platform_device *dsidev;
|
||||
} dpi;
|
||||
|
||||
#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
|
||||
static struct platform_device *dpi_get_dsidev(enum omap_dss_clk_source clk)
|
||||
{
|
||||
int dsi_module;
|
||||
|
||||
dsi_module = clk == OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC ? 0 : 1;
|
||||
|
||||
return dsi_get_dsidev_from_id(dsi_module);
|
||||
}
|
||||
|
||||
static bool dpi_use_dsi_pll(struct omap_dss_device *dssdev)
|
||||
{
|
||||
if (dssdev->clocks.dispc.dispc_fclk_src ==
|
||||
OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC ||
|
||||
dssdev->clocks.dispc.dispc_fclk_src ==
|
||||
OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC ||
|
||||
dssdev->clocks.dispc.channel.lcd_clk_src ==
|
||||
OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC ||
|
||||
dssdev->clocks.dispc.channel.lcd_clk_src ==
|
||||
OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
static int dpi_set_dsi_clk(struct omap_dss_device *dssdev, bool is_tft,
|
||||
unsigned long pck_req, unsigned long *fck, int *lck_div,
|
||||
int *pck_div)
|
||||
|
@ -48,16 +72,16 @@ static int dpi_set_dsi_clk(struct omap_dss_device *dssdev, bool is_tft,
|
|||
struct dispc_clock_info dispc_cinfo;
|
||||
int r;
|
||||
|
||||
r = dsi_pll_calc_clock_div_pck(is_tft, pck_req, &dsi_cinfo,
|
||||
&dispc_cinfo);
|
||||
r = dsi_pll_calc_clock_div_pck(dpi.dsidev, is_tft, pck_req,
|
||||
&dsi_cinfo, &dispc_cinfo);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = dsi_pll_set_clock_div(&dsi_cinfo);
|
||||
r = dsi_pll_set_clock_div(dpi.dsidev, &dsi_cinfo);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
dss_select_dispc_clk_source(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC);
|
||||
dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src);
|
||||
|
||||
r = dispc_set_clock_div(dssdev->manager->id, &dispc_cinfo);
|
||||
if (r)
|
||||
|
@ -69,7 +93,7 @@ static int dpi_set_dsi_clk(struct omap_dss_device *dssdev, bool is_tft,
|
|||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
|
||||
static int dpi_set_dispc_clk(struct omap_dss_device *dssdev, bool is_tft,
|
||||
unsigned long pck_req, unsigned long *fck, int *lck_div,
|
||||
int *pck_div)
|
||||
|
@ -96,13 +120,12 @@ static int dpi_set_dispc_clk(struct omap_dss_device *dssdev, bool is_tft,
|
|||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int dpi_set_mode(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct omap_video_timings *t = &dssdev->panel.timings;
|
||||
int lck_div, pck_div;
|
||||
unsigned long fck;
|
||||
int lck_div = 0, pck_div = 0;
|
||||
unsigned long fck = 0;
|
||||
unsigned long pck;
|
||||
bool is_tft;
|
||||
int r = 0;
|
||||
|
@ -114,13 +137,12 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
|
|||
|
||||
is_tft = (dssdev->panel.config & OMAP_DSS_LCD_TFT) != 0;
|
||||
|
||||
#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
|
||||
r = dpi_set_dsi_clk(dssdev, is_tft, t->pixel_clock * 1000, &fck,
|
||||
&lck_div, &pck_div);
|
||||
#else
|
||||
r = dpi_set_dispc_clk(dssdev, is_tft, t->pixel_clock * 1000, &fck,
|
||||
&lck_div, &pck_div);
|
||||
#endif
|
||||
if (dpi_use_dsi_pll(dssdev))
|
||||
r = dpi_set_dsi_clk(dssdev, is_tft, t->pixel_clock * 1000,
|
||||
&fck, &lck_div, &pck_div);
|
||||
else
|
||||
r = dpi_set_dispc_clk(dssdev, is_tft, t->pixel_clock * 1000,
|
||||
&fck, &lck_div, &pck_div);
|
||||
if (r)
|
||||
goto err0;
|
||||
|
||||
|
@ -179,12 +201,13 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
|
|||
if (r)
|
||||
goto err2;
|
||||
|
||||
#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
|
||||
dss_clk_enable(DSS_CLK_SYSCK);
|
||||
r = dsi_pll_init(dssdev, 0, 1);
|
||||
if (r)
|
||||
goto err3;
|
||||
#endif
|
||||
if (dpi_use_dsi_pll(dssdev)) {
|
||||
dss_clk_enable(DSS_CLK_SYSCK);
|
||||
r = dsi_pll_init(dpi.dsidev, 0, 1);
|
||||
if (r)
|
||||
goto err3;
|
||||
}
|
||||
|
||||
r = dpi_set_mode(dssdev);
|
||||
if (r)
|
||||
goto err4;
|
||||
|
@ -196,11 +219,11 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
|
|||
return 0;
|
||||
|
||||
err4:
|
||||
#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
|
||||
dsi_pll_uninit();
|
||||
if (dpi_use_dsi_pll(dssdev))
|
||||
dsi_pll_uninit(dpi.dsidev, true);
|
||||
err3:
|
||||
dss_clk_disable(DSS_CLK_SYSCK);
|
||||
#endif
|
||||
if (dpi_use_dsi_pll(dssdev))
|
||||
dss_clk_disable(DSS_CLK_SYSCK);
|
||||
err2:
|
||||
dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
|
||||
if (cpu_is_omap34xx())
|
||||
|
@ -216,11 +239,11 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
|
|||
{
|
||||
dssdev->manager->disable(dssdev->manager);
|
||||
|
||||
#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
|
||||
dss_select_dispc_clk_source(DSS_CLK_SRC_FCK);
|
||||
dsi_pll_uninit();
|
||||
dss_clk_disable(DSS_CLK_SYSCK);
|
||||
#endif
|
||||
if (dpi_use_dsi_pll(dssdev)) {
|
||||
dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
|
||||
dsi_pll_uninit(dpi.dsidev, true);
|
||||
dss_clk_disable(DSS_CLK_SYSCK);
|
||||
}
|
||||
|
||||
dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
|
||||
|
||||
|
@ -251,6 +274,7 @@ int dpi_check_timings(struct omap_dss_device *dssdev,
|
|||
int lck_div, pck_div;
|
||||
unsigned long fck;
|
||||
unsigned long pck;
|
||||
struct dispc_clock_info dispc_cinfo;
|
||||
|
||||
if (!dispc_lcd_timings_ok(timings))
|
||||
return -EINVAL;
|
||||
|
@ -260,11 +284,9 @@ int dpi_check_timings(struct omap_dss_device *dssdev,
|
|||
|
||||
is_tft = (dssdev->panel.config & OMAP_DSS_LCD_TFT) != 0;
|
||||
|
||||
#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
|
||||
{
|
||||
if (dpi_use_dsi_pll(dssdev)) {
|
||||
struct dsi_clock_info dsi_cinfo;
|
||||
struct dispc_clock_info dispc_cinfo;
|
||||
r = dsi_pll_calc_clock_div_pck(is_tft,
|
||||
r = dsi_pll_calc_clock_div_pck(dpi.dsidev, is_tft,
|
||||
timings->pixel_clock * 1000,
|
||||
&dsi_cinfo, &dispc_cinfo);
|
||||
|
||||
|
@ -272,13 +294,8 @@ int dpi_check_timings(struct omap_dss_device *dssdev,
|
|||
return r;
|
||||
|
||||
fck = dsi_cinfo.dsi_pll_hsdiv_dispc_clk;
|
||||
lck_div = dispc_cinfo.lck_div;
|
||||
pck_div = dispc_cinfo.pck_div;
|
||||
}
|
||||
#else
|
||||
{
|
||||
} else {
|
||||
struct dss_clock_info dss_cinfo;
|
||||
struct dispc_clock_info dispc_cinfo;
|
||||
r = dss_calc_clock_div(is_tft, timings->pixel_clock * 1000,
|
||||
&dss_cinfo, &dispc_cinfo);
|
||||
|
||||
|
@ -286,10 +303,10 @@ int dpi_check_timings(struct omap_dss_device *dssdev,
|
|||
return r;
|
||||
|
||||
fck = dss_cinfo.fck;
|
||||
lck_div = dispc_cinfo.lck_div;
|
||||
pck_div = dispc_cinfo.pck_div;
|
||||
}
|
||||
#endif
|
||||
|
||||
lck_div = dispc_cinfo.lck_div;
|
||||
pck_div = dispc_cinfo.pck_div;
|
||||
|
||||
pck = fck / lck_div / pck_div / 1000;
|
||||
|
||||
|
@ -316,6 +333,12 @@ int dpi_init_display(struct omap_dss_device *dssdev)
|
|||
dpi.vdds_dsi_reg = vdds_dsi;
|
||||
}
|
||||
|
||||
if (dpi_use_dsi_pll(dssdev)) {
|
||||
enum omap_dss_clk_source dispc_fclk_src =
|
||||
dssdev->clocks.dispc.dispc_fclk_src;
|
||||
dpi.dsidev = dpi_get_dsidev(dispc_fclk_src);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -29,7 +29,7 @@
|
|||
#include <linux/seq_file.h>
|
||||
#include <linux/clk.h>
|
||||
|
||||
#include <plat/display.h>
|
||||
#include <video/omapdss.h>
|
||||
#include <plat/clock.h>
|
||||
#include "dss.h"
|
||||
#include "dss_features.h"
|
||||
|
@ -45,7 +45,6 @@ struct dss_reg {
|
|||
#define DSS_REVISION DSS_REG(0x0000)
|
||||
#define DSS_SYSCONFIG DSS_REG(0x0010)
|
||||
#define DSS_SYSSTATUS DSS_REG(0x0014)
|
||||
#define DSS_IRQSTATUS DSS_REG(0x0018)
|
||||
#define DSS_CONTROL DSS_REG(0x0040)
|
||||
#define DSS_SDI_CONTROL DSS_REG(0x0044)
|
||||
#define DSS_PLL_CONTROL DSS_REG(0x0048)
|
||||
|
@ -75,17 +74,17 @@ static struct {
|
|||
struct dss_clock_info cache_dss_cinfo;
|
||||
struct dispc_clock_info cache_dispc_cinfo;
|
||||
|
||||
enum dss_clk_source dsi_clk_source;
|
||||
enum dss_clk_source dispc_clk_source;
|
||||
enum dss_clk_source lcd_clk_source[MAX_DSS_LCD_MANAGERS];
|
||||
enum omap_dss_clk_source dsi_clk_source[MAX_NUM_DSI];
|
||||
enum omap_dss_clk_source dispc_clk_source;
|
||||
enum omap_dss_clk_source lcd_clk_source[MAX_DSS_LCD_MANAGERS];
|
||||
|
||||
u32 ctx[DSS_SZ_REGS / sizeof(u32)];
|
||||
} dss;
|
||||
|
||||
static const char * const dss_generic_clk_source_names[] = {
|
||||
[DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "DSI_PLL_HSDIV_DISPC",
|
||||
[DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "DSI_PLL_HSDIV_DSI",
|
||||
[DSS_CLK_SRC_FCK] = "DSS_FCK",
|
||||
[OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "DSI_PLL_HSDIV_DISPC",
|
||||
[OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "DSI_PLL_HSDIV_DSI",
|
||||
[OMAP_DSS_CLK_SRC_FCK] = "DSS_FCK",
|
||||
};
|
||||
|
||||
static void dss_clk_enable_all_no_ctx(void);
|
||||
|
@ -230,7 +229,7 @@ void dss_sdi_disable(void)
|
|||
REG_FLD_MOD(DSS_PLL_CONTROL, 0, 18, 18); /* SDI_PLL_SYSRESET */
|
||||
}
|
||||
|
||||
const char *dss_get_generic_clk_source_name(enum dss_clk_source clk_src)
|
||||
const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src)
|
||||
{
|
||||
return dss_generic_clk_source_names[clk_src];
|
||||
}
|
||||
|
@ -246,8 +245,8 @@ void dss_dump_clocks(struct seq_file *s)
|
|||
|
||||
seq_printf(s, "- DSS -\n");
|
||||
|
||||
fclk_name = dss_get_generic_clk_source_name(DSS_CLK_SRC_FCK);
|
||||
fclk_real_name = dss_feat_get_clk_source_name(DSS_CLK_SRC_FCK);
|
||||
fclk_name = dss_get_generic_clk_source_name(OMAP_DSS_CLK_SRC_FCK);
|
||||
fclk_real_name = dss_feat_get_clk_source_name(OMAP_DSS_CLK_SRC_FCK);
|
||||
fclk_rate = dss_clk_get_rate(DSS_CLK_FCK);
|
||||
|
||||
if (dss.dpll4_m4_ck) {
|
||||
|
@ -286,7 +285,6 @@ void dss_dump_regs(struct seq_file *s)
|
|||
DUMPREG(DSS_REVISION);
|
||||
DUMPREG(DSS_SYSCONFIG);
|
||||
DUMPREG(DSS_SYSSTATUS);
|
||||
DUMPREG(DSS_IRQSTATUS);
|
||||
DUMPREG(DSS_CONTROL);
|
||||
|
||||
if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) &
|
||||
|
@ -300,18 +298,25 @@ void dss_dump_regs(struct seq_file *s)
|
|||
#undef DUMPREG
|
||||
}
|
||||
|
||||
void dss_select_dispc_clk_source(enum dss_clk_source clk_src)
|
||||
void dss_select_dispc_clk_source(enum omap_dss_clk_source clk_src)
|
||||
{
|
||||
struct platform_device *dsidev;
|
||||
int b;
|
||||
u8 start, end;
|
||||
|
||||
switch (clk_src) {
|
||||
case DSS_CLK_SRC_FCK:
|
||||
case OMAP_DSS_CLK_SRC_FCK:
|
||||
b = 0;
|
||||
break;
|
||||
case DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
|
||||
case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
|
||||
b = 1;
|
||||
dsi_wait_pll_hsdiv_dispc_active();
|
||||
dsidev = dsi_get_dsidev_from_id(0);
|
||||
dsi_wait_pll_hsdiv_dispc_active(dsidev);
|
||||
break;
|
||||
case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
|
||||
b = 2;
|
||||
dsidev = dsi_get_dsidev_from_id(1);
|
||||
dsi_wait_pll_hsdiv_dispc_active(dsidev);
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
|
@ -324,17 +329,27 @@ void dss_select_dispc_clk_source(enum dss_clk_source clk_src)
|
|||
dss.dispc_clk_source = clk_src;
|
||||
}
|
||||
|
||||
void dss_select_dsi_clk_source(enum dss_clk_source clk_src)
|
||||
void dss_select_dsi_clk_source(int dsi_module,
|
||||
enum omap_dss_clk_source clk_src)
|
||||
{
|
||||
struct platform_device *dsidev;
|
||||
int b;
|
||||
|
||||
switch (clk_src) {
|
||||
case DSS_CLK_SRC_FCK:
|
||||
case OMAP_DSS_CLK_SRC_FCK:
|
||||
b = 0;
|
||||
break;
|
||||
case DSS_CLK_SRC_DSI_PLL_HSDIV_DSI:
|
||||
case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI:
|
||||
BUG_ON(dsi_module != 0);
|
||||
b = 1;
|
||||
dsi_wait_pll_hsdiv_dsi_active();
|
||||
dsidev = dsi_get_dsidev_from_id(0);
|
||||
dsi_wait_pll_hsdiv_dsi_active(dsidev);
|
||||
break;
|
||||
case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI:
|
||||
BUG_ON(dsi_module != 1);
|
||||
b = 1;
|
||||
dsidev = dsi_get_dsidev_from_id(1);
|
||||
dsi_wait_pll_hsdiv_dsi_active(dsidev);
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
|
@ -342,25 +357,33 @@ void dss_select_dsi_clk_source(enum dss_clk_source clk_src)
|
|||
|
||||
REG_FLD_MOD(DSS_CONTROL, b, 1, 1); /* DSI_CLK_SWITCH */
|
||||
|
||||
dss.dsi_clk_source = clk_src;
|
||||
dss.dsi_clk_source[dsi_module] = clk_src;
|
||||
}
|
||||
|
||||
void dss_select_lcd_clk_source(enum omap_channel channel,
|
||||
enum dss_clk_source clk_src)
|
||||
enum omap_dss_clk_source clk_src)
|
||||
{
|
||||
struct platform_device *dsidev;
|
||||
int b, ix, pos;
|
||||
|
||||
if (!dss_has_feature(FEAT_LCD_CLK_SRC))
|
||||
return;
|
||||
|
||||
switch (clk_src) {
|
||||
case DSS_CLK_SRC_FCK:
|
||||
case OMAP_DSS_CLK_SRC_FCK:
|
||||
b = 0;
|
||||
break;
|
||||
case DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
|
||||
case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
|
||||
BUG_ON(channel != OMAP_DSS_CHANNEL_LCD);
|
||||
b = 1;
|
||||
dsi_wait_pll_hsdiv_dispc_active();
|
||||
dsidev = dsi_get_dsidev_from_id(0);
|
||||
dsi_wait_pll_hsdiv_dispc_active(dsidev);
|
||||
break;
|
||||
case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
|
||||
BUG_ON(channel != OMAP_DSS_CHANNEL_LCD2);
|
||||
b = 1;
|
||||
dsidev = dsi_get_dsidev_from_id(1);
|
||||
dsi_wait_pll_hsdiv_dispc_active(dsidev);
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
|
@ -373,17 +396,17 @@ void dss_select_lcd_clk_source(enum omap_channel channel,
|
|||
dss.lcd_clk_source[ix] = clk_src;
|
||||
}
|
||||
|
||||
enum dss_clk_source dss_get_dispc_clk_source(void)
|
||||
enum omap_dss_clk_source dss_get_dispc_clk_source(void)
|
||||
{
|
||||
return dss.dispc_clk_source;
|
||||
}
|
||||
|
||||
enum dss_clk_source dss_get_dsi_clk_source(void)
|
||||
enum omap_dss_clk_source dss_get_dsi_clk_source(int dsi_module)
|
||||
{
|
||||
return dss.dsi_clk_source;
|
||||
return dss.dsi_clk_source[dsi_module];
|
||||
}
|
||||
|
||||
enum dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel)
|
||||
enum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel)
|
||||
{
|
||||
if (dss_has_feature(FEAT_LCD_CLK_SRC)) {
|
||||
int ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 1;
|
||||
|
@ -665,13 +688,18 @@ static int dss_init(void)
|
|||
* the kernel resets it */
|
||||
omap_writel(omap_readl(0x48050440) & ~0x3, 0x48050440);
|
||||
|
||||
#ifdef CONFIG_OMAP2_DSS_SLEEP_BEFORE_RESET
|
||||
/* We need to wait here a bit, otherwise we sometimes start to
|
||||
* get synclost errors, and after that only power cycle will
|
||||
* restore DSS functionality. I have no idea why this happens.
|
||||
* And we have to wait _before_ resetting the DSS, but after
|
||||
* enabling clocks.
|
||||
*
|
||||
* This bug was at least present on OMAP3430. It's unknown
|
||||
* if it happens on OMAP2 or OMAP3630.
|
||||
*/
|
||||
msleep(50);
|
||||
#endif
|
||||
|
||||
_omap_dss_reset();
|
||||
|
||||
|
@ -706,10 +734,11 @@ static int dss_init(void)
|
|||
|
||||
dss.dpll4_m4_ck = dpll4_m4_ck;
|
||||
|
||||
dss.dsi_clk_source = DSS_CLK_SRC_FCK;
|
||||
dss.dispc_clk_source = DSS_CLK_SRC_FCK;
|
||||
dss.lcd_clk_source[0] = DSS_CLK_SRC_FCK;
|
||||
dss.lcd_clk_source[1] = DSS_CLK_SRC_FCK;
|
||||
dss.dsi_clk_source[0] = OMAP_DSS_CLK_SRC_FCK;
|
||||
dss.dsi_clk_source[1] = OMAP_DSS_CLK_SRC_FCK;
|
||||
dss.dispc_clk_source = OMAP_DSS_CLK_SRC_FCK;
|
||||
dss.lcd_clk_source[0] = OMAP_DSS_CLK_SRC_FCK;
|
||||
dss.lcd_clk_source[1] = OMAP_DSS_CLK_SRC_FCK;
|
||||
|
||||
dss_save_context();
|
||||
|
||||
|
@ -1021,6 +1050,14 @@ static void core_dump_clocks(struct seq_file *s)
|
|||
dss.dss_video_fck
|
||||
};
|
||||
|
||||
const char *names[5] = {
|
||||
"ick",
|
||||
"fck",
|
||||
"sys_clk",
|
||||
"tv_fck",
|
||||
"video_fck"
|
||||
};
|
||||
|
||||
seq_printf(s, "- CORE -\n");
|
||||
|
||||
seq_printf(s, "internal clk count\t\t%u\n", dss.num_clks_enabled);
|
||||
|
@ -1028,8 +1065,11 @@ static void core_dump_clocks(struct seq_file *s)
|
|||
for (i = 0; i < 5; i++) {
|
||||
if (!clocks[i])
|
||||
continue;
|
||||
seq_printf(s, "%-15s\t%lu\t%d\n",
|
||||
seq_printf(s, "%s (%s)%*s\t%lu\t%d\n",
|
||||
names[i],
|
||||
clocks[i]->name,
|
||||
24 - strlen(names[i]) - strlen(clocks[i]->name),
|
||||
"",
|
||||
clk_get_rate(clocks[i]),
|
||||
clocks[i]->usecount);
|
||||
}
|
||||
|
|
|
@ -117,15 +117,6 @@ enum dss_clock {
|
|||
DSS_CLK_VIDFCK = 1 << 4, /* DSS_96M_FCLK*/
|
||||
};
|
||||
|
||||
enum dss_clk_source {
|
||||
DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC, /* OMAP3: DSI1_PLL_FCLK
|
||||
* OMAP4: PLL1_CLK1 */
|
||||
DSS_CLK_SRC_DSI_PLL_HSDIV_DSI, /* OMAP3: DSI2_PLL_FCLK
|
||||
* OMAP4: PLL1_CLK2 */
|
||||
DSS_CLK_SRC_FCK, /* OMAP2/3: DSS1_ALWON_FCLK
|
||||
* OMAP4: DSS_FCLK */
|
||||
};
|
||||
|
||||
enum dss_hdmi_venc_clk_source_select {
|
||||
DSS_VENC_TV_CLK = 0,
|
||||
DSS_HDMI_M_PCLK = 1,
|
||||
|
@ -236,7 +227,7 @@ void dss_clk_enable(enum dss_clock clks);
|
|||
void dss_clk_disable(enum dss_clock clks);
|
||||
unsigned long dss_clk_get_rate(enum dss_clock clk);
|
||||
int dss_need_ctx_restore(void);
|
||||
const char *dss_get_generic_clk_source_name(enum dss_clk_source clk_src);
|
||||
const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src);
|
||||
void dss_dump_clocks(struct seq_file *s);
|
||||
|
||||
void dss_dump_regs(struct seq_file *s);
|
||||
|
@ -248,13 +239,14 @@ void dss_sdi_init(u8 datapairs);
|
|||
int dss_sdi_enable(void);
|
||||
void dss_sdi_disable(void);
|
||||
|
||||
void dss_select_dispc_clk_source(enum dss_clk_source clk_src);
|
||||
void dss_select_dsi_clk_source(enum dss_clk_source clk_src);
|
||||
void dss_select_dispc_clk_source(enum omap_dss_clk_source clk_src);
|
||||
void dss_select_dsi_clk_source(int dsi_module,
|
||||
enum omap_dss_clk_source clk_src);
|
||||
void dss_select_lcd_clk_source(enum omap_channel channel,
|
||||
enum dss_clk_source clk_src);
|
||||
enum dss_clk_source dss_get_dispc_clk_source(void);
|
||||
enum dss_clk_source dss_get_dsi_clk_source(void);
|
||||
enum dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel);
|
||||
enum omap_dss_clk_source clk_src);
|
||||
enum omap_dss_clk_source dss_get_dispc_clk_source(void);
|
||||
enum omap_dss_clk_source dss_get_dsi_clk_source(int dsi_module);
|
||||
enum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel);
|
||||
|
||||
void dss_set_venc_output(enum omap_dss_venc_type type);
|
||||
void dss_set_dac_pwrdn_bgz(bool enable);
|
||||
|
@ -284,31 +276,39 @@ static inline void sdi_exit(void)
|
|||
|
||||
/* DSI */
|
||||
#ifdef CONFIG_OMAP2_DSS_DSI
|
||||
|
||||
struct dentry;
|
||||
struct file_operations;
|
||||
|
||||
int dsi_init_platform_driver(void);
|
||||
void dsi_uninit_platform_driver(void);
|
||||
|
||||
void dsi_dump_clocks(struct seq_file *s);
|
||||
void dsi_dump_irqs(struct seq_file *s);
|
||||
void dsi_dump_regs(struct seq_file *s);
|
||||
void dsi_create_debugfs_files_irq(struct dentry *debugfs_dir,
|
||||
const struct file_operations *debug_fops);
|
||||
void dsi_create_debugfs_files_reg(struct dentry *debugfs_dir,
|
||||
const struct file_operations *debug_fops);
|
||||
|
||||
void dsi_save_context(void);
|
||||
void dsi_restore_context(void);
|
||||
|
||||
int dsi_init_display(struct omap_dss_device *display);
|
||||
void dsi_irq_handler(void);
|
||||
unsigned long dsi_get_pll_hsdiv_dispc_rate(void);
|
||||
int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo);
|
||||
int dsi_pll_calc_clock_div_pck(bool is_tft, unsigned long req_pck,
|
||||
struct dsi_clock_info *cinfo,
|
||||
unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev);
|
||||
int dsi_pll_set_clock_div(struct platform_device *dsidev,
|
||||
struct dsi_clock_info *cinfo);
|
||||
int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev, bool is_tft,
|
||||
unsigned long req_pck, struct dsi_clock_info *cinfo,
|
||||
struct dispc_clock_info *dispc_cinfo);
|
||||
int dsi_pll_init(struct omap_dss_device *dssdev, bool enable_hsclk,
|
||||
int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk,
|
||||
bool enable_hsdiv);
|
||||
void dsi_pll_uninit(void);
|
||||
void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes);
|
||||
void dsi_get_overlay_fifo_thresholds(enum omap_plane plane,
|
||||
u32 fifo_size, enum omap_burst_size *burst_size,
|
||||
u32 *fifo_low, u32 *fifo_high);
|
||||
void dsi_wait_pll_hsdiv_dispc_active(void);
|
||||
void dsi_wait_pll_hsdiv_dsi_active(void);
|
||||
void dsi_wait_pll_hsdiv_dispc_active(struct platform_device *dsidev);
|
||||
void dsi_wait_pll_hsdiv_dsi_active(struct platform_device *dsidev);
|
||||
struct platform_device *dsi_get_dsidev_from_id(int module);
|
||||
#else
|
||||
static inline int dsi_init_platform_driver(void)
|
||||
{
|
||||
|
@ -317,17 +317,47 @@ static inline int dsi_init_platform_driver(void)
|
|||
static inline void dsi_uninit_platform_driver(void)
|
||||
{
|
||||
}
|
||||
static inline unsigned long dsi_get_pll_hsdiv_dispc_rate(void)
|
||||
static inline unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev)
|
||||
{
|
||||
WARN("%s: DSI not compiled in, returning rate as 0\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
static inline void dsi_wait_pll_hsdiv_dispc_active(void)
|
||||
static inline int dsi_pll_set_clock_div(struct platform_device *dsidev,
|
||||
struct dsi_clock_info *cinfo)
|
||||
{
|
||||
WARN("%s: DSI not compiled in\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
static inline int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev,
|
||||
bool is_tft, unsigned long req_pck,
|
||||
struct dsi_clock_info *dsi_cinfo,
|
||||
struct dispc_clock_info *dispc_cinfo)
|
||||
{
|
||||
WARN("%s: DSI not compiled in\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
static inline int dsi_pll_init(struct platform_device *dsidev,
|
||||
bool enable_hsclk, bool enable_hsdiv)
|
||||
{
|
||||
WARN("%s: DSI not compiled in\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
static inline void dsi_pll_uninit(struct platform_device *dsidev,
|
||||
bool disconnect_lanes)
|
||||
{
|
||||
}
|
||||
static inline void dsi_wait_pll_hsdiv_dsi_active(void)
|
||||
static inline void dsi_wait_pll_hsdiv_dispc_active(struct platform_device *dsidev)
|
||||
{
|
||||
}
|
||||
static inline void dsi_wait_pll_hsdiv_dsi_active(struct platform_device *dsidev)
|
||||
{
|
||||
}
|
||||
static inline struct platform_device *dsi_get_dsidev_from_id(int module)
|
||||
{
|
||||
WARN("%s: DSI not compiled in, returning platform device as NULL\n",
|
||||
__func__);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* DPI */
|
||||
|
@ -391,7 +421,8 @@ int dispc_setup_plane(enum omap_plane plane,
|
|||
enum omap_dss_rotation_type rotation_type,
|
||||
u8 rotation, bool mirror,
|
||||
u8 global_alpha, u8 pre_mult_alpha,
|
||||
enum omap_channel channel);
|
||||
enum omap_channel channel,
|
||||
u32 puv_addr);
|
||||
|
||||
bool dispc_go_busy(enum omap_channel channel);
|
||||
void dispc_go(enum omap_channel channel);
|
||||
|
@ -485,13 +516,6 @@ void hdmi_panel_exit(void);
|
|||
int rfbi_init_platform_driver(void);
|
||||
void rfbi_uninit_platform_driver(void);
|
||||
void rfbi_dump_regs(struct seq_file *s);
|
||||
|
||||
int rfbi_configure(int rfbi_module, int bpp, int lines);
|
||||
void rfbi_enable_rfbi(bool enable);
|
||||
void rfbi_transfer_area(struct omap_dss_device *dssdev, u16 width,
|
||||
u16 height, void (callback)(void *data), void *data);
|
||||
void rfbi_set_timings(int rfbi_module, struct rfbi_timings *t);
|
||||
unsigned long rfbi_get_max_tx_rate(void);
|
||||
int rfbi_init_display(struct omap_dss_device *display);
|
||||
#else
|
||||
static inline int rfbi_init_platform_driver(void)
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include <linux/err.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <plat/display.h>
|
||||
#include <video/omapdss.h>
|
||||
#include <plat/cpu.h>
|
||||
|
||||
#include "dss.h"
|
||||
|
@ -52,7 +52,7 @@ struct omap_dss_features {
|
|||
};
|
||||
|
||||
/* This struct is assigned to one of the below during initialization */
|
||||
static struct omap_dss_features *omap_current_dss_features;
|
||||
static const struct omap_dss_features *omap_current_dss_features;
|
||||
|
||||
static const struct dss_reg_field omap2_dss_reg_fields[] = {
|
||||
[FEAT_REG_FIRHINC] = { 11, 0 },
|
||||
|
@ -177,22 +177,55 @@ static const enum omap_color_mode omap3_dss_supported_color_modes[] = {
|
|||
OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_RGBX32,
|
||||
};
|
||||
|
||||
static const enum omap_color_mode omap4_dss_supported_color_modes[] = {
|
||||
/* OMAP_DSS_GFX */
|
||||
OMAP_DSS_COLOR_CLUT1 | OMAP_DSS_COLOR_CLUT2 |
|
||||
OMAP_DSS_COLOR_CLUT4 | OMAP_DSS_COLOR_CLUT8 |
|
||||
OMAP_DSS_COLOR_RGB12U | OMAP_DSS_COLOR_ARGB16 |
|
||||
OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB24U |
|
||||
OMAP_DSS_COLOR_RGB24P | OMAP_DSS_COLOR_ARGB32 |
|
||||
OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_RGBX32 |
|
||||
OMAP_DSS_COLOR_ARGB16_1555,
|
||||
|
||||
/* OMAP_DSS_VIDEO1 */
|
||||
OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB12U |
|
||||
OMAP_DSS_COLOR_YUV2 | OMAP_DSS_COLOR_ARGB16_1555 |
|
||||
OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_NV12 |
|
||||
OMAP_DSS_COLOR_RGBA16 | OMAP_DSS_COLOR_RGB24U |
|
||||
OMAP_DSS_COLOR_RGB24P | OMAP_DSS_COLOR_UYVY |
|
||||
OMAP_DSS_COLOR_ARGB16 | OMAP_DSS_COLOR_XRGB16_1555 |
|
||||
OMAP_DSS_COLOR_ARGB32 | OMAP_DSS_COLOR_RGBX16 |
|
||||
OMAP_DSS_COLOR_RGBX32,
|
||||
|
||||
/* OMAP_DSS_VIDEO2 */
|
||||
OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB12U |
|
||||
OMAP_DSS_COLOR_YUV2 | OMAP_DSS_COLOR_ARGB16_1555 |
|
||||
OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_NV12 |
|
||||
OMAP_DSS_COLOR_RGBA16 | OMAP_DSS_COLOR_RGB24U |
|
||||
OMAP_DSS_COLOR_RGB24P | OMAP_DSS_COLOR_UYVY |
|
||||
OMAP_DSS_COLOR_ARGB16 | OMAP_DSS_COLOR_XRGB16_1555 |
|
||||
OMAP_DSS_COLOR_ARGB32 | OMAP_DSS_COLOR_RGBX16 |
|
||||
OMAP_DSS_COLOR_RGBX32,
|
||||
};
|
||||
|
||||
static const char * const omap2_dss_clk_source_names[] = {
|
||||
[DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "N/A",
|
||||
[DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "N/A",
|
||||
[DSS_CLK_SRC_FCK] = "DSS_FCLK1",
|
||||
[OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "N/A",
|
||||
[OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "N/A",
|
||||
[OMAP_DSS_CLK_SRC_FCK] = "DSS_FCLK1",
|
||||
};
|
||||
|
||||
static const char * const omap3_dss_clk_source_names[] = {
|
||||
[DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "DSI1_PLL_FCLK",
|
||||
[DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "DSI2_PLL_FCLK",
|
||||
[DSS_CLK_SRC_FCK] = "DSS1_ALWON_FCLK",
|
||||
[OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "DSI1_PLL_FCLK",
|
||||
[OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "DSI2_PLL_FCLK",
|
||||
[OMAP_DSS_CLK_SRC_FCK] = "DSS1_ALWON_FCLK",
|
||||
};
|
||||
|
||||
static const char * const omap4_dss_clk_source_names[] = {
|
||||
[DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "PLL1_CLK1",
|
||||
[DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "PLL1_CLK2",
|
||||
[DSS_CLK_SRC_FCK] = "DSS_FCLK",
|
||||
[OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "PLL1_CLK1",
|
||||
[OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "PLL1_CLK2",
|
||||
[OMAP_DSS_CLK_SRC_FCK] = "DSS_FCLK",
|
||||
[OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC] = "PLL2_CLK1",
|
||||
[OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI] = "PLL2_CLK2",
|
||||
};
|
||||
|
||||
static const struct dss_param_range omap2_dss_param_range[] = {
|
||||
|
@ -226,7 +259,7 @@ static const struct dss_param_range omap4_dss_param_range[] = {
|
|||
};
|
||||
|
||||
/* OMAP2 DSS Features */
|
||||
static struct omap_dss_features omap2_dss_features = {
|
||||
static const struct omap_dss_features omap2_dss_features = {
|
||||
.reg_fields = omap2_dss_reg_fields,
|
||||
.num_reg_fields = ARRAY_SIZE(omap2_dss_reg_fields),
|
||||
|
||||
|
@ -244,7 +277,7 @@ static struct omap_dss_features omap2_dss_features = {
|
|||
};
|
||||
|
||||
/* OMAP3 DSS Features */
|
||||
static struct omap_dss_features omap3430_dss_features = {
|
||||
static const struct omap_dss_features omap3430_dss_features = {
|
||||
.reg_fields = omap3_dss_reg_fields,
|
||||
.num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields),
|
||||
|
||||
|
@ -252,7 +285,8 @@ static struct omap_dss_features omap3430_dss_features = {
|
|||
FEAT_GLOBAL_ALPHA | FEAT_LCDENABLEPOL |
|
||||
FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE |
|
||||
FEAT_FUNCGATED | FEAT_ROWREPEATENABLE |
|
||||
FEAT_LINEBUFFERSPLIT | FEAT_RESIZECONF,
|
||||
FEAT_LINEBUFFERSPLIT | FEAT_RESIZECONF |
|
||||
FEAT_DSI_PLL_FREQSEL | FEAT_DSI_REVERSE_TXCLKESC,
|
||||
|
||||
.num_mgrs = 2,
|
||||
.num_ovls = 3,
|
||||
|
@ -262,7 +296,7 @@ static struct omap_dss_features omap3430_dss_features = {
|
|||
.dss_params = omap3_dss_param_range,
|
||||
};
|
||||
|
||||
static struct omap_dss_features omap3630_dss_features = {
|
||||
static const struct omap_dss_features omap3630_dss_features = {
|
||||
.reg_fields = omap3_dss_reg_fields,
|
||||
.num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields),
|
||||
|
||||
|
@ -271,7 +305,8 @@ static struct omap_dss_features omap3630_dss_features = {
|
|||
FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE |
|
||||
FEAT_PRE_MULT_ALPHA | FEAT_FUNCGATED |
|
||||
FEAT_ROWREPEATENABLE | FEAT_LINEBUFFERSPLIT |
|
||||
FEAT_RESIZECONF | FEAT_DSI_PLL_PWR_BUG,
|
||||
FEAT_RESIZECONF | FEAT_DSI_PLL_PWR_BUG |
|
||||
FEAT_DSI_PLL_FREQSEL,
|
||||
|
||||
.num_mgrs = 2,
|
||||
.num_ovls = 3,
|
||||
|
@ -282,19 +317,43 @@ static struct omap_dss_features omap3630_dss_features = {
|
|||
};
|
||||
|
||||
/* OMAP4 DSS Features */
|
||||
static struct omap_dss_features omap4_dss_features = {
|
||||
/* For OMAP4430 ES 1.0 revision */
|
||||
static const struct omap_dss_features omap4430_es1_0_dss_features = {
|
||||
.reg_fields = omap4_dss_reg_fields,
|
||||
.num_reg_fields = ARRAY_SIZE(omap4_dss_reg_fields),
|
||||
|
||||
.has_feature =
|
||||
FEAT_GLOBAL_ALPHA | FEAT_PRE_MULT_ALPHA |
|
||||
FEAT_MGR_LCD2 | FEAT_GLOBAL_ALPHA_VID1 |
|
||||
FEAT_CORE_CLK_DIV | FEAT_LCD_CLK_SRC,
|
||||
FEAT_CORE_CLK_DIV | FEAT_LCD_CLK_SRC |
|
||||
FEAT_DSI_DCS_CMD_CONFIG_VC | FEAT_DSI_VC_OCP_WIDTH |
|
||||
FEAT_DSI_GNQ | FEAT_HANDLE_UV_SEPARATE | FEAT_ATTR2,
|
||||
|
||||
.num_mgrs = 3,
|
||||
.num_ovls = 3,
|
||||
.supported_displays = omap4_dss_supported_displays,
|
||||
.supported_color_modes = omap3_dss_supported_color_modes,
|
||||
.supported_color_modes = omap4_dss_supported_color_modes,
|
||||
.clksrc_names = omap4_dss_clk_source_names,
|
||||
.dss_params = omap4_dss_param_range,
|
||||
};
|
||||
|
||||
/* For all the other OMAP4 versions */
|
||||
static const struct omap_dss_features omap4_dss_features = {
|
||||
.reg_fields = omap4_dss_reg_fields,
|
||||
.num_reg_fields = ARRAY_SIZE(omap4_dss_reg_fields),
|
||||
|
||||
.has_feature =
|
||||
FEAT_GLOBAL_ALPHA | FEAT_PRE_MULT_ALPHA |
|
||||
FEAT_MGR_LCD2 | FEAT_GLOBAL_ALPHA_VID1 |
|
||||
FEAT_CORE_CLK_DIV | FEAT_LCD_CLK_SRC |
|
||||
FEAT_DSI_DCS_CMD_CONFIG_VC | FEAT_DSI_VC_OCP_WIDTH |
|
||||
FEAT_DSI_GNQ | FEAT_HDMI_CTS_SWMODE |
|
||||
FEAT_HANDLE_UV_SEPARATE | FEAT_ATTR2,
|
||||
|
||||
.num_mgrs = 3,
|
||||
.num_ovls = 3,
|
||||
.supported_displays = omap4_dss_supported_displays,
|
||||
.supported_color_modes = omap4_dss_supported_color_modes,
|
||||
.clksrc_names = omap4_dss_clk_source_names,
|
||||
.dss_params = omap4_dss_param_range,
|
||||
};
|
||||
|
@ -337,7 +396,7 @@ bool dss_feat_color_mode_supported(enum omap_plane plane,
|
|||
color_mode;
|
||||
}
|
||||
|
||||
const char *dss_feat_get_clk_source_name(enum dss_clk_source id)
|
||||
const char *dss_feat_get_clk_source_name(enum omap_dss_clk_source id)
|
||||
{
|
||||
return omap_current_dss_features->clksrc_names[id];
|
||||
}
|
||||
|
@ -365,6 +424,10 @@ void dss_features_init(void)
|
|||
omap_current_dss_features = &omap3630_dss_features;
|
||||
else if (cpu_is_omap34xx())
|
||||
omap_current_dss_features = &omap3430_dss_features;
|
||||
else
|
||||
else if (omap_rev() == OMAP4430_REV_ES1_0)
|
||||
omap_current_dss_features = &omap4430_es1_0_dss_features;
|
||||
else if (cpu_is_omap44xx())
|
||||
omap_current_dss_features = &omap4_dss_features;
|
||||
else
|
||||
DSSWARN("Unsupported OMAP version");
|
||||
}
|
||||
|
|
|
@ -23,25 +23,34 @@
|
|||
#define MAX_DSS_MANAGERS 3
|
||||
#define MAX_DSS_OVERLAYS 3
|
||||
#define MAX_DSS_LCD_MANAGERS 2
|
||||
#define MAX_NUM_DSI 2
|
||||
|
||||
/* DSS has feature id */
|
||||
enum dss_feat_id {
|
||||
FEAT_GLOBAL_ALPHA = 1 << 0,
|
||||
FEAT_GLOBAL_ALPHA_VID1 = 1 << 1,
|
||||
FEAT_PRE_MULT_ALPHA = 1 << 2,
|
||||
FEAT_LCDENABLEPOL = 1 << 3,
|
||||
FEAT_LCDENABLESIGNAL = 1 << 4,
|
||||
FEAT_PCKFREEENABLE = 1 << 5,
|
||||
FEAT_FUNCGATED = 1 << 6,
|
||||
FEAT_MGR_LCD2 = 1 << 7,
|
||||
FEAT_LINEBUFFERSPLIT = 1 << 8,
|
||||
FEAT_ROWREPEATENABLE = 1 << 9,
|
||||
FEAT_RESIZECONF = 1 << 10,
|
||||
FEAT_GLOBAL_ALPHA = 1 << 0,
|
||||
FEAT_GLOBAL_ALPHA_VID1 = 1 << 1,
|
||||
FEAT_PRE_MULT_ALPHA = 1 << 2,
|
||||
FEAT_LCDENABLEPOL = 1 << 3,
|
||||
FEAT_LCDENABLESIGNAL = 1 << 4,
|
||||
FEAT_PCKFREEENABLE = 1 << 5,
|
||||
FEAT_FUNCGATED = 1 << 6,
|
||||
FEAT_MGR_LCD2 = 1 << 7,
|
||||
FEAT_LINEBUFFERSPLIT = 1 << 8,
|
||||
FEAT_ROWREPEATENABLE = 1 << 9,
|
||||
FEAT_RESIZECONF = 1 << 10,
|
||||
/* Independent core clk divider */
|
||||
FEAT_CORE_CLK_DIV = 1 << 11,
|
||||
FEAT_LCD_CLK_SRC = 1 << 12,
|
||||
FEAT_CORE_CLK_DIV = 1 << 11,
|
||||
FEAT_LCD_CLK_SRC = 1 << 12,
|
||||
/* DSI-PLL power command 0x3 is not working */
|
||||
FEAT_DSI_PLL_PWR_BUG = 1 << 13,
|
||||
FEAT_DSI_PLL_PWR_BUG = 1 << 13,
|
||||
FEAT_DSI_PLL_FREQSEL = 1 << 14,
|
||||
FEAT_DSI_DCS_CMD_CONFIG_VC = 1 << 15,
|
||||
FEAT_DSI_VC_OCP_WIDTH = 1 << 16,
|
||||
FEAT_DSI_REVERSE_TXCLKESC = 1 << 17,
|
||||
FEAT_DSI_GNQ = 1 << 18,
|
||||
FEAT_HDMI_CTS_SWMODE = 1 << 19,
|
||||
FEAT_HANDLE_UV_SEPARATE = 1 << 20,
|
||||
FEAT_ATTR2 = 1 << 21,
|
||||
};
|
||||
|
||||
/* DSS register field id */
|
||||
|
@ -79,7 +88,7 @@ enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel
|
|||
enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane);
|
||||
bool dss_feat_color_mode_supported(enum omap_plane plane,
|
||||
enum omap_color_mode color_mode);
|
||||
const char *dss_feat_get_clk_source_name(enum dss_clk_source id);
|
||||
const char *dss_feat_get_clk_source_name(enum omap_dss_clk_source id);
|
||||
|
||||
bool dss_has_feature(enum dss_feat_id id);
|
||||
void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end);
|
||||
|
|
|
@ -29,10 +29,16 @@
|
|||
#include <linux/mutex.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/string.h>
|
||||
#include <plat/display.h>
|
||||
#include <video/omapdss.h>
|
||||
#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
|
||||
defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
|
||||
#include <sound/soc.h>
|
||||
#include <sound/pcm_params.h>
|
||||
#endif
|
||||
|
||||
#include "dss.h"
|
||||
#include "hdmi.h"
|
||||
#include "dss_features.h"
|
||||
|
||||
static struct {
|
||||
struct mutex lock;
|
||||
|
@ -1052,25 +1058,26 @@ static void update_hdmi_timings(struct hdmi_config *cfg,
|
|||
cfg->timings.hsync_pol = cea_vesa_timings[code].hsync_pol;
|
||||
}
|
||||
|
||||
static void hdmi_compute_pll(unsigned long clkin, int phy,
|
||||
int n, struct hdmi_pll_info *pi)
|
||||
static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy,
|
||||
struct hdmi_pll_info *pi)
|
||||
{
|
||||
unsigned long refclk;
|
||||
unsigned long clkin, refclk;
|
||||
u32 mf;
|
||||
|
||||
clkin = dss_clk_get_rate(DSS_CLK_SYSCK) / 10000;
|
||||
/*
|
||||
* Input clock is predivided by N + 1
|
||||
* out put of which is reference clk
|
||||
*/
|
||||
refclk = clkin / (n + 1);
|
||||
pi->regn = n;
|
||||
pi->regn = dssdev->clocks.hdmi.regn;
|
||||
refclk = clkin / (pi->regn + 1);
|
||||
|
||||
/*
|
||||
* multiplier is pixel_clk/ref_clk
|
||||
* Multiplying by 100 to avoid fractional part removal
|
||||
*/
|
||||
pi->regm = (phy * 100/(refclk))/100;
|
||||
pi->regm2 = 1;
|
||||
pi->regm = (phy * 100 / (refclk)) / 100;
|
||||
pi->regm2 = dssdev->clocks.hdmi.regm2;
|
||||
|
||||
/*
|
||||
* fractional multiplier is remainder of the difference between
|
||||
|
@ -1078,14 +1085,14 @@ static void hdmi_compute_pll(unsigned long clkin, int phy,
|
|||
* multiplied by 2^18(262144) divided by the reference clock
|
||||
*/
|
||||
mf = (phy - pi->regm * refclk) * 262144;
|
||||
pi->regmf = mf/(refclk);
|
||||
pi->regmf = mf / (refclk);
|
||||
|
||||
/*
|
||||
* Dcofreq should be set to 1 if required pixel clock
|
||||
* is greater than 1000MHz
|
||||
*/
|
||||
pi->dcofreq = phy > 1000 * 100;
|
||||
pi->regsd = ((pi->regm * clkin / 10) / ((n + 1) * 250) + 5) / 10;
|
||||
pi->regsd = ((pi->regm * clkin / 10) / ((pi->regn + 1) * 250) + 5) / 10;
|
||||
|
||||
DSSDBG("M = %d Mf = %d\n", pi->regm, pi->regmf);
|
||||
DSSDBG("range = %d sd = %d\n", pi->dcofreq, pi->regsd);
|
||||
|
@ -1106,7 +1113,7 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
|
|||
int r, code = 0;
|
||||
struct hdmi_pll_info pll_data;
|
||||
struct omap_video_timings *p;
|
||||
int clkin, n, phy;
|
||||
unsigned long phy;
|
||||
|
||||
hdmi_enable_clocks(1);
|
||||
|
||||
|
@ -1126,11 +1133,9 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
|
|||
dssdev->panel.timings = cea_vesa_timings[code].timings;
|
||||
update_hdmi_timings(&hdmi.cfg, p, code);
|
||||
|
||||
clkin = 3840; /* 38.4 MHz */
|
||||
n = 15; /* this is a constant for our math */
|
||||
phy = p->pixel_clock;
|
||||
|
||||
hdmi_compute_pll(clkin, phy, n, &pll_data);
|
||||
hdmi_compute_pll(dssdev, phy, &pll_data);
|
||||
|
||||
hdmi_wp_video_start(0);
|
||||
|
||||
|
@ -1160,7 +1165,7 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
|
|||
* dynamically by user. This can be moved to single location , say
|
||||
* Boardfile.
|
||||
*/
|
||||
dss_select_dispc_clk_source(DSS_CLK_SRC_FCK);
|
||||
dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src);
|
||||
|
||||
/* bypass TV gamma table */
|
||||
dispc_enable_gamma_table(0);
|
||||
|
@ -1275,10 +1280,420 @@ void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev)
|
|||
mutex_unlock(&hdmi.lock);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
|
||||
defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
|
||||
static void hdmi_wp_audio_config_format(
|
||||
struct hdmi_audio_format *aud_fmt)
|
||||
{
|
||||
u32 r;
|
||||
|
||||
DSSDBG("Enter hdmi_wp_audio_config_format\n");
|
||||
|
||||
r = hdmi_read_reg(HDMI_WP_AUDIO_CFG);
|
||||
r = FLD_MOD(r, aud_fmt->stereo_channels, 26, 24);
|
||||
r = FLD_MOD(r, aud_fmt->active_chnnls_msk, 23, 16);
|
||||
r = FLD_MOD(r, aud_fmt->en_sig_blk_strt_end, 5, 5);
|
||||
r = FLD_MOD(r, aud_fmt->type, 4, 4);
|
||||
r = FLD_MOD(r, aud_fmt->justification, 3, 3);
|
||||
r = FLD_MOD(r, aud_fmt->sample_order, 2, 2);
|
||||
r = FLD_MOD(r, aud_fmt->samples_per_word, 1, 1);
|
||||
r = FLD_MOD(r, aud_fmt->sample_size, 0, 0);
|
||||
hdmi_write_reg(HDMI_WP_AUDIO_CFG, r);
|
||||
}
|
||||
|
||||
static void hdmi_wp_audio_config_dma(struct hdmi_audio_dma *aud_dma)
|
||||
{
|
||||
u32 r;
|
||||
|
||||
DSSDBG("Enter hdmi_wp_audio_config_dma\n");
|
||||
|
||||
r = hdmi_read_reg(HDMI_WP_AUDIO_CFG2);
|
||||
r = FLD_MOD(r, aud_dma->transfer_size, 15, 8);
|
||||
r = FLD_MOD(r, aud_dma->block_size, 7, 0);
|
||||
hdmi_write_reg(HDMI_WP_AUDIO_CFG2, r);
|
||||
|
||||
r = hdmi_read_reg(HDMI_WP_AUDIO_CTRL);
|
||||
r = FLD_MOD(r, aud_dma->mode, 9, 9);
|
||||
r = FLD_MOD(r, aud_dma->fifo_threshold, 8, 0);
|
||||
hdmi_write_reg(HDMI_WP_AUDIO_CTRL, r);
|
||||
}
|
||||
|
||||
static void hdmi_core_audio_config(struct hdmi_core_audio_config *cfg)
|
||||
{
|
||||
u32 r;
|
||||
|
||||
/* audio clock recovery parameters */
|
||||
r = hdmi_read_reg(HDMI_CORE_AV_ACR_CTRL);
|
||||
r = FLD_MOD(r, cfg->use_mclk, 2, 2);
|
||||
r = FLD_MOD(r, cfg->en_acr_pkt, 1, 1);
|
||||
r = FLD_MOD(r, cfg->cts_mode, 0, 0);
|
||||
hdmi_write_reg(HDMI_CORE_AV_ACR_CTRL, r);
|
||||
|
||||
REG_FLD_MOD(HDMI_CORE_AV_N_SVAL1, cfg->n, 7, 0);
|
||||
REG_FLD_MOD(HDMI_CORE_AV_N_SVAL2, cfg->n >> 8, 7, 0);
|
||||
REG_FLD_MOD(HDMI_CORE_AV_N_SVAL3, cfg->n >> 16, 7, 0);
|
||||
|
||||
if (cfg->cts_mode == HDMI_AUDIO_CTS_MODE_SW) {
|
||||
REG_FLD_MOD(HDMI_CORE_AV_CTS_SVAL1, cfg->cts, 7, 0);
|
||||
REG_FLD_MOD(HDMI_CORE_AV_CTS_SVAL2, cfg->cts >> 8, 7, 0);
|
||||
REG_FLD_MOD(HDMI_CORE_AV_CTS_SVAL3, cfg->cts >> 16, 7, 0);
|
||||
} else {
|
||||
/*
|
||||
* HDMI IP uses this configuration to divide the MCLK to
|
||||
* update CTS value.
|
||||
*/
|
||||
REG_FLD_MOD(HDMI_CORE_AV_FREQ_SVAL, cfg->mclk_mode, 2, 0);
|
||||
|
||||
/* Configure clock for audio packets */
|
||||
REG_FLD_MOD(HDMI_CORE_AV_AUD_PAR_BUSCLK_1,
|
||||
cfg->aud_par_busclk, 7, 0);
|
||||
REG_FLD_MOD(HDMI_CORE_AV_AUD_PAR_BUSCLK_2,
|
||||
(cfg->aud_par_busclk >> 8), 7, 0);
|
||||
REG_FLD_MOD(HDMI_CORE_AV_AUD_PAR_BUSCLK_3,
|
||||
(cfg->aud_par_busclk >> 16), 7, 0);
|
||||
}
|
||||
|
||||
/* Override of SPDIF sample frequency with value in I2S_CHST4 */
|
||||
REG_FLD_MOD(HDMI_CORE_AV_SPDIF_CTRL, cfg->fs_override, 1, 1);
|
||||
|
||||
/* I2S parameters */
|
||||
REG_FLD_MOD(HDMI_CORE_AV_I2S_CHST4, cfg->freq_sample, 3, 0);
|
||||
|
||||
r = hdmi_read_reg(HDMI_CORE_AV_I2S_IN_CTRL);
|
||||
r = FLD_MOD(r, cfg->i2s_cfg.en_high_bitrate_aud, 7, 7);
|
||||
r = FLD_MOD(r, cfg->i2s_cfg.sck_edge_mode, 6, 6);
|
||||
r = FLD_MOD(r, cfg->i2s_cfg.cbit_order, 5, 5);
|
||||
r = FLD_MOD(r, cfg->i2s_cfg.vbit, 4, 4);
|
||||
r = FLD_MOD(r, cfg->i2s_cfg.ws_polarity, 3, 3);
|
||||
r = FLD_MOD(r, cfg->i2s_cfg.justification, 2, 2);
|
||||
r = FLD_MOD(r, cfg->i2s_cfg.direction, 1, 1);
|
||||
r = FLD_MOD(r, cfg->i2s_cfg.shift, 0, 0);
|
||||
hdmi_write_reg(HDMI_CORE_AV_I2S_IN_CTRL, r);
|
||||
|
||||
r = hdmi_read_reg(HDMI_CORE_AV_I2S_CHST5);
|
||||
r = FLD_MOD(r, cfg->freq_sample, 7, 4);
|
||||
r = FLD_MOD(r, cfg->i2s_cfg.word_length, 3, 1);
|
||||
r = FLD_MOD(r, cfg->i2s_cfg.word_max_length, 0, 0);
|
||||
hdmi_write_reg(HDMI_CORE_AV_I2S_CHST5, r);
|
||||
|
||||
REG_FLD_MOD(HDMI_CORE_AV_I2S_IN_LEN, cfg->i2s_cfg.in_length_bits, 3, 0);
|
||||
|
||||
/* Audio channels and mode parameters */
|
||||
REG_FLD_MOD(HDMI_CORE_AV_HDMI_CTRL, cfg->layout, 2, 1);
|
||||
r = hdmi_read_reg(HDMI_CORE_AV_AUD_MODE);
|
||||
r = FLD_MOD(r, cfg->i2s_cfg.active_sds, 7, 4);
|
||||
r = FLD_MOD(r, cfg->en_dsd_audio, 3, 3);
|
||||
r = FLD_MOD(r, cfg->en_parallel_aud_input, 2, 2);
|
||||
r = FLD_MOD(r, cfg->en_spdif, 1, 1);
|
||||
hdmi_write_reg(HDMI_CORE_AV_AUD_MODE, r);
|
||||
}
|
||||
|
||||
static void hdmi_core_audio_infoframe_config(
|
||||
struct hdmi_core_infoframe_audio *info_aud)
|
||||
{
|
||||
u8 val;
|
||||
u8 sum = 0, checksum = 0;
|
||||
|
||||
/*
|
||||
* Set audio info frame type, version and length as
|
||||
* described in HDMI 1.4a Section 8.2.2 specification.
|
||||
* Checksum calculation is defined in Section 5.3.5.
|
||||
*/
|
||||
hdmi_write_reg(HDMI_CORE_AV_AUDIO_TYPE, 0x84);
|
||||
hdmi_write_reg(HDMI_CORE_AV_AUDIO_VERS, 0x01);
|
||||
hdmi_write_reg(HDMI_CORE_AV_AUDIO_LEN, 0x0a);
|
||||
sum += 0x84 + 0x001 + 0x00a;
|
||||
|
||||
val = (info_aud->db1_coding_type << 4)
|
||||
| (info_aud->db1_channel_count - 1);
|
||||
hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(0), val);
|
||||
sum += val;
|
||||
|
||||
val = (info_aud->db2_sample_freq << 2) | info_aud->db2_sample_size;
|
||||
hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(1), val);
|
||||
sum += val;
|
||||
|
||||
hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(2), 0x00);
|
||||
|
||||
val = info_aud->db4_channel_alloc;
|
||||
hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(3), val);
|
||||
sum += val;
|
||||
|
||||
val = (info_aud->db5_downmix_inh << 7) | (info_aud->db5_lsv << 3);
|
||||
hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(4), val);
|
||||
sum += val;
|
||||
|
||||
hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(5), 0x00);
|
||||
hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(6), 0x00);
|
||||
hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(7), 0x00);
|
||||
hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(8), 0x00);
|
||||
hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(9), 0x00);
|
||||
|
||||
checksum = 0x100 - sum;
|
||||
hdmi_write_reg(HDMI_CORE_AV_AUDIO_CHSUM, checksum);
|
||||
|
||||
/*
|
||||
* TODO: Add MPEG and SPD enable and repeat cfg when EDID parsing
|
||||
* is available.
|
||||
*/
|
||||
}
|
||||
|
||||
static int hdmi_config_audio_acr(u32 sample_freq, u32 *n, u32 *cts)
|
||||
{
|
||||
u32 r;
|
||||
u32 deep_color = 0;
|
||||
u32 pclk = hdmi.cfg.timings.timings.pixel_clock;
|
||||
|
||||
if (n == NULL || cts == NULL)
|
||||
return -EINVAL;
|
||||
/*
|
||||
* Obtain current deep color configuration. This needed
|
||||
* to calculate the TMDS clock based on the pixel clock.
|
||||
*/
|
||||
r = REG_GET(HDMI_WP_VIDEO_CFG, 1, 0);
|
||||
switch (r) {
|
||||
case 1: /* No deep color selected */
|
||||
deep_color = 100;
|
||||
break;
|
||||
case 2: /* 10-bit deep color selected */
|
||||
deep_color = 125;
|
||||
break;
|
||||
case 3: /* 12-bit deep color selected */
|
||||
deep_color = 150;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (sample_freq) {
|
||||
case 32000:
|
||||
if ((deep_color == 125) && ((pclk == 54054)
|
||||
|| (pclk == 74250)))
|
||||
*n = 8192;
|
||||
else
|
||||
*n = 4096;
|
||||
break;
|
||||
case 44100:
|
||||
*n = 6272;
|
||||
break;
|
||||
case 48000:
|
||||
if ((deep_color == 125) && ((pclk == 54054)
|
||||
|| (pclk == 74250)))
|
||||
*n = 8192;
|
||||
else
|
||||
*n = 6144;
|
||||
break;
|
||||
default:
|
||||
*n = 0;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Calculate CTS. See HDMI 1.3a or 1.4a specifications */
|
||||
*cts = pclk * (*n / 128) * deep_color / (sample_freq / 10);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hdmi_audio_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct hdmi_audio_format audio_format;
|
||||
struct hdmi_audio_dma audio_dma;
|
||||
struct hdmi_core_audio_config core_cfg;
|
||||
struct hdmi_core_infoframe_audio aud_if_cfg;
|
||||
int err, n, cts;
|
||||
enum hdmi_core_audio_sample_freq sample_freq;
|
||||
|
||||
switch (params_format(params)) {
|
||||
case SNDRV_PCM_FORMAT_S16_LE:
|
||||
core_cfg.i2s_cfg.word_max_length =
|
||||
HDMI_AUDIO_I2S_MAX_WORD_20BITS;
|
||||
core_cfg.i2s_cfg.word_length = HDMI_AUDIO_I2S_CHST_WORD_16_BITS;
|
||||
core_cfg.i2s_cfg.in_length_bits =
|
||||
HDMI_AUDIO_I2S_INPUT_LENGTH_16;
|
||||
core_cfg.i2s_cfg.justification = HDMI_AUDIO_JUSTIFY_LEFT;
|
||||
audio_format.samples_per_word = HDMI_AUDIO_ONEWORD_TWOSAMPLES;
|
||||
audio_format.sample_size = HDMI_AUDIO_SAMPLE_16BITS;
|
||||
audio_format.justification = HDMI_AUDIO_JUSTIFY_LEFT;
|
||||
audio_dma.transfer_size = 0x10;
|
||||
break;
|
||||
case SNDRV_PCM_FORMAT_S24_LE:
|
||||
core_cfg.i2s_cfg.word_max_length =
|
||||
HDMI_AUDIO_I2S_MAX_WORD_24BITS;
|
||||
core_cfg.i2s_cfg.word_length = HDMI_AUDIO_I2S_CHST_WORD_24_BITS;
|
||||
core_cfg.i2s_cfg.in_length_bits =
|
||||
HDMI_AUDIO_I2S_INPUT_LENGTH_24;
|
||||
audio_format.samples_per_word = HDMI_AUDIO_ONEWORD_ONESAMPLE;
|
||||
audio_format.sample_size = HDMI_AUDIO_SAMPLE_24BITS;
|
||||
audio_format.justification = HDMI_AUDIO_JUSTIFY_RIGHT;
|
||||
core_cfg.i2s_cfg.justification = HDMI_AUDIO_JUSTIFY_RIGHT;
|
||||
audio_dma.transfer_size = 0x20;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (params_rate(params)) {
|
||||
case 32000:
|
||||
sample_freq = HDMI_AUDIO_FS_32000;
|
||||
break;
|
||||
case 44100:
|
||||
sample_freq = HDMI_AUDIO_FS_44100;
|
||||
break;
|
||||
case 48000:
|
||||
sample_freq = HDMI_AUDIO_FS_48000;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
err = hdmi_config_audio_acr(params_rate(params), &n, &cts);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
/* Audio wrapper config */
|
||||
audio_format.stereo_channels = HDMI_AUDIO_STEREO_ONECHANNEL;
|
||||
audio_format.active_chnnls_msk = 0x03;
|
||||
audio_format.type = HDMI_AUDIO_TYPE_LPCM;
|
||||
audio_format.sample_order = HDMI_AUDIO_SAMPLE_LEFT_FIRST;
|
||||
/* Disable start/stop signals of IEC 60958 blocks */
|
||||
audio_format.en_sig_blk_strt_end = HDMI_AUDIO_BLOCK_SIG_STARTEND_OFF;
|
||||
|
||||
audio_dma.block_size = 0xC0;
|
||||
audio_dma.mode = HDMI_AUDIO_TRANSF_DMA;
|
||||
audio_dma.fifo_threshold = 0x20; /* in number of samples */
|
||||
|
||||
hdmi_wp_audio_config_dma(&audio_dma);
|
||||
hdmi_wp_audio_config_format(&audio_format);
|
||||
|
||||
/*
|
||||
* I2S config
|
||||
*/
|
||||
core_cfg.i2s_cfg.en_high_bitrate_aud = false;
|
||||
/* Only used with high bitrate audio */
|
||||
core_cfg.i2s_cfg.cbit_order = false;
|
||||
/* Serial data and word select should change on sck rising edge */
|
||||
core_cfg.i2s_cfg.sck_edge_mode = HDMI_AUDIO_I2S_SCK_EDGE_RISING;
|
||||
core_cfg.i2s_cfg.vbit = HDMI_AUDIO_I2S_VBIT_FOR_PCM;
|
||||
/* Set I2S word select polarity */
|
||||
core_cfg.i2s_cfg.ws_polarity = HDMI_AUDIO_I2S_WS_POLARITY_LOW_IS_LEFT;
|
||||
core_cfg.i2s_cfg.direction = HDMI_AUDIO_I2S_MSB_SHIFTED_FIRST;
|
||||
/* Set serial data to word select shift. See Phillips spec. */
|
||||
core_cfg.i2s_cfg.shift = HDMI_AUDIO_I2S_FIRST_BIT_SHIFT;
|
||||
/* Enable one of the four available serial data channels */
|
||||
core_cfg.i2s_cfg.active_sds = HDMI_AUDIO_I2S_SD0_EN;
|
||||
|
||||
/* Core audio config */
|
||||
core_cfg.freq_sample = sample_freq;
|
||||
core_cfg.n = n;
|
||||
core_cfg.cts = cts;
|
||||
if (dss_has_feature(FEAT_HDMI_CTS_SWMODE)) {
|
||||
core_cfg.aud_par_busclk = 0;
|
||||
core_cfg.cts_mode = HDMI_AUDIO_CTS_MODE_SW;
|
||||
core_cfg.use_mclk = false;
|
||||
} else {
|
||||
core_cfg.aud_par_busclk = (((128 * 31) - 1) << 8);
|
||||
core_cfg.cts_mode = HDMI_AUDIO_CTS_MODE_HW;
|
||||
core_cfg.use_mclk = true;
|
||||
core_cfg.mclk_mode = HDMI_AUDIO_MCLK_128FS;
|
||||
}
|
||||
core_cfg.layout = HDMI_AUDIO_LAYOUT_2CH;
|
||||
core_cfg.en_spdif = false;
|
||||
/* Use sample frequency from channel status word */
|
||||
core_cfg.fs_override = true;
|
||||
/* Enable ACR packets */
|
||||
core_cfg.en_acr_pkt = true;
|
||||
/* Disable direct streaming digital audio */
|
||||
core_cfg.en_dsd_audio = false;
|
||||
/* Use parallel audio interface */
|
||||
core_cfg.en_parallel_aud_input = true;
|
||||
|
||||
hdmi_core_audio_config(&core_cfg);
|
||||
|
||||
/*
|
||||
* Configure packet
|
||||
* info frame audio see doc CEA861-D page 74
|
||||
*/
|
||||
aud_if_cfg.db1_coding_type = HDMI_INFOFRAME_AUDIO_DB1CT_FROM_STREAM;
|
||||
aud_if_cfg.db1_channel_count = 2;
|
||||
aud_if_cfg.db2_sample_freq = HDMI_INFOFRAME_AUDIO_DB2SF_FROM_STREAM;
|
||||
aud_if_cfg.db2_sample_size = HDMI_INFOFRAME_AUDIO_DB2SS_FROM_STREAM;
|
||||
aud_if_cfg.db4_channel_alloc = 0x00;
|
||||
aud_if_cfg.db5_downmix_inh = false;
|
||||
aud_if_cfg.db5_lsv = 0;
|
||||
|
||||
hdmi_core_audio_infoframe_config(&aud_if_cfg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hdmi_audio_trigger(struct snd_pcm_substream *substream, int cmd,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
int err = 0;
|
||||
switch (cmd) {
|
||||
case SNDRV_PCM_TRIGGER_START:
|
||||
case SNDRV_PCM_TRIGGER_RESUME:
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
|
||||
REG_FLD_MOD(HDMI_CORE_AV_AUD_MODE, 1, 0, 0);
|
||||
REG_FLD_MOD(HDMI_WP_AUDIO_CTRL, 1, 31, 31);
|
||||
REG_FLD_MOD(HDMI_WP_AUDIO_CTRL, 1, 30, 30);
|
||||
break;
|
||||
|
||||
case SNDRV_PCM_TRIGGER_STOP:
|
||||
case SNDRV_PCM_TRIGGER_SUSPEND:
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
|
||||
REG_FLD_MOD(HDMI_CORE_AV_AUD_MODE, 0, 0, 0);
|
||||
REG_FLD_MOD(HDMI_WP_AUDIO_CTRL, 0, 30, 30);
|
||||
REG_FLD_MOD(HDMI_WP_AUDIO_CTRL, 0, 31, 31);
|
||||
break;
|
||||
default:
|
||||
err = -EINVAL;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static int hdmi_audio_startup(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
if (!hdmi.mode) {
|
||||
pr_err("Current video settings do not support audio.\n");
|
||||
return -EIO;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct snd_soc_codec_driver hdmi_audio_codec_drv = {
|
||||
};
|
||||
|
||||
static struct snd_soc_dai_ops hdmi_audio_codec_ops = {
|
||||
.hw_params = hdmi_audio_hw_params,
|
||||
.trigger = hdmi_audio_trigger,
|
||||
.startup = hdmi_audio_startup,
|
||||
};
|
||||
|
||||
static struct snd_soc_dai_driver hdmi_codec_dai_drv = {
|
||||
.name = "hdmi-audio-codec",
|
||||
.playback = {
|
||||
.channels_min = 2,
|
||||
.channels_max = 2,
|
||||
.rates = SNDRV_PCM_RATE_32000 |
|
||||
SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_LE |
|
||||
SNDRV_PCM_FMTBIT_S24_LE,
|
||||
},
|
||||
.ops = &hdmi_audio_codec_ops,
|
||||
};
|
||||
#endif
|
||||
|
||||
/* HDMI HW IP initialisation */
|
||||
static int omapdss_hdmihw_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *hdmi_mem;
|
||||
#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
|
||||
defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
|
||||
int ret;
|
||||
#endif
|
||||
|
||||
hdmi.pdata = pdev->dev.platform_data;
|
||||
hdmi.pdev = pdev;
|
||||
|
@ -1300,6 +1715,17 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev)
|
|||
|
||||
hdmi_panel_init();
|
||||
|
||||
#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
|
||||
defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
|
||||
|
||||
/* Register ASoC codec DAI */
|
||||
ret = snd_soc_register_codec(&pdev->dev, &hdmi_audio_codec_drv,
|
||||
&hdmi_codec_dai_drv, 1);
|
||||
if (ret) {
|
||||
DSSERR("can't register ASoC HDMI audio codec\n");
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1307,6 +1733,11 @@ static int omapdss_hdmihw_remove(struct platform_device *pdev)
|
|||
{
|
||||
hdmi_panel_exit();
|
||||
|
||||
#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
|
||||
defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
|
||||
snd_soc_unregister_codec(&pdev->dev);
|
||||
#endif
|
||||
|
||||
iounmap(hdmi.base_wp);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#define _OMAP4_DSS_HDMI_H_
|
||||
|
||||
#include <linux/string.h>
|
||||
#include <plat/display.h>
|
||||
#include <video/omapdss.h>
|
||||
|
||||
#define HDMI_WP 0x0
|
||||
#define HDMI_CORE_SYS 0x400
|
||||
|
@ -48,6 +48,10 @@ struct hdmi_reg { u16 idx; };
|
|||
#define HDMI_WP_VIDEO_TIMING_H HDMI_WP_REG(0x68)
|
||||
#define HDMI_WP_VIDEO_TIMING_V HDMI_WP_REG(0x6C)
|
||||
#define HDMI_WP_WP_CLK HDMI_WP_REG(0x70)
|
||||
#define HDMI_WP_AUDIO_CFG HDMI_WP_REG(0x80)
|
||||
#define HDMI_WP_AUDIO_CFG2 HDMI_WP_REG(0x84)
|
||||
#define HDMI_WP_AUDIO_CTRL HDMI_WP_REG(0x88)
|
||||
#define HDMI_WP_AUDIO_DATA HDMI_WP_REG(0x8C)
|
||||
|
||||
/* HDMI IP Core System */
|
||||
#define HDMI_CORE_SYS_REG(idx) HDMI_REG(HDMI_CORE_SYS + idx)
|
||||
|
@ -105,6 +109,8 @@ struct hdmi_reg { u16 idx; };
|
|||
#define HDMI_CORE_AV_AVI_DBYTE_NELEMS HDMI_CORE_AV_REG(15)
|
||||
#define HDMI_CORE_AV_SPD_DBYTE HDMI_CORE_AV_REG(0x190)
|
||||
#define HDMI_CORE_AV_SPD_DBYTE_NELEMS HDMI_CORE_AV_REG(27)
|
||||
#define HDMI_CORE_AV_AUD_DBYTE(n) HDMI_CORE_AV_REG(n * 4 + 0x210)
|
||||
#define HDMI_CORE_AV_AUD_DBYTE_NELEMS HDMI_CORE_AV_REG(10)
|
||||
#define HDMI_CORE_AV_MPEG_DBYTE HDMI_CORE_AV_REG(0x290)
|
||||
#define HDMI_CORE_AV_MPEG_DBYTE_NELEMS HDMI_CORE_AV_REG(27)
|
||||
#define HDMI_CORE_AV_GEN_DBYTE HDMI_CORE_AV_REG(0x300)
|
||||
|
@ -153,6 +159,10 @@ struct hdmi_reg { u16 idx; };
|
|||
#define HDMI_CORE_AV_SPD_VERS HDMI_CORE_AV_REG(0x184)
|
||||
#define HDMI_CORE_AV_SPD_LEN HDMI_CORE_AV_REG(0x188)
|
||||
#define HDMI_CORE_AV_SPD_CHSUM HDMI_CORE_AV_REG(0x18C)
|
||||
#define HDMI_CORE_AV_AUDIO_TYPE HDMI_CORE_AV_REG(0x200)
|
||||
#define HDMI_CORE_AV_AUDIO_VERS HDMI_CORE_AV_REG(0x204)
|
||||
#define HDMI_CORE_AV_AUDIO_LEN HDMI_CORE_AV_REG(0x208)
|
||||
#define HDMI_CORE_AV_AUDIO_CHSUM HDMI_CORE_AV_REG(0x20C)
|
||||
#define HDMI_CORE_AV_MPEG_TYPE HDMI_CORE_AV_REG(0x280)
|
||||
#define HDMI_CORE_AV_MPEG_VERS HDMI_CORE_AV_REG(0x284)
|
||||
#define HDMI_CORE_AV_MPEG_LEN HDMI_CORE_AV_REG(0x288)
|
||||
|
@ -272,7 +282,7 @@ enum hdmi_core_packet_ctrl {
|
|||
HDMI_PACKETREPEATOFF = 0
|
||||
};
|
||||
|
||||
/* INFOFRAME_AVI_ definitions */
|
||||
/* INFOFRAME_AVI_ and INFOFRAME_AUDIO_ definitions */
|
||||
enum hdmi_core_infoframe {
|
||||
HDMI_INFOFRAME_AVI_DB1Y_RGB = 0,
|
||||
HDMI_INFOFRAME_AVI_DB1Y_YUV422 = 1,
|
||||
|
@ -317,7 +327,36 @@ enum hdmi_core_infoframe {
|
|||
HDMI_INFOFRAME_AVI_DB5PR_7 = 6,
|
||||
HDMI_INFOFRAME_AVI_DB5PR_8 = 7,
|
||||
HDMI_INFOFRAME_AVI_DB5PR_9 = 8,
|
||||
HDMI_INFOFRAME_AVI_DB5PR_10 = 9
|
||||
HDMI_INFOFRAME_AVI_DB5PR_10 = 9,
|
||||
HDMI_INFOFRAME_AUDIO_DB1CT_FROM_STREAM = 0,
|
||||
HDMI_INFOFRAME_AUDIO_DB1CT_IEC60958 = 1,
|
||||
HDMI_INFOFRAME_AUDIO_DB1CT_AC3 = 2,
|
||||
HDMI_INFOFRAME_AUDIO_DB1CT_MPEG1 = 3,
|
||||
HDMI_INFOFRAME_AUDIO_DB1CT_MP3 = 4,
|
||||
HDMI_INFOFRAME_AUDIO_DB1CT_MPEG2_MULTICH = 5,
|
||||
HDMI_INFOFRAME_AUDIO_DB1CT_AAC = 6,
|
||||
HDMI_INFOFRAME_AUDIO_DB1CT_DTS = 7,
|
||||
HDMI_INFOFRAME_AUDIO_DB1CT_ATRAC = 8,
|
||||
HDMI_INFOFRAME_AUDIO_DB1CT_ONEBIT = 9,
|
||||
HDMI_INFOFRAME_AUDIO_DB1CT_DOLBY_DIGITAL_PLUS = 10,
|
||||
HDMI_INFOFRAME_AUDIO_DB1CT_DTS_HD = 11,
|
||||
HDMI_INFOFRAME_AUDIO_DB1CT_MAT = 12,
|
||||
HDMI_INFOFRAME_AUDIO_DB1CT_DST = 13,
|
||||
HDMI_INFOFRAME_AUDIO_DB1CT_WMA_PRO = 14,
|
||||
HDMI_INFOFRAME_AUDIO_DB2SF_FROM_STREAM = 0,
|
||||
HDMI_INFOFRAME_AUDIO_DB2SF_32000 = 1,
|
||||
HDMI_INFOFRAME_AUDIO_DB2SF_44100 = 2,
|
||||
HDMI_INFOFRAME_AUDIO_DB2SF_48000 = 3,
|
||||
HDMI_INFOFRAME_AUDIO_DB2SF_88200 = 4,
|
||||
HDMI_INFOFRAME_AUDIO_DB2SF_96000 = 5,
|
||||
HDMI_INFOFRAME_AUDIO_DB2SF_176400 = 6,
|
||||
HDMI_INFOFRAME_AUDIO_DB2SF_192000 = 7,
|
||||
HDMI_INFOFRAME_AUDIO_DB2SS_FROM_STREAM = 0,
|
||||
HDMI_INFOFRAME_AUDIO_DB2SS_16BIT = 1,
|
||||
HDMI_INFOFRAME_AUDIO_DB2SS_20BIT = 2,
|
||||
HDMI_INFOFRAME_AUDIO_DB2SS_24BIT = 3,
|
||||
HDMI_INFOFRAME_AUDIO_DB5_DM_INH_PERMITTED = 0,
|
||||
HDMI_INFOFRAME_AUDIO_DB5_DM_INH_PROHIBITED = 1
|
||||
};
|
||||
|
||||
enum hdmi_packing_mode {
|
||||
|
@ -327,6 +366,121 @@ enum hdmi_packing_mode {
|
|||
HDMI_PACK_ALREADYPACKED = 7
|
||||
};
|
||||
|
||||
enum hdmi_core_audio_sample_freq {
|
||||
HDMI_AUDIO_FS_32000 = 0x3,
|
||||
HDMI_AUDIO_FS_44100 = 0x0,
|
||||
HDMI_AUDIO_FS_48000 = 0x2,
|
||||
HDMI_AUDIO_FS_88200 = 0x8,
|
||||
HDMI_AUDIO_FS_96000 = 0xA,
|
||||
HDMI_AUDIO_FS_176400 = 0xC,
|
||||
HDMI_AUDIO_FS_192000 = 0xE,
|
||||
HDMI_AUDIO_FS_NOT_INDICATED = 0x1
|
||||
};
|
||||
|
||||
enum hdmi_core_audio_layout {
|
||||
HDMI_AUDIO_LAYOUT_2CH = 0,
|
||||
HDMI_AUDIO_LAYOUT_8CH = 1
|
||||
};
|
||||
|
||||
enum hdmi_core_cts_mode {
|
||||
HDMI_AUDIO_CTS_MODE_HW = 0,
|
||||
HDMI_AUDIO_CTS_MODE_SW = 1
|
||||
};
|
||||
|
||||
enum hdmi_stereo_channels {
|
||||
HDMI_AUDIO_STEREO_NOCHANNELS = 0,
|
||||
HDMI_AUDIO_STEREO_ONECHANNEL = 1,
|
||||
HDMI_AUDIO_STEREO_TWOCHANNELS = 2,
|
||||
HDMI_AUDIO_STEREO_THREECHANNELS = 3,
|
||||
HDMI_AUDIO_STEREO_FOURCHANNELS = 4
|
||||
};
|
||||
|
||||
enum hdmi_audio_type {
|
||||
HDMI_AUDIO_TYPE_LPCM = 0,
|
||||
HDMI_AUDIO_TYPE_IEC = 1
|
||||
};
|
||||
|
||||
enum hdmi_audio_justify {
|
||||
HDMI_AUDIO_JUSTIFY_LEFT = 0,
|
||||
HDMI_AUDIO_JUSTIFY_RIGHT = 1
|
||||
};
|
||||
|
||||
enum hdmi_audio_sample_order {
|
||||
HDMI_AUDIO_SAMPLE_RIGHT_FIRST = 0,
|
||||
HDMI_AUDIO_SAMPLE_LEFT_FIRST = 1
|
||||
};
|
||||
|
||||
enum hdmi_audio_samples_perword {
|
||||
HDMI_AUDIO_ONEWORD_ONESAMPLE = 0,
|
||||
HDMI_AUDIO_ONEWORD_TWOSAMPLES = 1
|
||||
};
|
||||
|
||||
enum hdmi_audio_sample_size {
|
||||
HDMI_AUDIO_SAMPLE_16BITS = 0,
|
||||
HDMI_AUDIO_SAMPLE_24BITS = 1
|
||||
};
|
||||
|
||||
enum hdmi_audio_transf_mode {
|
||||
HDMI_AUDIO_TRANSF_DMA = 0,
|
||||
HDMI_AUDIO_TRANSF_IRQ = 1
|
||||
};
|
||||
|
||||
enum hdmi_audio_blk_strt_end_sig {
|
||||
HDMI_AUDIO_BLOCK_SIG_STARTEND_ON = 0,
|
||||
HDMI_AUDIO_BLOCK_SIG_STARTEND_OFF = 1
|
||||
};
|
||||
|
||||
enum hdmi_audio_i2s_config {
|
||||
HDMI_AUDIO_I2S_WS_POLARITY_LOW_IS_LEFT = 0,
|
||||
HDMI_AUDIO_I2S_WS_POLARIT_YLOW_IS_RIGHT = 1,
|
||||
HDMI_AUDIO_I2S_MSB_SHIFTED_FIRST = 0,
|
||||
HDMI_AUDIO_I2S_LSB_SHIFTED_FIRST = 1,
|
||||
HDMI_AUDIO_I2S_MAX_WORD_20BITS = 0,
|
||||
HDMI_AUDIO_I2S_MAX_WORD_24BITS = 1,
|
||||
HDMI_AUDIO_I2S_CHST_WORD_NOT_SPECIFIED = 0,
|
||||
HDMI_AUDIO_I2S_CHST_WORD_16_BITS = 1,
|
||||
HDMI_AUDIO_I2S_CHST_WORD_17_BITS = 6,
|
||||
HDMI_AUDIO_I2S_CHST_WORD_18_BITS = 2,
|
||||
HDMI_AUDIO_I2S_CHST_WORD_19_BITS = 4,
|
||||
HDMI_AUDIO_I2S_CHST_WORD_20_BITS_20MAX = 5,
|
||||
HDMI_AUDIO_I2S_CHST_WORD_20_BITS_24MAX = 1,
|
||||
HDMI_AUDIO_I2S_CHST_WORD_21_BITS = 6,
|
||||
HDMI_AUDIO_I2S_CHST_WORD_22_BITS = 2,
|
||||
HDMI_AUDIO_I2S_CHST_WORD_23_BITS = 4,
|
||||
HDMI_AUDIO_I2S_CHST_WORD_24_BITS = 5,
|
||||
HDMI_AUDIO_I2S_SCK_EDGE_FALLING = 0,
|
||||
HDMI_AUDIO_I2S_SCK_EDGE_RISING = 1,
|
||||
HDMI_AUDIO_I2S_VBIT_FOR_PCM = 0,
|
||||
HDMI_AUDIO_I2S_VBIT_FOR_COMPRESSED = 1,
|
||||
HDMI_AUDIO_I2S_INPUT_LENGTH_NA = 0,
|
||||
HDMI_AUDIO_I2S_INPUT_LENGTH_16 = 2,
|
||||
HDMI_AUDIO_I2S_INPUT_LENGTH_17 = 12,
|
||||
HDMI_AUDIO_I2S_INPUT_LENGTH_18 = 4,
|
||||
HDMI_AUDIO_I2S_INPUT_LENGTH_19 = 8,
|
||||
HDMI_AUDIO_I2S_INPUT_LENGTH_20 = 10,
|
||||
HDMI_AUDIO_I2S_INPUT_LENGTH_21 = 13,
|
||||
HDMI_AUDIO_I2S_INPUT_LENGTH_22 = 5,
|
||||
HDMI_AUDIO_I2S_INPUT_LENGTH_23 = 9,
|
||||
HDMI_AUDIO_I2S_INPUT_LENGTH_24 = 11,
|
||||
HDMI_AUDIO_I2S_FIRST_BIT_SHIFT = 0,
|
||||
HDMI_AUDIO_I2S_FIRST_BIT_NO_SHIFT = 1,
|
||||
HDMI_AUDIO_I2S_SD0_EN = 1,
|
||||
HDMI_AUDIO_I2S_SD1_EN = 1 << 1,
|
||||
HDMI_AUDIO_I2S_SD2_EN = 1 << 2,
|
||||
HDMI_AUDIO_I2S_SD3_EN = 1 << 3,
|
||||
};
|
||||
|
||||
enum hdmi_audio_mclk_mode {
|
||||
HDMI_AUDIO_MCLK_128FS = 0,
|
||||
HDMI_AUDIO_MCLK_256FS = 1,
|
||||
HDMI_AUDIO_MCLK_384FS = 2,
|
||||
HDMI_AUDIO_MCLK_512FS = 3,
|
||||
HDMI_AUDIO_MCLK_768FS = 4,
|
||||
HDMI_AUDIO_MCLK_1024FS = 5,
|
||||
HDMI_AUDIO_MCLK_1152FS = 6,
|
||||
HDMI_AUDIO_MCLK_192FS = 7
|
||||
};
|
||||
|
||||
struct hdmi_core_video_config {
|
||||
enum hdmi_core_inputbus_width ip_bus_width;
|
||||
enum hdmi_core_dither_trunc op_dither_truc;
|
||||
|
@ -376,6 +530,19 @@ struct hdmi_core_infoframe_avi {
|
|||
u16 db12_13_pixel_sofright;
|
||||
/* Pixel number start of right bar */
|
||||
};
|
||||
/*
|
||||
* Refer to section 8.2 in HDMI 1.3 specification for
|
||||
* details about infoframe databytes
|
||||
*/
|
||||
struct hdmi_core_infoframe_audio {
|
||||
u8 db1_coding_type;
|
||||
u8 db1_channel_count;
|
||||
u8 db2_sample_freq;
|
||||
u8 db2_sample_size;
|
||||
u8 db4_channel_alloc;
|
||||
bool db5_downmix_inh;
|
||||
u8 db5_lsv; /* Level shift values for downmix */
|
||||
};
|
||||
|
||||
struct hdmi_core_packet_enable_repeat {
|
||||
u32 audio_pkt;
|
||||
|
@ -412,4 +579,53 @@ struct hdmi_config {
|
|||
struct hdmi_cm cm;
|
||||
};
|
||||
|
||||
struct hdmi_audio_format {
|
||||
enum hdmi_stereo_channels stereo_channels;
|
||||
u8 active_chnnls_msk;
|
||||
enum hdmi_audio_type type;
|
||||
enum hdmi_audio_justify justification;
|
||||
enum hdmi_audio_sample_order sample_order;
|
||||
enum hdmi_audio_samples_perword samples_per_word;
|
||||
enum hdmi_audio_sample_size sample_size;
|
||||
enum hdmi_audio_blk_strt_end_sig en_sig_blk_strt_end;
|
||||
};
|
||||
|
||||
struct hdmi_audio_dma {
|
||||
u8 transfer_size;
|
||||
u8 block_size;
|
||||
enum hdmi_audio_transf_mode mode;
|
||||
u16 fifo_threshold;
|
||||
};
|
||||
|
||||
struct hdmi_core_audio_i2s_config {
|
||||
u8 word_max_length;
|
||||
u8 word_length;
|
||||
u8 in_length_bits;
|
||||
u8 justification;
|
||||
u8 en_high_bitrate_aud;
|
||||
u8 sck_edge_mode;
|
||||
u8 cbit_order;
|
||||
u8 vbit;
|
||||
u8 ws_polarity;
|
||||
u8 direction;
|
||||
u8 shift;
|
||||
u8 active_sds;
|
||||
};
|
||||
|
||||
struct hdmi_core_audio_config {
|
||||
struct hdmi_core_audio_i2s_config i2s_cfg;
|
||||
enum hdmi_core_audio_sample_freq freq_sample;
|
||||
bool fs_override;
|
||||
u32 n;
|
||||
u32 cts;
|
||||
u32 aud_par_busclk;
|
||||
enum hdmi_core_audio_layout layout;
|
||||
enum hdmi_core_cts_mode cts_mode;
|
||||
bool use_mclk;
|
||||
enum hdmi_audio_mclk_mode mclk_mode;
|
||||
bool en_acr_pkt;
|
||||
bool en_dsd_audio;
|
||||
bool en_parallel_aud_input;
|
||||
bool en_spdif;
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include <linux/io.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/module.h>
|
||||
#include <plat/display.h>
|
||||
#include <video/omapdss.h>
|
||||
|
||||
#include "dss.h"
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
#include <linux/spinlock.h>
|
||||
#include <linux/jiffies.h>
|
||||
|
||||
#include <plat/display.h>
|
||||
#include <video/omapdss.h>
|
||||
#include <plat/cpu.h>
|
||||
|
||||
#include "dss.h"
|
||||
|
@ -393,6 +393,7 @@ struct overlay_cache_data {
|
|||
|
||||
u32 paddr;
|
||||
void __iomem *vaddr;
|
||||
u32 p_uv_addr; /* relevant for NV12 format only */
|
||||
u16 screen_width;
|
||||
u16 width;
|
||||
u16 height;
|
||||
|
@ -775,10 +776,17 @@ static int configure_overlay(enum omap_plane plane)
|
|||
}
|
||||
|
||||
switch (c->color_mode) {
|
||||
case OMAP_DSS_COLOR_NV12:
|
||||
bpp = 8;
|
||||
break;
|
||||
case OMAP_DSS_COLOR_RGB16:
|
||||
case OMAP_DSS_COLOR_ARGB16:
|
||||
case OMAP_DSS_COLOR_YUV2:
|
||||
case OMAP_DSS_COLOR_UYVY:
|
||||
case OMAP_DSS_COLOR_RGBA16:
|
||||
case OMAP_DSS_COLOR_RGBX16:
|
||||
case OMAP_DSS_COLOR_ARGB16_1555:
|
||||
case OMAP_DSS_COLOR_XRGB16_1555:
|
||||
bpp = 16;
|
||||
break;
|
||||
|
||||
|
@ -854,7 +862,8 @@ static int configure_overlay(enum omap_plane plane)
|
|||
c->mirror,
|
||||
c->global_alpha,
|
||||
c->pre_mult_alpha,
|
||||
c->channel);
|
||||
c->channel,
|
||||
c->p_uv_addr);
|
||||
|
||||
if (r) {
|
||||
/* this shouldn't happen */
|
||||
|
@ -1269,6 +1278,7 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
|
|||
|
||||
oc->paddr = ovl->info.paddr;
|
||||
oc->vaddr = ovl->info.vaddr;
|
||||
oc->p_uv_addr = ovl->info.p_uv_addr;
|
||||
oc->screen_width = ovl->info.screen_width;
|
||||
oc->width = ovl->info.width;
|
||||
oc->height = ovl->info.height;
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
#include <linux/delay.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <plat/display.h>
|
||||
#include <video/omapdss.h>
|
||||
#include <plat/cpu.h>
|
||||
|
||||
#include "dss.h"
|
||||
|
@ -201,12 +201,16 @@ static ssize_t overlay_enabled_show(struct omap_overlay *ovl, char *buf)
|
|||
static ssize_t overlay_enabled_store(struct omap_overlay *ovl, const char *buf,
|
||||
size_t size)
|
||||
{
|
||||
int r;
|
||||
int r, enable;
|
||||
struct omap_overlay_info info;
|
||||
|
||||
ovl->get_overlay_info(ovl, &info);
|
||||
|
||||
info.enabled = simple_strtoul(buf, NULL, 10);
|
||||
r = kstrtoint(buf, 0, &enable);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
info.enabled = !!enable;
|
||||
|
||||
r = ovl->set_overlay_info(ovl, &info);
|
||||
if (r)
|
||||
|
@ -231,8 +235,13 @@ static ssize_t overlay_global_alpha_store(struct omap_overlay *ovl,
|
|||
const char *buf, size_t size)
|
||||
{
|
||||
int r;
|
||||
u8 alpha;
|
||||
struct omap_overlay_info info;
|
||||
|
||||
r = kstrtou8(buf, 0, &alpha);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
ovl->get_overlay_info(ovl, &info);
|
||||
|
||||
/* Video1 plane does not support global alpha
|
||||
|
@ -242,7 +251,7 @@ static ssize_t overlay_global_alpha_store(struct omap_overlay *ovl,
|
|||
ovl->id == OMAP_DSS_VIDEO1)
|
||||
info.global_alpha = 255;
|
||||
else
|
||||
info.global_alpha = simple_strtoul(buf, NULL, 10);
|
||||
info.global_alpha = alpha;
|
||||
|
||||
r = ovl->set_overlay_info(ovl, &info);
|
||||
if (r)
|
||||
|
@ -268,8 +277,13 @@ static ssize_t overlay_pre_mult_alpha_store(struct omap_overlay *ovl,
|
|||
const char *buf, size_t size)
|
||||
{
|
||||
int r;
|
||||
u8 alpha;
|
||||
struct omap_overlay_info info;
|
||||
|
||||
r = kstrtou8(buf, 0, &alpha);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
ovl->get_overlay_info(ovl, &info);
|
||||
|
||||
/* only GFX and Video2 plane support pre alpha multiplied
|
||||
|
@ -279,7 +293,7 @@ static ssize_t overlay_pre_mult_alpha_store(struct omap_overlay *ovl,
|
|||
ovl->id == OMAP_DSS_VIDEO1)
|
||||
info.pre_mult_alpha = 0;
|
||||
else
|
||||
info.pre_mult_alpha = simple_strtoul(buf, NULL, 10);
|
||||
info.pre_mult_alpha = alpha;
|
||||
|
||||
r = ovl->set_overlay_info(ovl, &info);
|
||||
if (r)
|
||||
|
@ -491,13 +505,18 @@ static int omap_dss_set_manager(struct omap_overlay *ovl,
|
|||
ovl->manager = mgr;
|
||||
|
||||
dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
|
||||
/* XXX: on manual update display, in auto update mode, a bug happens
|
||||
* here. When an overlay is first enabled on LCD, then it's disabled,
|
||||
* and the manager is changed to TV, we sometimes get SYNC_LOST_DIGIT
|
||||
* errors. Waiting before changing the channel_out fixes it. I'm
|
||||
* guessing that the overlay is still somehow being used for the LCD,
|
||||
* but I don't understand how or why. */
|
||||
msleep(40);
|
||||
/* XXX: When there is an overlay on a DSI manual update display, and
|
||||
* the overlay is first disabled, then moved to tv, and enabled, we
|
||||
* seem to get SYNC_LOST_DIGIT error.
|
||||
*
|
||||
* Waiting doesn't seem to help, but updating the manual update display
|
||||
* after disabling the overlay seems to fix this. This hints that the
|
||||
* overlay is perhaps somehow tied to the LCD output until the output
|
||||
* is updated.
|
||||
*
|
||||
* Userspace workaround for this is to update the LCD after disabling
|
||||
* the overlay, but before moving the overlay to TV.
|
||||
*/
|
||||
dispc_set_channel_out(ovl->id, mgr->id);
|
||||
dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
|
||||
|
||||
|
|
|
@ -32,8 +32,9 @@
|
|||
#include <linux/ktime.h>
|
||||
#include <linux/hrtimer.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/semaphore.h>
|
||||
|
||||
#include <plat/display.h>
|
||||
#include <video/omapdss.h>
|
||||
#include "dss.h"
|
||||
|
||||
struct rfbi_reg { u16 idx; };
|
||||
|
@ -65,9 +66,6 @@ struct rfbi_reg { u16 idx; };
|
|||
#define REG_FLD_MOD(idx, val, start, end) \
|
||||
rfbi_write_reg(idx, FLD_MOD(rfbi_read_reg(idx), val, start, end))
|
||||
|
||||
/* To work around an RFBI transfer rate limitation */
|
||||
#define OMAP_RFBI_RATE_LIMIT 1
|
||||
|
||||
enum omap_rfbi_cycleformat {
|
||||
OMAP_DSS_RFBI_CYCLEFORMAT_1_1 = 0,
|
||||
OMAP_DSS_RFBI_CYCLEFORMAT_2_1 = 1,
|
||||
|
@ -89,11 +87,6 @@ enum omap_rfbi_parallelmode {
|
|||
OMAP_DSS_RFBI_PARALLELMODE_16 = 3,
|
||||
};
|
||||
|
||||
enum update_cmd {
|
||||
RFBI_CMD_UPDATE = 0,
|
||||
RFBI_CMD_SYNC = 1,
|
||||
};
|
||||
|
||||
static int rfbi_convert_timings(struct rfbi_timings *t);
|
||||
static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div);
|
||||
|
||||
|
@ -114,20 +107,9 @@ static struct {
|
|||
|
||||
struct omap_dss_device *dssdev[2];
|
||||
|
||||
struct kfifo cmd_fifo;
|
||||
spinlock_t cmd_lock;
|
||||
struct completion cmd_done;
|
||||
atomic_t cmd_fifo_full;
|
||||
atomic_t cmd_pending;
|
||||
struct semaphore bus_lock;
|
||||
} rfbi;
|
||||
|
||||
struct update_region {
|
||||
u16 x;
|
||||
u16 y;
|
||||
u16 w;
|
||||
u16 h;
|
||||
};
|
||||
|
||||
static inline void rfbi_write_reg(const struct rfbi_reg idx, u32 val)
|
||||
{
|
||||
__raw_writel(val, rfbi.base + idx.idx);
|
||||
|
@ -146,9 +128,20 @@ static void rfbi_enable_clocks(bool enable)
|
|||
dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
|
||||
}
|
||||
|
||||
void rfbi_bus_lock(void)
|
||||
{
|
||||
down(&rfbi.bus_lock);
|
||||
}
|
||||
EXPORT_SYMBOL(rfbi_bus_lock);
|
||||
|
||||
void rfbi_bus_unlock(void)
|
||||
{
|
||||
up(&rfbi.bus_lock);
|
||||
}
|
||||
EXPORT_SYMBOL(rfbi_bus_unlock);
|
||||
|
||||
void omap_rfbi_write_command(const void *buf, u32 len)
|
||||
{
|
||||
rfbi_enable_clocks(1);
|
||||
switch (rfbi.parallelmode) {
|
||||
case OMAP_DSS_RFBI_PARALLELMODE_8:
|
||||
{
|
||||
|
@ -172,13 +165,11 @@ void omap_rfbi_write_command(const void *buf, u32 len)
|
|||
default:
|
||||
BUG();
|
||||
}
|
||||
rfbi_enable_clocks(0);
|
||||
}
|
||||
EXPORT_SYMBOL(omap_rfbi_write_command);
|
||||
|
||||
void omap_rfbi_read_data(void *buf, u32 len)
|
||||
{
|
||||
rfbi_enable_clocks(1);
|
||||
switch (rfbi.parallelmode) {
|
||||
case OMAP_DSS_RFBI_PARALLELMODE_8:
|
||||
{
|
||||
|
@ -206,13 +197,11 @@ void omap_rfbi_read_data(void *buf, u32 len)
|
|||
default:
|
||||
BUG();
|
||||
}
|
||||
rfbi_enable_clocks(0);
|
||||
}
|
||||
EXPORT_SYMBOL(omap_rfbi_read_data);
|
||||
|
||||
void omap_rfbi_write_data(const void *buf, u32 len)
|
||||
{
|
||||
rfbi_enable_clocks(1);
|
||||
switch (rfbi.parallelmode) {
|
||||
case OMAP_DSS_RFBI_PARALLELMODE_8:
|
||||
{
|
||||
|
@ -237,7 +226,6 @@ void omap_rfbi_write_data(const void *buf, u32 len)
|
|||
BUG();
|
||||
|
||||
}
|
||||
rfbi_enable_clocks(0);
|
||||
}
|
||||
EXPORT_SYMBOL(omap_rfbi_write_data);
|
||||
|
||||
|
@ -249,8 +237,6 @@ void omap_rfbi_write_pixels(const void __iomem *buf, int scr_width,
|
|||
int horiz_offset = scr_width - w;
|
||||
int i;
|
||||
|
||||
rfbi_enable_clocks(1);
|
||||
|
||||
if (rfbi.datatype == OMAP_DSS_RFBI_DATATYPE_16 &&
|
||||
rfbi.parallelmode == OMAP_DSS_RFBI_PARALLELMODE_8) {
|
||||
const u16 __iomem *pd = buf;
|
||||
|
@ -295,12 +281,10 @@ void omap_rfbi_write_pixels(const void __iomem *buf, int scr_width,
|
|||
} else {
|
||||
BUG();
|
||||
}
|
||||
|
||||
rfbi_enable_clocks(0);
|
||||
}
|
||||
EXPORT_SYMBOL(omap_rfbi_write_pixels);
|
||||
|
||||
void rfbi_transfer_area(struct omap_dss_device *dssdev, u16 width,
|
||||
static void rfbi_transfer_area(struct omap_dss_device *dssdev, u16 width,
|
||||
u16 height, void (*callback)(void *data), void *data)
|
||||
{
|
||||
u32 l;
|
||||
|
@ -317,8 +301,6 @@ void rfbi_transfer_area(struct omap_dss_device *dssdev, u16 width,
|
|||
rfbi.framedone_callback = callback;
|
||||
rfbi.framedone_callback_data = data;
|
||||
|
||||
rfbi_enable_clocks(1);
|
||||
|
||||
rfbi_write_reg(RFBI_PIXEL_CNT, width * height);
|
||||
|
||||
l = rfbi_read_reg(RFBI_CONTROL);
|
||||
|
@ -337,15 +319,11 @@ static void framedone_callback(void *data, u32 mask)
|
|||
|
||||
REG_FLD_MOD(RFBI_CONTROL, 0, 0, 0);
|
||||
|
||||
rfbi_enable_clocks(0);
|
||||
|
||||
callback = rfbi.framedone_callback;
|
||||
rfbi.framedone_callback = NULL;
|
||||
|
||||
if (callback != NULL)
|
||||
callback(rfbi.framedone_callback_data);
|
||||
|
||||
atomic_set(&rfbi.cmd_pending, 0);
|
||||
}
|
||||
|
||||
#if 1 /* VERBOSE */
|
||||
|
@ -435,7 +413,7 @@ static int calc_extif_timings(struct rfbi_timings *t)
|
|||
}
|
||||
|
||||
|
||||
void rfbi_set_timings(int rfbi_module, struct rfbi_timings *t)
|
||||
static void rfbi_set_timings(int rfbi_module, struct rfbi_timings *t)
|
||||
{
|
||||
int r;
|
||||
|
||||
|
@ -447,7 +425,6 @@ void rfbi_set_timings(int rfbi_module, struct rfbi_timings *t)
|
|||
|
||||
BUG_ON(!t->converted);
|
||||
|
||||
rfbi_enable_clocks(1);
|
||||
rfbi_write_reg(RFBI_ONOFF_TIME(rfbi_module), t->tim[0]);
|
||||
rfbi_write_reg(RFBI_CYCLE_TIME(rfbi_module), t->tim[1]);
|
||||
|
||||
|
@ -456,7 +433,6 @@ void rfbi_set_timings(int rfbi_module, struct rfbi_timings *t)
|
|||
(t->tim[2] ? 1 : 0), 4, 4);
|
||||
|
||||
rfbi_print_timings();
|
||||
rfbi_enable_clocks(0);
|
||||
}
|
||||
|
||||
static int ps_to_rfbi_ticks(int time, int div)
|
||||
|
@ -472,59 +448,6 @@ static int ps_to_rfbi_ticks(int time, int div)
|
|||
return ret;
|
||||
}
|
||||
|
||||
#ifdef OMAP_RFBI_RATE_LIMIT
|
||||
unsigned long rfbi_get_max_tx_rate(void)
|
||||
{
|
||||
unsigned long l4_rate, dss1_rate;
|
||||
int min_l4_ticks = 0;
|
||||
int i;
|
||||
|
||||
/* According to TI this can't be calculated so make the
|
||||
* adjustments for a couple of known frequencies and warn for
|
||||
* others.
|
||||
*/
|
||||
static const struct {
|
||||
unsigned long l4_clk; /* HZ */
|
||||
unsigned long dss1_clk; /* HZ */
|
||||
unsigned long min_l4_ticks;
|
||||
} ftab[] = {
|
||||
{ 55, 132, 7, }, /* 7.86 MPix/s */
|
||||
{ 110, 110, 12, }, /* 9.16 MPix/s */
|
||||
{ 110, 132, 10, }, /* 11 Mpix/s */
|
||||
{ 120, 120, 10, }, /* 12 Mpix/s */
|
||||
{ 133, 133, 10, }, /* 13.3 Mpix/s */
|
||||
};
|
||||
|
||||
l4_rate = rfbi.l4_khz / 1000;
|
||||
dss1_rate = dss_clk_get_rate(DSS_CLK_FCK) / 1000000;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ftab); i++) {
|
||||
/* Use a window instead of an exact match, to account
|
||||
* for different DPLL multiplier / divider pairs.
|
||||
*/
|
||||
if (abs(ftab[i].l4_clk - l4_rate) < 3 &&
|
||||
abs(ftab[i].dss1_clk - dss1_rate) < 3) {
|
||||
min_l4_ticks = ftab[i].min_l4_ticks;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == ARRAY_SIZE(ftab)) {
|
||||
/* Can't be sure, return anyway the maximum not
|
||||
* rate-limited. This might cause a problem only for the
|
||||
* tearing synchronisation.
|
||||
*/
|
||||
DSSERR("can't determine maximum RFBI transfer rate\n");
|
||||
return rfbi.l4_khz * 1000;
|
||||
}
|
||||
return rfbi.l4_khz * 1000 / min_l4_ticks;
|
||||
}
|
||||
#else
|
||||
int rfbi_get_max_tx_rate(void)
|
||||
{
|
||||
return rfbi.l4_khz * 1000;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div)
|
||||
{
|
||||
*clk_period = 1000000000 / rfbi.l4_khz;
|
||||
|
@ -644,7 +567,6 @@ int omap_rfbi_setup_te(enum omap_rfbi_te_mode mode,
|
|||
DSSDBG("setup_te: mode %d hs %d vs %d hs_inv %d vs_inv %d\n",
|
||||
mode, hs, vs, hs_pol_inv, vs_pol_inv);
|
||||
|
||||
rfbi_enable_clocks(1);
|
||||
rfbi_write_reg(RFBI_HSYNC_WIDTH, hs);
|
||||
rfbi_write_reg(RFBI_VSYNC_WIDTH, vs);
|
||||
|
||||
|
@ -657,7 +579,6 @@ int omap_rfbi_setup_te(enum omap_rfbi_te_mode mode,
|
|||
l &= ~(1 << 20);
|
||||
else
|
||||
l |= 1 << 20;
|
||||
rfbi_enable_clocks(0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -672,7 +593,6 @@ int omap_rfbi_enable_te(bool enable, unsigned line)
|
|||
if (line > (1 << 11) - 1)
|
||||
return -EINVAL;
|
||||
|
||||
rfbi_enable_clocks(1);
|
||||
l = rfbi_read_reg(RFBI_CONFIG(0));
|
||||
l &= ~(0x3 << 2);
|
||||
if (enable) {
|
||||
|
@ -682,50 +602,12 @@ int omap_rfbi_enable_te(bool enable, unsigned line)
|
|||
rfbi.te_enabled = 0;
|
||||
rfbi_write_reg(RFBI_CONFIG(0), l);
|
||||
rfbi_write_reg(RFBI_LINE_NUMBER, line);
|
||||
rfbi_enable_clocks(0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(omap_rfbi_enable_te);
|
||||
|
||||
#if 0
|
||||
static void rfbi_enable_config(int enable1, int enable2)
|
||||
{
|
||||
u32 l;
|
||||
int cs = 0;
|
||||
|
||||
if (enable1)
|
||||
cs |= 1<<0;
|
||||
if (enable2)
|
||||
cs |= 1<<1;
|
||||
|
||||
rfbi_enable_clocks(1);
|
||||
|
||||
l = rfbi_read_reg(RFBI_CONTROL);
|
||||
|
||||
l = FLD_MOD(l, cs, 3, 2);
|
||||
l = FLD_MOD(l, 0, 1, 1);
|
||||
|
||||
rfbi_write_reg(RFBI_CONTROL, l);
|
||||
|
||||
|
||||
l = rfbi_read_reg(RFBI_CONFIG(0));
|
||||
l = FLD_MOD(l, 0, 3, 2); /* TRIGGERMODE: ITE */
|
||||
/*l |= FLD_VAL(2, 8, 7); */ /* L4FORMAT, 2pix/L4 */
|
||||
/*l |= FLD_VAL(0, 8, 7); */ /* L4FORMAT, 1pix/L4 */
|
||||
|
||||
l = FLD_MOD(l, 0, 16, 16); /* A0POLARITY */
|
||||
l = FLD_MOD(l, 1, 20, 20); /* TE_VSYNC_POLARITY */
|
||||
l = FLD_MOD(l, 1, 21, 21); /* HSYNCPOLARITY */
|
||||
|
||||
l = FLD_MOD(l, OMAP_DSS_RFBI_PARALLELMODE_8, 1, 0);
|
||||
rfbi_write_reg(RFBI_CONFIG(0), l);
|
||||
|
||||
rfbi_enable_clocks(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
int rfbi_configure(int rfbi_module, int bpp, int lines)
|
||||
static int rfbi_configure(int rfbi_module, int bpp, int lines)
|
||||
{
|
||||
u32 l;
|
||||
int cycle1 = 0, cycle2 = 0, cycle3 = 0;
|
||||
|
@ -821,8 +703,6 @@ int rfbi_configure(int rfbi_module, int bpp, int lines)
|
|||
break;
|
||||
}
|
||||
|
||||
rfbi_enable_clocks(1);
|
||||
|
||||
REG_FLD_MOD(RFBI_CONTROL, 0, 3, 2); /* clear CS */
|
||||
|
||||
l = 0;
|
||||
|
@ -856,11 +736,15 @@ int rfbi_configure(int rfbi_module, int bpp, int lines)
|
|||
DSSDBG("RFBI config: bpp %d, lines %d, cycles: 0x%x 0x%x 0x%x\n",
|
||||
bpp, lines, cycle1, cycle2, cycle3);
|
||||
|
||||
rfbi_enable_clocks(0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(rfbi_configure);
|
||||
|
||||
int omap_rfbi_configure(struct omap_dss_device *dssdev, int pixel_size,
|
||||
int data_lines)
|
||||
{
|
||||
return rfbi_configure(dssdev->phy.rfbi.channel, pixel_size, data_lines);
|
||||
}
|
||||
EXPORT_SYMBOL(omap_rfbi_configure);
|
||||
|
||||
int omap_rfbi_prepare_update(struct omap_dss_device *dssdev,
|
||||
u16 *x, u16 *y, u16 *w, u16 *h)
|
||||
|
@ -960,6 +844,8 @@ int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
|
|||
{
|
||||
int r;
|
||||
|
||||
rfbi_enable_clocks(1);
|
||||
|
||||
r = omap_dss_start_device(dssdev);
|
||||
if (r) {
|
||||
DSSERR("failed to start device\n");
|
||||
|
@ -1002,6 +888,8 @@ void omapdss_rfbi_display_disable(struct omap_dss_device *dssdev)
|
|||
omap_dispc_unregister_isr(framedone_callback, NULL,
|
||||
DISPC_IRQ_FRAMEDONE);
|
||||
omap_dss_stop_device(dssdev);
|
||||
|
||||
rfbi_enable_clocks(0);
|
||||
}
|
||||
EXPORT_SYMBOL(omapdss_rfbi_display_disable);
|
||||
|
||||
|
@ -1021,11 +909,7 @@ static int omap_rfbihw_probe(struct platform_device *pdev)
|
|||
|
||||
rfbi.pdev = pdev;
|
||||
|
||||
spin_lock_init(&rfbi.cmd_lock);
|
||||
|
||||
init_completion(&rfbi.cmd_done);
|
||||
atomic_set(&rfbi.cmd_fifo_full, 0);
|
||||
atomic_set(&rfbi.cmd_pending, 0);
|
||||
sema_init(&rfbi.bus_lock, 1);
|
||||
|
||||
rfbi_mem = platform_get_resource(rfbi.pdev, IORESOURCE_MEM, 0);
|
||||
if (!rfbi_mem) {
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include <linux/err.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
||||
#include <plat/display.h>
|
||||
#include <video/omapdss.h>
|
||||
#include <plat/cpu.h>
|
||||
#include "dss.h"
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
#include <linux/platform_device.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
||||
#include <plat/display.h>
|
||||
#include <video/omapdss.h>
|
||||
#include <plat/cpu.h>
|
||||
|
||||
#include "dss.h"
|
||||
|
@ -373,8 +373,11 @@ static void venc_reset(void)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OMAP2_DSS_SLEEP_AFTER_VENC_RESET
|
||||
/* the magical sleep that makes things work */
|
||||
/* XXX more info? What bug this circumvents? */
|
||||
msleep(20);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void venc_enable_clocks(int enable)
|
||||
|
@ -473,6 +476,12 @@ static int venc_panel_enable(struct omap_dss_device *dssdev)
|
|||
|
||||
mutex_lock(&venc.venc_lock);
|
||||
|
||||
r = omap_dss_start_device(dssdev);
|
||||
if (r) {
|
||||
DSSERR("failed to start device\n");
|
||||
goto err0;
|
||||
}
|
||||
|
||||
if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
|
||||
r = -EINVAL;
|
||||
goto err1;
|
||||
|
@ -484,10 +493,11 @@ static int venc_panel_enable(struct omap_dss_device *dssdev)
|
|||
|
||||
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
|
||||
|
||||
/* wait couple of vsyncs until enabling the LCD */
|
||||
msleep(50);
|
||||
|
||||
mutex_unlock(&venc.venc_lock);
|
||||
return 0;
|
||||
err1:
|
||||
omap_dss_stop_device(dssdev);
|
||||
err0:
|
||||
mutex_unlock(&venc.venc_lock);
|
||||
|
||||
return r;
|
||||
|
@ -510,10 +520,9 @@ static void venc_panel_disable(struct omap_dss_device *dssdev)
|
|||
|
||||
venc_power_off(dssdev);
|
||||
|
||||
/* wait at least 5 vsyncs after disabling the LCD */
|
||||
msleep(100);
|
||||
|
||||
dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
|
||||
|
||||
omap_dss_stop_device(dssdev);
|
||||
end:
|
||||
mutex_unlock(&venc.venc_lock);
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#include <linux/omapfb.h>
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
#include <plat/display.h>
|
||||
#include <video/omapdss.h>
|
||||
#include <plat/vrfb.h>
|
||||
#include <plat/vram.h>
|
||||
|
||||
|
@ -895,8 +895,16 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
|
|||
|
||||
p.display_info.xres = xres;
|
||||
p.display_info.yres = yres;
|
||||
p.display_info.width = 0;
|
||||
p.display_info.height = 0;
|
||||
|
||||
if (display->driver->get_dimensions) {
|
||||
u32 w, h;
|
||||
display->driver->get_dimensions(display, &w, &h);
|
||||
p.display_info.width = w;
|
||||
p.display_info.height = h;
|
||||
} else {
|
||||
p.display_info.width = 0;
|
||||
p.display_info.height = 0;
|
||||
}
|
||||
|
||||
if (copy_to_user((void __user *)arg, &p.display_info,
|
||||
sizeof(p.display_info)))
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
#include <linux/platform_device.h>
|
||||
#include <linux/omapfb.h>
|
||||
|
||||
#include <plat/display.h>
|
||||
#include <video/omapdss.h>
|
||||
#include <plat/vram.h>
|
||||
#include <plat/vrfb.h>
|
||||
|
||||
|
@ -702,8 +702,16 @@ int check_fb_var(struct fb_info *fbi, struct fb_var_screeninfo *var)
|
|||
var->xres, var->yres,
|
||||
var->xres_virtual, var->yres_virtual);
|
||||
|
||||
var->height = -1;
|
||||
var->width = -1;
|
||||
if (display && display->driver->get_dimensions) {
|
||||
u32 w, h;
|
||||
display->driver->get_dimensions(display, &w, &h);
|
||||
var->width = DIV_ROUND_CLOSEST(w, 1000);
|
||||
var->height = DIV_ROUND_CLOSEST(h, 1000);
|
||||
} else {
|
||||
var->height = -1;
|
||||
var->width = -1;
|
||||
}
|
||||
|
||||
var->grayscale = 0;
|
||||
|
||||
if (display && display->driver->get_timings) {
|
||||
|
@ -749,35 +757,6 @@ static int omapfb_open(struct fb_info *fbi, int user)
|
|||
|
||||
static int omapfb_release(struct fb_info *fbi, int user)
|
||||
{
|
||||
#if 0
|
||||
struct omapfb_info *ofbi = FB2OFB(fbi);
|
||||
struct omapfb2_device *fbdev = ofbi->fbdev;
|
||||
struct omap_dss_device *display = fb2display(fbi);
|
||||
|
||||
DBG("Closing fb with plane index %d\n", ofbi->id);
|
||||
|
||||
omapfb_lock(fbdev);
|
||||
|
||||
if (display && display->get_update_mode && display->update) {
|
||||
/* XXX this update should be removed, I think. But it's
|
||||
* good for debugging */
|
||||
if (display->get_update_mode(display) ==
|
||||
OMAP_DSS_UPDATE_MANUAL) {
|
||||
u16 w, h;
|
||||
|
||||
if (display->sync)
|
||||
display->sync(display);
|
||||
|
||||
display->get_resolution(display, &w, &h);
|
||||
display->update(display, 0, 0, w, h);
|
||||
}
|
||||
}
|
||||
|
||||
if (display && display->sync)
|
||||
display->sync(display);
|
||||
|
||||
omapfb_unlock(fbdev);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1263,7 +1242,6 @@ static int omapfb_blank(int blank, struct fb_info *fbi)
|
|||
struct omapfb_info *ofbi = FB2OFB(fbi);
|
||||
struct omapfb2_device *fbdev = ofbi->fbdev;
|
||||
struct omap_dss_device *display = fb2display(fbi);
|
||||
int do_update = 0;
|
||||
int r = 0;
|
||||
|
||||
if (!display)
|
||||
|
@ -1279,11 +1257,6 @@ static int omapfb_blank(int blank, struct fb_info *fbi)
|
|||
if (display->driver->resume)
|
||||
r = display->driver->resume(display);
|
||||
|
||||
if (r == 0 && display->driver->get_update_mode &&
|
||||
display->driver->get_update_mode(display) ==
|
||||
OMAP_DSS_UPDATE_MANUAL)
|
||||
do_update = 1;
|
||||
|
||||
break;
|
||||
|
||||
case FB_BLANK_NORMAL:
|
||||
|
@ -1307,13 +1280,6 @@ static int omapfb_blank(int blank, struct fb_info *fbi)
|
|||
exit:
|
||||
omapfb_unlock(fbdev);
|
||||
|
||||
if (r == 0 && do_update && display->driver->update) {
|
||||
u16 w, h;
|
||||
display->driver->get_resolution(display, &w, &h);
|
||||
|
||||
r = display->driver->update(display, 0, 0, w, h);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -2030,9 +1996,9 @@ static int omapfb_create_framebuffers(struct omapfb2_device *fbdev)
|
|||
static int omapfb_mode_to_timings(const char *mode_str,
|
||||
struct omap_video_timings *timings, u8 *bpp)
|
||||
{
|
||||
struct fb_info fbi;
|
||||
struct fb_var_screeninfo var;
|
||||
struct fb_ops fbops;
|
||||
struct fb_info *fbi;
|
||||
struct fb_var_screeninfo *var;
|
||||
struct fb_ops *fbops;
|
||||
int r;
|
||||
|
||||
#ifdef CONFIG_OMAP2_DSS_VENC
|
||||
|
@ -2050,39 +2016,66 @@ static int omapfb_mode_to_timings(const char *mode_str,
|
|||
/* this is quite a hack, but I wanted to use the modedb and for
|
||||
* that we need fb_info and var, so we create dummy ones */
|
||||
|
||||
memset(&fbi, 0, sizeof(fbi));
|
||||
memset(&var, 0, sizeof(var));
|
||||
memset(&fbops, 0, sizeof(fbops));
|
||||
fbi.fbops = &fbops;
|
||||
*bpp = 0;
|
||||
fbi = NULL;
|
||||
var = NULL;
|
||||
fbops = NULL;
|
||||
|
||||
r = fb_find_mode(&var, &fbi, mode_str, NULL, 0, NULL, 24);
|
||||
|
||||
if (r != 0) {
|
||||
timings->pixel_clock = PICOS2KHZ(var.pixclock);
|
||||
timings->hbp = var.left_margin;
|
||||
timings->hfp = var.right_margin;
|
||||
timings->vbp = var.upper_margin;
|
||||
timings->vfp = var.lower_margin;
|
||||
timings->hsw = var.hsync_len;
|
||||
timings->vsw = var.vsync_len;
|
||||
timings->x_res = var.xres;
|
||||
timings->y_res = var.yres;
|
||||
|
||||
switch (var.bits_per_pixel) {
|
||||
case 16:
|
||||
*bpp = 16;
|
||||
break;
|
||||
case 24:
|
||||
case 32:
|
||||
default:
|
||||
*bpp = 24;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
return -EINVAL;
|
||||
fbi = kzalloc(sizeof(*fbi), GFP_KERNEL);
|
||||
if (fbi == NULL) {
|
||||
r = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
var = kzalloc(sizeof(*var), GFP_KERNEL);
|
||||
if (var == NULL) {
|
||||
r = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
fbops = kzalloc(sizeof(*fbops), GFP_KERNEL);
|
||||
if (fbops == NULL) {
|
||||
r = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
fbi->fbops = fbops;
|
||||
|
||||
r = fb_find_mode(var, fbi, mode_str, NULL, 0, NULL, 24);
|
||||
if (r == 0) {
|
||||
r = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
timings->pixel_clock = PICOS2KHZ(var->pixclock);
|
||||
timings->hbp = var->left_margin;
|
||||
timings->hfp = var->right_margin;
|
||||
timings->vbp = var->upper_margin;
|
||||
timings->vfp = var->lower_margin;
|
||||
timings->hsw = var->hsync_len;
|
||||
timings->vsw = var->vsync_len;
|
||||
timings->x_res = var->xres;
|
||||
timings->y_res = var->yres;
|
||||
|
||||
switch (var->bits_per_pixel) {
|
||||
case 16:
|
||||
*bpp = 16;
|
||||
break;
|
||||
case 24:
|
||||
case 32:
|
||||
default:
|
||||
*bpp = 24;
|
||||
break;
|
||||
}
|
||||
|
||||
r = 0;
|
||||
|
||||
err:
|
||||
kfree(fbi);
|
||||
kfree(var);
|
||||
kfree(fbops);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int omapfb_set_def_mode(struct omapfb2_device *fbdev,
|
||||
|
@ -2185,6 +2178,61 @@ static int omapfb_parse_def_modes(struct omapfb2_device *fbdev)
|
|||
return r;
|
||||
}
|
||||
|
||||
static int omapfb_init_display(struct omapfb2_device *fbdev,
|
||||
struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct omap_dss_driver *dssdrv = dssdev->driver;
|
||||
int r;
|
||||
|
||||
r = dssdrv->enable(dssdev);
|
||||
if (r) {
|
||||
dev_warn(fbdev->dev, "Failed to enable display '%s'\n",
|
||||
dssdev->name);
|
||||
return r;
|
||||
}
|
||||
|
||||
if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
|
||||
u16 w, h;
|
||||
if (dssdrv->enable_te) {
|
||||
r = dssdrv->enable_te(dssdev, 1);
|
||||
if (r) {
|
||||
dev_err(fbdev->dev, "Failed to set TE\n");
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
if (dssdrv->set_update_mode) {
|
||||
r = dssdrv->set_update_mode(dssdev,
|
||||
OMAP_DSS_UPDATE_MANUAL);
|
||||
if (r) {
|
||||
dev_err(fbdev->dev,
|
||||
"Failed to set update mode\n");
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
dssdrv->get_resolution(dssdev, &w, &h);
|
||||
r = dssdrv->update(dssdev, 0, 0, w, h);
|
||||
if (r) {
|
||||
dev_err(fbdev->dev,
|
||||
"Failed to update display\n");
|
||||
return r;
|
||||
}
|
||||
} else {
|
||||
if (dssdrv->set_update_mode) {
|
||||
r = dssdrv->set_update_mode(dssdev,
|
||||
OMAP_DSS_UPDATE_AUTO);
|
||||
if (r) {
|
||||
dev_err(fbdev->dev,
|
||||
"Failed to set update mode\n");
|
||||
return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omapfb_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct omapfb2_device *fbdev = NULL;
|
||||
|
@ -2284,30 +2332,13 @@ static int omapfb_probe(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
if (def_display) {
|
||||
struct omap_dss_driver *dssdrv = def_display->driver;
|
||||
|
||||
r = def_display->driver->enable(def_display);
|
||||
r = omapfb_init_display(fbdev, def_display);
|
||||
if (r) {
|
||||
dev_warn(fbdev->dev, "Failed to enable display '%s'\n",
|
||||
def_display->name);
|
||||
dev_err(fbdev->dev,
|
||||
"failed to initialize default "
|
||||
"display\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (def_display->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
|
||||
u16 w, h;
|
||||
if (dssdrv->enable_te)
|
||||
dssdrv->enable_te(def_display, 1);
|
||||
if (dssdrv->set_update_mode)
|
||||
dssdrv->set_update_mode(def_display,
|
||||
OMAP_DSS_UPDATE_MANUAL);
|
||||
|
||||
dssdrv->get_resolution(def_display, &w, &h);
|
||||
def_display->driver->update(def_display, 0, 0, w, h);
|
||||
} else {
|
||||
if (dssdrv->set_update_mode)
|
||||
dssdrv->set_update_mode(def_display,
|
||||
OMAP_DSS_UPDATE_AUTO);
|
||||
}
|
||||
}
|
||||
|
||||
DBG("create sysfs for fbs\n");
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
#include <linux/mm.h>
|
||||
#include <linux/omapfb.h>
|
||||
|
||||
#include <plat/display.h>
|
||||
#include <video/omapdss.h>
|
||||
#include <plat/vrfb.h>
|
||||
|
||||
#include "omapfb.h"
|
||||
|
@ -50,10 +50,12 @@ static ssize_t store_rotate_type(struct device *dev,
|
|||
struct fb_info *fbi = dev_get_drvdata(dev);
|
||||
struct omapfb_info *ofbi = FB2OFB(fbi);
|
||||
struct omapfb2_mem_region *rg;
|
||||
enum omap_dss_rotation_type rot_type;
|
||||
int rot_type;
|
||||
int r;
|
||||
|
||||
rot_type = simple_strtoul(buf, NULL, 0);
|
||||
r = kstrtoint(buf, 0, &rot_type);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (rot_type != OMAP_DSS_ROT_DMA && rot_type != OMAP_DSS_ROT_VRFB)
|
||||
return -EINVAL;
|
||||
|
@ -102,14 +104,15 @@ static ssize_t store_mirror(struct device *dev,
|
|||
{
|
||||
struct fb_info *fbi = dev_get_drvdata(dev);
|
||||
struct omapfb_info *ofbi = FB2OFB(fbi);
|
||||
unsigned long mirror;
|
||||
int mirror;
|
||||
int r;
|
||||
struct fb_var_screeninfo new_var;
|
||||
|
||||
mirror = simple_strtoul(buf, NULL, 0);
|
||||
r = kstrtoint(buf, 0, &mirror);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (mirror != 0 && mirror != 1)
|
||||
return -EINVAL;
|
||||
mirror = !!mirror;
|
||||
|
||||
if (!lock_fb_info(fbi))
|
||||
return -ENODEV;
|
||||
|
@ -445,7 +448,11 @@ static ssize_t store_size(struct device *dev, struct device_attribute *attr,
|
|||
int r;
|
||||
int i;
|
||||
|
||||
size = PAGE_ALIGN(simple_strtoul(buf, NULL, 0));
|
||||
r = kstrtoul(buf, 0, &size);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
size = PAGE_ALIGN(size);
|
||||
|
||||
if (!lock_fb_info(fbi))
|
||||
return -ENODEV;
|
||||
|
|
|
@ -29,13 +29,15 @@
|
|||
|
||||
#include <linux/rwsem.h>
|
||||
|
||||
#include <plat/display.h>
|
||||
#include <video/omapdss.h>
|
||||
|
||||
#ifdef DEBUG
|
||||
extern unsigned int omapfb_debug;
|
||||
#define DBG(format, ...) \
|
||||
if (omapfb_debug) \
|
||||
printk(KERN_DEBUG "OMAPFB: " format, ## __VA_ARGS__)
|
||||
do { \
|
||||
if (omapfb_debug) \
|
||||
printk(KERN_DEBUG "OMAPFB: " format, ## __VA_ARGS__); \
|
||||
} while (0)
|
||||
#else
|
||||
#define DBG(format, ...)
|
||||
#endif
|
||||
|
|
|
@ -17,10 +17,10 @@
|
|||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_ARM_PLAT_OMAP_PANEL_GENERIC_DPI_H
|
||||
#define __ARCH_ARM_PLAT_OMAP_PANEL_GENERIC_DPI_H
|
||||
#ifndef __OMAP_PANEL_GENERIC_DPI_H
|
||||
#define __OMAP_PANEL_GENERIC_DPI_H
|
||||
|
||||
#include "display.h"
|
||||
struct omap_dss_device;
|
||||
|
||||
/**
|
||||
* struct panel_generic_dpi_data - panel driver configuration data
|
||||
|
@ -34,4 +34,4 @@ struct panel_generic_dpi_data {
|
|||
void (*platform_disable)(struct omap_dss_device *dssdev);
|
||||
};
|
||||
|
||||
#endif /* __ARCH_ARM_PLAT_OMAP_PANEL_GENERIC_DPI_H */
|
||||
#endif /* __OMAP_PANEL_GENERIC_DPI_H */
|
|
@ -1,14 +1,15 @@
|
|||
#ifndef __ARCH_ARM_PLAT_OMAP_NOKIA_DSI_PANEL_H
|
||||
#define __ARCH_ARM_PLAT_OMAP_NOKIA_DSI_PANEL_H
|
||||
#ifndef __OMAP_NOKIA_DSI_PANEL_H
|
||||
#define __OMAP_NOKIA_DSI_PANEL_H
|
||||
|
||||
#include "display.h"
|
||||
struct omap_dss_device;
|
||||
|
||||
/**
|
||||
* struct nokia_dsi_panel_data - Nokia DSI panel driver configuration
|
||||
* @name: panel name
|
||||
* @use_ext_te: use external TE
|
||||
* @ext_te_gpio: external TE GPIO
|
||||
* @use_esd_check: perform ESD checks
|
||||
* @esd_interval: interval of ESD checks, 0 = disabled (ms)
|
||||
* @ulps_timeout: time to wait before entering ULPS, 0 = disabled (ms)
|
||||
* @max_backlight_level: maximum backlight level
|
||||
* @set_backlight: pointer to backlight set function
|
||||
* @get_backlight: pointer to backlight get function
|
||||
|
@ -21,11 +22,12 @@ struct nokia_dsi_panel_data {
|
|||
bool use_ext_te;
|
||||
int ext_te_gpio;
|
||||
|
||||
bool use_esd_check;
|
||||
unsigned esd_interval;
|
||||
unsigned ulps_timeout;
|
||||
|
||||
int max_backlight_level;
|
||||
int (*set_backlight)(struct omap_dss_device *dssdev, int level);
|
||||
int (*get_backlight)(struct omap_dss_device *dssdev);
|
||||
};
|
||||
|
||||
#endif /* __ARCH_ARM_PLAT_OMAP_NOKIA_DSI_PANEL_H */
|
||||
#endif /* __OMAP_NOKIA_DSI_PANEL_H */
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/include/asm-arm/arch-omap/display.h
|
||||
*
|
||||
* Copyright (C) 2008 Nokia Corporation
|
||||
* Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
|
||||
*
|
||||
|
@ -17,8 +15,8 @@
|
|||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __ASM_ARCH_OMAP_DISPLAY_H
|
||||
#define __ASM_ARCH_OMAP_DISPLAY_H
|
||||
#ifndef __OMAP_OMAPDSS_H
|
||||
#define __OMAP_OMAPDSS_H
|
||||
|
||||
#include <linux/list.h>
|
||||
#include <linux/kobject.h>
|
||||
|
@ -88,6 +86,11 @@ enum omap_color_mode {
|
|||
OMAP_DSS_COLOR_ARGB32 = 1 << 11, /* ARGB32 */
|
||||
OMAP_DSS_COLOR_RGBA32 = 1 << 12, /* RGBA32 */
|
||||
OMAP_DSS_COLOR_RGBX32 = 1 << 13, /* RGBx32 */
|
||||
OMAP_DSS_COLOR_NV12 = 1 << 14, /* NV12 format: YUV 4:2:0 */
|
||||
OMAP_DSS_COLOR_RGBA16 = 1 << 15, /* RGBA16 - 4444 */
|
||||
OMAP_DSS_COLOR_RGBX16 = 1 << 16, /* RGBx16 - 4444 */
|
||||
OMAP_DSS_COLOR_ARGB16_1555 = 1 << 17, /* ARGB16 - 1555 */
|
||||
OMAP_DSS_COLOR_XRGB16_1555 = 1 << 18, /* xRGB16 - 1555 */
|
||||
};
|
||||
|
||||
enum omap_lcd_display_type {
|
||||
|
@ -174,6 +177,17 @@ enum omap_overlay_manager_caps {
|
|||
OMAP_DSS_OVL_MGR_CAP_DISPC = 1 << 0,
|
||||
};
|
||||
|
||||
enum omap_dss_clk_source {
|
||||
OMAP_DSS_CLK_SRC_FCK = 0, /* OMAP2/3: DSS1_ALWON_FCLK
|
||||
* OMAP4: DSS_FCLK */
|
||||
OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC, /* OMAP3: DSI1_PLL_FCLK
|
||||
* OMAP4: PLL1_CLK1 */
|
||||
OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI, /* OMAP3: DSI2_PLL_FCLK
|
||||
* OMAP4: PLL1_CLK2 */
|
||||
OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC, /* OMAP4: PLL2_CLK1 */
|
||||
OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI, /* OMAP4: PLL2_CLK2 */
|
||||
};
|
||||
|
||||
/* RFBI */
|
||||
|
||||
struct rfbi_timings {
|
||||
|
@ -205,20 +219,30 @@ int omap_rfbi_enable_te(bool enable, unsigned line);
|
|||
int omap_rfbi_setup_te(enum omap_rfbi_te_mode mode,
|
||||
unsigned hs_pulse_time, unsigned vs_pulse_time,
|
||||
int hs_pol_inv, int vs_pol_inv, int extif_div);
|
||||
void rfbi_bus_lock(void);
|
||||
void rfbi_bus_unlock(void);
|
||||
|
||||
/* DSI */
|
||||
void dsi_bus_lock(void);
|
||||
void dsi_bus_unlock(void);
|
||||
int dsi_vc_dcs_write(int channel, u8 *data, int len);
|
||||
int dsi_vc_dcs_write_0(int channel, u8 dcs_cmd);
|
||||
int dsi_vc_dcs_write_1(int channel, u8 dcs_cmd, u8 param);
|
||||
int dsi_vc_dcs_write_nosync(int channel, u8 *data, int len);
|
||||
int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen);
|
||||
int dsi_vc_dcs_read_1(int channel, u8 dcs_cmd, u8 *data);
|
||||
int dsi_vc_dcs_read_2(int channel, u8 dcs_cmd, u8 *data1, u8 *data2);
|
||||
int dsi_vc_set_max_rx_packet_size(int channel, u16 len);
|
||||
int dsi_vc_send_null(int channel);
|
||||
int dsi_vc_send_bta_sync(int channel);
|
||||
void dsi_bus_lock(struct omap_dss_device *dssdev);
|
||||
void dsi_bus_unlock(struct omap_dss_device *dssdev);
|
||||
int dsi_vc_dcs_write(struct omap_dss_device *dssdev, int channel, u8 *data,
|
||||
int len);
|
||||
int dsi_vc_dcs_write_0(struct omap_dss_device *dssdev, int channel,
|
||||
u8 dcs_cmd);
|
||||
int dsi_vc_dcs_write_1(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
|
||||
u8 param);
|
||||
int dsi_vc_dcs_write_nosync(struct omap_dss_device *dssdev, int channel,
|
||||
u8 *data, int len);
|
||||
int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
|
||||
u8 *buf, int buflen);
|
||||
int dsi_vc_dcs_read_1(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
|
||||
u8 *data);
|
||||
int dsi_vc_dcs_read_2(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
|
||||
u8 *data1, u8 *data2);
|
||||
int dsi_vc_set_max_rx_packet_size(struct omap_dss_device *dssdev, int channel,
|
||||
u16 len);
|
||||
int dsi_vc_send_null(struct omap_dss_device *dssdev, int channel);
|
||||
int dsi_vc_send_bta_sync(struct omap_dss_device *dssdev, int channel);
|
||||
|
||||
/* Board specific data */
|
||||
struct omap_dss_board_info {
|
||||
|
@ -226,6 +250,7 @@ struct omap_dss_board_info {
|
|||
int num_devices;
|
||||
struct omap_dss_device **devices;
|
||||
struct omap_dss_device *default_device;
|
||||
void (*dsi_mux_pads)(bool enable);
|
||||
};
|
||||
|
||||
#if defined(CONFIG_OMAP2_DSS_MODULE) || defined(CONFIG_OMAP2_DSS)
|
||||
|
@ -280,6 +305,7 @@ struct omap_overlay_info {
|
|||
|
||||
u32 paddr;
|
||||
void __iomem *vaddr;
|
||||
u32 p_uv_addr; /* for NV12 format */
|
||||
u16 screen_width;
|
||||
u16 width;
|
||||
u16 height;
|
||||
|
@ -400,18 +426,12 @@ struct omap_dss_device {
|
|||
u8 data1_pol;
|
||||
u8 data2_lane;
|
||||
u8 data2_pol;
|
||||
u8 data3_lane;
|
||||
u8 data3_pol;
|
||||
u8 data4_lane;
|
||||
u8 data4_pol;
|
||||
|
||||
struct {
|
||||
u16 regn;
|
||||
u16 regm;
|
||||
u16 regm_dispc;
|
||||
u16 regm_dsi;
|
||||
|
||||
u16 lp_clk_div;
|
||||
|
||||
u16 lck_div;
|
||||
u16 pck_div;
|
||||
} div;
|
||||
int module;
|
||||
|
||||
bool ext_te;
|
||||
u8 ext_te_gpio;
|
||||
|
@ -423,6 +443,33 @@ struct omap_dss_device {
|
|||
} venc;
|
||||
} phy;
|
||||
|
||||
struct {
|
||||
struct {
|
||||
struct {
|
||||
u16 lck_div;
|
||||
u16 pck_div;
|
||||
enum omap_dss_clk_source lcd_clk_src;
|
||||
} channel;
|
||||
|
||||
enum omap_dss_clk_source dispc_fclk_src;
|
||||
} dispc;
|
||||
|
||||
struct {
|
||||
u16 regn;
|
||||
u16 regm;
|
||||
u16 regm_dispc;
|
||||
u16 regm_dsi;
|
||||
|
||||
u16 lp_clk_div;
|
||||
enum omap_dss_clk_source dsi_fclk_src;
|
||||
} dsi;
|
||||
|
||||
struct {
|
||||
u16 regn;
|
||||
u16 regm2;
|
||||
} hdmi;
|
||||
} clocks;
|
||||
|
||||
struct {
|
||||
struct omap_video_timings timings;
|
||||
|
||||
|
@ -503,6 +550,8 @@ struct omap_dss_driver {
|
|||
|
||||
void (*get_resolution)(struct omap_dss_device *dssdev,
|
||||
u16 *xres, u16 *yres);
|
||||
void (*get_dimensions)(struct omap_dss_device *dssdev,
|
||||
u32 *width, u32 *height);
|
||||
int (*get_recommended_bpp)(struct omap_dss_device *dssdev);
|
||||
|
||||
int (*check_timings)(struct omap_dss_device *dssdev,
|
||||
|
@ -519,9 +568,6 @@ struct omap_dss_driver {
|
|||
int omap_dss_register_driver(struct omap_dss_driver *);
|
||||
void omap_dss_unregister_driver(struct omap_dss_driver *);
|
||||
|
||||
int omap_dss_register_device(struct omap_dss_device *);
|
||||
void omap_dss_unregister_device(struct omap_dss_device *);
|
||||
|
||||
void omap_dss_get_device(struct omap_dss_device *dssdev);
|
||||
void omap_dss_put_device(struct omap_dss_device *dssdev);
|
||||
#define for_each_dss_dev(d) while ((d = omap_dss_get_next_device(d)) != NULL)
|
||||
|
@ -553,7 +599,8 @@ int omap_dispc_wait_for_irq_interruptible_timeout(u32 irqmask,
|
|||
#define to_dss_driver(x) container_of((x), struct omap_dss_driver, driver)
|
||||
#define to_dss_device(x) container_of((x), struct omap_dss_device, dev)
|
||||
|
||||
void omapdss_dsi_vc_enable_hs(int channel, bool enable);
|
||||
void omapdss_dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel,
|
||||
bool enable);
|
||||
int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable);
|
||||
|
||||
int omap_dsi_prepare_update(struct omap_dss_device *dssdev,
|
||||
|
@ -568,7 +615,8 @@ int omap_dsi_set_vc_id(struct omap_dss_device *dssdev, int channel, int vc_id);
|
|||
void omap_dsi_release_vc(struct omap_dss_device *dssdev, int channel);
|
||||
|
||||
int omapdss_dsi_display_enable(struct omap_dss_device *dssdev);
|
||||
void omapdss_dsi_display_disable(struct omap_dss_device *dssdev);
|
||||
void omapdss_dsi_display_disable(struct omap_dss_device *dssdev,
|
||||
bool disconnect_lanes, bool enter_ulps);
|
||||
|
||||
int omapdss_dpi_display_enable(struct omap_dss_device *dssdev);
|
||||
void omapdss_dpi_display_disable(struct omap_dss_device *dssdev);
|
||||
|
@ -587,5 +635,7 @@ int omap_rfbi_prepare_update(struct omap_dss_device *dssdev,
|
|||
int omap_rfbi_update(struct omap_dss_device *dssdev,
|
||||
u16 x, u16 y, u16 w, u16 h,
|
||||
void (*callback)(void *), void *data);
|
||||
int omap_rfbi_configure(struct omap_dss_device *dssdev, int pixel_size,
|
||||
int data_lines);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue