Merge output work from Archit

The series removes bunch of dssdev references from the omapdss output drivers.
This is made to let us move to a common panel framework later, and also allows
us to implement OMAP's writeback support, which has been proven difficult with
the current output drivers.

OMAPDSS: APPLY: Constify timings argument in dss_mgr_set_timings
OMAPDSS: DPI: Add locking for DPI interface
OMAPDSS: Displays: Add locking in generic DPI panel driver
OMAPDSS: DPI: Maintain our own timings field in driver data
OMAPDSS: DPI displays: Take care of panel timings in the driver itself
OMAPDSS: DSI: Maintain own copy of timings in driver data
OMAPDSS: DSI: Add function to set panel size for command mode panels
OMAPDSS: DSI: Update manager timings on a manual update
OMAPDSS: HDMI: Use our own omap_video_timings field when setting interface timings
OMAPDSS: HDMI: Add locking for hdmi interface set timing functions
OMAPDSS: SDI: Create a function to set timings
OMAPDSS: SDI: Maintain our own timings field in driver data
OMAPDSS: VENC: Split VENC into interface and panel driver
OMAPDSS: VENC: Maintain our own timings field in driver data
OMAPDSS: RFBI: Remove partial update support
OMAPDSS: RFBI: Add function to set panel size
OMAPDSS: DSI: Maintain copy of pixel format in driver data
OMAPDSS: RFBI: Maintain copy of pixel size in driver data
OMAPDSS: RFBI: Maintain copy of number of data lines in driver data
OMAPDSS: DPI: Maintain copy of number of data lines in driver data
OMAPDSS: SDI: Maintain copy of data pairs in driver data
OMAPDSS: DSI: Maintain copy of operation mode in driver data
OMAPDSS: DSI: Rename dsi_videomode_data to dsi_videomode_timings
OMAPDSS: DSI: Maintain copy of video mode timings in driver data
OMAPDSS: RFBI: Maitain copy of rfbi timings in driver data
OMAPDSS: VENC: Maintain copy of venc type in driver data
OMAPDSS: VENC: Maintian copy of video output polarity info in private data
This commit is contained in:
Tomi Valkeinen 2012-08-17 15:16:45 +03:00
commit 60548a2b94
23 changed files with 844 additions and 375 deletions

View File

@ -600,6 +600,9 @@ static int acx_panel_power_on(struct omap_dss_device *dssdev)
mutex_lock(&md->mutex);
omapdss_sdi_set_timings(dssdev, &dssdev->panel.timings);
omapdss_sdi_set_datapairs(dssdev, dssdev->phy.sdi.datapairs);
r = omapdss_sdi_display_enable(dssdev);
if (r) {
pr_err("%s sdi enable failed\n", __func__);
@ -731,18 +734,9 @@ static int acx_panel_resume(struct omap_dss_device *dssdev)
static void acx_panel_set_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
{
int r;
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
omapdss_sdi_display_disable(dssdev);
omapdss_sdi_set_timings(dssdev, timings);
dssdev->panel.timings = *timings;
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
r = omapdss_sdi_display_enable(dssdev);
if (r)
dev_err(&dssdev->dev, "%s enable failed\n", __func__);
}
}
static int acx_panel_check_timings(struct omap_dss_device *dssdev,

View File

@ -545,6 +545,8 @@ struct panel_drv_data {
struct omap_dss_device *dssdev;
struct panel_config *panel_config;
struct mutex lock;
};
static inline struct panel_generic_dpi_data
@ -563,6 +565,9 @@ static int generic_dpi_panel_power_on(struct omap_dss_device *dssdev)
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
return 0;
omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
r = omapdss_dpi_display_enable(dssdev);
if (r)
goto err0;
@ -634,6 +639,8 @@ static int generic_dpi_panel_probe(struct omap_dss_device *dssdev)
drv_data->dssdev = dssdev;
drv_data->panel_config = panel_config;
mutex_init(&drv_data->lock);
dev_set_drvdata(&dssdev->dev, drv_data);
return 0;
@ -652,56 +659,108 @@ static void __exit generic_dpi_panel_remove(struct omap_dss_device *dssdev)
static int generic_dpi_panel_enable(struct omap_dss_device *dssdev)
{
int r = 0;
struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
int r;
mutex_lock(&drv_data->lock);
r = generic_dpi_panel_power_on(dssdev);
if (r)
return r;
goto err;
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
err:
mutex_unlock(&drv_data->lock);
return 0;
return r;
}
static void generic_dpi_panel_disable(struct omap_dss_device *dssdev)
{
struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
mutex_lock(&drv_data->lock);
generic_dpi_panel_power_off(dssdev);
dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
mutex_unlock(&drv_data->lock);
}
static int generic_dpi_panel_suspend(struct omap_dss_device *dssdev)
{
struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
mutex_lock(&drv_data->lock);
generic_dpi_panel_power_off(dssdev);
dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
mutex_unlock(&drv_data->lock);
return 0;
}
static int generic_dpi_panel_resume(struct omap_dss_device *dssdev)
{
int r = 0;
struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
int r;
mutex_lock(&drv_data->lock);
r = generic_dpi_panel_power_on(dssdev);
if (r)
return r;
goto err;
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
return 0;
err:
mutex_unlock(&drv_data->lock);
return r;
}
static void generic_dpi_panel_set_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
{
dpi_set_timings(dssdev, timings);
struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
mutex_lock(&drv_data->lock);
omapdss_dpi_set_timings(dssdev, timings);
dssdev->panel.timings = *timings;
mutex_unlock(&drv_data->lock);
}
static void generic_dpi_panel_get_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
{
struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
mutex_lock(&drv_data->lock);
*timings = dssdev->panel.timings;
mutex_unlock(&drv_data->lock);
}
static int generic_dpi_panel_check_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
{
return dpi_check_timings(dssdev, timings);
struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
int r;
mutex_lock(&drv_data->lock);
r = dpi_check_timings(dssdev, timings);
mutex_unlock(&drv_data->lock);
return r;
}
static struct omap_dss_driver dpi_driver = {
@ -714,6 +773,7 @@ static struct omap_dss_driver dpi_driver = {
.resume = generic_dpi_panel_resume,
.set_timings = generic_dpi_panel_set_timings,
.get_timings = generic_dpi_panel_get_timings,
.check_timings = generic_dpi_panel_check_timings,
.driver = {

View File

@ -55,6 +55,9 @@ static int lb035q02_panel_power_on(struct omap_dss_device *dssdev)
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
return 0;
omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
r = omapdss_dpi_display_enable(dssdev);
if (r)
goto err0;

View File

@ -150,11 +150,17 @@ static void blizzard_ctrl_setup_update(struct omap_dss_device *dssdev,
BLIZZARD_SRC_WRITE_LCD :
BLIZZARD_SRC_WRITE_LCD_DESTRUCTIVE;
omap_rfbi_configure(dssdev, 16, 8);
omapdss_rfbi_set_pixel_size(dssdev, 16);
omapdss_rfbi_set_data_lines(dssdev, 8);
omap_rfbi_configure(dssdev);
blizzard_write(BLIZZARD_INPUT_WIN_X_START_0, tmp, 18);
omap_rfbi_configure(dssdev, 16, 16);
omapdss_rfbi_set_pixel_size(dssdev, 16);
omapdss_rfbi_set_data_lines(dssdev, 16);
omap_rfbi_configure(dssdev);
}
static void mipid_transfer(struct spi_device *spi, int cmd, const u8 *wbuf,
@ -297,6 +303,12 @@ static int n8x0_panel_power_on(struct omap_dss_device *dssdev)
goto err_plat_en;
}
omapdss_rfbi_set_size(dssdev, dssdev->panel.timings.x_res,
dssdev->panel.timings.y_res);
omapdss_rfbi_set_pixel_size(dssdev, dssdev->ctrl.pixel_size);
omapdss_rfbi_set_data_lines(dssdev, dssdev->phy.rfbi.data_lines);
omapdss_rfbi_set_interface_timings(dssdev, &dssdev->ctrl.rfbi_timings);
r = omapdss_rfbi_display_enable(dssdev);
if (r)
goto err_rfbi_en;
@ -625,17 +637,25 @@ static int n8x0_panel_update(struct omap_dss_device *dssdev,
u16 x, u16 y, u16 w, u16 h)
{
struct panel_drv_data *ddata = get_drv_data(dssdev);
u16 dw, dh;
dev_dbg(&dssdev->dev, "update\n");
dw = dssdev->panel.timings.x_res;
dh = dssdev->panel.timings.y_res;
if (x != 0 || y != 0 || w != dw || h != dh) {
dev_err(&dssdev->dev, "invaid update region %d, %d, %d, %d\n",
x, y, w, h);
return -EINVAL;
}
mutex_lock(&ddata->lock);
rfbi_bus_lock();
omap_rfbi_prepare_update(dssdev, &x, &y, &w, &h);
blizzard_ctrl_setup_update(dssdev, x, y, w, h);
omap_rfbi_update(dssdev, x, y, w, h, update_done, NULL);
omap_rfbi_update(dssdev, update_done, NULL);
mutex_unlock(&ddata->lock);

View File

@ -175,6 +175,9 @@ static int nec_8048_panel_power_on(struct omap_dss_device *dssdev)
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
return 0;
omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
r = omapdss_dpi_display_enable(dssdev);
if (r)
goto err0;

View File

@ -377,6 +377,10 @@ static int picodlp_panel_power_on(struct omap_dss_device *dssdev)
* then only i2c commands can be successfully sent to dpp2600
*/
msleep(1000);
omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
r = omapdss_dpi_display_enable(dssdev);
if (r) {
dev_err(&dssdev->dev, "failed to enable DPI\n");

View File

@ -142,6 +142,9 @@ static int sharp_ls_power_on(struct omap_dss_device *dssdev)
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
return 0;
omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
r = omapdss_dpi_display_enable(dssdev);
if (r)
goto err0;

View File

@ -1060,6 +1060,11 @@ static int taal_power_on(struct omap_dss_device *dssdev)
goto err0;
};
omapdss_dsi_set_size(dssdev, dssdev->panel.timings.x_res,
dssdev->panel.timings.y_res);
omapdss_dsi_set_pixel_format(dssdev, OMAP_DSS_DSI_FMT_RGB888);
omapdss_dsi_set_operation_mode(dssdev, OMAP_DSS_DSI_CMD_MODE);
r = omapdss_dsi_display_enable(dssdev);
if (r) {
dev_err(&dssdev->dev, "failed to enable DSI\n");
@ -1487,6 +1492,7 @@ static int taal_get_te(struct omap_dss_device *dssdev)
static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate)
{
struct taal_data *td = dev_get_drvdata(&dssdev->dev);
u16 dw, dh;
int r;
dev_dbg(&dssdev->dev, "rotate %d\n", rotate);
@ -1508,6 +1514,16 @@ static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate)
goto err;
}
if (rotate == 0 || rotate == 2) {
dw = dssdev->panel.timings.x_res;
dh = dssdev->panel.timings.y_res;
} else {
dw = dssdev->panel.timings.y_res;
dh = dssdev->panel.timings.x_res;
}
omapdss_dsi_set_size(dssdev, dw, dh);
td->rotate = rotate;
dsi_bus_unlock(dssdev);

View File

@ -65,6 +65,9 @@ static int tfp410_power_on(struct omap_dss_device *dssdev)
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
return 0;
omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
r = omapdss_dpi_display_enable(dssdev);
if (r)
goto err0;
@ -231,7 +234,8 @@ static void tfp410_set_timings(struct omap_dss_device *dssdev,
struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
mutex_lock(&ddata->lock);
dpi_set_timings(dssdev, timings);
omapdss_dpi_set_timings(dssdev, timings);
dssdev->panel.timings = *timings;
mutex_unlock(&ddata->lock);
}

View File

@ -337,6 +337,9 @@ static int tpo_td043_enable_dss(struct omap_dss_device *dssdev)
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
return 0;
omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
r = omapdss_dpi_display_enable(dssdev);
if (r)
goto err0;
@ -480,7 +483,9 @@ static void tpo_td043_remove(struct omap_dss_device *dssdev)
static void tpo_td043_set_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
{
dpi_set_timings(dssdev, timings);
omapdss_dpi_set_timings(dssdev, timings);
dssdev->panel.timings = *timings;
}
static int tpo_td043_check_timings(struct omap_dss_device *dssdev,

View File

@ -3,7 +3,7 @@ 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
omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o venc_panel.o
omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o
omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o
omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi.o \

View File

@ -1302,7 +1302,7 @@ err:
}
static void dss_apply_mgr_timings(struct omap_overlay_manager *mgr,
struct omap_video_timings *timings)
const struct omap_video_timings *timings)
{
struct mgr_priv_data *mp = get_mgr_priv(mgr);
@ -1311,7 +1311,7 @@ static void dss_apply_mgr_timings(struct omap_overlay_manager *mgr,
}
void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
struct omap_video_timings *timings)
const struct omap_video_timings *timings)
{
unsigned long flags;

View File

@ -39,7 +39,11 @@ static struct {
struct regulator *vdds_dsi_reg;
struct platform_device *dsidev;
struct mutex lock;
struct omap_video_timings timings;
struct dss_lcd_mgr_config mgr_config;
int data_lines;
} dpi;
static struct platform_device *dpi_get_dsidev(enum omap_dss_clk_source clk)
@ -121,7 +125,7 @@ static int dpi_set_dispc_clk(struct omap_dss_device *dssdev,
static int dpi_set_mode(struct omap_dss_device *dssdev)
{
struct omap_video_timings *t = &dssdev->panel.timings;
struct omap_video_timings *t = &dpi.timings;
int lck_div = 0, pck_div = 0;
unsigned long fck = 0;
unsigned long pck;
@ -158,7 +162,7 @@ static void dpi_config_lcd_manager(struct omap_dss_device *dssdev)
dpi.mgr_config.stallmode = false;
dpi.mgr_config.fifohandcheck = false;
dpi.mgr_config.video_port_width = dssdev->phy.dpi.data_lines;
dpi.mgr_config.video_port_width = dpi.data_lines;
dpi.mgr_config.lcden_sig_polarity = 0;
@ -169,14 +173,18 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
{
int r;
mutex_lock(&dpi.lock);
if (cpu_is_omap34xx() && !dpi.vdds_dsi_reg) {
DSSERR("no VDSS_DSI regulator\n");
return -ENODEV;
r = -ENODEV;
goto err_no_reg;
}
if (dssdev->manager == NULL) {
DSSERR("failed to enable display: no manager\n");
return -ENODEV;
r = -ENODEV;
goto err_no_mgr;
}
r = omap_dss_start_device(dssdev);
@ -217,6 +225,8 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
if (r)
goto err_mgr_enable;
mutex_unlock(&dpi.lock);
return 0;
err_mgr_enable:
@ -234,12 +244,17 @@ err_get_dispc:
err_reg_enable:
omap_dss_stop_device(dssdev);
err_start_dev:
err_no_mgr:
err_no_reg:
mutex_unlock(&dpi.lock);
return r;
}
EXPORT_SYMBOL(omapdss_dpi_display_enable);
void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
{
mutex_lock(&dpi.lock);
dss_mgr_disable(dssdev->manager);
if (dpi_use_dsi_pll(dssdev)) {
@ -254,16 +269,22 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
regulator_disable(dpi.vdds_dsi_reg);
omap_dss_stop_device(dssdev);
mutex_unlock(&dpi.lock);
}
EXPORT_SYMBOL(omapdss_dpi_display_disable);
void dpi_set_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
void omapdss_dpi_set_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
{
int r;
DSSDBG("dpi_set_timings\n");
dssdev->panel.timings = *timings;
mutex_lock(&dpi.lock);
dpi.timings = *timings;
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
r = dispc_runtime_get();
if (r)
@ -275,8 +296,10 @@ void dpi_set_timings(struct omap_dss_device *dssdev,
} else {
dss_mgr_set_timings(dssdev->manager, timings);
}
mutex_unlock(&dpi.lock);
}
EXPORT_SYMBOL(dpi_set_timings);
EXPORT_SYMBOL(omapdss_dpi_set_timings);
int dpi_check_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
@ -325,6 +348,16 @@ int dpi_check_timings(struct omap_dss_device *dssdev,
}
EXPORT_SYMBOL(dpi_check_timings);
void omapdss_dpi_set_data_lines(struct omap_dss_device *dssdev, int data_lines)
{
mutex_lock(&dpi.lock);
dpi.data_lines = data_lines;
mutex_unlock(&dpi.lock);
}
EXPORT_SYMBOL(omapdss_dpi_set_data_lines);
static int __init dpi_init_display(struct omap_dss_device *dssdev)
{
DSSDBG("init_display\n");
@ -377,6 +410,8 @@ static void __init dpi_probe_pdata(struct platform_device *pdev)
static int __init omap_dpi_probe(struct platform_device *pdev)
{
mutex_init(&dpi.lock);
dpi_probe_pdata(pdev);
return 0;

View File

@ -333,6 +333,10 @@ struct dsi_data {
unsigned scp_clk_refcount;
struct dss_lcd_mgr_config mgr_config;
struct omap_video_timings timings;
enum omap_dss_dsi_pixel_format pix_fmt;
enum omap_dss_dsi_mode mode;
struct omap_dss_dsi_videomode_timings vm_timings;
};
struct dsi_packet_sent_handler_data {
@ -2360,10 +2364,10 @@ static int dsi_cio_init(struct omap_dss_device *dssdev)
dsi_cio_timings(dsidev);
if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) {
if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
/* DDR_CLK_ALWAYS_ON */
REG_FLD_MOD(dsidev, DSI_CLK_CTRL,
dssdev->panel.dsi_vm_data.ddr_clk_always_on, 13, 13);
dsi->vm_timings.ddr_clk_always_on, 13, 13);
}
dsi->ulps_enabled = false;
@ -2685,6 +2689,7 @@ void omapdss_dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel,
bool enable)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
DSSDBG("dsi_vc_enable_hs(%d, %d)\n", channel, enable);
@ -2701,7 +2706,7 @@ void omapdss_dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel,
dsi_force_tx_stop_mode_io(dsidev);
/* start the DDR clock by sending a NULL packet */
if (dssdev->panel.dsi_vm_data.ddr_clk_always_on && enable)
if (dsi->vm_timings.ddr_clk_always_on && enable)
dsi_vc_send_null(dssdev, channel);
}
EXPORT_SYMBOL(omapdss_dsi_vc_enable_hs);
@ -3607,12 +3612,14 @@ static void dsi_set_hs_tx_timeout(struct platform_device *dsidev,
static void dsi_config_vp_num_line_buffers(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 num_line_buffers;
if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) {
int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
int bpp = dsi_get_pixel_size(dsi->pix_fmt);
unsigned line_buf_size = dsi_get_line_buf_size(dsidev);
struct omap_video_timings *timings = &dssdev->panel.timings;
struct omap_video_timings *timings = &dsi->timings;
/*
* Don't use line buffers if width is greater than the video
* port's line buffer size
@ -3633,8 +3640,9 @@ static void dsi_config_vp_num_line_buffers(struct omap_dss_device *dssdev)
static void dsi_config_vp_sync_events(struct omap_dss_device *dssdev)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
bool vsync_end = dssdev->panel.dsi_vm_data.vp_vsync_end;
bool hsync_end = dssdev->panel.dsi_vm_data.vp_hsync_end;
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
bool vsync_end = dsi->vm_timings.vp_vsync_end;
bool hsync_end = dsi->vm_timings.vp_hsync_end;
u32 r;
r = dsi_read_reg(dsidev, DSI_CTRL);
@ -3651,10 +3659,11 @@ static void dsi_config_vp_sync_events(struct omap_dss_device *dssdev)
static void dsi_config_blanking_modes(struct omap_dss_device *dssdev)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
int blanking_mode = dssdev->panel.dsi_vm_data.blanking_mode;
int hfp_blanking_mode = dssdev->panel.dsi_vm_data.hfp_blanking_mode;
int hbp_blanking_mode = dssdev->panel.dsi_vm_data.hbp_blanking_mode;
int hsa_blanking_mode = dssdev->panel.dsi_vm_data.hsa_blanking_mode;
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
int blanking_mode = dsi->vm_timings.blanking_mode;
int hfp_blanking_mode = dsi->vm_timings.hfp_blanking_mode;
int hbp_blanking_mode = dsi->vm_timings.hbp_blanking_mode;
int hsa_blanking_mode = dsi->vm_timings.hsa_blanking_mode;
u32 r;
/*
@ -3741,8 +3750,8 @@ static void dsi_config_cmd_mode_interleaving(struct omap_dss_device *dssdev)
int ddr_clk_pre, ddr_clk_post, enter_hs_mode_lat, exit_hs_mode_lat;
int tclk_trail, ths_exit, exiths_clk;
bool ddr_alwon;
struct omap_video_timings *timings = &dssdev->panel.timings;
int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
struct omap_video_timings *timings = &dsi->timings;
int bpp = dsi_get_pixel_size(dsi->pix_fmt);
int ndl = dsi->num_lanes_used - 1;
int dsi_fclk_hsdiv = dssdev->clocks.dsi.regm_dsi + 1;
int hsa_interleave_hs = 0, hsa_interleave_lp = 0;
@ -3852,6 +3861,7 @@ static void dsi_config_cmd_mode_interleaving(struct omap_dss_device *dssdev)
static int dsi_proto_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);
u32 r;
int buswidth = 0;
@ -3871,7 +3881,7 @@ static int dsi_proto_config(struct omap_dss_device *dssdev)
dsi_set_lp_rx_timeout(dsidev, 0x1fff, true, true);
dsi_set_hs_tx_timeout(dsidev, 0x1fff, true, true);
switch (dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt)) {
switch (dsi_get_pixel_size(dsi->pix_fmt)) {
case 16:
buswidth = 0;
break;
@ -3905,7 +3915,7 @@ static int dsi_proto_config(struct omap_dss_device *dssdev)
dsi_config_vp_num_line_buffers(dssdev);
if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) {
if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
dsi_config_vp_sync_events(dssdev);
dsi_config_blanking_modes(dssdev);
dsi_config_cmd_mode_interleaving(dssdev);
@ -3984,18 +3994,18 @@ static void dsi_proto_timings(struct omap_dss_device *dssdev)
DSSDBG("enter_hs_mode_lat %u, exit_hs_mode_lat %u\n",
enter_hs_mode_lat, exit_hs_mode_lat);
if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) {
if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
/* TODO: Implement a video mode check_timings function */
int hsa = dssdev->panel.dsi_vm_data.hsa;
int hfp = dssdev->panel.dsi_vm_data.hfp;
int hbp = dssdev->panel.dsi_vm_data.hbp;
int vsa = dssdev->panel.dsi_vm_data.vsa;
int vfp = dssdev->panel.dsi_vm_data.vfp;
int vbp = dssdev->panel.dsi_vm_data.vbp;
int window_sync = dssdev->panel.dsi_vm_data.window_sync;
bool hsync_end = dssdev->panel.dsi_vm_data.vp_hsync_end;
struct omap_video_timings *timings = &dssdev->panel.timings;
int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
int hsa = dsi->vm_timings.hsa;
int hfp = dsi->vm_timings.hfp;
int hbp = dsi->vm_timings.hbp;
int vsa = dsi->vm_timings.vsa;
int vfp = dsi->vm_timings.vfp;
int vbp = dsi->vm_timings.vbp;
int window_sync = dsi->vm_timings.window_sync;
bool hsync_end = dsi->vm_timings.vp_hsync_end;
struct omap_video_timings *timings = &dsi->timings;
int bpp = dsi_get_pixel_size(dsi->pix_fmt);
int tl, t_he, width_bytes;
t_he = hsync_end ?
@ -4103,13 +4113,14 @@ EXPORT_SYMBOL(omapdss_dsi_configure_pins);
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);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
int bpp = dsi_get_pixel_size(dsi->pix_fmt);
u8 data_type;
u16 word_count;
int r;
if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) {
switch (dssdev->panel.dsi_pix_fmt) {
if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
switch (dsi->pix_fmt) {
case OMAP_DSS_DSI_FMT_RGB888:
data_type = MIPI_DSI_PACKED_PIXEL_STREAM_24;
break;
@ -4133,7 +4144,7 @@ int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
/* 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(dsi->timings.x_res * bpp, 8);
dsi_vc_write_long_header(dsidev, channel, data_type,
word_count, 0);
@ -4144,7 +4155,7 @@ int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
r = dss_mgr_enable(dssdev->manager);
if (r) {
if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) {
if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
dsi_if_enable(dsidev, false);
dsi_vc_enable(dsidev, channel, false);
}
@ -4159,8 +4170,9 @@ EXPORT_SYMBOL(dsi_enable_video_output);
void dsi_disable_video_output(struct omap_dss_device *dssdev, int channel)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) {
if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
dsi_if_enable(dsidev, false);
dsi_vc_enable(dsidev, channel, false);
@ -4175,8 +4187,7 @@ void dsi_disable_video_output(struct omap_dss_device *dssdev, int channel)
}
EXPORT_SYMBOL(dsi_disable_video_output);
static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
u16 w, u16 h)
static void dsi_update_screen_dispc(struct omap_dss_device *dssdev)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
@ -4190,12 +4201,14 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
int r;
const unsigned channel = dsi->update_channel;
const unsigned line_buf_size = dsi_get_line_buf_size(dsidev);
u16 w = dsi->timings.x_res;
u16 h = dsi->timings.y_res;
DSSDBG("dsi_update_screen_dispc(%dx%d)\n", w, h);
dsi_vc_config_source(dsidev, channel, DSI_VC_SOURCE_VP);
bytespp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt) / 8;
bytespp = dsi_get_pixel_size(dsi->pix_fmt) / 8;
bytespl = w * bytespp;
bytespf = bytespl * h;
@ -4239,6 +4252,8 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
msecs_to_jiffies(250));
BUG_ON(r == 0);
dss_mgr_set_timings(dssdev->manager, &dsi->timings);
dss_mgr_start_update(dssdev->manager);
if (dsi->te_enabled) {
@ -4325,13 +4340,14 @@ int omap_dsi_update(struct omap_dss_device *dssdev, int channel,
dsi->framedone_callback = callback;
dsi->framedone_data = data;
dssdev->driver->get_resolution(dssdev, &dw, &dh);
dw = dsi->timings.x_res;
dh = dsi->timings.y_res;
#ifdef DEBUG
dsi->update_bytes = dw * dh *
dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt) / 8;
dsi_get_pixel_size(dsi->pix_fmt) / 8;
#endif
dsi_update_screen_dispc(dssdev, dw, dh);
dsi_update_screen_dispc(dssdev);
return 0;
}
@ -4367,23 +4383,16 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
struct omap_video_timings timings;
int r;
u32 irq = 0;
if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_CMD_MODE) {
u16 dw, dh;
dssdev->driver->get_resolution(dssdev, &dw, &dh);
timings.x_res = dw;
timings.y_res = dh;
timings.hsw = 1;
timings.hfp = 1;
timings.hbp = 1;
timings.vsw = 1;
timings.vfp = 0;
timings.vbp = 0;
if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) {
dsi->timings.hsw = 1;
dsi->timings.hfp = 1;
dsi->timings.hbp = 1;
dsi->timings.vsw = 1;
dsi->timings.vfp = 0;
dsi->timings.vbp = 0;
irq = dispc_mgr_get_framedone_irq(dssdev->manager->id);
@ -4397,8 +4406,6 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
dsi->mgr_config.stallmode = true;
dsi->mgr_config.fifohandcheck = true;
} else {
timings = dssdev->panel.timings;
dsi->mgr_config.stallmode = false;
dsi->mgr_config.fifohandcheck = false;
}
@ -4407,14 +4414,14 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
* override interlace, logic level and edge related parameters in
* omap_video_timings with default values
*/
timings.interlace = false;
timings.hsync_level = OMAPDSS_SIG_ACTIVE_HIGH;
timings.vsync_level = OMAPDSS_SIG_ACTIVE_HIGH;
timings.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
timings.de_level = OMAPDSS_SIG_ACTIVE_HIGH;
timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES;
dsi->timings.interlace = false;
dsi->timings.hsync_level = OMAPDSS_SIG_ACTIVE_HIGH;
dsi->timings.vsync_level = OMAPDSS_SIG_ACTIVE_HIGH;
dsi->timings.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
dsi->timings.de_level = OMAPDSS_SIG_ACTIVE_HIGH;
dsi->timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES;
dss_mgr_set_timings(dssdev->manager, &timings);
dss_mgr_set_timings(dssdev->manager, &dsi->timings);
r = dsi_configure_dispc_clocks(dssdev);
if (r)
@ -4422,14 +4429,14 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
dsi->mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS;
dsi->mgr_config.video_port_width =
dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
dsi_get_pixel_size(dsi->pix_fmt);
dsi->mgr_config.lcden_sig_polarity = 0;
dss_mgr_set_lcd_config(dssdev->manager, &dsi->mgr_config);
return 0;
err1:
if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_CMD_MODE)
if (dsi->mode == OMAP_DSS_DSI_CMD_MODE)
omap_dispc_unregister_isr(dsi_framedone_irq_callback,
(void *) dssdev, irq);
err:
@ -4438,7 +4445,10 @@ err:
static void dsi_display_uninit_dispc(struct omap_dss_device *dssdev)
{
if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_CMD_MODE) {
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) {
u32 irq;
irq = dispc_mgr_get_framedone_irq(dssdev->manager->id);
@ -4653,6 +4663,76 @@ int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable)
}
EXPORT_SYMBOL(omapdss_dsi_enable_te);
void omapdss_dsi_set_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
mutex_lock(&dsi->lock);
dsi->timings = *timings;
mutex_unlock(&dsi->lock);
}
EXPORT_SYMBOL(omapdss_dsi_set_timings);
void omapdss_dsi_set_size(struct omap_dss_device *dssdev, u16 w, u16 h)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
mutex_lock(&dsi->lock);
dsi->timings.x_res = w;
dsi->timings.y_res = h;
mutex_unlock(&dsi->lock);
}
EXPORT_SYMBOL(omapdss_dsi_set_size);
void omapdss_dsi_set_pixel_format(struct omap_dss_device *dssdev,
enum omap_dss_dsi_pixel_format fmt)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
mutex_lock(&dsi->lock);
dsi->pix_fmt = fmt;
mutex_unlock(&dsi->lock);
}
EXPORT_SYMBOL(omapdss_dsi_set_pixel_format);
void omapdss_dsi_set_operation_mode(struct omap_dss_device *dssdev,
enum omap_dss_dsi_mode mode)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
mutex_lock(&dsi->lock);
dsi->mode = mode;
mutex_unlock(&dsi->lock);
}
EXPORT_SYMBOL(omapdss_dsi_set_operation_mode);
void omapdss_dsi_set_videomode_timings(struct omap_dss_device *dssdev,
struct omap_dss_dsi_videomode_timings *timings)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
mutex_lock(&dsi->lock);
dsi->vm_timings = *timings;
mutex_unlock(&dsi->lock);
}
EXPORT_SYMBOL(omapdss_dsi_set_videomode_timings);
static int __init dsi_init_display(struct omap_dss_device *dssdev)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
@ -4660,7 +4740,7 @@ static int __init dsi_init_display(struct omap_dss_device *dssdev)
DSSDBG("DSI init\n");
if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_CMD_MODE) {
if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) {
dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE |
OMAP_DSS_DISPLAY_CAP_TEAR_ELIM;
}

View File

@ -144,7 +144,7 @@ static void dss_restore_context(void)
#undef SR
#undef RR
void dss_sdi_init(u8 datapairs)
void dss_sdi_init(int datapairs)
{
u32 l;

View File

@ -206,7 +206,7 @@ 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);
void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
struct omap_video_timings *timings);
const struct omap_video_timings *timings);
void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr,
const struct dss_lcd_mgr_config *config);
const struct omap_video_timings *dss_mgr_get_timings(struct omap_overlay_manager *mgr);
@ -279,7 +279,7 @@ void dss_dump_clocks(struct seq_file *s);
void dss_debug_dump_clocks(struct seq_file *s);
#endif
void dss_sdi_init(u8 datapairs);
void dss_sdi_init(int datapairs);
int dss_sdi_enable(void);
void dss_sdi_disable(void);
@ -469,6 +469,20 @@ static inline unsigned long venc_get_pixel_clock(void)
return 0;
}
#endif
int omapdss_venc_display_enable(struct omap_dss_device *dssdev);
void omapdss_venc_display_disable(struct omap_dss_device *dssdev);
void omapdss_venc_set_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings);
int omapdss_venc_check_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings);
u32 omapdss_venc_get_wss(struct omap_dss_device *dssdev);
int omapdss_venc_set_wss(struct omap_dss_device *dssdev, u32 wss);
void omapdss_venc_set_type(struct omap_dss_device *dssdev,
enum omap_dss_venc_type type);
void omapdss_venc_invert_vid_out_polarity(struct omap_dss_device *dssdev,
bool invert_polarity);
int venc_panel_init(void);
void venc_panel_exit(void);
/* HDMI */
#ifdef CONFIG_OMAP4_DSS_HDMI
@ -484,7 +498,8 @@ static inline unsigned long hdmi_get_pixel_clock(void)
#endif
int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev);
void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev);
void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev);
void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev,
struct omap_video_timings *timings);
int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
struct omap_video_timings *timings);
int omapdss_hdmi_read_edid(u8 *buf, int len);

View File

@ -459,7 +459,6 @@ static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy,
static int hdmi_power_on(struct omap_dss_device *dssdev)
{
int r;
const struct hdmi_config *timing;
struct omap_video_timings *p;
unsigned long phy;
@ -469,22 +468,10 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
dss_mgr_disable(dssdev->manager);
p = &dssdev->panel.timings;
p = &hdmi.ip_data.cfg.timings;
DSSDBG("hdmi_power_on x_res= %d y_res = %d\n",
dssdev->panel.timings.x_res,
dssdev->panel.timings.y_res);
DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res);
timing = hdmi_get_timings();
if (timing == NULL) {
/* HDMI code 4 corresponds to 640 * 480 VGA */
hdmi.ip_data.cfg.cm.code = 4;
/* DVI mode 1 corresponds to HDMI 0 to DVI */
hdmi.ip_data.cfg.cm.mode = HDMI_DVI;
hdmi.ip_data.cfg = vesa_timings[0];
} else {
hdmi.ip_data.cfg = *timing;
}
phy = p->pixel_clock;
hdmi_compute_pll(dssdev, phy, &hdmi.ip_data.pll_data);
@ -521,7 +508,7 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
dispc_enable_gamma_table(0);
/* tv size */
dss_mgr_set_timings(dssdev->manager, &dssdev->panel.timings);
dss_mgr_set_timings(dssdev->manager, p);
r = hdmi.ip_data.ops->video_enable(&hdmi.ip_data);
if (r)
@ -568,13 +555,20 @@ int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
}
void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev)
void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
{
struct hdmi_cm cm;
const struct hdmi_config *t;
cm = hdmi_get_code(&dssdev->panel.timings);
hdmi.ip_data.cfg.cm.code = cm.code;
hdmi.ip_data.cfg.cm.mode = cm.mode;
mutex_lock(&hdmi.lock);
cm = hdmi_get_code(timings);
hdmi.ip_data.cfg.cm = cm;
t = hdmi_get_timings();
if (t != NULL)
hdmi.ip_data.cfg = *t;
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
int r;
@ -585,8 +579,10 @@ void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev)
if (r)
DSSERR("failed to power on device\n");
} else {
dss_mgr_set_timings(dssdev->manager, &dssdev->panel.timings);
dss_mgr_set_timings(dssdev->manager, &t->timings);
}
mutex_unlock(&hdmi.lock);
}
static void hdmi_dump_regs(struct seq_file *s)
@ -930,6 +926,7 @@ static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
hdmi.ip_data.core_av_offset = HDMI_CORE_AV;
hdmi.ip_data.pll_offset = HDMI_PLLCTRL;
hdmi.ip_data.phy_offset = HDMI_PHY;
mutex_init(&hdmi.ip_data.lock);
hdmi_panel_init();

View File

@ -41,17 +41,32 @@ static struct {
static int hdmi_panel_probe(struct omap_dss_device *dssdev)
{
/* Initialize default timings to VGA in DVI mode */
const struct omap_video_timings default_timings = {
.x_res = 640,
.y_res = 480,
.pixel_clock = 25175,
.hsw = 96,
.hfp = 16,
.hbp = 48,
.vsw = 2,
.vfp = 11,
.vbp = 31,
.vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
.hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
.interlace = false,
};
DSSDBG("ENTER hdmi_panel_probe\n");
dssdev->panel.timings = (struct omap_video_timings)
{ 640, 480, 25175, 96, 16, 48, 2, 11, 31,
OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
false,
};
dssdev->panel.timings = default_timings;
DSSDBG("hdmi_panel_probe x_res= %d y_res = %d\n",
dssdev->panel.timings.x_res,
dssdev->panel.timings.y_res);
return 0;
}
@ -228,6 +243,8 @@ static int hdmi_panel_enable(struct omap_dss_device *dssdev)
goto err;
}
omapdss_hdmi_display_set_timing(dssdev, &dssdev->panel.timings);
r = omapdss_hdmi_display_enable(dssdev);
if (r) {
DSSERR("failed to power on\n");
@ -336,8 +353,8 @@ static void hdmi_set_timings(struct omap_dss_device *dssdev,
*/
hdmi_panel_audio_disable(dssdev);
omapdss_hdmi_display_set_timing(dssdev, timings);
dssdev->panel.timings = *timings;
omapdss_hdmi_display_set_timing(dssdev);
mutex_unlock(&hdmi.lock);
}

View File

@ -111,6 +111,11 @@ static struct {
struct omap_dss_device *dssdev[2];
struct semaphore bus_lock;
struct omap_video_timings timings;
int pixel_size;
int data_lines;
struct rfbi_timings intf_timings;
} rfbi;
static inline void rfbi_write_reg(const struct rfbi_reg idx, u32 val)
@ -300,28 +305,20 @@ void omap_rfbi_write_pixels(const void __iomem *buf, int scr_width,
}
EXPORT_SYMBOL(omap_rfbi_write_pixels);
static int rfbi_transfer_area(struct omap_dss_device *dssdev, u16 width,
u16 height, void (*callback)(void *data), void *data)
static int rfbi_transfer_area(struct omap_dss_device *dssdev,
void (*callback)(void *data), void *data)
{
u32 l;
int r;
struct omap_video_timings timings = {
.hsw = 1,
.hfp = 1,
.hbp = 1,
.vsw = 1,
.vfp = 0,
.vbp = 0,
.x_res = width,
.y_res = height,
};
u16 width = rfbi.timings.x_res;
u16 height = rfbi.timings.y_res;
/*BUG_ON(callback == 0);*/
BUG_ON(rfbi.framedone_callback != NULL);
DSSDBG("rfbi_transfer_area %dx%d\n", width, height);
dss_mgr_set_timings(dssdev->manager, &timings);
dss_mgr_set_timings(dssdev->manager, &rfbi.timings);
r = dss_mgr_enable(dssdev->manager);
if (r)
@ -770,63 +767,46 @@ static int rfbi_configure(int rfbi_module, int bpp, int lines)
return 0;
}
int omap_rfbi_configure(struct omap_dss_device *dssdev, int pixel_size,
int data_lines)
int omap_rfbi_configure(struct omap_dss_device *dssdev)
{
return rfbi_configure(dssdev->phy.rfbi.channel, pixel_size, data_lines);
return rfbi_configure(dssdev->phy.rfbi.channel, rfbi.pixel_size,
rfbi.data_lines);
}
EXPORT_SYMBOL(omap_rfbi_configure);
int omap_rfbi_prepare_update(struct omap_dss_device *dssdev,
u16 *x, u16 *y, u16 *w, u16 *h)
int omap_rfbi_update(struct omap_dss_device *dssdev, void (*callback)(void *),
void *data)
{
u16 dw, dh;
struct omap_video_timings timings = {
.hsw = 1,
.hfp = 1,
.hbp = 1,
.vsw = 1,
.vfp = 0,
.vbp = 0,
.x_res = *w,
.y_res = *h,
};
dssdev->driver->get_resolution(dssdev, &dw, &dh);
if (*x > dw || *y > dh)
return -EINVAL;
if (*x + *w > dw)
return -EINVAL;
if (*y + *h > dh)
return -EINVAL;
if (*w == 1)
return -EINVAL;
if (*w == 0 || *h == 0)
return -EINVAL;
dss_mgr_set_timings(dssdev->manager, &timings);
return 0;
}
EXPORT_SYMBOL(omap_rfbi_prepare_update);
int omap_rfbi_update(struct omap_dss_device *dssdev,
u16 x, u16 y, u16 w, u16 h,
void (*callback)(void *), void *data)
{
int r;
r = rfbi_transfer_area(dssdev, w, h, callback, data);
return r;
return rfbi_transfer_area(dssdev, callback, data);
}
EXPORT_SYMBOL(omap_rfbi_update);
void omapdss_rfbi_set_size(struct omap_dss_device *dssdev, u16 w, u16 h)
{
rfbi.timings.x_res = w;
rfbi.timings.y_res = h;
}
EXPORT_SYMBOL(omapdss_rfbi_set_size);
void omapdss_rfbi_set_pixel_size(struct omap_dss_device *dssdev, int pixel_size)
{
rfbi.pixel_size = pixel_size;
}
EXPORT_SYMBOL(omapdss_rfbi_set_pixel_size);
void omapdss_rfbi_set_data_lines(struct omap_dss_device *dssdev, int data_lines)
{
rfbi.data_lines = data_lines;
}
EXPORT_SYMBOL(omapdss_rfbi_set_data_lines);
void omapdss_rfbi_set_interface_timings(struct omap_dss_device *dssdev,
struct rfbi_timings *timings)
{
rfbi.intf_timings = *timings;
}
EXPORT_SYMBOL(omapdss_rfbi_set_interface_timings);
static void rfbi_dump_regs(struct seq_file *s)
{
#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, rfbi_read_reg(r))
@ -877,10 +857,31 @@ static void rfbi_config_lcd_manager(struct omap_dss_device *dssdev)
/* Do we need fifohandcheck for RFBI? */
mgr_config.fifohandcheck = false;
mgr_config.video_port_width = dssdev->ctrl.pixel_size;
mgr_config.video_port_width = rfbi.pixel_size;
mgr_config.lcden_sig_polarity = 0;
dss_mgr_set_lcd_config(dssdev->manager, &mgr_config);
/*
* Set rfbi.timings with default values, the x_res and y_res fields
* are expected to be already configured by the panel driver via
* omapdss_rfbi_set_size()
*/
rfbi.timings.hsw = 1;
rfbi.timings.hfp = 1;
rfbi.timings.hbp = 1;
rfbi.timings.vsw = 1;
rfbi.timings.vfp = 0;
rfbi.timings.vbp = 0;
rfbi.timings.interlace = false;
rfbi.timings.hsync_level = OMAPDSS_SIG_ACTIVE_HIGH;
rfbi.timings.vsync_level = OMAPDSS_SIG_ACTIVE_HIGH;
rfbi.timings.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
rfbi.timings.de_level = OMAPDSS_SIG_ACTIVE_HIGH;
rfbi.timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES;
dss_mgr_set_timings(dssdev->manager, &rfbi.timings);
}
int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
@ -911,13 +912,10 @@ int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
rfbi_config_lcd_manager(dssdev);
rfbi_configure(dssdev->phy.rfbi.channel,
dssdev->ctrl.pixel_size,
dssdev->phy.rfbi.data_lines);
rfbi_set_timings(dssdev->phy.rfbi.channel,
&dssdev->ctrl.rfbi_timings);
rfbi_configure(dssdev->phy.rfbi.channel, rfbi.pixel_size,
rfbi.data_lines);
rfbi_set_timings(dssdev->phy.rfbi.channel, &rfbi.intf_timings);
return 0;
err1:

View File

@ -34,6 +34,8 @@ static struct {
struct regulator *vdds_sdi_reg;
struct dss_lcd_mgr_config mgr_config;
struct omap_video_timings timings;
int datapairs;
} sdi;
static void sdi_config_lcd_manager(struct omap_dss_device *dssdev)
@ -51,7 +53,7 @@ static void sdi_config_lcd_manager(struct omap_dss_device *dssdev)
int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
{
struct omap_video_timings *t = &dssdev->panel.timings;
struct omap_video_timings *t = &sdi.timings;
struct dss_clock_info dss_cinfo;
struct dispc_clock_info dispc_cinfo;
unsigned long pck;
@ -77,8 +79,8 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
goto err_get_dispc;
/* 15.5.9.1.2 */
dssdev->panel.timings.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
dssdev->panel.timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
t->data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
t->sync_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
r = dss_calc_clock_div(t->pixel_clock * 1000, &dss_cinfo, &dispc_cinfo);
if (r)
@ -105,7 +107,8 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
sdi_config_lcd_manager(dssdev);
dss_sdi_init(dssdev->phy.sdi.datapairs);
dss_sdi_init(sdi.datapairs);
r = dss_sdi_enable();
if (r)
goto err_sdi_enable;
@ -146,6 +149,29 @@ void omapdss_sdi_display_disable(struct omap_dss_device *dssdev)
}
EXPORT_SYMBOL(omapdss_sdi_display_disable);
void omapdss_sdi_set_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
{
int r;
sdi.timings = *timings;
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
omapdss_sdi_display_disable(dssdev);
r = omapdss_sdi_display_enable(dssdev);
if (r)
DSSERR("failed to set new timings\n");
}
}
EXPORT_SYMBOL(omapdss_sdi_set_timings);
void omapdss_sdi_set_datapairs(struct omap_dss_device *dssdev, int datapairs)
{
sdi.datapairs = datapairs;
}
EXPORT_SYMBOL(omapdss_sdi_set_datapairs);
static int __init sdi_init_display(struct omap_dss_device *dssdev)
{
DSSDBG("SDI init\n");

View File

@ -300,6 +300,10 @@ static struct {
struct regulator *vdda_dac_reg;
struct clk *tv_dac_clk;
struct omap_video_timings timings;
enum omap_dss_venc_type type;
bool invert_polarity;
} venc;
static inline void venc_write_reg(int idx, u32 val)
@ -427,48 +431,48 @@ 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));
r = venc_runtime_get();
if (r)
goto err0;
dss_set_venc_output(dssdev->phy.venc.type);
venc_reset();
venc_write_config(venc_timings_to_config(&venc.timings));
dss_set_venc_output(venc.type);
dss_set_dac_pwrdn_bgz(1);
l = 0;
if (dssdev->phy.venc.type == OMAP_DSS_VENC_TYPE_COMPOSITE)
if (venc.type == OMAP_DSS_VENC_TYPE_COMPOSITE)
l |= 1 << 1;
else /* S-Video */
l |= (1 << 0) | (1 << 2);
if (dssdev->phy.venc.invert_polarity == false)
if (venc.invert_polarity == false)
l |= 1 << 3;
venc_write_reg(VENC_OUTPUT_CONTROL, l);
dss_mgr_set_timings(dssdev->manager, &dssdev->panel.timings);
dss_mgr_set_timings(dssdev->manager, &venc.timings);
r = regulator_enable(venc.vdda_dac_reg);
if (r)
goto err;
if (dssdev->platform_enable)
dssdev->platform_enable(dssdev);
goto err1;
r = dss_mgr_enable(dssdev->manager);
if (r)
goto err;
goto err2;
return 0;
err:
err2:
regulator_disable(venc.vdda_dac_reg);
err1:
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);
venc_runtime_put();
err0:
return r;
}
@ -479,10 +483,9 @@ static void venc_power_off(struct omap_dss_device *dssdev)
dss_mgr_disable(dssdev->manager);
if (dssdev->platform_disable)
dssdev->platform_disable(dssdev);
regulator_disable(venc.vdda_dac_reg);
venc_runtime_put();
}
unsigned long venc_get_pixel_clock(void)
@ -491,171 +494,95 @@ unsigned long venc_get_pixel_clock(void)
return 13500000;
}
static ssize_t display_output_type_show(struct device *dev,
struct device_attribute *attr, char *buf)
int omapdss_venc_display_enable(struct omap_dss_device *dssdev)
{
struct omap_dss_device *dssdev = to_dss_device(dev);
const char *ret;
int r;
switch (dssdev->phy.venc.type) {
case OMAP_DSS_VENC_TYPE_COMPOSITE:
ret = "composite";
break;
case OMAP_DSS_VENC_TYPE_SVIDEO:
ret = "svideo";
break;
default:
return -EINVAL;
}
return snprintf(buf, PAGE_SIZE, "%s\n", ret);
}
static ssize_t display_output_type_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size)
{
struct omap_dss_device *dssdev = to_dss_device(dev);
enum omap_dss_venc_type new_type;
if (sysfs_streq("composite", buf))
new_type = OMAP_DSS_VENC_TYPE_COMPOSITE;
else if (sysfs_streq("svideo", buf))
new_type = OMAP_DSS_VENC_TYPE_SVIDEO;
else
return -EINVAL;
DSSDBG("venc_display_enable\n");
mutex_lock(&venc.venc_lock);
if (dssdev->phy.venc.type != new_type) {
dssdev->phy.venc.type = new_type;
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
venc_power_off(dssdev);
venc_power_on(dssdev);
}
if (dssdev->manager == NULL) {
DSSERR("Failed to enable display: no manager\n");
r = -ENODEV;
goto err0;
}
mutex_unlock(&venc.venc_lock);
return size;
}
static DEVICE_ATTR(output_type, S_IRUGO | S_IWUSR,
display_output_type_show, display_output_type_store);
/* driver */
static int venc_panel_probe(struct omap_dss_device *dssdev)
{
dssdev->panel.timings = omap_dss_pal_timings;
return device_create_file(&dssdev->dev, &dev_attr_output_type);
}
static void venc_panel_remove(struct omap_dss_device *dssdev)
{
device_remove_file(&dssdev->dev, &dev_attr_output_type);
}
static int venc_panel_enable(struct omap_dss_device *dssdev)
{
int r = 0;
DSSDBG("venc_enable_display\n");
mutex_lock(&venc.venc_lock);
r = omap_dss_start_device(dssdev);
if (r) {
DSSERR("failed to start device\n");
goto err0;
}
if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
r = -EINVAL;
goto err1;
}
if (dssdev->platform_enable)
dssdev->platform_enable(dssdev);
r = venc_runtime_get();
if (r)
goto err1;
r = venc_power_on(dssdev);
if (r)
goto err2;
goto err1;
venc.wss_data = 0;
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
mutex_unlock(&venc.venc_lock);
return 0;
err2:
venc_runtime_put();
err1:
if (dssdev->platform_disable)
dssdev->platform_disable(dssdev);
omap_dss_stop_device(dssdev);
err0:
mutex_unlock(&venc.venc_lock);
return r;
}
static void venc_panel_disable(struct omap_dss_device *dssdev)
void omapdss_venc_display_disable(struct omap_dss_device *dssdev)
{
DSSDBG("venc_disable_display\n");
DSSDBG("venc_display_disable\n");
mutex_lock(&venc.venc_lock);
if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED)
goto end;
if (dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED) {
/* suspended is the same as disabled with venc */
dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
goto end;
}
venc_power_off(dssdev);
venc_runtime_put();
dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
omap_dss_stop_device(dssdev);
end:
if (dssdev->platform_disable)
dssdev->platform_disable(dssdev);
mutex_unlock(&venc.venc_lock);
}
static int venc_panel_suspend(struct omap_dss_device *dssdev)
{
venc_panel_disable(dssdev);
return 0;
}
static int venc_panel_resume(struct omap_dss_device *dssdev)
{
return venc_panel_enable(dssdev);
}
static void venc_set_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
void omapdss_venc_set_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
{
DSSDBG("venc_set_timings\n");
mutex_lock(&venc.venc_lock);
/* Reset WSS data when the TV standard changes. */
if (memcmp(&dssdev->panel.timings, timings, sizeof(*timings)))
if (memcmp(&venc.timings, timings, sizeof(*timings)))
venc.wss_data = 0;
dssdev->panel.timings = *timings;
venc.timings = *timings;
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
int r;
/* turn the venc off and on to get new timings to use */
venc_panel_disable(dssdev);
venc_panel_enable(dssdev);
venc_power_off(dssdev);
r = venc_power_on(dssdev);
if (r)
DSSERR("failed to power on VENC\n");
} else {
dss_mgr_set_timings(dssdev->manager, timings);
}
mutex_unlock(&venc.venc_lock);
}
static int venc_check_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
int omapdss_venc_check_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
{
DSSDBG("venc_check_timings\n");
@ -668,13 +595,13 @@ static int venc_check_timings(struct omap_dss_device *dssdev,
return -EINVAL;
}
static u32 venc_get_wss(struct omap_dss_device *dssdev)
u32 omapdss_venc_get_wss(struct omap_dss_device *dssdev)
{
/* Invert due to VENC_L21_WC_CTL:INV=1 */
return (venc.wss_data >> 8) ^ 0xfffff;
}
static int venc_set_wss(struct omap_dss_device *dssdev, u32 wss)
int omapdss_venc_set_wss(struct omap_dss_device *dssdev, u32 wss)
{
const struct venc_config *config;
int r;
@ -683,7 +610,7 @@ static int venc_set_wss(struct omap_dss_device *dssdev, u32 wss)
mutex_lock(&venc.venc_lock);
config = venc_timings_to_config(&dssdev->panel.timings);
config = venc_timings_to_config(&venc.timings);
/* Invert due to VENC_L21_WC_CTL:INV=1 */
venc.wss_data = (wss ^ 0xfffff) << 8;
@ -703,30 +630,25 @@ err:
return r;
}
static struct omap_dss_driver venc_driver = {
.probe = venc_panel_probe,
.remove = venc_panel_remove,
void omapdss_venc_set_type(struct omap_dss_device *dssdev,
enum omap_dss_venc_type type)
{
mutex_lock(&venc.venc_lock);
.enable = venc_panel_enable,
.disable = venc_panel_disable,
.suspend = venc_panel_suspend,
.resume = venc_panel_resume,
venc.type = type;
.get_resolution = omapdss_default_get_resolution,
.get_recommended_bpp = omapdss_default_get_recommended_bpp,
mutex_unlock(&venc.venc_lock);
}
.set_timings = venc_set_timings,
.check_timings = venc_check_timings,
void omapdss_venc_invert_vid_out_polarity(struct omap_dss_device *dssdev,
bool invert_polarity)
{
mutex_lock(&venc.venc_lock);
.get_wss = venc_get_wss,
.set_wss = venc_set_wss,
venc.invert_polarity = invert_polarity;
.driver = {
.name = "venc",
.owner = THIS_MODULE,
},
};
/* driver end */
mutex_unlock(&venc.venc_lock);
}
static int __init venc_init_display(struct omap_dss_device *dssdev)
{
@ -897,9 +819,9 @@ static int __init omap_venchw_probe(struct platform_device *pdev)
venc_runtime_put();
r = omap_dss_register_driver(&venc_driver);
r = venc_panel_init();
if (r)
goto err_reg_panel_driver;
goto err_panel_init;
dss_debugfs_create_file("venc", venc_dump_regs);
@ -907,7 +829,7 @@ static int __init omap_venchw_probe(struct platform_device *pdev)
return 0;
err_reg_panel_driver:
err_panel_init:
err_runtime_get:
pm_runtime_disable(&pdev->dev);
venc_put_clocks();
@ -923,7 +845,7 @@ static int __exit omap_venchw_remove(struct platform_device *pdev)
venc.vdda_dac_reg = NULL;
}
omap_dss_unregister_driver(&venc_driver);
venc_panel_exit();
pm_runtime_disable(&pdev->dev);
venc_put_clocks();

View File

@ -0,0 +1,251 @@
/*
* Copyright (C) 2009 Nokia Corporation
* Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
*
* VENC panel driver
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/kernel.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/mutex.h>
#include <linux/module.h>
#include <video/omapdss.h>
#include "dss.h"
static struct {
struct mutex lock;
} venc_panel;
static ssize_t display_output_type_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct omap_dss_device *dssdev = to_dss_device(dev);
const char *ret;
switch (dssdev->phy.venc.type) {
case OMAP_DSS_VENC_TYPE_COMPOSITE:
ret = "composite";
break;
case OMAP_DSS_VENC_TYPE_SVIDEO:
ret = "svideo";
break;
default:
return -EINVAL;
}
return snprintf(buf, PAGE_SIZE, "%s\n", ret);
}
static ssize_t display_output_type_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size)
{
struct omap_dss_device *dssdev = to_dss_device(dev);
enum omap_dss_venc_type new_type;
if (sysfs_streq("composite", buf))
new_type = OMAP_DSS_VENC_TYPE_COMPOSITE;
else if (sysfs_streq("svideo", buf))
new_type = OMAP_DSS_VENC_TYPE_SVIDEO;
else
return -EINVAL;
mutex_lock(&venc_panel.lock);
if (dssdev->phy.venc.type != new_type) {
dssdev->phy.venc.type = new_type;
omapdss_venc_set_type(dssdev, new_type);
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
omapdss_venc_display_disable(dssdev);
omapdss_venc_display_enable(dssdev);
}
}
mutex_unlock(&venc_panel.lock);
return size;
}
static DEVICE_ATTR(output_type, S_IRUGO | S_IWUSR,
display_output_type_show, display_output_type_store);
static int venc_panel_probe(struct omap_dss_device *dssdev)
{
/* set default timings to PAL */
const struct omap_video_timings default_timings = {
.x_res = 720,
.y_res = 574,
.pixel_clock = 13500,
.hsw = 64,
.hfp = 12,
.hbp = 68,
.vsw = 5,
.vfp = 5,
.vbp = 41,
.vsync_level = OMAPDSS_SIG_ACTIVE_HIGH,
.hsync_level = OMAPDSS_SIG_ACTIVE_HIGH,
.interlace = true,
};
mutex_init(&venc_panel.lock);
dssdev->panel.timings = default_timings;
return device_create_file(&dssdev->dev, &dev_attr_output_type);
}
static void venc_panel_remove(struct omap_dss_device *dssdev)
{
device_remove_file(&dssdev->dev, &dev_attr_output_type);
}
static int venc_panel_enable(struct omap_dss_device *dssdev)
{
int r;
dev_dbg(&dssdev->dev, "venc_panel_enable\n");
mutex_lock(&venc_panel.lock);
if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
r = -EINVAL;
goto err;
}
omapdss_venc_set_timings(dssdev, &dssdev->panel.timings);
omapdss_venc_set_type(dssdev, dssdev->phy.venc.type);
omapdss_venc_invert_vid_out_polarity(dssdev,
dssdev->phy.venc.invert_polarity);
r = omapdss_venc_display_enable(dssdev);
if (r)
goto err;
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
mutex_unlock(&venc_panel.lock);
return 0;
err:
mutex_unlock(&venc_panel.lock);
return r;
}
static void venc_panel_disable(struct omap_dss_device *dssdev)
{
dev_dbg(&dssdev->dev, "venc_panel_disable\n");
mutex_lock(&venc_panel.lock);
if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED)
goto end;
if (dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED) {
/* suspended is the same as disabled with venc */
dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
goto end;
}
omapdss_venc_display_disable(dssdev);
dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
end:
mutex_unlock(&venc_panel.lock);
}
static int venc_panel_suspend(struct omap_dss_device *dssdev)
{
venc_panel_disable(dssdev);
return 0;
}
static int venc_panel_resume(struct omap_dss_device *dssdev)
{
return venc_panel_enable(dssdev);
}
static void venc_panel_set_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
{
dev_dbg(&dssdev->dev, "venc_panel_set_timings\n");
mutex_lock(&venc_panel.lock);
omapdss_venc_set_timings(dssdev, timings);
dssdev->panel.timings = *timings;
mutex_unlock(&venc_panel.lock);
}
static int venc_panel_check_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
{
dev_dbg(&dssdev->dev, "venc_panel_check_timings\n");
return omapdss_venc_check_timings(dssdev, timings);
}
static u32 venc_panel_get_wss(struct omap_dss_device *dssdev)
{
dev_dbg(&dssdev->dev, "venc_panel_get_wss\n");
return omapdss_venc_get_wss(dssdev);
}
static int venc_panel_set_wss(struct omap_dss_device *dssdev, u32 wss)
{
dev_dbg(&dssdev->dev, "venc_panel_set_wss\n");
return omapdss_venc_set_wss(dssdev, wss);
}
static struct omap_dss_driver venc_driver = {
.probe = venc_panel_probe,
.remove = venc_panel_remove,
.enable = venc_panel_enable,
.disable = venc_panel_disable,
.suspend = venc_panel_suspend,
.resume = venc_panel_resume,
.get_resolution = omapdss_default_get_resolution,
.get_recommended_bpp = omapdss_default_get_recommended_bpp,
.set_timings = venc_panel_set_timings,
.check_timings = venc_panel_check_timings,
.get_wss = venc_panel_get_wss,
.set_wss = venc_panel_set_wss,
.driver = {
.name = "venc",
.owner = THIS_MODULE,
},
};
int venc_panel_init(void)
{
return omap_dss_register_driver(&venc_driver);
}
void venc_panel_exit(void)
{
omap_dss_unregister_driver(&venc_driver);
}

View File

@ -243,7 +243,7 @@ void rfbi_bus_unlock(void);
/* DSI */
struct omap_dss_dsi_videomode_data {
struct omap_dss_dsi_videomode_timings {
/* DSI video mode blanking data */
/* Unit: byte clock cycles */
u16 hsa;
@ -564,7 +564,7 @@ struct omap_dss_device {
enum omap_dss_dsi_pixel_format dsi_pix_fmt;
enum omap_dss_dsi_mode dsi_mode;
struct omap_dss_dsi_videomode_data dsi_vm_data;
struct omap_dss_dsi_videomode_timings dsi_vm_timings;
} panel;
struct {
@ -719,6 +719,15 @@ int omap_dispc_wait_for_irq_interruptible_timeout(u32 irqmask,
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);
void omapdss_dsi_set_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings);
void omapdss_dsi_set_size(struct omap_dss_device *dssdev, u16 w, u16 h);
void omapdss_dsi_set_pixel_format(struct omap_dss_device *dssdev,
enum omap_dss_dsi_pixel_format fmt);
void omapdss_dsi_set_operation_mode(struct omap_dss_device *dssdev,
enum omap_dss_dsi_mode mode);
void omapdss_dsi_set_videomode_timings(struct omap_dss_device *dssdev,
struct omap_dss_dsi_videomode_timings *timings);
int omap_dsi_update(struct omap_dss_device *dssdev, int channel,
void (*callback)(int, void *), void *data);
@ -734,22 +743,29 @@ void omapdss_dsi_display_disable(struct omap_dss_device *dssdev,
int omapdss_dpi_display_enable(struct omap_dss_device *dssdev);
void omapdss_dpi_display_disable(struct omap_dss_device *dssdev);
void dpi_set_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings);
void omapdss_dpi_set_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings);
int dpi_check_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings);
void omapdss_dpi_set_data_lines(struct omap_dss_device *dssdev, int data_lines);
int omapdss_sdi_display_enable(struct omap_dss_device *dssdev);
void omapdss_sdi_display_disable(struct omap_dss_device *dssdev);
void omapdss_sdi_set_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings);
void omapdss_sdi_set_datapairs(struct omap_dss_device *dssdev, int datapairs);
int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev);
void omapdss_rfbi_display_disable(struct omap_dss_device *dssdev);
int omap_rfbi_prepare_update(struct omap_dss_device *dssdev,
u16 *x, u16 *y, u16 *w, u16 *h);
int omap_rfbi_update(struct omap_dss_device *dssdev,
u16 x, u16 y, u16 w, u16 h,
void (*callback)(void *), void *data);
int omap_rfbi_configure(struct omap_dss_device *dssdev, int pixel_size,
int omap_rfbi_update(struct omap_dss_device *dssdev, void (*callback)(void *),
void *data);
int omap_rfbi_configure(struct omap_dss_device *dssdev);
void omapdss_rfbi_set_size(struct omap_dss_device *dssdev, u16 w, u16 h);
void omapdss_rfbi_set_pixel_size(struct omap_dss_device *dssdev,
int pixel_size);
void omapdss_rfbi_set_data_lines(struct omap_dss_device *dssdev,
int data_lines);
void omapdss_rfbi_set_interface_timings(struct omap_dss_device *dssdev,
struct rfbi_timings *timings);
#endif