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:
@@ -600,6 +600,9 @@ static int acx_panel_power_on(struct omap_dss_device *dssdev)
|
|||||||
|
|
||||||
mutex_lock(&md->mutex);
|
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);
|
r = omapdss_sdi_display_enable(dssdev);
|
||||||
if (r) {
|
if (r) {
|
||||||
pr_err("%s sdi enable failed\n", __func__);
|
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,
|
static void acx_panel_set_timings(struct omap_dss_device *dssdev,
|
||||||
struct omap_video_timings *timings)
|
struct omap_video_timings *timings)
|
||||||
{
|
{
|
||||||
int r;
|
omapdss_sdi_set_timings(dssdev, timings);
|
||||||
|
|
||||||
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
|
|
||||||
omapdss_sdi_display_disable(dssdev);
|
|
||||||
|
|
||||||
dssdev->panel.timings = *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,
|
static int acx_panel_check_timings(struct omap_dss_device *dssdev,
|
||||||
|
|||||||
@@ -545,6 +545,8 @@ struct panel_drv_data {
|
|||||||
struct omap_dss_device *dssdev;
|
struct omap_dss_device *dssdev;
|
||||||
|
|
||||||
struct panel_config *panel_config;
|
struct panel_config *panel_config;
|
||||||
|
|
||||||
|
struct mutex lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline struct panel_generic_dpi_data
|
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)
|
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
|
||||||
return 0;
|
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);
|
r = omapdss_dpi_display_enable(dssdev);
|
||||||
if (r)
|
if (r)
|
||||||
goto err0;
|
goto err0;
|
||||||
@@ -634,6 +639,8 @@ static int generic_dpi_panel_probe(struct omap_dss_device *dssdev)
|
|||||||
drv_data->dssdev = dssdev;
|
drv_data->dssdev = dssdev;
|
||||||
drv_data->panel_config = panel_config;
|
drv_data->panel_config = panel_config;
|
||||||
|
|
||||||
|
mutex_init(&drv_data->lock);
|
||||||
|
|
||||||
dev_set_drvdata(&dssdev->dev, drv_data);
|
dev_set_drvdata(&dssdev->dev, drv_data);
|
||||||
|
|
||||||
return 0;
|
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)
|
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);
|
r = generic_dpi_panel_power_on(dssdev);
|
||||||
if (r)
|
if (r)
|
||||||
return r;
|
goto err;
|
||||||
|
|
||||||
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
|
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)
|
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);
|
generic_dpi_panel_power_off(dssdev);
|
||||||
|
|
||||||
dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
|
dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
|
||||||
|
|
||||||
|
mutex_unlock(&drv_data->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int generic_dpi_panel_suspend(struct omap_dss_device *dssdev)
|
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);
|
generic_dpi_panel_power_off(dssdev);
|
||||||
|
|
||||||
dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
|
dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
|
||||||
|
|
||||||
|
mutex_unlock(&drv_data->lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int generic_dpi_panel_resume(struct omap_dss_device *dssdev)
|
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);
|
r = generic_dpi_panel_power_on(dssdev);
|
||||||
if (r)
|
if (r)
|
||||||
return r;
|
goto err;
|
||||||
|
|
||||||
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
|
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,
|
static void generic_dpi_panel_set_timings(struct omap_dss_device *dssdev,
|
||||||
struct omap_video_timings *timings)
|
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,
|
static int generic_dpi_panel_check_timings(struct omap_dss_device *dssdev,
|
||||||
struct omap_video_timings *timings)
|
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 = {
|
static struct omap_dss_driver dpi_driver = {
|
||||||
@@ -714,6 +773,7 @@ static struct omap_dss_driver dpi_driver = {
|
|||||||
.resume = generic_dpi_panel_resume,
|
.resume = generic_dpi_panel_resume,
|
||||||
|
|
||||||
.set_timings = generic_dpi_panel_set_timings,
|
.set_timings = generic_dpi_panel_set_timings,
|
||||||
|
.get_timings = generic_dpi_panel_get_timings,
|
||||||
.check_timings = generic_dpi_panel_check_timings,
|
.check_timings = generic_dpi_panel_check_timings,
|
||||||
|
|
||||||
.driver = {
|
.driver = {
|
||||||
|
|||||||
@@ -55,6 +55,9 @@ static int lb035q02_panel_power_on(struct omap_dss_device *dssdev)
|
|||||||
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
|
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
|
||||||
return 0;
|
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);
|
r = omapdss_dpi_display_enable(dssdev);
|
||||||
if (r)
|
if (r)
|
||||||
goto err0;
|
goto err0;
|
||||||
|
|||||||
@@ -150,11 +150,17 @@ static void blizzard_ctrl_setup_update(struct omap_dss_device *dssdev,
|
|||||||
BLIZZARD_SRC_WRITE_LCD :
|
BLIZZARD_SRC_WRITE_LCD :
|
||||||
BLIZZARD_SRC_WRITE_LCD_DESTRUCTIVE;
|
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);
|
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,
|
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;
|
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);
|
r = omapdss_rfbi_display_enable(dssdev);
|
||||||
if (r)
|
if (r)
|
||||||
goto err_rfbi_en;
|
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)
|
u16 x, u16 y, u16 w, u16 h)
|
||||||
{
|
{
|
||||||
struct panel_drv_data *ddata = get_drv_data(dssdev);
|
struct panel_drv_data *ddata = get_drv_data(dssdev);
|
||||||
|
u16 dw, dh;
|
||||||
|
|
||||||
dev_dbg(&dssdev->dev, "update\n");
|
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);
|
mutex_lock(&ddata->lock);
|
||||||
rfbi_bus_lock();
|
rfbi_bus_lock();
|
||||||
|
|
||||||
omap_rfbi_prepare_update(dssdev, &x, &y, &w, &h);
|
|
||||||
|
|
||||||
blizzard_ctrl_setup_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);
|
mutex_unlock(&ddata->lock);
|
||||||
|
|
||||||
|
|||||||
@@ -175,6 +175,9 @@ static int nec_8048_panel_power_on(struct omap_dss_device *dssdev)
|
|||||||
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
|
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
|
||||||
return 0;
|
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);
|
r = omapdss_dpi_display_enable(dssdev);
|
||||||
if (r)
|
if (r)
|
||||||
goto err0;
|
goto err0;
|
||||||
|
|||||||
@@ -377,6 +377,10 @@ static int picodlp_panel_power_on(struct omap_dss_device *dssdev)
|
|||||||
* then only i2c commands can be successfully sent to dpp2600
|
* then only i2c commands can be successfully sent to dpp2600
|
||||||
*/
|
*/
|
||||||
msleep(1000);
|
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);
|
r = omapdss_dpi_display_enable(dssdev);
|
||||||
if (r) {
|
if (r) {
|
||||||
dev_err(&dssdev->dev, "failed to enable DPI\n");
|
dev_err(&dssdev->dev, "failed to enable DPI\n");
|
||||||
|
|||||||
@@ -142,6 +142,9 @@ static int sharp_ls_power_on(struct omap_dss_device *dssdev)
|
|||||||
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
|
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
|
||||||
return 0;
|
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);
|
r = omapdss_dpi_display_enable(dssdev);
|
||||||
if (r)
|
if (r)
|
||||||
goto err0;
|
goto err0;
|
||||||
|
|||||||
@@ -1060,6 +1060,11 @@ static int taal_power_on(struct omap_dss_device *dssdev)
|
|||||||
goto err0;
|
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);
|
r = omapdss_dsi_display_enable(dssdev);
|
||||||
if (r) {
|
if (r) {
|
||||||
dev_err(&dssdev->dev, "failed to enable DSI\n");
|
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)
|
static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate)
|
||||||
{
|
{
|
||||||
struct taal_data *td = dev_get_drvdata(&dssdev->dev);
|
struct taal_data *td = dev_get_drvdata(&dssdev->dev);
|
||||||
|
u16 dw, dh;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
dev_dbg(&dssdev->dev, "rotate %d\n", rotate);
|
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;
|
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;
|
td->rotate = rotate;
|
||||||
|
|
||||||
dsi_bus_unlock(dssdev);
|
dsi_bus_unlock(dssdev);
|
||||||
|
|||||||
@@ -65,6 +65,9 @@ static int tfp410_power_on(struct omap_dss_device *dssdev)
|
|||||||
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
|
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
|
||||||
return 0;
|
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);
|
r = omapdss_dpi_display_enable(dssdev);
|
||||||
if (r)
|
if (r)
|
||||||
goto err0;
|
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);
|
struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
|
||||||
|
|
||||||
mutex_lock(&ddata->lock);
|
mutex_lock(&ddata->lock);
|
||||||
dpi_set_timings(dssdev, timings);
|
omapdss_dpi_set_timings(dssdev, timings);
|
||||||
|
dssdev->panel.timings = *timings;
|
||||||
mutex_unlock(&ddata->lock);
|
mutex_unlock(&ddata->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -337,6 +337,9 @@ static int tpo_td043_enable_dss(struct omap_dss_device *dssdev)
|
|||||||
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
|
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
|
||||||
return 0;
|
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);
|
r = omapdss_dpi_display_enable(dssdev);
|
||||||
if (r)
|
if (r)
|
||||||
goto err0;
|
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,
|
static void tpo_td043_set_timings(struct omap_dss_device *dssdev,
|
||||||
struct omap_video_timings *timings)
|
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,
|
static int tpo_td043_check_timings(struct omap_dss_device *dssdev,
|
||||||
|
|||||||
@@ -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
|
manager.o overlay.o apply.o
|
||||||
omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o
|
omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o
|
||||||
omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.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_SDI) += sdi.o
|
||||||
omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o
|
omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o
|
||||||
omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi.o \
|
omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi.o \
|
||||||
|
|||||||
@@ -1302,7 +1302,7 @@ err:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void dss_apply_mgr_timings(struct omap_overlay_manager *mgr,
|
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);
|
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,
|
void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
|
||||||
struct omap_video_timings *timings)
|
const struct omap_video_timings *timings)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,11 @@ static struct {
|
|||||||
struct regulator *vdds_dsi_reg;
|
struct regulator *vdds_dsi_reg;
|
||||||
struct platform_device *dsidev;
|
struct platform_device *dsidev;
|
||||||
|
|
||||||
|
struct mutex lock;
|
||||||
|
|
||||||
|
struct omap_video_timings timings;
|
||||||
struct dss_lcd_mgr_config mgr_config;
|
struct dss_lcd_mgr_config mgr_config;
|
||||||
|
int data_lines;
|
||||||
} dpi;
|
} dpi;
|
||||||
|
|
||||||
static struct platform_device *dpi_get_dsidev(enum omap_dss_clk_source clk)
|
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)
|
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;
|
int lck_div = 0, pck_div = 0;
|
||||||
unsigned long fck = 0;
|
unsigned long fck = 0;
|
||||||
unsigned long pck;
|
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.stallmode = false;
|
||||||
dpi.mgr_config.fifohandcheck = 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;
|
dpi.mgr_config.lcden_sig_polarity = 0;
|
||||||
|
|
||||||
@@ -169,14 +173,18 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
|
|||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
mutex_lock(&dpi.lock);
|
||||||
|
|
||||||
if (cpu_is_omap34xx() && !dpi.vdds_dsi_reg) {
|
if (cpu_is_omap34xx() && !dpi.vdds_dsi_reg) {
|
||||||
DSSERR("no VDSS_DSI regulator\n");
|
DSSERR("no VDSS_DSI regulator\n");
|
||||||
return -ENODEV;
|
r = -ENODEV;
|
||||||
|
goto err_no_reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dssdev->manager == NULL) {
|
if (dssdev->manager == NULL) {
|
||||||
DSSERR("failed to enable display: no manager\n");
|
DSSERR("failed to enable display: no manager\n");
|
||||||
return -ENODEV;
|
r = -ENODEV;
|
||||||
|
goto err_no_mgr;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = omap_dss_start_device(dssdev);
|
r = omap_dss_start_device(dssdev);
|
||||||
@@ -217,6 +225,8 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
|
|||||||
if (r)
|
if (r)
|
||||||
goto err_mgr_enable;
|
goto err_mgr_enable;
|
||||||
|
|
||||||
|
mutex_unlock(&dpi.lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_mgr_enable:
|
err_mgr_enable:
|
||||||
@@ -234,12 +244,17 @@ err_get_dispc:
|
|||||||
err_reg_enable:
|
err_reg_enable:
|
||||||
omap_dss_stop_device(dssdev);
|
omap_dss_stop_device(dssdev);
|
||||||
err_start_dev:
|
err_start_dev:
|
||||||
|
err_no_mgr:
|
||||||
|
err_no_reg:
|
||||||
|
mutex_unlock(&dpi.lock);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(omapdss_dpi_display_enable);
|
EXPORT_SYMBOL(omapdss_dpi_display_enable);
|
||||||
|
|
||||||
void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
|
void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
|
||||||
{
|
{
|
||||||
|
mutex_lock(&dpi.lock);
|
||||||
|
|
||||||
dss_mgr_disable(dssdev->manager);
|
dss_mgr_disable(dssdev->manager);
|
||||||
|
|
||||||
if (dpi_use_dsi_pll(dssdev)) {
|
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);
|
regulator_disable(dpi.vdds_dsi_reg);
|
||||||
|
|
||||||
omap_dss_stop_device(dssdev);
|
omap_dss_stop_device(dssdev);
|
||||||
|
|
||||||
|
mutex_unlock(&dpi.lock);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(omapdss_dpi_display_disable);
|
EXPORT_SYMBOL(omapdss_dpi_display_disable);
|
||||||
|
|
||||||
void dpi_set_timings(struct omap_dss_device *dssdev,
|
void omapdss_dpi_set_timings(struct omap_dss_device *dssdev,
|
||||||
struct omap_video_timings *timings)
|
struct omap_video_timings *timings)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
DSSDBG("dpi_set_timings\n");
|
DSSDBG("dpi_set_timings\n");
|
||||||
dssdev->panel.timings = *timings;
|
|
||||||
|
mutex_lock(&dpi.lock);
|
||||||
|
|
||||||
|
dpi.timings = *timings;
|
||||||
|
|
||||||
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
|
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
|
||||||
r = dispc_runtime_get();
|
r = dispc_runtime_get();
|
||||||
if (r)
|
if (r)
|
||||||
@@ -275,8 +296,10 @@ void dpi_set_timings(struct omap_dss_device *dssdev,
|
|||||||
} else {
|
} else {
|
||||||
dss_mgr_set_timings(dssdev->manager, timings);
|
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,
|
int dpi_check_timings(struct omap_dss_device *dssdev,
|
||||||
struct omap_video_timings *timings)
|
struct omap_video_timings *timings)
|
||||||
@@ -325,6 +348,16 @@ int dpi_check_timings(struct omap_dss_device *dssdev,
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(dpi_check_timings);
|
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)
|
static int __init dpi_init_display(struct omap_dss_device *dssdev)
|
||||||
{
|
{
|
||||||
DSSDBG("init_display\n");
|
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)
|
static int __init omap_dpi_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
|
mutex_init(&dpi.lock);
|
||||||
|
|
||||||
dpi_probe_pdata(pdev);
|
dpi_probe_pdata(pdev);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
+146
-66
@@ -333,6 +333,10 @@ struct dsi_data {
|
|||||||
unsigned scp_clk_refcount;
|
unsigned scp_clk_refcount;
|
||||||
|
|
||||||
struct dss_lcd_mgr_config mgr_config;
|
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 {
|
struct dsi_packet_sent_handler_data {
|
||||||
@@ -2360,10 +2364,10 @@ static int dsi_cio_init(struct omap_dss_device *dssdev)
|
|||||||
|
|
||||||
dsi_cio_timings(dsidev);
|
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 */
|
/* DDR_CLK_ALWAYS_ON */
|
||||||
REG_FLD_MOD(dsidev, DSI_CLK_CTRL,
|
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;
|
dsi->ulps_enabled = false;
|
||||||
@@ -2685,6 +2689,7 @@ void omapdss_dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel,
|
|||||||
bool enable)
|
bool enable)
|
||||||
{
|
{
|
||||||
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
|
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);
|
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);
|
dsi_force_tx_stop_mode_io(dsidev);
|
||||||
|
|
||||||
/* start the DDR clock by sending a NULL packet */
|
/* 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);
|
dsi_vc_send_null(dssdev, channel);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(omapdss_dsi_vc_enable_hs);
|
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)
|
static void dsi_config_vp_num_line_buffers(struct omap_dss_device *dssdev)
|
||||||
{
|
{
|
||||||
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
|
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
|
||||||
|
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
||||||
int num_line_buffers;
|
int num_line_buffers;
|
||||||
|
|
||||||
if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) {
|
if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
|
||||||
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);
|
||||||
unsigned line_buf_size = dsi_get_line_buf_size(dsidev);
|
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
|
* Don't use line buffers if width is greater than the video
|
||||||
* port's line buffer size
|
* 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)
|
static void dsi_config_vp_sync_events(struct omap_dss_device *dssdev)
|
||||||
{
|
{
|
||||||
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
|
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
|
||||||
bool vsync_end = dssdev->panel.dsi_vm_data.vp_vsync_end;
|
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
||||||
bool hsync_end = dssdev->panel.dsi_vm_data.vp_hsync_end;
|
bool vsync_end = dsi->vm_timings.vp_vsync_end;
|
||||||
|
bool hsync_end = dsi->vm_timings.vp_hsync_end;
|
||||||
u32 r;
|
u32 r;
|
||||||
|
|
||||||
r = dsi_read_reg(dsidev, DSI_CTRL);
|
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)
|
static void dsi_config_blanking_modes(struct omap_dss_device *dssdev)
|
||||||
{
|
{
|
||||||
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
|
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
|
||||||
int blanking_mode = dssdev->panel.dsi_vm_data.blanking_mode;
|
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
||||||
int hfp_blanking_mode = dssdev->panel.dsi_vm_data.hfp_blanking_mode;
|
int blanking_mode = dsi->vm_timings.blanking_mode;
|
||||||
int hbp_blanking_mode = dssdev->panel.dsi_vm_data.hbp_blanking_mode;
|
int hfp_blanking_mode = dsi->vm_timings.hfp_blanking_mode;
|
||||||
int hsa_blanking_mode = dssdev->panel.dsi_vm_data.hsa_blanking_mode;
|
int hbp_blanking_mode = dsi->vm_timings.hbp_blanking_mode;
|
||||||
|
int hsa_blanking_mode = dsi->vm_timings.hsa_blanking_mode;
|
||||||
u32 r;
|
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 ddr_clk_pre, ddr_clk_post, enter_hs_mode_lat, exit_hs_mode_lat;
|
||||||
int tclk_trail, ths_exit, exiths_clk;
|
int tclk_trail, ths_exit, exiths_clk;
|
||||||
bool ddr_alwon;
|
bool ddr_alwon;
|
||||||
struct omap_video_timings *timings = &dssdev->panel.timings;
|
struct omap_video_timings *timings = &dsi->timings;
|
||||||
int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
|
int bpp = dsi_get_pixel_size(dsi->pix_fmt);
|
||||||
int ndl = dsi->num_lanes_used - 1;
|
int ndl = dsi->num_lanes_used - 1;
|
||||||
int dsi_fclk_hsdiv = dssdev->clocks.dsi.regm_dsi + 1;
|
int dsi_fclk_hsdiv = dssdev->clocks.dsi.regm_dsi + 1;
|
||||||
int hsa_interleave_hs = 0, hsa_interleave_lp = 0;
|
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)
|
static int dsi_proto_config(struct omap_dss_device *dssdev)
|
||||||
{
|
{
|
||||||
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
|
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
|
||||||
|
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
||||||
u32 r;
|
u32 r;
|
||||||
int buswidth = 0;
|
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_lp_rx_timeout(dsidev, 0x1fff, true, true);
|
||||||
dsi_set_hs_tx_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:
|
case 16:
|
||||||
buswidth = 0;
|
buswidth = 0;
|
||||||
break;
|
break;
|
||||||
@@ -3905,7 +3915,7 @@ static int dsi_proto_config(struct omap_dss_device *dssdev)
|
|||||||
|
|
||||||
dsi_config_vp_num_line_buffers(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_vp_sync_events(dssdev);
|
||||||
dsi_config_blanking_modes(dssdev);
|
dsi_config_blanking_modes(dssdev);
|
||||||
dsi_config_cmd_mode_interleaving(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",
|
DSSDBG("enter_hs_mode_lat %u, exit_hs_mode_lat %u\n",
|
||||||
enter_hs_mode_lat, exit_hs_mode_lat);
|
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 */
|
/* TODO: Implement a video mode check_timings function */
|
||||||
int hsa = dssdev->panel.dsi_vm_data.hsa;
|
int hsa = dsi->vm_timings.hsa;
|
||||||
int hfp = dssdev->panel.dsi_vm_data.hfp;
|
int hfp = dsi->vm_timings.hfp;
|
||||||
int hbp = dssdev->panel.dsi_vm_data.hbp;
|
int hbp = dsi->vm_timings.hbp;
|
||||||
int vsa = dssdev->panel.dsi_vm_data.vsa;
|
int vsa = dsi->vm_timings.vsa;
|
||||||
int vfp = dssdev->panel.dsi_vm_data.vfp;
|
int vfp = dsi->vm_timings.vfp;
|
||||||
int vbp = dssdev->panel.dsi_vm_data.vbp;
|
int vbp = dsi->vm_timings.vbp;
|
||||||
int window_sync = dssdev->panel.dsi_vm_data.window_sync;
|
int window_sync = dsi->vm_timings.window_sync;
|
||||||
bool hsync_end = dssdev->panel.dsi_vm_data.vp_hsync_end;
|
bool hsync_end = dsi->vm_timings.vp_hsync_end;
|
||||||
struct omap_video_timings *timings = &dssdev->panel.timings;
|
struct omap_video_timings *timings = &dsi->timings;
|
||||||
int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
|
int bpp = dsi_get_pixel_size(dsi->pix_fmt);
|
||||||
int tl, t_he, width_bytes;
|
int tl, t_he, width_bytes;
|
||||||
|
|
||||||
t_he = hsync_end ?
|
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)
|
int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
|
||||||
{
|
{
|
||||||
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
|
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;
|
u8 data_type;
|
||||||
u16 word_count;
|
u16 word_count;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) {
|
if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
|
||||||
switch (dssdev->panel.dsi_pix_fmt) {
|
switch (dsi->pix_fmt) {
|
||||||
case OMAP_DSS_DSI_FMT_RGB888:
|
case OMAP_DSS_DSI_FMT_RGB888:
|
||||||
data_type = MIPI_DSI_PACKED_PIXEL_STREAM_24;
|
data_type = MIPI_DSI_PACKED_PIXEL_STREAM_24;
|
||||||
break;
|
break;
|
||||||
@@ -4133,7 +4144,7 @@ int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
|
|||||||
/* MODE, 1 = video mode */
|
/* MODE, 1 = video mode */
|
||||||
REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 1, 4, 4);
|
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,
|
dsi_vc_write_long_header(dsidev, channel, data_type,
|
||||||
word_count, 0);
|
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);
|
r = dss_mgr_enable(dssdev->manager);
|
||||||
if (r) {
|
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_if_enable(dsidev, false);
|
||||||
dsi_vc_enable(dsidev, channel, 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)
|
void dsi_disable_video_output(struct omap_dss_device *dssdev, int channel)
|
||||||
{
|
{
|
||||||
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
|
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_if_enable(dsidev, false);
|
||||||
dsi_vc_enable(dsidev, channel, 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);
|
EXPORT_SYMBOL(dsi_disable_video_output);
|
||||||
|
|
||||||
static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
|
static void dsi_update_screen_dispc(struct omap_dss_device *dssdev)
|
||||||
u16 w, u16 h)
|
|
||||||
{
|
{
|
||||||
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
|
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
|
||||||
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
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;
|
int r;
|
||||||
const unsigned channel = dsi->update_channel;
|
const unsigned channel = dsi->update_channel;
|
||||||
const unsigned line_buf_size = dsi_get_line_buf_size(dsidev);
|
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);
|
DSSDBG("dsi_update_screen_dispc(%dx%d)\n", w, h);
|
||||||
|
|
||||||
dsi_vc_config_source(dsidev, channel, DSI_VC_SOURCE_VP);
|
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;
|
bytespl = w * bytespp;
|
||||||
bytespf = bytespl * h;
|
bytespf = bytespl * h;
|
||||||
|
|
||||||
@@ -4239,6 +4252,8 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
|
|||||||
msecs_to_jiffies(250));
|
msecs_to_jiffies(250));
|
||||||
BUG_ON(r == 0);
|
BUG_ON(r == 0);
|
||||||
|
|
||||||
|
dss_mgr_set_timings(dssdev->manager, &dsi->timings);
|
||||||
|
|
||||||
dss_mgr_start_update(dssdev->manager);
|
dss_mgr_start_update(dssdev->manager);
|
||||||
|
|
||||||
if (dsi->te_enabled) {
|
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_callback = callback;
|
||||||
dsi->framedone_data = data;
|
dsi->framedone_data = data;
|
||||||
|
|
||||||
dssdev->driver->get_resolution(dssdev, &dw, &dh);
|
dw = dsi->timings.x_res;
|
||||||
|
dh = dsi->timings.y_res;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
dsi->update_bytes = dw * dh *
|
dsi->update_bytes = dw * dh *
|
||||||
dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt) / 8;
|
dsi_get_pixel_size(dsi->pix_fmt) / 8;
|
||||||
#endif
|
#endif
|
||||||
dsi_update_screen_dispc(dssdev, dw, dh);
|
dsi_update_screen_dispc(dssdev);
|
||||||
|
|
||||||
return 0;
|
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 platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
|
||||||
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
||||||
struct omap_video_timings timings;
|
|
||||||
int r;
|
int r;
|
||||||
u32 irq = 0;
|
u32 irq = 0;
|
||||||
|
|
||||||
if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_CMD_MODE) {
|
if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) {
|
||||||
u16 dw, dh;
|
dsi->timings.hsw = 1;
|
||||||
|
dsi->timings.hfp = 1;
|
||||||
dssdev->driver->get_resolution(dssdev, &dw, &dh);
|
dsi->timings.hbp = 1;
|
||||||
|
dsi->timings.vsw = 1;
|
||||||
timings.x_res = dw;
|
dsi->timings.vfp = 0;
|
||||||
timings.y_res = dh;
|
dsi->timings.vbp = 0;
|
||||||
timings.hsw = 1;
|
|
||||||
timings.hfp = 1;
|
|
||||||
timings.hbp = 1;
|
|
||||||
timings.vsw = 1;
|
|
||||||
timings.vfp = 0;
|
|
||||||
timings.vbp = 0;
|
|
||||||
|
|
||||||
irq = dispc_mgr_get_framedone_irq(dssdev->manager->id);
|
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.stallmode = true;
|
||||||
dsi->mgr_config.fifohandcheck = true;
|
dsi->mgr_config.fifohandcheck = true;
|
||||||
} else {
|
} else {
|
||||||
timings = dssdev->panel.timings;
|
|
||||||
|
|
||||||
dsi->mgr_config.stallmode = false;
|
dsi->mgr_config.stallmode = false;
|
||||||
dsi->mgr_config.fifohandcheck = 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
|
* override interlace, logic level and edge related parameters in
|
||||||
* omap_video_timings with default values
|
* omap_video_timings with default values
|
||||||
*/
|
*/
|
||||||
timings.interlace = false;
|
dsi->timings.interlace = false;
|
||||||
timings.hsync_level = OMAPDSS_SIG_ACTIVE_HIGH;
|
dsi->timings.hsync_level = OMAPDSS_SIG_ACTIVE_HIGH;
|
||||||
timings.vsync_level = OMAPDSS_SIG_ACTIVE_HIGH;
|
dsi->timings.vsync_level = OMAPDSS_SIG_ACTIVE_HIGH;
|
||||||
timings.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
|
dsi->timings.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
|
||||||
timings.de_level = OMAPDSS_SIG_ACTIVE_HIGH;
|
dsi->timings.de_level = OMAPDSS_SIG_ACTIVE_HIGH;
|
||||||
timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES;
|
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);
|
r = dsi_configure_dispc_clocks(dssdev);
|
||||||
if (r)
|
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.io_pad_mode = DSS_IO_PAD_MODE_BYPASS;
|
||||||
dsi->mgr_config.video_port_width =
|
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;
|
dsi->mgr_config.lcden_sig_polarity = 0;
|
||||||
|
|
||||||
dss_mgr_set_lcd_config(dssdev->manager, &dsi->mgr_config);
|
dss_mgr_set_lcd_config(dssdev->manager, &dsi->mgr_config);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
err1:
|
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,
|
omap_dispc_unregister_isr(dsi_framedone_irq_callback,
|
||||||
(void *) dssdev, irq);
|
(void *) dssdev, irq);
|
||||||
err:
|
err:
|
||||||
@@ -4438,7 +4445,10 @@ err:
|
|||||||
|
|
||||||
static void dsi_display_uninit_dispc(struct omap_dss_device *dssdev)
|
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;
|
u32 irq;
|
||||||
|
|
||||||
irq = dispc_mgr_get_framedone_irq(dssdev->manager->id);
|
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);
|
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)
|
static int __init dsi_init_display(struct omap_dss_device *dssdev)
|
||||||
{
|
{
|
||||||
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(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");
|
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 |
|
dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE |
|
||||||
OMAP_DSS_DISPLAY_CAP_TEAR_ELIM;
|
OMAP_DSS_DISPLAY_CAP_TEAR_ELIM;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ static void dss_restore_context(void)
|
|||||||
#undef SR
|
#undef SR
|
||||||
#undef RR
|
#undef RR
|
||||||
|
|
||||||
void dss_sdi_init(u8 datapairs)
|
void dss_sdi_init(int datapairs)
|
||||||
{
|
{
|
||||||
u32 l;
|
u32 l;
|
||||||
|
|
||||||
|
|||||||
@@ -206,7 +206,7 @@ int dss_mgr_set_device(struct omap_overlay_manager *mgr,
|
|||||||
struct omap_dss_device *dssdev);
|
struct omap_dss_device *dssdev);
|
||||||
int dss_mgr_unset_device(struct omap_overlay_manager *mgr);
|
int dss_mgr_unset_device(struct omap_overlay_manager *mgr);
|
||||||
void dss_mgr_set_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);
|
||||||
void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr,
|
void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr,
|
||||||
const struct dss_lcd_mgr_config *config);
|
const struct dss_lcd_mgr_config *config);
|
||||||
const struct omap_video_timings *dss_mgr_get_timings(struct omap_overlay_manager *mgr);
|
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);
|
void dss_debug_dump_clocks(struct seq_file *s);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void dss_sdi_init(u8 datapairs);
|
void dss_sdi_init(int datapairs);
|
||||||
int dss_sdi_enable(void);
|
int dss_sdi_enable(void);
|
||||||
void dss_sdi_disable(void);
|
void dss_sdi_disable(void);
|
||||||
|
|
||||||
@@ -469,6 +469,20 @@ static inline unsigned long venc_get_pixel_clock(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#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 */
|
/* HDMI */
|
||||||
#ifdef CONFIG_OMAP4_DSS_HDMI
|
#ifdef CONFIG_OMAP4_DSS_HDMI
|
||||||
@@ -484,7 +498,8 @@ static inline unsigned long hdmi_get_pixel_clock(void)
|
|||||||
#endif
|
#endif
|
||||||
int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev);
|
int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev);
|
||||||
void omapdss_hdmi_display_disable(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,
|
int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
|
||||||
struct omap_video_timings *timings);
|
struct omap_video_timings *timings);
|
||||||
int omapdss_hdmi_read_edid(u8 *buf, int len);
|
int omapdss_hdmi_read_edid(u8 *buf, int len);
|
||||||
|
|||||||
@@ -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)
|
static int hdmi_power_on(struct omap_dss_device *dssdev)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
const struct hdmi_config *timing;
|
|
||||||
struct omap_video_timings *p;
|
struct omap_video_timings *p;
|
||||||
unsigned long phy;
|
unsigned long phy;
|
||||||
|
|
||||||
@@ -469,22 +468,10 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
|
|||||||
|
|
||||||
dss_mgr_disable(dssdev->manager);
|
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",
|
DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res);
|
||||||
dssdev->panel.timings.x_res,
|
|
||||||
dssdev->panel.timings.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;
|
phy = p->pixel_clock;
|
||||||
|
|
||||||
hdmi_compute_pll(dssdev, phy, &hdmi.ip_data.pll_data);
|
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);
|
dispc_enable_gamma_table(0);
|
||||||
|
|
||||||
/* tv size */
|
/* 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);
|
r = hdmi.ip_data.ops->video_enable(&hdmi.ip_data);
|
||||||
if (r)
|
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;
|
struct hdmi_cm cm;
|
||||||
|
const struct hdmi_config *t;
|
||||||
|
|
||||||
cm = hdmi_get_code(&dssdev->panel.timings);
|
mutex_lock(&hdmi.lock);
|
||||||
hdmi.ip_data.cfg.cm.code = cm.code;
|
|
||||||
hdmi.ip_data.cfg.cm.mode = cm.mode;
|
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) {
|
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
|
||||||
int r;
|
int r;
|
||||||
@@ -585,8 +579,10 @@ void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev)
|
|||||||
if (r)
|
if (r)
|
||||||
DSSERR("failed to power on device\n");
|
DSSERR("failed to power on device\n");
|
||||||
} else {
|
} 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)
|
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.core_av_offset = HDMI_CORE_AV;
|
||||||
hdmi.ip_data.pll_offset = HDMI_PLLCTRL;
|
hdmi.ip_data.pll_offset = HDMI_PLLCTRL;
|
||||||
hdmi.ip_data.phy_offset = HDMI_PHY;
|
hdmi.ip_data.phy_offset = HDMI_PHY;
|
||||||
|
|
||||||
mutex_init(&hdmi.ip_data.lock);
|
mutex_init(&hdmi.ip_data.lock);
|
||||||
|
|
||||||
hdmi_panel_init();
|
hdmi_panel_init();
|
||||||
|
|||||||
@@ -41,17 +41,32 @@ static struct {
|
|||||||
|
|
||||||
static int hdmi_panel_probe(struct omap_dss_device *dssdev)
|
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");
|
DSSDBG("ENTER hdmi_panel_probe\n");
|
||||||
|
|
||||||
dssdev->panel.timings = (struct omap_video_timings)
|
dssdev->panel.timings = default_timings;
|
||||||
{ 640, 480, 25175, 96, 16, 48, 2, 11, 31,
|
|
||||||
OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
|
|
||||||
false,
|
|
||||||
};
|
|
||||||
|
|
||||||
DSSDBG("hdmi_panel_probe x_res= %d y_res = %d\n",
|
DSSDBG("hdmi_panel_probe x_res= %d y_res = %d\n",
|
||||||
dssdev->panel.timings.x_res,
|
dssdev->panel.timings.x_res,
|
||||||
dssdev->panel.timings.y_res);
|
dssdev->panel.timings.y_res);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -228,6 +243,8 @@ static int hdmi_panel_enable(struct omap_dss_device *dssdev)
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
omapdss_hdmi_display_set_timing(dssdev, &dssdev->panel.timings);
|
||||||
|
|
||||||
r = omapdss_hdmi_display_enable(dssdev);
|
r = omapdss_hdmi_display_enable(dssdev);
|
||||||
if (r) {
|
if (r) {
|
||||||
DSSERR("failed to power on\n");
|
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);
|
hdmi_panel_audio_disable(dssdev);
|
||||||
|
|
||||||
|
omapdss_hdmi_display_set_timing(dssdev, timings);
|
||||||
dssdev->panel.timings = *timings;
|
dssdev->panel.timings = *timings;
|
||||||
omapdss_hdmi_display_set_timing(dssdev);
|
|
||||||
|
|
||||||
mutex_unlock(&hdmi.lock);
|
mutex_unlock(&hdmi.lock);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -111,6 +111,11 @@ static struct {
|
|||||||
struct omap_dss_device *dssdev[2];
|
struct omap_dss_device *dssdev[2];
|
||||||
|
|
||||||
struct semaphore bus_lock;
|
struct semaphore bus_lock;
|
||||||
|
|
||||||
|
struct omap_video_timings timings;
|
||||||
|
int pixel_size;
|
||||||
|
int data_lines;
|
||||||
|
struct rfbi_timings intf_timings;
|
||||||
} rfbi;
|
} rfbi;
|
||||||
|
|
||||||
static inline void rfbi_write_reg(const struct rfbi_reg idx, u32 val)
|
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);
|
EXPORT_SYMBOL(omap_rfbi_write_pixels);
|
||||||
|
|
||||||
static int rfbi_transfer_area(struct omap_dss_device *dssdev, u16 width,
|
static int rfbi_transfer_area(struct omap_dss_device *dssdev,
|
||||||
u16 height, void (*callback)(void *data), void *data)
|
void (*callback)(void *data), void *data)
|
||||||
{
|
{
|
||||||
u32 l;
|
u32 l;
|
||||||
int r;
|
int r;
|
||||||
struct omap_video_timings timings = {
|
u16 width = rfbi.timings.x_res;
|
||||||
.hsw = 1,
|
u16 height = rfbi.timings.y_res;
|
||||||
.hfp = 1,
|
|
||||||
.hbp = 1,
|
|
||||||
.vsw = 1,
|
|
||||||
.vfp = 0,
|
|
||||||
.vbp = 0,
|
|
||||||
.x_res = width,
|
|
||||||
.y_res = height,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*BUG_ON(callback == 0);*/
|
/*BUG_ON(callback == 0);*/
|
||||||
BUG_ON(rfbi.framedone_callback != NULL);
|
BUG_ON(rfbi.framedone_callback != NULL);
|
||||||
|
|
||||||
DSSDBG("rfbi_transfer_area %dx%d\n", width, height);
|
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);
|
r = dss_mgr_enable(dssdev->manager);
|
||||||
if (r)
|
if (r)
|
||||||
@@ -770,63 +767,46 @@ static int rfbi_configure(int rfbi_module, int bpp, int lines)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int omap_rfbi_configure(struct omap_dss_device *dssdev, int pixel_size,
|
int omap_rfbi_configure(struct omap_dss_device *dssdev)
|
||||||
int data_lines)
|
|
||||||
{
|
{
|
||||||
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);
|
EXPORT_SYMBOL(omap_rfbi_configure);
|
||||||
|
|
||||||
int omap_rfbi_prepare_update(struct omap_dss_device *dssdev,
|
int omap_rfbi_update(struct omap_dss_device *dssdev, void (*callback)(void *),
|
||||||
u16 *x, u16 *y, u16 *w, u16 *h)
|
void *data)
|
||||||
{
|
{
|
||||||
u16 dw, dh;
|
return rfbi_transfer_area(dssdev, callback, data);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(omap_rfbi_update);
|
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)
|
static void rfbi_dump_regs(struct seq_file *s)
|
||||||
{
|
{
|
||||||
#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, rfbi_read_reg(r))
|
#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? */
|
/* Do we need fifohandcheck for RFBI? */
|
||||||
mgr_config.fifohandcheck = false;
|
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;
|
mgr_config.lcden_sig_polarity = 0;
|
||||||
|
|
||||||
dss_mgr_set_lcd_config(dssdev->manager, &mgr_config);
|
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)
|
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_config_lcd_manager(dssdev);
|
||||||
|
|
||||||
rfbi_configure(dssdev->phy.rfbi.channel,
|
rfbi_configure(dssdev->phy.rfbi.channel, rfbi.pixel_size,
|
||||||
dssdev->ctrl.pixel_size,
|
rfbi.data_lines);
|
||||||
dssdev->phy.rfbi.data_lines);
|
|
||||||
|
|
||||||
rfbi_set_timings(dssdev->phy.rfbi.channel,
|
|
||||||
&dssdev->ctrl.rfbi_timings);
|
|
||||||
|
|
||||||
|
rfbi_set_timings(dssdev->phy.rfbi.channel, &rfbi.intf_timings);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
err1:
|
err1:
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ static struct {
|
|||||||
struct regulator *vdds_sdi_reg;
|
struct regulator *vdds_sdi_reg;
|
||||||
|
|
||||||
struct dss_lcd_mgr_config mgr_config;
|
struct dss_lcd_mgr_config mgr_config;
|
||||||
|
struct omap_video_timings timings;
|
||||||
|
int datapairs;
|
||||||
} sdi;
|
} sdi;
|
||||||
|
|
||||||
static void sdi_config_lcd_manager(struct omap_dss_device *dssdev)
|
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)
|
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 dss_clock_info dss_cinfo;
|
||||||
struct dispc_clock_info dispc_cinfo;
|
struct dispc_clock_info dispc_cinfo;
|
||||||
unsigned long pck;
|
unsigned long pck;
|
||||||
@@ -77,8 +79,8 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
|
|||||||
goto err_get_dispc;
|
goto err_get_dispc;
|
||||||
|
|
||||||
/* 15.5.9.1.2 */
|
/* 15.5.9.1.2 */
|
||||||
dssdev->panel.timings.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
|
t->data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
|
||||||
dssdev->panel.timings.sync_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);
|
r = dss_calc_clock_div(t->pixel_clock * 1000, &dss_cinfo, &dispc_cinfo);
|
||||||
if (r)
|
if (r)
|
||||||
@@ -105,7 +107,8 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
|
|||||||
|
|
||||||
sdi_config_lcd_manager(dssdev);
|
sdi_config_lcd_manager(dssdev);
|
||||||
|
|
||||||
dss_sdi_init(dssdev->phy.sdi.datapairs);
|
dss_sdi_init(sdi.datapairs);
|
||||||
|
|
||||||
r = dss_sdi_enable();
|
r = dss_sdi_enable();
|
||||||
if (r)
|
if (r)
|
||||||
goto err_sdi_enable;
|
goto err_sdi_enable;
|
||||||
@@ -146,6 +149,29 @@ void omapdss_sdi_display_disable(struct omap_dss_device *dssdev)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(omapdss_sdi_display_disable);
|
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)
|
static int __init sdi_init_display(struct omap_dss_device *dssdev)
|
||||||
{
|
{
|
||||||
DSSDBG("SDI init\n");
|
DSSDBG("SDI init\n");
|
||||||
|
|||||||
+81
-159
@@ -300,6 +300,10 @@ static struct {
|
|||||||
struct regulator *vdda_dac_reg;
|
struct regulator *vdda_dac_reg;
|
||||||
|
|
||||||
struct clk *tv_dac_clk;
|
struct clk *tv_dac_clk;
|
||||||
|
|
||||||
|
struct omap_video_timings timings;
|
||||||
|
enum omap_dss_venc_type type;
|
||||||
|
bool invert_polarity;
|
||||||
} venc;
|
} venc;
|
||||||
|
|
||||||
static inline void venc_write_reg(int idx, u32 val)
|
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;
|
u32 l;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
venc_reset();
|
r = venc_runtime_get();
|
||||||
venc_write_config(venc_timings_to_config(&dssdev->panel.timings));
|
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);
|
dss_set_dac_pwrdn_bgz(1);
|
||||||
|
|
||||||
l = 0;
|
l = 0;
|
||||||
|
|
||||||
if (dssdev->phy.venc.type == OMAP_DSS_VENC_TYPE_COMPOSITE)
|
if (venc.type == OMAP_DSS_VENC_TYPE_COMPOSITE)
|
||||||
l |= 1 << 1;
|
l |= 1 << 1;
|
||||||
else /* S-Video */
|
else /* S-Video */
|
||||||
l |= (1 << 0) | (1 << 2);
|
l |= (1 << 0) | (1 << 2);
|
||||||
|
|
||||||
if (dssdev->phy.venc.invert_polarity == false)
|
if (venc.invert_polarity == false)
|
||||||
l |= 1 << 3;
|
l |= 1 << 3;
|
||||||
|
|
||||||
venc_write_reg(VENC_OUTPUT_CONTROL, l);
|
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);
|
r = regulator_enable(venc.vdda_dac_reg);
|
||||||
if (r)
|
if (r)
|
||||||
goto err;
|
goto err1;
|
||||||
|
|
||||||
if (dssdev->platform_enable)
|
|
||||||
dssdev->platform_enable(dssdev);
|
|
||||||
|
|
||||||
r = dss_mgr_enable(dssdev->manager);
|
r = dss_mgr_enable(dssdev->manager);
|
||||||
if (r)
|
if (r)
|
||||||
goto err;
|
goto err2;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err:
|
err2:
|
||||||
|
regulator_disable(venc.vdda_dac_reg);
|
||||||
|
err1:
|
||||||
venc_write_reg(VENC_OUTPUT_CONTROL, 0);
|
venc_write_reg(VENC_OUTPUT_CONTROL, 0);
|
||||||
dss_set_dac_pwrdn_bgz(0);
|
dss_set_dac_pwrdn_bgz(0);
|
||||||
|
|
||||||
if (dssdev->platform_disable)
|
venc_runtime_put();
|
||||||
dssdev->platform_disable(dssdev);
|
err0:
|
||||||
|
|
||||||
regulator_disable(venc.vdda_dac_reg);
|
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -479,10 +483,9 @@ static void venc_power_off(struct omap_dss_device *dssdev)
|
|||||||
|
|
||||||
dss_mgr_disable(dssdev->manager);
|
dss_mgr_disable(dssdev->manager);
|
||||||
|
|
||||||
if (dssdev->platform_disable)
|
|
||||||
dssdev->platform_disable(dssdev);
|
|
||||||
|
|
||||||
regulator_disable(venc.vdda_dac_reg);
|
regulator_disable(venc.vdda_dac_reg);
|
||||||
|
|
||||||
|
venc_runtime_put();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long venc_get_pixel_clock(void)
|
unsigned long venc_get_pixel_clock(void)
|
||||||
@@ -491,171 +494,95 @@ unsigned long venc_get_pixel_clock(void)
|
|||||||
return 13500000;
|
return 13500000;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t display_output_type_show(struct device *dev,
|
int omapdss_venc_display_enable(struct omap_dss_device *dssdev)
|
||||||
struct device_attribute *attr, char *buf)
|
|
||||||
{
|
{
|
||||||
struct omap_dss_device *dssdev = to_dss_device(dev);
|
int r;
|
||||||
const char *ret;
|
|
||||||
|
|
||||||
switch (dssdev->phy.venc.type) {
|
DSSDBG("venc_display_enable\n");
|
||||||
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.venc_lock);
|
mutex_lock(&venc.venc_lock);
|
||||||
|
|
||||||
if (dssdev->phy.venc.type != new_type) {
|
if (dssdev->manager == NULL) {
|
||||||
dssdev->phy.venc.type = new_type;
|
DSSERR("Failed to enable display: no manager\n");
|
||||||
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
|
r = -ENODEV;
|
||||||
venc_power_off(dssdev);
|
goto err0;
|
||||||
venc_power_on(dssdev);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
r = omap_dss_start_device(dssdev);
|
||||||
if (r) {
|
if (r) {
|
||||||
DSSERR("failed to start device\n");
|
DSSERR("failed to start device\n");
|
||||||
goto err0;
|
goto err0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
|
if (dssdev->platform_enable)
|
||||||
r = -EINVAL;
|
dssdev->platform_enable(dssdev);
|
||||||
goto err1;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = venc_runtime_get();
|
|
||||||
if (r)
|
|
||||||
goto err1;
|
|
||||||
|
|
||||||
r = venc_power_on(dssdev);
|
r = venc_power_on(dssdev);
|
||||||
if (r)
|
if (r)
|
||||||
goto err2;
|
goto err1;
|
||||||
|
|
||||||
venc.wss_data = 0;
|
venc.wss_data = 0;
|
||||||
|
|
||||||
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
|
|
||||||
|
|
||||||
mutex_unlock(&venc.venc_lock);
|
mutex_unlock(&venc.venc_lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
err2:
|
|
||||||
venc_runtime_put();
|
|
||||||
err1:
|
err1:
|
||||||
|
if (dssdev->platform_disable)
|
||||||
|
dssdev->platform_disable(dssdev);
|
||||||
omap_dss_stop_device(dssdev);
|
omap_dss_stop_device(dssdev);
|
||||||
err0:
|
err0:
|
||||||
mutex_unlock(&venc.venc_lock);
|
mutex_unlock(&venc.venc_lock);
|
||||||
|
|
||||||
return r;
|
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);
|
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_power_off(dssdev);
|
||||||
|
|
||||||
venc_runtime_put();
|
|
||||||
|
|
||||||
dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
|
|
||||||
|
|
||||||
omap_dss_stop_device(dssdev);
|
omap_dss_stop_device(dssdev);
|
||||||
end:
|
|
||||||
|
if (dssdev->platform_disable)
|
||||||
|
dssdev->platform_disable(dssdev);
|
||||||
|
|
||||||
mutex_unlock(&venc.venc_lock);
|
mutex_unlock(&venc.venc_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int venc_panel_suspend(struct omap_dss_device *dssdev)
|
void omapdss_venc_set_timings(struct omap_dss_device *dssdev,
|
||||||
{
|
struct omap_video_timings *timings)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
DSSDBG("venc_set_timings\n");
|
DSSDBG("venc_set_timings\n");
|
||||||
|
|
||||||
|
mutex_lock(&venc.venc_lock);
|
||||||
|
|
||||||
/* Reset WSS data when the TV standard changes. */
|
/* 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;
|
venc.wss_data = 0;
|
||||||
|
|
||||||
dssdev->panel.timings = *timings;
|
venc.timings = *timings;
|
||||||
|
|
||||||
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
|
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
|
||||||
|
int r;
|
||||||
|
|
||||||
/* turn the venc off and on to get new timings to use */
|
/* turn the venc off and on to get new timings to use */
|
||||||
venc_panel_disable(dssdev);
|
venc_power_off(dssdev);
|
||||||
venc_panel_enable(dssdev);
|
|
||||||
|
r = venc_power_on(dssdev);
|
||||||
|
if (r)
|
||||||
|
DSSERR("failed to power on VENC\n");
|
||||||
} else {
|
} else {
|
||||||
dss_mgr_set_timings(dssdev->manager, timings);
|
dss_mgr_set_timings(dssdev->manager, timings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mutex_unlock(&venc.venc_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int venc_check_timings(struct omap_dss_device *dssdev,
|
int omapdss_venc_check_timings(struct omap_dss_device *dssdev,
|
||||||
struct omap_video_timings *timings)
|
struct omap_video_timings *timings)
|
||||||
{
|
{
|
||||||
DSSDBG("venc_check_timings\n");
|
DSSDBG("venc_check_timings\n");
|
||||||
|
|
||||||
@@ -668,13 +595,13 @@ static int venc_check_timings(struct omap_dss_device *dssdev,
|
|||||||
return -EINVAL;
|
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 */
|
/* Invert due to VENC_L21_WC_CTL:INV=1 */
|
||||||
return (venc.wss_data >> 8) ^ 0xfffff;
|
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;
|
const struct venc_config *config;
|
||||||
int r;
|
int r;
|
||||||
@@ -683,7 +610,7 @@ static int venc_set_wss(struct omap_dss_device *dssdev, u32 wss)
|
|||||||
|
|
||||||
mutex_lock(&venc.venc_lock);
|
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 */
|
/* Invert due to VENC_L21_WC_CTL:INV=1 */
|
||||||
venc.wss_data = (wss ^ 0xfffff) << 8;
|
venc.wss_data = (wss ^ 0xfffff) << 8;
|
||||||
@@ -703,30 +630,25 @@ err:
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct omap_dss_driver venc_driver = {
|
void omapdss_venc_set_type(struct omap_dss_device *dssdev,
|
||||||
.probe = venc_panel_probe,
|
enum omap_dss_venc_type type)
|
||||||
.remove = venc_panel_remove,
|
{
|
||||||
|
mutex_lock(&venc.venc_lock);
|
||||||
|
|
||||||
.enable = venc_panel_enable,
|
venc.type = type;
|
||||||
.disable = venc_panel_disable,
|
|
||||||
.suspend = venc_panel_suspend,
|
|
||||||
.resume = venc_panel_resume,
|
|
||||||
|
|
||||||
.get_resolution = omapdss_default_get_resolution,
|
mutex_unlock(&venc.venc_lock);
|
||||||
.get_recommended_bpp = omapdss_default_get_recommended_bpp,
|
}
|
||||||
|
|
||||||
.set_timings = venc_set_timings,
|
void omapdss_venc_invert_vid_out_polarity(struct omap_dss_device *dssdev,
|
||||||
.check_timings = venc_check_timings,
|
bool invert_polarity)
|
||||||
|
{
|
||||||
|
mutex_lock(&venc.venc_lock);
|
||||||
|
|
||||||
.get_wss = venc_get_wss,
|
venc.invert_polarity = invert_polarity;
|
||||||
.set_wss = venc_set_wss,
|
|
||||||
|
|
||||||
.driver = {
|
mutex_unlock(&venc.venc_lock);
|
||||||
.name = "venc",
|
}
|
||||||
.owner = THIS_MODULE,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
/* driver end */
|
|
||||||
|
|
||||||
static int __init venc_init_display(struct omap_dss_device *dssdev)
|
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();
|
venc_runtime_put();
|
||||||
|
|
||||||
r = omap_dss_register_driver(&venc_driver);
|
r = venc_panel_init();
|
||||||
if (r)
|
if (r)
|
||||||
goto err_reg_panel_driver;
|
goto err_panel_init;
|
||||||
|
|
||||||
dss_debugfs_create_file("venc", venc_dump_regs);
|
dss_debugfs_create_file("venc", venc_dump_regs);
|
||||||
|
|
||||||
@@ -907,7 +829,7 @@ static int __init omap_venchw_probe(struct platform_device *pdev)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_reg_panel_driver:
|
err_panel_init:
|
||||||
err_runtime_get:
|
err_runtime_get:
|
||||||
pm_runtime_disable(&pdev->dev);
|
pm_runtime_disable(&pdev->dev);
|
||||||
venc_put_clocks();
|
venc_put_clocks();
|
||||||
@@ -923,7 +845,7 @@ static int __exit omap_venchw_remove(struct platform_device *pdev)
|
|||||||
venc.vdda_dac_reg = NULL;
|
venc.vdda_dac_reg = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
omap_dss_unregister_driver(&venc_driver);
|
venc_panel_exit();
|
||||||
|
|
||||||
pm_runtime_disable(&pdev->dev);
|
pm_runtime_disable(&pdev->dev);
|
||||||
venc_put_clocks();
|
venc_put_clocks();
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
+26
-10
@@ -243,7 +243,7 @@ void rfbi_bus_unlock(void);
|
|||||||
|
|
||||||
/* DSI */
|
/* DSI */
|
||||||
|
|
||||||
struct omap_dss_dsi_videomode_data {
|
struct omap_dss_dsi_videomode_timings {
|
||||||
/* DSI video mode blanking data */
|
/* DSI video mode blanking data */
|
||||||
/* Unit: byte clock cycles */
|
/* Unit: byte clock cycles */
|
||||||
u16 hsa;
|
u16 hsa;
|
||||||
@@ -564,7 +564,7 @@ struct omap_dss_device {
|
|||||||
|
|
||||||
enum omap_dss_dsi_pixel_format dsi_pix_fmt;
|
enum omap_dss_dsi_pixel_format dsi_pix_fmt;
|
||||||
enum omap_dss_dsi_mode dsi_mode;
|
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;
|
} panel;
|
||||||
|
|
||||||
struct {
|
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,
|
void omapdss_dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel,
|
||||||
bool enable);
|
bool enable);
|
||||||
int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, 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,
|
int omap_dsi_update(struct omap_dss_device *dssdev, int channel,
|
||||||
void (*callback)(int, void *), void *data);
|
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);
|
int omapdss_dpi_display_enable(struct omap_dss_device *dssdev);
|
||||||
void omapdss_dpi_display_disable(struct omap_dss_device *dssdev);
|
void omapdss_dpi_display_disable(struct omap_dss_device *dssdev);
|
||||||
void dpi_set_timings(struct omap_dss_device *dssdev,
|
void omapdss_dpi_set_timings(struct omap_dss_device *dssdev,
|
||||||
struct omap_video_timings *timings);
|
struct omap_video_timings *timings);
|
||||||
int dpi_check_timings(struct omap_dss_device *dssdev,
|
int dpi_check_timings(struct omap_dss_device *dssdev,
|
||||||
struct omap_video_timings *timings);
|
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);
|
int omapdss_sdi_display_enable(struct omap_dss_device *dssdev);
|
||||||
void omapdss_sdi_display_disable(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);
|
int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev);
|
||||||
void omapdss_rfbi_display_disable(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,
|
int omap_rfbi_update(struct omap_dss_device *dssdev, void (*callback)(void *),
|
||||||
u16 *x, u16 *y, u16 *w, u16 *h);
|
void *data);
|
||||||
int omap_rfbi_update(struct omap_dss_device *dssdev,
|
int omap_rfbi_configure(struct omap_dss_device *dssdev);
|
||||||
u16 x, u16 y, u16 w, u16 h,
|
void omapdss_rfbi_set_size(struct omap_dss_device *dssdev, u16 w, u16 h);
|
||||||
void (*callback)(void *), void *data);
|
void omapdss_rfbi_set_pixel_size(struct omap_dss_device *dssdev,
|
||||||
int omap_rfbi_configure(struct omap_dss_device *dssdev, int pixel_size,
|
int pixel_size);
|
||||||
|
void omapdss_rfbi_set_data_lines(struct omap_dss_device *dssdev,
|
||||||
int data_lines);
|
int data_lines);
|
||||||
|
void omapdss_rfbi_set_interface_timings(struct omap_dss_device *dssdev,
|
||||||
|
struct rfbi_timings *timings);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user