diff options
author | Kevin Huang <kevinh@nvidia.com> | 2011-07-08 14:01:43 -0700 |
---|---|---|
committer | Varun Colbert <vcolbert@nvidia.com> | 2011-07-14 12:36:40 -0700 |
commit | bd2851636f71599498952db09c81a26d9e378da4 (patch) | |
tree | 39400de9ecced5c038758a96fc16a9ab837bc28a /drivers | |
parent | 4fed98b3fc71c5756845ad32b07b2129d049bf02 (diff) |
tegra: video: dc: Add sys interface to read display CRC.
- Add attribute in sys to read TEGRA_DC_CRC_CHECKSUM_LATCHED
- Fix some minor formatting issue of dc_sysfs.c
Bug 834332
Change-Id: I48f75fcb1d5403ab40d0da438200a5552ba4e6ff
Reviewed-on: http://git-master/r/37912
Reviewed-by: Varun Colbert <vcolbert@nvidia.com>
Tested-by: Varun Colbert <vcolbert@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/video/tegra/dc/dc.c | 42 | ||||
-rw-r--r-- | drivers/video/tegra/dc/dc_priv.h | 5 | ||||
-rw-r--r-- | drivers/video/tegra/dc/dc_reg.h | 8 | ||||
-rw-r--r-- | drivers/video/tegra/dc/dc_sysfs.c | 63 |
4 files changed, 109 insertions, 9 deletions
diff --git a/drivers/video/tegra/dc/dc.c b/drivers/video/tegra/dc/dc.c index 5560505fca4f..aa99dce17e0b 100644 --- a/drivers/video/tegra/dc/dc.c +++ b/drivers/video/tegra/dc/dc.c @@ -46,6 +46,8 @@ #include "overlay.h" #include "nvsd.h" +#define TEGRA_CRC_LATCHED_DELAY 34 + static int no_vsync; module_param_named(no_vsync, no_vsync, int, S_IRUGO | S_IWUSR); @@ -1554,6 +1556,46 @@ unsigned tegra_dc_get_out_max_pixclock(const struct tegra_dc *dc) } EXPORT_SYMBOL(tegra_dc_get_out_max_pixclock); +void tegra_dc_enable_crc(struct tegra_dc *dc) +{ + u32 val; + tegra_dc_io_start(dc); + + val = CRC_ALWAYS_ENABLE | CRC_INPUT_DATA_ACTIVE_DATA | + CRC_ENABLE_ENABLE; + tegra_dc_writel(dc, val, DC_COM_CRC_CONTROL); + tegra_dc_writel(dc, GENERAL_UPDATE, DC_CMD_STATE_CONTROL); + tegra_dc_writel(dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL); +} + +void tegra_dc_disable_crc(struct tegra_dc *dc) +{ + tegra_dc_writel(dc, 0x0, DC_COM_CRC_CONTROL); + tegra_dc_writel(dc, GENERAL_UPDATE, DC_CMD_STATE_CONTROL); + tegra_dc_writel(dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL); + + tegra_dc_io_end(dc); +} + +u32 tegra_dc_read_checksum_latched(struct tegra_dc *dc) +{ + int crc = 0; + u32 val = 0; + + if(!dc) { + dev_err(&dc->ndev->dev, "Failed to get dc.\n"); + goto crc_error; + } + + /* TODO: Replace mdelay with code to sync VBlANK, since + * DC_COM_CRC_CHECKSUM_LATCHED is available after VBLANK */ + mdelay(TEGRA_CRC_LATCHED_DELAY); + + crc = tegra_dc_readl(dc, DC_COM_CRC_CHECKSUM_LATCHED); +crc_error: + return crc; +} + static void tegra_dc_vblank(struct work_struct *work) { struct tegra_dc *dc = container_of(work, struct tegra_dc, vblank_work); diff --git a/drivers/video/tegra/dc/dc_priv.h b/drivers/video/tegra/dc/dc_priv.h index 6a89b09dd4e8..1df5299dafbc 100644 --- a/drivers/video/tegra/dc/dc_priv.h +++ b/drivers/video/tegra/dc/dc_priv.h @@ -207,5 +207,10 @@ void tegra_dc_create_sysfs(struct device *dev); /* defined in dc.c, used by dc_sysfs.c */ void tegra_dc_stats_enable(struct tegra_dc *dc, bool enable); bool tegra_dc_stats_get(struct tegra_dc *dc); + +/* defined in dc.c, used by dc_sysfs.c */ +u32 tegra_dc_read_checksum_latched(struct tegra_dc *dc); +void tegra_dc_enable_crc(struct tegra_dc *dc); +void tegra_dc_disable_crc(struct tegra_dc *dc); #endif diff --git a/drivers/video/tegra/dc/dc_reg.h b/drivers/video/tegra/dc/dc_reg.h index a736bc5a1ac5..4419fb514781 100644 --- a/drivers/video/tegra/dc/dc_reg.h +++ b/drivers/video/tegra/dc/dc_reg.h @@ -113,6 +113,14 @@ #define DC_CMD_REG_ACT_CONTROL 0x043 #define DC_COM_CRC_CONTROL 0x300 +#define CRC_ALWAYS_ENABLE (1 << 3) +#define CRC_ALWAYS_DISABLE (0 << 3) +#define CRC_INPUT_DATA_ACTIVE_DATA (1 << 2) +#define CRC_INPUT_DATA_FULL_FRAME (0 << 2) +#define CRC_WAIT_TWO_VSYNC (1 << 1) +#define CRC_WAIT_ONE_VSYNC (0 << 1) +#define CRC_ENABLE_ENABLE (1 << 0) +#define CRC_ENABLE_DISABLE (0 << 0) #define DC_COM_CRC_CHECKSUM 0x301 #define DC_COM_PIN_OUTPUT_ENABLE0 0x302 #define DC_COM_PIN_OUTPUT_ENABLE1 0x303 diff --git a/drivers/video/tegra/dc/dc_sysfs.c b/drivers/video/tegra/dc/dc_sysfs.c index 184353d43324..36294c60907f 100644 --- a/drivers/video/tegra/dc/dc_sysfs.c +++ b/drivers/video/tegra/dc/dc_sysfs.c @@ -124,6 +124,53 @@ static ssize_t enable_store(struct device *dev, static DEVICE_ATTR(enable, S_IRUGO|S_IWUSR, enable_show, enable_store); +static ssize_t crc_checksum_latched_show(struct device *device, + struct device_attribute *attr, char *buf) +{ + struct nvhost_device *ndev = to_nvhost_device(device); + struct tegra_dc *dc = nvhost_get_drvdata(ndev); + + u32 crc; + + if (!dc->enabled) { + dev_err(&dc->ndev->dev, "Failed to get dc.\n"); + return -EFAULT; + } + + crc = tegra_dc_read_checksum_latched(dc); + + return snprintf(buf, PAGE_SIZE, "%u", crc); +} + +static ssize_t crc_checksum_latched_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct nvhost_device *ndev = to_nvhost_device(dev); + struct tegra_dc *dc = nvhost_get_drvdata(ndev); + unsigned long val = 0; + + if (!dc->enabled) { + dev_err(&dc->ndev->dev, "Failed to get dc.\n"); + return -EFAULT; + } + + if (strict_strtoul(buf, 10, &val) < 0) + return -EINVAL; + + if (val == 1) { + tegra_dc_enable_crc(dc); + dev_err(&dc->ndev->dev, "crc is enabled.\n"); + } else if (val == 0) { + tegra_dc_disable_crc(dc); + dev_err(&dc->ndev->dev, "crc is disabled.\n"); + } else + dev_err(&dc->ndev->dev, "Invalid input.\n"); + + return count; +} +static DEVICE_ATTR(crc_checksum_latched, S_IRUGO|S_IWUSR|S_IWGRP, + crc_checksum_latched_show, crc_checksum_latched_store); + #define ORIENTATION_PORTRAIT "portrait" #define ORIENTATION_LANDSCAPE "landscape" @@ -235,18 +282,18 @@ void __devexit tegra_dc_remove_sysfs(struct device *dev) struct tegra_dc *dc = nvhost_get_drvdata(ndev); struct tegra_dc_sd_settings *sd_settings = dc->out->sd_settings; - device_remove_file(dev, &dev_attr_stats_enable); device_remove_file(dev, &dev_attr_mode); device_remove_file(dev, &dev_attr_enable); + device_remove_file(dev, &dev_attr_stats_enable); + device_remove_file(dev, &dev_attr_crc_checksum_latched); if (dc->out->stereo) { device_remove_file(dev, &dev_attr_stereo_orientation); device_remove_file(dev, &dev_attr_stereo_mode); } - if(sd_settings) { + if (sd_settings) nvsd_remove_sysfs(dev); - } } void tegra_dc_create_sysfs(struct device *dev) @@ -259,18 +306,16 @@ void tegra_dc_create_sysfs(struct device *dev) error |= device_create_file(dev, &dev_attr_mode); error |= device_create_file(dev, &dev_attr_enable); error |= device_create_file(dev, &dev_attr_stats_enable); + error |= device_create_file(dev, &dev_attr_crc_checksum_latched); if (dc->out->stereo) { error |= device_create_file(dev, &dev_attr_stereo_orientation); error |= device_create_file(dev, &dev_attr_stereo_mode); } - if(sd_settings) { + if (sd_settings) error |= nvsd_create_sysfs(dev); - } - if(error) { - printk("Failed to create sysfs attributes!\n"); - } + if (error) + dev_err(&ndev->dev, "Failed to create sysfs attributes!\n"); } - |