* [PATCH 0/3] QCOM QUP I2C - Add noise rejection, convert to YAML
@ 2021-01-13 18:25 AngeloGioacchino Del Regno
2021-01-13 18:25 ` [PATCH 1/3] dt-bindings: i2c: qcom,i2c-qup: Convert txt to YAML schema AngeloGioacchino Del Regno
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: AngeloGioacchino Del Regno @ 2021-01-13 18:25 UTC (permalink / raw)
To: agross
Cc: linux-kernel, konrad.dybcio, marijn.suijten, martin.botka,
bjorn.andersson, robh+dt, devicetree, linux-arm-msm, linux-i2c,
AngeloGioacchino Del Regno
This patch series converts the i2c-qup bindings to YAML and then
adds support for noise rejection, which is needed for some noisy
hardware, like the touchscreen on the F(x)Tec Pro1.
After adding noise rejection, the touchscreen stopped showing
ghost touch issues and lockups.
Tested on F(x)Tec Pro1 (MSM8998)
AngeloGioacchino Del Regno (3):
dt-bindings: i2c: qcom,i2c-qup: Convert txt to YAML schema
i2c: qup: Introduce SCL/SDA noise rejection
dt-bindings: i2c: qcom,i2c-qup: Document noise rejection properties
.../devicetree/bindings/i2c/qcom,i2c-qup.txt | 40 -------
.../devicetree/bindings/i2c/qcom,i2c-qup.yaml | 101 ++++++++++++++++++
drivers/i2c/busses/i2c-qup.c | 16 +++
3 files changed, 117 insertions(+), 40 deletions(-)
delete mode 100644 Documentation/devicetree/bindings/i2c/qcom,i2c-qup.txt
create mode 100644 Documentation/devicetree/bindings/i2c/qcom,i2c-qup.yaml
--
2.29.2
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/3] dt-bindings: i2c: qcom,i2c-qup: Convert txt to YAML schema
2021-01-13 18:25 [PATCH 0/3] QCOM QUP I2C - Add noise rejection, convert to YAML AngeloGioacchino Del Regno
@ 2021-01-13 18:25 ` AngeloGioacchino Del Regno
2021-01-13 18:25 ` [PATCH 2/3] i2c: qup: Introduce SCL/SDA noise rejection AngeloGioacchino Del Regno
2021-01-13 18:25 ` [PATCH 3/3] dt-bindings: i2c: qcom,i2c-qup: Document noise rejection properties AngeloGioacchino Del Regno
2 siblings, 0 replies; 6+ messages in thread
From: AngeloGioacchino Del Regno @ 2021-01-13 18:25 UTC (permalink / raw)
To: agross
Cc: linux-kernel, konrad.dybcio, marijn.suijten, martin.botka,
bjorn.andersson, robh+dt, devicetree, linux-arm-msm, linux-i2c,
AngeloGioacchino Del Regno
Convert the qcom,i2c-qup binding to YAML schema.
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
---
.../devicetree/bindings/i2c/qcom,i2c-qup.txt | 40 ---------
.../devicetree/bindings/i2c/qcom,i2c-qup.yaml | 87 +++++++++++++++++++
2 files changed, 87 insertions(+), 40 deletions(-)
delete mode 100644 Documentation/devicetree/bindings/i2c/qcom,i2c-qup.txt
create mode 100644 Documentation/devicetree/bindings/i2c/qcom,i2c-qup.yaml
diff --git a/Documentation/devicetree/bindings/i2c/qcom,i2c-qup.txt b/Documentation/devicetree/bindings/i2c/qcom,i2c-qup.txt
deleted file mode 100644
index dc71754a56af..000000000000
--- a/Documentation/devicetree/bindings/i2c/qcom,i2c-qup.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-Qualcomm Universal Peripheral (QUP) I2C controller
-
-Required properties:
- - compatible: Should be:
- * "qcom,i2c-qup-v1.1.1" for 8660, 8960 and 8064.
- * "qcom,i2c-qup-v2.1.1" for 8974 v1.
- * "qcom,i2c-qup-v2.2.1" for 8974 v2 and later.
- - reg: Should contain QUP register address and length.
- - interrupts: Should contain I2C interrupt.
-
- - clocks: A list of phandles + clock-specifiers, one for each entry in
- clock-names.
- - clock-names: Should contain:
- * "core" for the core clock
- * "iface" for the AHB clock
-
- - #address-cells: Should be <1> Address cells for i2c device address
- - #size-cells: Should be <0> as i2c addresses have no size component
-
-Optional properties:
- - clock-frequency: Should specify the desired i2c bus clock frequency in Hz,
- defaults to 100kHz if omitted.
-
-Child nodes should conform to i2c bus binding.
-
-Example:
-
- i2c@f9924000 {
- compatible = "qcom,i2c-qup-v2.2.1";
- reg = <0xf9924000 0x1000>;
- interrupts = <0 96 0>;
-
- clocks = <&gcc GCC_BLSP1_QUP2_I2C_APPS_CLK>, <&gcc GCC_BLSP1_AHB_CLK>;
- clock-names = "core", "iface";
-
- clock-frequency = <355000>;
-
- #address-cells = <1>;
- #size-cells = <0>;
- };
diff --git a/Documentation/devicetree/bindings/i2c/qcom,i2c-qup.yaml b/Documentation/devicetree/bindings/i2c/qcom,i2c-qup.yaml
new file mode 100644
index 000000000000..c5c7db3ac2a6
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/qcom,i2c-qup.yaml
@@ -0,0 +1,87 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+
+$id: http://devicetree.org/schemas/i2c/qcom,i2c-qup.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Universal Peripheral (QUP) I2C controller
+
+maintainers:
+ - Andy Gross <agross@kernel.org>
+ - Bjorn Andersson <bjorn.andersson@linaro.org>
+
+description: Binding for Qualcomm "QUP" I2C controllers
+
+allOf:
+ - $ref: /schemas/i2c/i2c-controller.yaml#
+
+properties:
+ compatible:
+ enum:
+ - qcom,i2c-qup-v1.1.1
+ - qcom,i2c-qup-v2.1.1
+ - qcom,i2c-qup-v2.2.1
+
+ reg:
+ items:
+ - description: QUP I2C register iospace
+
+ clocks:
+ items:
+ - description: Core QUP I2C clock
+ - description: AHB clock
+
+ clock-names:
+ items:
+ - const: core
+ - const: iface
+
+ clock-frequency:
+ minimum: 100000
+ maximum: 1000000
+ default: 100000
+
+ dmas:
+ items:
+ - description: RX DMA Channel phandle
+ - description: TX DMA Channel phandle
+
+ dma-names:
+ items:
+ - const: rx
+ - const: tx
+
+ '#address-cells':
+ const: 1
+
+ '#size-cells':
+ const: 0
+
+required:
+ - compatible
+ - clocks
+ - clock-names
+ - reg
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/qcom,gcc-msm8998.h>
+ #include <dt-bindings/gpio/gpio.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+ i2c@c175000 {
+ compatible = "qcom,i2c-qup-v2.2.1";
+ reg = <0x0c175000 0x600>;
+ interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&gcc GCC_BLSP1_QUP1_I2C_APPS_CLK>,
+ <&gcc GCC_BLSP1_AHB_CLK>;
+ clock-names = "core", "iface";
+ clock-frequency = <400000>;
+ dmas = <&blsp_dma 4>, <&blsp_dma 5>;
+ dma-names = "rx", "tx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
--
2.29.2
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/3] i2c: qup: Introduce SCL/SDA noise rejection
2021-01-13 18:25 [PATCH 0/3] QCOM QUP I2C - Add noise rejection, convert to YAML AngeloGioacchino Del Regno
2021-01-13 18:25 ` [PATCH 1/3] dt-bindings: i2c: qcom,i2c-qup: Convert txt to YAML schema AngeloGioacchino Del Regno
@ 2021-01-13 18:25 ` AngeloGioacchino Del Regno
2021-01-14 3:57 ` kernel test robot
2021-01-13 18:25 ` [PATCH 3/3] dt-bindings: i2c: qcom,i2c-qup: Document noise rejection properties AngeloGioacchino Del Regno
2 siblings, 1 reply; 6+ messages in thread
From: AngeloGioacchino Del Regno @ 2021-01-13 18:25 UTC (permalink / raw)
To: agross
Cc: linux-kernel, konrad.dybcio, marijn.suijten, martin.botka,
bjorn.andersson, robh+dt, devicetree, linux-arm-msm, linux-i2c,
AngeloGioacchino Del Regno
Some I2C devices may be glitchy due to electrical noise coming
from the device itself or because of possible board design issues.
To overcome this issue, the QUP's I2C in Qualcomm SoCs supports
a noise rejection setting for both SCL and SDA lines.
Introduce a setting for noise rejection through device properties,
"qcom,noise-reject-sda" and "qcom,noise-reject-scl", which will
be used to set the level of noise rejection sensitivity.
If the properties are not specified, noise rejection will not be
enabled.
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
---
drivers/i2c/busses/i2c-qup.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c
index 5a47915869ae..35cc47f010e3 100644
--- a/drivers/i2c/busses/i2c-qup.c
+++ b/drivers/i2c/busses/i2c-qup.c
@@ -39,6 +39,8 @@
#define QUP_MX_READ_CNT 0x208
#define QUP_IN_FIFO_BASE 0x218
#define QUP_I2C_CLK_CTL 0x400
+#define QUP_I2C_CLK_CTL_SDA_NR GENMASK(27, 26)
+#define QUP_I2C_CLK_CTL_SCL_NR GENMASK(25, 24)
#define QUP_I2C_STATUS 0x404
#define QUP_I2C_MASTER_GEN 0x408
@@ -1663,6 +1665,7 @@ static int qup_i2c_probe(struct platform_device *pdev)
int ret, fs_div, hs_div;
u32 src_clk_freq = DEFAULT_SRC_CLK;
u32 clk_freq = DEFAULT_CLK_FREQ;
+ u32 noise_reject_scl = 0, noise_reject_sda = 0;
int blocks;
bool is_qup_v1;
@@ -1860,6 +1863,19 @@ static int qup_i2c_probe(struct platform_device *pdev)
qup->clk_ctl = ((fs_div / 2) << 16) | (hs_div << 8) | (fs_div & 0xff);
}
+ /* SCL/SDA Noise rejection (optional) */
+ ret = device_property_read_u32(qup->dev, "qcom,noise-reject-scl",
+ &noise_reject_scl);
+ if (ret == 0)
+ qup->clk_ctl |= FIELD_PREP(QUP_I2C_CLK_CTL_SCL_NR,
+ noise_reject_scl);
+
+ ret = device_property_read_u32(qup->dev, "qcom,noise-reject-sda",
+ &noise_reject_sda);
+ if (ret == 0)
+ qup->clk_ctl |= FIELD_PREP(QUP_I2C_CLK_CTL_SDA_NR,
+ noise_reject_sda);
+
/*
* Time it takes for a byte to be clocked out on the bus.
* Each byte takes 9 clock cycles (8 bits + 1 ack).
--
2.29.2
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 3/3] dt-bindings: i2c: qcom,i2c-qup: Document noise rejection properties
2021-01-13 18:25 [PATCH 0/3] QCOM QUP I2C - Add noise rejection, convert to YAML AngeloGioacchino Del Regno
2021-01-13 18:25 ` [PATCH 1/3] dt-bindings: i2c: qcom,i2c-qup: Convert txt to YAML schema AngeloGioacchino Del Regno
2021-01-13 18:25 ` [PATCH 2/3] i2c: qup: Introduce SCL/SDA noise rejection AngeloGioacchino Del Regno
@ 2021-01-13 18:25 ` AngeloGioacchino Del Regno
2 siblings, 0 replies; 6+ messages in thread
From: AngeloGioacchino Del Regno @ 2021-01-13 18:25 UTC (permalink / raw)
To: agross
Cc: linux-kernel, konrad.dybcio, marijn.suijten, martin.botka,
bjorn.andersson, robh+dt, devicetree, linux-arm-msm, linux-i2c,
AngeloGioacchino Del Regno
Document the new noise rejection properties "qcom,noise-reject-sda"
and "qcom,noise-reject-scl".
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
---
.../devicetree/bindings/i2c/qcom,i2c-qup.yaml | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/Documentation/devicetree/bindings/i2c/qcom,i2c-qup.yaml b/Documentation/devicetree/bindings/i2c/qcom,i2c-qup.yaml
index c5c7db3ac2a6..3f14dd65c6b9 100644
--- a/Documentation/devicetree/bindings/i2c/qcom,i2c-qup.yaml
+++ b/Documentation/devicetree/bindings/i2c/qcom,i2c-qup.yaml
@@ -58,6 +58,20 @@ properties:
'#size-cells':
const: 0
+ qcom,noise-reject-sda:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: Noise rejection level for the SDA line.
+ minimum: 0
+ maximum: 3
+ default: 0
+
+ qcom,noise-reject-scl:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: Noise rejection level for the SCL line.
+ minimum: 0
+ maximum: 3
+ default: 0
+
required:
- compatible
- clocks
--
2.29.2
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 2/3] i2c: qup: Introduce SCL/SDA noise rejection
2021-01-13 18:25 ` [PATCH 2/3] i2c: qup: Introduce SCL/SDA noise rejection AngeloGioacchino Del Regno
@ 2021-01-14 3:57 ` kernel test robot
0 siblings, 0 replies; 6+ messages in thread
From: kernel test robot @ 2021-01-14 3:57 UTC (permalink / raw)
To: AngeloGioacchino Del Regno, agross
Cc: kbuild-all, linux-kernel, konrad.dybcio, marijn.suijten,
martin.botka, bjorn.andersson, robh+dt, devicetree,
linux-arm-msm, linux-i2c
[-- Attachment #1: Type: text/plain, Size: 10913 bytes --]
Hi AngeloGioacchino,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on wsa/i2c/for-next]
[also build test ERROR on linux/master robh/for-next linus/master v5.11-rc3 next-20210113]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/AngeloGioacchino-Del-Regno/QCOM-QUP-I2C-Add-noise-rejection-convert-to-YAML/20210114-023032
base: https://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git i2c/for-next
config: arm-allyesconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/0day-ci/linux/commit/a124c4d6bf942e45b63addcef97f56f2a8934fe8
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review AngeloGioacchino-Del-Regno/QCOM-QUP-I2C-Add-noise-rejection-convert-to-YAML/20210114-023032
git checkout a124c4d6bf942e45b63addcef97f56f2a8934fe8
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=arm
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All errors (new ones prefixed by >>):
drivers/i2c/busses/i2c-qup.c: In function 'qup_i2c_probe':
>> drivers/i2c/busses/i2c-qup.c:1870:19: error: implicit declaration of function 'FIELD_PREP' [-Werror=implicit-function-declaration]
1870 | qup->clk_ctl |= FIELD_PREP(QUP_I2C_CLK_CTL_SCL_NR,
| ^~~~~~~~~~
cc1: some warnings being treated as errors
vim +/FIELD_PREP +1870 drivers/i2c/busses/i2c-qup.c
1658
1659 static int qup_i2c_probe(struct platform_device *pdev)
1660 {
1661 static const int blk_sizes[] = {4, 16, 32};
1662 struct qup_i2c_dev *qup;
1663 unsigned long one_bit_t;
1664 u32 io_mode, hw_ver, size;
1665 int ret, fs_div, hs_div;
1666 u32 src_clk_freq = DEFAULT_SRC_CLK;
1667 u32 clk_freq = DEFAULT_CLK_FREQ;
1668 u32 noise_reject_scl = 0, noise_reject_sda = 0;
1669 int blocks;
1670 bool is_qup_v1;
1671
1672 qup = devm_kzalloc(&pdev->dev, sizeof(*qup), GFP_KERNEL);
1673 if (!qup)
1674 return -ENOMEM;
1675
1676 qup->dev = &pdev->dev;
1677 init_completion(&qup->xfer);
1678 platform_set_drvdata(pdev, qup);
1679
1680 if (scl_freq) {
1681 dev_notice(qup->dev, "Using override frequency of %u\n", scl_freq);
1682 clk_freq = scl_freq;
1683 } else {
1684 ret = device_property_read_u32(qup->dev, "clock-frequency", &clk_freq);
1685 if (ret) {
1686 dev_notice(qup->dev, "using default clock-frequency %d",
1687 DEFAULT_CLK_FREQ);
1688 }
1689 }
1690
1691 if (of_device_is_compatible(pdev->dev.of_node, "qcom,i2c-qup-v1.1.1")) {
1692 qup->adap.algo = &qup_i2c_algo;
1693 qup->adap.quirks = &qup_i2c_quirks;
1694 is_qup_v1 = true;
1695 } else {
1696 qup->adap.algo = &qup_i2c_algo_v2;
1697 qup->adap.quirks = &qup_i2c_quirks_v2;
1698 is_qup_v1 = false;
1699 if (acpi_match_device(qup_i2c_acpi_match, qup->dev))
1700 goto nodma;
1701 else
1702 ret = qup_i2c_req_dma(qup);
1703
1704 if (ret == -EPROBE_DEFER)
1705 goto fail_dma;
1706 else if (ret != 0)
1707 goto nodma;
1708
1709 qup->max_xfer_sg_len = (MX_BLOCKS << 1);
1710 blocks = (MX_DMA_BLOCKS << 1) + 1;
1711 qup->btx.sg = devm_kcalloc(&pdev->dev,
1712 blocks, sizeof(*qup->btx.sg),
1713 GFP_KERNEL);
1714 if (!qup->btx.sg) {
1715 ret = -ENOMEM;
1716 goto fail_dma;
1717 }
1718 sg_init_table(qup->btx.sg, blocks);
1719
1720 qup->brx.sg = devm_kcalloc(&pdev->dev,
1721 blocks, sizeof(*qup->brx.sg),
1722 GFP_KERNEL);
1723 if (!qup->brx.sg) {
1724 ret = -ENOMEM;
1725 goto fail_dma;
1726 }
1727 sg_init_table(qup->brx.sg, blocks);
1728
1729 /* 2 tag bytes for each block + 5 for start, stop tags */
1730 size = blocks * 2 + 5;
1731
1732 qup->start_tag.start = devm_kzalloc(&pdev->dev,
1733 size, GFP_KERNEL);
1734 if (!qup->start_tag.start) {
1735 ret = -ENOMEM;
1736 goto fail_dma;
1737 }
1738
1739 qup->brx.tag.start = devm_kzalloc(&pdev->dev, 2, GFP_KERNEL);
1740 if (!qup->brx.tag.start) {
1741 ret = -ENOMEM;
1742 goto fail_dma;
1743 }
1744
1745 qup->btx.tag.start = devm_kzalloc(&pdev->dev, 2, GFP_KERNEL);
1746 if (!qup->btx.tag.start) {
1747 ret = -ENOMEM;
1748 goto fail_dma;
1749 }
1750 qup->is_dma = true;
1751 }
1752
1753 nodma:
1754 /* We support frequencies up to FAST Mode Plus (1MHz) */
1755 if (!clk_freq || clk_freq > I2C_MAX_FAST_MODE_PLUS_FREQ) {
1756 dev_err(qup->dev, "clock frequency not supported %d\n",
1757 clk_freq);
1758 return -EINVAL;
1759 }
1760
1761 qup->base = devm_platform_ioremap_resource(pdev, 0);
1762 if (IS_ERR(qup->base))
1763 return PTR_ERR(qup->base);
1764
1765 qup->irq = platform_get_irq(pdev, 0);
1766 if (qup->irq < 0)
1767 return qup->irq;
1768
1769 if (has_acpi_companion(qup->dev)) {
1770 ret = device_property_read_u32(qup->dev,
1771 "src-clock-hz", &src_clk_freq);
1772 if (ret) {
1773 dev_notice(qup->dev, "using default src-clock-hz %d",
1774 DEFAULT_SRC_CLK);
1775 }
1776 ACPI_COMPANION_SET(&qup->adap.dev, ACPI_COMPANION(qup->dev));
1777 } else {
1778 qup->clk = devm_clk_get(qup->dev, "core");
1779 if (IS_ERR(qup->clk)) {
1780 dev_err(qup->dev, "Could not get core clock\n");
1781 return PTR_ERR(qup->clk);
1782 }
1783
1784 qup->pclk = devm_clk_get(qup->dev, "iface");
1785 if (IS_ERR(qup->pclk)) {
1786 dev_err(qup->dev, "Could not get iface clock\n");
1787 return PTR_ERR(qup->pclk);
1788 }
1789 qup_i2c_enable_clocks(qup);
1790 src_clk_freq = clk_get_rate(qup->clk);
1791 }
1792
1793 /*
1794 * Bootloaders might leave a pending interrupt on certain QUP's,
1795 * so we reset the core before registering for interrupts.
1796 */
1797 writel(1, qup->base + QUP_SW_RESET);
1798 ret = qup_i2c_poll_state_valid(qup);
1799 if (ret)
1800 goto fail;
1801
1802 ret = devm_request_irq(qup->dev, qup->irq, qup_i2c_interrupt,
1803 IRQF_TRIGGER_HIGH, "i2c_qup", qup);
1804 if (ret) {
1805 dev_err(qup->dev, "Request %d IRQ failed\n", qup->irq);
1806 goto fail;
1807 }
1808 disable_irq(qup->irq);
1809
1810 hw_ver = readl(qup->base + QUP_HW_VERSION);
1811 dev_dbg(qup->dev, "Revision %x\n", hw_ver);
1812
1813 io_mode = readl(qup->base + QUP_IO_MODE);
1814
1815 /*
1816 * The block/fifo size w.r.t. 'actual data' is 1/2 due to 'tag'
1817 * associated with each byte written/received
1818 */
1819 size = QUP_OUTPUT_BLOCK_SIZE(io_mode);
1820 if (size >= ARRAY_SIZE(blk_sizes)) {
1821 ret = -EIO;
1822 goto fail;
1823 }
1824 qup->out_blk_sz = blk_sizes[size];
1825
1826 size = QUP_INPUT_BLOCK_SIZE(io_mode);
1827 if (size >= ARRAY_SIZE(blk_sizes)) {
1828 ret = -EIO;
1829 goto fail;
1830 }
1831 qup->in_blk_sz = blk_sizes[size];
1832
1833 if (is_qup_v1) {
1834 /*
1835 * in QUP v1, QUP_CONFIG uses N as 15 i.e 16 bits constitutes a
1836 * single transfer but the block size is in bytes so divide the
1837 * in_blk_sz and out_blk_sz by 2
1838 */
1839 qup->in_blk_sz /= 2;
1840 qup->out_blk_sz /= 2;
1841 qup->write_tx_fifo = qup_i2c_write_tx_fifo_v1;
1842 qup->read_rx_fifo = qup_i2c_read_rx_fifo_v1;
1843 qup->write_rx_tags = qup_i2c_write_rx_tags_v1;
1844 } else {
1845 qup->write_tx_fifo = qup_i2c_write_tx_fifo_v2;
1846 qup->read_rx_fifo = qup_i2c_read_rx_fifo_v2;
1847 qup->write_rx_tags = qup_i2c_write_rx_tags_v2;
1848 }
1849
1850 size = QUP_OUTPUT_FIFO_SIZE(io_mode);
1851 qup->out_fifo_sz = qup->out_blk_sz * (2 << size);
1852
1853 size = QUP_INPUT_FIFO_SIZE(io_mode);
1854 qup->in_fifo_sz = qup->in_blk_sz * (2 << size);
1855
1856 hs_div = 3;
1857 if (clk_freq <= I2C_MAX_STANDARD_MODE_FREQ) {
1858 fs_div = ((src_clk_freq / clk_freq) / 2) - 3;
1859 qup->clk_ctl = (hs_div << 8) | (fs_div & 0xff);
1860 } else {
1861 /* 33%/66% duty cycle */
1862 fs_div = ((src_clk_freq / clk_freq) - 6) * 2 / 3;
1863 qup->clk_ctl = ((fs_div / 2) << 16) | (hs_div << 8) | (fs_div & 0xff);
1864 }
1865
1866 /* SCL/SDA Noise rejection (optional) */
1867 ret = device_property_read_u32(qup->dev, "qcom,noise-reject-scl",
1868 &noise_reject_scl);
1869 if (ret == 0)
> 1870 qup->clk_ctl |= FIELD_PREP(QUP_I2C_CLK_CTL_SCL_NR,
1871 noise_reject_scl);
1872
1873 ret = device_property_read_u32(qup->dev, "qcom,noise-reject-sda",
1874 &noise_reject_sda);
1875 if (ret == 0)
1876 qup->clk_ctl |= FIELD_PREP(QUP_I2C_CLK_CTL_SDA_NR,
1877 noise_reject_sda);
1878
1879 /*
1880 * Time it takes for a byte to be clocked out on the bus.
1881 * Each byte takes 9 clock cycles (8 bits + 1 ack).
1882 */
1883 one_bit_t = (USEC_PER_SEC / clk_freq) + 1;
1884 qup->one_byte_t = one_bit_t * 9;
1885 qup->xfer_timeout = TOUT_MIN * HZ +
1886 usecs_to_jiffies(MX_DMA_TX_RX_LEN * qup->one_byte_t);
1887
1888 dev_dbg(qup->dev, "IN:block:%d, fifo:%d, OUT:block:%d, fifo:%d\n",
1889 qup->in_blk_sz, qup->in_fifo_sz,
1890 qup->out_blk_sz, qup->out_fifo_sz);
1891
1892 i2c_set_adapdata(&qup->adap, qup);
1893 qup->adap.dev.parent = qup->dev;
1894 qup->adap.dev.of_node = pdev->dev.of_node;
1895 qup->is_last = true;
1896
1897 strlcpy(qup->adap.name, "QUP I2C adapter", sizeof(qup->adap.name));
1898
1899 pm_runtime_set_autosuspend_delay(qup->dev, MSEC_PER_SEC);
1900 pm_runtime_use_autosuspend(qup->dev);
1901 pm_runtime_set_active(qup->dev);
1902 pm_runtime_enable(qup->dev);
1903
1904 ret = i2c_add_adapter(&qup->adap);
1905 if (ret)
1906 goto fail_runtime;
1907
1908 return 0;
1909
1910 fail_runtime:
1911 pm_runtime_disable(qup->dev);
1912 pm_runtime_set_suspended(qup->dev);
1913 fail:
1914 qup_i2c_disable_clocks(qup);
1915 fail_dma:
1916 if (qup->btx.dma)
1917 dma_release_channel(qup->btx.dma);
1918 if (qup->brx.dma)
1919 dma_release_channel(qup->brx.dma);
1920 return ret;
1921 }
1922
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 77913 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 2/3] i2c: qup: Introduce SCL/SDA noise rejection
@ 2021-01-14 3:57 ` kernel test robot
0 siblings, 0 replies; 6+ messages in thread
From: kernel test robot @ 2021-01-14 3:57 UTC (permalink / raw)
To: kbuild-all
[-- Attachment #1: Type: text/plain, Size: 11222 bytes --]
Hi AngeloGioacchino,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on wsa/i2c/for-next]
[also build test ERROR on linux/master robh/for-next linus/master v5.11-rc3 next-20210113]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/AngeloGioacchino-Del-Regno/QCOM-QUP-I2C-Add-noise-rejection-convert-to-YAML/20210114-023032
base: https://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git i2c/for-next
config: arm-allyesconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/0day-ci/linux/commit/a124c4d6bf942e45b63addcef97f56f2a8934fe8
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review AngeloGioacchino-Del-Regno/QCOM-QUP-I2C-Add-noise-rejection-convert-to-YAML/20210114-023032
git checkout a124c4d6bf942e45b63addcef97f56f2a8934fe8
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=arm
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All errors (new ones prefixed by >>):
drivers/i2c/busses/i2c-qup.c: In function 'qup_i2c_probe':
>> drivers/i2c/busses/i2c-qup.c:1870:19: error: implicit declaration of function 'FIELD_PREP' [-Werror=implicit-function-declaration]
1870 | qup->clk_ctl |= FIELD_PREP(QUP_I2C_CLK_CTL_SCL_NR,
| ^~~~~~~~~~
cc1: some warnings being treated as errors
vim +/FIELD_PREP +1870 drivers/i2c/busses/i2c-qup.c
1658
1659 static int qup_i2c_probe(struct platform_device *pdev)
1660 {
1661 static const int blk_sizes[] = {4, 16, 32};
1662 struct qup_i2c_dev *qup;
1663 unsigned long one_bit_t;
1664 u32 io_mode, hw_ver, size;
1665 int ret, fs_div, hs_div;
1666 u32 src_clk_freq = DEFAULT_SRC_CLK;
1667 u32 clk_freq = DEFAULT_CLK_FREQ;
1668 u32 noise_reject_scl = 0, noise_reject_sda = 0;
1669 int blocks;
1670 bool is_qup_v1;
1671
1672 qup = devm_kzalloc(&pdev->dev, sizeof(*qup), GFP_KERNEL);
1673 if (!qup)
1674 return -ENOMEM;
1675
1676 qup->dev = &pdev->dev;
1677 init_completion(&qup->xfer);
1678 platform_set_drvdata(pdev, qup);
1679
1680 if (scl_freq) {
1681 dev_notice(qup->dev, "Using override frequency of %u\n", scl_freq);
1682 clk_freq = scl_freq;
1683 } else {
1684 ret = device_property_read_u32(qup->dev, "clock-frequency", &clk_freq);
1685 if (ret) {
1686 dev_notice(qup->dev, "using default clock-frequency %d",
1687 DEFAULT_CLK_FREQ);
1688 }
1689 }
1690
1691 if (of_device_is_compatible(pdev->dev.of_node, "qcom,i2c-qup-v1.1.1")) {
1692 qup->adap.algo = &qup_i2c_algo;
1693 qup->adap.quirks = &qup_i2c_quirks;
1694 is_qup_v1 = true;
1695 } else {
1696 qup->adap.algo = &qup_i2c_algo_v2;
1697 qup->adap.quirks = &qup_i2c_quirks_v2;
1698 is_qup_v1 = false;
1699 if (acpi_match_device(qup_i2c_acpi_match, qup->dev))
1700 goto nodma;
1701 else
1702 ret = qup_i2c_req_dma(qup);
1703
1704 if (ret == -EPROBE_DEFER)
1705 goto fail_dma;
1706 else if (ret != 0)
1707 goto nodma;
1708
1709 qup->max_xfer_sg_len = (MX_BLOCKS << 1);
1710 blocks = (MX_DMA_BLOCKS << 1) + 1;
1711 qup->btx.sg = devm_kcalloc(&pdev->dev,
1712 blocks, sizeof(*qup->btx.sg),
1713 GFP_KERNEL);
1714 if (!qup->btx.sg) {
1715 ret = -ENOMEM;
1716 goto fail_dma;
1717 }
1718 sg_init_table(qup->btx.sg, blocks);
1719
1720 qup->brx.sg = devm_kcalloc(&pdev->dev,
1721 blocks, sizeof(*qup->brx.sg),
1722 GFP_KERNEL);
1723 if (!qup->brx.sg) {
1724 ret = -ENOMEM;
1725 goto fail_dma;
1726 }
1727 sg_init_table(qup->brx.sg, blocks);
1728
1729 /* 2 tag bytes for each block + 5 for start, stop tags */
1730 size = blocks * 2 + 5;
1731
1732 qup->start_tag.start = devm_kzalloc(&pdev->dev,
1733 size, GFP_KERNEL);
1734 if (!qup->start_tag.start) {
1735 ret = -ENOMEM;
1736 goto fail_dma;
1737 }
1738
1739 qup->brx.tag.start = devm_kzalloc(&pdev->dev, 2, GFP_KERNEL);
1740 if (!qup->brx.tag.start) {
1741 ret = -ENOMEM;
1742 goto fail_dma;
1743 }
1744
1745 qup->btx.tag.start = devm_kzalloc(&pdev->dev, 2, GFP_KERNEL);
1746 if (!qup->btx.tag.start) {
1747 ret = -ENOMEM;
1748 goto fail_dma;
1749 }
1750 qup->is_dma = true;
1751 }
1752
1753 nodma:
1754 /* We support frequencies up to FAST Mode Plus (1MHz) */
1755 if (!clk_freq || clk_freq > I2C_MAX_FAST_MODE_PLUS_FREQ) {
1756 dev_err(qup->dev, "clock frequency not supported %d\n",
1757 clk_freq);
1758 return -EINVAL;
1759 }
1760
1761 qup->base = devm_platform_ioremap_resource(pdev, 0);
1762 if (IS_ERR(qup->base))
1763 return PTR_ERR(qup->base);
1764
1765 qup->irq = platform_get_irq(pdev, 0);
1766 if (qup->irq < 0)
1767 return qup->irq;
1768
1769 if (has_acpi_companion(qup->dev)) {
1770 ret = device_property_read_u32(qup->dev,
1771 "src-clock-hz", &src_clk_freq);
1772 if (ret) {
1773 dev_notice(qup->dev, "using default src-clock-hz %d",
1774 DEFAULT_SRC_CLK);
1775 }
1776 ACPI_COMPANION_SET(&qup->adap.dev, ACPI_COMPANION(qup->dev));
1777 } else {
1778 qup->clk = devm_clk_get(qup->dev, "core");
1779 if (IS_ERR(qup->clk)) {
1780 dev_err(qup->dev, "Could not get core clock\n");
1781 return PTR_ERR(qup->clk);
1782 }
1783
1784 qup->pclk = devm_clk_get(qup->dev, "iface");
1785 if (IS_ERR(qup->pclk)) {
1786 dev_err(qup->dev, "Could not get iface clock\n");
1787 return PTR_ERR(qup->pclk);
1788 }
1789 qup_i2c_enable_clocks(qup);
1790 src_clk_freq = clk_get_rate(qup->clk);
1791 }
1792
1793 /*
1794 * Bootloaders might leave a pending interrupt on certain QUP's,
1795 * so we reset the core before registering for interrupts.
1796 */
1797 writel(1, qup->base + QUP_SW_RESET);
1798 ret = qup_i2c_poll_state_valid(qup);
1799 if (ret)
1800 goto fail;
1801
1802 ret = devm_request_irq(qup->dev, qup->irq, qup_i2c_interrupt,
1803 IRQF_TRIGGER_HIGH, "i2c_qup", qup);
1804 if (ret) {
1805 dev_err(qup->dev, "Request %d IRQ failed\n", qup->irq);
1806 goto fail;
1807 }
1808 disable_irq(qup->irq);
1809
1810 hw_ver = readl(qup->base + QUP_HW_VERSION);
1811 dev_dbg(qup->dev, "Revision %x\n", hw_ver);
1812
1813 io_mode = readl(qup->base + QUP_IO_MODE);
1814
1815 /*
1816 * The block/fifo size w.r.t. 'actual data' is 1/2 due to 'tag'
1817 * associated with each byte written/received
1818 */
1819 size = QUP_OUTPUT_BLOCK_SIZE(io_mode);
1820 if (size >= ARRAY_SIZE(blk_sizes)) {
1821 ret = -EIO;
1822 goto fail;
1823 }
1824 qup->out_blk_sz = blk_sizes[size];
1825
1826 size = QUP_INPUT_BLOCK_SIZE(io_mode);
1827 if (size >= ARRAY_SIZE(blk_sizes)) {
1828 ret = -EIO;
1829 goto fail;
1830 }
1831 qup->in_blk_sz = blk_sizes[size];
1832
1833 if (is_qup_v1) {
1834 /*
1835 * in QUP v1, QUP_CONFIG uses N as 15 i.e 16 bits constitutes a
1836 * single transfer but the block size is in bytes so divide the
1837 * in_blk_sz and out_blk_sz by 2
1838 */
1839 qup->in_blk_sz /= 2;
1840 qup->out_blk_sz /= 2;
1841 qup->write_tx_fifo = qup_i2c_write_tx_fifo_v1;
1842 qup->read_rx_fifo = qup_i2c_read_rx_fifo_v1;
1843 qup->write_rx_tags = qup_i2c_write_rx_tags_v1;
1844 } else {
1845 qup->write_tx_fifo = qup_i2c_write_tx_fifo_v2;
1846 qup->read_rx_fifo = qup_i2c_read_rx_fifo_v2;
1847 qup->write_rx_tags = qup_i2c_write_rx_tags_v2;
1848 }
1849
1850 size = QUP_OUTPUT_FIFO_SIZE(io_mode);
1851 qup->out_fifo_sz = qup->out_blk_sz * (2 << size);
1852
1853 size = QUP_INPUT_FIFO_SIZE(io_mode);
1854 qup->in_fifo_sz = qup->in_blk_sz * (2 << size);
1855
1856 hs_div = 3;
1857 if (clk_freq <= I2C_MAX_STANDARD_MODE_FREQ) {
1858 fs_div = ((src_clk_freq / clk_freq) / 2) - 3;
1859 qup->clk_ctl = (hs_div << 8) | (fs_div & 0xff);
1860 } else {
1861 /* 33%/66% duty cycle */
1862 fs_div = ((src_clk_freq / clk_freq) - 6) * 2 / 3;
1863 qup->clk_ctl = ((fs_div / 2) << 16) | (hs_div << 8) | (fs_div & 0xff);
1864 }
1865
1866 /* SCL/SDA Noise rejection (optional) */
1867 ret = device_property_read_u32(qup->dev, "qcom,noise-reject-scl",
1868 &noise_reject_scl);
1869 if (ret == 0)
> 1870 qup->clk_ctl |= FIELD_PREP(QUP_I2C_CLK_CTL_SCL_NR,
1871 noise_reject_scl);
1872
1873 ret = device_property_read_u32(qup->dev, "qcom,noise-reject-sda",
1874 &noise_reject_sda);
1875 if (ret == 0)
1876 qup->clk_ctl |= FIELD_PREP(QUP_I2C_CLK_CTL_SDA_NR,
1877 noise_reject_sda);
1878
1879 /*
1880 * Time it takes for a byte to be clocked out on the bus.
1881 * Each byte takes 9 clock cycles (8 bits + 1 ack).
1882 */
1883 one_bit_t = (USEC_PER_SEC / clk_freq) + 1;
1884 qup->one_byte_t = one_bit_t * 9;
1885 qup->xfer_timeout = TOUT_MIN * HZ +
1886 usecs_to_jiffies(MX_DMA_TX_RX_LEN * qup->one_byte_t);
1887
1888 dev_dbg(qup->dev, "IN:block:%d, fifo:%d, OUT:block:%d, fifo:%d\n",
1889 qup->in_blk_sz, qup->in_fifo_sz,
1890 qup->out_blk_sz, qup->out_fifo_sz);
1891
1892 i2c_set_adapdata(&qup->adap, qup);
1893 qup->adap.dev.parent = qup->dev;
1894 qup->adap.dev.of_node = pdev->dev.of_node;
1895 qup->is_last = true;
1896
1897 strlcpy(qup->adap.name, "QUP I2C adapter", sizeof(qup->adap.name));
1898
1899 pm_runtime_set_autosuspend_delay(qup->dev, MSEC_PER_SEC);
1900 pm_runtime_use_autosuspend(qup->dev);
1901 pm_runtime_set_active(qup->dev);
1902 pm_runtime_enable(qup->dev);
1903
1904 ret = i2c_add_adapter(&qup->adap);
1905 if (ret)
1906 goto fail_runtime;
1907
1908 return 0;
1909
1910 fail_runtime:
1911 pm_runtime_disable(qup->dev);
1912 pm_runtime_set_suspended(qup->dev);
1913 fail:
1914 qup_i2c_disable_clocks(qup);
1915 fail_dma:
1916 if (qup->btx.dma)
1917 dma_release_channel(qup->btx.dma);
1918 if (qup->brx.dma)
1919 dma_release_channel(qup->brx.dma);
1920 return ret;
1921 }
1922
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org
[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 77913 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2021-01-14 3:58 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-13 18:25 [PATCH 0/3] QCOM QUP I2C - Add noise rejection, convert to YAML AngeloGioacchino Del Regno
2021-01-13 18:25 ` [PATCH 1/3] dt-bindings: i2c: qcom,i2c-qup: Convert txt to YAML schema AngeloGioacchino Del Regno
2021-01-13 18:25 ` [PATCH 2/3] i2c: qup: Introduce SCL/SDA noise rejection AngeloGioacchino Del Regno
2021-01-14 3:57 ` kernel test robot
2021-01-14 3:57 ` kernel test robot
2021-01-13 18:25 ` [PATCH 3/3] dt-bindings: i2c: qcom,i2c-qup: Document noise rejection properties AngeloGioacchino Del Regno
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.