diff options
| author | Shashank Mittal <mittals@codeaurora.org> | 2015-05-11 14:57:24 -0700 |
|---|---|---|
| committer | Jeevan Shriram <jshriram@codeaurora.org> | 2016-05-16 20:10:36 -0700 |
| commit | c5d78d4e6e6eb40903ecdf799470715a2813ee51 (patch) | |
| tree | bb3e4eabfc7ae53711908ddd02bb04d64a40a54d /drivers/soc | |
| parent | d3d5065b82d5ca7502f4c11f4794938aed4bd4e1 (diff) | |
soc: qcom: dcc: add support for CRC mode
In CRC mode DCC can perform CRC on configuration data or system memory
after receiving SW or HW trigger.
Change-Id: Iab0a6ffa92ef6e311054756cfe85d1b2b91743c9
Signed-off-by: Shashank Mittal <mittals@codeaurora.org>
Diffstat (limited to 'drivers/soc')
| -rw-r--r-- | drivers/soc/qcom/dcc.c | 60 |
1 files changed, 59 insertions, 1 deletions
diff --git a/drivers/soc/qcom/dcc.c b/drivers/soc/qcom/dcc.c index e02cf7dc77d2..b4a3536361a3 100644 --- a/drivers/soc/qcom/dcc.c +++ b/drivers/soc/qcom/dcc.c @@ -97,6 +97,7 @@ struct dcc_drvdata { enum dcc_func_type func_type; uint32_t ram_cfg; bool enable; + bool interrupt_disable; char *sram_node; struct cdev sram_dev; struct class *sram_class; @@ -281,6 +282,25 @@ static void __dcc_reg_dump(struct dcc_drvdata *drvdata) drvdata->reg_data.magic = DCC_REG_DUMP_MAGIC_V2; } +static void __dcc_first_crc(struct dcc_drvdata *drvdata) +{ + int i; + + /* + * Need to send 2 triggers to DCC. First trigger sets CRC error status + * bit. So need second trigger to reset this bit. + */ + for (i = 0; i < 2; i++) { + if (!dcc_ready(drvdata)) + dev_err(drvdata->dev, "DCC is not ready!\n"); + + dcc_writel(drvdata, 1, DCC_SW_CTL); + } + + /* Clear CRC error interrupt */ + dcc_writel(drvdata, BIT(0), DCC_INT_STATUS); +} + static int dcc_enable(struct dcc_drvdata *drvdata) { int ret = 0; @@ -314,7 +334,8 @@ static int dcc_enable(struct dcc_drvdata *drvdata) DCC_CFG); /* 5. Clears interrupt status register */ - dcc_writel(drvdata, 0, DCC_INT_STATUS); + dcc_writel(drvdata, 0, DCC_INT_ENABLE); + dcc_writel(drvdata, (BIT(4) | BIT(0)), DCC_INT_STATUS); /* Make sure all config is written in sram */ mb(); @@ -323,6 +344,14 @@ static int dcc_enable(struct dcc_drvdata *drvdata) dcc_writel(drvdata, 1, DCC_LL); drvdata->enable = 1; + if (drvdata->func_type == DCC_FUNC_TYPE_CRC) { + __dcc_first_crc(drvdata); + + /* Enable CRC error interrupt */ + if (!drvdata->interrupt_disable) + dcc_writel(drvdata, BIT(0), DCC_INT_ENABLE); + } + /* Save DCC registers */ if (drvdata->save_reg) __dcc_reg_dump(drvdata); @@ -670,6 +699,34 @@ err: } static DEVICE_ATTR(ready, S_IRUGO, dcc_show_ready, NULL); +static ssize_t dcc_show_interrupt_disable(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct dcc_drvdata *drvdata = dev_get_drvdata(dev); + + return scnprintf(buf, PAGE_SIZE, "%u\n", + (unsigned)drvdata->interrupt_disable); +} + +static ssize_t dcc_store_interrupt_disable(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + unsigned long val; + struct dcc_drvdata *drvdata = dev_get_drvdata(dev); + + if (kstrtoul(buf, 16, &val)) + return -EINVAL; + + mutex_lock(&drvdata->mutex); + drvdata->interrupt_disable = (val ? 1:0); + mutex_unlock(&drvdata->mutex); + return size; +} +static DEVICE_ATTR(interrupt_disable, S_IRUGO | S_IWUSR, + dcc_show_interrupt_disable, dcc_store_interrupt_disable); + static const struct device_attribute *dcc_attrs[] = { &dev_attr_func_type, &dev_attr_data_sink, @@ -679,6 +736,7 @@ static const struct device_attribute *dcc_attrs[] = { &dev_attr_config_reset, &dev_attr_ready, &dev_attr_crc_error, + &dev_attr_interrupt_disable, NULL, }; |
