Skip to content

Commit

Permalink
OMAPDSS: VENC: Split VENC into interface and panel driver
Browse files Browse the repository at this point in the history
The current venc.c driver contains both the interface and panel driver code.
This makes the driver hard to read, and difficult to understand the work split
between the interface and panel driver and the how the locking works.

This also makes it easier to clearly define the VENC interface ops called by the
panel driver.

Split venc.c into venc.c and venc_panel.c representing the interface and panel
driver respectively. This split is done along the lines of the HDMI interface
and panel drivers.

Signed-off-by: Archit Taneja <archit@ti.com>
  • Loading branch information
Archit Taneja committed Aug 15, 2012
1 parent 9b4a571 commit 156fd99
Show file tree
Hide file tree
Showing 4 changed files with 308 additions and 156 deletions.
2 changes: 1 addition & 1 deletion drivers/video/omap2/dss/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \
manager.o overlay.o apply.o
omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o
omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o
omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o
omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o venc_panel.o
omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o
omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o
omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi.o \
Expand Down
10 changes: 10 additions & 0 deletions drivers/video/omap2/dss/dss.h
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,16 @@ static inline unsigned long venc_get_pixel_clock(void)
return 0;
}
#endif
int omapdss_venc_display_enable(struct omap_dss_device *dssdev);
void omapdss_venc_display_disable(struct omap_dss_device *dssdev);
void omapdss_venc_set_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings);
int omapdss_venc_check_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings);
u32 omapdss_venc_get_wss(struct omap_dss_device *dssdev);
int omapdss_venc_set_wss(struct omap_dss_device *dssdev, u32 wss);
int venc_panel_init(void);
void venc_panel_exit(void);

/* HDMI */
#ifdef CONFIG_OMAP4_DSS_HDMI
Expand Down
208 changes: 53 additions & 155 deletions drivers/video/omap2/dss/venc.c
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,10 @@ static int venc_power_on(struct omap_dss_device *dssdev)
u32 l;
int r;

r = venc_runtime_get();
if (r)
goto err0;

venc_reset();
venc_write_config(venc_timings_to_config(&dssdev->panel.timings));

Expand All @@ -449,26 +453,22 @@ static int venc_power_on(struct omap_dss_device *dssdev)

r = regulator_enable(venc.vdda_dac_reg);
if (r)
goto err;

if (dssdev->platform_enable)
dssdev->platform_enable(dssdev);
goto err1;

r = dss_mgr_enable(dssdev->manager);
if (r)
goto err;
goto err2;

return 0;

err:
err2:
regulator_disable(venc.vdda_dac_reg);
err1:
venc_write_reg(VENC_OUTPUT_CONTROL, 0);
dss_set_dac_pwrdn_bgz(0);

if (dssdev->platform_disable)
dssdev->platform_disable(dssdev);

regulator_disable(venc.vdda_dac_reg);

venc_runtime_put();
err0:
return r;
}

Expand All @@ -479,10 +479,9 @@ static void venc_power_off(struct omap_dss_device *dssdev)

dss_mgr_disable(dssdev->manager);

if (dssdev->platform_disable)
dssdev->platform_disable(dssdev);

regulator_disable(venc.vdda_dac_reg);

venc_runtime_put();
}

unsigned long venc_get_pixel_clock(void)
Expand All @@ -491,171 +490,95 @@ unsigned long venc_get_pixel_clock(void)
return 13500000;
}

static ssize_t display_output_type_show(struct device *dev,
struct device_attribute *attr, char *buf)
int omapdss_venc_display_enable(struct omap_dss_device *dssdev)
{
struct omap_dss_device *dssdev = to_dss_device(dev);
const char *ret;

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;
}
int r;

return snprintf(buf, PAGE_SIZE, "%s\n", ret);
}

static ssize_t display_output_type_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size)
{
struct omap_dss_device *dssdev = to_dss_device(dev);
enum omap_dss_venc_type new_type;

if (sysfs_streq("composite", buf))
new_type = OMAP_DSS_VENC_TYPE_COMPOSITE;
else if (sysfs_streq("svideo", buf))
new_type = OMAP_DSS_VENC_TYPE_SVIDEO;
else
return -EINVAL;
DSSDBG("venc_display_enable\n");

mutex_lock(&venc.venc_lock);

if (dssdev->phy.venc.type != new_type) {
dssdev->phy.venc.type = new_type;
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
venc_power_off(dssdev);
venc_power_on(dssdev);
}
if (dssdev->manager == NULL) {
DSSERR("Failed to enable display: no manager\n");
r = -ENODEV;
goto err0;
}

mutex_unlock(&venc.venc_lock);

return size;
}

static DEVICE_ATTR(output_type, S_IRUGO | S_IWUSR,
display_output_type_show, display_output_type_store);

/* driver */
static int venc_panel_probe(struct omap_dss_device *dssdev)
{
dssdev->panel.timings = omap_dss_pal_timings;

return device_create_file(&dssdev->dev, &dev_attr_output_type);
}

static void venc_panel_remove(struct omap_dss_device *dssdev)
{
device_remove_file(&dssdev->dev, &dev_attr_output_type);
}

static int venc_panel_enable(struct omap_dss_device *dssdev)
{
int r = 0;

DSSDBG("venc_enable_display\n");

mutex_lock(&venc.venc_lock);

r = omap_dss_start_device(dssdev);
if (r) {
DSSERR("failed to start device\n");
goto err0;
}

if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
r = -EINVAL;
goto err1;
}
if (dssdev->platform_enable)
dssdev->platform_enable(dssdev);

r = venc_runtime_get();
if (r)
goto err1;

r = venc_power_on(dssdev);
if (r)
goto err2;
goto err1;

venc.wss_data = 0;

dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;

mutex_unlock(&venc.venc_lock);

return 0;
err2:
venc_runtime_put();
err1:
if (dssdev->platform_disable)
dssdev->platform_disable(dssdev);
omap_dss_stop_device(dssdev);
err0:
mutex_unlock(&venc.venc_lock);

return r;
}

static void venc_panel_disable(struct omap_dss_device *dssdev)
void omapdss_venc_display_disable(struct omap_dss_device *dssdev)
{
DSSDBG("venc_disable_display\n");
DSSDBG("venc_display_disable\n");

mutex_lock(&venc.venc_lock);

if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED)
goto end;

if (dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED) {
/* suspended is the same as disabled with venc */
dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
goto end;
}

venc_power_off(dssdev);

venc_runtime_put();

dssdev->state = OMAP_DSS_DISPLAY_DISABLED;

omap_dss_stop_device(dssdev);
end:
mutex_unlock(&venc.venc_lock);
}

static int venc_panel_suspend(struct omap_dss_device *dssdev)
{
venc_panel_disable(dssdev);
return 0;
}
if (dssdev->platform_disable)
dssdev->platform_disable(dssdev);

static int venc_panel_resume(struct omap_dss_device *dssdev)
{
return venc_panel_enable(dssdev);
mutex_unlock(&venc.venc_lock);
}

static void venc_set_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
void omapdss_venc_set_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
{
DSSDBG("venc_set_timings\n");

mutex_lock(&venc.venc_lock);

/* Reset WSS data when the TV standard changes. */
if (memcmp(&dssdev->panel.timings, timings, sizeof(*timings)))
venc.wss_data = 0;

dssdev->panel.timings = *timings;

if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
int r;

/* turn the venc off and on to get new timings to use */
venc_panel_disable(dssdev);
venc_panel_enable(dssdev);
venc_power_off(dssdev);

r = venc_power_on(dssdev);
if (r)
DSSERR("failed to power on VENC\n");
} else {
dss_mgr_set_timings(dssdev->manager, timings);
}

mutex_unlock(&venc.venc_lock);
}

static int venc_check_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
int omapdss_venc_check_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
{
DSSDBG("venc_check_timings\n");

Expand All @@ -668,13 +591,13 @@ static int venc_check_timings(struct omap_dss_device *dssdev,
return -EINVAL;
}

static u32 venc_get_wss(struct omap_dss_device *dssdev)
u32 omapdss_venc_get_wss(struct omap_dss_device *dssdev)
{
/* Invert due to VENC_L21_WC_CTL:INV=1 */
return (venc.wss_data >> 8) ^ 0xfffff;
}

static int venc_set_wss(struct omap_dss_device *dssdev, u32 wss)
int omapdss_venc_set_wss(struct omap_dss_device *dssdev, u32 wss)
{
const struct venc_config *config;
int r;
Expand Down Expand Up @@ -703,31 +626,6 @@ static int venc_set_wss(struct omap_dss_device *dssdev, u32 wss)
return r;
}

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_set_timings,
.check_timings = venc_check_timings,

.get_wss = venc_get_wss,
.set_wss = venc_set_wss,

.driver = {
.name = "venc",
.owner = THIS_MODULE,
},
};
/* driver end */

static int __init venc_init_display(struct omap_dss_device *dssdev)
{
DSSDBG("init_display\n");
Expand Down Expand Up @@ -897,17 +795,17 @@ static int __init omap_venchw_probe(struct platform_device *pdev)

venc_runtime_put();

r = omap_dss_register_driver(&venc_driver);
r = venc_panel_init();
if (r)
goto err_reg_panel_driver;
goto err_panel_init;

dss_debugfs_create_file("venc", venc_dump_regs);

venc_probe_pdata(pdev);

return 0;

err_reg_panel_driver:
err_panel_init:
err_runtime_get:
pm_runtime_disable(&pdev->dev);
venc_put_clocks();
Expand All @@ -923,7 +821,7 @@ static int __exit omap_venchw_remove(struct platform_device *pdev)
venc.vdda_dac_reg = NULL;
}

omap_dss_unregister_driver(&venc_driver);
venc_panel_exit();

pm_runtime_disable(&pdev->dev);
venc_put_clocks();
Expand Down
Loading

0 comments on commit 156fd99

Please sign in to comment.