msm8953-mainline / linux

Linux mainline kernel with WIP patches for msm8953 devices
Other
115 stars 59 forks source link

DMA for I2C #86

Closed z3ntu closed 1 year ago

z3ntu commented 1 year ago

Need to check if blsp dma works with something like the following diff:

diff --git a/arch/arm64/boot/dts/qcom/msm8953.dtsi b/arch/arm64/boot/dts/qcom/msm8953.dtsi
index 32349174c4bd..75850ce460a2 100644
--- a/arch/arm64/boot/dts/qcom/msm8953.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8953.dtsi
@@ -1155,6 +1155,16 @@ opp-200000000 {
            };
        };

+       blsp1_dma: dma-controller@7884000 {
+           compatible = "qcom,bam-v1.7.0";
+           reg = <0x07884000 0x1f000>;
+           interrupts = <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>;
+           clocks = <&gcc GCC_BLSP1_AHB_CLK>;
+           clock-names = "bam_clk";
+           #dma-cells = <1>;
+           qcom,ee = <0>;
+       };
+
        uart_0: serial@78af000 {
            compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
            reg = <0x78af000 0x200>;
@@ -1173,6 +1183,8 @@ i2c_1: i2c@78b5000 {
            clock-names = "core", "iface";
            clocks = <&gcc GCC_BLSP1_QUP1_I2C_APPS_CLK>,
                 <&gcc GCC_BLSP1_AHB_CLK>;
+           dmas = <&blsp1_dma 4>, <&blsp1_dma 5>;
+           dma-names = "tx", "rx";

            pinctrl-names = "default", "sleep";
            pinctrl-0 = <&i2c_1_default>;
@@ -1191,6 +1203,8 @@ i2c_2: i2c@78b6000 {
            clock-names = "core", "iface";
            clocks = <&gcc GCC_BLSP1_QUP2_I2C_APPS_CLK>,
                 <&gcc GCC_BLSP1_AHB_CLK>;
+           dmas = <&blsp1_dma 6>, <&blsp1_dma 7>;
+           dma-names = "tx", "rx";

            pinctrl-names = "default", "sleep";
            pinctrl-0 = <&i2c_2_default>;
@@ -1209,6 +1223,9 @@ i2c_3: i2c@78b7000 {
            clock-names = "core", "iface";
            clocks = <&gcc GCC_BLSP1_QUP3_I2C_APPS_CLK>,
                 <&gcc GCC_BLSP1_AHB_CLK>;
+           dmas = <&blsp1_dma 8>, <&blsp1_dma 9>;
+           dma-names = "tx", "rx";
+
            pinctrl-names = "default", "sleep";
            pinctrl-0 = <&i2c_3_default>;
            pinctrl-1 = <&i2c_3_sleep>;
@@ -1226,6 +1243,9 @@ i2c_4: i2c@78b8000 {
            clock-names = "core", "iface";
            clocks = <&gcc GCC_BLSP1_QUP4_I2C_APPS_CLK>,
                 <&gcc GCC_BLSP1_AHB_CLK>;
+           dmas = <&blsp2_dma 10>, <&blsp2_dma 11>;
+           dma-names = "tx", "rx";
+
            pinctrl-names = "default", "sleep";
            pinctrl-0 = <&i2c_4_default>;
            pinctrl-1 = <&i2c_4_sleep>;
@@ -1236,6 +1256,16 @@ i2c_4: i2c@78b8000 {
            status = "disabled";
        };

+       blsp2_dma: dma-controller@7ac4000 {
+           compatible = "qcom,bam-v1.7.0";
+           reg = <0x07ac4000 0x1f000>;
+           interrupts = <GIC_SPI 239 IRQ_TYPE_LEVEL_HIGH>;
+           clocks = <&gcc GCC_BLSP2_AHB_CLK>;
+           clock-names = "bam_clk";
+           #dma-cells = <1>;
+           qcom,ee = <0>;
+       };
+
        i2c_5: i2c@7af5000 {
            compatible = "qcom,i2c-qup-v2.2.1";
            reg = <0x7af5000 0x600>;
@@ -1243,6 +1273,9 @@ i2c_5: i2c@7af5000 {
            clock-names = "core", "iface";
            clocks = <&gcc GCC_BLSP2_QUP1_I2C_APPS_CLK>,
                 <&gcc GCC_BLSP2_AHB_CLK>;
+           dmas = <&blsp2_dma 4>, <&blsp2_dma 5>;
+           dma-names = "tx", "rx";
+
            pinctrl-names = "default", "sleep";
            pinctrl-0 = <&i2c_5_default>;
            pinctrl-1 = <&i2c_5_sleep>;
@@ -1260,6 +1293,9 @@ i2c_6: i2c@7af6000 {
            clock-names = "core", "iface";
            clocks = <&gcc GCC_BLSP2_QUP2_I2C_APPS_CLK>,
                 <&gcc GCC_BLSP2_AHB_CLK>;
+           dmas = <&blsp2_dma 6>, <&blsp2_dma 7>;
+           dma-names = "tx", "rx";
+
            pinctrl-names = "default", "sleep";
            pinctrl-0 = <&i2c_6_default>;
            pinctrl-1 = <&i2c_6_sleep>;
@@ -1277,6 +1313,9 @@ i2c_7: i2c@7af7000 {
            clock-names = "core", "iface";
            clocks = <&gcc GCC_BLSP2_QUP3_I2C_APPS_CLK>,
                 <&gcc GCC_BLSP2_AHB_CLK>;
+           dmas = <&blsp2_dma 8>, <&blsp2_dma 9>;
+           dma-names = "tx", "rx";
+
            pinctrl-names = "default", "sleep";
            pinctrl-0 = <&i2c_7_default>;
            pinctrl-1 = <&i2c_7_sleep>;
@@ -1294,6 +1333,9 @@ i2c_8: i2c@7af8000 {
            clock-names = "core", "iface";
            clocks = <&gcc GCC_BLSP2_QUP4_I2C_APPS_CLK>,
                 <&gcc GCC_BLSP2_AHB_CLK>;
+           dmas = <&blsp2_dma 10>, <&blsp2_dma 11>;
+           dma-names = "tx", "rx";
+
            pinctrl-names = "default", "sleep";
            pinctrl-0 = <&i2c_8_default>;
            pinctrl-1 = <&i2c_8_sleep>;

edit: doesn't seem relevant for now but spi uses qcom,bam-consumer-pipe-index & qcom,bam-producer-pipe-index; and for uart qcom,bam-tx-ep-pipe-index & qcom,bam-rx-ep-pipe-index for the indexes, not dmas property like i2c downstream

z3ntu commented 1 year ago

Seems to work, sent an adjusted version upstream: https://lore.kernel.org/linux-arm-msm/20230422-msm8953-blsp-dma-v1-1-0024801bb587@z3ntu.xyz/T/ & pull request in #87

For testing I've also used this to force short transfers to go via DMA too since my peripherals don't have long messages:

diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c
index 2e153f2f71b6..2665acf059bd 100644
--- a/drivers/i2c/busses/i2c-qup.c
+++ b/drivers/i2c/busses/i2c-qup.c
@@ -1522,8 +1522,9 @@ qup_i2c_determine_mode_v2(struct qup_i2c_dev *qup,
        total_len += msgs[idx].len;
    }

-   if (!no_dma && qup->is_dma &&
-       (total_len > qup->out_fifo_sz || total_len > qup->in_fifo_sz)) {
+   printk(KERN_ERR "%s:%d DBG no_dma=%d is_dma=%d total_len=%u out_fifo_sz=%d in_fifo_sz=%d\n", __func__, __LINE__, no_dma, qup->is_dma, total_len, qup->out_fifo_sz, qup->in_fifo_sz);
+   if (!no_dma && qup->is_dma /*&&
+       (total_len > qup->out_fifo_sz || total_len > qup->in_fifo_sz)*/) {
        qup->use_dma = true;
    } else {
        qup->blk.is_tx_blk_mode = max_tx_len > qup->out_fifo_sz -
@@ -1567,6 +1568,7 @@ static int qup_i2c_xfer_v2(struct i2c_adapter *adap,
        goto out;
    }

+   printk(KERN_ERR "%s:%d DBG use_dma=%d\n", __func__, __LINE__, qup->use_dma);
    if (qup->use_dma) {
        reinit_completion(&qup->xfer);
        ret = qup_i2c_bam_xfer(adap, &msgs[0], num);
z3ntu commented 1 year ago

The patch has been in mainline since v6.5-rc1, closing.