Re: [PATCH V8 1/1] i2c: i2c-qcom-geni: Add shutdown callback for i2c

2021-01-11 Thread Akash Asthana



On 1/8/2021 8:35 PM, Roja Rani Yarubandi wrote:

If the hardware is still accessing memory after SMMU translation
is disabled (as part of smmu shutdown callback), then the
IOVAs (I/O virtual address) which it was using will go on the bus
as the physical addresses which will result in unknown crashes
like NoC/interconnect errors.

So, implement shutdown callback to i2c driver to stop on-going transfer
and unmap DMA mappings during system "reboot" or "shutdown".

Fixes: 37692de5d523 ("i2c: i2c-qcom-geni: Add bus driver for the Qualcomm GENI I2C 
controller")
Signed-off-by: Roja Rani Yarubandi 

Reviewed-by: Akash Asthana 

--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project



Re: [PATCH V7 1/2] i2c: i2c-qcom-geni: Store DMA mapping data in geni_i2c_dev struct

2020-12-30 Thread Akash Asthana



On 12/21/2020 6:08 PM, Roja Rani Yarubandi wrote:

Store DMA mapping data in geni_i2c_dev struct to enhance DMA mapping
data scope. For example during shutdown callback to unmap DMA mapping,
this stored DMA mapping data can be used to call geni_se_tx_dma_unprep
and geni_se_rx_dma_unprep functions.

Add two helper functions geni_i2c_rx_msg_cleanup and
geni_i2c_tx_msg_cleanup to unwrap the things after rx/tx FIFO/DMA
transfers, so that the same can be used in geni_i2c_stop_xfer()
function during shutdown callback.

Signed-off-by: Roja Rani Yarubandi 

Reviewed-by: Akash Asthana 

--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project



Re: [PATCH V7 2/2] i2c: i2c-qcom-geni: Add shutdown callback for i2c

2020-12-30 Thread Akash Asthana



On 12/21/2020 6:08 PM, Roja Rani Yarubandi wrote:

If the hardware is still accessing memory after SMMU translation
is disabled (as part of smmu shutdown callback), then the
IOVAs (I/O virtual address) which it was using will go on the bus
as the physical addresses which will result in unknown crashes
like NoC/interconnect errors.

So, implement shutdown callback to i2c driver to stop on-going transfer
and unmap DMA mappings during system "reboot" or "shutdown".

Fixes: 37692de5d523 ("i2c: i2c-qcom-geni: Add bus driver for the Qualcomm GENI I2C 
controller")
Signed-off-by: Roja Rani Yarubandi 

Reviewed-by: Akash Asthana 

--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project



Re: [RESEND PATCH V6 1/2] i2c: i2c-qcom-geni: Store DMA mapping data in geni_i2c_dev struct

2020-12-09 Thread Akash Asthana

Hi Roja,

On 12/3/2020 4:01 PM, Roja Rani Yarubandi wrote:

Store DMA mapping data in geni_i2c_dev struct to enhance DMA mapping
data scope. For example during shutdown callback to unmap DMA mapping,
this stored DMA mapping data can be used to call geni_se_tx_dma_unprep
and geni_se_rx_dma_unprep functions.

Add two helper functions geni_i2c_rx_msg_cleanup and
geni_i2c_tx_msg_cleanup to unwrap the things after rx/tx FIFO/DMA
transfers, so that the same can be used in geni_i2c_stop_xfer()
function during shutdown callback.

Signed-off-by: Roja Rani Yarubandi 
---
Changes in V5:
  - As per Stephen's comments separated this patch from shutdown
callback patch, gi2c->cur = NULL is not removed from
geni_i2c_abort_xfer(), and made a copy of gi2c->cur and passed
to cleanup functions.

Changes in V6:
  - Added spin_lock/unlock in geni_i2c_rx_msg_cleanup() and
geni_i2c_tx_msg_cleanup() functions.

  drivers/i2c/busses/i2c-qcom-geni.c | 69 +++---
  1 file changed, 53 insertions(+), 16 deletions(-)

diff --git a/drivers/i2c/busses/i2c-qcom-geni.c 
b/drivers/i2c/busses/i2c-qcom-geni.c
index dce75b85253c..bfbc80f65006 100644
--- a/drivers/i2c/busses/i2c-qcom-geni.c
+++ b/drivers/i2c/busses/i2c-qcom-geni.c
@@ -86,6 +86,9 @@ struct geni_i2c_dev {
u32 clk_freq_out;
const struct geni_i2c_clk_fld *clk_fld;
int suspended;
+   void *dma_buf;
+   size_t xfer_len;
+   dma_addr_t dma_addr;
  };
  
  struct geni_i2c_err_log {

@@ -348,14 +351,49 @@ static void geni_i2c_tx_fsm_rst(struct geni_i2c_dev *gi2c)
dev_err(gi2c->se.dev, "Timeout resetting TX_FSM\n");
  }
  
+static void geni_i2c_rx_msg_cleanup(struct geni_i2c_dev *gi2c,

+struct i2c_msg *cur)
+{
+   struct geni_se *se = >se;
+   unsigned long flags;
+
+   spin_lock_irqsave(>lock, flags);
+   gi2c->cur_rd = 0;
+   if (gi2c->dma_buf) {
+   if (gi2c->err)
+   geni_i2c_rx_fsm_rst(gi2c);


Which race we are trying to avoid here by holding spinlock?

We cannot call any sleeping API by holding spinlock, geni_i2c_rx_fsm_rst 
calls *wait-for-completion*, which is a sleeping call.



+   geni_se_rx_dma_unprep(se, gi2c->dma_addr, gi2c->xfer_len);
+   i2c_put_dma_safe_msg_buf(gi2c->dma_buf, cur, !gi2c->err);
+   }
+   spin_unlock_irqrestore(>lock, flags);
+}
+
+static void geni_i2c_tx_msg_cleanup(struct geni_i2c_dev *gi2c,
+struct i2c_msg *cur)
+{
+   struct geni_se *se = >se;
+   unsigned long flags;
+
+   spin_lock_irqsave(>lock, flags);
+   gi2c->cur_wr = 0;
+   if (gi2c->dma_buf) {
+   if (gi2c->err)
+   geni_i2c_tx_fsm_rst(gi2c);


Same here

Regards,

Akash


+   geni_se_tx_dma_unprep(se, gi2c->dma_addr, gi2c->xfer_len);
+   i2c_put_dma_safe_msg_buf(gi2c->dma_buf, cur, !gi2c->err);
+   }
+   spin_unlock_irqrestore(>lock, flags);
+}
+
  static int geni_i2c_rx_one_msg(struct geni_i2c_dev *gi2c, struct i2c_msg *msg,
u32 m_param)
  {
-   dma_addr_t rx_dma;
+   dma_addr_t rx_dma = 0;
unsigned long time_left;
void *dma_buf = NULL;
struct geni_se *se = >se;
size_t len = msg->len;
+   struct i2c_msg *cur;
  
  	if (!of_machine_is_compatible("lenovo,yoga-c630"))

dma_buf = i2c_get_dma_safe_msg_buf(msg, 32);
@@ -372,19 +410,18 @@ static int geni_i2c_rx_one_msg(struct geni_i2c_dev *gi2c, 
struct i2c_msg *msg,
geni_se_select_mode(se, GENI_SE_FIFO);
i2c_put_dma_safe_msg_buf(dma_buf, msg, false);
dma_buf = NULL;
+   } else {
+   gi2c->xfer_len = len;
+   gi2c->dma_addr = rx_dma;
+   gi2c->dma_buf = dma_buf;
}
  
+	cur = gi2c->cur;

time_left = wait_for_completion_timeout(>done, XFER_TIMEOUT);
if (!time_left)
geni_i2c_abort_xfer(gi2c);
  
-	gi2c->cur_rd = 0;

-   if (dma_buf) {
-   if (gi2c->err)
-   geni_i2c_rx_fsm_rst(gi2c);
-   geni_se_rx_dma_unprep(se, rx_dma, len);
-   i2c_put_dma_safe_msg_buf(dma_buf, msg, !gi2c->err);
-   }
+   geni_i2c_rx_msg_cleanup(gi2c, cur);
  
  	return gi2c->err;

  }
@@ -392,11 +429,12 @@ static int geni_i2c_rx_one_msg(struct geni_i2c_dev *gi2c, 
struct i2c_msg *msg,
  static int geni_i2c_tx_one_msg(struct geni_i2c_dev *gi2c, struct i2c_msg *msg,
u32 m_param)
  {
-   dma_addr_t tx_dma;
+   dma_addr_t tx_dma = 0;
unsigned long time_left;
void *dma_buf = NULL;
struct geni_se *se = >se;
size_t len = msg->len;
+   struct i2c_msg *cur;
  
  	if (!of_machine_is_compatible("lenovo,yoga-c630"))

dma_buf = i2c_get_dma_safe_msg_buf(msg, 32);
@@ -413,22 +451,21 @@ static 

Re: [PATCH 3/3] Serial: Separate out earlycon support

2020-12-07 Thread Akash Asthana

Hi Greg,

On 12/7/2020 3:13 PM, Greg KH wrote:

On Mon, Dec 07, 2020 at 02:17:27PM +0530, Akash Asthana wrote:

Separate out earlycon support from serial driver and remove it's
dependency on QUP wrapper driver.

This enable us to manage earlycon independently and we can re-use the
same earlycon driver for android project which currently uses
downstream version of QUP drivers.

Signed-off-by: Akash Asthana 
---
  drivers/tty/serial/Kconfig  |   9 +
  drivers/tty/serial/Makefile |   1 +
  drivers/tty/serial/qcom_geni_earlycon.c | 649 
  drivers/tty/serial/qcom_geni_serial.c   |  97 -
  4 files changed, 659 insertions(+), 97 deletions(-)
  create mode 100644 drivers/tty/serial/qcom_geni_earlycon.c

Nit, your subject line shoudl say somewhere that this is the qcom
earlycon driver/support, not "earlycon in general".

Thanks for feedback, I will take care of it in next post.


thanks,

greg k-h


--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project



Re: [PATCH 3/3] Serial: Separate out earlycon support

2020-12-07 Thread Akash Asthana

Hi Greg,

On 12/7/2020 2:41 PM, Greg KH wrote:

On Mon, Dec 07, 2020 at 02:17:27PM +0530, Akash Asthana wrote:

Separate out earlycon support from serial driver and remove it's
dependency on QUP wrapper driver.

This enable us to manage earlycon independently and we can re-use the
same earlycon driver for android project which currently uses
downstream version of QUP drivers.

What do you mean by "downstream" here?


Signed-off-by: Akash Asthana 
---
  drivers/tty/serial/Kconfig  |   9 +
  drivers/tty/serial/Makefile |   1 +
  drivers/tty/serial/qcom_geni_earlycon.c | 649 
  drivers/tty/serial/qcom_geni_serial.c   |  97 -

So you are replacing 97 lines of code with 649 lines?  How is this
benefiting anyone?

confused,


We have 2 versions of QUP driver, upstream version(Present in linus 
tree, mostly used for chromium project) and downstream version(belong to 
vendor part of code in GKI design, used for all the other project).


There is need to enable geni earlycon in Google provided boot image for 
GKI to facilitate the debug until real console(belong to vendor code) is up.


Currently it won't be possible because geni earlycon cannot be enabled 
independently, it depends on upstream QUP wrapper driver 
(soc/qcom/qcom-geni-se.c) and upstream serial 
driver(serial/qcom_geni_serial.c).


With this patch I am trying to break any dependency btw earlycon hook 
and QUP kernel drivers, so it can be managed independently.


Regards,

Akash


--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project



[PATCH 3/3] Serial: Separate out earlycon support

2020-12-07 Thread Akash Asthana
Separate out earlycon support from serial driver and remove it's
dependency on QUP wrapper driver.

This enable us to manage earlycon independently and we can re-use the
same earlycon driver for android project which currently uses
downstream version of QUP drivers.

Signed-off-by: Akash Asthana 
---
 drivers/tty/serial/Kconfig  |   9 +
 drivers/tty/serial/Makefile |   1 +
 drivers/tty/serial/qcom_geni_earlycon.c | 649 
 drivers/tty/serial/qcom_geni_serial.c   |  97 -
 4 files changed, 659 insertions(+), 97 deletions(-)
 create mode 100644 drivers/tty/serial/qcom_geni_earlycon.c

diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index 3409e0b..393a017 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -957,6 +957,15 @@ config SERIAL_QCOM_GENI
depends on QCOM_GENI_SE
select SERIAL_CORE
 
+config SERIAL_QCOM_GENI_EARLYCON
+   bool "QCOM GENI Early Console support"
+   select SERIAL_CORE
+   select SERIAL_CORE_CONSOLE
+   select SERIAL_EARLYCON
+   help
+ Serial early console driver for Qualcomm Technologies Inc's GENI
+ based QUP hardware.
+
 config SERIAL_QCOM_GENI_CONSOLE
bool "QCOM GENI Serial Console support"
depends on SERIAL_QCOM_GENI
diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile
index b85d53f..4f9c318 100644
--- a/drivers/tty/serial/Makefile
+++ b/drivers/tty/serial/Makefile
@@ -55,6 +55,7 @@ obj-$(CONFIG_SERIAL_VR41XX) += vr41xx_siu.o
 obj-$(CONFIG_SERIAL_ATMEL) += atmel_serial.o
 obj-$(CONFIG_SERIAL_UARTLITE) += uartlite.o
 obj-$(CONFIG_SERIAL_MSM) += msm_serial.o
+obj-$(CONFIG_SERIAL_QCOM_GENI_EARLYCON) += qcom_geni_earlycon.o
 obj-$(CONFIG_SERIAL_QCOM_GENI) += qcom_geni_serial.o
 obj-$(CONFIG_SERIAL_OMAP) += omap-serial.o
 obj-$(CONFIG_SERIAL_ALTERA_UART) += altera_uart.o
diff --git a/drivers/tty/serial/qcom_geni_earlycon.c 
b/drivers/tty/serial/qcom_geni_earlycon.c
new file mode 100644
index 000..847cc7b
--- /dev/null
+++ b/drivers/tty/serial/qcom_geni_earlycon.c
@@ -0,0 +1,649 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2020, The Linux foundation. All rights reserved.
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* Common SE registers */
+#define GENI_FORCE_DEFAULT_REG 0x20
+#define GENI_FW_REVISION_RO0x68
+#define SE_GENI_DMA_MODE_EN0x258
+#define SE_GENI_M_CMD0 0x600
+#define SE_GENI_M_CMD_CTRL_REG 0x604
+#define SE_GENI_M_IRQ_STATUS   0x610
+#define SE_GENI_M_IRQ_EN   0x614
+#define SE_GENI_M_IRQ_CLEAR0x618
+#define SE_GENI_S_CMD0 0x630
+#define SE_GENI_S_CMD_CTRL_REG 0x634
+#define SE_GENI_S_IRQ_STATUS   0x640
+#define SE_GENI_S_IRQ_EN   0x644
+#define SE_GENI_S_IRQ_CLEAR0x648
+#define SE_GENI_TX_FIFOn   0x700
+#define SE_GENI_RX_FIFOn   0x780
+#define SE_GENI_TX_FIFO_STATUS 0x800
+#define SE_GENI_RX_FIFO_STATUS 0x804
+#define SE_GENI_TX_WATERMARK_REG   0x80c
+#define SE_GENI_RX_WATERMARK_REG   0x810
+#define SE_GENI_RX_RFR_WATERMARK_REG   0x814
+#define SE_DMA_TX_IRQ_CLR  0xc44
+#define SE_DMA_RX_IRQ_CLR  0xd44
+
+/* GENI_FORCE_DEFAULT_REG fields */
+#define FORCE_DEFAULT  BIT(0)
+
+/* GENI_FW_REVISION_RO fields */
+#define FW_REV_PROTOCOL_MSKGENMASK(15, 8)
+#define FW_REV_PROTOCOL_SHFT   8
+
+/* SE_GENI_DMA_MODE_EN */
+#define GENI_DMA_MODE_EN   BIT(0)
+
+/* GENI_M_CMD0 fields */
+#define M_OPCODE_MSK   GENMASK(31, 27)
+#define M_OPCODE_SHFT  27
+#define M_PARAMS_MSK   GENMASK(26, 0)
+
+/* GENI_M_CMD_CTRL_REG */
+#define M_GENI_CMD_CANCEL  BIT(2)
+#define M_GENI_CMD_ABORT   BIT(1)
+#define M_GENI_DISABLE BIT(0)
+
+/* GENI_S_CMD0 fields */
+#define S_OPCODE_MSK   GENMASK(31, 27)
+#define S_OPCODE_SHFT  27
+#define S_PARAMS_MSK   GENMASK(26, 0)
+
+/* GENI_S_CMD_CTRL_REG */
+#define S_GENI_CMD_CANCEL  BIT(2)
+#define S_GENI_CMD_ABORT   BIT(1)
+#define S_GENI_DISABLE BIT(0)
+
+/* GENI_M_IRQ_EN fields */
+#define M_CMD_DONE_EN  BIT(0)
+#define M_CMD_OVERRUN_EN   BIT(1)
+#define M_ILLEGAL_CMD_EN   BIT(2)
+#define M_CMD_FAILURE_EN   BIT(3)
+#define M_CMD_CANCEL_ENBIT(4)
+#define M_CMD_ABORT_EN BIT(5)
+#define M_TIMESTAMP_EN BIT(6)
+#define M_RX_IRQ_ENBIT(7)
+#define M_GP_SYNC_IRQ_0_EN BIT(8)
+#define M_GP_IRQ_0_EN  BIT(9)
+#define M_GP_IRQ_1_EN  BIT(10)
+#define M_GP_IRQ_2_EN  

[PATCH 1/3] soc: qcom-geni-se: Cleanup the code to remove proxy votes

2020-12-07 Thread Akash Asthana
ICC core and platforms drivers supports sync_state feature, which
ensures that the default ICC BW votes from the bootloader is not
removed until all it's consumers are probes.

The proxy votes were needed in case other QUP child drivers
I2C, SPI probes before UART, they can turn off the QUP-CORE clock
which is shared resources for all QUP driver, this causes unclocked
access to HW from earlycon.

Given above support from ICC there is no longer need to maintain
proxy votes on QUP-CORE ICC node from QUP wrapper driver for early
console usecase, the default votes won't be removed until real
console is probed.

Signed-off-by: Akash Asthana 
---
 drivers/soc/qcom/qcom-geni-se.c   | 74 ---
 drivers/tty/serial/qcom_geni_serial.c |  7 
 include/linux/qcom-geni-se.h  |  2 -
 3 files changed, 83 deletions(-)

diff --git a/drivers/soc/qcom/qcom-geni-se.c b/drivers/soc/qcom/qcom-geni-se.c
index f42954e..1fd29f9 100644
--- a/drivers/soc/qcom/qcom-geni-se.c
+++ b/drivers/soc/qcom/qcom-geni-se.c
@@ -3,7 +3,6 @@
 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -92,14 +91,11 @@ struct geni_wrapper {
struct device *dev;
void __iomem *base;
struct clk_bulk_data ahb_clks[NUM_AHB_CLKS];
-   struct geni_icc_path to_core;
 };
 
 static const char * const icc_path_names[] = {"qup-core", "qup-config",
"qup-memory"};
 
-static struct geni_wrapper *earlycon_wrapper;
-
 #define QUP_HW_VER_REG 0x4
 
 /* Common SE registers */
@@ -843,44 +839,11 @@ int geni_icc_disable(struct geni_se *se)
 }
 EXPORT_SYMBOL(geni_icc_disable);
 
-void geni_remove_earlycon_icc_vote(void)
-{
-   struct platform_device *pdev;
-   struct geni_wrapper *wrapper;
-   struct device_node *parent;
-   struct device_node *child;
-
-   if (!earlycon_wrapper)
-   return;
-
-   wrapper = earlycon_wrapper;
-   parent = of_get_next_parent(wrapper->dev->of_node);
-   for_each_child_of_node(parent, child) {
-   if (!of_device_is_compatible(child, "qcom,geni-se-qup"))
-   continue;
-
-   pdev = of_find_device_by_node(child);
-   if (!pdev)
-   continue;
-
-   wrapper = platform_get_drvdata(pdev);
-   icc_put(wrapper->to_core.path);
-   wrapper->to_core.path = NULL;
-
-   }
-   of_node_put(parent);
-
-   earlycon_wrapper = NULL;
-}
-EXPORT_SYMBOL(geni_remove_earlycon_icc_vote);
-
 static int geni_se_probe(struct platform_device *pdev)
 {
struct device *dev = >dev;
struct resource *res;
struct geni_wrapper *wrapper;
-   struct console __maybe_unused *bcon;
-   bool __maybe_unused has_earlycon = false;
int ret;
 
wrapper = devm_kzalloc(dev, sizeof(*wrapper), GFP_KERNEL);
@@ -903,43 +866,6 @@ static int geni_se_probe(struct platform_device *pdev)
}
}
 
-#ifdef CONFIG_SERIAL_EARLYCON
-   for_each_console(bcon) {
-   if (!strcmp(bcon->name, "qcom_geni")) {
-   has_earlycon = true;
-   break;
-   }
-   }
-   if (!has_earlycon)
-   goto exit;
-
-   wrapper->to_core.path = devm_of_icc_get(dev, "qup-core");
-   if (IS_ERR(wrapper->to_core.path))
-   return PTR_ERR(wrapper->to_core.path);
-   /*
-* Put minmal BW request on core clocks on behalf of early console.
-* The vote will be removed earlycon exit function.
-*
-* Note: We are putting vote on each QUP wrapper instead only to which
-* earlycon is connected because QUP core clock of different wrapper
-* share same voltage domain. If core1 is put to 0, then core2 will
-* also run at 0, if not voted. Default ICC vote will be removed ASA
-* we touch any of the core clock.
-* core1 = core2 = max(core1, core2)
-*/
-   ret = icc_set_bw(wrapper->to_core.path, GENI_DEFAULT_BW,
-   GENI_DEFAULT_BW);
-   if (ret) {
-   dev_err(>dev, "%s: ICC BW voting failed for core: %d\n",
-   __func__, ret);
-   return ret;
-   }
-
-   if (of_get_compatible_child(pdev->dev.of_node, "qcom,geni-debug-uart"))
-   earlycon_wrapper = wrapper;
-   of_node_put(pdev->dev.of_node);
-exit:
-#endif
dev_set_drvdata(dev, wrapper);
dev_dbg(dev, "GENI SE Driver probed\n");
return devm_of_platform_populate(dev);
diff --git a/drivers/tty/serial/qcom_geni_serial.c 
b/drivers/tty/serial/qcom_geni_serial.c
index 291649f..0d85b55 100644
--- a/drivers/tty/serial/qcom_geni_serial.c
+++ b/drive

[PATCH 2/3] arm64: dts: qcom: sc7180: Remove QUP-CORE ICC path

2020-12-07 Thread Akash Asthana
We had introduced the QUP-CORE ICC path to put proxy votes from
QUP wrapper on behalf of earlycon, if other users of QUP-CORE turn
off this clock before the real console is probed, unclocked access
to HW was seen from earlycon.

With ICC sync state support proxy votes are no longer need as ICC
will ensure that the default bootloader votes are not removed until
all it's consumer are probed.

We can safely remove ICC path for QUP-CORE clock from QUP wrapper
device.

Signed-off-by: Akash Asthana 
---
 arch/arm64/boot/dts/qcom/sc7180.dtsi | 4 
 1 file changed, 4 deletions(-)

diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi 
b/arch/arm64/boot/dts/qcom/sc7180.dtsi
index 22b832f..cd09b67 100644
--- a/arch/arm64/boot/dts/qcom/sc7180.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi
@@ -763,8 +763,6 @@
#size-cells = <2>;
ranges;
iommus = <_smmu 0x43 0x0>;
-   interconnects = <_virt MASTER_QUP_CORE_0 0 
_virt SLAVE_QUP_CORE_0 0>;
-   interconnect-names = "qup-core";
status = "disabled";
 
i2c0: i2c@88 {
@@ -1054,8 +1052,6 @@
#size-cells = <2>;
ranges;
iommus = <_smmu 0x4c3 0x0>;
-   interconnects = <_virt MASTER_QUP_CORE_1 0 
_virt SLAVE_QUP_CORE_1 0>;
-   interconnect-names = "qup-core";
status = "disabled";
 
i2c6: i2c@a8 {
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project



[PATCH 0/3] Separate out earlycon

2020-12-07 Thread Akash Asthana
Patch 3/3 depends on patch 1/3, Greg would it be possible to
ack patch 3/3. So it could land via QCOM tree.

Akash Asthana (3):
  soc: qcom-geni-se: Cleanup the code to remove proxy votes
  arm64: dts: qcom: sc7180: Remove QUP-CORE ICC path
  Serial: Separate out earlycon support

 arch/arm64/boot/dts/qcom/sc7180.dtsi|   4 -
 drivers/soc/qcom/qcom-geni-se.c |  74 
 drivers/tty/serial/Kconfig  |   9 +
 drivers/tty/serial/Makefile |   1 +
 drivers/tty/serial/qcom_geni_earlycon.c | 649 
 drivers/tty/serial/qcom_geni_serial.c   | 104 -
 include/linux/qcom-geni-se.h|   2 -
 7 files changed, 659 insertions(+), 184 deletions(-)
 create mode 100644 drivers/tty/serial/qcom_geni_earlycon.c

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project



Re: [PATCH] Revert "i2c: qcom-geni: Disable DMA processing on the Lenovo Yoga C630"

2020-12-01 Thread Akash Asthana



On 11/25/2020 12:27 AM, Bjorn Andersson wrote:

A combination of recent bug fixes by Doug Anderson and the proper
definition of iommu streams means that this hack is no longer needed.
Let's clean up the code by reverting '127068abe85b ("i2c: qcom-geni:
Disable DMA processing on the Lenovo Yoga C630")'.

Signed-off-by: Bjorn Andersson 

Reviewed-by: Akash Asthana 

--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project



Re: [PATCH 5/5] i2c: geni: sdm845: dont perform DMA for OnePlus 6 devices

2020-11-17 Thread Akash Asthana



On 11/12/2020 9:52 PM, Caleb Connolly wrote:

The OnePlus 6/T has the same issue as the Yoga c630 causing a crash when DMA
is used for i2c, so disable it.

https://patchwork.kernel.org/patch/11133827/

Signed-off-by: Caleb Connolly 

Reviewed-by : Akash Asthana 

--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project



Re: [PATCH] interconnect: qcom: Ensure that the floor bandwidth value is enforced

2020-10-22 Thread Akash Asthana



On 10/21/2020 9:29 PM, Georgi Djakov wrote:

Take into account the initial bandwidth from the framework and update
the internal sum and max values before committing if needed. This will
ensure that the floor bandwidth values are enforced until the providers
get into sync state.

Fixes: 7d3b0b0d8184 ("interconnect: qcom: Use icc_sync_state")
Signed-off-by: Georgi Djakov 


Thanks Georgi,
I removed proxy ICC BW votes for earlycon driver "qcom_geni" introduced by 
patch [1], trogdor chromium board booted up fine, which use to crash without this patch.

https://patchwork.kernel.org/project/linux-arm-msm/patch/1592908737-7068-3-git-send-email-akash...@codeaurora.org/
 [1]

Tested-by: Akash Asthana 
  


--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project



Re: [PATCH v2 3/3] soc: qcom: geni: Optimize/comment select fifo/dma mode

2020-10-14 Thread Akash Asthana



On 10/14/2020 2:55 AM, Douglas Anderson wrote:

The functions geni_se_select_fifo_mode() and
geni_se_select_fifo_mode() are a little funny.  They read/write a
bunch of memory mapped registers even if they don't change or aren't
relevant for the current protocol.  Let's make them a little more
sane.  We'll also add a comment explaining why we don't do some of the
operations for UART.

NOTE: there is no evidence at all that this makes any performance
difference and it fixes no bugs.  However, it seems (to me) like it
makes the functions a little easier to understand.  Decreasing the
amount of times we read/write memory mapped registers is also nice,
even if we are using "relaxed" variants.

Signed-off-by: Douglas Anderson 

Reviewed-by: Akash Asthana 

The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project



Re: [PATCH 1/3] soc: qcom: geni: More properly switch to DMA mode

2020-10-12 Thread Akash Asthana

Hi Stephen,


  
  static void geni_se_select_dma_mode(struct geni_se *se)

  {
+   u32 proto = geni_se_read_proto(se);
 u32 val;
  
 geni_se_irq_clear(se);
  
+   val = readl_relaxed(se->base + SE_GENI_M_IRQ_EN);

+   if (proto != GENI_SE_UART) {

Not a problem with this patch but it would be great if there was a
comment here (and probably in geni_se_select_fifo_mode() too) indicating
why GENI_SE_UART is special. Is it because GENI_SE_UART doesn't use the
main sequencer? I think that is the reason, but I forgot and reading
this code doesn't tell me that.

Splitting the driver in this way where the logic is in the geni wrapper
and in the engine driver leads to this confusion.


GENI_SE_UART uses main sequencer for TX and secondary for RX transfers 
because it is asynchronous in nature.


That's why  RX related bits (M_RX_FIFO_WATERMARK_EN | 
M_RX_FIFO_LAST_EN)  are not enable in main sequencer for UART.


(M_CMD_DONE_EN | M_TX_FIFO_WATERMARK_EN) bits are controlled from UART 
driver, it's gets enabled and disabled multiple times from start_tx 
,stop_tx respectively.



Regards,

Akash




+   val &= ~(M_CMD_DONE_EN | M_TX_FIFO_WATERMARK_EN);
+   val &= ~(M_RX_FIFO_WATERMARK_EN | M_RX_FIFO_LAST_EN);
+   }
+   writel_relaxed(val, se->base + SE_GENI_M_IRQ_EN);
+
+   val = readl_relaxed(se->base + SE_GENI_S_IRQ_EN);
+   if (proto != GENI_SE_UART)
+   val &= ~S_CMD_DONE_EN;
+   writel_relaxed(val, se->base + SE_GENI_S_IRQ_EN);
+
 val = readl_relaxed(se->base + SE_GENI_DMA_MODE_EN);
 val |= GENI_DMA_MODE_EN;
 writel_relaxed(val, se->base + SE_GENI_DMA_MODE_EN);


--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project



Re: [PATCH 2/3] Revert "i2c: i2c-qcom-geni: Fix DMA transfer race"

2020-10-12 Thread Akash Asthana



On 10/9/2020 4:22 AM, Douglas Anderson wrote:

This reverts commit 02b9aec59243c6240fc42884acc958602146ddf6.

As talked about in the patch ("soc: qcom: geni: More properly switch
to DMA mode"), swapping the order of geni_se_setup_m_cmd() and
geni_se_xx_dma_prep() can sometimes cause corrupted transfers.  Thus
we traded one problem for another.  Now that we've debugged the
problem further and fixed the geni helper functions to more disable
FIFO interrupts when we move to DMA mode we can revert it and end up
with (hopefully) zero problems!

To be explicit, the patch ("soc: qcom: geni: More properly switch
to DMA mode") is a prerequisite for this one.

Fixes: 02b9aec59243 ("i2c: i2c-qcom-geni: Fix DMA transfer race")
Signed-off-by: Douglas Anderson 

Reviewed-by: Akash Asthana 

--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project



Re: [PATCH 1/3] soc: qcom: geni: More properly switch to DMA mode

2020-10-12 Thread Akash Asthana



On 10/9/2020 4:22 AM, Douglas Anderson wrote:

On geni-i2c transfers using DMA, it was seen that if you program the
command (I2C_READ) before calling geni_se_rx_dma_prep() that it could
cause interrupts to fire.  If we get unlucky, these interrupts can
just keep firing (and not be handled) blocking further progress and
hanging the system.

In commit 02b9aec59243 ("i2c: i2c-qcom-geni: Fix DMA transfer race")
we avoided that by making sure we didn't program the command until
after geni_se_rx_dma_prep() was called.  While that avoided the
problems, it also turns out to be invalid.  At least in the TX case we
started seeing sporadic corrupted transfers.  This is easily seen by
adding an msleep() between the DMA prep and the writing of the
command, which makes the problem worse.  That means we need to revert
that commit and find another way to fix the bogus IRQs.

Specifically, after reverting commit 02b9aec59243 ("i2c:
i2c-qcom-geni: Fix DMA transfer race"), I put some traces in.  I found
that the when the interrupts were firing like crazy:
- "m_stat" had bits for M_RX_IRQ_EN, M_RX_FIFO_WATERMARK_EN set.
- "dma" was set.

Further debugging showed that I could make the problem happen more
reliably by adding an "msleep(1)" any time after geni_se_setup_m_cmd()
ran up until geni_se_rx_dma_prep() programmed the length.

A rather simple fix is to change geni_se_select_dma_mode() so it's a
true inverse of geni_se_select_fifo_mode() and disables all the FIFO
related interrupts.  Now the problematic interrupts can't fire and we
can program things in the correct order without worrying.

As part of this, let's also change the writel_relaxed() in the prepare
function to a writel() so that our DMA is guaranteed to be prepared
now that we can't rely on geni_se_setup_m_cmd()'s writel().

NOTE: the only current user of GENI_SE_DMA in mainline is i2c.

Fixes: 37692de5d523 ("i2c: i2c-qcom-geni: Add bus driver for the Qualcomm GENI I2C 
controller")
Fixes: 02b9aec59243 ("i2c: i2c-qcom-geni: Fix DMA transfer race")
Signed-off-by: Douglas Anderson 

Reviewed-by: Akash Asthana 

--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project



Re: [PATCH 5/5] i2c: geni: sdm845: dont perform DMA for the oneplus6

2020-10-08 Thread Akash Asthana

On 10/7/2020 11:19 PM, Caleb Connolly wrote:

The OnePlus 6/T has the same issues as the c630 causing a crash when DMA
is used for i2c, so disable it.

https://patchwork.kernel.org/patch/11133827


Reviewed-by: Akash Asthana 


Signed-off-by: Caleb Connolly 
---
  drivers/i2c/busses/i2c-qcom-geni.c | 6 --
  1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/i2c/busses/i2c-qcom-geni.c 
b/drivers/i2c/busses/i2c-qcom-geni.c
index dead5db3315a..50a0674a6553 100644
--- a/drivers/i2c/busses/i2c-qcom-geni.c
+++ b/drivers/i2c/busses/i2c-qcom-geni.c
@@ -358,7 +358,8 @@ static int geni_i2c_rx_one_msg(struct geni_i2c_dev *gi2c, 
struct i2c_msg *msg,
struct geni_se *se = >se;
size_t len = msg->len;
  
-	if (!of_machine_is_compatible("lenovo,yoga-c630"))

+   if (!of_machine_is_compatible("lenovo,yoga-c630") &&
+   !of_machine_is_compatible("oneplus,oneplus6"))
dma_buf = i2c_get_dma_safe_msg_buf(msg, 32);
  
  	if (dma_buf)

@@ -400,7 +401,8 @@ static int geni_i2c_tx_one_msg(struct geni_i2c_dev *gi2c, 
struct i2c_msg *msg,
struct geni_se *se = >se;
size_t len = msg->len;
  
-	if (!of_machine_is_compatible("lenovo,yoga-c630"))

+   if (!of_machine_is_compatible("lenovo,yoga-c630") &&
+   !of_machine_is_compatible("oneplus,oneplus6"))
dma_buf = i2c_get_dma_safe_msg_buf(msg, 32);
  
  	if (dma_buf)


--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project



Re: [PATCH V6] serial: qcom_geni_serial: To correct QUP Version detection logic

2020-09-30 Thread Akash Asthana



On 9/30/2020 11:35 AM, Paras Sharma wrote:

For QUP IP versions 2.5 and above the oversampling rate is
halved from 32 to 16.

Commit ce734600545f ("tty: serial: qcom_geni_serial: Update
the oversampling rate") is pushed to handle this scenario.
But the existing logic is failing to classify QUP Version 3.0
into the correct group ( 2.5 and above).

As result Serial Engine clocks are not configured properly for
baud rate and garbage data is sampled to FIFOs from the line.

So, fix the logic to detect QUP with versions 2.5 and above.

Fixes: ce734600545f ("tty: serial: qcom_geni_serial: Update the oversampling 
rate")
Signed-off-by: Paras Sharma 

Reviewed-by: Akash Asthana 

--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project



Re: [PATCH v3 2/2] arm64: dts: qcom: Switch sc7180-trogdor to control SPI CS via GPIO

2020-09-21 Thread Akash Asthana



On 9/22/2020 2:57 AM, Douglas Anderson wrote:

As talked about in the patch ("arm64: dts: qcom: sc7180: Provide
pinconf for SPI to use GPIO for CS"), on some boards it makes much
more sense (and is much more efficient) to think of the SPI Chip
Select as a GPIO.  Trogdor is one such board where the SPI parts don't
run in GSI mode and we do a lot of SPI traffic.

Signed-off-by: Douglas Anderson 
Reviewed-by: Stephen Boyd 

Reviewed-by: Akash Asthana 

--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project



Re: [PATCH v3 1/2] arm64: dts: qcom: sc7180: Provide pinconf for SPI to use GPIO for CS

2020-09-21 Thread Akash Asthana



On 9/22/2020 2:57 AM, Douglas Anderson wrote:

When the chip select line is controlled by the QUP, changing CS is a
time consuming operation.  We have to send a command over to the geni
and wait for it to Ack us every time we want to change (both making it
high and low).  To send this command we have to make a choice in
software when we want to control the chip select, we have to either:
A) Wait for the Ack via interrupt which slows down all SPI transfers
(and incurrs extra processing associated with interrupts).
B) Sit in a loop and poll, waiting for the Ack.

Neither A) nor B) is a great option.

We can avoid all of this by realizing that, at least on some boards,
there is no advantage of considering this line to be a geni line.
While it's true that geni _can_ control the line, it's also true that
the line can be a GPIO and there is no downside of viewing it that
way.  Setting a GPIO is a simple MMIO operation.

This patch provides definitions so a board can easily select the GPIO
mode.

NOTE: apparently, it's possible to run the geni in "GSI" mode.  In GSI
the SPI port is allowed to be controlled by more than one user (like
firmware and Linux) and also the port can operate sequences of
operations in one go.  In GSI mode it _would_ be invalid to look at
the chip select as a GPIO because that would prevent other users from
using it.  In theory GSI mode would also avoid some overhead by
allowing us to sequence the chip select better.  However, I'll argue
GSI is not relevant for all boards (and certainly not any boards
supported by mainline today).  Why?
- Apparently to run a SPI chip in GSI mode you need to initialize it
   (in the bootloader) with a different firmware and then it will
   always run in GSI mode.  Since there is no support for GSI mode in
   the current Linux driver, it must be that existing boards don't have
   firmware that's doing that.  Note that the kernel device tree
   describes hardware but also firmware, so it is legitimate to make
   the assumption that we don't have GSI firmware in a given dts file.
- Some boards with sc7180 have SPI connected to the Chrome OS EC or
   security chip (Cr50).  The protocols for talking to cros_ec and cr50
   are extremely complex.  Both drivers in Linux fully lock the bus
   across several distinct SPI transfers.  While I am not an expert on
   GSI mode it feels highly unlikely to me that we'd ever be able to
   enable GSI mode for these devices.

 From a testing perspective, running "flashrom -p ec -r /tmp/foo.bin"
in a loop after this patch shows almost no reduction in time, but the
number of interrupts per command goes from 32357 down to 30611 (about
a 5% reduction).

Signed-off-by: Douglas Anderson 
Reviewed-by: Stephen Boyd 
---

Reviewed-by: Akash Asthana 


--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project



Re: [PATCH V4] serial: qcom_geni_serial: To correct QUP Version detection logic

2020-09-15 Thread Akash Asthana

Hi Paras,

On 9/14/2020 12:49 PM, Paras Sharma wrote:

The current implementation reduces the sampling rate by half
if qup HW version is  greater is than 2.5 by checking if the
geni SE major version is greater than 2 and geni SE minor version
is greater than 5.This implementation fails when the version is
greater than or equal to 3.

Hence, a new macro QUP_SE_VERSION_2_5 is defined having value
for major number 2 and minor number 5 as 0x2005.Hence,if
ver is greater than this value,sampling rate is halved.
This logic would work for any future qup version.


Can we rewrite commit message something like below:

For QUP IP versions 2.5 and above the oversampling rate is halved from 
32 to 16.


Commit ce734600545f ("tty: serial: qcom_geni_serial: Update the 
oversampling rate") is pushed to handle this scenario.


But the existing logic is failing to classify QUP 3.0 to correct group ( 
2.5 and above).


As result SE clocks are not configured properly for baud rate and 
garbage data is sampled to FIFOs from the line.



So, fix the logic to detect QUP with versions 2.5 and above.



Fixes: ce734600545f ("tty: serial: qcom_geni_serial: Update the oversampling 
rate")
Signed-off-by: Paras Sharma 
---
Changes in V4:
Created a new macro QUP_SE_VERSION_2_5 for Qup se version 2.5


You can mention changes in V3 and V2 here.



  drivers/tty/serial/qcom_geni_serial.c | 5 -
  1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/serial/qcom_geni_serial.c 
b/drivers/tty/serial/qcom_geni_serial.c
index f0b1b47..9b74b1e 100644
--- a/drivers/tty/serial/qcom_geni_serial.c
+++ b/drivers/tty/serial/qcom_geni_serial.c
@@ -106,6 +106,9 @@
  /* We always configure 4 bytes per FIFO word */
  #define BYTES_PER_FIFO_WORD   4
  
+/* QUP SE VERSION value for major number 2 and minor number 5 */

+#define QUP_SE_VERSION_2_5  0x2005
+


How about moving this Macro to common header, qcom-geni-se.h so that if 
needed other QUP driver also can use it.


Regards,

Akash


  struct qcom_geni_private_data {
/* NOTE: earlycon port will have NULL here */
struct uart_driver *drv;
@@ -1000,7 +1003,7 @@ static void qcom_geni_serial_set_termios(struct uart_port 
*uport,
sampling_rate = UART_OVERSAMPLING;
/* Sampling rate is halved for IP versions >= 2.5 */
ver = geni_se_get_qup_hw_version(>se);
-   if (GENI_SE_VERSION_MAJOR(ver) >= 2 && GENI_SE_VERSION_MINOR(ver) >= 5)
+   if (ver >= QUP_SE_VERSION_2_5)
sampling_rate /= 2;
  
  	clk_rate = get_clk_div_rate(baud, sampling_rate, _div);


--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project



Re: [PATCH 2/3] spi: spi-geni-qcom: Don't program CS_TOGGLE again and again

2020-09-15 Thread Akash Asthana



On 9/13/2020 2:38 AM, Douglas Anderson wrote:

We always toggle the chip select manually in spi-geni-qcom so that we
can properly implement the Linux API.  There's no reason to program
this to the hardware on every transfer.  Program it once at init and
be done with it.

This saves some part of a microsecond of overhead on each transfer.
While not really noticeable on any real world benchmarks, we might as
well save the time.


Yeah this is configuration part, can be moved to one time init function, 
as per HPG CS_TOGGLE bit of SPI_TRANS_CFG register is used to instruct 
FW to toggle CS line btw each words. We never came across any 
usecase/slave who needs this.


Reviewed-by: Akash Asthana 


Signed-off-by: Douglas Anderson 
---

  drivers/spi/spi-geni-qcom.c | 12 +++-
  1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/spi/spi-geni-qcom.c b/drivers/spi/spi-geni-qcom.c
index 7f0bf0dec466..92d88bf85a90 100644
--- a/drivers/spi/spi-geni-qcom.c
+++ b/drivers/spi/spi-geni-qcom.c
@@ -290,6 +290,7 @@ static int spi_geni_init(struct spi_geni_master *mas)
  {
struct geni_se *se = >se;
unsigned int proto, major, minor, ver;
+   u32 spi_tx_cfg;
  
  	pm_runtime_get_sync(mas->dev);
  
@@ -322,6 +323,11 @@ static int spi_geni_init(struct spi_geni_master *mas)
  
  	geni_se_select_mode(se, GENI_SE_FIFO);
  
+	/* We always control CS manually */

+   spi_tx_cfg = readl(se->base + SE_SPI_TRANS_CFG);
+   spi_tx_cfg &= ~CS_TOGGLE;
+   writel(spi_tx_cfg, se->base + SE_SPI_TRANS_CFG);
+
pm_runtime_put(mas->dev);
return 0;
  }
@@ -331,7 +337,7 @@ static void setup_fifo_xfer(struct spi_transfer *xfer,
u16 mode, struct spi_master *spi)
  {
u32 m_cmd = 0;
-   u32 spi_tx_cfg, len;
+   u32 len;
struct geni_se *se = >se;
int ret;
  
@@ -350,7 +356,6 @@ static void setup_fifo_xfer(struct spi_transfer *xfer,

spin_lock_irq(>lock);
spin_unlock_irq(>lock);
  
-	spi_tx_cfg = readl(se->base + SE_SPI_TRANS_CFG);

if (xfer->bits_per_word != mas->cur_bits_per_word) {
spi_setup_word_len(mas, mode, xfer->bits_per_word);
mas->cur_bits_per_word = xfer->bits_per_word;
@@ -364,8 +369,6 @@ static void setup_fifo_xfer(struct spi_transfer *xfer,
mas->tx_rem_bytes = 0;
mas->rx_rem_bytes = 0;
  
-	spi_tx_cfg &= ~CS_TOGGLE;

-
if (!(mas->cur_bits_per_word % MIN_WORD_LEN))
len = xfer->len * BITS_PER_BYTE / mas->cur_bits_per_word;
else
@@ -384,7 +387,6 @@ static void setup_fifo_xfer(struct spi_transfer *xfer,
writel(len, se->base + SE_SPI_RX_TRANS_LEN);
mas->rx_rem_bytes = xfer->len;
}
-   writel(spi_tx_cfg, se->base + SE_SPI_TRANS_CFG);
  
  	/*

 * Lock around right before we start the transfer since our


--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project



Re: [PATCH 1/3] spi: spi-geni-qcom: Use the FIFO even more

2020-09-15 Thread Akash Asthana



On 9/13/2020 2:37 AM, Douglas Anderson wrote:

In commit 902481a78ee4 ("spi: spi-geni-qcom: Actually use our FIFO") I
explained that the maximum size we could program the FIFO was
"mas->tx_fifo_depth - 3" but that I chose "mas->tx_fifo_depth()"
because I was worried about decreased bandwidth.

Since that time:
* All the interconnect patches have landed, making things run at the
   proper speed.
* I've done more measurements.

This lets me confirm that there's really no downside of using the FIFO
more.  Specifically I did "flashrom -p ec -r /tmp/foo.bin" on a
Chromebook and averaged over several runs.

Before: It took 6.66 seconds and 59669 interrupts fired.
After:  It took 6.66 seconds and 47992 interrupts fired.


Reviewed-by: Akash Asthana 


Signed-off-by: Douglas Anderson 
---



--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project



Re: [PATCH] spi: spi-geni-qcom: Don't wait to start 1st transfer if transmitting

2020-09-14 Thread Akash Asthana



On 9/12/2020 11:47 PM, Douglas Anderson wrote:

If we're sending bytes over SPI, we know the FIFO is empty at the
start of the transfer.  There's no reason to wait for the interrupt
telling us to start--we can just start right away.  Then if we
transmit everything in one swell foop we don't even need to bother
listening for TX interrupts.

In a test of "flashrom -p ec -r /tmp/foo.bin" interrupts were reduced
from ~30560 to ~29730, about a 3% savings.

This patch looks bigger than it is because I moved a few functions
rather than adding a forward declaration.  The only actual change to
geni_spi_handle_tx() was to make it return a bool indicating if there
is more to tx.

Reviewed-by: Akash Asthana 

Signed-off-by: Douglas Anderson


--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project



Re: [PATCH] tty: serial: qcom_geni_serial: 115.2 is a better console default than 9600

2020-09-14 Thread Akash Asthana



On 9/11/2020 8:30 PM, Douglas Anderson wrote:

Commit c5cbc78acf69 ("tty: serial: qcom_geni_serial: Initialize baud
in qcom_geni_console_setup") fixed a bug by initting a variable that
was used in some cases without initialization.  However, the "default"
baud rate picked by that CL was probably not the best choice.  The
chances that anyone out there is trying to run a system with kernel
messages piped out over a 9600 baud serial port is just about nil.
Console messages are printed in a blocking manner.  At 9600 baud we
print about 1 character per millisecond which means that printing a
40-byte message to the console will take ~40 ms.  While it would
probably work, it's going to make boot _very_ slow and probably cause
the occasional timeout here and there in drivers (heck, even at 115200
console delays can wreck havoc).

This has already bit at least two people that I'm aware of that tried
to enable serial console by just adding "console=ttyMSM0" (instead of
"console=ttyMSM0,115200n8") to the command line, so it seems like it'd
be nice to fix.

Let's switch the default to 115200.

Reviewed-by: Akash Asthana 

Signed-off-by: Douglas Anderson 
---



--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project



Re: [PATCH V2 2/2] i2c: i2c-qcom-geni: Add shutdown callback for i2c

2020-08-26 Thread Akash Asthana

Hi Roja,

On 8/20/2020 4:05 PM, Roja Rani Yarubandi wrote:

If the hardware is still accessing memory after SMMU translation
is disabled (as part of smmu shutdown callback), then the
IOVAs (I/O virtual address) which it was using will go on the bus
as the physical addresses which will result in unknown crashes
like NoC/interconnect errors.

So, implement shutdown callback to i2c driver to unmap DMA mappings
during system "reboot" or "shutdown".

Signed-off-by: Roja Rani Yarubandi 
---
Changes in V2:
  - As per Stephen's comments added seperate function for stop transfer,
fixed minor nitpicks.

  drivers/i2c/busses/i2c-qcom-geni.c | 43 ++
  include/linux/qcom-geni-se.h   |  5 
  2 files changed, 48 insertions(+)

diff --git a/drivers/i2c/busses/i2c-qcom-geni.c 
b/drivers/i2c/busses/i2c-qcom-geni.c
index 1fda5c7c2cfc..d07f2f33bb75 100644
--- a/drivers/i2c/busses/i2c-qcom-geni.c
+++ b/drivers/i2c/busses/i2c-qcom-geni.c
@@ -486,6 +486,28 @@ static int geni_i2c_xfer(struct i2c_adapter *adap,
return ret;
  }
  
+static void geni_i2c_stop_xfer(struct geni_i2c_dev *gi2c)

+{
+   u32 val;
+   struct geni_se *se = >se;
+
+   val = readl_relaxed(gi2c->se.base + SE_DMA_DEBUG_REG0);
+   if (val & DMA_TX_ACTIVE) {
+   geni_i2c_abort_xfer(gi2c);
+   gi2c->cur_wr = 0;
+   if (gi2c->err)
+   geni_i2c_tx_fsm_rst(gi2c);
+   geni_se_tx_dma_unprep(se, gi2c->tx_dma, gi2c->xfer_len);
+   }

should be 'else if', because TX and RX can't happen parallel.

+   if (val & DMA_RX_ACTIVE) {
+   geni_i2c_abort_xfer(gi2c);
+   gi2c->cur_rd = 0;
+   if (gi2c->err)
+   geni_i2c_rx_fsm_rst(gi2c);
+   geni_se_rx_dma_unprep(se, gi2c->rx_dma, gi2c->xfer_len);
+   }
+}
+
  static u32 geni_i2c_func(struct i2c_adapter *adap)
  {
return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK);
@@ -617,6 +639,26 @@ static int geni_i2c_remove(struct platform_device *pdev)
return 0;
  }
  
+static void geni_i2c_shutdown(struct platform_device *pdev)

+{
+   int ret;
+   u32 dma;
+   struct geni_i2c_dev *gi2c = platform_get_drvdata(pdev);
+   struct geni_se *se = >se;
+
+   ret = pm_runtime_get_sync(gi2c->se.dev);
+   if (ret < 0) {
+   dev_err(gi2c->se.dev, "Failed to resume device: %d\n", ret);
+   return;
+   }
+
+   dma = readl_relaxed(se->base + SE_GENI_DMA_MODE_EN);


Wrt to current issue context it may be suffice to stop just DMA mode 
transfers but why not stop all mode of active transfer during shutdown 
in a generic way.


Regards,

Akash


+   if (dma)
+   geni_i2c_stop_xfer(gi2c);
+
+   pm_runtime_put_sync_suspend(gi2c->se.dev);
+}
+
  static int __maybe_unused geni_i2c_runtime_suspend(struct device *dev)
  {
int ret;
@@ -677,6 +719,7 @@ MODULE_DEVICE_TABLE(of, geni_i2c_dt_match);
  static struct platform_driver geni_i2c_driver = {
.probe  = geni_i2c_probe,
.remove = geni_i2c_remove,
+   .shutdown = geni_i2c_shutdown,
.driver = {
.name = "geni_i2c",
.pm = _i2c_pm_ops,
diff --git a/include/linux/qcom-geni-se.h b/include/linux/qcom-geni-se.h
index dd464943f717..c3c016496d98 100644
--- a/include/linux/qcom-geni-se.h
+++ b/include/linux/qcom-geni-se.h
@@ -77,6 +77,7 @@ struct geni_se {
  #define SE_DMA_RX_FSM_RST 0xd58
  #define SE_HW_PARAM_0 0xe24
  #define SE_HW_PARAM_1 0xe28
+#define SE_DMA_DEBUG_REG0  0xe40
  
  /* GENI_FORCE_DEFAULT_REG fields */

  #define FORCE_DEFAULT BIT(0)
@@ -207,6 +208,10 @@ struct geni_se {
  #define RX_GENI_CANCEL_IRQBIT(11)
  #define RX_GENI_GP_IRQ_EXTGENMASK(13, 12)
  
+/* SE_DMA_DEBUG_REG0 Register fields */

+#define DMA_TX_ACTIVE  BIT(0)
+#define DMA_RX_ACTIVE  BIT(1)
+
  /* SE_HW_PARAM_0 fields */
  #define TX_FIFO_WIDTH_MSK GENMASK(29, 24)
  #define TX_FIFO_WIDTH_SHFT24


--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project



Re: [PATCH V2 1/2] i2c: i2c-qcom-geni: Store DMA mapping data in geni_i2c_dev struct

2020-08-26 Thread Akash Asthana

Hi Roja,

On 8/20/2020 4:05 PM, Roja Rani Yarubandi wrote:

Store DMA mapping data in geni_i2c_dev struct to enhance DMA mapping
data scope. For example during shutdown callback to unmap DMA mapping,
this stored DMA mapping data can be used to call geni_se_tx_dma_unprep
and geni_se_rx_dma_unprep functions.

Signed-off-by: Roja Rani Yarubandi 
---
Changes in V2:
  - As per Stephen's comments, changed commit text, fixed minor nitpicks.

  drivers/i2c/busses/i2c-qcom-geni.c | 7 +++
  1 file changed, 7 insertions(+)

diff --git a/drivers/i2c/busses/i2c-qcom-geni.c 
b/drivers/i2c/busses/i2c-qcom-geni.c
index 7f130829bf01..1fda5c7c2cfc 100644
--- a/drivers/i2c/busses/i2c-qcom-geni.c
+++ b/drivers/i2c/busses/i2c-qcom-geni.c
@@ -86,6 +86,9 @@ struct geni_i2c_dev {
u32 clk_freq_out;
const struct geni_i2c_clk_fld *clk_fld;
int suspended;
+   dma_addr_t tx_dma;
+   dma_addr_t rx_dma;
+   size_t xfer_len;
  };
  
  struct geni_i2c_err_log {

@@ -358,6 +361,7 @@ static int geni_i2c_rx_one_msg(struct geni_i2c_dev *gi2c, 
struct i2c_msg *msg,
struct geni_se *se = >se;
size_t len = msg->len;
  
+	gi2c->xfer_len = msg->len;


nit: gi2c->xfer = len, for tx_one_msg as well.

Regards,

Akash


if (!of_machine_is_compatible("lenovo,yoga-c630"))
dma_buf = i2c_get_dma_safe_msg_buf(msg, 32);
  
@@ -384,6 +388,7 @@ static int geni_i2c_rx_one_msg(struct geni_i2c_dev *gi2c, struct i2c_msg *msg,

if (dma_buf) {
if (gi2c->err)
geni_i2c_rx_fsm_rst(gi2c);
+   gi2c->rx_dma = rx_dma;
geni_se_rx_dma_unprep(se, rx_dma, len);
i2c_put_dma_safe_msg_buf(dma_buf, msg, !gi2c->err);
}
@@ -400,6 +405,7 @@ static int geni_i2c_tx_one_msg(struct geni_i2c_dev *gi2c, 
struct i2c_msg *msg,
struct geni_se *se = >se;
size_t len = msg->len;
  
+	gi2c->xfer_len = msg->len;

if (!of_machine_is_compatible("lenovo,yoga-c630"))
dma_buf = i2c_get_dma_safe_msg_buf(msg, 32);
  
@@ -429,6 +435,7 @@ static int geni_i2c_tx_one_msg(struct geni_i2c_dev *gi2c, struct i2c_msg *msg,

if (dma_buf) {
if (gi2c->err)
geni_i2c_tx_fsm_rst(gi2c);
+   gi2c->tx_dma = tx_dma;
geni_se_tx_dma_unprep(se, tx_dma, len);
i2c_put_dma_safe_msg_buf(dma_buf, msg, !gi2c->err);
}


--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project



Re: [PATCH] serial: qcom_geni_serial: Fix recent kdb hang

2020-08-11 Thread Akash Asthana



On 8/11/2020 2:56 AM, Doug Anderson wrote:

Hi,

On Mon, Aug 10, 2020 at 5:32 AM Akash Asthana  wrote:

Hi Doug,

On 8/7/2020 10:49 AM, Douglas Anderson wrote:

The commit e42d6c3ec0c7 ("serial: qcom_geni_serial: Make kgdb work
even if UART isn't console") worked pretty well and I've been doing a
lot of debugging with it.  However, recently I typed "dmesg" in kdb
and then held the space key down to scroll through the pagination.  My
device hung.  This was repeatable and I found that it was introduced
with the aforementioned commit.

It turns out that there are some strange boundary cases in geni where
in some weird situations it will signal RX_LAST but then will put 0 in
RX_LAST_BYTE.  This means that the entire last FIFO entry is valid.

IMO that means we received a word in RX_FIFO and it is the last word
hence RX_LAST bit is set.

What you say would make logical sense, but it's not how I have
observed geni to work.  See below.



RX_LAST_BYTE is 0 means none of the bytes are valid in the last word.

This would imply that qcom_geni_serial_handle_rx() is also broken
though, wouldn't it?  Specifically imagine that WORD_CNT is 1 and
RX_LAST is set and RX_LAST_BYTE_VALID is true.  Here's the logic from
that function:

   total_bytes = BYTES_PER_FIFO_WORD * (word_cnt - 1);
   if (last_word_partial && last_word_byte_cnt)
 total_bytes += last_word_byte_cnt;
   else
 total_bytes += BYTES_PER_FIFO_WORD;
   port->handle_rx(uport, total_bytes, drop);

As you can see that logic will set "total_bytes" to 4 in the case I'm
talking about.


Yeah IMO as per theory this should also be corrected but since you have 
already pulled out few experiment to prove garbage data issue(which I  
was suspecting) is not seen.


It's already consistent with existing logic and it behaves well 
practically . So the changes could be merge. Meanwhile I am checking 
with HW team to get clarity.






In such scenario we should just read RX_FIFO buffer (to empty it),
discard the word and return NO_POLL_CHAR. Something like below.

-

  else
  private_data->poll_cached_bytes_cnt = 4;

  private_data->poll_cached_bytes =
  readl(uport->membase + SE_GENI_RX_FIFOn);
  }

+if (!private_data->poll_cached_bytes_cnt)
+  return NO_POLL_CHAR;
  private_data->poll_cached_bytes_cnt--;
  ret = private_data->poll_cached_bytes & 0xff;
-

Please let me know whether above code helps.

Your code will avoid the hang.  Yes.  ...but it will drop bytes.  I
devised a quick-n-dirty test.  Here's a test of your code:
I assumed those as invalid bytes and don't wanted to read them so yeah 
dropping of bytes was expected.


https://crrev.com/c/2346886

...and here's a test of my code:

https://crrev.com/c/2346884

I had to keep a buffer around since it's hard to debug the serial
driver.  In both cases I put "DOUG" into the buffer when I detect this
case.  If my theory about how geni worked was wrong then we should
expect to see some garbage in the buffer right after the DOUG, right?
...but my code gets the alphabet in nice sequence.  Your code drops 4
bytes.

Yeah I was expecting garbage data.



NOTE: while poking around with the above two test patches I found it
was pretty easy to get geni to drop bytes / hit overflow cases and
also to insert bogus 0 bytes in the stream (I believe these are
related).  I was able to reproduce this:
* With ${SUBJECT} patch in place.
* With your proposed patch.
* With the recent "geni" patches reverted (in other words back to 1
byte per FIFO entry).

It's not terribly surprising that we're overflowing since I believe
kgdb isn't too keen to read characters at the same time it's writing.
That doesn't explain the weird 0-bytes that geni seemed to be
inserting, but at least it would explain the overflows.  However, even
after I fixed this I _still_ was getting problems.  Specifically geni
seemed to be hiding bytes from me until it was too late.  I put
logging in and would see this:

1 word in FIFO - wxyz
1 word in FIFO (last set, last FIFO has 1 byte) - \n
Check again, still 0 bytes in FIFO
Suddenly 16 bytes are in FIFO and S_RX_FIFO_WR_ERR_EN is set.


RX data first stored in RX_ASYNC_FIFO then it's transfered to RX_FIFO

When get_char is called and we observe 0 bytes in RX_FIFO, most probably 
data is not transfered from RX_ASYNC_FIFO to RX_FIFO.


BITS 27:25 of SE_GENI_RX_FIFO_STATUS register shows RX_ASYNC_FIFO word 
count.





I spent a whole bunch of time poking at this and couldn't find any
sort of workaround.  P

Re: [PATCH] serial: qcom_geni_serial: Fix recent kdb hang

2020-08-10 Thread Akash Asthana

Hi Doug,

On 8/7/2020 10:49 AM, Douglas Anderson wrote:

The commit e42d6c3ec0c7 ("serial: qcom_geni_serial: Make kgdb work
even if UART isn't console") worked pretty well and I've been doing a
lot of debugging with it.  However, recently I typed "dmesg" in kdb
and then held the space key down to scroll through the pagination.  My
device hung.  This was repeatable and I found that it was introduced
with the aforementioned commit.

It turns out that there are some strange boundary cases in geni where
in some weird situations it will signal RX_LAST but then will put 0 in
RX_LAST_BYTE.  This means that the entire last FIFO entry is valid.


IMO that means we received a word in RX_FIFO and it is the last word 
hence RX_LAST bit is set.


RX_LAST_BYTE is 0 means none of the bytes are valid in the last word.

In such scenario we should just read RX_FIFO buffer (to empty it), 
discard the word and return NO_POLL_CHAR. Something like below.


-

    else
    private_data->poll_cached_bytes_cnt = 4;

    private_data->poll_cached_bytes =
    readl(uport->membase + SE_GENI_RX_FIFOn);
    }

+    if (!private_data->poll_cached_bytes_cnt)
+  return NO_POLL_CHAR;
    private_data->poll_cached_bytes_cnt--;
    ret = private_data->poll_cached_bytes & 0xff;
-

Please let me know whether above code helps.

I am not sure about what all scenario can leads to this behavior from 
hardware, I will try to get an answer from hardware team.


Any error bit was set for SE_GENI_S_IRQ_STATUS & SE_GENI_M_IRQ_STATUS 
registers?



I guess the hang was seen because *poll_cached_bytes_cnt* is unsigned 
int and it's value was 0, when it's decremented by 1 it's value become 
'4294967295' (very large) and dummy RX (0x00) would happen that


many times before reading any actual RX transfers/bytes.

Regards,

Akash



This weird corner case is handled in qcom_geni_serial_handle_rx()
where you can see that we only honor RX_LAST_BYTE if RX_LAST is set
_and_ RX_LAST_BYTE is non-zero.  If either of these is not true we use
BYTES_PER_FIFO_WORD (4) for the size of the last FIFO word.

Let's fix kgdb.  While at it, also use the proper #define for 4.

Fixes: e42d6c3ec0c7 ("serial: qcom_geni_serial: Make kgdb work even if UART isn't 
console")
Signed-off-by: Douglas Anderson 
---

  drivers/tty/serial/qcom_geni_serial.c | 9 +++--
  1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/qcom_geni_serial.c 
b/drivers/tty/serial/qcom_geni_serial.c
index 07b7b6b05b8b..e27077656939 100644
--- a/drivers/tty/serial/qcom_geni_serial.c
+++ b/drivers/tty/serial/qcom_geni_serial.c
@@ -361,11 +361,16 @@ static int qcom_geni_serial_get_char(struct uart_port 
*uport)
return NO_POLL_CHAR;
  
  		if (word_cnt == 1 && (status & RX_LAST))

+   /*
+* NOTE: If RX_LAST_BYTE_VALID is 0 it needs to be
+* treated as if it was BYTES_PER_FIFO_WORD.
+*/
private_data->poll_cached_bytes_cnt =
(status & RX_LAST_BYTE_VALID_MSK) >>
RX_LAST_BYTE_VALID_SHFT;
-   else
-   private_data->poll_cached_bytes_cnt = 4;
+
+   if (private_data->poll_cached_bytes_cnt == 0)
+   private_data->poll_cached_bytes_cnt = 
BYTES_PER_FIFO_WORD;
  
  		private_data->poll_cached_bytes =

readl(uport->membase + SE_GENI_RX_FIFOn);


--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project



Re: [PATCH V2 3/3] tty: serial: qcom_geni_serial: Fix the UART wakeup issue

2020-07-27 Thread Akash Asthana



On 7/24/2020 9:28 AM, satya priya wrote:

As a part of system suspend we call uart_port_suspend from the
Serial driver, which calls set_mctrl passing mctrl as NULL. This
makes RFR high(NOT_READY) during suspend.

Due to this BT SoC is not able to send wakeup bytes to UART during
suspend. Included if check for non-suspend case to keep RFR low
during suspend.



Reviewed-by: Akash Asthana 


Signed-off-by: satya priya 
---
Changes in V2:
  - This patch fixes the UART flow control issue during suspend.
Newly added in V2.

  drivers/tty/serial/qcom_geni_serial.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/tty/serial/qcom_geni_serial.c 
b/drivers/tty/serial/qcom_geni_serial.c
index 07b7b6b..7108dfc 100644
--- a/drivers/tty/serial/qcom_geni_serial.c
+++ b/drivers/tty/serial/qcom_geni_serial.c
@@ -242,7 +242,7 @@ static void qcom_geni_serial_set_mctrl(struct uart_port 
*uport,
if (mctrl & TIOCM_LOOP)
port->loopback = RX_TX_CTS_RTS_SORTED;
  
-	if (!(mctrl & TIOCM_RTS))

+   if ((!(mctrl & TIOCM_RTS)) && (!(uport->suspended)))
uart_manual_rfr = UART_MANUAL_RFR_EN | UART_RFR_NOT_READY;
writel(uart_manual_rfr, uport->membase + SE_UART_MANUAL_RFR);
  }


--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project



Re: [PATCH V2 2/3] arm64: dts: qcom: sc7180: Add sleep pin ctrl for BT uart

2020-07-27 Thread Akash Asthana



On 7/24/2020 9:28 AM, satya priya wrote:

Add sleep pin ctrl for BT uart, and also change the bias
configuration to match Bluetooth module.



Reviewed-by: Akash Asthana 


Signed-off-by: satya priya 
---
Changes in V2:
  - This patch adds sleep state for BT UART. Newly added in V2.

  arch/arm64/boot/dts/qcom/sc7180-idp.dts | 42 -
  1 file changed, 36 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/boot/dts/qcom/sc7180-idp.dts 
b/arch/arm64/boot/dts/qcom/sc7180-idp.dts
index 26cc491..bc919f2 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-idp.dts
+++ b/arch/arm64/boot/dts/qcom/sc7180-idp.dts
@@ -469,20 +469,50 @@
  
  _uart3_default {

pinconf-cts {
-   /*
-* Configure a pull-down on 38 (CTS) to match the pull of
-* the Bluetooth module.
-*/
+   /* Configure no pull on 38 (CTS) to match Bluetooth module */
pins = "gpio38";
+   bias-disable;
+   };
+
+   pinconf-rts {
+   /* We'll drive 39 (RTS), so configure pull-down */
+   pins = "gpio39";
+   drive-strength = <2>;
bias-pull-down;
+   };
+
+   pinconf-tx {
+   /* We'll drive 40 (TX), so no pull */
+   pins = "gpio40";
+   drive-strength = <2>;
+   bias-disable;
output-high;
};
  
+	pinconf-rx {

+   /*
+* Configure a pull-up on 41 (RX). This is needed to avoid
+* garbage data when the TX pin of the Bluetooth module is
+* in tri-state (module powered off or not driving the
+* signal yet).
+*/
+   pins = "gpio41";
+   bias-pull-up;
+   };
+};
+
+_uart3_sleep {
+   pinconf-cts {
+   /* Configure no-pull on 38 (CTS) to match Bluetooth module */
+   pins = "gpio38";
+   bias-disable;
+   };
+
pinconf-rts {
-   /* We'll drive 39 (RTS), so no pull */
+   /* We'll drive 39 (RTS), so configure pull-down */
pins = "gpio39";
drive-strength = <2>;
-   bias-disable;
+   bias-pull-down;
};
  
  	pinconf-tx {


--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project



Re: [PATCH V2 1/3] arm64: dts: sc7180: Add wakeup support over UART RX

2020-07-27 Thread Akash Asthana



On 7/24/2020 9:28 AM, satya priya wrote:

Add the necessary pinctrl and interrupts to make UART
wakeup capable.



Reviewed-by: Akash Asthana 


Signed-off-by: satya priya 
---
Changes in V2:
  - As per Matthias's comment added wakeup support for all the UARTs
of SC7180.

  arch/arm64/boot/dts/qcom/sc7180.dtsi | 98 ++--
  1 file changed, 84 insertions(+), 14 deletions(-)

diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi 
b/arch/arm64/boot/dts/qcom/sc7180.dtsi
index 16df08d..044a4d0 100644
--- a/arch/arm64/boot/dts/qcom/sc7180.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi
@@ -787,9 +787,11 @@
reg = <0 0x0088 0 0x4000>;
clock-names = "se";
clocks = < GCC_QUPV3_WRAP0_S0_CLK>;
-   pinctrl-names = "default";
+   pinctrl-names = "default", "sleep";
pinctrl-0 = <_uart0_default>;
-   interrupts = ;
+   pinctrl-1 = <_uart0_sleep>;
+   interrupts-extended = < GIC_SPI 601 
IRQ_TYPE_LEVEL_HIGH>,
+   < 37 
IRQ_TYPE_EDGE_FALLING>;
power-domains = < SC7180_CX>;
operating-points-v2 = <_opp_table>;
interconnects = <_virt MASTER_QUP_CORE_0 
_virt SLAVE_QUP_CORE_0>,
@@ -839,9 +841,11 @@
reg = <0 0x00884000 0 0x4000>;
clock-names = "se";
clocks = < GCC_QUPV3_WRAP0_S1_CLK>;
-   pinctrl-names = "default";
+   pinctrl-names = "default", "sleep";
pinctrl-0 = <_uart1_default>;
-   interrupts = ;
+   pinctrl-1 = <_uart1_sleep>;
+   interrupts-extended = < GIC_SPI 602 
IRQ_TYPE_LEVEL_HIGH>,
+   < 3 
IRQ_TYPE_EDGE_FALLING>;
power-domains = < SC7180_CX>;
operating-points-v2 = <_opp_table>;
interconnects = <_virt MASTER_QUP_CORE_0 
_virt SLAVE_QUP_CORE_0>,
@@ -925,9 +929,11 @@
reg = <0 0x0088c000 0 0x4000>;
clock-names = "se";
clocks = < GCC_QUPV3_WRAP0_S3_CLK>;
-   pinctrl-names = "default";
+   pinctrl-names = "default", "sleep";
pinctrl-0 = <_uart3_default>;
-   interrupts = ;
+   pinctrl-1 = <_uart3_sleep>;
+   interrupts-extended = < GIC_SPI 604 
IRQ_TYPE_LEVEL_HIGH>,
+   < 41 
IRQ_TYPE_EDGE_FALLING>;
power-domains = < SC7180_CX>;
operating-points-v2 = <_opp_table>;
interconnects = <_virt MASTER_QUP_CORE_0 
_virt SLAVE_QUP_CORE_0>,
@@ -1011,9 +1017,11 @@
reg = <0 0x00894000 0 0x4000>;
clock-names = "se";
clocks = < GCC_QUPV3_WRAP0_S5_CLK>;
-   pinctrl-names = "default";
+   pinctrl-names = "default", "sleep";
pinctrl-0 = <_uart5_default>;
-   interrupts = ;
+   pinctrl-1 = <_uart5_sleep>;
+   interrupts-extended = < GIC_SPI 606 
IRQ_TYPE_LEVEL_HIGH>,
+   < 28 
IRQ_TYPE_EDGE_FALLING>;
power-domains = < SC7180_CX>;
operating-points-v2 = <_opp_table>;
interconnects = <_virt MASTER_QUP_CORE_0 
_virt SLAVE_QUP_CORE_0>,
@@ -1078,9 +1086,11 @@
reg = <0 0x00a8 0 0x4000>;
clock-names = "se";
clocks = < GCC_QUPV3_WRAP1_S0_CLK>;
-   pinctrl-names = "default";
+   pinctrl-names = "default&quo

Re: [PATCH v2] i2c: i2c-qcom-geni: Fix DMA transfer race

2020-07-27 Thread Akash Asthana

On 7/26/2020 6:17 PM, Wolfram Sang wrote:

On Thu, Jul 23, 2020 at 09:56:34PM +0200, Wolfram Sang wrote:

On Wed, Jul 22, 2020 at 03:00:21PM -0700, Douglas Anderson wrote:

When I have KASAN enabled on my kernel and I start stressing the
touchscreen my system tends to hang.  The touchscreen is one of the
only things that does a lot of big i2c transfers and ends up hitting
the DMA paths in the geni i2c driver.  It appears that KASAN adds
enough delay in my system to tickle a race condition in the DMA setup
code.

When the system hangs, I found that it was running the geni_i2c_irq()
over and over again.  It had these:

m_stat   = 0x0480
rx_st= 0x3011
dm_tx_st = 0x
dm_rx_st = 0x
dma  = 0x0001

Notably we're in DMA mode but are getting M_RX_IRQ_EN and
M_RX_FIFO_WATERMARK_EN over and over again.

Putting some traces in geni_i2c_rx_one_msg() showed that when we
failed we were getting to the start of geni_i2c_rx_one_msg() but were
never executing geni_se_rx_dma_prep().

I believe that the problem here is that we are starting the geni
command before we run geni_se_rx_dma_prep().  If a transfer makes it
far enough before we do that then we get into the state I have
observed.  Let's change the order, which seems to work fine.

Although problems were seen on the RX path, code inspection suggests
that the TX should be changed too.  Change it as well.

Fixes: 37692de5d523 ("i2c: i2c-qcom-geni: Add bus driver for the Qualcomm GENI I2C 
controller")
Signed-off-by: Douglas Anderson 
Tested-by: Sai Prakash Ranjan 
Reviewed-by: Akash Asthana 

Applied to for-current, thanks!

Glad we got this sorted. I just wondered that Alok wasn't part of the
discussion. Is he still interested in maintaining the driver? Also
because there is an unprocessed patch left for this driver:

http://patchwork.ozlabs.org/project/linux-i2c/patch/20191103212204.13606-1-colin.k...@canonical.com/


Alok has moved out of GENI team, he no longer supports GENI I2C drivers.

I have posted a patch to update maintainers list. Patch: 
https://patchwork.kernel.org/patch/11686541/ [MAINTAINERS: Update Geni 
I2C maintainers list]


Also, Girish Mahadevan, Sagar Dharia and Karthikeyan Ramasubramanian  no 
longer supports GENI drivers.


Regards,

Akash




--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project



[PATCH] MAINTAINERS: Update GENI I2C maintainers list

2020-07-27 Thread Akash Asthana
Alok Chauhan has moved out of GENI team, he no longer supports GENI I2C
driver, remove him from maintainer list.

Add Akash Asthana & Mukesh Savaliya as maintainers for GENI I2C drivers.

Signed-off-by: Akash Asthana 
---
 MAINTAINERS | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 235ab38..d216344 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -13845,7 +13845,8 @@ F:  
drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
 F: Documentation/devicetree/bindings/net/qcom,ethqos.txt
 
 QUALCOMM GENERIC INTERFACE I2C DRIVER
-M: Alok Chauhan 
+M: Akash Asthana 
+M: Mukesh Savaliya 
 L: linux-...@vger.kernel.org
 L: linux-arm-...@vger.kernel.org
 S: Supported
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project



Re: [PATCH] i2c: qcom-geni: fix spelling mistake "unepxected" -> "unexpected"

2020-07-27 Thread Akash Asthana



On 7/27/2020 1:25 PM, Akash Asthana wrote:


On 11/4/2019 2:52 AM, Colin King wrote:

From: Colin Ian King 

There is a spelling mistake in an error message string, fix it.

Signed-off-by: Colin Ian King 
---
  drivers/i2c/busses/i2c-qcom-geni.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/i2c/busses/i2c-qcom-geni.c 
b/drivers/i2c/busses/i2c-qcom-geni.c

index 17abf60c94ae..387fb5a83471 100644
--- a/drivers/i2c/busses/i2c-qcom-geni.c
+++ b/drivers/i2c/busses/i2c-qcom-geni.c
@@ -98,7 +98,7 @@ static const struct geni_i2c_err_log gi2c_log[] = {
  [GP_IRQ0] = {-EIO, "Unknown I2C err GP_IRQ0"},
  [NACK] = {-ENXIO, "NACK: slv unresponsive, check its 
power/reset-ln"},

  [GP_IRQ2] = {-EIO, "Unknown I2C err GP IRQ2"},
-    [BUS_PROTO] = {-EPROTO, "Bus proto err, noisy/unepxected 
start/stop"},
+    [BUS_PROTO] = {-EPROTO, "Bus proto err, noisy/unexpected 
start/stop"},
  [ARB_LOST] = {-EAGAIN, "Bus arbitration lost, clock line 
undriveable"},

  [GP_IRQ5] = {-EIO, "Unknown I2C err GP IRQ5"},
  [GENI_OVERRUN] = {-EIO, "Cmd overrun, check GENI cmd-state 
machine"},


The patch is still applying cleanly on tip.

Reviewed-by: Akash Asthana 

Correct tag

Reviewed-by: Akash Asthana 

--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project



Re: [PATCH] i2c: qcom-geni: fix spelling mistake "unepxected" -> "unexpected"

2020-07-27 Thread Akash Asthana



On 11/4/2019 2:52 AM, Colin King wrote:

From: Colin Ian King 

There is a spelling mistake in an error message string, fix it.

Signed-off-by: Colin Ian King 
---
  drivers/i2c/busses/i2c-qcom-geni.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/i2c/busses/i2c-qcom-geni.c 
b/drivers/i2c/busses/i2c-qcom-geni.c
index 17abf60c94ae..387fb5a83471 100644
--- a/drivers/i2c/busses/i2c-qcom-geni.c
+++ b/drivers/i2c/busses/i2c-qcom-geni.c
@@ -98,7 +98,7 @@ static const struct geni_i2c_err_log gi2c_log[] = {
[GP_IRQ0] = {-EIO, "Unknown I2C err GP_IRQ0"},
[NACK] = {-ENXIO, "NACK: slv unresponsive, check its power/reset-ln"},
[GP_IRQ2] = {-EIO, "Unknown I2C err GP IRQ2"},
-   [BUS_PROTO] = {-EPROTO, "Bus proto err, noisy/unepxected start/stop"},
+   [BUS_PROTO] = {-EPROTO, "Bus proto err, noisy/unexpected start/stop"},
[ARB_LOST] = {-EAGAIN, "Bus arbitration lost, clock line undriveable"},
[GP_IRQ5] = {-EIO, "Unknown I2C err GP IRQ5"},
[GENI_OVERRUN] = {-EIO, "Cmd overrun, check GENI cmd-state machine"},


The patch is still applying cleanly on tip.

Reviewed-by: Akash Asthana 

--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project



Re: [PATCH] soc: qcom-geni-se: Don't use relaxed writes when writing commands

2020-07-22 Thread Akash Asthana



On 7/23/2020 3:31 AM, Douglas Anderson wrote:

Writing the command is the final step in kicking off a transfer.
Let's use writel() to ensure that any other memory accesses are done
before the command kicks off.  It's expected that this is mostly
relevant if we're in DMA mode but since it doesn't appear to regress
performance in a measurable way [1] even in PIO mode and it's easier
to reason about then let's just always use it.

NOTE: this patch came about due to code inspection.  No actual
problems were observed that this patch fixes.

[1] Tested by timing "flashrom -p ec" on a Chromebook which stresses
GENI SPI a lot.

Suggested-by: Stephen Boyd 
Signed-off-by: Douglas Anderson 
---

Reviewed-by: Akash Asthana 

--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project



Re: [PATCH] i2c: i2c-qcom-geni: Fix DMA transfer race

2020-07-21 Thread Akash Asthana



On 7/21/2020 5:54 AM, Douglas Anderson wrote:

When I have KASAN enabled on my kernel and I start stressing the
touchscreen my system tends to hang.  The touchscreen is one of the
only things that does a lot of big i2c transfers and ends up hitting
the DMA paths in the geni i2c driver.  It appears that KASAN adds
enough delay in my system to tickle a race condition in the DMA setup
code.

When the system hangs, I found that it was running the geni_i2c_irq()
over and over again.  It had these:

m_stat   = 0x0480
rx_st= 0x3011
dm_tx_st = 0x
dm_rx_st = 0x
dma  = 0x0001

Notably we're in DMA mode but are getting M_RX_IRQ_EN and
M_RX_FIFO_WATERMARK_EN over and over again.

Putting some traces in geni_i2c_rx_one_msg() showed that when we
failed we were getting to the start of geni_i2c_rx_one_msg() but were
never executing geni_se_rx_dma_prep().

I believe that the problem here is that we are writing the transfer
length and setting up the geni command before we run
geni_se_rx_dma_prep().  If a transfer makes it far enough before we do
that then we get into the state I have observed.  Let's change the
order, which seems to work fine.

Fixes: 37692de5d523 ("i2c: i2c-qcom-geni: Add bus driver for the Qualcomm GENI I2C 
controller")
Signed-off-by: Douglas Anderson 
---


Reviewed-by: Akash Asthana 

--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project



[PATCH V2] soc: qcom: geni: Fix NULL pointer dereference

2020-07-20 Thread Akash Asthana
pdev struct doesn't exists for the devices whose status are disabled
from DT node, in such cases NULL is returned from 'of_find_device_by_node'
Later when we try to get drvdata from pdev struct NULL pointer dereference
is triggered.

Add a NULL check for return values to fix the issue.

We were hitting this issue when one of QUP is disabled.

Fixes: 048eb908a1f2 ("soc: qcom-geni-se: Add interconnect support to fix 
earlycon crash")
Reported-by: Sai Prakash Ranjan 
Reviewed-by: Matthias Kaehlcke 
Signed-off-by: Akash Asthana 
---
Changes in V2:
 - Change variable name 'wrapper_pdev' to 'pdev.

 drivers/soc/qcom/qcom-geni-se.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/soc/qcom/qcom-geni-se.c b/drivers/soc/qcom/qcom-geni-se.c
index 355d503..996f20c 100644
--- a/drivers/soc/qcom/qcom-geni-se.c
+++ b/drivers/soc/qcom/qcom-geni-se.c
@@ -820,6 +820,7 @@ void geni_remove_earlycon_icc_vote(void)
struct geni_wrapper *wrapper;
struct device_node *parent;
struct device_node *child;
+   struct platform_device *pdev;
 
if (!earlycon_wrapper)
return;
@@ -829,7 +830,12 @@ void geni_remove_earlycon_icc_vote(void)
for_each_child_of_node(parent, child) {
if (!of_device_is_compatible(child, "qcom,geni-se-qup"))
continue;
-   wrapper = platform_get_drvdata(of_find_device_by_node(child));
+
+   pdev = of_find_device_by_node(child);
+   if (!pdev)
+   continue;
+
+   wrapper = platform_get_drvdata(pdev);
icc_put(wrapper->to_core.path);
wrapper->to_core.path = NULL;
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project



Re: [PATCH] soc: qcom: geni: Fix NULL pointer dereference

2020-07-20 Thread Akash Asthana

Hi Matthias,

On 7/17/2020 8:18 PM, Matthias Kaehlcke wrote:

Please make sure to cc the linux-arm-msm@vger list for patches of
Qualcomm code.

Sure.

On Fri, Jul 17, 2020 at 08:02:22PM +0530, Akash Asthana wrote:

pdev struct doesn't exits for the devices whose status are disabled

s/exits/exist/

ok



from DT node, in such cases NULL is returned from 'of_find_device_by_node'
Later when we try to get drvdata from pdev struct NULL pointer dereference
is triggered.

Add a NULL check for return values to fix the issue.

We were hitting this issue when one of QUP is disabled.

Fixes: 048eb908a1f2 ("soc: qcom-geni-se: Add interconnect support to fix earlycon 
crash")
Reported-by: Sai Prakash Ranjan 
Signed-off-by: Akash Asthana 
---
  drivers/soc/qcom/qcom-geni-se.c | 8 +++-
  1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/soc/qcom/qcom-geni-se.c b/drivers/soc/qcom/qcom-geni-se.c
index 355d503..6e5fe65 100644
--- a/drivers/soc/qcom/qcom-geni-se.c
+++ b/drivers/soc/qcom/qcom-geni-se.c
@@ -820,6 +820,7 @@ void geni_remove_earlycon_icc_vote(void)
struct geni_wrapper *wrapper;
struct device_node *parent;
struct device_node *child;
+   struct platform_device *wrapper_pdev;

nit: since there is no other 'pdev' in this function you could just name
it 'pdev', which is less clunky. The variable is only used immediately
after it is assigned, so it's clear from the context that it refers to
the 'wrapper'.


ok

Thankyou for review!.


regards,

Akash



Reviewed-by: Matthias Kaehlcke 


--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project



[PATCH] soc: qcom: geni: Fix NULL pointer dereference

2020-07-17 Thread Akash Asthana
pdev struct doesn't exits for the devices whose status are disabled
from DT node, in such cases NULL is returned from 'of_find_device_by_node'
Later when we try to get drvdata from pdev struct NULL pointer dereference
is triggered.

Add a NULL check for return values to fix the issue.

We were hitting this issue when one of QUP is disabled.

Fixes: 048eb908a1f2 ("soc: qcom-geni-se: Add interconnect support to fix 
earlycon crash")
Reported-by: Sai Prakash Ranjan 
Signed-off-by: Akash Asthana 
---
 drivers/soc/qcom/qcom-geni-se.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/soc/qcom/qcom-geni-se.c b/drivers/soc/qcom/qcom-geni-se.c
index 355d503..6e5fe65 100644
--- a/drivers/soc/qcom/qcom-geni-se.c
+++ b/drivers/soc/qcom/qcom-geni-se.c
@@ -820,6 +820,7 @@ void geni_remove_earlycon_icc_vote(void)
struct geni_wrapper *wrapper;
struct device_node *parent;
struct device_node *child;
+   struct platform_device *wrapper_pdev;
 
if (!earlycon_wrapper)
return;
@@ -829,7 +830,12 @@ void geni_remove_earlycon_icc_vote(void)
for_each_child_of_node(parent, child) {
if (!of_device_is_compatible(child, "qcom,geni-se-qup"))
continue;
-   wrapper = platform_get_drvdata(of_find_device_by_node(child));
+
+   wrapper_pdev = of_find_device_by_node(child);
+   if (!wrapper_pdev)
+   continue;
+
+   wrapper = platform_get_drvdata(wrapper_pdev);
icc_put(wrapper->to_core.path);
wrapper->to_core.path = NULL;
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project



[PATCH] of: Add stub for of_get_next_parent

2020-07-10 Thread Akash Asthana
Fixes compilation error reported on x86 platform:

drivers/soc/qcom/qcom-geni-se.c:819:11: error: implicit declaration of
function 'of_get_next_parent'.

drivers/soc/qcom/qcom-geni-se.c:819:9: warning: incompatible integer to
pointer conversion assigning to 'struct device_node *' from 'int'

Fixes: 048eb908a1f2 ("soc: qcom-geni-se: Add interconnect support to fix
earlycon crash")
Reported-by: kernel test robot 
Signed-off-by: Akash Asthana 
---
 include/linux/of.h | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/include/linux/of.h b/include/linux/of.h
index c669c0a..72e7198 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -630,6 +630,12 @@ static inline struct device_node *of_get_parent(const 
struct device_node *node)
return NULL;
 }
 
+static inline struct device_node *of_get_next_parent(
+   const struct device_node *node)
+{
+   return NULL;
+}
+
 static inline struct device_node *of_get_next_child(
const struct device_node *node, struct device_node *prev)
 {
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project



Re: [PATCH v2 0/2] spi: spi-qcom-qspi: Avoid some per-transfer overhead

2020-07-09 Thread Akash Asthana



On 7/9/2020 8:21 PM, Douglas Anderson wrote:

Not to be confused with the similar series I posed for the _other_
Qualcomm SPI controller (spi-geni-qcom) [1], this one avoids the
overhead on the Quad SPI controller.

It's based atop the current Qualcomm tree including Rajendra's ("spi:
spi-qcom-qspi: Use OPP API to set clk/perf state").  As discussed in
individual patches, these could ideally land through the Qualcomm tree
with Mark's Ack.

Measuring:
* Before OPP / Interconnect patches reading all flash takes: ~3.4 seconds
* After OPP / Interconnect patches reading all flash takes: ~4.7 seconds
* After this patch reading all flash takes: ~3.3 seconds

[1] https://lore.kernel.org/r/20200702004509.2333554-1-diand...@chromium.org
[2] 
https://lore.kernel.org/r/1593769293-6354-2-git-send-email-rna...@codeaurora.org

Changes in v2:
- Return error from runtime resume if dev_pm_opp_set_rate() fails.

Douglas Anderson (2):
   spi: spi-qcom-qspi: Avoid clock setting if not needed
   spi: spi-qcom-qspi: Set an autosuspend delay of 250 ms

  drivers/spi/spi-qcom-qspi.c | 43 -
  1 file changed, 33 insertions(+), 10 deletions(-)

Reviewed-by: Akash Asthana 

--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project



Re: [PATCH v2] spi: spi-geni-qcom: Set the clock properly at runtime resume

2020-07-09 Thread Akash Asthana



On 7/9/2020 8:10 PM, Douglas Anderson wrote:

In the patch ("spi: spi-geni-qcom: Avoid clock setting if not needed")
we avoid a whole pile of clock code.  As part of that, we should have
restored the clock at runtime resume.  Do that.

It turns out that, at least with today's configurations, this doesn't
actually matter.  That's because none of the current device trees have
an OPP table for geni SPI yet.  That makes dev_pm_opp_set_rate(dev, 0)
a no-op.  This is why it wasn't noticed in the testing of the original
patch.  It's still a good idea to fix, though.

Reviewed-by: Akash Asthana 

--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project



Re: [PATCH] tty: serial: qcom-geni-serial: Drop the icc bw votes in suspend for console

2020-07-09 Thread Akash Asthana



On 7/9/2020 3:07 PM, Rajendra Nayak wrote:

When using the geni-serial as console, its important to be
able to hit the lowest possible power state in suspend,
even with no_console_suspend.
The only thing that prevents it today on platforms like the sc7180
is the interconnect BW votes, which we certainly don't need when
the system is in suspend. So in the suspend handler mark them as
ACTIVE_ONLY (0x3) and on resume switch them back to the ALWAYS tag (0x7)

Reviewed-by: Akash Asthana 

--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project



Re: [PATCH] spi: spi-geni-qcom: Set the clock properly at runtime resume

2020-07-09 Thread Akash Asthana

Hi Doug,

  
@@ -670,7 +674,13 @@ static int __maybe_unused spi_geni_runtime_resume(struct device *dev)

if (ret)
return ret;
  
-	return geni_se_resources_on(>se);

+   ret = geni_se_resources_on(>se);
+   if (ret)
+   return ret;
+
+   dev_pm_opp_set_rate(mas->dev, mas->cur_sclk_hz);
+
+   return 0;
  }


Should we fail to resume if error is returned from 'opp_set_rate'?

'spi_geni_prepare_message' use to fail for any error from 
'opp_set_rate'  before patch series "Avoid clock setting if not needed".


But now it's possible that 'prepare_message' can return success even 
when opp are not at desired state(from previous resume call).


Regards,

Akash

  
  static int __maybe_unused spi_geni_suspend(struct device *dev)


--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project



Re: [PATCH 3/3] spi: spi-geni-qcom: Get rid of most overhead in prepare_message()

2020-07-07 Thread Akash Asthana



On 7/2/2020 6:15 AM, Douglas Anderson wrote:

There's a bunch of overhead in spi-geni-qcom's prepare_message.  Get
rid of it.  Before this change spi_geni_prepare_message() took around
14.5 us.  After this change, spi_geni_prepare_message() takes about
1.75 us (as measured by ftrace).

What's here:
* We're always in FIFO mode, so no need to call it for every transfer.
   This avoids a whole ton of readl/writel calls.
* We don't need to write a whole pile of config registers if the mode
   isn't changing.  Cache the last mode and only do the work if needed.
* For several registers we were trying to do read/modify/write, but
   there was no reason.  The registers only have one thing in them, so
   just write them.

Signed-off-by: Douglas Anderson 
---

  drivers/spi/spi-geni-qcom.c | 54 +
  1 file changed, 24 insertions(+), 30 deletions(-)

diff --git a/drivers/spi/spi-geni-qcom.c b/drivers/spi/spi-geni-qcom.c
index f51279608fc7..97fac5ea6afd 100644
--- a/drivers/spi/spi-geni-qcom.c
+++ b/drivers/spi/spi-geni-qcom.c
@@ -77,6 +77,7 @@ struct spi_geni_master {
u32 tx_fifo_depth;
u32 fifo_width_bits;
u32 tx_wm;
+   u32 last_mode;
unsigned long cur_speed_hz;
unsigned int cur_bits_per_word;
unsigned int tx_rem_bytes;
@@ -177,8 +178,6 @@ static void spi_setup_word_len(struct spi_geni_master *mas, 
u16 mode,
struct geni_se *se = >se;
u32 word_len;
  
-	word_len = readl(se->base + SE_SPI_WORD_LEN);

-
/*
 * If bits_per_word isn't a byte aligned value, set the packing to be
 * 1 SPI word per FIFO word.
@@ -187,10 +186,9 @@ static void spi_setup_word_len(struct spi_geni_master 
*mas, u16 mode,
pack_words = mas->fifo_width_bits / bits_per_word;
else
pack_words = 1;
-   word_len &= ~WORD_LEN_MSK;
-   word_len |= ((bits_per_word - MIN_WORD_LEN) & WORD_LEN_MSK);
geni_se_config_packing(>se, bits_per_word, pack_words, msb_first,
true, true);
+   word_len = (bits_per_word - MIN_WORD_LEN) & WORD_LEN_MSK;
writel(word_len, se->base + SE_SPI_WORD_LEN);
  }
  
@@ -238,38 +236,34 @@ static int setup_fifo_params(struct spi_device *spi_slv,

  {
struct spi_geni_master *mas = spi_master_get_devdata(spi);
struct geni_se *se = >se;
-   u32 loopback_cfg, cpol, cpha, demux_output_inv;
+   u32 loopback_cfg = 0, cpol = 0, cpha = 0, demux_output_inv = 0;
u32 demux_sel;
  
-	loopback_cfg = readl(se->base + SE_SPI_LOOPBACK);

-   cpol = readl(se->base + SE_SPI_CPOL);
-   cpha = readl(se->base + SE_SPI_CPHA);
-   demux_output_inv = 0;
-   loopback_cfg &= ~LOOPBACK_MSK;
-   cpol &= ~CPOL;
-   cpha &= ~CPHA;
+   if (mas->last_mode != spi_slv->mode) {
+   if (spi_slv->mode & SPI_LOOP)
+   loopback_cfg = LOOPBACK_ENABLE;
  
-	if (spi_slv->mode & SPI_LOOP)

-   loopback_cfg |= LOOPBACK_ENABLE;
+   if (spi_slv->mode & SPI_CPOL)
+   cpol = CPOL;
  
-	if (spi_slv->mode & SPI_CPOL)

-   cpol |= CPOL;
+   if (spi_slv->mode & SPI_CPHA)
+   cpha = CPHA;
  
-	if (spi_slv->mode & SPI_CPHA)

-   cpha |= CPHA;
+   if (spi_slv->mode & SPI_CS_HIGH)
+   demux_output_inv = BIT(spi_slv->chip_select);
  
-	if (spi_slv->mode & SPI_CS_HIGH)

-   demux_output_inv = BIT(spi_slv->chip_select);
+   demux_sel = spi_slv->chip_select;
+   mas->cur_bits_per_word = spi_slv->bits_per_word;
  
-	demux_sel = spi_slv->chip_select;

-   mas->cur_bits_per_word = spi_slv->bits_per_word;
+   spi_setup_word_len(mas, spi_slv->mode, spi_slv->bits_per_word);
+   writel(loopback_cfg, se->base + SE_SPI_LOOPBACK);
+   writel(demux_sel, se->base + SE_SPI_DEMUX_SEL);
+   writel(cpha, se->base + SE_SPI_CPHA);
+   writel(cpol, se->base + SE_SPI_CPOL);
+   writel(demux_output_inv, se->base + SE_SPI_DEMUX_OUTPUT_INV);
  
-	spi_setup_word_len(mas, spi_slv->mode, spi_slv->bits_per_word);

-   writel(loopback_cfg, se->base + SE_SPI_LOOPBACK);
-   writel(demux_sel, se->base + SE_SPI_DEMUX_SEL);
-   writel(cpha, se->base + SE_SPI_CPHA);
-   writel(cpol, se->base + SE_SPI_CPOL);
-   writel(demux_output_inv, se->base + SE_SPI_DEMUX_OUTPUT_INV);
+   mas->last_mode = spi_slv->mode;
+   }
  
  	return geni_spi_set_clock_and_bw(mas, spi_slv->max_speed_hz);

  }


Yeah looks good to me, the default/reset value of these registers are 0 
we don't have to preserve any bits here.


We can directly update the register with required value.

Reviewed-by: Akash Asthana 

--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project



Re: [PATCH 2/3] spi: spi-geni-qcom: Set an autosuspend delay of 250 ms

2020-07-07 Thread Akash Asthana



On 7/2/2020 6:15 AM, Douglas Anderson wrote:

In commit 0e3b8a81f5df ("spi: spi-geni-qcom: Add interconnect
support") the spi_geni_runtime_suspend() and spi_geni_runtime_resume()
became a bit slower.  Measuring on my hardware I see numbers in the
hundreds of microseconds now.

Let's use autosuspend to help avoid some of the overhead.  Now if
we're doing a bunch of transfers we won't need to be constantly
chruning.

The number 250 ms for the autosuspend delay was picked a bit
arbitrarily, so if someone has measurements showing a better value we
could easily change this.


Reviewed-by: Akash Asthana

--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project



Re: [PATCH 1/3] spi: spi-geni-qcom: Avoid clock setting if not needed

2020-07-07 Thread Akash Asthana



On 7/2/2020 6:15 AM, Douglas Anderson wrote:

Every SPI transfer could have a different clock rate.  The
spi-geni-qcom controller code to deal with this was never very well
optimized and has always had a lot of code plus some calls into the
clk framework which, at the very least, would grab a mutex.  However,
until recently, the overhead wasn't _too_ much.  That changed with
commit 0e3b8a81f5df ("spi: spi-geni-qcom: Add interconnect support")
we're now calling geni_icc_set_bw(), which leads to a bunch of math
plus:
   geni_icc_set_bw()
 icc_set_bw()
   apply_constraints()
 qcom_icc_set()
   qcom_icc_bcm_voter_commit()
 rpmh_invalidate()
 rpmh_write_batch()
...and those rpmh commands can be a bit beefy if you call them too
often.


Reviewed-by: Akash Asthana

--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project



[PATCH V8 5/8] spi: spi-geni-qcom: Combine the clock setting code

2020-06-23 Thread Akash Asthana
From: Douglas Anderson 

There is code for adjusting the clock both in setup_fifo_params()
(called from prepare_message()) and in setup_fifo_xfer() (called from
transfer_one()).  The code is the same.  Abstract it out to a shared
function.

This is a no-op cleanup patch.  The only change is to the error string
if we fail to set the clock.  Since the two paths has marginally
different error messages I picked the clean one.

Signed-off-by: Douglas Anderson 
Signed-off-by: Akash Asthana 
---
This patch is introduced in V8 of the series.

 drivers/spi/spi-geni-qcom.c | 70 ++---
 1 file changed, 35 insertions(+), 35 deletions(-)

diff --git a/drivers/spi/spi-geni-qcom.c b/drivers/spi/spi-geni-qcom.c
index 0c534d1..f186906 100644
--- a/drivers/spi/spi-geni-qcom.c
+++ b/drivers/spi/spi-geni-qcom.c
@@ -192,14 +192,42 @@ static void spi_setup_word_len(struct spi_geni_master 
*mas, u16 mode,
writel(word_len, se->base + SE_SPI_WORD_LEN);
 }
 
+static int geni_spi_set_clock(struct spi_geni_master *mas, unsigned long 
clk_hz)
+{
+   u32 clk_sel, m_clk_cfg, idx, div;
+   struct geni_se *se = >se;
+   int ret;
+
+   ret = get_spi_clk_cfg(clk_hz, mas, , );
+   if (ret) {
+   dev_err(mas->dev, "Err setting clk to %lu: %d\n", clk_hz, ret);
+   return ret;
+   }
+
+   /*
+* SPI core clock gets configured with the requested frequency
+* or the frequency closer to the requested frequency.
+* For that reason requested frequency is stored in the
+* cur_speed_hz and referred in the consecutive transfer instead
+* of calling clk_get_rate() API.
+*/
+   mas->cur_speed_hz = clk_hz;
+
+   clk_sel = idx & CLK_SEL_MSK;
+   m_clk_cfg = (div << CLK_DIV_SHFT) | SER_CLK_EN;
+   writel(clk_sel, se->base + SE_GENI_CLK_SEL);
+   writel(m_clk_cfg, se->base + GENI_SER_M_CLK_CFG);
+
+   return 0;
+}
+
 static int setup_fifo_params(struct spi_device *spi_slv,
struct spi_master *spi)
 {
struct spi_geni_master *mas = spi_master_get_devdata(spi);
struct geni_se *se = >se;
u32 loopback_cfg, cpol, cpha, demux_output_inv;
-   u32 demux_sel, clk_sel, m_clk_cfg, idx, div;
-   int ret;
+   u32 demux_sel;
 
loopback_cfg = readl(se->base + SE_SPI_LOOPBACK);
cpol = readl(se->base + SE_SPI_CPOL);
@@ -222,27 +250,16 @@ static int setup_fifo_params(struct spi_device *spi_slv,
demux_output_inv = BIT(spi_slv->chip_select);
 
demux_sel = spi_slv->chip_select;
-   mas->cur_speed_hz = spi_slv->max_speed_hz;
mas->cur_bits_per_word = spi_slv->bits_per_word;
 
-   ret = get_spi_clk_cfg(mas->cur_speed_hz, mas, , );
-   if (ret) {
-   dev_err(mas->dev, "Err setting clks ret(%d) for %ld\n",
-   ret, mas->cur_speed_hz);
-   return ret;
-   }
-
-   clk_sel = idx & CLK_SEL_MSK;
-   m_clk_cfg = (div << CLK_DIV_SHFT) | SER_CLK_EN;
spi_setup_word_len(mas, spi_slv->mode, spi_slv->bits_per_word);
writel(loopback_cfg, se->base + SE_SPI_LOOPBACK);
writel(demux_sel, se->base + SE_SPI_DEMUX_SEL);
writel(cpha, se->base + SE_SPI_CPHA);
writel(cpol, se->base + SE_SPI_CPOL);
writel(demux_output_inv, se->base + SE_SPI_DEMUX_OUTPUT_INV);
-   writel(clk_sel, se->base + SE_GENI_CLK_SEL);
-   writel(m_clk_cfg, se->base + GENI_SER_M_CLK_CFG);
-   return 0;
+
+   return geni_spi_set_clock(mas, spi_slv->max_speed_hz);
 }
 
 static int spi_geni_prepare_message(struct spi_master *spi,
@@ -304,6 +321,7 @@ static void setup_fifo_xfer(struct spi_transfer *xfer,
u32 m_cmd = 0;
u32 spi_tx_cfg, len;
struct geni_se *se = >se;
+   int ret;
 
/*
 * Ensure that our interrupt handler isn't still running from some
@@ -328,27 +346,9 @@ static void setup_fifo_xfer(struct spi_transfer *xfer,
 
/* Speed and bits per word can be overridden per transfer */
if (xfer->speed_hz != mas->cur_speed_hz) {
-   int ret;
-   u32 clk_sel, m_clk_cfg;
-   unsigned int idx, div;
-
-   ret = get_spi_clk_cfg(xfer->speed_hz, mas, , );
-   if (ret) {
-   dev_err(mas->dev, "Err setting clks:%d\n", ret);
+   ret = geni_spi_set_clock(mas, xfer->speed_hz);
+   if (ret)
return;
-   }
-   /*
-* SPI core clock gets configured with the requested frequency
-* or the frequency closer to the requested frequency.
-* For that reason requested frequency is stored in the
-*

[PATCH V8 7/8] spi: spi-qcom-qspi: Add interconnect support

2020-06-23 Thread Akash Asthana
Get the interconnect paths for QSPI device and vote according to the
current bus speed of the driver.

Signed-off-by: Akash Asthana 
Reviewed-by: Matthias Kaehlcke 
---
Changes in V2:
 - As per Bjorn's comment, introduced and using devm_of_icc_get API for getting
   path handle
 - As per Matthias comment, added error handling for icc_set_bw call

Changes in V3:
 - No Change.

Changes in V4:
 - As per Mark's comment move peak_bw guess as twice of avg_bw if
   nothing mentioned explicitly to ICC core.

Changes in V5:
 - Add icc_enable/disable to power on/off call.
 - Save some non-zero avg/peak value to ICC core by calling geni_icc_set_bw
   from probe so that when resume/icc_enable is called NOC are running at
   some non-zero value.

Changes in V6:
 - As per Matthias's comment made print statement consistent across driver

Changes in V7:
 - As per Matthias's comment removed usage of peak_bw variable because we don't
   have explicit peak requirement, we were voting peak = avg and this can be
   tracked using single variable for avg bw.
 - As per Matthias's comment improved print log.

Changes in Resend V7:
 - As per Matthias comment removed "unsigned int avg_bw_cpu" from
   struct qcom_qspi as we are using that variable only once.

Changes in V8:
 - No change

 drivers/spi/spi-qcom-qspi.c | 56 -
 1 file changed, 55 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-qcom-qspi.c b/drivers/spi/spi-qcom-qspi.c
index 3c4f83b..b5b4cf6 100644
--- a/drivers/spi/spi-qcom-qspi.c
+++ b/drivers/spi/spi-qcom-qspi.c
@@ -2,6 +2,7 @@
 // Copyright (c) 2017-2018, The Linux foundation. All rights reserved.
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -139,7 +140,8 @@ struct qcom_qspi {
struct device *dev;
struct clk_bulk_data *clks;
struct qspi_xfer xfer;
-   /* Lock to protect xfer and IRQ accessed registers */
+   struct icc_path *icc_path_cpu_to_qspi;
+   /* Lock to protect data accessed by IRQs */
spinlock_t lock;
 };
 
@@ -229,6 +231,7 @@ static int qcom_qspi_transfer_one(struct spi_master *master,
int ret;
unsigned long speed_hz;
unsigned long flags;
+   unsigned int avg_bw_cpu;
 
speed_hz = slv->max_speed_hz;
if (xfer->speed_hz)
@@ -241,6 +244,18 @@ static int qcom_qspi_transfer_one(struct spi_master 
*master,
return ret;
}
 
+   /*
+* Set BW quota for CPU as driver supports FIFO mode only.
+* We don't have explicit peak requirement so keep it equal to avg_bw.
+*/
+   avg_bw_cpu = Bps_to_icc(speed_hz);
+   ret = icc_set_bw(ctrl->icc_path_cpu_to_qspi, avg_bw_cpu, avg_bw_cpu);
+   if (ret) {
+   dev_err(ctrl->dev, "%s: ICC BW voting failed for cpu: %d\n",
+   __func__, ret);
+   return ret;
+   }
+
spin_lock_irqsave(>lock, flags);
 
/* We are half duplex, so either rx or tx will be set */
@@ -458,6 +473,29 @@ static int qcom_qspi_probe(struct platform_device *pdev)
if (ret)
goto exit_probe_master_put;
 
+   ctrl->icc_path_cpu_to_qspi = devm_of_icc_get(dev, "qspi-config");
+   if (IS_ERR(ctrl->icc_path_cpu_to_qspi)) {
+   ret = PTR_ERR(ctrl->icc_path_cpu_to_qspi);
+   if (ret != -EPROBE_DEFER)
+   dev_err(dev, "Failed to get cpu path: %d\n", ret);
+   goto exit_probe_master_put;
+   }
+   /* Set BW vote for register access */
+   ret = icc_set_bw(ctrl->icc_path_cpu_to_qspi, Bps_to_icc(1000),
+   Bps_to_icc(1000));
+   if (ret) {
+   dev_err(ctrl->dev, "%s: ICC BW voting failed for cpu: %d\n",
+   __func__, ret);
+   goto exit_probe_master_put;
+   }
+
+   ret = icc_disable(ctrl->icc_path_cpu_to_qspi);
+   if (ret) {
+   dev_err(ctrl->dev, "%s: ICC disable failed for cpu: %d\n",
+   __func__, ret);
+   goto exit_probe_master_put;
+   }
+
ret = platform_get_irq(pdev, 0);
if (ret < 0)
goto exit_probe_master_put;
@@ -511,9 +549,17 @@ static int __maybe_unused qcom_qspi_runtime_suspend(struct 
device *dev)
 {
struct spi_master *master = dev_get_drvdata(dev);
struct qcom_qspi *ctrl = spi_master_get_devdata(master);
+   int ret;
 
clk_bulk_disable_unprepare(QSPI_NUM_CLKS, ctrl->clks);
 
+   ret = icc_disable(ctrl->icc_path_cpu_to_qspi);
+   if (ret) {
+   dev_err_ratelimited(ctrl->dev, "%s: ICC disable failed for cpu: 
%d\n",
+   __func__, ret);
+   return ret;
+   }
+
return 0;
 }
 
@@ -521,6 +567,14 @@ static int __maybe_unused qcom_qspi_runtime_r

[PATCH V8 8/8] arm64: dts: sc7180: Add interconnect for QUP and QSPI

2020-06-23 Thread Akash Asthana
Add interconnect ports for GENI QUPs and QSPI to set bus capabilities.

Signed-off-by: Akash Asthana 
---
Changes in V2:
 - As per Bjorn's comment, ignoring 80 char limit in defining interconnects
   paths.

Changes in V3:
 - No change.

Change in V4:
 - No change.

Changes in V5:
 - No change.

Chnages in V6:
 - No change.

Changes in V7:
 - No change.

Changes in V8:
 - No change.

 arch/arm64/boot/dts/qcom/sc7180.dtsi | 127 +++
 1 file changed, 127 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi 
b/arch/arm64/boot/dts/qcom/sc7180.dtsi
index 3a8076c..ad57df2 100644
--- a/arch/arm64/boot/dts/qcom/sc7180.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi
@@ -547,6 +547,8 @@
#size-cells = <2>;
ranges;
iommus = <_smmu 0x43 0x0>;
+   interconnects = <_virt MASTER_QUP_CORE_0 _virt 
SLAVE_QUP_CORE_0>;
+   interconnect-names = "qup-core";
status = "disabled";
 
i2c0: i2c@88 {
@@ -559,6 +561,11 @@
interrupts = ;
#address-cells = <1>;
#size-cells = <0>;
+   interconnects = <_virt MASTER_QUP_CORE_0 
_virt SLAVE_QUP_CORE_0>,
+   <_noc MASTER_APPSS_PROC 
_noc SLAVE_QUP_0>,
+   <_noc MASTER_QUP_0 
_virt SLAVE_EBI1>;
+   interconnect-names = "qup-core", "qup-config",
+   "qup-memory";
status = "disabled";
};
 
@@ -572,6 +579,9 @@
interrupts = ;
#address-cells = <1>;
#size-cells = <0>;
+   interconnects = <_virt MASTER_QUP_CORE_0 
_virt SLAVE_QUP_CORE_0>,
+   <_noc MASTER_APPSS_PROC 
_noc SLAVE_QUP_0>;
+   interconnect-names = "qup-core", "qup-config";
status = "disabled";
};
 
@@ -583,6 +593,9 @@
pinctrl-names = "default";
pinctrl-0 = <_uart0_default>;
interrupts = ;
+   interconnects = <_virt MASTER_QUP_CORE_0 
_virt SLAVE_QUP_CORE_0>,
+   <_noc MASTER_APPSS_PROC 
_noc SLAVE_QUP_0>;
+   interconnect-names = "qup-core", "qup-config";
status = "disabled";
};
 
@@ -596,6 +609,11 @@
interrupts = ;
#address-cells = <1>;
#size-cells = <0>;
+   interconnects = <_virt MASTER_QUP_CORE_0 
_virt SLAVE_QUP_CORE_0>,
+   <_noc MASTER_APPSS_PROC 
_noc SLAVE_QUP_0>,
+   <_noc MASTER_QUP_0 
_virt SLAVE_EBI1>;
+   interconnect-names = "qup-core", "qup-config",
+   "qup-memory";
status = "disabled";
};
 
@@ -609,6 +627,9 @@
interrupts = ;
#address-cells = <1>;
#size-cells = <0>;
+   interconnects = <_virt MASTER_QUP_CORE_0 
_virt SLAVE_QUP_CORE_0>,
+   <_noc MASTER_APPSS_PROC 
_noc SLAVE_QUP_0>;
+   interconnect-names = "qup-core", "qup-config";
status = "disabled";
};
 
@@ -620,6 +641,9 @@
pinctrl-names = "default";
pinctrl-0 = <_uart1_default>;
interrupts = ;
+   interconnects = <_virt MASTER_QUP_CORE_0 
_virt SLAVE_QUP_CORE_0>,
+   <_noc MASTER_APPSS_PROC 
_noc SLAVE_QUP_0>;
+   interconnect-names = "qup-core", "qup-config";
status = "disa

[PATCH V8 3/8] i2c: i2c-qcom-geni: Add interconnect support

2020-06-23 Thread Akash Asthana
Get the interconnect paths for I2C based Serial Engine device
and vote according to the bus speed of the driver.

Signed-off-by: Akash Asthana 
Reviewed-by: Matthias Kaehlcke 
Acked-by: Wolfram Sang 
---
Changes in V2:
 - As per Bjorn's comment, removed se == NULL check from geni_i2c_icc_get
 - As per Bjorn's comment, removed code to set se->icc_path* to NULL in failure
 - As per Bjorn's comment, introduced and using devm_of_icc_get API for getting
   path handle
 - As per Matthias comment, added error handling for icc_set_bw call

Changes in V3:
 - As per Matthias comment, use common library APIs defined in geni-se
   driver for ICC functionality.

Changes in V4:
 - Move peak_bw guess as twice of avg_bw if nothing mentioned explicitly
   to ICC core.

Changes in V5:
 - Use icc_enable/disable in power on/off call.

Changes in V6:
 - No changes

Changes in V7:
 - As per Matthias's comment removed usage of peak_bw variable because we don't
   have explicit peak requirement, we were voting peak = avg and this can be
   tracked using single variable for avg bw.

Changes in V8:
 - No change.

 drivers/i2c/busses/i2c-qcom-geni.c | 26 +-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/drivers/i2c/busses/i2c-qcom-geni.c 
b/drivers/i2c/busses/i2c-qcom-geni.c
index 18d1e4f..32b2a99 100644
--- a/drivers/i2c/busses/i2c-qcom-geni.c
+++ b/drivers/i2c/busses/i2c-qcom-geni.c
@@ -557,6 +557,22 @@ static int geni_i2c_probe(struct platform_device *pdev)
gi2c->adap.dev.of_node = dev->of_node;
strlcpy(gi2c->adap.name, "Geni-I2C", sizeof(gi2c->adap.name));
 
+   ret = geni_icc_get(>se, "qup-memory");
+   if (ret)
+   return ret;
+   /*
+* Set the bus quota for core and cpu to a reasonable value for
+* register access.
+* Set quota for DDR based on bus speed.
+*/
+   gi2c->se.icc_paths[GENI_TO_CORE].avg_bw = GENI_DEFAULT_BW;
+   gi2c->se.icc_paths[CPU_TO_GENI].avg_bw = GENI_DEFAULT_BW;
+   gi2c->se.icc_paths[GENI_TO_DDR].avg_bw = Bps_to_icc(gi2c->clk_freq_out);
+
+   ret = geni_icc_set_bw(>se);
+   if (ret)
+   return ret;
+
ret = geni_se_resources_on(>se);
if (ret) {
dev_err(dev, "Error turning on resources %d\n", ret);
@@ -579,6 +595,10 @@ static int geni_i2c_probe(struct platform_device *pdev)
return ret;
}
 
+   ret = geni_icc_disable(>se);
+   if (ret)
+   return ret;
+
dev_dbg(dev, "i2c fifo/se-dma mode. fifo depth:%d\n", tx_depth);
 
gi2c->suspended = 1;
@@ -623,7 +643,7 @@ static int __maybe_unused geni_i2c_runtime_suspend(struct 
device *dev)
gi2c->suspended = 1;
}
 
-   return 0;
+   return geni_icc_disable(>se);
 }
 
 static int __maybe_unused geni_i2c_runtime_resume(struct device *dev)
@@ -631,6 +651,10 @@ static int __maybe_unused geni_i2c_runtime_resume(struct 
device *dev)
int ret;
struct geni_i2c_dev *gi2c = dev_get_drvdata(dev);
 
+   ret = geni_icc_enable(>se);
+   if (ret)
+   return ret;
+
ret = geni_se_resources_on(>se);
if (ret)
return ret;
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project



[PATCH V8 0/8] Add interconnect support to QSPI and QUP drivers

2020-06-23 Thread Akash Asthana
This patch series is based on tag "next-20200622" of linux-next tree.

High level design:
 - QUP wrapper/common driver.
   Vote for QUP core on behalf of earlycon from probe.
   Remove BW vote during earlycon exit call

 - SERIAL driver.
   Vote only for CPU/CORE path because driver is in FIFO mode only
   Vote/unvote from qcom_geni_serial_pm func.
   Bump up the CPU vote from set_termios call based on real time need

 - I2C driver.
   Vote for CORE/CPU/DDR path
   Vote/unvote from runtime resume/suspend callback
   As bus speed for I2C is fixed from probe itself no need for bump up.

 - SPI QUP driver.
   Vote only for CPU/CORE path because driver is in FIFO mode only
   Vote/unvote from runtime resume/suspend callback
   Bump up CPU vote based on real time need per transfer.

 - QSPI driver.
   Vote only for CPU path
   Vote/unvote from runtime resume/suspend callback
   Bump up CPU vote based on real time need per transfer.

Changes in V2:
 - Add devm_of_icc_get() API interconnect core.
 - Add ICC support to common driver to fix earlyconsole crash.

Changes in V3:
 - Define common ICC APIs in geni-se driver and use it across geni based
   I2C,SPI and UART driver.

Changes in V4:
 - Add a patch to ICC core to scale peak requirement
   as twice of average if it is not mentioned explicilty.

Changes in V5:
 - As per Georgi's suggestion removed patch from ICC core for assuming
   peak_bw as twice of average when it's not mentioned, instead assume it
   equall to avg_bw and keep this assumption in ICC client itself.
 - As per Matthias suggestion use enum for GENI QUP ICC paths.

Changes in V6:
 - No Major change

Changes in V7:
 - As per Matthias's comment removed usage of peak_bw variable because we don't
   have explicit peak requirement, we were voting peak = avg and this can be
   tracked using single variable for avg bw.
 - As per Matthias's comment improved print log.

Changes in V8:
 - Add [PATCH V8 5/8] to factor out common code for clock setting.
 - Combine ICC voting and clock setting to single API. [PATCH V8 6/8]
 - Add ICC voting per transfer because in case of multi message,
   transfer frequency can vary for each message/transfer.[PATCH V8 6/8]

Akash Asthana (7):
  soc: qcom: geni: Support for ICC voting
  soc: qcom-geni-se: Add interconnect support to fix earlycon crash
  i2c: i2c-qcom-geni: Add interconnect support
  tty: serial: qcom_geni_serial: Add interconnect support
  spi: spi-geni-qcom: Add interconnect support
  spi: spi-qcom-qspi: Add interconnect support
  arm64: dts: sc7180: Add interconnect for QUP and QSPI

Douglas Anderson (1):
  spi: spi-geni-qcom: Combine the clock setting code

 arch/arm64/boot/dts/qcom/sc7180.dtsi  | 127 
 drivers/i2c/busses/i2c-qcom-geni.c|  26 +-
 drivers/soc/qcom/qcom-geni-se.c   | 150 ++
 drivers/spi/spi-geni-qcom.c   | 100 +++
 drivers/spi/spi-qcom-qspi.c   |  56 -
 drivers/tty/serial/qcom_geni_serial.c |  38 -
 include/linux/qcom-geni-se.h  |  40 +
 7 files changed, 496 insertions(+), 41 deletions(-)

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project



[PATCH V8 2/8] soc: qcom-geni-se: Add interconnect support to fix earlycon crash

2020-06-23 Thread Akash Asthana
QUP core clock is shared among all the SE drivers present on particular
QUP wrapper, the system will reset(unclocked access) if earlycon used after
QUP core clock is put to 0 from other SE drivers before real console comes
up.

As earlycon can't vote for it's QUP core need, to fix this add ICC
support to common/QUP wrapper driver and put vote for QUP core from
probe on behalf of earlycon and remove vote during earlycon exit call.

Signed-off-by: Akash Asthana 
Reported-by: Matthias Kaehlcke 
Reviewed-by: Matthias Kaehlcke 
---
Change in V3:
 - Add geni_remove_earlycon_icc_vote API that will be used by earlycon
   exit function to remove ICC vote for earlyconsole.
 - Remove suspend/resume hook for geni-se driver as we are no longer
   removing earlyconsole ICC vote from system suspend, we are removing
   from earlycon exit.

Change in V4:
 - As per Matthias comment make 'earlycon_wrapper' as static structure.

Changes in V5:
 - Vote for core path only after checking whether "qcom_geni" earlycon is
   actually present or not by traversing over structure "console_drivers".

Changes in V6:
 - As per Matthias's comment removed NULL check for console_drivers global
   struct, added NULL check for earlycon_wrapper in _remove_earlycon_icc_vote
   API
 - Addressed nitpicks from Andy.

Changes in V7:
 - As per Matthias's comment removed usage of peak_bw variable because we don't
   have explicit peak requirement, we were voting peak = avg and this can be
   tracked using single variable for avg bw.
 - As per Matthias's comment improved print log.

Changes in V8:
 - No change.

 drivers/soc/qcom/qcom-geni-se.c   | 68 +++
 drivers/tty/serial/qcom_geni_serial.c |  7 
 include/linux/qcom-geni-se.h  |  2 ++
 3 files changed, 77 insertions(+)

diff --git a/drivers/soc/qcom/qcom-geni-se.c b/drivers/soc/qcom/qcom-geni-se.c
index 950e347..e2a0ba2 100644
--- a/drivers/soc/qcom/qcom-geni-se.c
+++ b/drivers/soc/qcom/qcom-geni-se.c
@@ -3,6 +3,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -90,11 +91,14 @@ struct geni_wrapper {
struct device *dev;
void __iomem *base;
struct clk_bulk_data ahb_clks[NUM_AHB_CLKS];
+   struct geni_icc_path to_core;
 };
 
 static const char * const icc_path_names[] = {"qup-core", "qup-config",
"qup-memory"};
 
+static struct geni_wrapper *earlycon_wrapper;
+
 #define QUP_HW_VER_REG 0x4
 
 /* Common SE registers */
@@ -802,11 +806,38 @@ int geni_icc_disable(struct geni_se *se)
 }
 EXPORT_SYMBOL(geni_icc_disable);
 
+void geni_remove_earlycon_icc_vote(void)
+{
+   struct geni_wrapper *wrapper;
+   struct device_node *parent;
+   struct device_node *child;
+
+   if (!earlycon_wrapper)
+   return;
+
+   wrapper = earlycon_wrapper;
+   parent = of_get_next_parent(wrapper->dev->of_node);
+   for_each_child_of_node(parent, child) {
+   if (!of_device_is_compatible(child, "qcom,geni-se-qup"))
+   continue;
+   wrapper = platform_get_drvdata(of_find_device_by_node(child));
+   icc_put(wrapper->to_core.path);
+   wrapper->to_core.path = NULL;
+
+   }
+   of_node_put(parent);
+
+   earlycon_wrapper = NULL;
+}
+EXPORT_SYMBOL(geni_remove_earlycon_icc_vote);
+
 static int geni_se_probe(struct platform_device *pdev)
 {
struct device *dev = >dev;
struct resource *res;
struct geni_wrapper *wrapper;
+   struct console __maybe_unused *bcon;
+   bool __maybe_unused has_earlycon = false;
int ret;
 
wrapper = devm_kzalloc(dev, sizeof(*wrapper), GFP_KERNEL);
@@ -829,6 +860,43 @@ static int geni_se_probe(struct platform_device *pdev)
}
}
 
+#ifdef CONFIG_SERIAL_EARLYCON
+   for_each_console(bcon) {
+   if (!strcmp(bcon->name, "qcom_geni")) {
+   has_earlycon = true;
+   break;
+   }
+   }
+   if (!has_earlycon)
+   goto exit;
+
+   wrapper->to_core.path = devm_of_icc_get(dev, "qup-core");
+   if (IS_ERR(wrapper->to_core.path))
+   return PTR_ERR(wrapper->to_core.path);
+   /*
+* Put minmal BW request on core clocks on behalf of early console.
+* The vote will be removed earlycon exit function.
+*
+* Note: We are putting vote on each QUP wrapper instead only to which
+* earlycon is connected because QUP core clock of different wrapper
+* share same voltage domain. If core1 is put to 0, then core2 will
+* also run at 0, if not voted. Default ICC vote will be removed ASA
+* we touch any of the core clock.
+* core1 = core2 = max(core1, core2)
+*/
+   ret = icc_set_b

[PATCH V8 1/8] soc: qcom: geni: Support for ICC voting

2020-06-23 Thread Akash Asthana
Add necessary macros and structure variables to support ICC BW
voting from individual SE drivers.

Signed-off-by: Akash Asthana 
Reviewed-by: Matthias Kaehlcke 
---
Changes in V2:
 - As per Bjorn's comment dropped enums for ICC paths, given the three
   paths individual members

Changes in V3:
 - Add geni_icc_get, geni_icc_vote_on and geni_icc_vote_off as helper API.
 - Add geni_icc_path structure in common header

Changes in V4:
 - As per Bjorn's comment print error message in geni_icc_get if return
   value is not -EPROBE_DEFER.
 - As per Bjorn's comment remove NULL on path before calling icc_set_bw
   API.
 - As per Bjorn's comment drop __func__ print.
 - As per Matthias's comment, make ICC path a array instead of individual
   member entry in geni_se struct.

Changes in V5:
 - As per Matthias's comment defined enums for ICC paths.
 - Integrate icc_enable/disable with power on/off call for driver.
 - As per Matthias's comment added icc_path_names array to print icc path name
   in failure case.
 - As per Georgi's suggestion assume peak_bw = avg_bw if not mentioned.

Changes in V6:
 - Addressed nitpicks from Matthias.

Changes in V7:
 - As per Matthias's comment removed usage of peak_bw variable because we don't
   have explicit peak requirement, we were voting peak = avg and this can be
   tracked using single variable for avg bw.
 - As per Matthias's comment improved print log.

Changes in V8:
 - No change.

Note: I have ignored below check patch suggestion because it was throwing
  compilation error as 'icc_ddr' is not compile time comstant.

WARNING: char * array declaration might be better as static const
 - FILE: drivers/soc/qcom/qcom-geni-se.c:726:
 - const char *icc_names[] = {"qup-core", "qup-config", icc_ddr};

 drivers/soc/qcom/qcom-geni-se.c | 82 +
 include/linux/qcom-geni-se.h| 38 +++
 2 files changed, 120 insertions(+)

diff --git a/drivers/soc/qcom/qcom-geni-se.c b/drivers/soc/qcom/qcom-geni-se.c
index 7d622ea..950e347 100644
--- a/drivers/soc/qcom/qcom-geni-se.c
+++ b/drivers/soc/qcom/qcom-geni-se.c
@@ -92,6 +92,9 @@ struct geni_wrapper {
struct clk_bulk_data ahb_clks[NUM_AHB_CLKS];
 };
 
+static const char * const icc_path_names[] = {"qup-core", "qup-config",
+   "qup-memory"};
+
 #define QUP_HW_VER_REG 0x4
 
 /* Common SE registers */
@@ -720,6 +723,85 @@ void geni_se_rx_dma_unprep(struct geni_se *se, dma_addr_t 
iova, size_t len)
 }
 EXPORT_SYMBOL(geni_se_rx_dma_unprep);
 
+int geni_icc_get(struct geni_se *se, const char *icc_ddr)
+{
+   int i, err;
+   const char *icc_names[] = {"qup-core", "qup-config", icc_ddr};
+
+   for (i = 0; i < ARRAY_SIZE(se->icc_paths); i++) {
+   if (!icc_names[i])
+   continue;
+
+   se->icc_paths[i].path = devm_of_icc_get(se->dev, icc_names[i]);
+   if (IS_ERR(se->icc_paths[i].path))
+   goto err;
+   }
+
+   return 0;
+
+err:
+   err = PTR_ERR(se->icc_paths[i].path);
+   if (err != -EPROBE_DEFER)
+   dev_err_ratelimited(se->dev, "Failed to get ICC path '%s': 
%d\n",
+   icc_names[i], err);
+   return err;
+
+}
+EXPORT_SYMBOL(geni_icc_get);
+
+int geni_icc_set_bw(struct geni_se *se)
+{
+   int i, ret;
+
+   for (i = 0; i < ARRAY_SIZE(se->icc_paths); i++) {
+   ret = icc_set_bw(se->icc_paths[i].path,
+   se->icc_paths[i].avg_bw, se->icc_paths[i].avg_bw);
+   if (ret) {
+   dev_err_ratelimited(se->dev, "ICC BW voting failed on 
path '%s': %d\n",
+   icc_path_names[i], ret);
+   return ret;
+   }
+   }
+
+   return 0;
+}
+EXPORT_SYMBOL(geni_icc_set_bw);
+
+/* To do: Replace this by icc_bulk_enable once it's implemented in ICC core */
+int geni_icc_enable(struct geni_se *se)
+{
+   int i, ret;
+
+   for (i = 0; i < ARRAY_SIZE(se->icc_paths); i++) {
+   ret = icc_enable(se->icc_paths[i].path);
+   if (ret) {
+   dev_err_ratelimited(se->dev, "ICC enable failed on path 
'%s': %d\n",
+   icc_path_names[i], ret);
+   return ret;
+   }
+   }
+
+   return 0;
+}
+EXPORT_SYMBOL(geni_icc_enable);
+
+int geni_icc_disable(struct geni_se *se)
+{
+   int i, ret;
+
+   for (i = 0; i < ARRAY_SIZE(se->icc_paths); i++) {
+   ret = icc_disable(se->icc_paths[i].path);
+   if (ret) {
+   dev_err_ratelimited(se->dev, "ICC disable failed on 
path '%s': %d\n",
+   icc_pat

[PATCH V8 4/8] tty: serial: qcom_geni_serial: Add interconnect support

2020-06-23 Thread Akash Asthana
Get the interconnect paths for Uart based Serial Engine device
and vote according to the baud rate requirement of the driver.

Signed-off-by: Akash Asthana 
Reviewed-by: Matthias Kaehlcke 
Acked-by: Greg Kroah-Hartman 
---
Changes in V2:
 - As per Bjorn's comment, removed se == NULL check from geni_serial_icc_get
 - As per Bjorn's comment, removed code to set se->icc_path* to NULL in failure
 - As per Bjorn's comment, introduced and using devm_of_icc_get API for getting
   path handle
 - As per Matthias comment, added error handling for icc_set_bw call

Changes in V3:
 - As per Matthias comment, use common library APIs defined in geni-se
   driver for ICC functionality.

Changes in V4:
 - As per Mark's comment move peak_bw guess as twice of avg_bw if
   nothing mentioned explicitly to ICC core.
 - As per Matthias's comment select core clock BW based on baud rate.
   If it's less than 115200 go for GENI_DEFAULT_BW else CORE_2X_50_MHZ

Changes in V5:
 - Add icc_enable/disable to power on/off call.
 - Save some non-zero avg/peak value to ICC core by calling geni_icc_set_bw
   from probe so that when resume/icc_enable is called NOC are running at
   some non-zero value. No need to call icc_disable after BW vote because
   console devices are expected to be in active state from the probe itself
   and qcom_geni_serial_pm(STATE_OFF) will be called for non-console ones.

Changes in V6:
 - No change

Changes in V7:
 - As per Matthias's comment removed usage of peak_bw variable because we don't
   have explicit peak requirement, we were voting peak = avg and this can be
   tracked using single variable for avg bw.

Changes in V8:
 - No change.

 drivers/tty/serial/qcom_geni_serial.c | 31 ---
 1 file changed, 28 insertions(+), 3 deletions(-)

diff --git a/drivers/tty/serial/qcom_geni_serial.c 
b/drivers/tty/serial/qcom_geni_serial.c
index a4468db..f701c7e 100644
--- a/drivers/tty/serial/qcom_geni_serial.c
+++ b/drivers/tty/serial/qcom_geni_serial.c
@@ -945,6 +945,7 @@ static void qcom_geni_serial_set_termios(struct uart_port 
*uport,
struct qcom_geni_serial_port *port = to_dev_port(uport, uport);
unsigned long clk_rate;
u32 ver, sampling_rate;
+   unsigned int avg_bw_core;
 
qcom_geni_serial_stop_rx(uport);
/* baud rate */
@@ -966,6 +967,16 @@ static void qcom_geni_serial_set_termios(struct uart_port 
*uport,
ser_clk_cfg = SER_CLK_EN;
ser_clk_cfg |= clk_div << CLK_DIV_SHFT;
 
+   /*
+* Bump up BW vote on CPU and CORE path as driver supports FIFO mode
+* only.
+*/
+   avg_bw_core = (baud > 115200) ? Bps_to_icc(CORE_2X_50_MHZ)
+   : GENI_DEFAULT_BW;
+   port->se.icc_paths[GENI_TO_CORE].avg_bw = avg_bw_core;
+   port->se.icc_paths[CPU_TO_GENI].avg_bw = Bps_to_icc(baud);
+   geni_icc_set_bw(>se);
+
/* parity */
tx_trans_cfg = readl(uport->membase + SE_UART_TX_TRANS_CFG);
tx_parity_cfg = readl(uport->membase + SE_UART_TX_PARITY_CFG);
@@ -1235,11 +1246,14 @@ static void qcom_geni_serial_pm(struct uart_port *uport,
if (old_state == UART_PM_STATE_UNDEFINED)
old_state = UART_PM_STATE_OFF;
 
-   if (new_state == UART_PM_STATE_ON && old_state == UART_PM_STATE_OFF)
+   if (new_state == UART_PM_STATE_ON && old_state == UART_PM_STATE_OFF) {
+   geni_icc_enable(>se);
geni_se_resources_on(>se);
-   else if (new_state == UART_PM_STATE_OFF &&
-   old_state == UART_PM_STATE_ON)
+   } else if (new_state == UART_PM_STATE_OFF &&
+   old_state == UART_PM_STATE_ON) {
geni_se_resources_off(>se);
+   geni_icc_disable(>se);
+   }
 }
 
 static const struct uart_ops qcom_geni_console_pops = {
@@ -1337,6 +1351,17 @@ static int qcom_geni_serial_probe(struct platform_device 
*pdev)
return -ENOMEM;
}
 
+   ret = geni_icc_get(>se, NULL);
+   if (ret)
+   return ret;
+   port->se.icc_paths[GENI_TO_CORE].avg_bw = GENI_DEFAULT_BW;
+   port->se.icc_paths[CPU_TO_GENI].avg_bw = GENI_DEFAULT_BW;
+
+   /* Set BW for register access */
+   ret = geni_icc_set_bw(>se);
+   if (ret)
+   return ret;
+
port->name = devm_kasprintf(uport->dev, GFP_KERNEL,
"qcom_geni_serial_%s%d",
uart_console(uport) ? "console" : "uart", uport->line);
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project



[PATCH V8 6/8] spi: spi-geni-qcom: Add interconnect support

2020-06-23 Thread Akash Asthana
Get the interconnect paths for SPI based Serial Engine device
and vote according to the current bus speed of the driver.

Signed-off-by: Akash Asthana 
---
Changes in V2:
 - As per Bjorn's comment, removed se == NULL check from geni_spi_icc_get
 - As per Bjorn's comment, removed code to set se->icc_path* to NULL in failure
 - As per Bjorn's comment, introduced and using devm_of_icc_get API for getting
   path handle
 - As per Matthias comment, added error handling for icc_set_bw call

Changes in V3:
 - As per Matthias's comment, use helper ICC function from geni-se driver.

Changes in V4:
 - Move peak_bw guess as twice of avg_bw if nothing mentioned explicitly
   to ICC core.

Changes in V5:
 - Use icc_enable/disable in power on/off call.
 - Save some non-zero avg/peak value to ICC core by calling geni_icc_set_bw
   from probe so that when resume/icc_enable is called NOC are running at
   some non-zero value. No need to call icc_disable after BW vote because
   device will resume and suspend before probe return and will leave ICC in
   disabled state.

Changes in V6:
 - No change

Changes in V7:
 - As per Matthias's comment removed usage of peak_bw variable because we don't
   have explicit peak requirement, we were voting peak = avg and this can be
   tracked using single variable for avg bw.

Changes in V8:
 - Adjust ICC vote per transfer, in multimessage transfer scenario.
 - Move ICC voting to common API "geni_spi_set_clock_and_bw".

 drivers/spi/spi-geni-qcom.c | 36 
 1 file changed, 32 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/spi-geni-qcom.c b/drivers/spi/spi-geni-qcom.c
index f186906..7a2e579 100644
--- a/drivers/spi/spi-geni-qcom.c
+++ b/drivers/spi/spi-geni-qcom.c
@@ -192,7 +192,8 @@ static void spi_setup_word_len(struct spi_geni_master *mas, 
u16 mode,
writel(word_len, se->base + SE_SPI_WORD_LEN);
 }
 
-static int geni_spi_set_clock(struct spi_geni_master *mas, unsigned long 
clk_hz)
+static int geni_spi_set_clock_and_bw(struct spi_geni_master *mas,
+   unsigned long clk_hz)
 {
u32 clk_sel, m_clk_cfg, idx, div;
struct geni_se *se = >se;
@@ -218,6 +219,12 @@ static int geni_spi_set_clock(struct spi_geni_master *mas, 
unsigned long clk_hz)
writel(clk_sel, se->base + SE_GENI_CLK_SEL);
writel(m_clk_cfg, se->base + GENI_SER_M_CLK_CFG);
 
+   /* Set BW quota for CPU as driver supports FIFO mode only. */
+   se->icc_paths[CPU_TO_GENI].avg_bw = Bps_to_icc(mas->cur_speed_hz);
+   ret = geni_icc_set_bw(se);
+   if (ret)
+   return ret;
+
return 0;
 }
 
@@ -259,7 +266,7 @@ static int setup_fifo_params(struct spi_device *spi_slv,
writel(cpol, se->base + SE_SPI_CPOL);
writel(demux_output_inv, se->base + SE_SPI_DEMUX_OUTPUT_INV);
 
-   return geni_spi_set_clock(mas, spi_slv->max_speed_hz);
+   return geni_spi_set_clock_and_bw(mas, spi_slv->max_speed_hz);
 }
 
 static int spi_geni_prepare_message(struct spi_master *spi,
@@ -346,7 +353,7 @@ static void setup_fifo_xfer(struct spi_transfer *xfer,
 
/* Speed and bits per word can be overridden per transfer */
if (xfer->speed_hz != mas->cur_speed_hz) {
-   ret = geni_spi_set_clock(mas, xfer->speed_hz);
+   ret = geni_spi_set_clock_and_bw(mas, xfer->speed_hz);
if (ret)
return;
}
@@ -620,6 +627,17 @@ static int spi_geni_probe(struct platform_device *pdev)
spin_lock_init(>lock);
pm_runtime_enable(dev);
 
+   ret = geni_icc_get(>se, NULL);
+   if (ret)
+   goto spi_geni_probe_runtime_disable;
+   /* Set the bus quota to a reasonable value for register access */
+   mas->se.icc_paths[GENI_TO_CORE].avg_bw = Bps_to_icc(CORE_2X_50_MHZ);
+   mas->se.icc_paths[CPU_TO_GENI].avg_bw = GENI_DEFAULT_BW;
+
+   ret = geni_icc_set_bw(>se);
+   if (ret)
+   goto spi_geni_probe_runtime_disable;
+
ret = spi_geni_init(mas);
if (ret)
goto spi_geni_probe_runtime_disable;
@@ -658,14 +676,24 @@ static int __maybe_unused spi_geni_runtime_suspend(struct 
device *dev)
 {
struct spi_master *spi = dev_get_drvdata(dev);
struct spi_geni_master *mas = spi_master_get_devdata(spi);
+   int ret;
+
+   ret = geni_se_resources_off(>se);
+   if (ret)
+   return ret;
 
-   return geni_se_resources_off(>se);
+   return geni_icc_disable(>se);
 }
 
 static int __maybe_unused spi_geni_runtime_resume(struct device *dev)
 {
struct spi_master *spi = dev_get_drvdata(dev);
struct spi_geni_master *mas = spi_master_get_devdata(spi);
+   int ret;
+
+   ret = geni_icc_enable(>se);
+   if (ret)
+   return ret;
 
return geni_se_resources_on(>se);
 }
-- 
The Qualco

[PATCH V6] serial: msm_geni_serial_console : Add Earlycon support

2020-06-22 Thread Akash Asthana
From: Mukesh Kumar Savaliya 

This change enables earlyconsole support as static driver for geni
based UART. Kernel space UART console driver will be generic for
console and other usecases of UART.

Signed-off-by: Mukesh Kumar Savaliya 
Signed-off-by: Akash Asthana 
---
Changes In V2:
 - Fixed Makefile Typo issue.

Changes In V3:
 - Removed mb() calls as *_relaxed() should take care.

Changes In V4:
 - Minor change: space between offset and base addition.

Changes In V5:
 - Removed unlikely() macro.
 - root_freq() array taken as static.
 - Removed extra readback of the register having no meaning.

Changes in V6:
 - Drop SERIAL_MSM_GENI_HALF_SAMPLING config and support only
   QUP HW ver > 2.5. As of now no device with QUP ver < 2.5 is using this
   code for earlycon so it won't break them. I will post separate patch to
   resolve this limitation.

Sending patch on behalf of Mukesh Savaliya.

 drivers/tty/serial/Kconfig   |   7 +
 drivers/tty/serial/Makefile  |   1 +
 drivers/tty/serial/msm_geni_serial_console.c | 480 +++
 3 files changed, 488 insertions(+)
 create mode 100644 drivers/tty/serial/msm_geni_serial_console.c

diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index 780908d..47caaa6 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -956,6 +956,13 @@ config SERIAL_MSM_CONSOLE
select SERIAL_CORE_CONSOLE
select SERIAL_EARLYCON
 
+config SERIAL_MSM_GENI_EARLY_CONSOLE
+   bool "MSM on-chip GENI HW based early console support"
+   select SERIAL_MSM_GENI_HALF_SAMPLING
+   help
+ Serial early console driver for Qualcomm Technologies Inc's GENI
+ based QUP hardware.
+
 config SERIAL_QCOM_GENI
tristate "QCOM on-chip GENI based serial port support"
depends on ARCH_QCOM || COMPILE_TEST
diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile
index d056ee6..7b6422e 100644
--- a/drivers/tty/serial/Makefile
+++ b/drivers/tty/serial/Makefile
@@ -55,6 +55,7 @@ obj-$(CONFIG_SERIAL_VR41XX) += vr41xx_siu.o
 obj-$(CONFIG_SERIAL_ATMEL) += atmel_serial.o
 obj-$(CONFIG_SERIAL_UARTLITE) += uartlite.o
 obj-$(CONFIG_SERIAL_MSM) += msm_serial.o
+obj-$(CONFIG_SERIAL_MSM_GENI_EARLY_CONSOLE) += msm_geni_serial_console.o
 obj-$(CONFIG_SERIAL_QCOM_GENI) += qcom_geni_serial.o
 obj-$(CONFIG_SERIAL_OMAP) += omap-serial.o
 obj-$(CONFIG_SERIAL_ALTERA_UART) += altera_uart.o
diff --git a/drivers/tty/serial/msm_geni_serial_console.c 
b/drivers/tty/serial/msm_geni_serial_console.c
new file mode 100644
index 000..80a7231
--- /dev/null
+++ b/drivers/tty/serial/msm_geni_serial_console.c
@@ -0,0 +1,480 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ */
+#include 
+#include 
+#include 
+#include 
+
+#define SE_UART_TX_TRANS_CFG   (0x25C)
+#define SE_UART_TX_WORD_LEN(0x268)
+#define SE_UART_TX_STOP_BIT_LEN(0x26C)
+#define SE_UART_TX_TRANS_LEN   (0x270)
+#define SE_UART_TX_PARITY_CFG  (0x2A4)
+/* SE_UART_TRANS_CFG */
+#define UART_CTS_MASK  (BIT(1))
+/* UART M_CMD OP codes */
+#define UART_START_TX  (0x1)
+
+#define UART_OVERSAMPLING  (32)
+#define DEF_FIFO_DEPTH_WORDS   (16)
+#define DEF_TX_WM  (2)
+#define DEF_FIFO_WIDTH_BITS(32)
+
+#define GENI_FORCE_DEFAULT_REG (0x20)
+#define GENI_OUTPUT_CTRL   (0x24)
+#define GENI_CGC_CTRL  (0x28)
+#define GENI_SER_M_CLK_CFG (0x48)
+#define GENI_FW_REVISION_RO(0x68)
+
+#define SE_GENI_TX_PACKING_CFG0(0x260)
+#define SE_GENI_TX_PACKING_CFG1(0x264)
+#define SE_GENI_M_CMD0 (0x600)
+#define SE_GENI_M_CMD_CTRL_REG (0x604)
+#define SE_GENI_M_IRQ_STATUS   (0x610)
+#define SE_GENI_M_IRQ_EN   (0x614)
+#define SE_GENI_M_IRQ_CLEAR(0x618)
+#define SE_GENI_TX_FIFOn   (0x700)
+#define SE_GENI_TX_WATERMARK_REG   (0x80C)
+
+#define SE_IRQ_EN  (0xE1C)
+#define SE_HW_PARAM_0  (0xE24)
+#define SE_HW_PARAM_1  (0xE28)
+
+/* GENI_OUTPUT_CTRL fields */
+#define DEFAULT_IO_OUTPUT_CTRL_MSK (GENMASK(6, 0))
+
+/* GENI_FORCE_DEFAULT_REG fields */
+#define FORCE_DEFAULT  (BIT(0))
+
+/* GENI_CGC_CTRL fields */
+#define CFG_AHB_CLK_CGC_ON (BIT(0))
+#define CFG_AHB_WR_ACLK_CGC_ON (BIT(1))
+#define DATA_AHB_CLK_CGC_ON(BIT(2))
+#define SCLK_CGC_ON(BIT(3))
+#define TX_CLK_CGC_ON  (BIT(4))
+#define RX_CLK_CGC_ON  (BIT(5))
+#define EXT_CLK_CGC_ON (BIT(6))
+#define PROG_RAM_HCLK_OFF  (BIT(8))
+#define PROG_RAM_SCLK_OFF  (BIT(9))
+#define DEFAULT_CGC_EN (GENMASK(6, 0))
+
+/* GENI_STATUS fields */
+#define M_GENI_CMD_

[PATCH V7 1/3] dt-bindings: geni-se: Convert QUP geni-se bindings to YAML

2020-05-27 Thread Akash Asthana
Convert QUP geni-se bindings to DT schema format using json-schema.

Signed-off-by: Akash Asthana 
Reviewed-by: Rob Herring 
Reviewed-by: Stephen Boyd 
---
Changes in V2:
 - As per Stephen's comment corrected defintion of interrupts for UART node.
   Any valid UART node must contain atleast 1 interrupts.

Changes in V3:
 - As per Rob's comment, added number of reg entries for reg property.
 - As per Rob's comment, corrected unit address to hex.
 - As per Rob's comment, created a pattern which matches everything common
   to geni based I2C, SPI and UART controller and then one pattern  for each.
 - As per Rob's comment, restored original example.

Changes in V4:
 - Resolve below compilation error reported from bot.

/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/soc/qcom/
qcom,geni-se.yaml: properties:clocks:minItems: False schema does not allow 2
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/soc/qcom/
qcom,geni-se.yaml: properties:clocks:maxItems: False schema does not allow 2
Documentation/devicetree/bindings/Makefile:12: recipe for target
'Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.example.dts' failed
make[1]: *** [Documentation/devicetree/bindings/soc/qcom/
qcom,geni-se.example.dts] Error 1
Makefile:1263: recipe for target 'dt_binding_check' failed
make: *** [dt_binding_check] Error 2

Changes in V6:
 - Added reg entry for soc@0 example node to address below warning.

Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.example.dts:22.20-60.11
: Warning (unit_address_vs_reg): /example-0/soc@0: node has a unit name,
but no reg or ranges property

Changes in V7:
 - No change.

 .../devicetree/bindings/soc/qcom/qcom,geni-se.txt  |  94 -
 .../devicetree/bindings/soc/qcom/qcom,geni-se.yaml | 210 +
 2 files changed, 210 insertions(+), 94 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt
 create mode 100644 Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.yaml

diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt 
b/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt
deleted file mode 100644
index dab7ca9..000
--- a/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt
+++ /dev/null
@@ -1,94 +0,0 @@
-Qualcomm Technologies, Inc. GENI Serial Engine QUP Wrapper Controller
-
-Generic Interface (GENI) based Qualcomm Universal Peripheral (QUP) wrapper
-is a programmable module for supporting a wide range of serial interfaces
-like UART, SPI, I2C, I3C, etc. A single QUP module can provide upto 8 Serial
-Interfaces, using its internal Serial Engines. The GENI Serial Engine QUP
-Wrapper controller is modeled as a node with zero or more child nodes each
-representing a serial engine.
-
-Required properties:
-- compatible:  Must be "qcom,geni-se-qup".
-- reg: Must contain QUP register address and length.
-- clock-names: Must contain "m-ahb" and "s-ahb".
-- clocks:  AHB clocks needed by the device.
-
-Required properties if child node exists:
-- #address-cells:  Must be <1> for Serial Engine Address
-- #size-cells: Must be <1> for Serial Engine Address Size
-- ranges:  Must be present
-
-Properties for children:
-
-A GENI based QUP wrapper controller node can contain 0 or more child nodes
-representing serial devices.  These serial devices can be a QCOM UART, I2C
-controller, SPI controller, or some combination of aforementioned devices.
-Please refer below the child node definitions for the supported serial
-interface protocols.
-
-Qualcomm Technologies Inc. GENI Serial Engine based I2C Controller
-
-Required properties:
-- compatible:  Must be "qcom,geni-i2c".
-- reg: Must contain QUP register address and length.
-- interrupts:  Must contain I2C interrupt.
-- clock-names: Must contain "se".
-- clocks:  Serial engine core clock needed by the device.
-- #address-cells:  Must be <1> for I2C device address.
-- #size-cells: Must be <0> as I2C addresses have no size component.
-
-Optional property:
-- clock-frequency: Desired I2C bus clock frequency in Hz.
-   When missing default to 10Hz.
-
-Child nodes should conform to I2C bus binding as described in i2c.txt.
-
-Qualcomm Technologies Inc. GENI Serial Engine based UART Controller
-
-Required properties:
-- compatible:  Must be "qcom,geni-debug-uart" or "qcom,geni-uart".
-- reg: Must contain UART register location and length.
-- interrupts:  Must contain UART core interrupts.
-- clock-names: Must contain "se".
-- clocks:  Serial engine core clock needed by the device.
-
-Qualcomm Technologies Inc. GENI Serial Engine based SPI Controller
-node binding is

[PATCH V7 3/3] dt-bindings: serial: Add binding for UART pin swap

2020-05-27 Thread Akash Asthana
Add documentation to support RX-TX & CTS-RTS GPIO pin swap in HW.

Signed-off-by: Akash Asthana 
Reviewed-by: Stephen Boyd 
---
Changes in V7:
 - As per Rob's comment, added type: boolean to properties.

 Documentation/devicetree/bindings/serial/serial.yaml | 8 
 1 file changed, 8 insertions(+)

diff --git a/Documentation/devicetree/bindings/serial/serial.yaml 
b/Documentation/devicetree/bindings/serial/serial.yaml
index 53204d9..8645d0e 100644
--- a/Documentation/devicetree/bindings/serial/serial.yaml
+++ b/Documentation/devicetree/bindings/serial/serial.yaml
@@ -67,6 +67,14 @@ properties:
   (wired and enabled by pinmux configuration).  This depends on both the
   UART hardware and the board wiring.
 
+  rx-tx-swap:
+type: boolean
+description: RX and TX pins are swapped.
+
+  cts-rts-swap:
+type: boolean
+description: CTS and RTS pins are swapped.
+
 if:
   required:
 - uart-has-rtscts
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project



[PATCH V7 2/3] dt-bindings: geni-se: Add interconnect binding for GENI QUP

2020-05-27 Thread Akash Asthana
Add documentation for the interconnect and interconnect-names properties
for the GENI QUP.

Signed-off-by: Akash Asthana 
Reviewed-by: Stephen Boyd 
---
Changes in V5:
 - Add interconnect property for QUP wrapper (parent node).
 - Add minItems = 2 for interconnect property in child nodes

Changes in V6:
 - As per Rob's comment added minItems = 2 for interconnect-names.

Changes in V7:
 - No change.

 .../devicetree/bindings/soc/qcom/qcom,geni-se.yaml  | 17 +
 1 file changed, 17 insertions(+)

diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.yaml 
b/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.yaml
index 885966f..b19505b 100644
--- a/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.yaml
+++ b/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.yaml
@@ -46,6 +46,12 @@ properties:
 
   ranges: true
 
+  interconnects:
+maxItems: 1
+
+  interconnect-names:
+const: qup-core
+
 required:
   - compatible
   - reg
@@ -73,6 +79,17 @@ patternProperties:
 description: Serial engine core clock needed by the device.
 maxItems: 1
 
+  interconnects:
+ minItems: 2
+ maxItems: 3
+
+  interconnect-names:
+ minItems: 2
+ items:
+   - const: qup-core
+   - const: qup-config
+   - const: qup-memory
+
 required:
   - reg
   - clock-names
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project



[PATCH V7 0/3] Convert QUP bindings to YAML and add ICC, pin swap doc

2020-05-27 Thread Akash Asthana
Changes in V6:
 - As per Rob's suggestion moved pin swap documentation from QUP to
   serial.yaml file[PATCH V6 3/3].

Changes in V4:
 - Add interconnect binding patch.
 - Add UART pin swap binding patch.

Akash Asthana (3):
  dt-bindings: geni-se: Convert QUP geni-se bindings to YAML
  dt-bindings: geni-se: Add interconnect binding for GENI QUP
  dt-bindings: serial: Add binding for UART pin swap

 .../devicetree/bindings/serial/serial.yaml |   6 +
 .../devicetree/bindings/soc/qcom/qcom,geni-se.txt  |  94 -
 .../devicetree/bindings/soc/qcom/qcom,geni-se.yaml | 227 +
 3 files changed, 233 insertions(+), 94 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt
 create mode 100644 Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.yaml

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project



Re: [PATCH V6 3/3] dt-bindings: serial: Add binding for UART pin swap

2020-05-18 Thread Akash Asthana

Hi Rob,

On 5/15/2020 8:31 AM, Rob Herring wrote:

On Thu, May 07, 2020 at 08:30:47PM +0530, Akash Asthana wrote:

Add documentation to support RX-TX & CTS-RTS GPIO pin swap in HW.

Signed-off-by: Akash Asthana 
---
  Documentation/devicetree/bindings/serial/serial.yaml | 6 ++
  1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/serial/serial.yaml 
b/Documentation/devicetree/bindings/serial/serial.yaml
index 53204d9..e657dd6 100644
--- a/Documentation/devicetree/bindings/serial/serial.yaml
+++ b/Documentation/devicetree/bindings/serial/serial.yaml
@@ -67,6 +67,12 @@ properties:
(wired and enabled by pinmux configuration).  This depends on both the
UART hardware and the board wiring.
  
+  rx-tx-swap:

+description: RX and TX pins are swapped.
+
+  cts-rts-swap:
+description: CTS and RTS pins are swapped.

Need 'type: boolean' on both of these.


okay, will correct in next version

Regards,

Akash




+
  if:
required:
  - uart-has-rtscts
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project


--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project


Re: [PATCH V6 0/3] Convert QUP bindings to YAML and add ICC, pin swap doc

2020-05-18 Thread Akash Asthana

Hi Stephen,

On 5/14/2020 7:33 AM, Stephen Boyd wrote:

Quoting Akash Asthana (2020-05-07 08:00:44)

Changes in V6:
  - As per Rob's suggestion moved pin swap documentation from QUP to
serial.yaml file[PATCH V6 3/3].

Changes in V4:
  - Add interconnect binding patch.
  - Add UART pin swap binding patch.

Akash Asthana (3):
   dt-bindings: geni-se: Convert QUP geni-se bindings to YAML
   dt-bindings: geni-se: Add interconnect binding for GENI QUP
   dt-bindings: serial: Add binding for UART pin swap


Who do you intend to pick up these patches? Rob or Greg? I suppose if
it's all in bindings then maybe Rob can pick them up.


I intended Rob to pick these patches but Greg is maintainer of 
serial.yaml file so I send patches to him as well, I thought I would be 
needing ack from him.


But from your reply it's clear that I should be sending to Rob only.

Regards,

Akash

--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project



[PATCH V6 2/3] dt-bindings: geni-se: Add interconnect binding for GENI QUP

2020-05-07 Thread Akash Asthana
Add documentation for the interconnect and interconnect-names properties
for the GENI QUP.

Signed-off-by: Akash Asthana 
---
Changes in V5:
 - Add interconnect property for QUP wrapper (parent node).
 - Add minItems = 2 for interconnect property in child nodes

Changes in V6:
 - As per Rob's comment added minItems = 2 for interconnect-names.

 .../devicetree/bindings/soc/qcom/qcom,geni-se.yaml  | 17 +
 1 file changed, 17 insertions(+)

diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.yaml 
b/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.yaml
index 885966f..b19505b 100644
--- a/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.yaml
+++ b/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.yaml
@@ -46,6 +46,12 @@ properties:
 
   ranges: true
 
+  interconnects:
+maxItems: 1
+
+  interconnect-names:
+const: qup-core
+
 required:
   - compatible
   - reg
@@ -73,6 +79,17 @@ patternProperties:
 description: Serial engine core clock needed by the device.
 maxItems: 1
 
+  interconnects:
+ minItems: 2
+ maxItems: 3
+
+  interconnect-names:
+ minItems: 2
+ items:
+   - const: qup-core
+   - const: qup-config
+   - const: qup-memory
+
 required:
   - reg
   - clock-names
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project


[PATCH V6 3/3] dt-bindings: serial: Add binding for UART pin swap

2020-05-07 Thread Akash Asthana
Add documentation to support RX-TX & CTS-RTS GPIO pin swap in HW.

Signed-off-by: Akash Asthana 
---
 Documentation/devicetree/bindings/serial/serial.yaml | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/serial/serial.yaml 
b/Documentation/devicetree/bindings/serial/serial.yaml
index 53204d9..e657dd6 100644
--- a/Documentation/devicetree/bindings/serial/serial.yaml
+++ b/Documentation/devicetree/bindings/serial/serial.yaml
@@ -67,6 +67,12 @@ properties:
   (wired and enabled by pinmux configuration).  This depends on both the
   UART hardware and the board wiring.
 
+  rx-tx-swap:
+description: RX and TX pins are swapped.
+
+  cts-rts-swap:
+description: CTS and RTS pins are swapped.
+
 if:
   required:
 - uart-has-rtscts
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project


[PATCH V6 1/3] dt-bindings: geni-se: Convert QUP geni-se bindings to YAML

2020-05-07 Thread Akash Asthana
Convert QUP geni-se bindings to DT schema format using json-schema.

Signed-off-by: Akash Asthana 
Reviewed-by: Rob Herring 
Reviewed-by: Stephen Boyd 
---
Changes in V2:
 - As per Stephen's comment corrected defintion of interrupts for UART node.
   Any valid UART node must contain atleast 1 interrupts.

Changes in V3:
 - As per Rob's comment, added number of reg entries for reg property.
 - As per Rob's comment, corrected unit address to hex.
 - As per Rob's comment, created a pattern which matches everything common
   to geni based I2C, SPI and UART controller and then one pattern  for each.
 - As per Rob's comment, restored original example.

Changes in V4:
 - Resolve below compilation error reported from bot.

/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/soc/qcom/
qcom,geni-se.yaml: properties:clocks:minItems: False schema does not allow 2
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/soc/qcom/
qcom,geni-se.yaml: properties:clocks:maxItems: False schema does not allow 2
Documentation/devicetree/bindings/Makefile:12: recipe for target
'Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.example.dts' failed
make[1]: *** [Documentation/devicetree/bindings/soc/qcom/
qcom,geni-se.example.dts] Error 1
Makefile:1263: recipe for target 'dt_binding_check' failed
make: *** [dt_binding_check] Error 2

Changes in V6:
 - Added reg entry for soc@0 example node to address below warning.

Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.example.dts:22.20-60.11
: Warning (unit_address_vs_reg): /example-0/soc@0: node has a unit name,
but no reg or ranges property

 .../devicetree/bindings/soc/qcom/qcom,geni-se.txt  |  94 -
 .../devicetree/bindings/soc/qcom/qcom,geni-se.yaml | 210 +
 2 files changed, 210 insertions(+), 94 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt
 create mode 100644 Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.yaml

diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt 
b/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt
deleted file mode 100644
index dab7ca9..000
--- a/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt
+++ /dev/null
@@ -1,94 +0,0 @@
-Qualcomm Technologies, Inc. GENI Serial Engine QUP Wrapper Controller
-
-Generic Interface (GENI) based Qualcomm Universal Peripheral (QUP) wrapper
-is a programmable module for supporting a wide range of serial interfaces
-like UART, SPI, I2C, I3C, etc. A single QUP module can provide upto 8 Serial
-Interfaces, using its internal Serial Engines. The GENI Serial Engine QUP
-Wrapper controller is modeled as a node with zero or more child nodes each
-representing a serial engine.
-
-Required properties:
-- compatible:  Must be "qcom,geni-se-qup".
-- reg: Must contain QUP register address and length.
-- clock-names: Must contain "m-ahb" and "s-ahb".
-- clocks:  AHB clocks needed by the device.
-
-Required properties if child node exists:
-- #address-cells:  Must be <1> for Serial Engine Address
-- #size-cells: Must be <1> for Serial Engine Address Size
-- ranges:  Must be present
-
-Properties for children:
-
-A GENI based QUP wrapper controller node can contain 0 or more child nodes
-representing serial devices.  These serial devices can be a QCOM UART, I2C
-controller, SPI controller, or some combination of aforementioned devices.
-Please refer below the child node definitions for the supported serial
-interface protocols.
-
-Qualcomm Technologies Inc. GENI Serial Engine based I2C Controller
-
-Required properties:
-- compatible:  Must be "qcom,geni-i2c".
-- reg: Must contain QUP register address and length.
-- interrupts:  Must contain I2C interrupt.
-- clock-names: Must contain "se".
-- clocks:  Serial engine core clock needed by the device.
-- #address-cells:  Must be <1> for I2C device address.
-- #size-cells: Must be <0> as I2C addresses have no size component.
-
-Optional property:
-- clock-frequency: Desired I2C bus clock frequency in Hz.
-   When missing default to 10Hz.
-
-Child nodes should conform to I2C bus binding as described in i2c.txt.
-
-Qualcomm Technologies Inc. GENI Serial Engine based UART Controller
-
-Required properties:
-- compatible:  Must be "qcom,geni-debug-uart" or "qcom,geni-uart".
-- reg: Must contain UART register location and length.
-- interrupts:  Must contain UART core interrupts.
-- clock-names: Must contain "se".
-- clocks:  Serial engine core clock needed by the device.
-
-Qualcomm Technologies Inc. GENI Serial Engine based SPI Controller
-node binding is described in
-Documentation/devicet

Re: [PATCH V5 2/3] dt-bindings: geni-se: Add interconnect binding for GENI QUP

2020-05-07 Thread Akash Asthana

Hi Rob,

  
+  interconnects:

+ minItems: 2
+ maxItems: 3
+
+  interconnect-names:
+ items:
+   - const: qup-core
+   - const: qup-config
+   - const: qup-memory

Don't you need 'minItems: 2' here?


Yeah I need minItems: 2 here, thanks for reviewing.

regards,

Akash



Rob


--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project


[PATCH V6 0/3] Convert QUP bindings to YAML and add ICC, pin swap doc

2020-05-07 Thread Akash Asthana
Changes in V6:
 - As per Rob's suggestion moved pin swap documentation from QUP to
   serial.yaml file[PATCH V6 3/3].

Changes in V4:
 - Add interconnect binding patch.
 - Add UART pin swap binding patch.

Akash Asthana (3):
  dt-bindings: geni-se: Convert QUP geni-se bindings to YAML
  dt-bindings: geni-se: Add interconnect binding for GENI QUP
  dt-bindings: serial: Add binding for UART pin swap

 .../devicetree/bindings/serial/serial.yaml |   6 +
 .../devicetree/bindings/soc/qcom/qcom,geni-se.txt  |  94 -
 .../devicetree/bindings/soc/qcom/qcom,geni-se.yaml | 227 +
 3 files changed, 233 insertions(+), 94 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt
 create mode 100644 Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.yaml

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project


Re: [PATCH] interconnect: Add helpers for enabling/disabling a path

2020-05-04 Thread Akash Asthana

Hi Georgi,

On 4/28/2020 2:46 PM, Georgi Djakov wrote:

There is a repeated pattern in multiple drivers where they want to switch
the bandwidth between zero and some other value. This is happening often
in the suspend/resume callbacks. Let's add helper functions to enable and
disable the path, so that callers don't have to take care of remembering
the bandwidth values and handle this in the framework instead.

With this patch the users can call icc_disable() and icc_enable() to lower
their bandwidth request to zero and then restore it back to it's previous
value.


Thanks for this patch.

Are you planning to add bulk versions of icc_enable/disable APIs?

Regards,

Akash

--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project


Re: [PATCH V5 3/3] dt-bindings: geni-se: Add binding for UART pin swap

2020-04-28 Thread Akash Asthana

Hi Matthias

Thanks for notifying, I will make the changes.

Regards,

Akash

On 4/25/2020 2:27 AM, Matthias Kaehlcke wrote:

Hi Akash,

On Tue, Mar 24, 2020 at 10:46:40AM +0530, Akash Asthana wrote:

Hi Rob,

On 3/20/2020 11:37 PM, Rob Herring wrote:

On Fri, Mar 13, 2020 at 4:29 AM Akash Asthana  wrote:

Add documentation to support RX/TX/CTS/RTS pin swap in HW.

Signed-off-by: Akash Asthana 
---
Changes in V5:
   -  As per Matthias's comment, remove rx-tx-cts-rts-swap property from UART
  child node.

   Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.yaml | 6 ++
   1 file changed, 6 insertions(+)

STM32 folks need something similar. Can you move this to a common
location. That's serial.txt, but that is being converted to DT schema.

Rob

Okay, once serial.txt is converted to DT schema, I will move it there.

It has landed upstream:

175a7427bb72 dt-bindings: serial: Convert generic bindings to json-schema


--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na 
Linux Foundation Collaborative Project