Merge branch 'for-florian' of git://gitorious.org/linux-omap-dss2/linux into fbdev-next
This commit is contained in:
commit
193984f43d
|
@ -595,20 +595,6 @@ static void __init omap_sfh7741prox_init(void)
|
|||
__func__, OMAP4_SFH7741_ENABLE_GPIO, error);
|
||||
}
|
||||
|
||||
static void sdp4430_hdmi_mux_init(void)
|
||||
{
|
||||
/* PAD0_HDMI_HPD_PAD1_HDMI_CEC */
|
||||
omap_mux_init_signal("hdmi_hpd",
|
||||
OMAP_PIN_INPUT_PULLUP);
|
||||
omap_mux_init_signal("hdmi_cec",
|
||||
OMAP_PIN_INPUT_PULLUP);
|
||||
/* PAD0_HDMI_DDC_SCL_PAD1_HDMI_DDC_SDA */
|
||||
omap_mux_init_signal("hdmi_ddc_scl",
|
||||
OMAP_PIN_INPUT_PULLUP);
|
||||
omap_mux_init_signal("hdmi_ddc_sda",
|
||||
OMAP_PIN_INPUT_PULLUP);
|
||||
}
|
||||
|
||||
static struct gpio sdp4430_hdmi_gpios[] = {
|
||||
{ HDMI_GPIO_HPD, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_hpd" },
|
||||
{ HDMI_GPIO_LS_OE, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ls_oe" },
|
||||
|
@ -826,9 +812,16 @@ static void omap_4430sdp_display_init(void)
|
|||
pr_err("%s: Could not get display_sel GPIO\n", __func__);
|
||||
|
||||
sdp4430_lcd_init();
|
||||
sdp4430_hdmi_mux_init();
|
||||
sdp4430_picodlp_init();
|
||||
omap_display_init(&sdp4430_dss_data);
|
||||
/*
|
||||
* OMAP4460SDP/Blaze and OMAP4430 ES2.3 SDP/Blaze boards and
|
||||
* later have external pull up on the HDMI I2C lines
|
||||
*/
|
||||
if (cpu_is_omap446x() || omap_rev() > OMAP4430_REV_ES2_2)
|
||||
omap_hdmi_init(OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP);
|
||||
else
|
||||
omap_hdmi_init(0);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OMAP_MUX
|
||||
|
|
|
@ -478,21 +478,6 @@ int __init omap4_panda_dvi_init(void)
|
|||
return r;
|
||||
}
|
||||
|
||||
|
||||
static void omap4_panda_hdmi_mux_init(void)
|
||||
{
|
||||
/* PAD0_HDMI_HPD_PAD1_HDMI_CEC */
|
||||
omap_mux_init_signal("hdmi_hpd",
|
||||
OMAP_PIN_INPUT_PULLUP);
|
||||
omap_mux_init_signal("hdmi_cec",
|
||||
OMAP_PIN_INPUT_PULLUP);
|
||||
/* PAD0_HDMI_DDC_SCL_PAD1_HDMI_DDC_SDA */
|
||||
omap_mux_init_signal("hdmi_ddc_scl",
|
||||
OMAP_PIN_INPUT_PULLUP);
|
||||
omap_mux_init_signal("hdmi_ddc_sda",
|
||||
OMAP_PIN_INPUT_PULLUP);
|
||||
}
|
||||
|
||||
static struct gpio panda_hdmi_gpios[] = {
|
||||
{ HDMI_GPIO_HPD, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_hpd" },
|
||||
{ HDMI_GPIO_LS_OE, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ls_oe" },
|
||||
|
@ -544,8 +529,16 @@ void omap4_panda_display_init(void)
|
|||
if (r)
|
||||
pr_err("error initializing panda DVI\n");
|
||||
|
||||
omap4_panda_hdmi_mux_init();
|
||||
omap_display_init(&omap4_panda_dss_data);
|
||||
|
||||
/*
|
||||
* OMAP4460SDP/Blaze and OMAP4430 ES2.3 SDP/Blaze boards and
|
||||
* later have external pull up on the HDMI I2C lines
|
||||
*/
|
||||
if (cpu_is_omap446x() || omap_rev() > OMAP4430_REV_ES2_2)
|
||||
omap_hdmi_init(OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP);
|
||||
else
|
||||
omap_hdmi_init(0);
|
||||
}
|
||||
|
||||
static void __init omap4_panda_init(void)
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <plat/omap-pm.h>
|
||||
#include <plat/common.h>
|
||||
|
||||
#include "mux.h"
|
||||
#include "control.h"
|
||||
#include "display.h"
|
||||
|
||||
|
@ -96,6 +97,36 @@ static const struct omap_dss_hwmod_data omap4_dss_hwmod_data[] __initdata = {
|
|||
{ "dss_hdmi", "omapdss_hdmi", -1 },
|
||||
};
|
||||
|
||||
static void omap4_hdmi_mux_pads(enum omap_hdmi_flags flags)
|
||||
{
|
||||
u32 reg;
|
||||
u16 control_i2c_1;
|
||||
|
||||
/* PAD0_HDMI_HPD_PAD1_HDMI_CEC */
|
||||
omap_mux_init_signal("hdmi_hpd",
|
||||
OMAP_PIN_INPUT_PULLUP);
|
||||
omap_mux_init_signal("hdmi_cec",
|
||||
OMAP_PIN_INPUT_PULLUP);
|
||||
/* PAD0_HDMI_DDC_SCL_PAD1_HDMI_DDC_SDA */
|
||||
omap_mux_init_signal("hdmi_ddc_scl",
|
||||
OMAP_PIN_INPUT_PULLUP);
|
||||
omap_mux_init_signal("hdmi_ddc_sda",
|
||||
OMAP_PIN_INPUT_PULLUP);
|
||||
|
||||
/*
|
||||
* CONTROL_I2C_1: HDMI_DDC_SDA_PULLUPRESX (bit 28) and
|
||||
* HDMI_DDC_SCL_PULLUPRESX (bit 24) are set to disable
|
||||
* internal pull up resistor.
|
||||
*/
|
||||
if (flags & OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP) {
|
||||
control_i2c_1 = OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_I2C_1;
|
||||
reg = omap4_ctrl_pad_readl(control_i2c_1);
|
||||
reg |= (OMAP4_HDMI_DDC_SDA_PULLUPRESX_MASK |
|
||||
OMAP4_HDMI_DDC_SCL_PULLUPRESX_MASK);
|
||||
omap4_ctrl_pad_writel(reg, control_i2c_1);
|
||||
}
|
||||
}
|
||||
|
||||
static int omap4_dsi_mux_pads(int dsi_id, unsigned lanes)
|
||||
{
|
||||
u32 enable_mask, enable_shift;
|
||||
|
@ -129,6 +160,14 @@ static int omap4_dsi_mux_pads(int dsi_id, unsigned lanes)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int omap_hdmi_init(enum omap_hdmi_flags flags)
|
||||
{
|
||||
if (cpu_is_omap44xx())
|
||||
omap4_hdmi_mux_pads(flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap_dsi_enable_pads(int dsi_id, unsigned lane_mask)
|
||||
{
|
||||
if (cpu_is_omap44xx())
|
||||
|
|
|
@ -423,7 +423,7 @@ static int omapvid_setup_overlay(struct omap_vout_device *vout,
|
|||
"%s enable=%d addr=%x width=%d\n height=%d color_mode=%d\n"
|
||||
"rotation=%d mirror=%d posx=%d posy=%d out_width = %d \n"
|
||||
"out_height=%d rotation_type=%d screen_width=%d\n",
|
||||
__func__, info.enabled, info.paddr, info.width, info.height,
|
||||
__func__, ovl->is_enabled(ovl), info.paddr, info.width, info.height,
|
||||
info.color_mode, info.rotation, info.mirror, info.pos_x,
|
||||
info.pos_y, info.out_width, info.out_height, info.rotation_type,
|
||||
info.screen_width);
|
||||
|
@ -942,12 +942,8 @@ static int omap_vout_release(struct file *file)
|
|||
/* Disable all the overlay managers connected with this interface */
|
||||
for (i = 0; i < ovid->num_overlays; i++) {
|
||||
struct omap_overlay *ovl = ovid->overlays[i];
|
||||
if (ovl->manager && ovl->manager->device) {
|
||||
struct omap_overlay_info info;
|
||||
ovl->get_overlay_info(ovl, &info);
|
||||
info.enabled = 0;
|
||||
ovl->set_overlay_info(ovl, &info);
|
||||
}
|
||||
if (ovl->manager && ovl->manager->device)
|
||||
ovl->disable(ovl);
|
||||
}
|
||||
/* Turn off the pipeline */
|
||||
ret = omapvid_apply_changes(vout);
|
||||
|
@ -1667,7 +1663,6 @@ static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
|
|||
if (ovl->manager && ovl->manager->device) {
|
||||
struct omap_overlay_info info;
|
||||
ovl->get_overlay_info(ovl, &info);
|
||||
info.enabled = 1;
|
||||
info.paddr = addr;
|
||||
if (ovl->set_overlay_info(ovl, &info)) {
|
||||
ret = -EINVAL;
|
||||
|
@ -1686,6 +1681,16 @@ static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
|
|||
if (ret)
|
||||
v4l2_err(&vout->vid_dev->v4l2_dev, "failed to change mode\n");
|
||||
|
||||
for (j = 0; j < ovid->num_overlays; j++) {
|
||||
struct omap_overlay *ovl = ovid->overlays[j];
|
||||
|
||||
if (ovl->manager && ovl->manager->device) {
|
||||
ret = ovl->enable(ovl);
|
||||
if (ret)
|
||||
goto streamon_err1;
|
||||
}
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
streamon_err1:
|
||||
|
@ -1715,16 +1720,8 @@ static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i)
|
|||
for (j = 0; j < ovid->num_overlays; j++) {
|
||||
struct omap_overlay *ovl = ovid->overlays[j];
|
||||
|
||||
if (ovl->manager && ovl->manager->device) {
|
||||
struct omap_overlay_info info;
|
||||
|
||||
ovl->get_overlay_info(ovl, &info);
|
||||
info.enabled = 0;
|
||||
ret = ovl->set_overlay_info(ovl, &info);
|
||||
if (ret)
|
||||
v4l2_err(&vout->vid_dev->v4l2_dev,
|
||||
"failed to update overlay info in streamoff\n");
|
||||
}
|
||||
if (ovl->manager && ovl->manager->device)
|
||||
ovl->disable(ovl);
|
||||
}
|
||||
|
||||
/* Turn of the pipeline */
|
||||
|
|
|
@ -198,7 +198,7 @@ static int ams_delta_panel_resume(struct platform_device *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
struct platform_driver ams_delta_panel_driver = {
|
||||
static struct platform_driver ams_delta_panel_driver = {
|
||||
.probe = ams_delta_panel_probe,
|
||||
.remove = ams_delta_panel_remove,
|
||||
.suspend = ams_delta_panel_suspend,
|
||||
|
@ -209,15 +209,4 @@ struct platform_driver ams_delta_panel_driver = {
|
|||
},
|
||||
};
|
||||
|
||||
static int __init ams_delta_panel_drv_init(void)
|
||||
{
|
||||
return platform_driver_register(&ams_delta_panel_driver);
|
||||
}
|
||||
|
||||
static void __exit ams_delta_panel_drv_cleanup(void)
|
||||
{
|
||||
platform_driver_unregister(&ams_delta_panel_driver);
|
||||
}
|
||||
|
||||
module_init(ams_delta_panel_drv_init);
|
||||
module_exit(ams_delta_panel_drv_cleanup);
|
||||
module_platform_driver(ams_delta_panel_driver);
|
||||
|
|
|
@ -113,7 +113,7 @@ static int h3_panel_resume(struct platform_device *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
struct platform_driver h3_panel_driver = {
|
||||
static struct platform_driver h3_panel_driver = {
|
||||
.probe = h3_panel_probe,
|
||||
.remove = h3_panel_remove,
|
||||
.suspend = h3_panel_suspend,
|
||||
|
@ -124,16 +124,4 @@ struct platform_driver h3_panel_driver = {
|
|||
},
|
||||
};
|
||||
|
||||
static int __init h3_panel_drv_init(void)
|
||||
{
|
||||
return platform_driver_register(&h3_panel_driver);
|
||||
}
|
||||
|
||||
static void __exit h3_panel_drv_cleanup(void)
|
||||
{
|
||||
platform_driver_unregister(&h3_panel_driver);
|
||||
}
|
||||
|
||||
module_init(h3_panel_drv_init);
|
||||
module_exit(h3_panel_drv_cleanup);
|
||||
|
||||
module_platform_driver(h3_panel_driver);
|
||||
|
|
|
@ -104,7 +104,7 @@ static int htcherald_panel_resume(struct platform_device *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
struct platform_driver htcherald_panel_driver = {
|
||||
static struct platform_driver htcherald_panel_driver = {
|
||||
.probe = htcherald_panel_probe,
|
||||
.remove = htcherald_panel_remove,
|
||||
.suspend = htcherald_panel_suspend,
|
||||
|
@ -115,16 +115,4 @@ struct platform_driver htcherald_panel_driver = {
|
|||
},
|
||||
};
|
||||
|
||||
static int __init htcherald_panel_drv_init(void)
|
||||
{
|
||||
return platform_driver_register(&htcherald_panel_driver);
|
||||
}
|
||||
|
||||
static void __exit htcherald_panel_drv_cleanup(void)
|
||||
{
|
||||
platform_driver_unregister(&htcherald_panel_driver);
|
||||
}
|
||||
|
||||
module_init(htcherald_panel_drv_init);
|
||||
module_exit(htcherald_panel_drv_cleanup);
|
||||
|
||||
module_platform_driver(htcherald_panel_driver);
|
||||
|
|
|
@ -98,7 +98,7 @@ static int innovator1510_panel_resume(struct platform_device *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
struct platform_driver innovator1510_panel_driver = {
|
||||
static struct platform_driver innovator1510_panel_driver = {
|
||||
.probe = innovator1510_panel_probe,
|
||||
.remove = innovator1510_panel_remove,
|
||||
.suspend = innovator1510_panel_suspend,
|
||||
|
@ -109,16 +109,4 @@ struct platform_driver innovator1510_panel_driver = {
|
|||
},
|
||||
};
|
||||
|
||||
static int __init innovator1510_panel_drv_init(void)
|
||||
{
|
||||
return platform_driver_register(&innovator1510_panel_driver);
|
||||
}
|
||||
|
||||
static void __exit innovator1510_panel_drv_cleanup(void)
|
||||
{
|
||||
platform_driver_unregister(&innovator1510_panel_driver);
|
||||
}
|
||||
|
||||
module_init(innovator1510_panel_drv_init);
|
||||
module_exit(innovator1510_panel_drv_cleanup);
|
||||
|
||||
module_platform_driver(innovator1510_panel_driver);
|
||||
|
|
|
@ -122,7 +122,7 @@ static int innovator1610_panel_resume(struct platform_device *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
struct platform_driver innovator1610_panel_driver = {
|
||||
static struct platform_driver innovator1610_panel_driver = {
|
||||
.probe = innovator1610_panel_probe,
|
||||
.remove = innovator1610_panel_remove,
|
||||
.suspend = innovator1610_panel_suspend,
|
||||
|
@ -133,16 +133,4 @@ struct platform_driver innovator1610_panel_driver = {
|
|||
},
|
||||
};
|
||||
|
||||
static int __init innovator1610_panel_drv_init(void)
|
||||
{
|
||||
return platform_driver_register(&innovator1610_panel_driver);
|
||||
}
|
||||
|
||||
static void __exit innovator1610_panel_drv_cleanup(void)
|
||||
{
|
||||
platform_driver_unregister(&innovator1610_panel_driver);
|
||||
}
|
||||
|
||||
module_init(innovator1610_panel_drv_init);
|
||||
module_exit(innovator1610_panel_drv_cleanup);
|
||||
|
||||
module_platform_driver(innovator1610_panel_driver);
|
||||
|
|
|
@ -116,7 +116,7 @@ static int osk_panel_resume(struct platform_device *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
struct platform_driver osk_panel_driver = {
|
||||
static struct platform_driver osk_panel_driver = {
|
||||
.probe = osk_panel_probe,
|
||||
.remove = osk_panel_remove,
|
||||
.suspend = osk_panel_suspend,
|
||||
|
@ -127,16 +127,4 @@ struct platform_driver osk_panel_driver = {
|
|||
},
|
||||
};
|
||||
|
||||
static int __init osk_panel_drv_init(void)
|
||||
{
|
||||
return platform_driver_register(&osk_panel_driver);
|
||||
}
|
||||
|
||||
static void __exit osk_panel_drv_cleanup(void)
|
||||
{
|
||||
platform_driver_unregister(&osk_panel_driver);
|
||||
}
|
||||
|
||||
module_init(osk_panel_drv_init);
|
||||
module_exit(osk_panel_drv_cleanup);
|
||||
|
||||
module_platform_driver(osk_panel_driver);
|
||||
|
|
|
@ -97,7 +97,7 @@ static int palmte_panel_resume(struct platform_device *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
struct platform_driver palmte_panel_driver = {
|
||||
static struct platform_driver palmte_panel_driver = {
|
||||
.probe = palmte_panel_probe,
|
||||
.remove = palmte_panel_remove,
|
||||
.suspend = palmte_panel_suspend,
|
||||
|
@ -108,16 +108,4 @@ struct platform_driver palmte_panel_driver = {
|
|||
},
|
||||
};
|
||||
|
||||
static int __init palmte_panel_drv_init(void)
|
||||
{
|
||||
return platform_driver_register(&palmte_panel_driver);
|
||||
}
|
||||
|
||||
static void __exit palmte_panel_drv_cleanup(void)
|
||||
{
|
||||
platform_driver_unregister(&palmte_panel_driver);
|
||||
}
|
||||
|
||||
module_init(palmte_panel_drv_init);
|
||||
module_exit(palmte_panel_drv_cleanup);
|
||||
|
||||
module_platform_driver(palmte_panel_driver);
|
||||
|
|
|
@ -102,7 +102,7 @@ static int palmtt_panel_resume(struct platform_device *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
struct platform_driver palmtt_panel_driver = {
|
||||
static struct platform_driver palmtt_panel_driver = {
|
||||
.probe = palmtt_panel_probe,
|
||||
.remove = palmtt_panel_remove,
|
||||
.suspend = palmtt_panel_suspend,
|
||||
|
@ -113,15 +113,4 @@ struct platform_driver palmtt_panel_driver = {
|
|||
},
|
||||
};
|
||||
|
||||
static int __init palmtt_panel_drv_init(void)
|
||||
{
|
||||
return platform_driver_register(&palmtt_panel_driver);
|
||||
}
|
||||
|
||||
static void __exit palmtt_panel_drv_cleanup(void)
|
||||
{
|
||||
platform_driver_unregister(&palmtt_panel_driver);
|
||||
}
|
||||
|
||||
module_init(palmtt_panel_drv_init);
|
||||
module_exit(palmtt_panel_drv_cleanup);
|
||||
module_platform_driver(palmtt_panel_driver);
|
||||
|
|
|
@ -98,7 +98,7 @@ static int palmz71_panel_resume(struct platform_device *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
struct platform_driver palmz71_panel_driver = {
|
||||
static struct platform_driver palmz71_panel_driver = {
|
||||
.probe = palmz71_panel_probe,
|
||||
.remove = palmz71_panel_remove,
|
||||
.suspend = palmz71_panel_suspend,
|
||||
|
@ -109,15 +109,4 @@ struct platform_driver palmz71_panel_driver = {
|
|||
},
|
||||
};
|
||||
|
||||
static int __init palmz71_panel_drv_init(void)
|
||||
{
|
||||
return platform_driver_register(&palmz71_panel_driver);
|
||||
}
|
||||
|
||||
static void __exit palmz71_panel_drv_cleanup(void)
|
||||
{
|
||||
platform_driver_unregister(&palmz71_panel_driver);
|
||||
}
|
||||
|
||||
module_init(palmz71_panel_drv_init);
|
||||
module_exit(palmz71_panel_drv_cleanup);
|
||||
module_platform_driver(palmz71_panel_driver);
|
||||
|
|
|
@ -41,7 +41,7 @@ config PANEL_NEC_NL8048HL11_01B
|
|||
|
||||
config PANEL_PICODLP
|
||||
tristate "TI PICO DLP mini-projector"
|
||||
depends on OMAP2_DSS && I2C
|
||||
depends on OMAP2_DSS_DPI && I2C
|
||||
help
|
||||
A mini-projector used in TI's SDP4430 and EVM boards
|
||||
For more info please visit http://www.dlp.com/projector/
|
||||
|
|
|
@ -297,6 +297,72 @@ static struct panel_config generic_dpi_panels[] = {
|
|||
|
||||
.name = "apollon",
|
||||
},
|
||||
/* FocalTech ETM070003DH6 */
|
||||
{
|
||||
{
|
||||
.x_res = 800,
|
||||
.y_res = 480,
|
||||
|
||||
.pixel_clock = 28000,
|
||||
|
||||
.hsw = 48,
|
||||
.hfp = 40,
|
||||
.hbp = 40,
|
||||
|
||||
.vsw = 3,
|
||||
.vfp = 13,
|
||||
.vbp = 29,
|
||||
},
|
||||
.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
|
||||
OMAP_DSS_LCD_IHS,
|
||||
.name = "focaltech_etm070003dh6",
|
||||
},
|
||||
|
||||
/* Microtips Technologies - UMSH-8173MD */
|
||||
{
|
||||
{
|
||||
.x_res = 800,
|
||||
.y_res = 480,
|
||||
|
||||
.pixel_clock = 34560,
|
||||
|
||||
.hsw = 13,
|
||||
.hfp = 101,
|
||||
.hbp = 101,
|
||||
|
||||
.vsw = 23,
|
||||
.vfp = 1,
|
||||
.vbp = 1,
|
||||
},
|
||||
.acbi = 0x0,
|
||||
.acb = 0x0,
|
||||
.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
|
||||
OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IPC,
|
||||
.power_on_delay = 0,
|
||||
.power_off_delay = 0,
|
||||
.name = "microtips_umsh_8173md",
|
||||
},
|
||||
|
||||
/* OrtusTech COM43H4M10XTC */
|
||||
{
|
||||
{
|
||||
.x_res = 480,
|
||||
.y_res = 272,
|
||||
|
||||
.pixel_clock = 8000,
|
||||
|
||||
.hsw = 41,
|
||||
.hfp = 8,
|
||||
.hbp = 4,
|
||||
|
||||
.vsw = 10,
|
||||
.vfp = 4,
|
||||
.vbp = 2,
|
||||
},
|
||||
.config = OMAP_DSS_LCD_TFT,
|
||||
|
||||
.name = "ortustech_com43h4m10xtc",
|
||||
},
|
||||
};
|
||||
|
||||
struct panel_drv_data {
|
||||
|
|
|
@ -163,50 +163,93 @@ static void nec_8048_panel_remove(struct omap_dss_device *dssdev)
|
|||
kfree(necd);
|
||||
}
|
||||
|
||||
static int nec_8048_panel_enable(struct omap_dss_device *dssdev)
|
||||
static int nec_8048_panel_power_on(struct omap_dss_device *dssdev)
|
||||
{
|
||||
int r = 0;
|
||||
int r;
|
||||
struct nec_8048_data *necd = dev_get_drvdata(&dssdev->dev);
|
||||
struct backlight_device *bl = necd->bl;
|
||||
|
||||
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
|
||||
return 0;
|
||||
|
||||
r = omapdss_dpi_display_enable(dssdev);
|
||||
if (r)
|
||||
goto err0;
|
||||
|
||||
if (dssdev->platform_enable) {
|
||||
r = dssdev->platform_enable(dssdev);
|
||||
if (r)
|
||||
return r;
|
||||
goto err1;
|
||||
}
|
||||
|
||||
r = nec_8048_bl_update_status(bl);
|
||||
if (r < 0)
|
||||
dev_err(&dssdev->dev, "failed to set lcd brightness\n");
|
||||
|
||||
r = omapdss_dpi_display_enable(dssdev);
|
||||
|
||||
return 0;
|
||||
err1:
|
||||
omapdss_dpi_display_disable(dssdev);
|
||||
err0:
|
||||
return r;
|
||||
}
|
||||
|
||||
static void nec_8048_panel_disable(struct omap_dss_device *dssdev)
|
||||
static void nec_8048_panel_power_off(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct nec_8048_data *necd = dev_get_drvdata(&dssdev->dev);
|
||||
struct backlight_device *bl = necd->bl;
|
||||
|
||||
omapdss_dpi_display_disable(dssdev);
|
||||
if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
|
||||
return;
|
||||
|
||||
bl->props.brightness = 0;
|
||||
nec_8048_bl_update_status(bl);
|
||||
|
||||
if (dssdev->platform_disable)
|
||||
dssdev->platform_disable(dssdev);
|
||||
|
||||
omapdss_dpi_display_disable(dssdev);
|
||||
}
|
||||
|
||||
static int nec_8048_panel_enable(struct omap_dss_device *dssdev)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = nec_8048_panel_power_on(dssdev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void nec_8048_panel_disable(struct omap_dss_device *dssdev)
|
||||
{
|
||||
nec_8048_panel_power_off(dssdev);
|
||||
|
||||
dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
|
||||
}
|
||||
|
||||
static int nec_8048_panel_suspend(struct omap_dss_device *dssdev)
|
||||
{
|
||||
nec_8048_panel_disable(dssdev);
|
||||
nec_8048_panel_power_off(dssdev);
|
||||
|
||||
dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nec_8048_panel_resume(struct omap_dss_device *dssdev)
|
||||
{
|
||||
return nec_8048_panel_enable(dssdev);
|
||||
int r;
|
||||
|
||||
r = nec_8048_panel_power_on(dssdev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nec_8048_recommended_bpp(struct omap_dss_device *dssdev)
|
||||
|
|
|
@ -198,12 +198,6 @@ struct taal_data {
|
|||
bool te_enabled;
|
||||
|
||||
atomic_t do_update;
|
||||
struct {
|
||||
u16 x;
|
||||
u16 y;
|
||||
u16 w;
|
||||
u16 h;
|
||||
} update_region;
|
||||
int channel;
|
||||
|
||||
struct delayed_work te_timeout_work;
|
||||
|
@ -1188,6 +1182,10 @@ static int taal_power_on(struct omap_dss_device *dssdev)
|
|||
if (r)
|
||||
goto err;
|
||||
|
||||
r = dsi_enable_video_output(dssdev, td->channel);
|
||||
if (r)
|
||||
goto err;
|
||||
|
||||
td->enabled = 1;
|
||||
|
||||
if (!td->intro_printed) {
|
||||
|
@ -1217,6 +1215,8 @@ static void taal_power_off(struct omap_dss_device *dssdev)
|
|||
struct taal_data *td = dev_get_drvdata(&dssdev->dev);
|
||||
int r;
|
||||
|
||||
dsi_disable_video_output(dssdev, td->channel);
|
||||
|
||||
r = taal_dcs_write_0(td, MIPI_DCS_SET_DISPLAY_OFF);
|
||||
if (!r)
|
||||
r = taal_sleep_in(td);
|
||||
|
@ -1394,12 +1394,8 @@ static irqreturn_t taal_te_isr(int irq, void *data)
|
|||
if (old) {
|
||||
cancel_delayed_work(&td->te_timeout_work);
|
||||
|
||||
r = omap_dsi_update(dssdev, td->channel,
|
||||
td->update_region.x,
|
||||
td->update_region.y,
|
||||
td->update_region.w,
|
||||
td->update_region.h,
|
||||
taal_framedone_cb, dssdev);
|
||||
r = omap_dsi_update(dssdev, td->channel, taal_framedone_cb,
|
||||
dssdev);
|
||||
if (r)
|
||||
goto err;
|
||||
}
|
||||
|
@ -1444,26 +1440,20 @@ static int taal_update(struct omap_dss_device *dssdev,
|
|||
goto err;
|
||||
}
|
||||
|
||||
r = omap_dsi_prepare_update(dssdev, &x, &y, &w, &h, true);
|
||||
if (r)
|
||||
goto err;
|
||||
|
||||
r = taal_set_update_window(td, x, y, w, h);
|
||||
/* XXX no need to send this every frame, but dsi break if not done */
|
||||
r = taal_set_update_window(td, 0, 0,
|
||||
td->panel_config->timings.x_res,
|
||||
td->panel_config->timings.y_res);
|
||||
if (r)
|
||||
goto err;
|
||||
|
||||
if (td->te_enabled && panel_data->use_ext_te) {
|
||||
td->update_region.x = x;
|
||||
td->update_region.y = y;
|
||||
td->update_region.w = w;
|
||||
td->update_region.h = h;
|
||||
barrier();
|
||||
schedule_delayed_work(&td->te_timeout_work,
|
||||
msecs_to_jiffies(250));
|
||||
atomic_set(&td->do_update, 1);
|
||||
} else {
|
||||
r = omap_dsi_update(dssdev, td->channel, x, y, w, h,
|
||||
taal_framedone_cb, dssdev);
|
||||
r = omap_dsi_update(dssdev, td->channel, taal_framedone_cb,
|
||||
dssdev);
|
||||
if (r)
|
||||
goto err;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
obj-$(CONFIG_OMAP2_DSS) += omapdss.o
|
||||
omapdss-y := core.o dss.o dss_features.o dispc.o display.o manager.o overlay.o
|
||||
omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \
|
||||
manager.o overlay.o apply.o
|
||||
omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o
|
||||
omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o
|
||||
omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -178,6 +178,8 @@ static int omap_dss_probe(struct platform_device *pdev)
|
|||
|
||||
dss_features_init();
|
||||
|
||||
dss_apply_init();
|
||||
|
||||
dss_init_overlay_managers(pdev);
|
||||
dss_init_overlays(pdev);
|
||||
|
||||
|
|
|
@ -64,22 +64,6 @@ struct omap_dispc_isr_data {
|
|||
u32 mask;
|
||||
};
|
||||
|
||||
struct dispc_h_coef {
|
||||
s8 hc4;
|
||||
s8 hc3;
|
||||
u8 hc2;
|
||||
s8 hc1;
|
||||
s8 hc0;
|
||||
};
|
||||
|
||||
struct dispc_v_coef {
|
||||
s8 vc22;
|
||||
s8 vc2;
|
||||
u8 vc1;
|
||||
s8 vc0;
|
||||
s8 vc00;
|
||||
};
|
||||
|
||||
enum omap_burst_size {
|
||||
BURST_SIZE_X2 = 0,
|
||||
BURST_SIZE_X4 = 1,
|
||||
|
@ -438,6 +422,34 @@ static struct omap_dss_device *dispc_mgr_get_device(enum omap_channel channel)
|
|||
return mgr ? mgr->device : NULL;
|
||||
}
|
||||
|
||||
u32 dispc_mgr_get_vsync_irq(enum omap_channel channel)
|
||||
{
|
||||
switch (channel) {
|
||||
case OMAP_DSS_CHANNEL_LCD:
|
||||
return DISPC_IRQ_VSYNC;
|
||||
case OMAP_DSS_CHANNEL_LCD2:
|
||||
return DISPC_IRQ_VSYNC2;
|
||||
case OMAP_DSS_CHANNEL_DIGIT:
|
||||
return DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
u32 dispc_mgr_get_framedone_irq(enum omap_channel channel)
|
||||
{
|
||||
switch (channel) {
|
||||
case OMAP_DSS_CHANNEL_LCD:
|
||||
return DISPC_IRQ_FRAMEDONE;
|
||||
case OMAP_DSS_CHANNEL_LCD2:
|
||||
return DISPC_IRQ_FRAMEDONE2;
|
||||
case OMAP_DSS_CHANNEL_DIGIT:
|
||||
return 0;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
bool dispc_mgr_go_busy(enum omap_channel channel)
|
||||
{
|
||||
int bit;
|
||||
|
@ -533,105 +545,27 @@ static void dispc_ovl_write_firv2_reg(enum omap_plane plane, int reg, u32 value)
|
|||
dispc_write_reg(DISPC_OVL_FIR_COEF_V2(plane, reg), value);
|
||||
}
|
||||
|
||||
static void dispc_ovl_set_scale_coef(enum omap_plane plane, int hscaleup,
|
||||
int vscaleup, int five_taps,
|
||||
enum omap_color_component color_comp)
|
||||
static void dispc_ovl_set_scale_coef(enum omap_plane plane, int fir_hinc,
|
||||
int fir_vinc, int five_taps,
|
||||
enum omap_color_component color_comp)
|
||||
{
|
||||
/* Coefficients for horizontal up-sampling */
|
||||
static const struct dispc_h_coef coef_hup[8] = {
|
||||
{ 0, 0, 128, 0, 0 },
|
||||
{ -1, 13, 124, -8, 0 },
|
||||
{ -2, 30, 112, -11, -1 },
|
||||
{ -5, 51, 95, -11, -2 },
|
||||
{ 0, -9, 73, 73, -9 },
|
||||
{ -2, -11, 95, 51, -5 },
|
||||
{ -1, -11, 112, 30, -2 },
|
||||
{ 0, -8, 124, 13, -1 },
|
||||
};
|
||||
|
||||
/* Coefficients for vertical up-sampling */
|
||||
static const struct dispc_v_coef coef_vup_3tap[8] = {
|
||||
{ 0, 0, 128, 0, 0 },
|
||||
{ 0, 3, 123, 2, 0 },
|
||||
{ 0, 12, 111, 5, 0 },
|
||||
{ 0, 32, 89, 7, 0 },
|
||||
{ 0, 0, 64, 64, 0 },
|
||||
{ 0, 7, 89, 32, 0 },
|
||||
{ 0, 5, 111, 12, 0 },
|
||||
{ 0, 2, 123, 3, 0 },
|
||||
};
|
||||
|
||||
static const struct dispc_v_coef coef_vup_5tap[8] = {
|
||||
{ 0, 0, 128, 0, 0 },
|
||||
{ -1, 13, 124, -8, 0 },
|
||||
{ -2, 30, 112, -11, -1 },
|
||||
{ -5, 51, 95, -11, -2 },
|
||||
{ 0, -9, 73, 73, -9 },
|
||||
{ -2, -11, 95, 51, -5 },
|
||||
{ -1, -11, 112, 30, -2 },
|
||||
{ 0, -8, 124, 13, -1 },
|
||||
};
|
||||
|
||||
/* Coefficients for horizontal down-sampling */
|
||||
static const struct dispc_h_coef coef_hdown[8] = {
|
||||
{ 0, 36, 56, 36, 0 },
|
||||
{ 4, 40, 55, 31, -2 },
|
||||
{ 8, 44, 54, 27, -5 },
|
||||
{ 12, 48, 53, 22, -7 },
|
||||
{ -9, 17, 52, 51, 17 },
|
||||
{ -7, 22, 53, 48, 12 },
|
||||
{ -5, 27, 54, 44, 8 },
|
||||
{ -2, 31, 55, 40, 4 },
|
||||
};
|
||||
|
||||
/* Coefficients for vertical down-sampling */
|
||||
static const struct dispc_v_coef coef_vdown_3tap[8] = {
|
||||
{ 0, 36, 56, 36, 0 },
|
||||
{ 0, 40, 57, 31, 0 },
|
||||
{ 0, 45, 56, 27, 0 },
|
||||
{ 0, 50, 55, 23, 0 },
|
||||
{ 0, 18, 55, 55, 0 },
|
||||
{ 0, 23, 55, 50, 0 },
|
||||
{ 0, 27, 56, 45, 0 },
|
||||
{ 0, 31, 57, 40, 0 },
|
||||
};
|
||||
|
||||
static const struct dispc_v_coef coef_vdown_5tap[8] = {
|
||||
{ 0, 36, 56, 36, 0 },
|
||||
{ 4, 40, 55, 31, -2 },
|
||||
{ 8, 44, 54, 27, -5 },
|
||||
{ 12, 48, 53, 22, -7 },
|
||||
{ -9, 17, 52, 51, 17 },
|
||||
{ -7, 22, 53, 48, 12 },
|
||||
{ -5, 27, 54, 44, 8 },
|
||||
{ -2, 31, 55, 40, 4 },
|
||||
};
|
||||
|
||||
const struct dispc_h_coef *h_coef;
|
||||
const struct dispc_v_coef *v_coef;
|
||||
const struct dispc_coef *h_coef, *v_coef;
|
||||
int i;
|
||||
|
||||
if (hscaleup)
|
||||
h_coef = coef_hup;
|
||||
else
|
||||
h_coef = coef_hdown;
|
||||
|
||||
if (vscaleup)
|
||||
v_coef = five_taps ? coef_vup_5tap : coef_vup_3tap;
|
||||
else
|
||||
v_coef = five_taps ? coef_vdown_5tap : coef_vdown_3tap;
|
||||
h_coef = dispc_ovl_get_scale_coef(fir_hinc, true);
|
||||
v_coef = dispc_ovl_get_scale_coef(fir_vinc, five_taps);
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
u32 h, hv;
|
||||
|
||||
h = FLD_VAL(h_coef[i].hc0, 7, 0)
|
||||
| FLD_VAL(h_coef[i].hc1, 15, 8)
|
||||
| FLD_VAL(h_coef[i].hc2, 23, 16)
|
||||
| FLD_VAL(h_coef[i].hc3, 31, 24);
|
||||
hv = FLD_VAL(h_coef[i].hc4, 7, 0)
|
||||
| FLD_VAL(v_coef[i].vc0, 15, 8)
|
||||
| FLD_VAL(v_coef[i].vc1, 23, 16)
|
||||
| FLD_VAL(v_coef[i].vc2, 31, 24);
|
||||
h = FLD_VAL(h_coef[i].hc0_vc00, 7, 0)
|
||||
| FLD_VAL(h_coef[i].hc1_vc0, 15, 8)
|
||||
| FLD_VAL(h_coef[i].hc2_vc1, 23, 16)
|
||||
| FLD_VAL(h_coef[i].hc3_vc2, 31, 24);
|
||||
hv = FLD_VAL(h_coef[i].hc4_vc22, 7, 0)
|
||||
| FLD_VAL(v_coef[i].hc1_vc0, 15, 8)
|
||||
| FLD_VAL(v_coef[i].hc2_vc1, 23, 16)
|
||||
| FLD_VAL(v_coef[i].hc3_vc2, 31, 24);
|
||||
|
||||
if (color_comp == DISPC_COLOR_COMPONENT_RGB_Y) {
|
||||
dispc_ovl_write_firh_reg(plane, i, h);
|
||||
|
@ -646,8 +580,8 @@ static void dispc_ovl_set_scale_coef(enum omap_plane plane, int hscaleup,
|
|||
if (five_taps) {
|
||||
for (i = 0; i < 8; i++) {
|
||||
u32 v;
|
||||
v = FLD_VAL(v_coef[i].vc00, 7, 0)
|
||||
| FLD_VAL(v_coef[i].vc22, 15, 8);
|
||||
v = FLD_VAL(v_coef[i].hc0_vc00, 7, 0)
|
||||
| FLD_VAL(v_coef[i].hc4_vc22, 15, 8);
|
||||
if (color_comp == DISPC_COLOR_COMPONENT_RGB_Y)
|
||||
dispc_ovl_write_firv_reg(plane, i, v);
|
||||
else
|
||||
|
@ -875,8 +809,7 @@ static void dispc_ovl_set_color_mode(enum omap_plane plane,
|
|||
REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), m, 4, 1);
|
||||
}
|
||||
|
||||
static void dispc_ovl_set_channel_out(enum omap_plane plane,
|
||||
enum omap_channel channel)
|
||||
void dispc_ovl_set_channel_out(enum omap_plane plane, enum omap_channel channel)
|
||||
{
|
||||
int shift;
|
||||
u32 val;
|
||||
|
@ -923,6 +856,39 @@ static void dispc_ovl_set_channel_out(enum omap_plane plane,
|
|||
dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), val);
|
||||
}
|
||||
|
||||
static enum omap_channel dispc_ovl_get_channel_out(enum omap_plane plane)
|
||||
{
|
||||
int shift;
|
||||
u32 val;
|
||||
enum omap_channel channel;
|
||||
|
||||
switch (plane) {
|
||||
case OMAP_DSS_GFX:
|
||||
shift = 8;
|
||||
break;
|
||||
case OMAP_DSS_VIDEO1:
|
||||
case OMAP_DSS_VIDEO2:
|
||||
case OMAP_DSS_VIDEO3:
|
||||
shift = 16;
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
||||
val = dispc_read_reg(DISPC_OVL_ATTRIBUTES(plane));
|
||||
|
||||
if (dss_has_feature(FEAT_MGR_LCD2)) {
|
||||
if (FLD_GET(val, 31, 30) == 0)
|
||||
channel = FLD_GET(val, shift, shift);
|
||||
else
|
||||
channel = OMAP_DSS_CHANNEL_LCD2;
|
||||
} else {
|
||||
channel = FLD_GET(val, shift, shift);
|
||||
}
|
||||
|
||||
return channel;
|
||||
}
|
||||
|
||||
static void dispc_ovl_set_burst_size(enum omap_plane plane,
|
||||
enum omap_burst_size burst_size)
|
||||
{
|
||||
|
@ -964,7 +930,7 @@ void dispc_enable_gamma_table(bool enable)
|
|||
REG_FLD_MOD(DISPC_CONFIG, enable, 9, 9);
|
||||
}
|
||||
|
||||
void dispc_mgr_enable_cpr(enum omap_channel channel, bool enable)
|
||||
static void dispc_mgr_enable_cpr(enum omap_channel channel, bool enable)
|
||||
{
|
||||
u16 reg;
|
||||
|
||||
|
@ -978,7 +944,7 @@ void dispc_mgr_enable_cpr(enum omap_channel channel, bool enable)
|
|||
REG_FLD_MOD(reg, enable, 15, 15);
|
||||
}
|
||||
|
||||
void dispc_mgr_set_cpr_coef(enum omap_channel channel,
|
||||
static void dispc_mgr_set_cpr_coef(enum omap_channel channel,
|
||||
struct omap_dss_cpr_coefs *coefs)
|
||||
{
|
||||
u32 coef_r, coef_g, coef_b;
|
||||
|
@ -1057,8 +1023,7 @@ u32 dispc_ovl_get_fifo_size(enum omap_plane plane)
|
|||
return dispc.fifo_size[plane];
|
||||
}
|
||||
|
||||
static void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low,
|
||||
u32 high)
|
||||
void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high)
|
||||
{
|
||||
u8 hi_start, hi_end, lo_start, lo_end;
|
||||
u32 unit;
|
||||
|
@ -1169,17 +1134,12 @@ static void dispc_ovl_set_scale_param(enum omap_plane plane,
|
|||
enum omap_color_component color_comp)
|
||||
{
|
||||
int fir_hinc, fir_vinc;
|
||||
int hscaleup, vscaleup;
|
||||
|
||||
hscaleup = orig_width <= out_width;
|
||||
vscaleup = orig_height <= out_height;
|
||||
|
||||
dispc_ovl_set_scale_coef(plane, hscaleup, vscaleup, five_taps,
|
||||
color_comp);
|
||||
|
||||
fir_hinc = 1024 * orig_width / out_width;
|
||||
fir_vinc = 1024 * orig_height / out_height;
|
||||
|
||||
dispc_ovl_set_scale_coef(plane, fir_hinc, fir_vinc, five_taps,
|
||||
color_comp);
|
||||
dispc_ovl_set_fir(plane, fir_hinc, fir_vinc, color_comp);
|
||||
}
|
||||
|
||||
|
@ -1654,6 +1614,9 @@ static unsigned long calc_fclk_five_taps(enum omap_channel channel, u16 width,
|
|||
u32 fclk = 0;
|
||||
u64 tmp, pclk = dispc_mgr_pclk_rate(channel);
|
||||
|
||||
if (height <= out_height && width <= out_width)
|
||||
return (unsigned long) pclk;
|
||||
|
||||
if (height > out_height) {
|
||||
struct omap_dss_device *dssdev = dispc_mgr_get_device(channel);
|
||||
unsigned int ppl = dssdev->panel.timings.x_res;
|
||||
|
@ -1708,7 +1671,16 @@ static unsigned long calc_fclk(enum omap_channel channel, u16 width,
|
|||
else
|
||||
vf = 1;
|
||||
|
||||
return dispc_mgr_pclk_rate(channel) * vf * hf;
|
||||
if (cpu_is_omap24xx()) {
|
||||
if (vf > 1 && hf > 1)
|
||||
return dispc_mgr_pclk_rate(channel) * 4;
|
||||
else
|
||||
return dispc_mgr_pclk_rate(channel) * 2;
|
||||
} else if (cpu_is_omap34xx()) {
|
||||
return dispc_mgr_pclk_rate(channel) * vf * hf;
|
||||
} else {
|
||||
return dispc_mgr_pclk_rate(channel) * hf;
|
||||
}
|
||||
}
|
||||
|
||||
static int dispc_ovl_calc_scaling(enum omap_plane plane,
|
||||
|
@ -1718,6 +1690,8 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
|
|||
{
|
||||
struct omap_overlay *ovl = omap_dss_get_overlay(plane);
|
||||
const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE);
|
||||
const int maxsinglelinewidth =
|
||||
dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
|
||||
unsigned long fclk = 0;
|
||||
|
||||
if (width == out_width && height == out_height)
|
||||
|
@ -1734,28 +1708,40 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
|
|||
out_height > height * 8)
|
||||
return -EINVAL;
|
||||
|
||||
/* Must use 5-tap filter? */
|
||||
*five_taps = height > out_height * 2;
|
||||
|
||||
if (!*five_taps) {
|
||||
if (cpu_is_omap24xx()) {
|
||||
if (width > maxsinglelinewidth)
|
||||
DSSERR("Cannot scale max input width exceeded");
|
||||
*five_taps = false;
|
||||
fclk = calc_fclk(channel, width, height, out_width,
|
||||
out_height);
|
||||
} else if (cpu_is_omap34xx()) {
|
||||
if (width > (maxsinglelinewidth * 2)) {
|
||||
DSSERR("Cannot setup scaling");
|
||||
DSSERR("width exceeds maximum width possible");
|
||||
return -EINVAL;
|
||||
}
|
||||
fclk = calc_fclk_five_taps(channel, width, height, out_width,
|
||||
out_height, color_mode);
|
||||
if (width > maxsinglelinewidth) {
|
||||
if (height > out_height && height < out_height * 2)
|
||||
*five_taps = false;
|
||||
else {
|
||||
DSSERR("cannot setup scaling with five taps");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
if (!*five_taps)
|
||||
fclk = calc_fclk(channel, width, height, out_width,
|
||||
out_height);
|
||||
} else {
|
||||
if (width > maxsinglelinewidth) {
|
||||
DSSERR("Cannot scale width exceeds max line width");
|
||||
return -EINVAL;
|
||||
}
|
||||
fclk = calc_fclk(channel, width, height, out_width,
|
||||
out_height);
|
||||
|
||||
/* Try 5-tap filter if 3-tap fclk is too high */
|
||||
if (cpu_is_omap34xx() && height > out_height &&
|
||||
fclk > dispc_fclk_rate())
|
||||
*five_taps = true;
|
||||
}
|
||||
|
||||
if (width > (2048 >> *five_taps)) {
|
||||
DSSERR("failed to set up scaling, fclk too low\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (*five_taps)
|
||||
fclk = calc_fclk_five_taps(channel, width, height,
|
||||
out_width, out_height, color_mode);
|
||||
|
||||
DSSDBG("required fclk rate = %lu Hz\n", fclk);
|
||||
DSSDBG("current fclk rate = %lu Hz\n", dispc_fclk_rate());
|
||||
|
||||
|
@ -1771,11 +1757,10 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
|
|||
}
|
||||
|
||||
int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
|
||||
bool ilace, enum omap_channel channel, bool replication,
|
||||
u32 fifo_low, u32 fifo_high)
|
||||
bool ilace, bool replication)
|
||||
{
|
||||
struct omap_overlay *ovl = omap_dss_get_overlay(plane);
|
||||
bool five_taps = false;
|
||||
bool five_taps = true;
|
||||
bool fieldmode = 0;
|
||||
int r, cconv = 0;
|
||||
unsigned offset0, offset1;
|
||||
|
@ -1783,36 +1768,43 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
|
|||
s32 pix_inc;
|
||||
u16 frame_height = oi->height;
|
||||
unsigned int field_offset = 0;
|
||||
u16 outw, outh;
|
||||
enum omap_channel channel;
|
||||
|
||||
channel = dispc_ovl_get_channel_out(plane);
|
||||
|
||||
DSSDBG("dispc_ovl_setup %d, pa %x, pa_uv %x, sw %d, %d,%d, %dx%d -> "
|
||||
"%dx%d, cmode %x, rot %d, mir %d, ilace %d chan %d repl %d "
|
||||
"fifo_low %d fifo high %d\n", plane, oi->paddr, oi->p_uv_addr,
|
||||
"%dx%d, cmode %x, rot %d, mir %d, ilace %d chan %d repl %d\n",
|
||||
plane, oi->paddr, oi->p_uv_addr,
|
||||
oi->screen_width, oi->pos_x, oi->pos_y, oi->width, oi->height,
|
||||
oi->out_width, oi->out_height, oi->color_mode, oi->rotation,
|
||||
oi->mirror, ilace, channel, replication, fifo_low, fifo_high);
|
||||
oi->mirror, ilace, channel, replication);
|
||||
|
||||
if (oi->paddr == 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (ilace && oi->height == oi->out_height)
|
||||
outw = oi->out_width == 0 ? oi->width : oi->out_width;
|
||||
outh = oi->out_height == 0 ? oi->height : oi->out_height;
|
||||
|
||||
if (ilace && oi->height == outh)
|
||||
fieldmode = 1;
|
||||
|
||||
if (ilace) {
|
||||
if (fieldmode)
|
||||
oi->height /= 2;
|
||||
oi->pos_y /= 2;
|
||||
oi->out_height /= 2;
|
||||
outh /= 2;
|
||||
|
||||
DSSDBG("adjusting for ilace: height %d, pos_y %d, "
|
||||
"out_height %d\n",
|
||||
oi->height, oi->pos_y, oi->out_height);
|
||||
oi->height, oi->pos_y, outh);
|
||||
}
|
||||
|
||||
if (!dss_feat_color_mode_supported(plane, oi->color_mode))
|
||||
return -EINVAL;
|
||||
|
||||
r = dispc_ovl_calc_scaling(plane, channel, oi->width, oi->height,
|
||||
oi->out_width, oi->out_height, oi->color_mode,
|
||||
outw, outh, oi->color_mode,
|
||||
&five_taps);
|
||||
if (r)
|
||||
return r;
|
||||
|
@ -1830,10 +1822,10 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
|
|||
* so the integer part must be added to the base address of the
|
||||
* bottom field.
|
||||
*/
|
||||
if (!oi->height || oi->height == oi->out_height)
|
||||
if (!oi->height || oi->height == outh)
|
||||
field_offset = 0;
|
||||
else
|
||||
field_offset = oi->height / oi->out_height / 2;
|
||||
field_offset = oi->height / outh / 2;
|
||||
}
|
||||
|
||||
/* Fields are independent but interleaved in memory. */
|
||||
|
@ -1869,7 +1861,7 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
|
|||
dispc_ovl_set_pix_inc(plane, pix_inc);
|
||||
|
||||
DSSDBG("%d,%d %dx%d -> %dx%d\n", oi->pos_x, oi->pos_y, oi->width,
|
||||
oi->height, oi->out_width, oi->out_height);
|
||||
oi->height, outw, outh);
|
||||
|
||||
dispc_ovl_set_pos(plane, oi->pos_x, oi->pos_y);
|
||||
|
||||
|
@ -1877,10 +1869,10 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
|
|||
|
||||
if (ovl->caps & OMAP_DSS_OVL_CAP_SCALE) {
|
||||
dispc_ovl_set_scaling(plane, oi->width, oi->height,
|
||||
oi->out_width, oi->out_height,
|
||||
outw, outh,
|
||||
ilace, five_taps, fieldmode,
|
||||
oi->color_mode, oi->rotation);
|
||||
dispc_ovl_set_vid_size(plane, oi->out_width, oi->out_height);
|
||||
dispc_ovl_set_vid_size(plane, outw, outh);
|
||||
dispc_ovl_set_vid_color_conv(plane, cconv);
|
||||
}
|
||||
|
||||
|
@ -1891,10 +1883,7 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
|
|||
dispc_ovl_set_pre_mult_alpha(plane, oi->pre_mult_alpha);
|
||||
dispc_ovl_setup_global_alpha(plane, oi->global_alpha);
|
||||
|
||||
dispc_ovl_set_channel_out(plane, channel);
|
||||
|
||||
dispc_ovl_enable_replication(plane, replication);
|
||||
dispc_ovl_set_fifo_threshold(plane, fifo_low, fifo_high);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1916,10 +1905,14 @@ static void dispc_disable_isr(void *data, u32 mask)
|
|||
|
||||
static void _enable_lcd_out(enum omap_channel channel, bool enable)
|
||||
{
|
||||
if (channel == OMAP_DSS_CHANNEL_LCD2)
|
||||
if (channel == OMAP_DSS_CHANNEL_LCD2) {
|
||||
REG_FLD_MOD(DISPC_CONTROL2, enable ? 1 : 0, 0, 0);
|
||||
else
|
||||
/* flush posted write */
|
||||
dispc_read_reg(DISPC_CONTROL2);
|
||||
} else {
|
||||
REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 0, 0);
|
||||
dispc_read_reg(DISPC_CONTROL);
|
||||
}
|
||||
}
|
||||
|
||||
static void dispc_mgr_enable_lcd_out(enum omap_channel channel, bool enable)
|
||||
|
@ -1967,6 +1960,8 @@ static void dispc_mgr_enable_lcd_out(enum omap_channel channel, bool enable)
|
|||
static void _enable_digit_out(bool enable)
|
||||
{
|
||||
REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 1, 1);
|
||||
/* flush posted write */
|
||||
dispc_read_reg(DISPC_CONTROL);
|
||||
}
|
||||
|
||||
static void dispc_mgr_enable_digit_out(bool enable)
|
||||
|
@ -2124,25 +2119,12 @@ void dispc_set_loadmode(enum omap_dss_load_mode mode)
|
|||
}
|
||||
|
||||
|
||||
void dispc_mgr_set_default_color(enum omap_channel channel, u32 color)
|
||||
static void dispc_mgr_set_default_color(enum omap_channel channel, u32 color)
|
||||
{
|
||||
dispc_write_reg(DISPC_DEFAULT_COLOR(channel), color);
|
||||
}
|
||||
|
||||
u32 dispc_mgr_get_default_color(enum omap_channel channel)
|
||||
{
|
||||
u32 l;
|
||||
|
||||
BUG_ON(channel != OMAP_DSS_CHANNEL_DIGIT &&
|
||||
channel != OMAP_DSS_CHANNEL_LCD &&
|
||||
channel != OMAP_DSS_CHANNEL_LCD2);
|
||||
|
||||
l = dispc_read_reg(DISPC_DEFAULT_COLOR(channel));
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
void dispc_mgr_set_trans_key(enum omap_channel ch,
|
||||
static void dispc_mgr_set_trans_key(enum omap_channel ch,
|
||||
enum omap_dss_trans_key_type type,
|
||||
u32 trans_key)
|
||||
{
|
||||
|
@ -2156,26 +2138,7 @@ void dispc_mgr_set_trans_key(enum omap_channel ch,
|
|||
dispc_write_reg(DISPC_TRANS_COLOR(ch), trans_key);
|
||||
}
|
||||
|
||||
void dispc_mgr_get_trans_key(enum omap_channel ch,
|
||||
enum omap_dss_trans_key_type *type,
|
||||
u32 *trans_key)
|
||||
{
|
||||
if (type) {
|
||||
if (ch == OMAP_DSS_CHANNEL_LCD)
|
||||
*type = REG_GET(DISPC_CONFIG, 11, 11);
|
||||
else if (ch == OMAP_DSS_CHANNEL_DIGIT)
|
||||
*type = REG_GET(DISPC_CONFIG, 13, 13);
|
||||
else if (ch == OMAP_DSS_CHANNEL_LCD2)
|
||||
*type = REG_GET(DISPC_CONFIG2, 11, 11);
|
||||
else
|
||||
BUG();
|
||||
}
|
||||
|
||||
if (trans_key)
|
||||
*trans_key = dispc_read_reg(DISPC_TRANS_COLOR(ch));
|
||||
}
|
||||
|
||||
void dispc_mgr_enable_trans_key(enum omap_channel ch, bool enable)
|
||||
static void dispc_mgr_enable_trans_key(enum omap_channel ch, bool enable)
|
||||
{
|
||||
if (ch == OMAP_DSS_CHANNEL_LCD)
|
||||
REG_FLD_MOD(DISPC_CONFIG, enable, 10, 10);
|
||||
|
@ -2185,7 +2148,8 @@ void dispc_mgr_enable_trans_key(enum omap_channel ch, bool enable)
|
|||
REG_FLD_MOD(DISPC_CONFIG2, enable, 10, 10);
|
||||
}
|
||||
|
||||
void dispc_mgr_enable_alpha_fixed_zorder(enum omap_channel ch, bool enable)
|
||||
static void dispc_mgr_enable_alpha_fixed_zorder(enum omap_channel ch,
|
||||
bool enable)
|
||||
{
|
||||
if (!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER))
|
||||
return;
|
||||
|
@ -2196,40 +2160,20 @@ void dispc_mgr_enable_alpha_fixed_zorder(enum omap_channel ch, bool enable)
|
|||
REG_FLD_MOD(DISPC_CONFIG, enable, 19, 19);
|
||||
}
|
||||
|
||||
bool dispc_mgr_alpha_fixed_zorder_enabled(enum omap_channel ch)
|
||||
void dispc_mgr_setup(enum omap_channel channel,
|
||||
struct omap_overlay_manager_info *info)
|
||||
{
|
||||
bool enabled;
|
||||
|
||||
if (!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER))
|
||||
return false;
|
||||
|
||||
if (ch == OMAP_DSS_CHANNEL_LCD)
|
||||
enabled = REG_GET(DISPC_CONFIG, 18, 18);
|
||||
else if (ch == OMAP_DSS_CHANNEL_DIGIT)
|
||||
enabled = REG_GET(DISPC_CONFIG, 19, 19);
|
||||
else
|
||||
BUG();
|
||||
|
||||
return enabled;
|
||||
dispc_mgr_set_default_color(channel, info->default_color);
|
||||
dispc_mgr_set_trans_key(channel, info->trans_key_type, info->trans_key);
|
||||
dispc_mgr_enable_trans_key(channel, info->trans_enabled);
|
||||
dispc_mgr_enable_alpha_fixed_zorder(channel,
|
||||
info->partial_alpha_enabled);
|
||||
if (dss_has_feature(FEAT_CPR)) {
|
||||
dispc_mgr_enable_cpr(channel, info->cpr_enable);
|
||||
dispc_mgr_set_cpr_coef(channel, &info->cpr_coefs);
|
||||
}
|
||||
}
|
||||
|
||||
bool dispc_mgr_trans_key_enabled(enum omap_channel ch)
|
||||
{
|
||||
bool enabled;
|
||||
|
||||
if (ch == OMAP_DSS_CHANNEL_LCD)
|
||||
enabled = REG_GET(DISPC_CONFIG, 10, 10);
|
||||
else if (ch == OMAP_DSS_CHANNEL_DIGIT)
|
||||
enabled = REG_GET(DISPC_CONFIG, 12, 12);
|
||||
else if (ch == OMAP_DSS_CHANNEL_LCD2)
|
||||
enabled = REG_GET(DISPC_CONFIG2, 10, 10);
|
||||
else
|
||||
BUG();
|
||||
|
||||
return enabled;
|
||||
}
|
||||
|
||||
|
||||
void dispc_mgr_set_tft_data_lines(enum omap_channel channel, u8 data_lines)
|
||||
{
|
||||
int code;
|
||||
|
@ -3184,7 +3128,8 @@ static void dispc_error_worker(struct work_struct *work)
|
|||
for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
|
||||
struct omap_overlay_manager *mgr;
|
||||
mgr = omap_dss_get_overlay_manager(i);
|
||||
mgr->device->driver->disable(mgr->device);
|
||||
if (mgr->device && mgr->device->driver)
|
||||
mgr->device->driver->disable(mgr->device);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -97,6 +97,17 @@
|
|||
#define DISPC_OVL_PRELOAD(n) (DISPC_OVL_BASE(n) + \
|
||||
DISPC_PRELOAD_OFFSET(n))
|
||||
|
||||
/* DISPC up/downsampling FIR filter coefficient structure */
|
||||
struct dispc_coef {
|
||||
s8 hc4_vc22;
|
||||
s8 hc3_vc2;
|
||||
u8 hc2_vc1;
|
||||
s8 hc1_vc0;
|
||||
s8 hc0_vc00;
|
||||
};
|
||||
|
||||
const struct dispc_coef *dispc_ovl_get_scale_coef(int inc, int five_taps);
|
||||
|
||||
/* DISPC manager/channel specific registers */
|
||||
static inline u16 DISPC_DEFAULT_COLOR(enum omap_channel channel)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,326 @@
|
|||
/*
|
||||
* linux/drivers/video/omap2/dss/dispc_coefs.c
|
||||
*
|
||||
* Copyright (C) 2011 Texas Instruments
|
||||
* Author: Chandrabhanu Mahapatra <cmahapatra@ti.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published by
|
||||
* the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <video/omapdss.h>
|
||||
#include "dispc.h"
|
||||
|
||||
#define ARRAY_LEN(array) (sizeof(array) / sizeof(array[0]))
|
||||
|
||||
static const struct dispc_coef coef3_M8[8] = {
|
||||
{ 0, 0, 128, 0, 0 },
|
||||
{ 0, -4, 123, 9, 0 },
|
||||
{ 0, -4, 108, 87, 0 },
|
||||
{ 0, -2, 87, 43, 0 },
|
||||
{ 0, 64, 64, 0, 0 },
|
||||
{ 0, 43, 87, -2, 0 },
|
||||
{ 0, 24, 108, -4, 0 },
|
||||
{ 0, 9, 123, -4, 0 },
|
||||
};
|
||||
|
||||
static const struct dispc_coef coef3_M9[8] = {
|
||||
{ 0, 6, 116, 6, 0 },
|
||||
{ 0, 0, 112, 16, 0 },
|
||||
{ 0, -2, 100, 30, 0 },
|
||||
{ 0, -2, 83, 47, 0 },
|
||||
{ 0, 64, 64, 0, 0 },
|
||||
{ 0, 47, 83, -2, 0 },
|
||||
{ 0, 30, 100, -2, 0 },
|
||||
{ 0, 16, 112, 0, 0 },
|
||||
};
|
||||
|
||||
static const struct dispc_coef coef3_M10[8] = {
|
||||
{ 0, 10, 108, 10, 0 },
|
||||
{ 0, 3, 104, 21, 0 },
|
||||
{ 0, 0, 94, 34, 0 },
|
||||
{ 0, -1, 80, 49, 0 },
|
||||
{ 0, 64, 64, 0, 0 },
|
||||
{ 0, 49, 80, -1, 0 },
|
||||
{ 0, 34, 94, 0, 0 },
|
||||
{ 0, 21, 104, 3, 0 },
|
||||
};
|
||||
|
||||
static const struct dispc_coef coef3_M11[8] = {
|
||||
{ 0, 14, 100, 14, 0 },
|
||||
{ 0, 6, 98, 24, 0 },
|
||||
{ 0, 2, 90, 36, 0 },
|
||||
{ 0, 0, 78, 50, 0 },
|
||||
{ 0, 64, 64, 0, 0 },
|
||||
{ 0, 50, 78, 0, 0 },
|
||||
{ 0, 36, 90, 2, 0 },
|
||||
{ 0, 24, 98, 6, 0 },
|
||||
};
|
||||
|
||||
static const struct dispc_coef coef3_M12[8] = {
|
||||
{ 0, 16, 96, 16, 0 },
|
||||
{ 0, 9, 93, 26, 0 },
|
||||
{ 0, 4, 86, 38, 0 },
|
||||
{ 0, 1, 76, 51, 0 },
|
||||
{ 0, 64, 64, 0, 0 },
|
||||
{ 0, 51, 76, 1, 0 },
|
||||
{ 0, 38, 86, 4, 0 },
|
||||
{ 0, 26, 93, 9, 0 },
|
||||
};
|
||||
|
||||
static const struct dispc_coef coef3_M13[8] = {
|
||||
{ 0, 18, 92, 18, 0 },
|
||||
{ 0, 10, 90, 28, 0 },
|
||||
{ 0, 5, 83, 40, 0 },
|
||||
{ 0, 1, 75, 52, 0 },
|
||||
{ 0, 64, 64, 0, 0 },
|
||||
{ 0, 52, 75, 1, 0 },
|
||||
{ 0, 40, 83, 5, 0 },
|
||||
{ 0, 28, 90, 10, 0 },
|
||||
};
|
||||
|
||||
static const struct dispc_coef coef3_M14[8] = {
|
||||
{ 0, 20, 88, 20, 0 },
|
||||
{ 0, 12, 86, 30, 0 },
|
||||
{ 0, 6, 81, 41, 0 },
|
||||
{ 0, 2, 74, 52, 0 },
|
||||
{ 0, 64, 64, 0, 0 },
|
||||
{ 0, 52, 74, 2, 0 },
|
||||
{ 0, 41, 81, 6, 0 },
|
||||
{ 0, 30, 86, 12, 0 },
|
||||
};
|
||||
|
||||
static const struct dispc_coef coef3_M16[8] = {
|
||||
{ 0, 22, 84, 22, 0 },
|
||||
{ 0, 14, 82, 32, 0 },
|
||||
{ 0, 8, 78, 42, 0 },
|
||||
{ 0, 3, 72, 53, 0 },
|
||||
{ 0, 64, 64, 0, 0 },
|
||||
{ 0, 53, 72, 3, 0 },
|
||||
{ 0, 42, 78, 8, 0 },
|
||||
{ 0, 32, 82, 14, 0 },
|
||||
};
|
||||
|
||||
static const struct dispc_coef coef3_M19[8] = {
|
||||
{ 0, 24, 80, 24, 0 },
|
||||
{ 0, 16, 79, 33, 0 },
|
||||
{ 0, 9, 76, 43, 0 },
|
||||
{ 0, 4, 70, 54, 0 },
|
||||
{ 0, 64, 64, 0, 0 },
|
||||
{ 0, 54, 70, 4, 0 },
|
||||
{ 0, 43, 76, 9, 0 },
|
||||
{ 0, 33, 79, 16, 0 },
|
||||
};
|
||||
|
||||
static const struct dispc_coef coef3_M22[8] = {
|
||||
{ 0, 25, 78, 25, 0 },
|
||||
{ 0, 17, 77, 34, 0 },
|
||||
{ 0, 10, 74, 44, 0 },
|
||||
{ 0, 5, 69, 54, 0 },
|
||||
{ 0, 64, 64, 0, 0 },
|
||||
{ 0, 54, 69, 5, 0 },
|
||||
{ 0, 44, 74, 10, 0 },
|
||||
{ 0, 34, 77, 17, 0 },
|
||||
};
|
||||
|
||||
static const struct dispc_coef coef3_M26[8] = {
|
||||
{ 0, 26, 76, 26, 0 },
|
||||
{ 0, 19, 74, 35, 0 },
|
||||
{ 0, 11, 72, 45, 0 },
|
||||
{ 0, 5, 69, 54, 0 },
|
||||
{ 0, 64, 64, 0, 0 },
|
||||
{ 0, 54, 69, 5, 0 },
|
||||
{ 0, 45, 72, 11, 0 },
|
||||
{ 0, 35, 74, 19, 0 },
|
||||
};
|
||||
|
||||
static const struct dispc_coef coef3_M32[8] = {
|
||||
{ 0, 27, 74, 27, 0 },
|
||||
{ 0, 19, 73, 36, 0 },
|
||||
{ 0, 12, 71, 45, 0 },
|
||||
{ 0, 6, 68, 54, 0 },
|
||||
{ 0, 64, 64, 0, 0 },
|
||||
{ 0, 54, 68, 6, 0 },
|
||||
{ 0, 45, 71, 12, 0 },
|
||||
{ 0, 36, 73, 19, 0 },
|
||||
};
|
||||
|
||||
static const struct dispc_coef coef5_M8[8] = {
|
||||
{ 0, 0, 128, 0, 0 },
|
||||
{ -2, 14, 125, -10, 1 },
|
||||
{ -6, 33, 114, -15, 2 },
|
||||
{ -10, 55, 98, -16, 1 },
|
||||
{ 0, -14, 78, 78, -14 },
|
||||
{ 1, -16, 98, 55, -10 },
|
||||
{ 2, -15, 114, 33, -6 },
|
||||
{ 1, -10, 125, 14, -2 },
|
||||
};
|
||||
|
||||
static const struct dispc_coef coef5_M9[8] = {
|
||||
{ -3, 10, 114, 10, -3 },
|
||||
{ -6, 24, 110, 0, -1 },
|
||||
{ -8, 40, 103, -7, 0 },
|
||||
{ -11, 58, 91, -11, 1 },
|
||||
{ 0, -12, 76, 76, -12 },
|
||||
{ 1, -11, 91, 58, -11 },
|
||||
{ 0, -7, 103, 40, -8 },
|
||||
{ -1, 0, 111, 24, -6 },
|
||||
};
|
||||
|
||||
static const struct dispc_coef coef5_M10[8] = {
|
||||
{ -4, 18, 100, 18, -4 },
|
||||
{ -6, 30, 99, 8, -3 },
|
||||
{ -8, 44, 93, 0, -1 },
|
||||
{ -9, 58, 84, -5, 0 },
|
||||
{ 0, -8, 72, 72, -8 },
|
||||
{ 0, -5, 84, 58, -9 },
|
||||
{ -1, 0, 93, 44, -8 },
|
||||
{ -3, 8, 99, 30, -6 },
|
||||
};
|
||||
|
||||
static const struct dispc_coef coef5_M11[8] = {
|
||||
{ -5, 23, 92, 23, -5 },
|
||||
{ -6, 34, 90, 13, -3 },
|
||||
{ -6, 45, 85, 6, -2 },
|
||||
{ -6, 57, 78, 0, -1 },
|
||||
{ 0, -4, 68, 68, -4 },
|
||||
{ -1, 0, 78, 57, -6 },
|
||||
{ -2, 6, 85, 45, -6 },
|
||||
{ -3, 13, 90, 34, -6 },
|
||||
};
|
||||
|
||||
static const struct dispc_coef coef5_M12[8] = {
|
||||
{ -4, 26, 84, 26, -4 },
|
||||
{ -5, 36, 82, 18, -3 },
|
||||
{ -4, 46, 78, 10, -2 },
|
||||
{ -3, 55, 72, 5, -1 },
|
||||
{ 0, 0, 64, 64, 0 },
|
||||
{ -1, 5, 72, 55, -3 },
|
||||
{ -2, 10, 78, 46, -4 },
|
||||
{ -3, 18, 82, 36, -5 },
|
||||
};
|
||||
|
||||
static const struct dispc_coef coef5_M13[8] = {
|
||||
{ -3, 28, 78, 28, -3 },
|
||||
{ -3, 37, 76, 21, -3 },
|
||||
{ -2, 45, 73, 14, -2 },
|
||||
{ 0, 53, 68, 8, -1 },
|
||||
{ 0, 3, 61, 61, 3 },
|
||||
{ -1, 8, 68, 53, 0 },
|
||||
{ -2, 14, 73, 45, -2 },
|
||||
{ -3, 21, 76, 37, -3 },
|
||||
};
|
||||
|
||||
static const struct dispc_coef coef5_M14[8] = {
|
||||
{ -2, 30, 72, 30, -2 },
|
||||
{ -1, 37, 71, 23, -2 },
|
||||
{ 0, 45, 69, 16, -2 },
|
||||
{ 3, 52, 64, 10, -1 },
|
||||
{ 0, 6, 58, 58, 6 },
|
||||
{ -1, 10, 64, 52, 3 },
|
||||
{ -2, 16, 69, 45, 0 },
|
||||
{ -2, 23, 71, 37, -1 },
|
||||
};
|
||||
|
||||
static const struct dispc_coef coef5_M16[8] = {
|
||||
{ 0, 31, 66, 31, 0 },
|
||||
{ 1, 38, 65, 25, -1 },
|
||||
{ 3, 44, 62, 20, -1 },
|
||||
{ 6, 49, 59, 14, 0 },
|
||||
{ 0, 10, 54, 54, 10 },
|
||||
{ 0, 14, 59, 49, 6 },
|
||||
{ -1, 20, 62, 44, 3 },
|
||||
{ -1, 25, 65, 38, 1 },
|
||||
};
|
||||
|
||||
static const struct dispc_coef coef5_M19[8] = {
|
||||
{ 3, 32, 58, 32, 3 },
|
||||
{ 4, 38, 58, 27, 1 },
|
||||
{ 7, 42, 55, 23, 1 },
|
||||
{ 10, 46, 54, 18, 0 },
|
||||
{ 0, 14, 50, 50, 14 },
|
||||
{ 0, 18, 54, 46, 10 },
|
||||
{ 1, 23, 55, 42, 7 },
|
||||
{ 1, 27, 58, 38, 4 },
|
||||
};
|
||||
|
||||
static const struct dispc_coef coef5_M22[8] = {
|
||||
{ 4, 33, 54, 33, 4 },
|
||||
{ 6, 37, 54, 28, 3 },
|
||||
{ 9, 41, 53, 24, 1 },
|
||||
{ 12, 45, 51, 20, 0 },
|
||||
{ 0, 16, 48, 48, 16 },
|
||||
{ 0, 20, 51, 45, 12 },
|
||||
{ 1, 24, 53, 41, 9 },
|
||||
{ 3, 28, 54, 37, 6 },
|
||||
};
|
||||
|
||||
static const struct dispc_coef coef5_M26[8] = {
|
||||
{ 6, 33, 50, 33, 6 },
|
||||
{ 8, 36, 51, 29, 4 },
|
||||
{ 11, 40, 50, 25, 2 },
|
||||
{ 14, 43, 48, 22, 1 },
|
||||
{ 0, 18, 46, 46, 18 },
|
||||
{ 1, 22, 48, 43, 14 },
|
||||
{ 2, 25, 50, 40, 11 },
|
||||
{ 4, 29, 51, 36, 8 },
|
||||
};
|
||||
|
||||
static const struct dispc_coef coef5_M32[8] = {
|
||||
{ 7, 33, 48, 33, 7 },
|
||||
{ 10, 36, 48, 29, 5 },
|
||||
{ 13, 39, 47, 26, 3 },
|
||||
{ 16, 42, 46, 23, 1 },
|
||||
{ 0, 19, 45, 45, 19 },
|
||||
{ 1, 23, 46, 42, 16 },
|
||||
{ 3, 26, 47, 39, 13 },
|
||||
{ 5, 29, 48, 36, 10 },
|
||||
};
|
||||
|
||||
const struct dispc_coef *dispc_ovl_get_scale_coef(int inc, int five_taps)
|
||||
{
|
||||
int i;
|
||||
static const struct {
|
||||
int Mmin;
|
||||
int Mmax;
|
||||
const struct dispc_coef *coef_3;
|
||||
const struct dispc_coef *coef_5;
|
||||
} coefs[] = {
|
||||
{ 27, 32, coef3_M32, coef5_M32 },
|
||||
{ 23, 26, coef3_M26, coef5_M26 },
|
||||
{ 20, 22, coef3_M22, coef5_M22 },
|
||||
{ 17, 19, coef3_M19, coef5_M19 },
|
||||
{ 15, 16, coef3_M16, coef5_M16 },
|
||||
{ 14, 14, coef3_M14, coef5_M14 },
|
||||
{ 13, 13, coef3_M13, coef5_M13 },
|
||||
{ 12, 12, coef3_M12, coef5_M12 },
|
||||
{ 11, 11, coef3_M11, coef5_M11 },
|
||||
{ 10, 10, coef3_M10, coef5_M10 },
|
||||
{ 9, 9, coef3_M9, coef5_M9 },
|
||||
{ 4, 8, coef3_M8, coef5_M8 },
|
||||
/*
|
||||
* When upscaling more than two times, blockiness and outlines
|
||||
* around the image are observed when M8 tables are used. M11,
|
||||
* M16 and M19 tables are used to prevent this.
|
||||
*/
|
||||
{ 3, 3, coef3_M11, coef5_M11 },
|
||||
{ 2, 2, coef3_M16, coef5_M16 },
|
||||
{ 0, 1, coef3_M19, coef5_M19 },
|
||||
};
|
||||
|
||||
inc /= 128;
|
||||
for (i = 0; i < ARRAY_LEN(coefs); ++i)
|
||||
if (inc >= coefs[i].Mmin && inc <= coefs[i].Mmax)
|
||||
return five_taps ? coefs[i].coef_5 : coefs[i].coef_3;
|
||||
return NULL;
|
||||
}
|
|
@ -223,10 +223,13 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
|
|||
|
||||
mdelay(2);
|
||||
|
||||
dssdev->manager->enable(dssdev->manager);
|
||||
r = dss_mgr_enable(dssdev->manager);
|
||||
if (r)
|
||||
goto err_mgr_enable;
|
||||
|
||||
return 0;
|
||||
|
||||
err_mgr_enable:
|
||||
err_set_mode:
|
||||
if (dpi_use_dsi_pll(dssdev))
|
||||
dsi_pll_uninit(dpi.dsidev, true);
|
||||
|
@ -249,7 +252,7 @@ EXPORT_SYMBOL(omapdss_dpi_display_enable);
|
|||
|
||||
void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
|
||||
{
|
||||
dssdev->manager->disable(dssdev->manager);
|
||||
dss_mgr_disable(dssdev->manager);
|
||||
|
||||
if (dpi_use_dsi_pll(dssdev)) {
|
||||
dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
|
||||
|
|
|
@ -203,6 +203,21 @@ struct dsi_reg { u16 idx; };
|
|||
typedef void (*omap_dsi_isr_t) (void *arg, u32 mask);
|
||||
|
||||
#define DSI_MAX_NR_ISRS 2
|
||||
#define DSI_MAX_NR_LANES 5
|
||||
|
||||
enum dsi_lane_function {
|
||||
DSI_LANE_UNUSED = 0,
|
||||
DSI_LANE_CLK,
|
||||
DSI_LANE_DATA1,
|
||||
DSI_LANE_DATA2,
|
||||
DSI_LANE_DATA3,
|
||||
DSI_LANE_DATA4,
|
||||
};
|
||||
|
||||
struct dsi_lane_config {
|
||||
enum dsi_lane_function function;
|
||||
u8 polarity;
|
||||
};
|
||||
|
||||
struct dsi_isr_data {
|
||||
omap_dsi_isr_t isr;
|
||||
|
@ -223,24 +238,6 @@ enum dsi_vc_source {
|
|||
DSI_VC_SOURCE_VP,
|
||||
};
|
||||
|
||||
enum dsi_lane {
|
||||
DSI_CLK_P = 1 << 0,
|
||||
DSI_CLK_N = 1 << 1,
|
||||
DSI_DATA1_P = 1 << 2,
|
||||
DSI_DATA1_N = 1 << 3,
|
||||
DSI_DATA2_P = 1 << 4,
|
||||
DSI_DATA2_N = 1 << 5,
|
||||
DSI_DATA3_P = 1 << 6,
|
||||
DSI_DATA3_N = 1 << 7,
|
||||
DSI_DATA4_P = 1 << 8,
|
||||
DSI_DATA4_N = 1 << 9,
|
||||
};
|
||||
|
||||
struct dsi_update_region {
|
||||
u16 x, y, w, h;
|
||||
struct omap_dss_device *device;
|
||||
};
|
||||
|
||||
struct dsi_irq_stats {
|
||||
unsigned long last_reset;
|
||||
unsigned irq_count;
|
||||
|
@ -290,7 +287,9 @@ struct dsi_data {
|
|||
struct dsi_isr_tables isr_tables_copy;
|
||||
|
||||
int update_channel;
|
||||
struct dsi_update_region update_region;
|
||||
#ifdef DEBUG
|
||||
unsigned update_bytes;
|
||||
#endif
|
||||
|
||||
bool te_enabled;
|
||||
bool ulps_enabled;
|
||||
|
@ -327,7 +326,10 @@ struct dsi_data {
|
|||
unsigned long fint_min, fint_max;
|
||||
unsigned long lpdiv_max;
|
||||
|
||||
int num_data_lanes;
|
||||
unsigned num_lanes_supported;
|
||||
|
||||
struct dsi_lane_config lanes[DSI_MAX_NR_LANES];
|
||||
unsigned num_lanes_used;
|
||||
|
||||
unsigned scp_clk_refcount;
|
||||
};
|
||||
|
@ -413,14 +415,29 @@ static void dsi_completion_handler(void *data, u32 mask)
|
|||
static inline int wait_for_bit_change(struct platform_device *dsidev,
|
||||
const struct dsi_reg idx, int bitnum, int value)
|
||||
{
|
||||
int t = 100000;
|
||||
unsigned long timeout;
|
||||
ktime_t wait;
|
||||
int t;
|
||||
|
||||
while (REG_GET(dsidev, idx, bitnum, bitnum) != value) {
|
||||
if (--t == 0)
|
||||
return !value;
|
||||
/* first busyloop to see if the bit changes right away */
|
||||
t = 100;
|
||||
while (t-- > 0) {
|
||||
if (REG_GET(dsidev, idx, bitnum, bitnum) == value)
|
||||
return value;
|
||||
}
|
||||
|
||||
return value;
|
||||
/* then loop for 500ms, sleeping for 1ms in between */
|
||||
timeout = jiffies + msecs_to_jiffies(500);
|
||||
while (time_before(jiffies, timeout)) {
|
||||
if (REG_GET(dsidev, idx, bitnum, bitnum) == value)
|
||||
return value;
|
||||
|
||||
wait = ns_to_ktime(1000 * 1000);
|
||||
set_current_state(TASK_UNINTERRUPTIBLE);
|
||||
schedule_hrtimeout(&wait, HRTIMER_MODE_REL);
|
||||
}
|
||||
|
||||
return !value;
|
||||
}
|
||||
|
||||
u8 dsi_get_pixel_size(enum omap_dss_dsi_pixel_format fmt)
|
||||
|
@ -454,7 +471,6 @@ static void dsi_perf_mark_start(struct platform_device *dsidev)
|
|||
static void dsi_perf_show(struct platform_device *dsidev, const char *name)
|
||||
{
|
||||
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
||||
struct omap_dss_device *dssdev = dsi->update_region.device;
|
||||
ktime_t t, setup_time, trans_time;
|
||||
u32 total_bytes;
|
||||
u32 setup_us, trans_us, total_us;
|
||||
|
@ -476,9 +492,7 @@ static void dsi_perf_show(struct platform_device *dsidev, const char *name)
|
|||
|
||||
total_us = setup_us + trans_us;
|
||||
|
||||
total_bytes = dsi->update_region.w *
|
||||
dsi->update_region.h *
|
||||
dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt) / 8;
|
||||
total_bytes = dsi->update_bytes;
|
||||
|
||||
printk(KERN_INFO "DSI(%s): %u us + %u us = %u us (%uHz), "
|
||||
"%u bytes, %u kbytes/sec\n",
|
||||
|
@ -1720,17 +1734,19 @@ static void dsi_dump_dsidev_clocks(struct platform_device *dsidev,
|
|||
seq_printf(s, "CLKIN4DDR\t%-16luregm %u\n",
|
||||
cinfo->clkin4ddr, cinfo->regm);
|
||||
|
||||
seq_printf(s, "%s (%s)\t%-16luregm_dispc %u\t(%s)\n",
|
||||
dss_get_generic_clk_source_name(dispc_clk_src),
|
||||
dss_feat_get_clk_source_name(dispc_clk_src),
|
||||
seq_printf(s, "DSI_PLL_HSDIV_DISPC (%s)\t%-16luregm_dispc %u\t(%s)\n",
|
||||
dss_feat_get_clk_source_name(dsi_module == 0 ?
|
||||
OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC :
|
||||
OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC),
|
||||
cinfo->dsi_pll_hsdiv_dispc_clk,
|
||||
cinfo->regm_dispc,
|
||||
dispc_clk_src == OMAP_DSS_CLK_SRC_FCK ?
|
||||
"off" : "on");
|
||||
|
||||
seq_printf(s, "%s (%s)\t%-16luregm_dsi %u\t(%s)\n",
|
||||
dss_get_generic_clk_source_name(dsi_clk_src),
|
||||
dss_feat_get_clk_source_name(dsi_clk_src),
|
||||
seq_printf(s, "DSI_PLL_HSDIV_DSI (%s)\t%-16luregm_dsi %u\t(%s)\n",
|
||||
dss_feat_get_clk_source_name(dsi_module == 0 ?
|
||||
OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI :
|
||||
OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI),
|
||||
cinfo->dsi_pll_hsdiv_dsi_clk,
|
||||
cinfo->regm_dsi,
|
||||
dsi_clk_src == OMAP_DSS_CLK_SRC_FCK ?
|
||||
|
@ -2029,34 +2045,6 @@ static int dsi_cio_power(struct platform_device *dsidev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Number of data lanes present on DSI interface */
|
||||
static inline int dsi_get_num_data_lanes(struct platform_device *dsidev)
|
||||
{
|
||||
/* DSI on OMAP3 doesn't have register DSI_GNQ, set number
|
||||
* of data lanes as 2 by default */
|
||||
if (dss_has_feature(FEAT_DSI_GNQ))
|
||||
return REG_GET(dsidev, DSI_GNQ, 11, 9); /* NB_DATA_LANES */
|
||||
else
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* Number of data lanes used by the dss device */
|
||||
static inline int dsi_get_num_data_lanes_dssdev(struct omap_dss_device *dssdev)
|
||||
{
|
||||
int num_data_lanes = 0;
|
||||
|
||||
if (dssdev->phy.dsi.data1_lane != 0)
|
||||
num_data_lanes++;
|
||||
if (dssdev->phy.dsi.data2_lane != 0)
|
||||
num_data_lanes++;
|
||||
if (dssdev->phy.dsi.data3_lane != 0)
|
||||
num_data_lanes++;
|
||||
if (dssdev->phy.dsi.data4_lane != 0)
|
||||
num_data_lanes++;
|
||||
|
||||
return num_data_lanes;
|
||||
}
|
||||
|
||||
static unsigned dsi_get_line_buf_size(struct platform_device *dsidev)
|
||||
{
|
||||
int val;
|
||||
|
@ -2088,59 +2076,112 @@ static unsigned dsi_get_line_buf_size(struct platform_device *dsidev)
|
|||
}
|
||||
}
|
||||
|
||||
static void dsi_set_lane_config(struct omap_dss_device *dssdev)
|
||||
static int dsi_parse_lane_config(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
|
||||
u32 r;
|
||||
int num_data_lanes_dssdev = dsi_get_num_data_lanes_dssdev(dssdev);
|
||||
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
||||
u8 lanes[DSI_MAX_NR_LANES];
|
||||
u8 polarities[DSI_MAX_NR_LANES];
|
||||
int num_lanes, i;
|
||||
|
||||
int clk_lane = dssdev->phy.dsi.clk_lane;
|
||||
int data1_lane = dssdev->phy.dsi.data1_lane;
|
||||
int data2_lane = dssdev->phy.dsi.data2_lane;
|
||||
int clk_pol = dssdev->phy.dsi.clk_pol;
|
||||
int data1_pol = dssdev->phy.dsi.data1_pol;
|
||||
int data2_pol = dssdev->phy.dsi.data2_pol;
|
||||
static const enum dsi_lane_function functions[] = {
|
||||
DSI_LANE_CLK,
|
||||
DSI_LANE_DATA1,
|
||||
DSI_LANE_DATA2,
|
||||
DSI_LANE_DATA3,
|
||||
DSI_LANE_DATA4,
|
||||
};
|
||||
|
||||
lanes[0] = dssdev->phy.dsi.clk_lane;
|
||||
lanes[1] = dssdev->phy.dsi.data1_lane;
|
||||
lanes[2] = dssdev->phy.dsi.data2_lane;
|
||||
lanes[3] = dssdev->phy.dsi.data3_lane;
|
||||
lanes[4] = dssdev->phy.dsi.data4_lane;
|
||||
polarities[0] = dssdev->phy.dsi.clk_pol;
|
||||
polarities[1] = dssdev->phy.dsi.data1_pol;
|
||||
polarities[2] = dssdev->phy.dsi.data2_pol;
|
||||
polarities[3] = dssdev->phy.dsi.data3_pol;
|
||||
polarities[4] = dssdev->phy.dsi.data4_pol;
|
||||
|
||||
num_lanes = 0;
|
||||
|
||||
for (i = 0; i < dsi->num_lanes_supported; ++i)
|
||||
dsi->lanes[i].function = DSI_LANE_UNUSED;
|
||||
|
||||
for (i = 0; i < dsi->num_lanes_supported; ++i) {
|
||||
int num;
|
||||
|
||||
if (lanes[i] == DSI_LANE_UNUSED)
|
||||
break;
|
||||
|
||||
num = lanes[i] - 1;
|
||||
|
||||
if (num >= dsi->num_lanes_supported)
|
||||
return -EINVAL;
|
||||
|
||||
if (dsi->lanes[num].function != DSI_LANE_UNUSED)
|
||||
return -EINVAL;
|
||||
|
||||
dsi->lanes[num].function = functions[i];
|
||||
dsi->lanes[num].polarity = polarities[i];
|
||||
num_lanes++;
|
||||
}
|
||||
|
||||
if (num_lanes < 2 || num_lanes > dsi->num_lanes_supported)
|
||||
return -EINVAL;
|
||||
|
||||
dsi->num_lanes_used = num_lanes;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dsi_set_lane_config(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
|
||||
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
||||
static const u8 offsets[] = { 0, 4, 8, 12, 16 };
|
||||
static const enum dsi_lane_function functions[] = {
|
||||
DSI_LANE_CLK,
|
||||
DSI_LANE_DATA1,
|
||||
DSI_LANE_DATA2,
|
||||
DSI_LANE_DATA3,
|
||||
DSI_LANE_DATA4,
|
||||
};
|
||||
u32 r;
|
||||
int i;
|
||||
|
||||
r = dsi_read_reg(dsidev, DSI_COMPLEXIO_CFG1);
|
||||
r = FLD_MOD(r, clk_lane, 2, 0);
|
||||
r = FLD_MOD(r, clk_pol, 3, 3);
|
||||
r = FLD_MOD(r, data1_lane, 6, 4);
|
||||
r = FLD_MOD(r, data1_pol, 7, 7);
|
||||
r = FLD_MOD(r, data2_lane, 10, 8);
|
||||
r = FLD_MOD(r, data2_pol, 11, 11);
|
||||
if (num_data_lanes_dssdev > 2) {
|
||||
int data3_lane = dssdev->phy.dsi.data3_lane;
|
||||
int data3_pol = dssdev->phy.dsi.data3_pol;
|
||||
|
||||
r = FLD_MOD(r, data3_lane, 14, 12);
|
||||
r = FLD_MOD(r, data3_pol, 15, 15);
|
||||
}
|
||||
if (num_data_lanes_dssdev > 3) {
|
||||
int data4_lane = dssdev->phy.dsi.data4_lane;
|
||||
int data4_pol = dssdev->phy.dsi.data4_pol;
|
||||
for (i = 0; i < dsi->num_lanes_used; ++i) {
|
||||
unsigned offset = offsets[i];
|
||||
unsigned polarity, lane_number;
|
||||
unsigned t;
|
||||
|
||||
r = FLD_MOD(r, data4_lane, 18, 16);
|
||||
r = FLD_MOD(r, data4_pol, 19, 19);
|
||||
for (t = 0; t < dsi->num_lanes_supported; ++t)
|
||||
if (dsi->lanes[t].function == functions[i])
|
||||
break;
|
||||
|
||||
if (t == dsi->num_lanes_supported)
|
||||
return -EINVAL;
|
||||
|
||||
lane_number = t;
|
||||
polarity = dsi->lanes[t].polarity;
|
||||
|
||||
r = FLD_MOD(r, lane_number + 1, offset + 2, offset);
|
||||
r = FLD_MOD(r, polarity, offset + 3, offset + 3);
|
||||
}
|
||||
|
||||
/* clear the unused lanes */
|
||||
for (; i < dsi->num_lanes_supported; ++i) {
|
||||
unsigned offset = offsets[i];
|
||||
|
||||
r = FLD_MOD(r, 0, offset + 2, offset);
|
||||
r = FLD_MOD(r, 0, offset + 3, offset + 3);
|
||||
}
|
||||
|
||||
dsi_write_reg(dsidev, DSI_COMPLEXIO_CFG1, r);
|
||||
|
||||
/* The configuration of the DSI complex I/O (number of data lanes,
|
||||
position, differential order) should not be changed while
|
||||
DSS.DSI_CLK_CRTRL[20] LP_CLK_ENABLE bit is set to 1. In order for
|
||||
the hardware to take into account a new configuration of the complex
|
||||
I/O (done in DSS.DSI_COMPLEXIO_CFG1 register), it is recommended to
|
||||
follow this sequence: First set the DSS.DSI_CTRL[0] IF_EN bit to 1,
|
||||
then reset the DSS.DSI_CTRL[0] IF_EN to 0, then set
|
||||
DSS.DSI_CLK_CTRL[20] LP_CLK_ENABLE to 1 and finally set again the
|
||||
DSS.DSI_CTRL[0] IF_EN bit to 1. If the sequence is not followed, the
|
||||
DSI complex I/O configuration is unknown. */
|
||||
|
||||
/*
|
||||
REG_FLD_MOD(dsidev, DSI_CTRL, 1, 0, 0);
|
||||
REG_FLD_MOD(dsidev, DSI_CTRL, 0, 0, 0);
|
||||
REG_FLD_MOD(dsidev, DSI_CLK_CTRL, 1, 20, 20);
|
||||
REG_FLD_MOD(dsidev, DSI_CTRL, 1, 0, 0);
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline unsigned ns2ddr(struct platform_device *dsidev, unsigned ns)
|
||||
|
@ -2230,49 +2271,28 @@ static void dsi_cio_timings(struct platform_device *dsidev)
|
|||
dsi_write_reg(dsidev, DSI_DSIPHY_CFG2, r);
|
||||
}
|
||||
|
||||
/* lane masks have lane 0 at lsb. mask_p for positive lines, n for negative */
|
||||
static void dsi_cio_enable_lane_override(struct omap_dss_device *dssdev,
|
||||
enum dsi_lane lanes)
|
||||
unsigned mask_p, unsigned mask_n)
|
||||
{
|
||||
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
|
||||
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
||||
int clk_lane = dssdev->phy.dsi.clk_lane;
|
||||
int data1_lane = dssdev->phy.dsi.data1_lane;
|
||||
int data2_lane = dssdev->phy.dsi.data2_lane;
|
||||
int data3_lane = dssdev->phy.dsi.data3_lane;
|
||||
int data4_lane = dssdev->phy.dsi.data4_lane;
|
||||
int clk_pol = dssdev->phy.dsi.clk_pol;
|
||||
int data1_pol = dssdev->phy.dsi.data1_pol;
|
||||
int data2_pol = dssdev->phy.dsi.data2_pol;
|
||||
int data3_pol = dssdev->phy.dsi.data3_pol;
|
||||
int data4_pol = dssdev->phy.dsi.data4_pol;
|
||||
int i;
|
||||
u32 l;
|
||||
u8 lptxscp_start = dsi->num_lanes_supported == 3 ? 22 : 26;
|
||||
|
||||
u32 l = 0;
|
||||
u8 lptxscp_start = dsi->num_data_lanes == 2 ? 22 : 26;
|
||||
l = 0;
|
||||
|
||||
if (lanes & DSI_CLK_P)
|
||||
l |= 1 << ((clk_lane - 1) * 2 + (clk_pol ? 0 : 1));
|
||||
if (lanes & DSI_CLK_N)
|
||||
l |= 1 << ((clk_lane - 1) * 2 + (clk_pol ? 1 : 0));
|
||||
for (i = 0; i < dsi->num_lanes_supported; ++i) {
|
||||
unsigned p = dsi->lanes[i].polarity;
|
||||
|
||||
if (lanes & DSI_DATA1_P)
|
||||
l |= 1 << ((data1_lane - 1) * 2 + (data1_pol ? 0 : 1));
|
||||
if (lanes & DSI_DATA1_N)
|
||||
l |= 1 << ((data1_lane - 1) * 2 + (data1_pol ? 1 : 0));
|
||||
if (mask_p & (1 << i))
|
||||
l |= 1 << (i * 2 + (p ? 0 : 1));
|
||||
|
||||
if (lanes & DSI_DATA2_P)
|
||||
l |= 1 << ((data2_lane - 1) * 2 + (data2_pol ? 0 : 1));
|
||||
if (lanes & DSI_DATA2_N)
|
||||
l |= 1 << ((data2_lane - 1) * 2 + (data2_pol ? 1 : 0));
|
||||
if (mask_n & (1 << i))
|
||||
l |= 1 << (i * 2 + (p ? 1 : 0));
|
||||
}
|
||||
|
||||
if (lanes & DSI_DATA3_P)
|
||||
l |= 1 << ((data3_lane - 1) * 2 + (data3_pol ? 0 : 1));
|
||||
if (lanes & DSI_DATA3_N)
|
||||
l |= 1 << ((data3_lane - 1) * 2 + (data3_pol ? 1 : 0));
|
||||
|
||||
if (lanes & DSI_DATA4_P)
|
||||
l |= 1 << ((data4_lane - 1) * 2 + (data4_pol ? 0 : 1));
|
||||
if (lanes & DSI_DATA4_N)
|
||||
l |= 1 << ((data4_lane - 1) * 2 + (data4_pol ? 1 : 0));
|
||||
/*
|
||||
* Bits in REGLPTXSCPDAT4TO0DXDY:
|
||||
* 17: DY0 18: DX0
|
||||
|
@ -2305,51 +2325,40 @@ static void dsi_cio_disable_lane_override(struct platform_device *dsidev)
|
|||
static int dsi_cio_wait_tx_clk_esc_reset(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
|
||||
int t;
|
||||
int bits[3];
|
||||
bool in_use[3];
|
||||
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
||||
int t, i;
|
||||
bool in_use[DSI_MAX_NR_LANES];
|
||||
static const u8 offsets_old[] = { 28, 27, 26 };
|
||||
static const u8 offsets_new[] = { 24, 25, 26, 27, 28 };
|
||||
const u8 *offsets;
|
||||
|
||||
if (dss_has_feature(FEAT_DSI_REVERSE_TXCLKESC)) {
|
||||
bits[0] = 28;
|
||||
bits[1] = 27;
|
||||
bits[2] = 26;
|
||||
} else {
|
||||
bits[0] = 24;
|
||||
bits[1] = 25;
|
||||
bits[2] = 26;
|
||||
}
|
||||
if (dss_has_feature(FEAT_DSI_REVERSE_TXCLKESC))
|
||||
offsets = offsets_old;
|
||||
else
|
||||
offsets = offsets_new;
|
||||
|
||||
in_use[0] = false;
|
||||
in_use[1] = false;
|
||||
in_use[2] = false;
|
||||
|
||||
if (dssdev->phy.dsi.clk_lane != 0)
|
||||
in_use[dssdev->phy.dsi.clk_lane - 1] = true;
|
||||
if (dssdev->phy.dsi.data1_lane != 0)
|
||||
in_use[dssdev->phy.dsi.data1_lane - 1] = true;
|
||||
if (dssdev->phy.dsi.data2_lane != 0)
|
||||
in_use[dssdev->phy.dsi.data2_lane - 1] = true;
|
||||
for (i = 0; i < dsi->num_lanes_supported; ++i)
|
||||
in_use[i] = dsi->lanes[i].function != DSI_LANE_UNUSED;
|
||||
|
||||
t = 100000;
|
||||
while (true) {
|
||||
u32 l;
|
||||
int i;
|
||||
int ok;
|
||||
|
||||
l = dsi_read_reg(dsidev, DSI_DSIPHY_CFG5);
|
||||
|
||||
ok = 0;
|
||||
for (i = 0; i < 3; ++i) {
|
||||
if (!in_use[i] || (l & (1 << bits[i])))
|
||||
for (i = 0; i < dsi->num_lanes_supported; ++i) {
|
||||
if (!in_use[i] || (l & (1 << offsets[i])))
|
||||
ok++;
|
||||
}
|
||||
|
||||
if (ok == 3)
|
||||
if (ok == dsi->num_lanes_supported)
|
||||
break;
|
||||
|
||||
if (--t == 0) {
|
||||
for (i = 0; i < 3; ++i) {
|
||||
if (!in_use[i] || (l & (1 << bits[i])))
|
||||
for (i = 0; i < dsi->num_lanes_supported; ++i) {
|
||||
if (!in_use[i] || (l & (1 << offsets[i])))
|
||||
continue;
|
||||
|
||||
DSSERR("CIO TXCLKESC%d domain not coming " \
|
||||
|
@ -2362,22 +2371,20 @@ static int dsi_cio_wait_tx_clk_esc_reset(struct omap_dss_device *dssdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* return bitmask of enabled lanes, lane0 being the lsb */
|
||||
static unsigned dsi_get_lane_mask(struct omap_dss_device *dssdev)
|
||||
{
|
||||
unsigned lanes = 0;
|
||||
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
|
||||
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
||||
unsigned mask = 0;
|
||||
int i;
|
||||
|
||||
if (dssdev->phy.dsi.clk_lane != 0)
|
||||
lanes |= 1 << (dssdev->phy.dsi.clk_lane - 1);
|
||||
if (dssdev->phy.dsi.data1_lane != 0)
|
||||
lanes |= 1 << (dssdev->phy.dsi.data1_lane - 1);
|
||||
if (dssdev->phy.dsi.data2_lane != 0)
|
||||
lanes |= 1 << (dssdev->phy.dsi.data2_lane - 1);
|
||||
if (dssdev->phy.dsi.data3_lane != 0)
|
||||
lanes |= 1 << (dssdev->phy.dsi.data3_lane - 1);
|
||||
if (dssdev->phy.dsi.data4_lane != 0)
|
||||
lanes |= 1 << (dssdev->phy.dsi.data4_lane - 1);
|
||||
for (i = 0; i < dsi->num_lanes_supported; ++i) {
|
||||
if (dsi->lanes[i].function != DSI_LANE_UNUSED)
|
||||
mask |= 1 << i;
|
||||
}
|
||||
|
||||
return lanes;
|
||||
return mask;
|
||||
}
|
||||
|
||||
static int dsi_cio_init(struct omap_dss_device *dssdev)
|
||||
|
@ -2385,7 +2392,6 @@ static int dsi_cio_init(struct omap_dss_device *dssdev)
|
|||
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
|
||||
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
||||
int r;
|
||||
int num_data_lanes_dssdev = dsi_get_num_data_lanes_dssdev(dssdev);
|
||||
u32 l;
|
||||
|
||||
DSSDBGF();
|
||||
|
@ -2407,7 +2413,9 @@ static int dsi_cio_init(struct omap_dss_device *dssdev)
|
|||
goto err_scp_clk_dom;
|
||||
}
|
||||
|
||||
dsi_set_lane_config(dssdev);
|
||||
r = dsi_set_lane_config(dssdev);
|
||||
if (r)
|
||||
goto err_scp_clk_dom;
|
||||
|
||||
/* set TX STOP MODE timer to maximum for this operation */
|
||||
l = dsi_read_reg(dsidev, DSI_TIMING1);
|
||||
|
@ -2418,7 +2426,8 @@ static int dsi_cio_init(struct omap_dss_device *dssdev)
|
|||
dsi_write_reg(dsidev, DSI_TIMING1, l);
|
||||
|
||||
if (dsi->ulps_enabled) {
|
||||
u32 lane_mask = DSI_CLK_P | DSI_DATA1_P | DSI_DATA2_P;
|
||||
unsigned mask_p;
|
||||
int i;
|
||||
|
||||
DSSDBG("manual ulps exit\n");
|
||||
|
||||
|
@ -2427,16 +2436,19 @@ static int dsi_cio_init(struct omap_dss_device *dssdev)
|
|||
* ULPS exit sequence, as after reset the DSS HW thinks
|
||||
* that we are not in ULPS mode, and refuses to send the
|
||||
* sequence. So we need to send the ULPS exit sequence
|
||||
* manually.
|
||||
* manually by setting positive lines high and negative lines
|
||||
* low for 1ms.
|
||||
*/
|
||||
|
||||
if (num_data_lanes_dssdev > 2)
|
||||
lane_mask |= DSI_DATA3_P;
|
||||
mask_p = 0;
|
||||
|
||||
if (num_data_lanes_dssdev > 3)
|
||||
lane_mask |= DSI_DATA4_P;
|
||||
for (i = 0; i < dsi->num_lanes_supported; ++i) {
|
||||
if (dsi->lanes[i].function == DSI_LANE_UNUSED)
|
||||
continue;
|
||||
mask_p |= 1 << i;
|
||||
}
|
||||
|
||||
dsi_cio_enable_lane_override(dssdev, lane_mask);
|
||||
dsi_cio_enable_lane_override(dssdev, mask_p, 0);
|
||||
}
|
||||
|
||||
r = dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_ON);
|
||||
|
@ -2913,6 +2925,9 @@ static int dsi_vc_send_bta(struct platform_device *dsidev, int channel)
|
|||
|
||||
REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 1, 6, 6); /* BTA_EN */
|
||||
|
||||
/* flush posted write */
|
||||
dsi_read_reg(dsidev, DSI_VC_CTRL(channel));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3513,7 +3528,8 @@ static int dsi_enter_ulps(struct platform_device *dsidev)
|
|||
{
|
||||
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
||||
DECLARE_COMPLETION_ONSTACK(completion);
|
||||
int r;
|
||||
int r, i;
|
||||
unsigned mask;
|
||||
|
||||
DSSDBGF();
|
||||
|
||||
|
@ -3524,9 +3540,11 @@ static int dsi_enter_ulps(struct platform_device *dsidev)
|
|||
if (dsi->ulps_enabled)
|
||||
return 0;
|
||||
|
||||
/* DDR_CLK_ALWAYS_ON */
|
||||
if (REG_GET(dsidev, DSI_CLK_CTRL, 13, 13)) {
|
||||
DSSERR("DDR_CLK_ALWAYS_ON enabled when entering ULPS\n");
|
||||
return -EIO;
|
||||
dsi_if_enable(dsidev, 0);
|
||||
REG_FLD_MOD(dsidev, DSI_CLK_CTRL, 0, 13, 13);
|
||||
dsi_if_enable(dsidev, 1);
|
||||
}
|
||||
|
||||
dsi_sync_vc(dsidev, 0);
|
||||
|
@ -3556,10 +3574,19 @@ static int dsi_enter_ulps(struct platform_device *dsidev)
|
|||
if (r)
|
||||
return r;
|
||||
|
||||
mask = 0;
|
||||
|
||||
for (i = 0; i < dsi->num_lanes_supported; ++i) {
|
||||
if (dsi->lanes[i].function == DSI_LANE_UNUSED)
|
||||
continue;
|
||||
mask |= 1 << i;
|
||||
}
|
||||
/* Assert TxRequestEsc for data lanes and TxUlpsClk for clk lane */
|
||||
/* LANEx_ULPS_SIG2 */
|
||||
REG_FLD_MOD(dsidev, DSI_COMPLEXIO_CFG2, (1 << 0) | (1 << 1) | (1 << 2),
|
||||
7, 5);
|
||||
REG_FLD_MOD(dsidev, DSI_COMPLEXIO_CFG2, mask, 9, 5);
|
||||
|
||||
/* flush posted write and wait for SCP interface to finish the write */
|
||||
dsi_read_reg(dsidev, DSI_COMPLEXIO_CFG2);
|
||||
|
||||
if (wait_for_completion_timeout(&completion,
|
||||
msecs_to_jiffies(1000)) == 0) {
|
||||
|
@ -3572,8 +3599,10 @@ static int dsi_enter_ulps(struct platform_device *dsidev)
|
|||
DSI_CIO_IRQ_ULPSACTIVENOT_ALL0);
|
||||
|
||||
/* Reset LANEx_ULPS_SIG2 */
|
||||
REG_FLD_MOD(dsidev, DSI_COMPLEXIO_CFG2, (0 << 0) | (0 << 1) | (0 << 2),
|
||||
7, 5);
|
||||
REG_FLD_MOD(dsidev, DSI_COMPLEXIO_CFG2, 0, 9, 5);
|
||||
|
||||
/* flush posted write and wait for SCP interface to finish the write */
|
||||
dsi_read_reg(dsidev, DSI_COMPLEXIO_CFG2);
|
||||
|
||||
dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_ULPS);
|
||||
|
||||
|
@ -3836,6 +3865,7 @@ static int dsi_proto_config(struct omap_dss_device *dssdev)
|
|||
static void dsi_proto_timings(struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
|
||||
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
||||
unsigned tlpx, tclk_zero, tclk_prepare, tclk_trail;
|
||||
unsigned tclk_pre, tclk_post;
|
||||
unsigned ths_prepare, ths_prepare_ths_zero, ths_zero;
|
||||
|
@ -3843,7 +3873,7 @@ static void dsi_proto_timings(struct omap_dss_device *dssdev)
|
|||
unsigned ddr_clk_pre, ddr_clk_post;
|
||||
unsigned enter_hs_mode_lat, exit_hs_mode_lat;
|
||||
unsigned ths_eot;
|
||||
int ndl = dsi_get_num_data_lanes_dssdev(dssdev);
|
||||
int ndl = dsi->num_lanes_used - 1;
|
||||
u32 r;
|
||||
|
||||
r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG0);
|
||||
|
@ -3945,68 +3975,82 @@ static void dsi_proto_timings(struct omap_dss_device *dssdev)
|
|||
}
|
||||
}
|
||||
|
||||
int dsi_video_mode_enable(struct omap_dss_device *dssdev, int channel)
|
||||
int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
|
||||
{
|
||||
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
|
||||
int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
|
||||
u8 data_type;
|
||||
u16 word_count;
|
||||
int r;
|
||||
|
||||
switch (dssdev->panel.dsi_pix_fmt) {
|
||||
case OMAP_DSS_DSI_FMT_RGB888:
|
||||
data_type = MIPI_DSI_PACKED_PIXEL_STREAM_24;
|
||||
break;
|
||||
case OMAP_DSS_DSI_FMT_RGB666:
|
||||
data_type = MIPI_DSI_PIXEL_STREAM_3BYTE_18;
|
||||
break;
|
||||
case OMAP_DSS_DSI_FMT_RGB666_PACKED:
|
||||
data_type = MIPI_DSI_PACKED_PIXEL_STREAM_18;
|
||||
break;
|
||||
case OMAP_DSS_DSI_FMT_RGB565:
|
||||
data_type = MIPI_DSI_PACKED_PIXEL_STREAM_16;
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
};
|
||||
if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) {
|
||||
switch (dssdev->panel.dsi_pix_fmt) {
|
||||
case OMAP_DSS_DSI_FMT_RGB888:
|
||||
data_type = MIPI_DSI_PACKED_PIXEL_STREAM_24;
|
||||
break;
|
||||
case OMAP_DSS_DSI_FMT_RGB666:
|
||||
data_type = MIPI_DSI_PIXEL_STREAM_3BYTE_18;
|
||||
break;
|
||||
case OMAP_DSS_DSI_FMT_RGB666_PACKED:
|
||||
data_type = MIPI_DSI_PACKED_PIXEL_STREAM_18;
|
||||
break;
|
||||
case OMAP_DSS_DSI_FMT_RGB565:
|
||||
data_type = MIPI_DSI_PACKED_PIXEL_STREAM_16;
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
};
|
||||
|
||||
dsi_if_enable(dsidev, false);
|
||||
dsi_vc_enable(dsidev, channel, false);
|
||||
dsi_if_enable(dsidev, false);
|
||||
dsi_vc_enable(dsidev, channel, false);
|
||||
|
||||
/* MODE, 1 = video mode */
|
||||
REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 1, 4, 4);
|
||||
/* MODE, 1 = video mode */
|
||||
REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 1, 4, 4);
|
||||
|
||||
word_count = DIV_ROUND_UP(dssdev->panel.timings.x_res * bpp, 8);
|
||||
word_count = DIV_ROUND_UP(dssdev->panel.timings.x_res * bpp, 8);
|
||||
|
||||
dsi_vc_write_long_header(dsidev, channel, data_type, word_count, 0);
|
||||
dsi_vc_write_long_header(dsidev, channel, data_type,
|
||||
word_count, 0);
|
||||
|
||||
dsi_vc_enable(dsidev, channel, true);
|
||||
dsi_if_enable(dsidev, true);
|
||||
dsi_vc_enable(dsidev, channel, true);
|
||||
dsi_if_enable(dsidev, true);
|
||||
}
|
||||
|
||||
dssdev->manager->enable(dssdev->manager);
|
||||
r = dss_mgr_enable(dssdev->manager);
|
||||
if (r) {
|
||||
if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) {
|
||||
dsi_if_enable(dsidev, false);
|
||||
dsi_vc_enable(dsidev, channel, false);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(dsi_video_mode_enable);
|
||||
EXPORT_SYMBOL(dsi_enable_video_output);
|
||||
|
||||
void dsi_video_mode_disable(struct omap_dss_device *dssdev, int channel)
|
||||
void dsi_disable_video_output(struct omap_dss_device *dssdev, int channel)
|
||||
{
|
||||
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
|
||||
|
||||
dsi_if_enable(dsidev, false);
|
||||
dsi_vc_enable(dsidev, channel, false);
|
||||
if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) {
|
||||
dsi_if_enable(dsidev, false);
|
||||
dsi_vc_enable(dsidev, channel, false);
|
||||
|
||||
/* MODE, 0 = command mode */
|
||||
REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 0, 4, 4);
|
||||
/* MODE, 0 = command mode */
|
||||
REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 0, 4, 4);
|
||||
|
||||
dsi_vc_enable(dsidev, channel, true);
|
||||
dsi_if_enable(dsidev, true);
|
||||
dsi_vc_enable(dsidev, channel, true);
|
||||
dsi_if_enable(dsidev, true);
|
||||
}
|
||||
|
||||
dssdev->manager->disable(dssdev->manager);
|
||||
dss_mgr_disable(dssdev->manager);
|
||||
}
|
||||
EXPORT_SYMBOL(dsi_video_mode_disable);
|
||||
EXPORT_SYMBOL(dsi_disable_video_output);
|
||||
|
||||
static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
|
||||
u16 x, u16 y, u16 w, u16 h)
|
||||
u16 w, u16 h)
|
||||
{
|
||||
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
|
||||
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
||||
|
@ -4021,8 +4065,7 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
|
|||
const unsigned channel = dsi->update_channel;
|
||||
const unsigned line_buf_size = dsi_get_line_buf_size(dsidev);
|
||||
|
||||
DSSDBG("dsi_update_screen_dispc(%d,%d %dx%d)\n",
|
||||
x, y, w, h);
|
||||
DSSDBG("dsi_update_screen_dispc(%dx%d)\n", w, h);
|
||||
|
||||
dsi_vc_config_source(dsidev, channel, DSI_VC_SOURCE_VP);
|
||||
|
||||
|
@ -4070,7 +4113,7 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
|
|||
msecs_to_jiffies(250));
|
||||
BUG_ON(r == 0);
|
||||
|
||||
dss_start_update(dssdev);
|
||||
dss_mgr_start_update(dssdev->manager);
|
||||
|
||||
if (dsi->te_enabled) {
|
||||
/* disable LP_RX_TO, so that we can receive TE. Time to wait
|
||||
|
@ -4146,66 +4189,27 @@ static void dsi_framedone_irq_callback(void *data, u32 mask)
|
|||
#endif
|
||||
}
|
||||
|
||||
int omap_dsi_prepare_update(struct omap_dss_device *dssdev,
|
||||
u16 *x, u16 *y, u16 *w, u16 *h,
|
||||
bool enlarge_update_area)
|
||||
{
|
||||
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
|
||||
u16 dw, dh;
|
||||
|
||||
dssdev->driver->get_resolution(dssdev, &dw, &dh);
|
||||
|
||||
if (*x > dw || *y > dh)
|
||||
return -EINVAL;
|
||||
|
||||
if (*x + *w > dw)
|
||||
return -EINVAL;
|
||||
|
||||
if (*y + *h > dh)
|
||||
return -EINVAL;
|
||||
|
||||
if (*w == 1)
|
||||
return -EINVAL;
|
||||
|
||||
if (*w == 0 || *h == 0)
|
||||
return -EINVAL;
|
||||
|
||||
dsi_perf_mark_setup(dsidev);
|
||||
|
||||
dss_setup_partial_planes(dssdev, x, y, w, h,
|
||||
enlarge_update_area);
|
||||
dispc_mgr_set_lcd_size(dssdev->manager->id, *w, *h);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(omap_dsi_prepare_update);
|
||||
|
||||
int omap_dsi_update(struct omap_dss_device *dssdev,
|
||||
int channel,
|
||||
u16 x, u16 y, u16 w, u16 h,
|
||||
int omap_dsi_update(struct omap_dss_device *dssdev, int channel,
|
||||
void (*callback)(int, void *), void *data)
|
||||
{
|
||||
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
|
||||
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
||||
u16 dw, dh;
|
||||
|
||||
dsi_perf_mark_setup(dsidev);
|
||||
|
||||
dsi->update_channel = channel;
|
||||
|
||||
/* OMAP DSS cannot send updates of odd widths.
|
||||
* omap_dsi_prepare_update() makes the widths even, but add a BUG_ON
|
||||
* here to make sure we catch erroneous updates. Otherwise we'll only
|
||||
* see rather obscure HW error happening, as DSS halts. */
|
||||
BUG_ON(x % 2 == 1);
|
||||
|
||||
dsi->framedone_callback = callback;
|
||||
dsi->framedone_data = data;
|
||||
|
||||
dsi->update_region.x = x;
|
||||
dsi->update_region.y = y;
|
||||
dsi->update_region.w = w;
|
||||
dsi->update_region.h = h;
|
||||
dsi->update_region.device = dssdev;
|
||||
dssdev->driver->get_resolution(dssdev, &dw, &dh);
|
||||
|
||||
dsi_update_screen_dispc(dssdev, x, y, w, h);
|
||||
#ifdef DEBUG
|
||||
dsi->update_bytes = dw * dh *
|
||||
dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt) / 8;
|
||||
#endif
|
||||
dsi_update_screen_dispc(dssdev, dw, dh);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -4218,6 +4222,7 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
|
|||
int r;
|
||||
|
||||
if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_CMD_MODE) {
|
||||
u16 dw, dh;
|
||||
u32 irq;
|
||||
struct omap_video_timings timings = {
|
||||
.hsw = 1,
|
||||
|
@ -4228,6 +4233,10 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
|
|||
.vbp = 0,
|
||||
};
|
||||
|
||||
dssdev->driver->get_resolution(dssdev, &dw, &dh);
|
||||
timings.x_res = dw;
|
||||
timings.y_res = dh;
|
||||
|
||||
irq = dssdev->manager->id == OMAP_DSS_CHANNEL_LCD ?
|
||||
DISPC_IRQ_FRAMEDONE : DISPC_IRQ_FRAMEDONE2;
|
||||
|
||||
|
@ -4330,6 +4339,12 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
|
|||
int dsi_module = dsi_get_dsidev_id(dsidev);
|
||||
int r;
|
||||
|
||||
r = dsi_parse_lane_config(dssdev);
|
||||
if (r) {
|
||||
DSSERR("illegal lane config");
|
||||
goto err0;
|
||||
}
|
||||
|
||||
r = dsi_pll_init(dsidev, true, true);
|
||||
if (r)
|
||||
goto err0;
|
||||
|
@ -4521,7 +4536,6 @@ int dsi_init_display(struct omap_dss_device *dssdev)
|
|||
{
|
||||
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
|
||||
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
||||
int dsi_module = dsi_get_dsidev_id(dsidev);
|
||||
|
||||
DSSDBG("DSI init\n");
|
||||
|
||||
|
@ -4543,12 +4557,6 @@ int dsi_init_display(struct omap_dss_device *dssdev)
|
|||
dsi->vdds_dsi_reg = vdds_dsi;
|
||||
}
|
||||
|
||||
if (dsi_get_num_data_lanes_dssdev(dssdev) > dsi->num_data_lanes) {
|
||||
DSSERR("DSI%d can't support more than %d data lanes\n",
|
||||
dsi_module + 1, dsi->num_data_lanes);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -4771,7 +4779,13 @@ static int omap_dsihw_probe(struct platform_device *dsidev)
|
|||
dev_dbg(&dsidev->dev, "OMAP DSI rev %d.%d\n",
|
||||
FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
|
||||
|
||||
dsi->num_data_lanes = dsi_get_num_data_lanes(dsidev);
|
||||
/* DSI on OMAP3 doesn't have register DSI_GNQ, set number
|
||||
* of data to 3 by default */
|
||||
if (dss_has_feature(FEAT_DSI_GNQ))
|
||||
/* NB_DATA_LANES */
|
||||
dsi->num_lanes_supported = 1 + REG_GET(dsidev, DSI_GNQ, 11, 9);
|
||||
else
|
||||
dsi->num_lanes_supported = 3;
|
||||
|
||||
dsi_runtime_put(dsidev);
|
||||
|
||||
|
|
|
@ -163,6 +163,34 @@ struct bus_type *dss_get_bus(void);
|
|||
struct regulator *dss_get_vdds_dsi(void);
|
||||
struct regulator *dss_get_vdds_sdi(void);
|
||||
|
||||
/* apply */
|
||||
void dss_apply_init(void);
|
||||
int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr);
|
||||
int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl);
|
||||
void dss_mgr_start_update(struct omap_overlay_manager *mgr);
|
||||
int omap_dss_mgr_apply(struct omap_overlay_manager *mgr);
|
||||
|
||||
int dss_mgr_enable(struct omap_overlay_manager *mgr);
|
||||
void dss_mgr_disable(struct omap_overlay_manager *mgr);
|
||||
int dss_mgr_set_info(struct omap_overlay_manager *mgr,
|
||||
struct omap_overlay_manager_info *info);
|
||||
void dss_mgr_get_info(struct omap_overlay_manager *mgr,
|
||||
struct omap_overlay_manager_info *info);
|
||||
int dss_mgr_set_device(struct omap_overlay_manager *mgr,
|
||||
struct omap_dss_device *dssdev);
|
||||
int dss_mgr_unset_device(struct omap_overlay_manager *mgr);
|
||||
|
||||
bool dss_ovl_is_enabled(struct omap_overlay *ovl);
|
||||
int dss_ovl_enable(struct omap_overlay *ovl);
|
||||
int dss_ovl_disable(struct omap_overlay *ovl);
|
||||
int dss_ovl_set_info(struct omap_overlay *ovl,
|
||||
struct omap_overlay_info *info);
|
||||
void dss_ovl_get_info(struct omap_overlay *ovl,
|
||||
struct omap_overlay_info *info);
|
||||
int dss_ovl_set_manager(struct omap_overlay *ovl,
|
||||
struct omap_overlay_manager *mgr);
|
||||
int dss_ovl_unset_manager(struct omap_overlay *ovl);
|
||||
|
||||
/* display */
|
||||
int dss_suspend_all_devices(void);
|
||||
int dss_resume_all_devices(void);
|
||||
|
@ -181,21 +209,22 @@ void default_get_overlay_fifo_thresholds(enum omap_plane plane,
|
|||
/* manager */
|
||||
int dss_init_overlay_managers(struct platform_device *pdev);
|
||||
void dss_uninit_overlay_managers(struct platform_device *pdev);
|
||||
int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl);
|
||||
void dss_setup_partial_planes(struct omap_dss_device *dssdev,
|
||||
u16 *x, u16 *y, u16 *w, u16 *h,
|
||||
bool enlarge_update_area);
|
||||
void dss_start_update(struct omap_dss_device *dssdev);
|
||||
int dss_mgr_simple_check(struct omap_overlay_manager *mgr,
|
||||
const struct omap_overlay_manager_info *info);
|
||||
int dss_mgr_check(struct omap_overlay_manager *mgr,
|
||||
struct omap_dss_device *dssdev,
|
||||
struct omap_overlay_manager_info *info,
|
||||
struct omap_overlay_info **overlay_infos);
|
||||
|
||||
/* overlay */
|
||||
void dss_init_overlays(struct platform_device *pdev);
|
||||
void dss_uninit_overlays(struct platform_device *pdev);
|
||||
int dss_check_overlay(struct omap_overlay *ovl, struct omap_dss_device *dssdev);
|
||||
void dss_overlay_setup_dispc_manager(struct omap_overlay_manager *mgr);
|
||||
#ifdef L4_EXAMPLE
|
||||
void dss_overlay_setup_l4_manager(struct omap_overlay_manager *mgr);
|
||||
#endif
|
||||
void dss_recheck_connections(struct omap_dss_device *dssdev, bool force);
|
||||
int dss_ovl_simple_check(struct omap_overlay *ovl,
|
||||
const struct omap_overlay_info *info);
|
||||
int dss_ovl_check(struct omap_overlay *ovl,
|
||||
struct omap_overlay_info *info, struct omap_dss_device *dssdev);
|
||||
|
||||
/* DSS */
|
||||
int dss_init_platform_driver(void);
|
||||
|
@ -399,21 +428,22 @@ int dispc_calc_clock_rates(unsigned long dispc_fclk_rate,
|
|||
struct dispc_clock_info *cinfo);
|
||||
|
||||
|
||||
void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high);
|
||||
u32 dispc_ovl_get_fifo_size(enum omap_plane plane);
|
||||
u32 dispc_ovl_get_burst_size(enum omap_plane plane);
|
||||
int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
|
||||
bool ilace, enum omap_channel channel, bool replication,
|
||||
u32 fifo_low, u32 fifo_high);
|
||||
bool ilace, bool replication);
|
||||
int dispc_ovl_enable(enum omap_plane plane, bool enable);
|
||||
|
||||
void dispc_ovl_set_channel_out(enum omap_plane plane,
|
||||
enum omap_channel channel);
|
||||
|
||||
void dispc_mgr_enable_fifohandcheck(enum omap_channel channel, bool enable);
|
||||
void dispc_mgr_set_lcd_size(enum omap_channel channel, u16 width, u16 height);
|
||||
void dispc_mgr_enable_cpr(enum omap_channel channel, bool enable);
|
||||
void dispc_mgr_set_cpr_coef(enum omap_channel channel,
|
||||
struct omap_dss_cpr_coefs *coefs);
|
||||
u32 dispc_mgr_get_vsync_irq(enum omap_channel channel);
|
||||
u32 dispc_mgr_get_framedone_irq(enum omap_channel channel);
|
||||
bool dispc_mgr_go_busy(enum omap_channel channel);
|
||||
void dispc_mgr_go(enum omap_channel channel);
|
||||
bool dispc_mgr_is_enabled(enum omap_channel channel);
|
||||
void dispc_mgr_enable(enum omap_channel channel, bool enable);
|
||||
bool dispc_mgr_is_channel_enabled(enum omap_channel channel);
|
||||
void dispc_mgr_set_io_pad_mode(enum dss_io_pad_mode mode);
|
||||
|
@ -421,18 +451,6 @@ void dispc_mgr_enable_stallmode(enum omap_channel channel, bool enable);
|
|||
void dispc_mgr_set_tft_data_lines(enum omap_channel channel, u8 data_lines);
|
||||
void dispc_mgr_set_lcd_display_type(enum omap_channel channel,
|
||||
enum omap_lcd_display_type type);
|
||||
void dispc_mgr_set_default_color(enum omap_channel channel, u32 color);
|
||||
u32 dispc_mgr_get_default_color(enum omap_channel channel);
|
||||
void dispc_mgr_set_trans_key(enum omap_channel ch,
|
||||
enum omap_dss_trans_key_type type,
|
||||
u32 trans_key);
|
||||
void dispc_mgr_get_trans_key(enum omap_channel ch,
|
||||
enum omap_dss_trans_key_type *type,
|
||||
u32 *trans_key);
|
||||
void dispc_mgr_enable_trans_key(enum omap_channel ch, bool enable);
|
||||
void dispc_mgr_enable_alpha_fixed_zorder(enum omap_channel ch, bool enable);
|
||||
bool dispc_mgr_trans_key_enabled(enum omap_channel ch);
|
||||
bool dispc_mgr_alpha_fixed_zorder_enabled(enum omap_channel ch);
|
||||
void dispc_mgr_set_lcd_timings(enum omap_channel channel,
|
||||
struct omap_video_timings *timings);
|
||||
void dispc_mgr_set_pol_freq(enum omap_channel channel,
|
||||
|
@ -443,6 +461,8 @@ int dispc_mgr_set_clock_div(enum omap_channel channel,
|
|||
struct dispc_clock_info *cinfo);
|
||||
int dispc_mgr_get_clock_div(enum omap_channel channel,
|
||||
struct dispc_clock_info *cinfo);
|
||||
void dispc_mgr_setup(enum omap_channel channel,
|
||||
struct omap_overlay_manager_info *info);
|
||||
|
||||
/* VENC */
|
||||
#ifdef CONFIG_OMAP2_DSS_VENC
|
||||
|
|
|
@ -304,6 +304,11 @@ static const struct dss_param_range omap2_dss_param_range[] = {
|
|||
[FEAT_PARAM_DSIPLL_FINT] = { 0, 0 },
|
||||
[FEAT_PARAM_DSIPLL_LPDIV] = { 0, 0 },
|
||||
[FEAT_PARAM_DOWNSCALE] = { 1, 2 },
|
||||
/*
|
||||
* Assuming the line width buffer to be 768 pixels as OMAP2 DISPC
|
||||
* scaler cannot scale a image with width more than 768.
|
||||
*/
|
||||
[FEAT_PARAM_LINEWIDTH] = { 1, 768 },
|
||||
};
|
||||
|
||||
static const struct dss_param_range omap3_dss_param_range[] = {
|
||||
|
@ -316,6 +321,7 @@ static const struct dss_param_range omap3_dss_param_range[] = {
|
|||
[FEAT_PARAM_DSIPLL_FINT] = { 750000, 2100000 },
|
||||
[FEAT_PARAM_DSIPLL_LPDIV] = { 1, (1 << 13) - 1},
|
||||
[FEAT_PARAM_DOWNSCALE] = { 1, 4 },
|
||||
[FEAT_PARAM_LINEWIDTH] = { 1, 1024 },
|
||||
};
|
||||
|
||||
static const struct dss_param_range omap4_dss_param_range[] = {
|
||||
|
@ -328,6 +334,7 @@ static const struct dss_param_range omap4_dss_param_range[] = {
|
|||
[FEAT_PARAM_DSIPLL_FINT] = { 500000, 2500000 },
|
||||
[FEAT_PARAM_DSIPLL_LPDIV] = { 0, (1 << 13) - 1 },
|
||||
[FEAT_PARAM_DOWNSCALE] = { 1, 4 },
|
||||
[FEAT_PARAM_LINEWIDTH] = { 1, 2048 },
|
||||
};
|
||||
|
||||
/* OMAP2 DSS Features */
|
||||
|
@ -465,6 +472,10 @@ static const struct ti_hdmi_ip_ops omap4_hdmi_functions = {
|
|||
.dump_core = ti_hdmi_4xxx_core_dump,
|
||||
.dump_pll = ti_hdmi_4xxx_pll_dump,
|
||||
.dump_phy = ti_hdmi_4xxx_phy_dump,
|
||||
#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
|
||||
defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
|
||||
.audio_enable = ti_hdmi_4xxx_wp_audio_enable,
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -86,6 +86,7 @@ enum dss_range_param {
|
|||
FEAT_PARAM_DSIPLL_FINT,
|
||||
FEAT_PARAM_DSIPLL_LPDIV,
|
||||
FEAT_PARAM_DOWNSCALE,
|
||||
FEAT_PARAM_LINEWIDTH,
|
||||
};
|
||||
|
||||
/* DSS Feature Functions */
|
||||
|
|
|
@ -333,7 +333,7 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
|
|||
if (r)
|
||||
return r;
|
||||
|
||||
dispc_mgr_enable(OMAP_DSS_CHANNEL_DIGIT, 0);
|
||||
dss_mgr_disable(dssdev->manager);
|
||||
|
||||
p = &dssdev->panel.timings;
|
||||
|
||||
|
@ -387,9 +387,16 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
|
|||
|
||||
hdmi.ip_data.ops->video_enable(&hdmi.ip_data, 1);
|
||||
|
||||
dispc_mgr_enable(OMAP_DSS_CHANNEL_DIGIT, 1);
|
||||
r = dss_mgr_enable(dssdev->manager);
|
||||
if (r)
|
||||
goto err_mgr_enable;
|
||||
|
||||
return 0;
|
||||
|
||||
err_mgr_enable:
|
||||
hdmi.ip_data.ops->video_enable(&hdmi.ip_data, 0);
|
||||
hdmi.ip_data.ops->phy_disable(&hdmi.ip_data);
|
||||
hdmi.ip_data.ops->pll_disable(&hdmi.ip_data);
|
||||
err:
|
||||
hdmi_runtime_put();
|
||||
return -EIO;
|
||||
|
@ -397,7 +404,7 @@ err:
|
|||
|
||||
static void hdmi_power_off(struct omap_dss_device *dssdev)
|
||||
{
|
||||
dispc_mgr_enable(OMAP_DSS_CHANNEL_DIGIT, 0);
|
||||
dss_mgr_disable(dssdev->manager);
|
||||
|
||||
hdmi.ip_data.ops->video_enable(&hdmi.ip_data, 0);
|
||||
hdmi.ip_data.ops->phy_disable(&hdmi.ip_data);
|
||||
|
@ -554,11 +561,44 @@ void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev)
|
|||
#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
|
||||
defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
|
||||
|
||||
static int hdmi_audio_hw_params(struct hdmi_ip_data *ip_data,
|
||||
struct snd_pcm_substream *substream,
|
||||
static int hdmi_audio_trigger(struct snd_pcm_substream *substream, int cmd,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct snd_soc_codec *codec = rtd->codec;
|
||||
struct platform_device *pdev = to_platform_device(codec->dev);
|
||||
struct hdmi_ip_data *ip_data = snd_soc_codec_get_drvdata(codec);
|
||||
int err = 0;
|
||||
|
||||
if (!(ip_data->ops) && !(ip_data->ops->audio_enable)) {
|
||||
dev_err(&pdev->dev, "Cannot enable/disable audio\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
case SNDRV_PCM_TRIGGER_START:
|
||||
case SNDRV_PCM_TRIGGER_RESUME:
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
|
||||
ip_data->ops->audio_enable(ip_data, true);
|
||||
break;
|
||||
case SNDRV_PCM_TRIGGER_STOP:
|
||||
case SNDRV_PCM_TRIGGER_SUSPEND:
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
|
||||
ip_data->ops->audio_enable(ip_data, false);
|
||||
break;
|
||||
default:
|
||||
err = -EINVAL;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static int hdmi_audio_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct snd_soc_codec *codec = rtd->codec;
|
||||
struct hdmi_ip_data *ip_data = snd_soc_codec_get_drvdata(codec);
|
||||
struct hdmi_audio_format audio_format;
|
||||
struct hdmi_audio_dma audio_dma;
|
||||
struct hdmi_core_audio_config core_cfg;
|
||||
|
@ -698,7 +738,16 @@ static int hdmi_audio_startup(struct snd_pcm_substream *substream,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int hdmi_audio_codec_probe(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct hdmi_ip_data *priv = &hdmi.ip_data;
|
||||
|
||||
snd_soc_codec_set_drvdata(codec, priv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct snd_soc_codec_driver hdmi_audio_codec_drv = {
|
||||
.probe = hdmi_audio_codec_probe,
|
||||
};
|
||||
|
||||
static struct snd_soc_dai_ops hdmi_audio_codec_ops = {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -38,7 +38,7 @@
|
|||
#include "dss_features.h"
|
||||
|
||||
static int num_overlays;
|
||||
static struct list_head overlay_list;
|
||||
static struct omap_overlay *overlays;
|
||||
|
||||
static ssize_t overlay_name_show(struct omap_overlay *ovl, char *buf)
|
||||
{
|
||||
|
@ -124,19 +124,31 @@ err:
|
|||
|
||||
static ssize_t overlay_input_size_show(struct omap_overlay *ovl, char *buf)
|
||||
{
|
||||
struct omap_overlay_info info;
|
||||
|
||||
ovl->get_overlay_info(ovl, &info);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%d,%d\n",
|
||||
ovl->info.width, ovl->info.height);
|
||||
info.width, info.height);
|
||||
}
|
||||
|
||||
static ssize_t overlay_screen_width_show(struct omap_overlay *ovl, char *buf)
|
||||
{
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", ovl->info.screen_width);
|
||||
struct omap_overlay_info info;
|
||||
|
||||
ovl->get_overlay_info(ovl, &info);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", info.screen_width);
|
||||
}
|
||||
|
||||
static ssize_t overlay_position_show(struct omap_overlay *ovl, char *buf)
|
||||
{
|
||||
struct omap_overlay_info info;
|
||||
|
||||
ovl->get_overlay_info(ovl, &info);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%d,%d\n",
|
||||
ovl->info.pos_x, ovl->info.pos_y);
|
||||
info.pos_x, info.pos_y);
|
||||
}
|
||||
|
||||
static ssize_t overlay_position_store(struct omap_overlay *ovl,
|
||||
|
@ -170,8 +182,12 @@ static ssize_t overlay_position_store(struct omap_overlay *ovl,
|
|||
|
||||
static ssize_t overlay_output_size_show(struct omap_overlay *ovl, char *buf)
|
||||
{
|
||||
struct omap_overlay_info info;
|
||||
|
||||
ovl->get_overlay_info(ovl, &info);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%d,%d\n",
|
||||
ovl->info.out_width, ovl->info.out_height);
|
||||
info.out_width, info.out_height);
|
||||
}
|
||||
|
||||
static ssize_t overlay_output_size_store(struct omap_overlay *ovl,
|
||||
|
@ -205,7 +221,7 @@ static ssize_t overlay_output_size_store(struct omap_overlay *ovl,
|
|||
|
||||
static ssize_t overlay_enabled_show(struct omap_overlay *ovl, char *buf)
|
||||
{
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", ovl->info.enabled);
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", ovl->is_enabled(ovl));
|
||||
}
|
||||
|
||||
static ssize_t overlay_enabled_store(struct omap_overlay *ovl, const char *buf,
|
||||
|
@ -213,33 +229,30 @@ static ssize_t overlay_enabled_store(struct omap_overlay *ovl, const char *buf,
|
|||
{
|
||||
int r;
|
||||
bool enable;
|
||||
struct omap_overlay_info info;
|
||||
|
||||
ovl->get_overlay_info(ovl, &info);
|
||||
|
||||
r = strtobool(buf, &enable);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
info.enabled = enable;
|
||||
if (enable)
|
||||
r = ovl->enable(ovl);
|
||||
else
|
||||
r = ovl->disable(ovl);
|
||||
|
||||
r = ovl->set_overlay_info(ovl, &info);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (ovl->manager) {
|
||||
r = ovl->manager->apply(ovl->manager);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static ssize_t overlay_global_alpha_show(struct omap_overlay *ovl, char *buf)
|
||||
{
|
||||
struct omap_overlay_info info;
|
||||
|
||||
ovl->get_overlay_info(ovl, &info);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n",
|
||||
ovl->info.global_alpha);
|
||||
info.global_alpha);
|
||||
}
|
||||
|
||||
static ssize_t overlay_global_alpha_store(struct omap_overlay *ovl,
|
||||
|
@ -276,8 +289,12 @@ static ssize_t overlay_global_alpha_store(struct omap_overlay *ovl,
|
|||
static ssize_t overlay_pre_mult_alpha_show(struct omap_overlay *ovl,
|
||||
char *buf)
|
||||
{
|
||||
struct omap_overlay_info info;
|
||||
|
||||
ovl->get_overlay_info(ovl, &info);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n",
|
||||
ovl->info.pre_mult_alpha);
|
||||
info.pre_mult_alpha);
|
||||
}
|
||||
|
||||
static ssize_t overlay_pre_mult_alpha_store(struct omap_overlay *ovl,
|
||||
|
@ -313,7 +330,11 @@ static ssize_t overlay_pre_mult_alpha_store(struct omap_overlay *ovl,
|
|||
|
||||
static ssize_t overlay_zorder_show(struct omap_overlay *ovl, char *buf)
|
||||
{
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", ovl->info.zorder);
|
||||
struct omap_overlay_info info;
|
||||
|
||||
ovl->get_overlay_info(ovl, &info);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", info.zorder);
|
||||
}
|
||||
|
||||
static ssize_t overlay_zorder_store(struct omap_overlay *ovl,
|
||||
|
@ -430,183 +451,6 @@ static struct kobj_type overlay_ktype = {
|
|||
.default_attrs = overlay_sysfs_attrs,
|
||||
};
|
||||
|
||||
/* Check if overlay parameters are compatible with display */
|
||||
int dss_check_overlay(struct omap_overlay *ovl, struct omap_dss_device *dssdev)
|
||||
{
|
||||
struct omap_overlay_info *info;
|
||||
u16 outw, outh;
|
||||
u16 dw, dh;
|
||||
int i;
|
||||
|
||||
if (!dssdev)
|
||||
return 0;
|
||||
|
||||
if (!ovl->info.enabled)
|
||||
return 0;
|
||||
|
||||
info = &ovl->info;
|
||||
|
||||
if (info->paddr == 0) {
|
||||
DSSDBG("check_overlay failed: paddr 0\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dssdev->driver->get_resolution(dssdev, &dw, &dh);
|
||||
|
||||
DSSDBG("check_overlay %d: (%d,%d %dx%d -> %dx%d) disp (%dx%d)\n",
|
||||
ovl->id,
|
||||
info->pos_x, info->pos_y,
|
||||
info->width, info->height,
|
||||
info->out_width, info->out_height,
|
||||
dw, dh);
|
||||
|
||||
if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0) {
|
||||
outw = info->width;
|
||||
outh = info->height;
|
||||
} else {
|
||||
if (info->out_width == 0)
|
||||
outw = info->width;
|
||||
else
|
||||
outw = info->out_width;
|
||||
|
||||
if (info->out_height == 0)
|
||||
outh = info->height;
|
||||
else
|
||||
outh = info->out_height;
|
||||
}
|
||||
|
||||
if (dw < info->pos_x + outw) {
|
||||
DSSDBG("check_overlay failed 1: %d < %d + %d\n",
|
||||
dw, info->pos_x, outw);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (dh < info->pos_y + outh) {
|
||||
DSSDBG("check_overlay failed 2: %d < %d + %d\n",
|
||||
dh, info->pos_y, outh);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((ovl->supported_modes & info->color_mode) == 0) {
|
||||
DSSERR("overlay doesn't support mode %d\n", info->color_mode);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ovl->caps & OMAP_DSS_OVL_CAP_ZORDER) {
|
||||
if (info->zorder < 0 || info->zorder > 3) {
|
||||
DSSERR("zorder out of range: %d\n",
|
||||
info->zorder);
|
||||
return -EINVAL;
|
||||
}
|
||||
/*
|
||||
* Check that zorder doesn't match with zorder of any other
|
||||
* overlay which is enabled and is also connected to the same
|
||||
* manager
|
||||
*/
|
||||
for (i = 0; i < omap_dss_get_num_overlays(); i++) {
|
||||
struct omap_overlay *tmp_ovl = omap_dss_get_overlay(i);
|
||||
|
||||
if (tmp_ovl->id != ovl->id &&
|
||||
tmp_ovl->manager == ovl->manager &&
|
||||
tmp_ovl->info.enabled == true &&
|
||||
tmp_ovl->info.zorder == info->zorder) {
|
||||
DSSERR("%s and %s have same zorder: %d\n",
|
||||
ovl->name, tmp_ovl->name, info->zorder);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dss_ovl_set_overlay_info(struct omap_overlay *ovl,
|
||||
struct omap_overlay_info *info)
|
||||
{
|
||||
int r;
|
||||
struct omap_overlay_info old_info;
|
||||
|
||||
old_info = ovl->info;
|
||||
ovl->info = *info;
|
||||
|
||||
if (ovl->manager) {
|
||||
r = dss_check_overlay(ovl, ovl->manager->device);
|
||||
if (r) {
|
||||
ovl->info = old_info;
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
ovl->info_dirty = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dss_ovl_get_overlay_info(struct omap_overlay *ovl,
|
||||
struct omap_overlay_info *info)
|
||||
{
|
||||
*info = ovl->info;
|
||||
}
|
||||
|
||||
static int dss_ovl_wait_for_go(struct omap_overlay *ovl)
|
||||
{
|
||||
return dss_mgr_wait_for_go_ovl(ovl);
|
||||
}
|
||||
|
||||
static int omap_dss_set_manager(struct omap_overlay *ovl,
|
||||
struct omap_overlay_manager *mgr)
|
||||
{
|
||||
if (!mgr)
|
||||
return -EINVAL;
|
||||
|
||||
if (ovl->manager) {
|
||||
DSSERR("overlay '%s' already has a manager '%s'\n",
|
||||
ovl->name, ovl->manager->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ovl->info.enabled) {
|
||||
DSSERR("overlay has to be disabled to change the manager\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ovl->manager = mgr;
|
||||
ovl->manager_changed = true;
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap_dss_unset_manager(struct omap_overlay *ovl)
|
||||
{
|
||||
if (!ovl->manager) {
|
||||
DSSERR("failed to detach overlay: manager not set\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ovl->info.enabled) {
|
||||
DSSERR("overlay has to be disabled to unset the manager\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ovl->manager = NULL;
|
||||
ovl->manager_changed = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int omap_dss_get_num_overlays(void)
|
||||
{
|
||||
return num_overlays;
|
||||
|
@ -615,134 +459,65 @@ EXPORT_SYMBOL(omap_dss_get_num_overlays);
|
|||
|
||||
struct omap_overlay *omap_dss_get_overlay(int num)
|
||||
{
|
||||
int i = 0;
|
||||
struct omap_overlay *ovl;
|
||||
if (num >= num_overlays)
|
||||
return NULL;
|
||||
|
||||
list_for_each_entry(ovl, &overlay_list, list) {
|
||||
if (i++ == num)
|
||||
return ovl;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return &overlays[num];
|
||||
}
|
||||
EXPORT_SYMBOL(omap_dss_get_overlay);
|
||||
|
||||
static void omap_dss_add_overlay(struct omap_overlay *overlay)
|
||||
{
|
||||
++num_overlays;
|
||||
list_add_tail(&overlay->list, &overlay_list);
|
||||
}
|
||||
|
||||
static struct omap_overlay *dispc_overlays[MAX_DSS_OVERLAYS];
|
||||
|
||||
void dss_overlay_setup_dispc_manager(struct omap_overlay_manager *mgr)
|
||||
{
|
||||
mgr->num_overlays = dss_feat_get_num_ovls();
|
||||
mgr->overlays = dispc_overlays;
|
||||
}
|
||||
|
||||
#ifdef L4_EXAMPLE
|
||||
static struct omap_overlay *l4_overlays[1];
|
||||
void dss_overlay_setup_l4_manager(struct omap_overlay_manager *mgr)
|
||||
{
|
||||
mgr->num_overlays = 1;
|
||||
mgr->overlays = l4_overlays;
|
||||
}
|
||||
#endif
|
||||
|
||||
void dss_init_overlays(struct platform_device *pdev)
|
||||
{
|
||||
int i, r;
|
||||
|
||||
INIT_LIST_HEAD(&overlay_list);
|
||||
num_overlays = dss_feat_get_num_ovls();
|
||||
|
||||
num_overlays = 0;
|
||||
overlays = kzalloc(sizeof(struct omap_overlay) * num_overlays,
|
||||
GFP_KERNEL);
|
||||
|
||||
for (i = 0; i < dss_feat_get_num_ovls(); ++i) {
|
||||
struct omap_overlay *ovl;
|
||||
ovl = kzalloc(sizeof(*ovl), GFP_KERNEL);
|
||||
BUG_ON(overlays == NULL);
|
||||
|
||||
BUG_ON(ovl == NULL);
|
||||
for (i = 0; i < num_overlays; ++i) {
|
||||
struct omap_overlay *ovl = &overlays[i];
|
||||
|
||||
switch (i) {
|
||||
case 0:
|
||||
ovl->name = "gfx";
|
||||
ovl->id = OMAP_DSS_GFX;
|
||||
ovl->info.global_alpha = 255;
|
||||
ovl->info.zorder = 0;
|
||||
break;
|
||||
case 1:
|
||||
ovl->name = "vid1";
|
||||
ovl->id = OMAP_DSS_VIDEO1;
|
||||
ovl->info.global_alpha = 255;
|
||||
ovl->info.zorder =
|
||||
dss_has_feature(FEAT_ALPHA_FREE_ZORDER) ? 3 : 0;
|
||||
break;
|
||||
case 2:
|
||||
ovl->name = "vid2";
|
||||
ovl->id = OMAP_DSS_VIDEO2;
|
||||
ovl->info.global_alpha = 255;
|
||||
ovl->info.zorder =
|
||||
dss_has_feature(FEAT_ALPHA_FREE_ZORDER) ? 2 : 0;
|
||||
break;
|
||||
case 3:
|
||||
ovl->name = "vid3";
|
||||
ovl->id = OMAP_DSS_VIDEO3;
|
||||
ovl->info.global_alpha = 255;
|
||||
ovl->info.zorder =
|
||||
dss_has_feature(FEAT_ALPHA_FREE_ZORDER) ? 1 : 0;
|
||||
break;
|
||||
}
|
||||
|
||||
ovl->set_manager = &omap_dss_set_manager;
|
||||
ovl->unset_manager = &omap_dss_unset_manager;
|
||||
ovl->set_overlay_info = &dss_ovl_set_overlay_info;
|
||||
ovl->get_overlay_info = &dss_ovl_get_overlay_info;
|
||||
ovl->wait_for_go = &dss_ovl_wait_for_go;
|
||||
ovl->is_enabled = &dss_ovl_is_enabled;
|
||||
ovl->enable = &dss_ovl_enable;
|
||||
ovl->disable = &dss_ovl_disable;
|
||||
ovl->set_manager = &dss_ovl_set_manager;
|
||||
ovl->unset_manager = &dss_ovl_unset_manager;
|
||||
ovl->set_overlay_info = &dss_ovl_set_info;
|
||||
ovl->get_overlay_info = &dss_ovl_get_info;
|
||||
ovl->wait_for_go = &dss_mgr_wait_for_go_ovl;
|
||||
|
||||
ovl->caps = dss_feat_get_overlay_caps(ovl->id);
|
||||
ovl->supported_modes =
|
||||
dss_feat_get_supported_color_modes(ovl->id);
|
||||
|
||||
omap_dss_add_overlay(ovl);
|
||||
|
||||
r = kobject_init_and_add(&ovl->kobj, &overlay_ktype,
|
||||
&pdev->dev.kobj, "overlay%d", i);
|
||||
|
||||
if (r) {
|
||||
DSSERR("failed to create sysfs file\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
dispc_overlays[i] = ovl;
|
||||
}
|
||||
|
||||
#ifdef L4_EXAMPLE
|
||||
{
|
||||
struct omap_overlay *ovl;
|
||||
ovl = kzalloc(sizeof(*ovl), GFP_KERNEL);
|
||||
|
||||
BUG_ON(ovl == NULL);
|
||||
|
||||
ovl->name = "l4";
|
||||
ovl->supported_modes = OMAP_DSS_COLOR_RGB24U;
|
||||
|
||||
ovl->set_manager = &omap_dss_set_manager;
|
||||
ovl->unset_manager = &omap_dss_unset_manager;
|
||||
ovl->set_overlay_info = &dss_ovl_set_overlay_info;
|
||||
ovl->get_overlay_info = &dss_ovl_get_overlay_info;
|
||||
|
||||
omap_dss_add_overlay(ovl);
|
||||
|
||||
r = kobject_init_and_add(&ovl->kobj, &overlay_ktype,
|
||||
&pdev->dev.kobj, "overlayl4");
|
||||
|
||||
if (r)
|
||||
DSSERR("failed to create sysfs file\n");
|
||||
|
||||
l4_overlays[0] = ovl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* connect overlays to the new device, if not already connected. if force
|
||||
|
@ -795,8 +570,8 @@ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
|
|||
ovl = omap_dss_get_overlay(i);
|
||||
if (!ovl->manager || force) {
|
||||
if (ovl->manager)
|
||||
omap_dss_unset_manager(ovl);
|
||||
omap_dss_set_manager(ovl, mgr);
|
||||
ovl->unset_manager(ovl);
|
||||
ovl->set_manager(ovl, mgr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -806,17 +581,95 @@ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
|
|||
|
||||
void dss_uninit_overlays(struct platform_device *pdev)
|
||||
{
|
||||
struct omap_overlay *ovl;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < num_overlays; ++i) {
|
||||
struct omap_overlay *ovl = &overlays[i];
|
||||
|
||||
while (!list_empty(&overlay_list)) {
|
||||
ovl = list_first_entry(&overlay_list,
|
||||
struct omap_overlay, list);
|
||||
list_del(&ovl->list);
|
||||
kobject_del(&ovl->kobj);
|
||||
kobject_put(&ovl->kobj);
|
||||
kfree(ovl);
|
||||
}
|
||||
|
||||
kfree(overlays);
|
||||
overlays = NULL;
|
||||
num_overlays = 0;
|
||||
}
|
||||
|
||||
int dss_ovl_simple_check(struct omap_overlay *ovl,
|
||||
const struct omap_overlay_info *info)
|
||||
{
|
||||
if (info->paddr == 0) {
|
||||
DSSERR("check_overlay: paddr cannot be 0\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0) {
|
||||
if (info->out_width != 0 && info->width != info->out_width) {
|
||||
DSSERR("check_overlay: overlay %d doesn't support "
|
||||
"scaling\n", ovl->id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (info->out_height != 0 && info->height != info->out_height) {
|
||||
DSSERR("check_overlay: overlay %d doesn't support "
|
||||
"scaling\n", ovl->id);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
if ((ovl->supported_modes & info->color_mode) == 0) {
|
||||
DSSERR("check_overlay: overlay %d doesn't support mode %d\n",
|
||||
ovl->id, info->color_mode);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (info->zorder >= omap_dss_get_num_overlays()) {
|
||||
DSSERR("check_overlay: zorder %d too high\n", info->zorder);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dss_ovl_check(struct omap_overlay *ovl,
|
||||
struct omap_overlay_info *info, struct omap_dss_device *dssdev)
|
||||
{
|
||||
u16 outw, outh;
|
||||
u16 dw, dh;
|
||||
|
||||
if (dssdev == NULL)
|
||||
return 0;
|
||||
|
||||
dssdev->driver->get_resolution(dssdev, &dw, &dh);
|
||||
|
||||
if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0) {
|
||||
outw = info->width;
|
||||
outh = info->height;
|
||||
} else {
|
||||
if (info->out_width == 0)
|
||||
outw = info->width;
|
||||
else
|
||||
outw = info->out_width;
|
||||
|
||||
if (info->out_height == 0)
|
||||
outh = info->height;
|
||||
else
|
||||
outh = info->out_height;
|
||||
}
|
||||
|
||||
if (dw < info->pos_x + outw) {
|
||||
DSSERR("overlay %d horizontally not inside the display area "
|
||||
"(%d + %d >= %d)\n",
|
||||
ovl->id, info->pos_x, outw, dw);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (dh < info->pos_y + outh) {
|
||||
DSSERR("overlay %d vertically not inside the display area "
|
||||
"(%d + %d >= %d)\n",
|
||||
ovl->id, info->pos_y, outh, dh);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -784,7 +784,6 @@ int omap_rfbi_prepare_update(struct omap_dss_device *dssdev,
|
|||
if (*w == 0 || *h == 0)
|
||||
return -EINVAL;
|
||||
|
||||
dss_setup_partial_planes(dssdev, x, y, w, h, true);
|
||||
dispc_mgr_set_lcd_size(dssdev->manager->id, *w, *h);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -123,10 +123,14 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
|
|||
goto err_sdi_enable;
|
||||
mdelay(2);
|
||||
|
||||
dssdev->manager->enable(dssdev->manager);
|
||||
r = dss_mgr_enable(dssdev->manager);
|
||||
if (r)
|
||||
goto err_mgr_enable;
|
||||
|
||||
return 0;
|
||||
|
||||
err_mgr_enable:
|
||||
dss_sdi_disable();
|
||||
err_sdi_enable:
|
||||
err_set_dispc_clock_div:
|
||||
err_set_dss_clock_div:
|
||||
|
@ -145,7 +149,7 @@ EXPORT_SYMBOL(omapdss_sdi_display_enable);
|
|||
|
||||
void omapdss_sdi_display_disable(struct omap_dss_device *dssdev)
|
||||
{
|
||||
dssdev->manager->disable(dssdev->manager);
|
||||
dss_mgr_disable(dssdev->manager);
|
||||
|
||||
dss_sdi_disable();
|
||||
|
||||
|
|
|
@ -110,6 +110,11 @@ struct ti_hdmi_ip_ops {
|
|||
|
||||
void (*dump_phy)(struct hdmi_ip_data *ip_data, struct seq_file *s);
|
||||
|
||||
#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
|
||||
defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
|
||||
void (*audio_enable)(struct hdmi_ip_data *ip_data, bool start);
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
struct hdmi_ip_data {
|
||||
|
@ -134,5 +139,8 @@ void ti_hdmi_4xxx_wp_dump(struct hdmi_ip_data *ip_data, struct seq_file *s);
|
|||
void ti_hdmi_4xxx_pll_dump(struct hdmi_ip_data *ip_data, struct seq_file *s);
|
||||
void ti_hdmi_4xxx_core_dump(struct hdmi_ip_data *ip_data, struct seq_file *s);
|
||||
void ti_hdmi_4xxx_phy_dump(struct hdmi_ip_data *ip_data, struct seq_file *s);
|
||||
|
||||
#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
|
||||
defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
|
||||
void ti_hdmi_4xxx_wp_audio_enable(struct hdmi_ip_data *ip_data, bool enable);
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -1204,36 +1204,13 @@ int hdmi_config_audio_acr(struct hdmi_ip_data *ip_data,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int hdmi_audio_trigger(struct hdmi_ip_data *ip_data,
|
||||
struct snd_pcm_substream *substream, int cmd,
|
||||
struct snd_soc_dai *dai)
|
||||
void ti_hdmi_4xxx_wp_audio_enable(struct hdmi_ip_data *ip_data, bool enable)
|
||||
{
|
||||
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_av_base(ip_data),
|
||||
HDMI_CORE_AV_AUD_MODE, 1, 0, 0);
|
||||
REG_FLD_MOD(hdmi_wp_base(ip_data),
|
||||
HDMI_WP_AUDIO_CTRL, 1, 31, 31);
|
||||
REG_FLD_MOD(hdmi_wp_base(ip_data),
|
||||
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_av_base(ip_data),
|
||||
HDMI_CORE_AV_AUD_MODE, 0, 0, 0);
|
||||
REG_FLD_MOD(hdmi_wp_base(ip_data),
|
||||
HDMI_WP_AUDIO_CTRL, 0, 30, 30);
|
||||
REG_FLD_MOD(hdmi_wp_base(ip_data),
|
||||
HDMI_WP_AUDIO_CTRL, 0, 31, 31);
|
||||
break;
|
||||
default:
|
||||
err = -EINVAL;
|
||||
}
|
||||
return err;
|
||||
REG_FLD_MOD(hdmi_av_base(ip_data),
|
||||
HDMI_CORE_AV_AUD_MODE, enable, 0, 0);
|
||||
REG_FLD_MOD(hdmi_wp_base(ip_data),
|
||||
HDMI_WP_AUDIO_CTRL, enable, 31, 31);
|
||||
REG_FLD_MOD(hdmi_wp_base(ip_data),
|
||||
HDMI_WP_AUDIO_CTRL, enable, 30, 30);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -576,9 +576,6 @@ struct hdmi_core_audio_config {
|
|||
|
||||
#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
|
||||
defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
|
||||
int hdmi_audio_trigger(struct hdmi_ip_data *ip_data,
|
||||
struct snd_pcm_substream *substream, int cmd,
|
||||
struct snd_soc_dai *dai);
|
||||
int hdmi_config_audio_acr(struct hdmi_ip_data *ip_data,
|
||||
u32 sample_freq, u32 *n, u32 *cts);
|
||||
void hdmi_core_audio_infoframe_config(struct hdmi_ip_data *ip_data,
|
||||
|
|
|
@ -417,9 +417,10 @@ static const struct venc_config *venc_timings_to_config(
|
|||
BUG();
|
||||
}
|
||||
|
||||
static void venc_power_on(struct omap_dss_device *dssdev)
|
||||
static int venc_power_on(struct omap_dss_device *dssdev)
|
||||
{
|
||||
u32 l;
|
||||
int r;
|
||||
|
||||
venc_reset();
|
||||
venc_write_config(venc_timings_to_config(&dssdev->panel.timings));
|
||||
|
@ -447,7 +448,22 @@ static void venc_power_on(struct omap_dss_device *dssdev)
|
|||
if (dssdev->platform_enable)
|
||||
dssdev->platform_enable(dssdev);
|
||||
|
||||
dssdev->manager->enable(dssdev->manager);
|
||||
r = dss_mgr_enable(dssdev->manager);
|
||||
if (r)
|
||||
goto err;
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
venc_write_reg(VENC_OUTPUT_CONTROL, 0);
|
||||
dss_set_dac_pwrdn_bgz(0);
|
||||
|
||||
if (dssdev->platform_disable)
|
||||
dssdev->platform_disable(dssdev);
|
||||
|
||||
regulator_disable(venc.vdda_dac_reg);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static void venc_power_off(struct omap_dss_device *dssdev)
|
||||
|
@ -455,7 +471,7 @@ static void venc_power_off(struct omap_dss_device *dssdev)
|
|||
venc_write_reg(VENC_OUTPUT_CONTROL, 0);
|
||||
dss_set_dac_pwrdn_bgz(0);
|
||||
|
||||
dssdev->manager->disable(dssdev->manager);
|
||||
dss_mgr_disable(dssdev->manager);
|
||||
|
||||
if (dssdev->platform_disable)
|
||||
dssdev->platform_disable(dssdev);
|
||||
|
@ -504,7 +520,9 @@ static int venc_panel_enable(struct omap_dss_device *dssdev)
|
|||
if (r)
|
||||
goto err1;
|
||||
|
||||
venc_power_on(dssdev);
|
||||
r = venc_power_on(dssdev);
|
||||
if (r)
|
||||
goto err2;
|
||||
|
||||
venc.wss_data = 0;
|
||||
|
||||
|
@ -512,6 +530,8 @@ static int venc_panel_enable(struct omap_dss_device *dssdev)
|
|||
|
||||
mutex_unlock(&venc.venc_lock);
|
||||
return 0;
|
||||
err2:
|
||||
venc_runtime_put();
|
||||
err1:
|
||||
omap_dss_stop_device(dssdev);
|
||||
err0:
|
||||
|
|
|
@ -111,28 +111,22 @@ static int omapfb_setup_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
|
|||
set_fb_fix(fbi);
|
||||
}
|
||||
|
||||
if (pi->enabled) {
|
||||
struct omap_overlay_info info;
|
||||
if (!pi->enabled) {
|
||||
r = ovl->disable(ovl);
|
||||
if (r)
|
||||
goto undo;
|
||||
}
|
||||
|
||||
if (pi->enabled) {
|
||||
r = omapfb_setup_overlay(fbi, ovl, pi->pos_x, pi->pos_y,
|
||||
pi->out_width, pi->out_height);
|
||||
if (r)
|
||||
goto undo;
|
||||
|
||||
ovl->get_overlay_info(ovl, &info);
|
||||
|
||||
if (!info.enabled) {
|
||||
info.enabled = pi->enabled;
|
||||
r = ovl->set_overlay_info(ovl, &info);
|
||||
if (r)
|
||||
goto undo;
|
||||
}
|
||||
} else {
|
||||
struct omap_overlay_info info;
|
||||
|
||||
ovl->get_overlay_info(ovl, &info);
|
||||
|
||||
info.enabled = pi->enabled;
|
||||
info.pos_x = pi->pos_x;
|
||||
info.pos_y = pi->pos_y;
|
||||
info.out_width = pi->out_width;
|
||||
|
@ -146,6 +140,12 @@ static int omapfb_setup_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
|
|||
if (ovl->manager)
|
||||
ovl->manager->apply(ovl->manager);
|
||||
|
||||
if (pi->enabled) {
|
||||
r = ovl->enable(ovl);
|
||||
if (r)
|
||||
goto undo;
|
||||
}
|
||||
|
||||
/* Release the locks in a specific order to keep lockdep happy */
|
||||
if (old_rg->id > new_rg->id) {
|
||||
omapfb_put_mem_region(old_rg);
|
||||
|
@ -189,19 +189,19 @@ static int omapfb_query_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
|
|||
memset(pi, 0, sizeof(*pi));
|
||||
} else {
|
||||
struct omap_overlay *ovl;
|
||||
struct omap_overlay_info *ovli;
|
||||
struct omap_overlay_info ovli;
|
||||
|
||||
ovl = ofbi->overlays[0];
|
||||
ovli = &ovl->info;
|
||||
ovl->get_overlay_info(ovl, &ovli);
|
||||
|
||||
pi->pos_x = ovli->pos_x;
|
||||
pi->pos_y = ovli->pos_y;
|
||||
pi->enabled = ovli->enabled;
|
||||
pi->pos_x = ovli.pos_x;
|
||||
pi->pos_y = ovli.pos_y;
|
||||
pi->enabled = ovl->is_enabled(ovl);
|
||||
pi->channel_out = 0; /* xxx */
|
||||
pi->mirror = 0;
|
||||
pi->mem_idx = get_mem_idx(ofbi);
|
||||
pi->out_width = ovli->out_width;
|
||||
pi->out_height = ovli->out_height;
|
||||
pi->out_width = ovli.out_width;
|
||||
pi->out_height = ovli.out_height;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -238,7 +238,9 @@ static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
|
|||
continue;
|
||||
|
||||
for (j = 0; j < ofbi2->num_overlays; j++) {
|
||||
if (ofbi2->overlays[j]->info.enabled) {
|
||||
struct omap_overlay *ovl;
|
||||
ovl = ofbi2->overlays[j];
|
||||
if (ovl->is_enabled(ovl)) {
|
||||
r = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
|
|
|
@ -970,16 +970,20 @@ int omapfb_apply_changes(struct fb_info *fbi, int init)
|
|||
outh = var->yres;
|
||||
}
|
||||
} else {
|
||||
outw = ovl->info.out_width;
|
||||
outh = ovl->info.out_height;
|
||||
struct omap_overlay_info info;
|
||||
ovl->get_overlay_info(ovl, &info);
|
||||
outw = info.out_width;
|
||||
outh = info.out_height;
|
||||
}
|
||||
|
||||
if (init) {
|
||||
posx = 0;
|
||||
posy = 0;
|
||||
} else {
|
||||
posx = ovl->info.pos_x;
|
||||
posy = ovl->info.pos_y;
|
||||
struct omap_overlay_info info;
|
||||
ovl->get_overlay_info(ovl, &info);
|
||||
posx = info.pos_x;
|
||||
posy = info.pos_y;
|
||||
}
|
||||
|
||||
r = omapfb_setup_overlay(fbi, ovl, posx, posy, outw, outh);
|
||||
|
@ -2067,6 +2071,8 @@ static int omapfb_create_framebuffers(struct omapfb2_device *fbdev)
|
|||
if (ofbi->num_overlays > 0) {
|
||||
struct omap_overlay *ovl = ofbi->overlays[0];
|
||||
|
||||
ovl->manager->apply(ovl->manager);
|
||||
|
||||
r = omapfb_overlay_enable(ovl, 1);
|
||||
|
||||
if (r) {
|
||||
|
|
|
@ -473,7 +473,9 @@ static ssize_t store_size(struct device *dev, struct device_attribute *attr,
|
|||
continue;
|
||||
|
||||
for (j = 0; j < ofbi2->num_overlays; j++) {
|
||||
if (ofbi2->overlays[j]->info.enabled) {
|
||||
struct omap_overlay *ovl;
|
||||
ovl = ofbi2->overlays[j];
|
||||
if (ovl->is_enabled(ovl)) {
|
||||
r = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
|
|
|
@ -181,13 +181,10 @@ static inline void omapfb_unlock(struct omapfb2_device *fbdev)
|
|||
static inline int omapfb_overlay_enable(struct omap_overlay *ovl,
|
||||
int enable)
|
||||
{
|
||||
struct omap_overlay_info info;
|
||||
|
||||
ovl->get_overlay_info(ovl, &info);
|
||||
if (info.enabled == enable)
|
||||
return 0;
|
||||
info.enabled = enable;
|
||||
return ovl->set_overlay_info(ovl, &info);
|
||||
if (enable)
|
||||
return ovl->enable(ovl);
|
||||
else
|
||||
return ovl->disable(ovl);
|
||||
}
|
||||
|
||||
static inline struct omapfb2_mem_region *
|
||||
|
|
|
@ -200,6 +200,10 @@ enum omap_dss_clk_source {
|
|||
OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI, /* OMAP4: PLL2_CLK2 */
|
||||
};
|
||||
|
||||
enum omap_hdmi_flags {
|
||||
OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP = 1 << 0,
|
||||
};
|
||||
|
||||
/* RFBI */
|
||||
|
||||
struct rfbi_timings {
|
||||
|
@ -294,8 +298,8 @@ 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);
|
||||
int dsi_video_mode_enable(struct omap_dss_device *dssdev, int channel);
|
||||
void dsi_video_mode_disable(struct omap_dss_device *dssdev, int channel);
|
||||
int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel);
|
||||
void dsi_disable_video_output(struct omap_dss_device *dssdev, int channel);
|
||||
|
||||
/* Board specific data */
|
||||
struct omap_dss_board_info {
|
||||
|
@ -309,6 +313,8 @@ struct omap_dss_board_info {
|
|||
|
||||
/* Init with the board info */
|
||||
extern int omap_display_init(struct omap_dss_board_info *board_data);
|
||||
/* HDMI mux init*/
|
||||
extern int omap_hdmi_init(enum omap_hdmi_flags flags);
|
||||
|
||||
struct omap_display_platform_data {
|
||||
struct omap_dss_board_info *board_data;
|
||||
|
@ -352,8 +358,6 @@ struct omap_dss_cpr_coefs {
|
|||
};
|
||||
|
||||
struct omap_overlay_info {
|
||||
bool enabled;
|
||||
|
||||
u32 paddr;
|
||||
u32 p_uv_addr; /* for NV12 format */
|
||||
u16 screen_width;
|
||||
|
@ -385,11 +389,21 @@ struct omap_overlay {
|
|||
|
||||
/* dynamic fields */
|
||||
struct omap_overlay_manager *manager;
|
||||
struct omap_overlay_info info;
|
||||
|
||||
bool manager_changed;
|
||||
/* if true, info has been changed, but not applied() yet */
|
||||
bool info_dirty;
|
||||
/*
|
||||
* The following functions do not block:
|
||||
*
|
||||
* is_enabled
|
||||
* set_overlay_info
|
||||
* get_overlay_info
|
||||
*
|
||||
* The rest of the functions may block and cannot be called from
|
||||
* interrupt context
|
||||
*/
|
||||
|
||||
int (*enable)(struct omap_overlay *ovl);
|
||||
int (*disable)(struct omap_overlay *ovl);
|
||||
bool (*is_enabled)(struct omap_overlay *ovl);
|
||||
|
||||
int (*set_manager)(struct omap_overlay *ovl,
|
||||
struct omap_overlay_manager *mgr);
|
||||
|
@ -418,23 +432,27 @@ struct omap_overlay_manager_info {
|
|||
|
||||
struct omap_overlay_manager {
|
||||
struct kobject kobj;
|
||||
struct list_head list;
|
||||
|
||||
/* static fields */
|
||||
const char *name;
|
||||
enum omap_channel id;
|
||||
enum omap_overlay_manager_caps caps;
|
||||
int num_overlays;
|
||||
struct omap_overlay **overlays;
|
||||
struct list_head overlays;
|
||||
enum omap_display_type supported_displays;
|
||||
|
||||
/* dynamic fields */
|
||||
struct omap_dss_device *device;
|
||||
struct omap_overlay_manager_info info;
|
||||
|
||||
bool device_changed;
|
||||
/* if true, info has been changed but not applied() yet */
|
||||
bool info_dirty;
|
||||
/*
|
||||
* The following functions do not block:
|
||||
*
|
||||
* set_manager_info
|
||||
* get_manager_info
|
||||
* apply
|
||||
*
|
||||
* The rest of the functions may block and cannot be called from
|
||||
* interrupt context
|
||||
*/
|
||||
|
||||
int (*set_device)(struct omap_overlay_manager *mgr,
|
||||
struct omap_dss_device *dssdev);
|
||||
|
@ -448,9 +466,6 @@ struct omap_overlay_manager {
|
|||
int (*apply)(struct omap_overlay_manager *mgr);
|
||||
int (*wait_for_go)(struct omap_overlay_manager *mgr);
|
||||
int (*wait_for_vsync)(struct omap_overlay_manager *mgr);
|
||||
|
||||
int (*enable)(struct omap_overlay_manager *mgr);
|
||||
int (*disable)(struct omap_overlay_manager *mgr);
|
||||
};
|
||||
|
||||
struct omap_dss_device {
|
||||
|
@ -662,12 +677,7 @@ 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,
|
||||
u16 *x, u16 *y, u16 *w, u16 *h,
|
||||
bool enlarge_update_area);
|
||||
int omap_dsi_update(struct omap_dss_device *dssdev,
|
||||
int channel,
|
||||
u16 x, u16 y, u16 w, u16 h,
|
||||
int omap_dsi_update(struct omap_dss_device *dssdev, int channel,
|
||||
void (*callback)(int, void *), void *data);
|
||||
int omap_dsi_request_vc(struct omap_dss_device *dssdev, int *channel);
|
||||
int omap_dsi_set_vc_id(struct omap_dss_device *dssdev, int channel, int vc_id);
|
||||
|
|
Loading…
Reference in New Issue