summaryrefslogtreecommitdiff
path: root/drivers/video/tegra/dc
diff options
context:
space:
mode:
authorKevin Huang <kevinh@nvidia.com>2011-07-08 14:01:43 -0700
committerDan Willemsen <dwillemsen@nvidia.com>2011-11-30 21:47:39 -0800
commita6ea24cb910bed2dfa68376c22b8b176a3979881 (patch)
treea6cb0ba8b86a0a15191f9b0f08ba9b6e281f124d /drivers/video/tegra/dc
parent37ff98089370ef8b4b077c0ab32791de4d2df690 (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 Original-Change-Id: I48f75fcb1d5403ab40d0da438200a5552ba4e6ff Reviewed-on: http://git-master/r/37912 Reviewed-by: Varun Colbert <vcolbert@nvidia.com> Tested-by: Varun Colbert <vcolbert@nvidia.com> Rebase-Id: Rde819259112b14ed1ae67b41d66b1785d68a2b7f
Diffstat (limited to 'drivers/video/tegra/dc')
-rw-r--r--drivers/video/tegra/dc/dc.c42
-rw-r--r--drivers/video/tegra/dc/dc_priv.h5
-rw-r--r--drivers/video/tegra/dc/dc_reg.h8
-rw-r--r--drivers/video/tegra/dc/dc_sysfs.c63
4 files changed, 109 insertions, 9 deletions
diff --git a/drivers/video/tegra/dc/dc.c b/drivers/video/tegra/dc/dc.c
index b6844f5acab2..7457286c9a81 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);
@@ -1551,6 +1553,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 f3b585eb7f11..efc2b972a342 100644
--- a/drivers/video/tegra/dc/dc_priv.h
+++ b/drivers/video/tegra/dc/dc_priv.h
@@ -204,5 +204,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");
}
-