提交 193984f4 编写于 作者: F Florian Tobias Schandinat

Merge branch 'for-florian' of git://gitorious.org/linux-omap-dss2/linux into fbdev-next

......@@ -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;
}
......
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
......
此差异已折叠。
......@@ -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)
{
/* 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;
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)
{
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)
{
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;
}
bool dispc_mgr_trans_key_enabled(enum omap_channel ch)
void dispc_mgr_setup(enum omap_channel channel,
struct omap_overlay_manager_info *info)
{
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;
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);
}
}
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)
{
......
/*
* 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);
......
此差异已折叠。
......@@ -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 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
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 = {
......
此差异已折叠。
......@@ -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 @@ static ssize_t overlay_manager_store(struct omap_overlay *ovl, const char *buf,
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;
}
......
......@@ -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;
}
......
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册