[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <79ca9bbfb988445fda98ec23f4a63c562b07d04b.1675054375.git.quic_schowdhu@quicinc.com>
Date: Mon, 30 Jan 2023 10:43:56 +0530
From: Souradeep Chowdhury <quic_schowdhu@...cinc.com>
To: Andy Gross <agross@...nel.org>,
Konrad Dybcio <konrad.dybcio@...ainline.org>,
Bjorn Andersson <andersson@...nel.org>,
"Alex Elder" <elder@...e.org>
CC: <linux-arm-kernel@...ts.infradead.org>,
<linux-kernel@...r.kernel.org>, <linux-arm-msm@...r.kernel.org>,
Sai Prakash Ranjan <quic_saipraka@...cinc.com>,
Sibi Sankar <quic_sibis@...cinc.com>,
"Rajendra Nayak" <quic_rjendra@...cinc.com>, <vkoul@...nel.org>,
Souradeep Chowdhury <quic_schowdhu@...cinc.com>
Subject: [PATCH V3 2/3] soc: qcom: dcc: Add CTI-trigger support for DCC
CTI trigger is used to enable the Cross trigger interface for DCC.
On enabling CTI trigger the dcc software trigger can be done by
writing to CTI trig-out. Add the debugfs file ctitrigger which
gives the user option to enable ctitrigger for a list. Also add
hwtrigger debugfs file which needs to be disabled on enabling
the CTI-trigger. Hwtrigger needs to be disabled for components
to be able to write to cti-trigout.
Signed-off-by: Souradeep Chowdhury <quic_schowdhu@...cinc.com>
---
Documentation/ABI/testing/debugfs-driver-dcc | 16 +++
drivers/soc/qcom/dcc.c | 148 ++++++++++++++++++++++++++-
2 files changed, 160 insertions(+), 4 deletions(-)
diff --git a/Documentation/ABI/testing/debugfs-driver-dcc b/Documentation/ABI/testing/debugfs-driver-dcc
index 27ed591..6f5d965 100644
--- a/Documentation/ABI/testing/debugfs-driver-dcc
+++ b/Documentation/ABI/testing/debugfs-driver-dcc
@@ -125,3 +125,19 @@ Description:
on manual or crash induced triggers. Lists must
be configured and enabled sequentially, e.g. list
2 can only be enabled when list 1 have so.
+
+What: /sys/kernel/debug/dcc/.../[list-number]/ctitrigger
+Date: January 2023
+Contact: Souradeep Chowdhury <quic_schowdhu@...cinc.com>
+Description:
+ This debugfs interface is used for enabling the
+ ctitrigger. Ctitrigger can be enabled by writing
+ a '1' to the file.
+
+What: /sys/kernel/debug/dcc/.../[list-number]/hwtrigger
+Date: January 2023
+Contact: Souradeep Chowdhury <quic_schowdhu@...cinc.com>
+Description:
+ This debugfs interface is used for enabling the
+ hwtrigger. Hwtrigger can be enabled by writing
+ a '1' to the file.
diff --git a/drivers/soc/qcom/dcc.c b/drivers/soc/qcom/dcc.c
index 93e8f86..a75b9af 100644
--- a/drivers/soc/qcom/dcc.c
+++ b/drivers/soc/qcom/dcc.c
@@ -37,6 +37,7 @@
#define DCC_LL_INT_STATUS 0x1c
#define DCC_LL_SW_TRIGGER 0x2c
#define DCC_LL_BUS_ACCESS_STATUS 0x30
+#define DCC_CTI_TRIG 0x34
/* Default value used if a bit 6 in the HW_INFO register is set. */
#define DCC_FIX_LOOP_OFFSET 16
@@ -115,6 +116,8 @@ struct dcc_config_entry {
* @nr_link_list: Total number of linkedlists supported by the DCC configuration
* @loop_shift: Loop offset bits range for the addresses
* @enable_bitmap: Bitmap to capture the enabled status of each linked list of addresses
+ * @cti_bitmap: Bitmap to capture the cti-trigger status of each linked list of addresses
+ * @hwtrig_bitmap: Bitmap to capture the hwtrig status of each linked list of addresses
*/
struct dcc_drvdata {
void __iomem *base;
@@ -132,6 +135,8 @@ struct dcc_drvdata {
size_t nr_link_list;
u8 loop_shift;
unsigned long *enable_bitmap;
+ unsigned long *cti_bitmap;
+ unsigned long *hwtrig_bitmap;
};
struct dcc_cfg_attr {
@@ -213,7 +218,10 @@ static int dcc_sw_trigger(struct dcc_drvdata *drvdata)
if (!test_bit(i, drvdata->enable_bitmap))
continue;
ll_cfg = dcc_list_readl(drvdata, i, DCC_LL_CFG);
- tmp_ll_cfg = ll_cfg & ~DCC_TRIGGER_MASK;
+ if (drvdata->mem_map_ver != 3)
+ tmp_ll_cfg = ll_cfg & ~DCC_TRIGGER_MASK;
+ else
+ tmp_ll_cfg = ll_cfg & ~BIT(8);
dcc_list_writel(drvdata, tmp_ll_cfg, i, DCC_LL_CFG);
dcc_list_writel(drvdata, 1, i, DCC_LL_SW_TRIGGER);
dcc_list_writel(drvdata, ll_cfg, i, DCC_LL_CFG);
@@ -590,6 +598,23 @@ static int dcc_enable(struct dcc_drvdata *drvdata, unsigned int curr_list)
/* 5. Configure trigger */
dcc_list_writel(drvdata, DCC_TRIGGER_MASK,
curr_list, DCC_LL_CFG);
+ if (drvdata->mem_map_ver == 3) {
+ dcc_list_writel(drvdata, test_bit(curr_list, drvdata->cti_bitmap), curr_list,
+ DCC_CTI_TRIG);
+ if (test_bit(curr_list, drvdata->hwtrig_bitmap))
+ dcc_list_writel(drvdata, BIT(8), curr_list, DCC_LL_CFG);
+ else
+ dcc_list_writel(drvdata, (unsigned int)~BIT(8), curr_list, DCC_LL_CFG);
+ } else {
+ if (test_bit(curr_list, drvdata->hwtrig_bitmap))
+ dcc_list_writel(drvdata, DCC_TRIGGER_MASK |
+ test_bit(curr_list, drvdata->cti_bitmap) << 8,
+ curr_list, DCC_LL_CFG);
+ else
+ dcc_list_writel(drvdata, ~DCC_TRIGGER_MASK &
+ test_bit(curr_list, drvdata->cti_bitmap) << 8,
+ curr_list, DCC_LL_CFG);
+ }
out_unlock:
mutex_unlock(&drvdata->mutex);
@@ -1116,6 +1141,110 @@ static const struct file_operations config_fops = {
.release = single_release,
};
+static ssize_t ctitrigger_read(struct file *filp, char __user *userbuf,
+ size_t count, loff_t *ppos)
+{
+ char *buf;
+ int curr_list;
+ struct dcc_drvdata *drvdata = filp->private_data;
+
+ curr_list = dcc_filp_curr_list(filp);
+
+ mutex_lock(&drvdata->mutex);
+
+ if (test_bit(curr_list, drvdata->cti_bitmap))
+ buf = "Y\n";
+ else
+ buf = "N\n";
+
+ mutex_unlock(&drvdata->mutex);
+
+ return simple_read_from_buffer(userbuf, count, ppos, buf, strlen(buf));
+}
+
+static ssize_t ctitrigger_write(struct file *filp, const char __user *userbuf,
+ size_t count, loff_t *ppos)
+{
+ int ret, curr_list;
+ bool val;
+ struct dcc_drvdata *drvdata = filp->private_data;
+
+ curr_list = dcc_filp_curr_list(filp);
+
+ if (test_bit(curr_list, drvdata->enable_bitmap))
+ return -EBUSY;
+
+ ret = kstrtobool_from_user(userbuf, count, &val);
+ if (ret < 0)
+ return ret;
+
+ if (val)
+ set_bit(curr_list, drvdata->cti_bitmap);
+ else
+ clear_bit(curr_list, drvdata->cti_bitmap);
+
+ return count;
+}
+
+static const struct file_operations ctitrigger_fops = {
+ .read = ctitrigger_read,
+ .write = ctitrigger_write,
+ .open = simple_open,
+ .llseek = generic_file_llseek,
+};
+
+static ssize_t hwtrigger_read(struct file *filp, char __user *userbuf,
+ size_t count, loff_t *ppos)
+{
+ char *buf;
+ int curr_list;
+ struct dcc_drvdata *drvdata = filp->private_data;
+
+ curr_list = dcc_filp_curr_list(filp);
+
+ mutex_lock(&drvdata->mutex);
+
+ if (test_bit(curr_list, drvdata->hwtrig_bitmap))
+ buf = "Y\n";
+ else
+ buf = "N\n";
+
+ mutex_unlock(&drvdata->mutex);
+
+ return simple_read_from_buffer(userbuf, count, ppos, buf, strlen(buf));
+}
+
+static ssize_t hwtrigger_write(struct file *filp, const char __user *userbuf,
+ size_t count, loff_t *ppos)
+{
+ int ret, curr_list;
+ bool val;
+ struct dcc_drvdata *drvdata = filp->private_data;
+
+ curr_list = dcc_filp_curr_list(filp);
+
+ if (test_bit(curr_list, drvdata->enable_bitmap))
+ return -EBUSY;
+
+ ret = kstrtobool_from_user(userbuf, count, &val);
+ if (ret < 0)
+ return ret;
+
+ if (val)
+ set_bit(curr_list, drvdata->hwtrig_bitmap);
+ else
+ clear_bit(curr_list, drvdata->hwtrig_bitmap);
+
+ return count;
+}
+
+static const struct file_operations hwtrigger_fops = {
+ .read = hwtrigger_read,
+ .write = hwtrigger_write,
+ .open = simple_open,
+ .llseek = generic_file_llseek,
+};
+
static void dcc_delete_debug_dir(struct dcc_drvdata *drvdata)
{
debugfs_remove_recursive(drvdata->dbg_dir);
@@ -1145,6 +1274,8 @@ static void dcc_create_debug_dir(struct dcc_drvdata *drvdata)
debugfs_create_file("ready", 0400, drvdata->dbg_dir, drvdata, &ready_fops);
debugfs_create_file("config_reset", 0200, drvdata->dbg_dir,
drvdata, &config_reset_fops);
+ debugfs_create_file("ctitrigger", 0600, list, drvdata, &ctitrigger_fops);
+ debugfs_create_file("hwtrigger", 0600, list, drvdata, &hwtrigger_fops);
}
static ssize_t dcc_sram_read(struct file *file, char __user *data,
@@ -1304,18 +1435,27 @@ static int __init dcc_probe(struct platform_device *pdev)
mutex_init(&drvdata->mutex);
- drvdata->enable_bitmap = devm_kcalloc(dev, BITS_TO_LONGS(drvdata->nr_link_list),
- sizeof(*drvdata->enable_bitmap), GFP_KERNEL);
+ drvdata->enable_bitmap = devm_bitmap_alloc(dev, drvdata->nr_link_list, GFP_KERNEL);
if (!drvdata->enable_bitmap)
return -ENOMEM;
+ drvdata->cti_bitmap = devm_bitmap_alloc(dev, drvdata->nr_link_list, GFP_KERNEL);
+ if (!drvdata->cti_bitmap)
+ return -ENOMEM;
+
+ drvdata->hwtrig_bitmap = devm_bitmap_alloc(dev, drvdata->nr_link_list, GFP_KERNEL);
+ if (!drvdata->hwtrig_bitmap)
+ return -ENOMEM;
+
drvdata->cfg_head = devm_kcalloc(dev, drvdata->nr_link_list,
sizeof(*drvdata->cfg_head), GFP_KERNEL);
if (!drvdata->cfg_head)
return -ENOMEM;
- for (i = 0; i < drvdata->nr_link_list; i++)
+ for (i = 0; i < drvdata->nr_link_list; i++) {
INIT_LIST_HEAD(&drvdata->cfg_head[i]);
+ set_bit(i, drvdata->hwtrig_bitmap);
+ }
ret = dcc_sram_dev_init(drvdata);
if (ret) {
--
2.7.4
Powered by blists - more mailing lists