[PATCH V5 6/6] dts: msm8974: Add dma channels for blsp2_i2c1 node

2015-11-17 Thread Sricharan R
Signed-off-by: Sricharan R 
---
 arch/arm/boot/dts/qcom-msm8974.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi 
b/arch/arm/boot/dts/qcom-msm8974.dtsi
index 7786408..bd1be53 100644
--- a/arch/arm/boot/dts/qcom-msm8974.dtsi
+++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
@@ -328,6 +328,8 @@
clock-names = "core", "iface";
#address-cells = <1>;
#size-cells = <0>;
+   dmas = <_dma 20>, <_dma 21>;
+   dma-names = "tx", "rx";
};
 
spmi_bus: spmi@fc4cf000 {
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation

--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH V5 4/6] i2c: qup: Add bam dma capabilities

2015-11-17 Thread Sricharan R
QUP cores can be attached to a BAM module, which acts as a dma engine for the
QUP core. When DMA with BAM is enabled, the BAM consumer pipe transmitted data
is written to the output FIFO and the BAM producer pipe received data is read
from the input FIFO.

With BAM capabilities, qup-i2c core can transfer more than 256 bytes, without a
'stop' which is not possible otherwise.

Signed-off-by: Sricharan R 
---
 drivers/i2c/busses/i2c-qup.c | 447 ++-
 1 file changed, 439 insertions(+), 8 deletions(-)

diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c
index f9009d6..4ca1669 100644
--- a/drivers/i2c/busses/i2c-qup.c
+++ b/drivers/i2c/busses/i2c-qup.c
@@ -14,8 +14,12 @@
  *
  */
 
+#include 
 #include 
 #include 
+#include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -24,6 +28,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /* QUP Registers */
 #define QUP_CONFIG 0x000
@@ -33,6 +38,7 @@
 #define QUP_OPERATIONAL0x018
 #define QUP_ERROR_FLAGS0x01c
 #define QUP_ERROR_FLAGS_EN 0x020
+#define QUP_OPERATIONAL_MASK   0x028
 #define QUP_HW_VERSION 0x030
 #define QUP_MX_OUTPUT_CNT  0x100
 #define QUP_OUT_FIFO_BASE  0x110
@@ -52,6 +58,7 @@
 
 #define QUP_STATE_VALIDBIT(2)
 #define QUP_I2C_MAST_GEN   BIT(4)
+#define QUP_I2C_FLUSH  BIT(6)
 
 #define QUP_OPERATIONAL_RESET  0x000ff0
 #define QUP_I2C_STATUS_RESET   0xfc
@@ -77,7 +84,10 @@
 
 /* Packing/Unpacking words in FIFOs, and IO modes */
 #define QUP_OUTPUT_BLK_MODE(1 << 10)
+#define QUP_OUTPUT_BAM_MODE(3 << 10)
 #define QUP_INPUT_BLK_MODE (1 << 12)
+#define QUP_INPUT_BAM_MODE (3 << 12)
+#define QUP_BAM_MODE   (QUP_OUTPUT_BAM_MODE | QUP_INPUT_BAM_MODE)
 #define QUP_UNPACK_EN  BIT(14)
 #define QUP_PACK_ENBIT(15)
 
@@ -94,6 +104,8 @@
 #define QUP_TAG_DATA   (2 << 8)
 #define QUP_TAG_STOP   (3 << 8)
 #define QUP_TAG_REC(4 << 8)
+#define QUP_BAM_INPUT_EOT  0x93
+#define QUP_BAM_FLUSH_STOP 0x96
 
 /* QUP v2 tags */
 #define QUP_TAG_V2_START   0x81
@@ -114,6 +126,12 @@
 #define ONE_BYTE   0x1
 #define QUP_I2C_MX_CONFIG_DURING_RUN   BIT(31)
 
+#define MX_TX_RX_LEN   SZ_64K
+#define MX_BLOCKS  (MX_TX_RX_LEN / QUP_READ_LIMIT)
+
+/* Max timeout in ms for 32k bytes */
+#define TOUT_MAX   300
+
 struct qup_i2c_block {
int count;
int pos;
@@ -123,6 +141,17 @@ struct qup_i2c_block {
u8  tags[6];
 };
 
+struct qup_i2c_tag {
+   u8 *start;
+   dma_addr_t addr;
+};
+
+struct qup_i2c_bam {
+   struct  qup_i2c_tag tag;
+   struct  dma_chan *dma;
+   struct  scatterlist *sg;
+};
+
 struct qup_i2c_dev {
struct device   *dev;
void __iomem*base;
@@ -154,6 +183,13 @@ struct qup_i2c_dev {
/* To configure when bus is in run state */
int config_run;
 
+   /* dma parameters */
+   boolis_dma;
+   struct  dma_pool *dpool;
+   struct  qup_i2c_tag start_tag;
+   struct  qup_i2c_bam brx;
+   struct  qup_i2c_bam btx;
+
struct completion   xfer;
 };
 
@@ -230,6 +266,14 @@ static int qup_i2c_poll_state(struct qup_i2c_dev *qup, u32 
req_state)
return qup_i2c_poll_state_mask(qup, req_state, QUP_STATE_MASK);
 }
 
+static void qup_i2c_flush(struct qup_i2c_dev *qup)
+{
+   u32 val = readl(qup->base + QUP_STATE);
+
+   val |= QUP_I2C_FLUSH;
+   writel(val, qup->base + QUP_STATE);
+}
+
 static int qup_i2c_poll_state_valid(struct qup_i2c_dev *qup)
 {
return qup_i2c_poll_state_mask(qup, 0, 0);
@@ -437,12 +481,14 @@ static int qup_i2c_get_data_len(struct qup_i2c_dev *qup)
 }
 
 static int qup_i2c_set_tags(u8 *tags, struct qup_i2c_dev *qup,
-   struct i2c_msg *msg)
+   struct i2c_msg *msg,  int is_dma)
 {
u16 addr = (msg->addr << 1) | ((msg->flags & I2C_M_RD) == I2C_M_RD);
int len = 0;
int data_len;
 
+   int last = (qup->blk.pos == (qup->blk.count - 1)) && (qup->is_last);
+
if (qup->blk.pos == 0) {
tags[len++] = QUP_TAG_V2_START;
tags[len++] = addr & 0xff;
@@ -452,7 +498,7 @@ static int qup_i2c_set_tags(u8 *tags, struct qup_i2c_dev 
*qup,
}
 
/* Send _STOP commands for the last block */
-   if ((qup->blk.pos == (qup->blk.count - 1)) && qup->is_last) {
+   if (last) {
if (msg->flags & I2C_M_RD)
tags[len++] = QUP_TAG_V2_DATARD_STOP;
else
@@ -472,6 +518,11 @@ static int qup_i2c_set_tags(u8 *tags, struct qup_i2c_dev 
*qup,
else
tags[len++] = data_len;
 

[PATCH V5 2/6] i2c: qup: Add V2 tags support

2015-11-17 Thread Sricharan R
QUP from version 2.1.1 onwards, supports a new format of
i2c command tags. Tag codes instructs the controller to
perform a operation like read/write. This new tagging version
supports bam dma and transfers of more than 256 bytes without 'stop'
in between. Adding the support for the same.

For each block a data_write/read tag and data_len tag is added to
the output fifo. For the final block of data write_stop/read_stop
tag is used.

Signed-off-by: Andy Gross 
Signed-off-by: Sricharan R 
---
 drivers/i2c/busses/i2c-qup.c | 415 ---
 1 file changed, 386 insertions(+), 29 deletions(-)

diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c
index 81ed120..715d4d7 100644
--- a/drivers/i2c/busses/i2c-qup.c
+++ b/drivers/i2c/busses/i2c-qup.c
@@ -42,6 +42,7 @@
 #define QUP_IN_FIFO_BASE   0x218
 #define QUP_I2C_CLK_CTL0x400
 #define QUP_I2C_STATUS 0x404
+#define QUP_I2C_MASTER_GEN 0x408
 
 /* QUP States and reset values */
 #define QUP_RESET_STATE0
@@ -69,6 +70,8 @@
 #define QUP_CLOCK_AUTO_GATEBIT(13)
 #define I2C_MINI_CORE  (2 << 8)
 #define I2C_N_VAL  15
+#define I2C_N_VAL_V2   7
+
 /* Most significant word offset in FIFO port */
 #define QUP_MSW_SHIFT  (I2C_N_VAL + 1)
 
@@ -79,6 +82,7 @@
 #define QUP_PACK_ENBIT(15)
 
 #define QUP_REPACK_EN  (QUP_UNPACK_EN | QUP_PACK_EN)
+#define QUP_V2_TAGS_EN 1
 
 #define QUP_OUTPUT_BLOCK_SIZE(x)(((x) >> 0) & 0x03)
 #define QUP_OUTPUT_FIFO_SIZE(x)(((x) >> 2) & 0x07)
@@ -91,6 +95,13 @@
 #define QUP_TAG_STOP   (3 << 8)
 #define QUP_TAG_REC(4 << 8)
 
+/* QUP v2 tags */
+#define QUP_TAG_V2_START   0x81
+#define QUP_TAG_V2_DATAWR  0x82
+#define QUP_TAG_V2_DATAWR_STOP 0x83
+#define QUP_TAG_V2_DATARD  0x85
+#define QUP_TAG_V2_DATARD_STOP 0x87
+
 /* Status, Error flags */
 #define I2C_STATUS_WR_BUFFER_FULL  BIT(0)
 #define I2C_STATUS_BUS_ACTIVE  BIT(8)
@@ -102,6 +113,15 @@
 #define RESET_BIT  0x0
 #define ONE_BYTE   0x1
 
+struct qup_i2c_block {
+   int count;
+   int pos;
+   int tx_tag_len;
+   int rx_tag_len;
+   int data_len;
+   u8  tags[6];
+};
+
 struct qup_i2c_dev {
struct device   *dev;
void __iomem*base;
@@ -117,6 +137,7 @@ struct qup_i2c_dev {
int in_blk_sz;
 
unsigned long   one_byte_t;
+   struct qup_i2c_blockblk;
 
struct i2c_msg  *msg;
/* Current posion in user message buffer */
@@ -263,6 +284,24 @@ static int qup_i2c_wait_ready(struct qup_i2c_dev *qup, int 
op, bool val,
}
 }
 
+static void qup_i2c_set_write_mode_v2(struct qup_i2c_dev *qup,
+ struct i2c_msg *msg)
+{
+   /* Number of entries to shift out, including the tags */
+   int total = msg->len + qup->blk.tx_tag_len;
+
+   if (total < qup->out_fifo_sz) {
+   /* FIFO mode */
+   writel(QUP_REPACK_EN, qup->base + QUP_IO_MODE);
+   writel(total, qup->base + QUP_MX_WRITE_CNT);
+   } else {
+   /* BLOCK mode (transfer data on chunks) */
+   writel(QUP_OUTPUT_BLK_MODE | QUP_REPACK_EN,
+  qup->base + QUP_IO_MODE);
+   writel(total, qup->base + QUP_MX_OUTPUT_CNT);
+   }
+}
+
 static void qup_i2c_set_write_mode(struct qup_i2c_dev *qup, struct i2c_msg 
*msg)
 {
/* Number of entries to shift out, including the start */
@@ -324,9 +363,189 @@ static int qup_i2c_issue_write(struct qup_i2c_dev *qup, 
struct i2c_msg *msg)
return ret;
 }
 
-static int qup_i2c_write_one(struct qup_i2c_dev *qup, struct i2c_msg *msg)
+static void qup_i2c_set_blk_data(struct qup_i2c_dev *qup,
+struct i2c_msg *msg)
+{
+   memset(>blk, 0, sizeof(qup->blk));
+
+   qup->blk.data_len = msg->len;
+   qup->blk.count = (msg->len + QUP_READ_LIMIT - 1) / QUP_READ_LIMIT;
+
+   /* 4 bytes for first block and 2 writes for rest */
+   qup->blk.tx_tag_len = 4 + (qup->blk.count - 1) * 2;
+
+   /* There are 2 tag bytes that are read in to fifo for every block */
+   if (msg->flags & I2C_M_RD)
+   qup->blk.rx_tag_len = qup->blk.count * 2;
+}
+
+static int qup_i2c_send_data(struct qup_i2c_dev *qup, int tlen, u8 *tbuf,
+int dlen, u8 *dbuf)
+{
+   u32 val = 0, idx = 0, pos = 0, i = 0, t;
+   int  len = tlen + dlen;
+   u8 *buf = tbuf;
+   int ret = 0;
+
+   while (len > 0) {
+   ret = qup_i2c_wait_ready(qup, QUP_OUT_FULL,
+RESET_BIT, 4 * ONE_BYTE);
+   if (ret) {
+   dev_err(qup->dev, "timeout for 

[PATCH V5 5/6] dts: msm8974: Add blsp2_bam dma node

2015-11-17 Thread Sricharan R
Signed-off-by: Sricharan R 
---
 arch/arm/boot/dts/qcom-msm8974.dtsi | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi 
b/arch/arm/boot/dts/qcom-msm8974.dtsi
index 753bdfd..7786408 100644
--- a/arch/arm/boot/dts/qcom-msm8974.dtsi
+++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
@@ -1,6 +1,6 @@
 /dts-v1/;
 
-#include 
+#include 
 #include 
 #include "skeleton.dtsi"
 
@@ -345,6 +345,16 @@
interrupt-controller;
#interrupt-cells = <4>;
};
+
+   blsp2_dma: dma-controller@f9944000 {
+   compatible = "qcom,bam-v1.4.0";
+   reg = <0xf9944000 0x19000>;
+   interrupts = ;
+   clocks = < GCC_BLSP2_AHB_CLK>;
+   clock-names = "bam_clk";
+   #dma-cells = <1>;
+   qcom,ee = <0>;
+   };
};
 
smd {
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation

--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH V5 3/6] i2c: qup: Transfer each i2c_msg in i2c_msgs without a stop bit

2015-11-17 Thread Sricharan R
The definition of i2c_msg says that

"If this is the last message in a group, it is followed by a STOP.
Otherwise it is followed by the next @i2c_msg transaction segment,
beginning with a (repeated) START"

So the expectation is that there is no 'STOP' bit inbetween individual
i2c_msg segments with repeated 'START'. The QUP i2c hardware has no way
to inform that there should not be a 'STOP' at the end of transaction.
The only way to implement this is to coalesce all the i2c_msg in i2c_msgs
in to one transaction and transfer them. Adding the support for the same.

This is required for some clients like touchscreen which keeps
incrementing counts across individual transfers and 'STOP' bit inbetween
resets the counter, which is not required.

This patch adds the support in non-dma mode.

Signed-off-by: Sricharan R 
---
 drivers/i2c/busses/i2c-qup.c | 34 ++
 1 file changed, 26 insertions(+), 8 deletions(-)

diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c
index 715d4d7..f9009d6 100644
--- a/drivers/i2c/busses/i2c-qup.c
+++ b/drivers/i2c/busses/i2c-qup.c
@@ -112,6 +112,7 @@
 #define SET_BIT0x1
 #define RESET_BIT  0x0
 #define ONE_BYTE   0x1
+#define QUP_I2C_MX_CONFIG_DURING_RUN   BIT(31)
 
 struct qup_i2c_block {
int count;
@@ -147,6 +148,12 @@ struct qup_i2c_dev {
/* QUP core errors */
u32 qup_err;
 
+   /* To check if this is the last msg */
+   boolis_last;
+
+   /* To configure when bus is in run state */
+   int config_run;
+
struct completion   xfer;
 };
 
@@ -269,7 +276,7 @@ static int qup_i2c_wait_ready(struct qup_i2c_dev *qup, int 
op, bool val,
status = readl(qup->base + QUP_I2C_STATUS);
 
if (((opflags & op) >> shift) == val) {
-   if (op == QUP_OUT_NOT_EMPTY) {
+   if ((op == QUP_OUT_NOT_EMPTY) && qup->is_last) {
if (!(status & I2C_STATUS_BUS_ACTIVE))
return 0;
} else {
@@ -290,6 +297,8 @@ static void qup_i2c_set_write_mode_v2(struct qup_i2c_dev 
*qup,
/* Number of entries to shift out, including the tags */
int total = msg->len + qup->blk.tx_tag_len;
 
+   total |= qup->config_run;
+
if (total < qup->out_fifo_sz) {
/* FIFO mode */
writel(QUP_REPACK_EN, qup->base + QUP_IO_MODE);
@@ -443,7 +452,7 @@ static int qup_i2c_set_tags(u8 *tags, struct qup_i2c_dev 
*qup,
}
 
/* Send _STOP commands for the last block */
-   if (qup->blk.pos == (qup->blk.count - 1)) {
+   if ((qup->blk.pos == (qup->blk.count - 1)) && qup->is_last) {
if (msg->flags & I2C_M_RD)
tags[len++] = QUP_TAG_V2_DATARD_STOP;
else
@@ -581,7 +590,6 @@ static int qup_i2c_write_one(struct qup_i2c_dev *qup, 
struct i2c_msg *msg)
 
/* Wait for the outstanding data in the fifo to drain */
ret = qup_i2c_wait_ready(qup, QUP_OUT_NOT_EMPTY, RESET_BIT, ONE_BYTE);
-
 err:
disable_irq(qup->irq);
qup->msg = NULL;
@@ -608,18 +616,20 @@ static void qup_i2c_set_read_mode_v2(struct qup_i2c_dev 
*qup, int len)
int tx_len = qup->blk.tx_tag_len;
 
len += qup->blk.rx_tag_len;
+   len |= qup->config_run;
+   tx_len |= qup->config_run;
 
if (len < qup->in_fifo_sz) {
/* FIFO mode */
writel(QUP_REPACK_EN, qup->base + QUP_IO_MODE);
-   writel(len, qup->base + QUP_MX_READ_CNT);
writel(tx_len, qup->base + QUP_MX_WRITE_CNT);
+   writel(len, qup->base + QUP_MX_READ_CNT);
} else {
/* BLOCK mode (transfer data on chunks) */
writel(QUP_INPUT_BLK_MODE | QUP_REPACK_EN,
   qup->base + QUP_IO_MODE);
-   writel(len, qup->base + QUP_MX_INPUT_CNT);
writel(tx_len, qup->base + QUP_MX_OUTPUT_CNT);
+   writel(len, qup->base + QUP_MX_INPUT_CNT);
}
 }
 
@@ -866,6 +876,12 @@ static int qup_i2c_xfer_v2(struct i2c_adapter *adap,
goto out;
}
 
+   qup->is_last = (idx == (num - 1));
+   if (idx)
+   qup->config_run = QUP_I2C_MX_CONFIG_DURING_RUN;
+   else
+   qup->config_run = 0;
+
reinit_completion(>xfer);
 
if (msgs[idx].flags & I2C_M_RD)
@@ -873,13 +889,13 @@ static int qup_i2c_xfer_v2(struct i2c_adapter *adap,
else
ret = qup_i2c_write_one_v2(qup, [idx]);
 
-   if (!ret)
-   ret = qup_i2c_change_state(qup, QUP_RESET_STATE);
-
if (ret)

[PATCH V5 1/6] i2c: qup: Change qup_wait_writeready function to use for all timeouts

2015-11-17 Thread Sricharan R
qup_wait_writeready waits only on a output fifo empty event.
Change the same function to accept the event and data length
to wait as parameters. This way the same function can be used for
timeouts in other places as well.

Signed-off-by: Sricharan R 
---
 drivers/i2c/busses/i2c-qup.c | 67 +++-
 1 file changed, 48 insertions(+), 19 deletions(-)

diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c
index fdcbdab..81ed120 100644
--- a/drivers/i2c/busses/i2c-qup.c
+++ b/drivers/i2c/busses/i2c-qup.c
@@ -98,6 +98,9 @@
 #define QUP_STATUS_ERROR_FLAGS 0x7c
 
 #define QUP_READ_LIMIT 256
+#define SET_BIT0x1
+#define RESET_BIT  0x0
+#define ONE_BYTE   0x1
 
 struct qup_i2c_dev {
struct device   *dev;
@@ -221,26 +224,42 @@ static int qup_i2c_change_state(struct qup_i2c_dev *qup, 
u32 state)
return 0;
 }
 
-static int qup_i2c_wait_writeready(struct qup_i2c_dev *qup)
+/**
+ * qup_i2c_wait_ready - wait for a give number of bytes in tx/rx path
+ * @qup: The qup_i2c_dev device
+ * @op: The bit/event to wait on
+ * @val: value of the bit to wait on, 0 or 1
+ * @len: The length the bytes to be transferred
+ */
+static int qup_i2c_wait_ready(struct qup_i2c_dev *qup, int op, bool val,
+ int len)
 {
unsigned long timeout;
u32 opflags;
u32 status;
+   u32 shift = __ffs(op);
 
-   timeout = jiffies + HZ;
+   len *= qup->one_byte_t;
+   /* timeout after a wait of twice the max time */
+   timeout = jiffies + len * 4;
 
for (;;) {
opflags = readl(qup->base + QUP_OPERATIONAL);
status = readl(qup->base + QUP_I2C_STATUS);
 
-   if (!(opflags & QUP_OUT_NOT_EMPTY) &&
-   !(status & I2C_STATUS_BUS_ACTIVE))
-   return 0;
+   if (((opflags & op) >> shift) == val) {
+   if (op == QUP_OUT_NOT_EMPTY) {
+   if (!(status & I2C_STATUS_BUS_ACTIVE))
+   return 0;
+   } else {
+   return 0;
+   }
+   }
 
if (time_after(jiffies, timeout))
return -ETIMEDOUT;
 
-   usleep_range(qup->one_byte_t, qup->one_byte_t * 2);
+   usleep_range(len, len * 2);
}
 }
 
@@ -261,13 +280,13 @@ static void qup_i2c_set_write_mode(struct qup_i2c_dev 
*qup, struct i2c_msg *msg)
}
 }
 
-static void qup_i2c_issue_write(struct qup_i2c_dev *qup, struct i2c_msg *msg)
+static int qup_i2c_issue_write(struct qup_i2c_dev *qup, struct i2c_msg *msg)
 {
u32 addr = msg->addr << 1;
u32 qup_tag;
-   u32 opflags;
int idx;
u32 val;
+   int ret = 0;
 
if (qup->pos == 0) {
val = QUP_TAG_START | addr;
@@ -279,9 +298,10 @@ static void qup_i2c_issue_write(struct qup_i2c_dev *qup, 
struct i2c_msg *msg)
 
while (qup->pos < msg->len) {
/* Check that there's space in the FIFO for our pair */
-   opflags = readl(qup->base + QUP_OPERATIONAL);
-   if (opflags & QUP_OUT_FULL)
-   break;
+   ret = qup_i2c_wait_ready(qup, QUP_OUT_FULL, RESET_BIT,
+4 * ONE_BYTE);
+   if (ret)
+   return ret;
 
if (qup->pos == msg->len - 1)
qup_tag = QUP_TAG_STOP;
@@ -300,6 +320,8 @@ static void qup_i2c_issue_write(struct qup_i2c_dev *qup, 
struct i2c_msg *msg)
qup->pos++;
idx++;
}
+
+   return ret;
 }
 
 static int qup_i2c_write_one(struct qup_i2c_dev *qup, struct i2c_msg *msg)
@@ -325,7 +347,9 @@ static int qup_i2c_write_one(struct qup_i2c_dev *qup, 
struct i2c_msg *msg)
if (ret)
goto err;
 
-   qup_i2c_issue_write(qup, msg);
+   ret = qup_i2c_issue_write(qup, msg);
+   if (ret)
+   goto err;
 
ret = qup_i2c_change_state(qup, QUP_RUN_STATE);
if (ret)
@@ -347,7 +371,7 @@ static int qup_i2c_write_one(struct qup_i2c_dev *qup, 
struct i2c_msg *msg)
} while (qup->pos < msg->len);
 
/* Wait for the outstanding data in the fifo to drain */
-   ret = qup_i2c_wait_writeready(qup);
+   ret = qup_i2c_wait_ready(qup, QUP_OUT_NOT_EMPTY, RESET_BIT, ONE_BYTE);
 
 err:
disable_irq(qup->irq);
@@ -384,18 +408,19 @@ static void qup_i2c_issue_read(struct qup_i2c_dev *qup, 
struct i2c_msg *msg)
 }
 
 
-static void qup_i2c_read_fifo(struct qup_i2c_dev *qup, struct i2c_msg *msg)
+static int qup_i2c_read_fifo(struct qup_i2c_dev *qup, struct i2c_msg *msg)
 {
-   u32 opflags;
 

[PATCH V5 0/6] i2c: qup: Add support for v2 tags and bam dma

2015-11-17 Thread Sricharan R
QUP from version 2.1.1 onwards, supports a new format of i2c command tags.
Tag codes instructs the controller to perform a operation like read/write.
This new tagging version supports and is required for adding bam dma
capabilities. V2 tags supports transfer of more than 256 bytes in a single i2c
transaction. Also adding bam dma support facilitates transferring each i2c_msg
in i2c_msgs without a 'stop' bit in between which is required for some of
the clients.

Tested this series on apq8074 dragon board eeprom client on i2c bus1

[V5] Addressed few more comments from Ivan T. Ivanov.
 Squashed patch 2 and 3 as no point in having only few lines of
 common code between v1 and v2 tags for increased complexity.
 Couple of non functional review comments fixes in patch 3, 4.
 Added a change in patch 4 to have proper transfer completion in
 a corner case. patch 5, 6 unchanged.

[V4] Added a patch to factor out some common code.
 Removed support for freq > 400KHZ as per comments.
 Addressed comments from Ivan T. Ivanov to keep the code for
 V2 support in a separate path. 
 Changed the authorship of V2 tags support patch.

[V3] Added support to coalesce each i2c_msg in i2c_msgs for fifo and
 block mode in Patch 2. Also addressed further code comments.

 http://comments.gmane.org/gmane.linux.drivers.i2c/22497

[V2] Addressed comments from Ivan T. Ivanov, Andy Gross [v1] Initial Version

Sricharan R (6):
  i2c: qup: Change qup_wait_writeready function to use for all timeouts
  i2c: qup: Add V2 tags support
  i2c: qup: Transfer each i2c_msg in i2c_msgs without a stop bit
  i2c: qup: Add bam dma capabilities
  dts: msm8974: Add blsp2_bam dma node
  dts: msm8974: Add dma channels for blsp2_i2c1 node

 arch/arm/boot/dts/qcom-msm8974.dtsi |  14 +-
 drivers/i2c/busses/i2c-qup.c| 931 ++--
 2 files changed, 896 insertions(+), 49 deletions(-)

-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation

--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] pinctrl: fix qcom ssbi drivers for 64-bit compilation

2015-11-17 Thread Linus Walleij
On Mon, Nov 16, 2015 at 5:41 PM, Arnd Bergmann  wrote:

> When building pinctrl-ssbi-gpio and pinctrl-ssbi-mpp for ARM64, we get
> a compile warning about invalid types:
>
> drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c: In function 'pm8xxx_gpio_probe':
> drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c:675:17: warning: cast from pointer 
> to integer of different size [-Wpointer-to-int-cast]
> drivers/pinctrl/qcom/pinctrl-ssbi-mpp.c: In function 'pm8xxx_mpp_probe':
> drivers/pinctrl/qcom/pinctrl-ssbi-mpp.c:766:17: warning: cast from pointer to 
> integer of different size [-Wpointer-to-int-cast]
>
> This changes the code so we cast the pointer to 'unsigned long', which
> is the right thing to do here.
>
> Signed-off-by: Arnd Bergmann 

Patch applied for fixes with Björn's review tag.

Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH RFC 23/27] ARM64: psci: Support cluster idle states for OS-Initated

2015-11-17 Thread Lina Iyer
ARMv8 PSCI firmware may allow Linux to determine the state of the CPU
cluster and the cluster at coherency level to enter idle states when
there are no active CPUs. Since Linux has a better idea of the QoS and
the wakeup pattern of the CPUs, the cluster idle states may be better
determined by the OS instead of the firmware.

The last CPU entering idle in a cluster, holds the responsibility of
selecting the state of the cluster. Only one CPU in a cluster may
provide the cluster idle state to the firmware. Similarly, the last CPU
in the cluster of clusters may provide the state of the coherency
domain.

The CPU PM domain framework facilitates registration of CPU PM domains
and reference counting for the last man down and the first man up. But
the organzation of CPUs into clusters must be provided. The cpu-map
topology node provides the information. Call into the CPU PM framework
to parse the CPU topology node and setup the PM domains. The state id
for the cluster ids is available with the domain idle state.

The last CPU PSCI state id of the entire system would therefore be -
Coherency State ID + Cluster State ID + CPU idle state ID, that is
passed into the PSCI firmware when the CPU makes the PSCI enable-method.

Cc: Daniel Lezcano 
Cc: Lorenzo Pieralisi 
Cc: Mark Rutland 
Signed-off-by: Lina Iyer 
---
 arch/arm64/kernel/psci.c | 54 +---
 1 file changed, 51 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/kernel/psci.c b/arch/arm64/kernel/psci.c
index f67f35b..6618d33 100644
--- a/arch/arm64/kernel/psci.c
+++ b/arch/arm64/kernel/psci.c
@@ -15,10 +15,12 @@
 
 #define pr_fmt(fmt) "psci: " fmt
 
+#include 
 #include 
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -31,6 +33,44 @@
 #include 
 
 static DEFINE_PER_CPU_READ_MOSTLY(u32 *, psci_power_state);
+static DEFINE_PER_CPU(u32, cluster_state_id);
+
+static inline u32 psci_get_composite_state_id(u32 cpu_state)
+{
+   u32 val = cpu_state;
+
+   if (psci_has_ext_power_state())
+   val += this_cpu_read(cluster_state_id);
+
+   return val;
+}
+
+static inline void psci_reset_composite_state_id(void)
+{
+   this_cpu_write(cluster_state_id, 0);
+}
+
+static int psci_pd_power_on(struct generic_pm_domain *genpd)
+{
+   return 0;
+}
+
+static int psci_pd_power_off(struct generic_pm_domain *genpd)
+{
+   __this_cpu_add(cluster_state_id, genpd->states[genpd->state_idx].param);
+   return 0;
+}
+
+static const struct cpu_pd_ops psci_pd_ops = {
+   .power_on = psci_pd_power_on,
+   .power_off = psci_pd_power_off,
+};
+
+static int __init psci_setup_cpu_domains(void)
+{
+   return of_setup_cpu_domain_topology(_pd_ops);
+}
+subsys_initcall(psci_setup_cpu_domains);
 
 static int __maybe_unused cpu_psci_cpu_init_idle(unsigned int cpu)
 {
@@ -117,6 +157,8 @@ static int cpu_psci_cpu_boot(unsigned int cpu)
if (err)
pr_err("failed to boot CPU%d (%d)\n", cpu, err);
 
+   /* Reset CPU cluster states */
+   psci_reset_composite_state_id();
return err;
 }
 
@@ -181,15 +223,16 @@ static int cpu_psci_cpu_kill(unsigned int cpu)
 static int psci_suspend_finisher(unsigned long index)
 {
u32 *state = __this_cpu_read(psci_power_state);
+   u32 ext_state = psci_get_composite_state_id(state[index - 1]);
 
-   return psci_ops.cpu_suspend(state[index - 1],
-   virt_to_phys(cpu_resume));
+   return psci_ops.cpu_suspend(ext_state, virt_to_phys(cpu_resume));
 }
 
 static int __maybe_unused cpu_psci_cpu_suspend(unsigned long index)
 {
int ret;
u32 *state = __this_cpu_read(psci_power_state);
+   u32 ext_state = psci_get_composite_state_id(state[index - 1]);
/*
 * idle state index 0 corresponds to wfi, should never be called
 * from the cpu_suspend operations
@@ -198,10 +241,15 @@ static int __maybe_unused cpu_psci_cpu_suspend(unsigned 
long index)
return -EINVAL;
 
if (!psci_power_state_loses_context(state[index - 1]))
-   ret = psci_ops.cpu_suspend(state[index - 1], 0);
+   ret = psci_ops.cpu_suspend(ext_state, 0);
else
ret = cpu_suspend(index, psci_suspend_finisher);
 
+   /*
+* Clear the CPU's cluster states, we start afresh after coming
+* out of idle.
+*/
+   psci_reset_composite_state_id();
return ret;
 }
 
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH RFC 25/27] devicetree: bindings: Document qcom,msm-id and qcom,board-id

2015-11-17 Thread Lina Iyer
From: Kumar Gala 

The top level qcom,msm-id and qcom,board-id are utilized by bootloaders
on Qualcomm MSM platforms to determine which device tree should be
utilized and passed to the kernel.

Cc: 
Signed-off-by: Kumar Gala 
---
 Documentation/devicetree/bindings/arm/msm/ids.txt | 65 +++
 include/dt-bindings/arm/qcom-ids.h| 33 
 2 files changed, 98 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/msm/ids.txt
 create mode 100644 include/dt-bindings/arm/qcom-ids.h

diff --git a/Documentation/devicetree/bindings/arm/msm/ids.txt 
b/Documentation/devicetree/bindings/arm/msm/ids.txt
new file mode 100644
index 000..9ee8428
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/msm/ids.txt
@@ -0,0 +1,65 @@
+* MSM-ID
+
+The qcom,msm-id entry specifies the MSM chipset and hardware revision.  It can
+optionally be an array of these to indicate multiple hardware that use the same
+device tree.  It is expected that the bootloader will use this information at
+boot-up to decide which device tree to use when given multiple device trees,
+some of which may not be compatible with the actual hardware.  It is the
+bootloader's responsibility to pass the correct device tree to the kernel.
+
+PROPERTIES
+
+- qcom,msm-id:
+   Usage: required
+   Value type:  ( [,  ..])
+   Definition:
+   The "chipset_id" consists of three fields as below:
+
+   bits 0-15  = The unique MSM chipset id.
+   bits 16-31 = Reserved.  Should be 0
+
+   chipset_id is an exact match value
+
+   The "rev_id" is a chipset specific 32-bit id that represents
+   the version of the chipset.
+
+   The rev_id is a best match id.  The bootloader will look for
+   the closest possible patch.
+
+* BOARD-ID
+
+The qcom,board-id entry specifies the board type and revision information.  It
+can optionally be an array of these to indicate multiple boards that use the
+same device tree.  It is expected that the bootloader will use this information
+at boot-up to decide which device tree to use when given multiple device trees,
+some of which may not be compatible with the actual hardware.  It is the
+bootloader's responsibility to pass the correct device tree to the kernel.
+
+PROPERTIES
+
+- qcom,board-id:
+   Usage: required
+   Value type:  ( [,  
..])
+   Definition:
+   The "board_id" consists of three fields as below:
+
+   bits 31-24 = Unusued.
+   bits 23-16 = Platform Version Major
+   bits 15-8  = Platfrom Version Minor
+   bits 7-0   = Platform Type
+
+   Platform Type field is an exact match value.  The Platform
+   Major/Minor field is a best match.  The bootloader will look
+   for the closest possible match.
+
+   The "subtype_id" is unique to a Platform Type/Chipset ID.  For
+   a given Platform Type, there will typically only be a single
+   board and the subtype_id will be 0.  However in some cases board
+   variants may need to be distinquished by different subtype_id
+   values.
+
+   subtype_id is an exact match value.
+
+EXAMPLE:
+   qcom,board-id = <15 2>;
+   qcom,msm-id = <0x1007e 0>;
diff --git a/include/dt-bindings/arm/qcom-ids.h 
b/include/dt-bindings/arm/qcom-ids.h
new file mode 100644
index 000..a18f34e
--- /dev/null
+++ b/include/dt-bindings/arm/qcom-ids.h
@@ -0,0 +1,33 @@
+/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#ifndef __DT_BINDINGS_QCOM_IDS_H
+#define __DT_BINDINGS_QCOM_IDS_H
+
+/* qcom,msm-id */
+#define QCOM_ID_MSM8916206
+#define QCOM_ID_APQ8016247
+#define QCOM_ID_MSM8216248
+#define QCOM_ID_MSM8116249
+#define QCOM_ID_MSM8616250
+
+/* qcom,board-id */
+#define QCOM_BRD_ID(a, major, minor) \
+   (((major & 0xff) << 16) | ((minor & 0xff) << 8) | QCOM_BRD_ID_##a)
+
+#define QCOM_BRD_ID_MTP8
+#define QCOM_BRD_ID_DRAGONBRD  10
+#define QCOM_BRD_ID_SBC24
+
+#define QCOM_BRD_SUBTYPE_DEFAULT   0
+#define QCOM_BRD_SUBTYPE_MTP8916_SMB1360   1
+
+#endif
-- 
2.1.4

--
To unsubscribe from this list: send the line 

[PATCH RFC 27/27] ARM64: dts: Define CPU power domain for MSM8916

2015-11-17 Thread Lina Iyer
Define power domain and the power states for the domain as defined by
the PSCI firmware.

Signed-off-by: Lina Iyer 
---
 arch/arm64/boot/dts/qcom/msm8916.dtsi | 48 ++-
 1 file changed, 47 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi 
b/arch/arm64/boot/dts/qcom/msm8916.dtsi
index 5806438..3ea8126 100644
--- a/arch/arm64/boot/dts/qcom/msm8916.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi
@@ -47,12 +47,32 @@
#address-cells = <1>;
#size-cells = <0>;
 
+   cpu-map {
+   cluster0 {
+   cluster = <>;
+
+   core0 {
+   cpu = <>;
+   };
+   core1 {
+   cpu = <>;
+   };
+   core2 {
+   cpu = <>;
+   };
+   core3 {
+   cpu = <>;
+   };
+   };
+   };
+
CPU0: cpu@0 {
device_type = "cpu";
compatible = "arm,cortex-a53", "arm,armv8";
reg = <0x0>;
enable-method = "psci";
cpu-idle-states = <_SPC>;
+   power-domains = <>;
};
 
CPU1: cpu@1 {
@@ -61,6 +81,7 @@
reg = <0x1>;
enable-method = "psci";
cpu-idle-states = <_SPC>;
+   power-domains = <>;
};
 
CPU2: cpu@2 {
@@ -69,6 +90,7 @@
reg = <0x2>;
enable-method = "psci";
cpu-idle-states = <_SPC>;
+   power-domains = <>;
};
 
CPU3: cpu@3 {
@@ -77,6 +99,7 @@
reg = <0x3>;
enable-method = "psci";
cpu-idle-states = <_SPC>;
+   power-domains = <>;
};
 
idle-states {
@@ -89,8 +112,31 @@
min-residency-us = <2000>;
};
};
+
+   CLUSTER0: cluster@0 {
+   #power-domain-cells = <0>;
+   power-states = <_RET>, <_PWR_DWN>;
+   };
+
+   cluster-power-states {
+   CLUSTER_RET: power-state@1 {
+   compatible = "linux,domain-state";
+   state-param = <0x110>;
+   entry-latency-us = <500>;
+   exit-latency-us = <500>;
+   residency-us = <2000>;
+};
+
+   CLUSTER_PWR_DWN: power-state@2 {
+   compatible = "linux,domain-state";
+   state-param = <0x130>;
+   entry-latency-us = <2000>;
+   exit-latency-us = <2000>;
+   residency-us = <6000>;
+   };
+   };
};
-   
+
psci {
compatible = "arm,psci-1.0";
method = "smc";
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH RFC 24/27] arm64: dts: Add Qualcomm MSM8916, MTP8916, APQ8016, SBC8016 ids

2015-11-17 Thread Lina Iyer
From: Kumar Gala 

Add qcom,msm-id and qcom,board-id to allow bootloader to identify which
device tree to boot on the MTP8916 & SBC8016 boards.

Signed-off-by: Kumar Gala 
---
 arch/arm64/boot/dts/qcom/apq8016-sbc.dts | 2 ++
 arch/arm64/boot/dts/qcom/msm8916-mtp.dts | 3 +++
 arch/arm64/boot/dts/qcom/msm8916.dtsi| 6 ++
 3 files changed, 11 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dts 
b/arch/arm64/boot/dts/qcom/apq8016-sbc.dts
index 825f489..6fea25d 100644
--- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dts
+++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dts
@@ -13,9 +13,11 @@
 
 /dts-v1/;
 
+#include 
 #include "apq8016-sbc.dtsi"
 
 / {
model = "Qualcomm Technologies, Inc. APQ 8016 SBC";
compatible = "qcom,apq8016-sbc", "qcom,apq8016", "qcom,sbc";
+   qcom,board-id = ;
 };
diff --git a/arch/arm64/boot/dts/qcom/msm8916-mtp.dts 
b/arch/arm64/boot/dts/qcom/msm8916-mtp.dts
index fced77f..6c68b4e 100644
--- a/arch/arm64/boot/dts/qcom/msm8916-mtp.dts
+++ b/arch/arm64/boot/dts/qcom/msm8916-mtp.dts
@@ -13,10 +13,13 @@
 
 /dts-v1/;
 
+#include 
 #include "msm8916-mtp.dtsi"
 
 / {
model = "Qualcomm Technologies, Inc. MSM 8916 MTP";
compatible = "qcom,msm8916-mtp", "qcom,msm8916-mtp-smb1360",
"qcom,msm8916", "qcom,mtp";
+   qcom,board-id = ,
+   ;
 };
diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi 
b/arch/arm64/boot/dts/qcom/msm8916.dtsi
index 8d184ff..7be7c23 100644
--- a/arch/arm64/boot/dts/qcom/msm8916.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi
@@ -14,10 +14,16 @@
 #include 
 #include 
 #include 
+#include 
 
 / {
model = "Qualcomm Technologies, Inc. MSM8916";
compatible = "qcom,msm8916";
+   qcom,msm-id =   ,
+   ,
+   ,
+   ,
+   ;
 
interrupt-parent = <>;
 
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH RFC 26/27] ARM64: dts: Add PSCI cpuidle support for MSM8916

2015-11-17 Thread Lina Iyer
Add device bindings for CPUs to suspend using PSCI as the enable-method.

Signed-off-by: Lina Iyer 
---
 arch/arm64/boot/dts/qcom/msm8916.dtsi | 24 
 1 file changed, 24 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi 
b/arch/arm64/boot/dts/qcom/msm8916.dtsi
index 7be7c23..5806438 100644
--- a/arch/arm64/boot/dts/qcom/msm8916.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi
@@ -51,25 +51,49 @@
device_type = "cpu";
compatible = "arm,cortex-a53", "arm,armv8";
reg = <0x0>;
+   enable-method = "psci";
+   cpu-idle-states = <_SPC>;
};
 
CPU1: cpu@1 {
device_type = "cpu";
compatible = "arm,cortex-a53", "arm,armv8";
reg = <0x1>;
+   enable-method = "psci";
+   cpu-idle-states = <_SPC>;
};
 
CPU2: cpu@2 {
device_type = "cpu";
compatible = "arm,cortex-a53", "arm,armv8";
reg = <0x2>;
+   enable-method = "psci";
+   cpu-idle-states = <_SPC>;
};
 
CPU3: cpu@3 {
device_type = "cpu";
compatible = "arm,cortex-a53", "arm,armv8";
reg = <0x3>;
+   enable-method = "psci";
+   cpu-idle-states = <_SPC>;
};
+
+   idle-states {
+   CPU_SPC: spc {
+   compatible = "qcom,idle-state-spc",
+   "arm,idle-state";
+   arm,psci-suspend-param = <0x4002>;
+   entry-latency-us = <130>;
+   exit-latency-us = <150>;
+   min-residency-us = <2000>;
+   };
+   };
+   };
+   
+   psci {
+   compatible = "arm,psci-1.0";
+   method = "smc";
};
 
timer {
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH RFC 19/27] drivers: cpu-pd: Invoke CPU PM runtime on hotplug

2015-11-17 Thread Lina Iyer
When a CPU is hotplugged off invoke CPU runtime suspend to notify
runtime PM of the CPU being powered down and opportunistically power
down the domain as well. Do that independent of the architecture using
hotplug notifiers.

Signed-off-by: Lina Iyer 
---
 drivers/base/power/cpu-pd.c | 31 +--
 1 file changed, 29 insertions(+), 2 deletions(-)

diff --git a/drivers/base/power/cpu-pd.c b/drivers/base/power/cpu-pd.c
index a00abc1..e331ae6 100644
--- a/drivers/base/power/cpu-pd.c
+++ b/drivers/base/power/cpu-pd.c
@@ -237,6 +237,30 @@ static int of_pm_domain_attach_cpus(struct device_node *dn,
return 0;
 }
 
+static int cpu_hotplug(struct notifier_block *nb,
+   unsigned long action, void *data)
+{
+   struct device *dev = get_cpu_device(smp_processor_id());
+
+   /* Execute CPU runtime PM on that CPU */
+   switch (action) {
+   case CPU_DYING:
+   case CPU_DYING_FROZEN:
+   pm_runtime_put_sync_suspend(dev);
+   pm_runtime_disable(dev);
+   break;
+   case CPU_STARTING:
+   case CPU_STARTING_FROZEN:
+   pm_runtime_enable(dev);
+   pm_runtime_get_sync(dev);
+   break;
+   default:
+   break;
+   }
+
+   return NOTIFY_OK;
+}
+
 int of_register_cpu_pm_domain(struct device_node *dn,
struct cpu_pm_domain *pd)
 {
@@ -277,10 +301,13 @@ int of_register_cpu_pm_domain(struct device_node *dn,
 
/* Attach the CPUs to the CPU PM domain */
ret = of_pm_domain_attach_cpus(dn, pd);
-   if (ret)
+   if (ret) {
of_genpd_del_provider(dn);
+   return ret;
+   }
 
-   return ret;
+   hotcpu_notifier(cpu_hotplug, 0)
+   return 0;
 }
 
 /**
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH RFC 10/27] drivers: power: Introduce PM domains for CPUs/clusters

2015-11-17 Thread Lina Iyer
Define and add Generic PM domains (genpd) for CPU clusters. Many new
SoCs group CPUs as clusters. Clusters share common resources like power
rails, caches, VFP, Coresight etc. When all CPUs in the cluster are
idle, these shared resources may also be put in their idle state.

The idle time between the last CPU entering idle and a CPU resuming
execution is an opportunity for these shared resources to be powered
down. Generic PM domain provides a framework for defining such power
domains and attach devices to the domain. When the devices in the domain
are idle at runtime, the domain would also be suspended and resumed
before the first of the devices resume execution.

We define a generic PM domain for each cluster and attach CPU devices in
the cluster to that PM domain. The DT definitions for the SoC describe
this relationship. Genpd callbacks for power_on and power_off can then
be used to power up/down the shared resources for the domain.

Cc: Stephen Boyd 
Cc: Kevin Hilman 
Cc: Ulf Hansson 
Cc: Daniel Lezcano 
Cc: Lorenzo Pieralisi 
Signed-off-by: Kevin Hilman 
Signed-off-by: Lina Iyer 
---
 Documentation/arm/cpu-domains.txt |  52 +
 drivers/base/power/Makefile   |   1 +
 drivers/base/power/cpu-pd.c   | 231 ++
 include/linux/cpu-pd.h|  32 ++
 4 files changed, 316 insertions(+)
 create mode 100644 Documentation/arm/cpu-domains.txt
 create mode 100644 drivers/base/power/cpu-pd.c
 create mode 100644 include/linux/cpu-pd.h

diff --git a/Documentation/arm/cpu-domains.txt 
b/Documentation/arm/cpu-domains.txt
new file mode 100644
index 000..ef5f215
--- /dev/null
+++ b/Documentation/arm/cpu-domains.txt
@@ -0,0 +1,52 @@
+CPU Clusters and PM domain
+
+Newer CPUs are grouped in a SoC as clusters. A cluster in addition to the
+CPUs may have caches, GIC, VFP and architecture specific power controller to
+power the cluster. A cluster may also be nested in another cluster, the
+hierarchy of which is depicted in the device tree. CPUIdle frameworks enables
+the CPUs to determine the sleep time and enter low power state to save power
+during periods of idle. CPUs in a cluster may enter and exit idle state
+independently. During the time when all the CPUs are in idle state, the
+cluster can safely be in idle state as well. When the last of the CPUs is
+powered off as a result of idle, the cluster may also be powered down, but the
+domain must be powered on before the first of the CPUs in the cluster resumes
+execution.
+
+SoCs can power down the CPU and resume execution in a few uSecs and the domain
+that powers the CPU cluster also have comparable idle latencies. The CPU WFI
+signal in ARM CPUs is used as a hardware trigger for the cluster hardware to
+enter their idle state. The hardware can be programmed in advance to put the
+cluster in the desired idle state befitting the wakeup latency requested by
+the CPUs. When all the CPUs in a cluster have executed their WFI instruction,
+the state machine for the power controller may put the cluster components in
+their power down or idle state. Generally, the domains would power on with the
+hardware sensing the CPU's interrupts. The domains may however, need to be
+reconfigured by the CPU to remain active, until the last CPU is ready to enter
+idle again. To power down a cluster, it is generally required to power down
+all the CPUs. The caches would also need to be flushed. The hardware state of
+some of the components may need to be saved and restored when powered back on.
+SoC vendors may also have hardware specific configuration that must be done
+before the cluster can be powered off. When the cluster is powered off,
+notifications may be sent out to other SoC components to scale down or even
+power off their resources.
+
+Power management domains represent relationship of devices and their power
+controllers. They are represented in the DT as domain consumers and providers.
+A device may have a domain provider and a domain provider may support multiple
+domain consumers. Domains like clusters, may also be nested inside one
+another. A domain that has no active consumer, may be powered off and any
+resuming consumer would trigger the domain back to active. Parent domains may
+be powered off when the child domains are powered off. The CPU cluster can be
+fashioned as a PM domain. When the CPU devices are powered off, the PM domain
+may be powered off.
+
+The code in Generic PM domains handles the hierarchy of devices, domains and
+the reference counting of objects leading to last man down and first man up.
+The CPU domains core code defines PM domains for each CPU cluster and attaches
+the domains' CPU devices to as specified in the DT. Platform drivers may use
+the following API to register their CPU PM domains.
+
+of_init_cpu_pm_domain() -

[PATCH RFC 17/27] drivers: cpu-pd: Record CPUs that are part of the domain

2015-11-17 Thread Lina Iyer
In order to power down the heirarchy of the CPU domain, the domain needs
information about the CPUs in that domain hierarchy . A domain that has
sub-domains containing CPU devices, will need information about all the
CPUs in the sub-domains as well.

Introduce of_attach_cpu_pm_domain() to allow CPU domains to be attached
to its parent domain and the information on CPUs attached directly or
indirectly be bubbled up the hierarchy.

Signed-off-by: Lina Iyer 
---
 drivers/base/power/cpu-pd.c | 96 -
 include/linux/cpu-pd.h  |  3 ++
 2 files changed, 97 insertions(+), 2 deletions(-)

diff --git a/drivers/base/power/cpu-pd.c b/drivers/base/power/cpu-pd.c
index 9758b8d..617ce54 100644
--- a/drivers/base/power/cpu-pd.c
+++ b/drivers/base/power/cpu-pd.c
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -44,6 +45,27 @@ struct cpu_pm_domain *to_cpu_pd(struct generic_pm_domain *d)
return res;
 }
 
+/**
+ * get_cpus_in_domain() - Recursively parse CPUs in a domain.
+ */
+static void get_cpus_in_domain(struct generic_pm_domain *genpd,
+   struct cpumask *mask)
+{
+   struct gpd_link *link;
+   struct cpu_pm_domain *pd = to_cpu_pd(genpd);
+   struct generic_pm_domain *sd;
+
+   if (!cpumask_empty(pd->cpus) && mask != pd->cpus) {
+   cpumask_or(mask, pd->cpus, mask);
+   return;
+   }
+
+   list_for_each_entry(link, >master_links, master_node) {
+   sd = link->slave;
+   get_cpus_in_domain(sd, mask);
+   }
+}
+
 static int cpu_pd_power_off(struct generic_pm_domain *genpd)
 {
struct cpu_pm_domain *pd = to_cpu_pd(genpd);
@@ -81,7 +103,8 @@ static void run_cpu(void *unused)
pm_runtime_get_noresume(cpu_dev);
 }
 
-static int of_pm_domain_attach_cpus(struct device_node *dn)
+static int of_pm_domain_attach_cpus(struct device_node *dn,
+   struct cpu_pm_domain *pd)
 {
int cpuid, ret;
 
@@ -126,6 +149,7 @@ static int of_pm_domain_attach_cpus(struct device_node *dn)
} else {
pm_runtime_enable(cpu_dev);
dev_dbg(cpu_dev, "Attached CPU%d to domain\n", cpuid);
+   cpumask_set_cpu(cpuid, pd->cpus);
}
}
 
@@ -171,7 +195,7 @@ int of_register_cpu_pm_domain(struct device_node *dn,
pd->genpd->name);
 
/* Attach the CPUs to the CPU PM domain */
-   ret = of_pm_domain_attach_cpus(dn);
+   ret = of_pm_domain_attach_cpus(dn, pd);
if (ret)
of_genpd_del_provider(dn);
 
@@ -213,6 +237,13 @@ struct generic_pm_domain *of_init_cpu_pm_domain(struct 
device_node *dn,
return ERR_PTR(-ENOMEM);
}
 
+   if (!zalloc_cpumask_var(>cpus, GFP_KERNEL)) {
+   kfree(pd->genpd->name);
+   kfree(pd->genpd);
+   kfree(pd);
+   return ERR_PTR(-ENOMEM);
+   }
+
if (ops) {
pd->plat_ops.power_off = ops->power_off;
pd->plat_ops.power_on = ops->power_on;
@@ -222,6 +253,7 @@ struct generic_pm_domain *of_init_cpu_pm_domain(struct 
device_node *dn,
if (ret) {
kfree(pd->genpd->name);
kfree(pd->genpd);
+   kfree(pd->cpus);
kfree(pd);
return ERR_PTR(ret);
}
@@ -229,3 +261,63 @@ struct generic_pm_domain *of_init_cpu_pm_domain(struct 
device_node *dn,
return pd->genpd;
 }
 EXPORT_SYMBOL(of_init_cpu_pm_domain);
+
+/**
+ * of_attach_cpu_pm_domain() - Attach a CPU PM domain to its parent
+ * @dn: The device node of the CPU PM domain that needs to be attached
+ *
+ * The platform code can use this simplfied function to parse the domain
+ * provider of this device node and attach the genpd associated with @dn
+ * to it parents.
+ *
+ * Note: Both @dn and its domain provider must be initialized using
+ * of_init_cpu_pm_domain.
+ */
+int of_attach_cpu_pm_domain(struct device_node *dn)
+{
+   struct of_phandle_args args;
+   struct generic_pm_domain *genpd, *parent;
+   struct cpu_pm_domain *pd;
+   int ret;
+
+   args.np = dn;
+   args.args_count = 0;
+
+   genpd = of_genpd_get_from_provider();
+   if (IS_ERR(genpd))
+   return -EINVAL;
+
+   if (!to_cpu_pd(genpd)) {
+   pr_warn("%s: domain %s is not a CPU domain\n",
+   __func__, genpd->name);
+   return -EINVAL;
+   }
+
+   ret = of_parse_phandle_with_args(dn, "power-domains",
+   "#power-domain-cells", 0, );
+   if (ret < 0)
+   return ret;
+
+   parent = of_genpd_get_from_provider();
+   if (IS_ERR(parent))
+   return -EINVAL;
+
+   pd = to_cpu_pd(parent);
+   if (!pd) {
+   pr_warn("%s: domain (%s) parent (%s) is non-CPU 

[PATCH RFC 21/27] drivers: cpu-pd: Parse topology to setup CPU PM domains

2015-11-17 Thread Lina Iyer
Architectures that support CPU domain control in the firmware specify
the domain heirarchy as part of the topology nodes. Parse and initialize
domains from the topology node for such architectures.

Cc: Rob Herring 
Cc: Stephen Boyd 
Cc: Kevin Hilman 
Cc: Ulf Hansson 
Cc: Lorenzo Pieralisi 
Signed-off-by: Lina Iyer 
---
 drivers/base/power/cpu-pd.c | 76 +
 include/linux/cpu-pd.h  |  1 +
 2 files changed, 77 insertions(+)

diff --git a/drivers/base/power/cpu-pd.c b/drivers/base/power/cpu-pd.c
index e331ae6..2872c18 100644
--- a/drivers/base/power/cpu-pd.c
+++ b/drivers/base/power/cpu-pd.c
@@ -429,3 +429,79 @@ int of_attach_cpu_pm_domain(struct device_node *dn)
return 0;
 }
 EXPORT_SYMBOL(of_attach_cpu_pm_domain);
+
+static int of_parse_cpu_pd(struct device_node *cluster,
+   const struct cpu_pd_ops *ops)
+{
+   struct device_node *domain_node;
+   struct generic_pm_domain *genpd;
+   char name[10];
+   struct device_node *c;
+   int i, ret;
+
+   for (i = 0; ; i++) {
+   snprintf(name, sizeof(name), "cluster%d", i);
+   c = of_get_child_by_name(cluster, name);
+   if (!c)
+   break;
+
+   domain_node = of_parse_phandle(c, "cluster", 0);
+   if (!domain_node)
+   return -1;
+
+   /* Initialize CPU PM domain domain at this level */
+   genpd = of_init_cpu_pm_domain(domain_node, ops);
+   if (IS_ERR(genpd))
+   return -1;
+
+   /* Initialize and attach child domains */
+   ret = of_parse_cpu_pd(c, ops);
+
+   /*
+* Attach the domain to its parent after reading
+* the children, so the mask of CPUs in this domain
+* are setup correctly.
+*/
+   if (!ret)
+   of_attach_cpu_pm_domain(domain_node);
+
+   of_node_put(c);
+   if (ret != 0)
+   return ret;
+   }
+
+   return 0;
+}
+
+/**
+ * of_setup_cpu_domain_topology() - Setup the CPU domains from the CPU
+ * topology node in DT.
+ *
+ * @ops: The PM domain suspend/resume ops for all the domains in the topology
+ */
+int of_setup_cpu_domain_topology(const struct cpu_pd_ops *ops)
+{
+   struct device_node *cn, *map;
+   int ret = 0;
+
+   cn = of_find_node_by_path("/cpus");
+   if (!cn) {
+   pr_err("No CPU information found in DT\n");
+   return 0;
+   }
+
+   map = of_get_child_by_name(cn, "cpu-map");
+   if (!map)
+   goto out;
+
+   ret = of_parse_cpu_pd(map, ops);
+   if (ret != 0)
+   goto out_map;
+
+out_map:
+   of_node_put(map);
+out:
+   of_node_put(cn);
+   return ret;
+}
+EXPORT_SYMBOL(of_setup_cpu_domain_topology);
diff --git a/include/linux/cpu-pd.h b/include/linux/cpu-pd.h
index 489ee2f..e8290db 100644
--- a/include/linux/cpu-pd.h
+++ b/include/linux/cpu-pd.h
@@ -32,4 +32,5 @@ struct cpu_pm_domain {
 struct generic_pm_domain *of_init_cpu_pm_domain(struct device_node *dn,
const struct cpu_pd_ops *ops);
 int of_attach_cpu_pm_domain(struct device_node *dn);
+int of_setup_cpu_domain_topology(const struct cpu_pd_ops *ops);
 #endif /* __CPU_PD_H__ */
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH RFC 12/27] ARM: cpuidle: remove cpu parameter from the cpuidle_ops suspend hook

2015-11-17 Thread Lina Iyer
From: Lorenzo Pieralisi 

The suspend() hook in the cpuidle_ops struct is always called on
the cpu entering idle, which means that the cpu parameter passed
to the suspend hook always corresponds to the local cpu, making
it somewhat redundant.

This patch removes the logical cpu parameter from the ARM
cpuidle_ops.suspend hook and updates all the existing kernel
implementations to reflect this change.

Signed-off-by: Lorenzo Pieralisi 
Cc: Lina Iyer 
Cc: Russell King 
Cc: Daniel Lezcano 
---
 arch/arm/include/asm/cpuidle.h |  2 +-
 arch/arm/kernel/cpuidle.c  |  2 +-
 drivers/soc/qcom/spm.c | 10 +-
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/arch/arm/include/asm/cpuidle.h b/arch/arm/include/asm/cpuidle.h
index 0f84249..3848259 100644
--- a/arch/arm/include/asm/cpuidle.h
+++ b/arch/arm/include/asm/cpuidle.h
@@ -30,7 +30,7 @@ static inline int arm_cpuidle_simple_enter(struct 
cpuidle_device *dev,
 struct device_node;
 
 struct cpuidle_ops {
-   int (*suspend)(int cpu, unsigned long arg);
+   int (*suspend)(unsigned long arg);
int (*init)(struct device_node *, int cpu);
 };
 
diff --git a/arch/arm/kernel/cpuidle.c b/arch/arm/kernel/cpuidle.c
index 318da33..703926e 100644
--- a/arch/arm/kernel/cpuidle.c
+++ b/arch/arm/kernel/cpuidle.c
@@ -56,7 +56,7 @@ int arm_cpuidle_suspend(int index)
int cpu = smp_processor_id();
 
if (cpuidle_ops[cpu].suspend)
-   ret = cpuidle_ops[cpu].suspend(cpu, index);
+   ret = cpuidle_ops[cpu].suspend(index);
 
return ret;
 }
diff --git a/drivers/soc/qcom/spm.c b/drivers/soc/qcom/spm.c
index b04b05a..0ad66fa 100644
--- a/drivers/soc/qcom/spm.c
+++ b/drivers/soc/qcom/spm.c
@@ -116,7 +116,7 @@ static const struct spm_reg_data spm_reg_8064_cpu = {
 
 static DEFINE_PER_CPU(struct spm_driver_data *, cpu_spm_drv);
 
-typedef int (*idle_fn)(int);
+typedef int (*idle_fn)(void);
 static DEFINE_PER_CPU(idle_fn*, qcom_idle_ops);
 
 static inline void spm_register_write(struct spm_driver_data *drv,
@@ -179,10 +179,10 @@ static int qcom_pm_collapse(unsigned long int unused)
return -1;
 }
 
-static int qcom_cpu_spc(int cpu)
+static int qcom_cpu_spc(void)
 {
int ret;
-   struct spm_driver_data *drv = per_cpu(cpu_spm_drv, cpu);
+   struct spm_driver_data *drv = __this_cpu_read(cpu_spm_drv);
 
spm_set_low_power_mode(drv, PM_SLEEP_MODE_SPC);
ret = cpu_suspend(0, qcom_pm_collapse);
@@ -197,9 +197,9 @@ static int qcom_cpu_spc(int cpu)
return ret;
 }
 
-static int qcom_idle_enter(int cpu, unsigned long index)
+static int qcom_idle_enter(unsigned long index)
 {
-   return per_cpu(qcom_idle_ops, cpu)[index](cpu);
+   return __this_cpu_read(qcom_idle_ops)[index]();
 }
 
 static const struct of_device_id qcom_idle_state_match[] __initconst = {
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH RFC 14/27] tick: get next wakeup event for the CPU

2015-11-17 Thread Lina Iyer
CPUidle governors use the sleep time of the CPU to determine the idle
state of the CPU. However, to determine a common sleep time between CPUs
that enter idle at different times, the tick_nohz_get_sleep_length() API
is not very helpful.

Add API to read the next event for the CPU. The value can be evaluated
at any time to determine the remaining sleep time of the CPU.

Cc: Thomas Gleixner 
Signed-off-by: Lina Iyer 
---
 include/linux/tick.h | 10 ++
 kernel/time/tick-sched.c |  8 
 2 files changed, 18 insertions(+)

diff --git a/include/linux/tick.h b/include/linux/tick.h
index e312219..6db3e52 100644
--- a/include/linux/tick.h
+++ b/include/linux/tick.h
@@ -103,6 +103,7 @@ extern void tick_nohz_idle_enter(void);
 extern void tick_nohz_idle_exit(void);
 extern void tick_nohz_irq_exit(void);
 extern ktime_t tick_nohz_get_sleep_length(void);
+extern ktime_t tick_nohz_get_next_wakeup(void);
 extern u64 get_cpu_idle_time_us(int cpu, u64 *last_update_time);
 extern u64 get_cpu_iowait_time_us(int cpu, u64 *last_update_time);
 #else /* !CONFIG_NO_HZ_COMMON */
@@ -116,6 +117,15 @@ static inline ktime_t tick_nohz_get_sleep_length(void)
 
return len;
 }
+
+static inline ktime_t tick_nohz_get_next_wakeup(void)
+{
+   ktime_t len = { .tv64 = NSEC_PER_SEC/HZ };
+
+   /* Next wake up is the tick period, assume it starts now */
+   return ktime_add(len, ktime_get());
+}
+
 static inline u64 get_cpu_idle_time_us(int cpu, u64 *unused) { return -1; }
 static inline u64 get_cpu_iowait_time_us(int cpu, u64 *unused) { return -1; }
 #endif /* !CONFIG_NO_HZ_COMMON */
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index 7c7ec45..e130edd 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -870,6 +870,14 @@ ktime_t tick_nohz_get_sleep_length(void)
return ts->sleep_length;
 }
 
+ktime_t tick_nohz_get_next_wakeup(void)
+{
+   struct clock_event_device *dev =
+   __this_cpu_read(tick_cpu_device.evtdev);
+
+   return dev->next_event;
+}
+
 static void tick_nohz_account_idle_ticks(struct tick_sched *ts)
 {
 #ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH RFC 15/27] PM / Domains: Add next_wakeup to device's timing data

2015-11-17 Thread Lina Iyer
Allow devices that know when their next wakeup event is, to record save
it as part of timing data. A genpd governor may use this data to
determine if suspending the domain is going to affect the QoS of its
devices.

Signed-off-by: Lina Iyer 
---
 include/linux/pm_domain.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index f1329ea..9ac089d 100644
--- a/include/linux/pm_domain.h
+++ b/include/linux/pm_domain.h
@@ -16,6 +16,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /* Defines used for the flags field in the struct generic_pm_domain */
 #define GENPD_FLAG_PM_CLK  (1U << 0) /* PM domain uses PM clk */
@@ -104,6 +105,7 @@ struct gpd_timing_data {
s64 effective_constraint_ns;
bool constraint_changed;
bool cached_stop_ok;
+   ktime_t next_wakeup;
 };
 
 struct pm_domain_data {
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH RFC 16/27] ARM: cpuidle: Record the next wakeup event of the CPU

2015-11-17 Thread Lina Iyer
Reading the next wakeup of the CPU can only be realiably done only from
that CPU. In the idle enter path record the next wake up of the CPU. The
information is useful to determine the sleep time left for the CPU.

Signed-off-by: Lina Iyer 
---
 drivers/cpuidle/cpuidle-arm.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/cpuidle/cpuidle-arm.c b/drivers/cpuidle/cpuidle-arm.c
index 8e72a23..b3133ef 100644
--- a/drivers/cpuidle/cpuidle-arm.c
+++ b/drivers/cpuidle/cpuidle-arm.c
@@ -18,9 +18,11 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -49,7 +51,9 @@ static int arm_enter_idle_state(struct cpuidle_device *dev,
ret = cpu_pm_enter();
if (!ret) {
struct device *cpu_dev = get_cpu_device(dev->cpu);
+   struct generic_pm_domain_data *gpd = dev_gpd_data(cpu_dev);
 
+   gpd->td.next_wakeup = tick_nohz_get_next_wakeup();
RCU_NONIDLE(pm_runtime_put_sync_suspend(cpu_dev));
 
/*
@@ -60,6 +64,7 @@ static int arm_enter_idle_state(struct cpuidle_device *dev,
arm_cpuidle_suspend(idx);
 
RCU_NONIDLE(pm_runtime_get_sync(cpu_dev));
+   gpd->td.next_wakeup.tv64 = 0;
cpu_pm_exit();
}
 
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH RFC 18/27] drivers: cpu-pd: Add PM Domain governor for CPUs

2015-11-17 Thread Lina Iyer
A PM domain comprising of CPUs may be powered off when all the CPUs in
the domain are powered down. Powering down a CPU domain is generally a
expensive operation and therefore the power performance trade offs
should be considered. The time between the last CPU powering down and
the first CPU powering up in a domain, is the time available for the
domain to sleep. Ideally, the sleep time of the domain should fulfill
the residency requirement of the domains' idle state.

To do this effectively, read the time before the wakeup of the cluster's
CPUs and ensure that the domain's idle state sleep time guarantees the
QoS requirements of each of the CPU, the PM QoS CPU_DMA_LATENCY and the
state's residency.

Signed-off-by: Lina Iyer 
---
 drivers/base/power/cpu-pd.c | 83 -
 1 file changed, 82 insertions(+), 1 deletion(-)

diff --git a/drivers/base/power/cpu-pd.c b/drivers/base/power/cpu-pd.c
index 617ce54..a00abc1 100644
--- a/drivers/base/power/cpu-pd.c
+++ b/drivers/base/power/cpu-pd.c
@@ -21,6 +21,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define CPU_PD_NAME_MAX 36
 
@@ -66,6 +67,86 @@ static void get_cpus_in_domain(struct generic_pm_domain 
*genpd,
}
 }
 
+static bool cpu_pd_down_ok(struct dev_pm_domain *pd)
+{
+   struct generic_pm_domain *genpd = pd_to_genpd(pd);
+   struct cpu_pm_domain *cpu_pd = to_cpu_pd(genpd);
+   int qos = pm_qos_request(PM_QOS_CPU_DMA_LATENCY);
+   u64 sleep_ns = ~0;
+   ktime_t earliest;
+   int cpu;
+   int i;
+
+   /* Reset the last set genpd state, default to index 0 */
+   genpd->state_idx = 0;
+
+   /* We dont want to power down, if QoS is 0 */
+   if (!qos)
+   return false;
+
+   /*
+* Find the sleep time for the cluster.
+* The time between now and the first wake up of any CPU that
+* are in this domain hierarchy is the time available for the
+* domain to be idle.
+*/
+   earliest.tv64 = KTIME_MAX;
+   for_each_cpu_and(cpu, cpu_pd->cpus, cpu_online_mask) {
+   struct device *cpu_dev = get_cpu_device(cpu);
+   struct gpd_timing_data *td;
+
+   td = _gpd_data(cpu_dev)->td;
+
+   if (earliest.tv64 < td->next_wakeup.tv64)
+   earliest = td->next_wakeup;
+   }
+
+   sleep_ns = ktime_to_ns(ktime_sub(earliest, ktime_get()));
+   if (sleep_ns <= 0)
+   return false;
+
+   /*
+* Find the deepest sleep state that satisfies the residency
+* requirement and the QoS constraint
+*/
+   for (i = genpd->state_count - 1; i > 0; i--) {
+   u64 state_sleep_ns;
+
+   state_sleep_ns = genpd->states[i].power_off_latency_ns +
+   genpd->states[i].power_on_latency_ns +
+   genpd->states[i].residency_ns;
+
+   /*
+* If we cant sleep to save power in the state, move on
+* to the next lower idle state.
+*/
+   if (state_sleep_ns > sleep_ns)
+  continue;
+
+   /*
+* We also dont want to sleep more than we should to
+* gaurantee QoS.
+*/
+   if (state_sleep_ns < (qos * NSEC_PER_USEC))
+   break;
+   }
+
+   if (i >= 0)
+   genpd->state_idx = i;
+
+   return  (i >= 0) ? true : false;
+}
+
+static bool cpu_stop_ok(struct device *dev)
+{
+   return true;
+}
+
+struct dev_power_governor cpu_pd_gov = {
+   .power_down_ok = cpu_pd_down_ok,
+   .stop_ok = cpu_stop_ok,
+};
+
 static int cpu_pd_power_off(struct generic_pm_domain *genpd)
 {
struct cpu_pm_domain *pd = to_cpu_pd(genpd);
@@ -183,7 +264,7 @@ int of_register_cpu_pm_domain(struct device_node *dn,
 
/* Register the CPU genpd */
pr_debug("adding %s as CPU PM domain.\n", pd->genpd->name);
-   ret = of_pm_genpd_init(dn, pd->genpd, _qos_governor, false);
+   ret = of_pm_genpd_init(dn, pd->genpd, _pd_gov, false);
if (ret) {
pr_err("Unable to initialize domain %s\n", dn->full_name);
return ret;
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH RFC 20/27] Documentation: ARM: topology: 'cluster' property for cluster nodes

2015-11-17 Thread Lina Iyer
Add a place holder phandle for a cluster to define cluster specific
properties like PM domain definitions etc.

Cc: Rob Herring 
Cc: Lorenzo Pieralisi 
Signed-off-by: Lina Iyer 
---
 Documentation/devicetree/bindings/arm/topology.txt | 8 
 1 file changed, 8 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/topology.txt 
b/Documentation/devicetree/bindings/arm/topology.txt
index 1061faf..12b4082 100644
--- a/Documentation/devicetree/bindings/arm/topology.txt
+++ b/Documentation/devicetree/bindings/arm/topology.txt
@@ -109,6 +109,14 @@ Bindings for cluster/cpu/thread nodes are defined as 
follows:
The cluster node name must be "clusterN" as described in 2.1 above.
A cluster node can not be a leaf node.
 
+   Properties for a cluster node are -
+
+   -cluster
+   Usage: Optional
+   Value type: 
+   Definition: a phandle to a cluster node that corresponds to
+   this cluster.
+
A cluster node's child nodes must be:
 
- one or more cluster nodes; or
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH RFC 22/27] drivers: firmware: PSCI: Export psci_has_ext_power_state()

2015-11-17 Thread Lina Iyer
Export psci_has_ext_power_state() to allow PSCI layers to determine and
pass the correct state id in the format supported.

Cc: Lorenzo Pieralisi 
Cc: Mark Rutland 
Signed-off-by: Lina Iyer 
---
 drivers/firmware/psci.c | 2 +-
 include/linux/psci.h| 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/firmware/psci.c b/drivers/firmware/psci.c
index d24f35d..3fd42e4 100644
--- a/drivers/firmware/psci.c
+++ b/drivers/firmware/psci.c
@@ -83,7 +83,7 @@ static u32 psci_function_id[PSCI_FN_MAX];
 
 static u32 psci_cpu_suspend_feature;
 
-static inline bool psci_has_ext_power_state(void)
+bool psci_has_ext_power_state(void)
 {
return psci_cpu_suspend_feature &
PSCI_1_0_FEATURES_CPU_SUSPEND_PF_MASK;
diff --git a/include/linux/psci.h b/include/linux/psci.h
index 12c4865..b9afbe2 100644
--- a/include/linux/psci.h
+++ b/include/linux/psci.h
@@ -23,6 +23,7 @@
 bool psci_tos_resident_on(int cpu);
 bool psci_power_state_loses_context(u32 state);
 bool psci_power_state_is_valid(u32 state);
+bool psci_has_ext_power_state(void);
 
 struct psci_operations {
int (*cpu_suspend)(u32 state, unsigned long entry_point);
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH RFC 13/27] ARM: cpuidle: Add runtime PM support for CPU idle

2015-11-17 Thread Lina Iyer
Notify runtime PM when the CPU is going to be powered off in the idle
state. This allows for runtime PM suspend/resume of the CPU as well as
its PM domain.

Cc: Daniel Lezcano 
Cc: Lorenzo Pieralisi 
Signed-off-by: Lina Iyer 
---
 drivers/cpuidle/cpuidle-arm.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/cpuidle/cpuidle-arm.c b/drivers/cpuidle/cpuidle-arm.c
index 545069d..8e72a23 100644
--- a/drivers/cpuidle/cpuidle-arm.c
+++ b/drivers/cpuidle/cpuidle-arm.c
@@ -11,13 +11,16 @@
 
 #define pr_fmt(fmt) "CPUidle arm: " fmt
 
+#include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
+#include 
 #include 
+#include 
 
 #include 
 
@@ -45,6 +48,10 @@ static int arm_enter_idle_state(struct cpuidle_device *dev,
 
ret = cpu_pm_enter();
if (!ret) {
+   struct device *cpu_dev = get_cpu_device(dev->cpu);
+
+   RCU_NONIDLE(pm_runtime_put_sync_suspend(cpu_dev));
+
/*
 * Pass idle state index to cpu_suspend which in turn will
 * call the CPU ops suspend protocol with idle index as a
@@ -52,6 +59,7 @@ static int arm_enter_idle_state(struct cpuidle_device *dev,
 */
arm_cpuidle_suspend(idx);
 
+   RCU_NONIDLE(pm_runtime_get_sync(cpu_dev));
cpu_pm_exit();
}
 
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH RFC 11/27] drivers: cpu: Define CPU devices as IRQ safe

2015-11-17 Thread Lina Iyer
CPUs may be powered off from CPUIdle or hotplug and are called with
IRQ's disabled. Define CPU devices as IRQ safe, so they may be runtime
suspended/resumed.

Reviewed-by: Stephen Boyd 
Signed-off-by: Lina Iyer 
---
 drivers/base/cpu.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index 91bbb19..6633210 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -17,6 +17,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "base.h"
 
@@ -371,10 +372,11 @@ int register_cpu(struct cpu *cpu, int num)
if (cpu->hotpluggable)
cpu->dev.groups = hotplugable_cpu_attr_groups;
error = device_register(>dev);
-   if (!error)
+   if (!error) {
+   pm_runtime_irq_safe(>dev);
per_cpu(cpu_sys_devices, num) = >dev;
-   if (!error)
register_cpu_under_node(num, cpu_to_node(num));
+   }
 
return error;
 }
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] mfd: qcom-spmi-pmic: Don't access non-existing registers

2015-11-17 Thread Stephen Boyd
From: "Ivan T. Ivanov" 

Revision ID registers are available only on devices with
Slave IDs that are even, so don't make access to unavailable
registers.

Signed-off-by: Ivan T. Ivanov 
[sb...@codeaurora.org: Consider all slave ids that are even]
Signed-off-by: Stephen Boyd 
---
 drivers/mfd/qcom-spmi-pmic.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/mfd/qcom-spmi-pmic.c b/drivers/mfd/qcom-spmi-pmic.c
index af6ac1c4b45c..8653e8b9bb4f 100644
--- a/drivers/mfd/qcom-spmi-pmic.c
+++ b/drivers/mfd/qcom-spmi-pmic.c
@@ -127,7 +127,9 @@ static int pmic_spmi_probe(struct spmi_device *sdev)
if (IS_ERR(regmap))
return PTR_ERR(regmap);
 
-   pmic_spmi_show_revid(regmap, >dev);
+   /* Only the first slave id for a PMIC contains this information */
+   if (sdev->usid % 2 == 0)
+   pmic_spmi_show_revid(regmap, >dev);
 
return of_platform_populate(root, NULL, NULL, >dev);
 }
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2] spmi: pmic-arb: Support more than 128 peripherals

2015-11-17 Thread Stephen Boyd
Add support for more than 128 peripherals by taking a lazy
caching approach to the mapping tables. Instead of reading and
caching the tables at boot given some fixed size, read them and
cache them on an as needed basis. We still assume a max size of
512 peripherals, trading off some space for simplicity.

Based on a patch by Gilad Avidov  and
Sagar Dharia .

Cc: Gilad Avidov 
Cc: Sagar Dharia 
Signed-off-by: Stephen Boyd 
---

Changes from v1:
 * Return error from offset search if can't find a mapping

 drivers/spmi/spmi-pmic-arb.c | 153 +++
 1 file changed, 111 insertions(+), 42 deletions(-)

diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
index be822f7a9ce6..aca282d45421 100644
--- a/drivers/spmi/spmi-pmic-arb.c
+++ b/drivers/spmi/spmi-pmic-arb.c
@@ -10,6 +10,7 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  */
+#include 
 #include 
 #include 
 #include 
@@ -47,9 +48,9 @@
 #define SPMI_MAPPING_BIT_IS_1_FLAG(X)  (((X) >> 8) & 0x1)
 #define SPMI_MAPPING_BIT_IS_1_RESULT(X)(((X) >> 0) & 0xFF)
 
-#define SPMI_MAPPING_TABLE_LEN 255
 #define SPMI_MAPPING_TABLE_TREE_DEPTH  16  /* Maximum of 16-bits */
-#define PPID_TO_CHAN_TABLE_SZ  BIT(12) /* PPID is 12bit chan is 1byte*/
+#define PMIC_ARB_MAX_PPID  BIT(12) /* PPID is 12bit */
+#define PMIC_ARB_CHAN_VALIDBIT(15)
 
 /* Ownership Table */
 #define SPMI_OWNERSHIP_TABLE_REG(N)(0x0700 + (4 * (N)))
@@ -85,9 +86,7 @@ enum pmic_arb_cmd_op_code {
 };
 
 /* Maximum number of support PMIC peripherals */
-#define PMIC_ARB_MAX_PERIPHS   256
-#define PMIC_ARB_MAX_CHNL  128
-#define PMIC_ARB_PERIPH_ID_VALID   (1 << 15)
+#define PMIC_ARB_MAX_PERIPHS   512
 #define PMIC_ARB_TIMEOUT_US100
 #define PMIC_ARB_MAX_TRANS_BYTES   (8)
 
@@ -125,18 +124,22 @@ struct spmi_pmic_arb_dev {
void __iomem*wr_base;
void __iomem*intr;
void __iomem*cnfg;
+   void __iomem*core;
+   resource_size_t core_size;
raw_spinlock_t  lock;
u8  channel;
int irq;
u8  ee;
-   u8  min_apid;
-   u8  max_apid;
-   u32 mapping_table[SPMI_MAPPING_TABLE_LEN];
+   u16 min_apid;
+   u16 max_apid;
+   u32 *mapping_table;
+   DECLARE_BITMAP(mapping_table_valid, PMIC_ARB_MAX_PERIPHS);
struct irq_domain   *domain;
struct spmi_controller  *spmic;
-   u16 apid_to_ppid[256];
+   u16 *apid_to_ppid;
const struct pmic_arb_ver_ops *ver_ops;
-   u8  *ppid_to_chan;
+   u16 *ppid_to_chan;
+   u16 last_channel;
 };
 
 /**
@@ -158,7 +161,8 @@ struct spmi_pmic_arb_dev {
  */
 struct pmic_arb_ver_ops {
/* spmi commands (read_cmd, write_cmd, cmd) functionality */
-   u32 (*offset)(struct spmi_pmic_arb_dev *dev, u8 sid, u16 addr);
+   int (*offset)(struct spmi_pmic_arb_dev *dev, u8 sid, u16 addr,
+ u32 *offset);
u32 (*fmt_cmd)(u8 opc, u8 sid, u16 addr, u8 bc);
int (*non_data_cmd)(struct spmi_controller *ctrl, u8 opc, u8 sid);
/* Interrupts controller functionality (offset of PIC registers) */
@@ -212,7 +216,14 @@ static int pmic_arb_wait_for_done(struct spmi_controller 
*ctrl,
struct spmi_pmic_arb_dev *dev = spmi_controller_get_drvdata(ctrl);
u32 status = 0;
u32 timeout = PMIC_ARB_TIMEOUT_US;
-   u32 offset = dev->ver_ops->offset(dev, sid, addr) + PMIC_ARB_STATUS;
+   u32 offset;
+   int rc;
+
+   rc = dev->ver_ops->offset(dev, sid, addr, );
+   if (rc)
+   return rc;
+
+   offset += PMIC_ARB_STATUS;
 
while (timeout--) {
status = readl_relaxed(base + offset);
@@ -257,7 +268,11 @@ pmic_arb_non_data_cmd_v1(struct spmi_controller *ctrl, u8 
opc, u8 sid)
unsigned long flags;
u32 cmd;
int rc;
-   u32 offset = pmic_arb->ver_ops->offset(pmic_arb, sid, 0);
+   u32 offset;
+
+   rc = pmic_arb->ver_ops->offset(pmic_arb, sid, 0, );
+   if (rc)
+   return rc;
 
cmd = ((opc | 0x40) << 27) | ((sid & 0xf) << 20);
 
@@ -297,7 +312,11 @@ static int pmic_arb_read_cmd(struct spmi_controller *ctrl, 
u8 opc, u8 sid,
u8 bc = len - 1;
u32 cmd;
int rc;
-   u32 offset = pmic_arb->ver_ops->offset(pmic_arb, sid, addr);
+   u32 offset;
+
+   rc = pmic_arb->ver_ops->offset(pmic_arb, sid, addr, );
+ 

[PATCH] pinctrl: qcom: Add msm8996 pinctrl driver

2015-11-17 Thread Stephen Boyd
From: Joonwoo Park 

Add initial pinctrl driver to support pin configuration with
pinctrl framework for msm8996.

Cc: 
Cc: Bjorn Andersson 
Signed-off-by: Joonwoo Park 
[sb...@codeaurora.org: Remove duplicate entries and enums]
Signed-off-by: Stephen Boyd 
---
 .../bindings/pinctrl/qcom,msm8996-pinctrl.txt  |  199 ++
 drivers/pinctrl/qcom/Kconfig   |8 +
 drivers/pinctrl/qcom/Makefile  |1 +
 drivers/pinctrl/qcom/pinctrl-msm8996.c | 1942 
 4 files changed, 2150 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/pinctrl/qcom,msm8996-pinctrl.txt
 create mode 100644 drivers/pinctrl/qcom/pinctrl-msm8996.c

diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,msm8996-pinctrl.txt 
b/Documentation/devicetree/bindings/pinctrl/qcom,msm8996-pinctrl.txt
new file mode 100644
index ..e312a71b2f94
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/qcom,msm8996-pinctrl.txt
@@ -0,0 +1,199 @@
+Qualcomm MSM8996 TLMM block
+
+This binding describes the Top Level Mode Multiplexer block found in the
+MSM8996 platform.
+
+- compatible:
+   Usage: required
+   Value type: 
+   Definition: must be "qcom,msm8996-pinctrl"
+
+- reg:
+   Usage: required
+   Value type: 
+   Definition: the base address and size of the TLMM register space.
+
+- interrupts:
+   Usage: required
+   Value type: 
+   Definition: should specify the TLMM summary IRQ.
+
+- interrupt-controller:
+   Usage: required
+   Value type: 
+   Definition: identifies this node as an interrupt controller
+
+- #interrupt-cells:
+   Usage: required
+   Value type: 
+   Definition: must be 2. Specifying the pin number and flags, as defined
+   in 
+
+- gpio-controller:
+   Usage: required
+   Value type: 
+   Definition: identifies this node as a gpio controller
+
+- #gpio-cells:
+   Usage: required
+   Value type: 
+   Definition: must be 2. Specifying the pin number and flags, as defined
+   in 
+
+Please refer to ../gpio/gpio.txt and ../interrupt-controller/interrupts.txt for
+a general description of GPIO and interrupt bindings.
+
+Please refer to pinctrl-bindings.txt in this directory for details of the
+common pinctrl bindings used by client devices, including the meaning of the
+phrase "pin configuration node".
+
+The pin configuration nodes act as a container for an arbitrary number of
+subnodes. Each of these subnodes represents some desired configuration for a
+pin, a group, or a list of pins or groups. This configuration can include the
+mux function to select on those pin(s)/group(s), and various pin configuration
+parameters, such as pull-up, drive strength, etc.
+
+
+PIN CONFIGURATION NODES:
+
+The name of each subnode is not important; all subnodes should be enumerated
+and processed purely based on their content.
+
+Each subnode only affects those parameters that are explicitly listed. In
+other words, a subnode that lists a mux function but no pin configuration
+parameters implies no information about any pin configuration parameters.
+Similarly, a pin subnode that describes a pullup parameter implies no
+information about e.g. the mux function.
+
+
+The following generic properties as defined in pinctrl-bindings.txt are valid
+to specify in a pin configuration subnode:
+
+- pins:
+   Usage: required
+   Value type: 
+   Definition: List of gpio pins affected by the properties specified in
+   this subnode.
+
+   Valid pins are:
+ gpio0-gpio149
+   Supports mux, bias and drive-strength
+
+ sdc1_clk, sdc1_cmd, sdc1_data sdc2_clk, sdc2_cmd,
+ sdc2_data sdc1_rclk
+   Supports bias and drive-strength
+
+- function:
+   Usage: required
+   Value type: 
+   Definition: Specify the alternative function to be configured for the
+   specified pins. Functions are only valid for gpio pins.
+   Valid values are:
+
+   blsp_uart1, blsp_spi1, blsp_i2c1, blsp_uim1, atest_tsens,
+   bimc_dte1, dac_calib0, blsp_spi8, blsp_uart8, blsp_uim8,
+   qdss_cti_trig_out_b, bimc_dte0, dac_calib1, 
qdss_cti_trig_in_b,
+   dac_calib2, atest_tsens2, atest_usb1, blsp_spi10, 
blsp_uart10,
+   blsp_uim10, atest_bbrx1, atest_usb13, atest_bbrx0, 
atest_usb12,
+   mdp_vsync, edp_lcd, blsp_i2c10, atest_gpsadc1, atest_usb11,
+   atest_gpsadc0, edp_hot, atest_usb10, m_voc, dac_gpio, 
atest_char,
+   cam_mclk, pll_bypassnl, qdss_stm7, blsp_i2c8, 
qdss_tracedata_b,
+   pll_reset, qdss_stm6, 

[PATCH 2/2] pinctrl: qcom: spmi-mpp: Add pm8994 mpp support

2015-11-17 Thread Stephen Boyd
Update the driver and binding for pm8994-mpp devices.

Cc: 
Cc: "Ivan T. Ivanov" 
Cc: Bjorn Andersson 
Signed-off-by: Stephen Boyd 
---
 Documentation/devicetree/bindings/pinctrl/qcom,pmic-mpp.txt | 1 +
 drivers/pinctrl/qcom/pinctrl-spmi-mpp.c | 1 +
 2 files changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-mpp.txt 
b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-mpp.txt
index d7803a2a94e9..d74e631e10da 100644
--- a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-mpp.txt
+++ b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-mpp.txt
@@ -15,6 +15,7 @@ of PMIC's from Qualcomm.
"qcom,pm8917-mpp",
"qcom,pm8921-mpp",
"qcom,pm8941-mpp",
+   "qcom,pm8994-mpp",
"qcom,pma8084-mpp",
 
 - reg:
diff --git a/drivers/pinctrl/qcom/pinctrl-spmi-mpp.c 
b/drivers/pinctrl/qcom/pinctrl-spmi-mpp.c
index 9ce0e30e33e8..7b4136a22c5b 100644
--- a/drivers/pinctrl/qcom/pinctrl-spmi-mpp.c
+++ b/drivers/pinctrl/qcom/pinctrl-spmi-mpp.c
@@ -907,6 +907,7 @@ static const struct of_device_id pmic_mpp_of_match[] = {
{ .compatible = "qcom,pm8841-mpp" },/* 4 MPP's */
{ .compatible = "qcom,pm8916-mpp" },/* 4 MPP's */
{ .compatible = "qcom,pm8941-mpp" },/* 8 MPP's */
+   { .compatible = "qcom,pm8994-mpp" },/* 8 MPP's */
{ .compatible = "qcom,pma8084-mpp" },   /* 8 MPP's */
{ },
 };
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 0/2] Add pm8994 gpio and mpp support

2015-11-17 Thread Stephen Boyd
This adds the support for pm8994 gpio and mpp modules. Given that there's
nothing besides a compatible string update, I'm going to send a separate
patch to add generic compatible strings for these sorts of things.

Stephen Boyd (2):
  pinctrl: qcom: spmi-gpio: Add pm8994 gpio support
  pinctrl: qcom: spmi-mpp: Add pm8994 mpp support

Cc: 
Cc: "Ivan T. Ivanov" 
Cc: Bjorn Andersson 

 Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt | 2 ++
 Documentation/devicetree/bindings/pinctrl/qcom,pmic-mpp.txt  | 1 +
 drivers/pinctrl/qcom/pinctrl-spmi-gpio.c | 1 +
 drivers/pinctrl/qcom/pinctrl-spmi-mpp.c  | 1 +
 4 files changed, 5 insertions(+)

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

--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/2] pinctrl: qcom: spmi-gpio: Add pm8994 gpio support

2015-11-17 Thread Stephen Boyd
Update the binding and driver for pm8994-gpio devices.

Cc: 
Cc: "Ivan T. Ivanov" 
Cc: Bjorn Andersson 
Signed-off-by: Stephen Boyd 
---
 Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt | 2 ++
 drivers/pinctrl/qcom/pinctrl-spmi-gpio.c | 1 +
 2 files changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt 
b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt
index 1ae63c0acd40..a90c812ad642 100644
--- a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt
+++ b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt
@@ -14,6 +14,7 @@ PMIC's from Qualcomm.
"qcom,pm8917-gpio"
"qcom,pm8921-gpio"
"qcom,pm8941-gpio"
+   "qcom,pm8994-gpio"
"qcom,pma8084-gpio"
 
 - reg:
@@ -79,6 +80,7 @@ to specify in a pin configuration subnode:
gpio1-gpio38 for pm8917
gpio1-gpio44 for pm8921
gpio1-gpio36 for pm8941
+   gpio1-gpio22 for pm8994
gpio1-gpio22 for pma8084
 
 - function:
diff --git a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c 
b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c
index 6c42ca14d2fd..df4413023e21 100644
--- a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c
+++ b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c
@@ -804,6 +804,7 @@ static int pmic_gpio_remove(struct platform_device *pdev)
 static const struct of_device_id pmic_gpio_of_match[] = {
{ .compatible = "qcom,pm8916-gpio" },   /* 4 GPIO's */
{ .compatible = "qcom,pm8941-gpio" },   /* 36 GPIO's */
+   { .compatible = "qcom,pm8994-gpio" },   /* 22 GPIO's */
{ .compatible = "qcom,pma8084-gpio" },  /* 22 GPIO's */
{ },
 };
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC/PATCH] pinctrl: qcom: Add generic ssbi and spmi GPIO/MPP bindings

2015-11-17 Thread Stephen Boyd
The drivers don't really need to know which PMIC they're for, so
make a generic binding for them. This alleviates us from updating
the drivers every time a new PMIC comes out. It's still
recommended that we update the binding with new PMIC models and
always specify the specific model for the MPPs and gpios before
the generic compatible string in devicetree, but this at least
cuts down on adding more and more compatible strings to the
drivers until we actually need them.

Cc: 
Cc: "Ivan T. Ivanov" 
Cc: Bjorn Andersson 
Signed-off-by: Stephen Boyd 
---

We can also figure out the number of the pins from the number
of interrupts, so we really don't need to even look at the size of the
reg property or model number for the spmi and ssbi modules. I'll propose
that change as well tomorrow.

 Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt | 5 -
 Documentation/devicetree/bindings/pinctrl/qcom,pmic-mpp.txt  | 5 -
 drivers/pinctrl/qcom/pinctrl-spmi-gpio.c | 1 +
 drivers/pinctrl/qcom/pinctrl-spmi-mpp.c  | 1 +
 4 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt 
b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt
index a90c812ad642..f1e4643f4132 100644
--- a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt
+++ b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt
@@ -17,6 +17,9 @@ PMIC's from Qualcomm.
"qcom,pm8994-gpio"
"qcom,pma8084-gpio"
 
+   And must contain either "qcom,spmi-gpio" or "qcom,ssbi-gpio"
+   if the device is on an spmi bus or an ssbi bus respectively
+
 - reg:
Usage: required
Value type: 
@@ -183,7 +186,7 @@ to specify in a pin configuration subnode:
 Example:
 
pm8921_gpio: gpio@150 {
-   compatible = "qcom,pm8921-gpio";
+   compatible = "qcom,pm8921-gpio", "qcom,ssbi-gpio";
reg = <0x150 0x160>;
interrupts = <192 1>, <193 1>, <194 1>,
 <195 1>, <196 1>, <197 1>,
diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-mpp.txt 
b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-mpp.txt
index d74e631e10da..e28320b18ecb 100644
--- a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-mpp.txt
+++ b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-mpp.txt
@@ -18,6 +18,9 @@ of PMIC's from Qualcomm.
"qcom,pm8994-mpp",
"qcom,pma8084-mpp",
 
+   And must contain either "qcom,spmi-mpp" or "qcom,ssbi-mpp"
+   if the device is on an spmi bus or an ssbi bus respectively.
+
 - reg:
Usage: required
Value type: 
@@ -157,7 +160,7 @@ to specify in a pin configuration subnode:
 Example:
 
mpps@a000 {
-   compatible = "qcom,pm8841-mpp";
+   compatible = "qcom,pm8841-mpp", "qcom,spmi-mpp";
reg = <0xa000>;
gpio-controller;
#gpio-cells = <2>;
diff --git a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c 
b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c
index df4413023e21..9f9979903fcb 100644
--- a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c
+++ b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c
@@ -806,6 +806,7 @@ static const struct of_device_id pmic_gpio_of_match[] = {
{ .compatible = "qcom,pm8941-gpio" },   /* 36 GPIO's */
{ .compatible = "qcom,pm8994-gpio" },   /* 22 GPIO's */
{ .compatible = "qcom,pma8084-gpio" },  /* 22 GPIO's */
+   { .compatible = "qcom,spmi-gpio" }, /* Generic */
{ },
 };
 
diff --git a/drivers/pinctrl/qcom/pinctrl-spmi-mpp.c 
b/drivers/pinctrl/qcom/pinctrl-spmi-mpp.c
index 7b4136a22c5b..5a4373dd9c61 100644
--- a/drivers/pinctrl/qcom/pinctrl-spmi-mpp.c
+++ b/drivers/pinctrl/qcom/pinctrl-spmi-mpp.c
@@ -909,6 +909,7 @@ static const struct of_device_id pmic_mpp_of_match[] = {
{ .compatible = "qcom,pm8941-mpp" },/* 8 MPP's */
{ .compatible = "qcom,pm8994-mpp" },/* 8 MPP's */
{ .compatible = "qcom,pma8084-mpp" },   /* 8 MPP's */
+   { .compatible = "qcom,spmi-mpp" },  /* Generic */
{ },
 };
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 4/5] clk: qcom: Add gfx3d ping-pong PLL frequency switching

2015-11-17 Thread Stephen Boyd
The GPU clocks on msm8996 have three dedicated PLLs, MMPLL2,
MMPLL8, and MMPLL9. We leave MMPLL9 at the maximum speed (624
MHz), and we use MMPLL2 and MMPLL8 for the other frequencies. To
make switching frequencies faster, we ping-pong between MMPLL2
and MMPLL8 when we're switching between frequencies that aren't
the maximum. Implement custom rcg clk ops for this type of
frequency switching.

Signed-off-by: Stephen Boyd 
---
 drivers/clk/qcom/clk-rcg.h  |  1 +
 drivers/clk/qcom/clk-rcg2.c | 87 +
 2 files changed, 88 insertions(+)

diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h
index 4b1e94bdf29e..b904c335cda4 100644
--- a/drivers/clk/qcom/clk-rcg.h
+++ b/drivers/clk/qcom/clk-rcg.h
@@ -178,5 +178,6 @@ extern const struct clk_ops clk_edp_pixel_ops;
 extern const struct clk_ops clk_byte_ops;
 extern const struct clk_ops clk_byte2_ops;
 extern const struct clk_ops clk_pixel_ops;
+extern const struct clk_ops clk_gfx3d_ops;
 
 #endif
diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c
index b544bb302f79..a071bba8018c 100644
--- a/drivers/clk/qcom/clk-rcg2.c
+++ b/drivers/clk/qcom/clk-rcg2.c
@@ -723,3 +723,90 @@ const struct clk_ops clk_pixel_ops = {
.determine_rate = clk_pixel_determine_rate,
 };
 EXPORT_SYMBOL_GPL(clk_pixel_ops);
+
+static int clk_gfx3d_determine_rate(struct clk_hw *hw,
+   struct clk_rate_request *req)
+{
+   struct clk_rate_request parent_req = { };
+   struct clk_hw *p2, *p8, *p9, *xo;
+   unsigned long p9_rate;
+   int ret;
+
+   xo = clk_hw_get_parent_by_index(hw, 0);
+   if (req->rate == clk_hw_get_rate(xo)) {
+   req->best_parent_hw = xo;
+   return 0;
+   }
+
+   p9 = clk_hw_get_parent_by_index(hw, 2);
+   p2 = clk_hw_get_parent_by_index(hw, 3);
+   p8 = clk_hw_get_parent_by_index(hw, 4);
+
+   /* PLL9 is a fixed rate PLL */
+   p9_rate = clk_hw_get_rate(p9);
+
+   parent_req.rate = req->rate = min(req->rate, p9_rate);
+   if (req->rate == p9_rate) {
+   req->rate = req->best_parent_rate = p9_rate;
+   req->best_parent_hw = p9;
+   return 0;
+   }
+
+   if (req->best_parent_hw == p9) {
+   /* Are we going back to a previously used rate? */
+   if (clk_hw_get_rate(p8) == req->rate)
+   req->best_parent_hw = p8;
+   else
+   req->best_parent_hw = p2;
+   } else if (req->best_parent_hw == p8) {
+   req->best_parent_hw = p2;
+   } else {
+   req->best_parent_hw = p8;
+   }
+
+   ret = __clk_determine_rate(req->best_parent_hw, _req);
+   if (ret)
+   return ret;
+
+   req->rate = req->best_parent_rate = parent_req.rate;
+
+   return 0;
+}
+
+static int clk_gfx3d_set_rate_and_parent(struct clk_hw *hw, unsigned long rate,
+   unsigned long parent_rate, u8 index)
+{
+   struct clk_rcg2 *rcg = to_clk_rcg2(hw);
+   u32 cfg;
+   int ret;
+
+   /* Just mux it, we don't use the division or m/n hardware */
+   cfg = rcg->parent_map[index].cfg << CFG_SRC_SEL_SHIFT;
+   ret = regmap_write(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, cfg);
+   if (ret)
+   return ret;
+
+   return update_config(rcg);
+}
+
+static int clk_gfx3d_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+   /*
+* We should never get here; clk_gfx3d_determine_rate() should always
+* make us use a different parent than what we're currently using, so
+* clk_gfx3d_set_rate_and_parent() should always be called.
+*/
+   return 0;
+}
+
+const struct clk_ops clk_gfx3d_ops = {
+   .is_enabled = clk_rcg2_is_enabled,
+   .get_parent = clk_rcg2_get_parent,
+   .set_parent = clk_rcg2_set_parent,
+   .recalc_rate = clk_rcg2_recalc_rate,
+   .set_rate = clk_gfx3d_set_rate,
+   .set_rate_and_parent = clk_gfx3d_set_rate_and_parent,
+   .determine_rate = clk_gfx3d_determine_rate,
+};
+EXPORT_SYMBOL_GPL(clk_gfx3d_ops);
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/5] clk: divider: Cap table divider values to 'width' member

2015-11-17 Thread Stephen Boyd
When we use a clk divider with a divider table, we limit the
maximum divider value in divider_get_val() to the
div_mask(width), but when we calculate the divider in
divider_round_rate() we don't consider that the maximum divider
may be limited by the width. Pass the width along to
_get_table_maxdiv() so that we only return the maximum divider
that is valid. This is useful for clocks that want to share the
same divider table while limiting the available dividers to some
subset of the table depending on the width of the bitfield.

Cc: Rajendra Nayak 
Signed-off-by: Stephen Boyd 
---
 drivers/clk/clk-divider.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c
index 3ace102a2a0a..ded3ff4b91b9 100644
--- a/drivers/clk/clk-divider.c
+++ b/drivers/clk/clk-divider.c
@@ -32,13 +32,14 @@
 
 #define div_mask(width)((1 << (width)) - 1)
 
-static unsigned int _get_table_maxdiv(const struct clk_div_table *table)
+static unsigned int _get_table_maxdiv(const struct clk_div_table *table,
+ u8 width)
 {
-   unsigned int maxdiv = 0;
+   unsigned int maxdiv = 0, mask = div_mask(width);
const struct clk_div_table *clkt;
 
for (clkt = table; clkt->div; clkt++)
-   if (clkt->div > maxdiv)
+   if (clkt->div > maxdiv && clkt->val <= mask)
maxdiv = clkt->div;
return maxdiv;
 }
@@ -62,7 +63,7 @@ static unsigned int _get_maxdiv(const struct clk_div_table 
*table, u8 width,
if (flags & CLK_DIVIDER_POWER_OF_TWO)
return 1 << div_mask(width);
if (table)
-   return _get_table_maxdiv(table);
+   return _get_table_maxdiv(table, width);
return div_mask(width) + 1;
 }
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/5] clk: qcom: Add Alpha PLL support

2015-11-17 Thread Stephen Boyd
Add support for configuring rates of, enabling, and disabling
Alpha PLLs. This is sufficient for the types of PLLs found in
the global and multimedia clock controllers.

Signed-off-by: Stephen Boyd 
---
 drivers/clk/qcom/Makefile|   1 +
 drivers/clk/qcom/clk-alpha-pll.c | 355 +++
 drivers/clk/qcom/clk-alpha-pll.h |  57 +++
 3 files changed, 413 insertions(+)
 create mode 100644 drivers/clk/qcom/clk-alpha-pll.c
 create mode 100644 drivers/clk/qcom/clk-alpha-pll.h

diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index fe6252349e55..472200040788 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -2,6 +2,7 @@ obj-$(CONFIG_COMMON_CLK_QCOM) += clk-qcom.o
 
 clk-qcom-y += common.o
 clk-qcom-y += clk-regmap.o
+clk-qcom-y += clk-alpha-pll.o
 clk-qcom-y += clk-pll.o
 clk-qcom-y += clk-rcg.o
 clk-qcom-y += clk-rcg2.o
diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c
new file mode 100644
index ..e6a03eaf7a93
--- /dev/null
+++ b/drivers/clk/qcom/clk-alpha-pll.c
@@ -0,0 +1,355 @@
+/*
+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "clk-alpha-pll.h"
+
+#define PLL_MODE   0x00
+# define PLL_OUTCTRL   BIT(0)
+# define PLL_BYPASSNL  BIT(1)
+# define PLL_RESET_N   BIT(2)
+# define PLL_LOCK_COUNT_SHIFT  8
+# define PLL_LOCK_COUNT_MASK   0x3f
+# define PLL_BIAS_COUNT_SHIFT  14
+# define PLL_BIAS_COUNT_MASK   0x3f
+# define PLL_VOTE_FSM_ENA  BIT(20)
+# define PLL_VOTE_FSM_RESETBIT(21)
+# define PLL_ACTIVE_FLAG   BIT(30)
+# define PLL_LOCK_DET  BIT(31)
+
+#define PLL_L_VAL  0x04
+#define PLL_ALPHA_VAL  0x08
+#define PLL_ALPHA_VAL_U0x0c
+
+#define PLL_USER_CTL   0x10
+# define PLL_POST_DIV_SHIFT8
+# define PLL_POST_DIV_MASK 0xf
+# define PLL_ALPHA_EN  BIT(24)
+# define PLL_VCO_SHIFT 20
+# define PLL_VCO_MASK  0x3
+
+#define PLL_USER_CTL_U 0x14
+
+#define PLL_CONFIG_CTL 0x18
+#define PLL_TEST_CTL   0x1c
+#define PLL_TEST_CTL_U 0x20
+#define PLL_STATUS 0x24
+
+/*
+ * Even though 40 bits are present, use only 32 for ease of calculation.
+ */
+#define ALPHA_REG_BITWIDTH 40
+#define ALPHA_BITWIDTH 32
+
+#define to_clk_alpha_pll(_hw) container_of(to_clk_regmap(_hw), \
+  struct clk_alpha_pll, clkr)
+
+#define to_clk_alpha_pll_postdiv(_hw) container_of(to_clk_regmap(_hw), \
+  struct clk_alpha_pll_postdiv, clkr)
+
+static int wait_for_pll(struct clk_alpha_pll *pll)
+{
+   u32 val, mask, off;
+   int count;
+   int ret;
+   const char *name = clk_hw_get_name(>clkr.hw);
+
+   off = pll->offset;
+   ret = regmap_read(pll->clkr.regmap, off + PLL_MODE, );
+   if (ret)
+   return ret;
+
+   if (val & PLL_VOTE_FSM_ENA)
+   mask = PLL_ACTIVE_FLAG;
+   else
+   mask = PLL_LOCK_DET;
+
+   /* Wait for pll to enable. */
+   for (count = 100; count > 0; count--) {
+   ret = regmap_read(pll->clkr.regmap, off + PLL_MODE, );
+   if (ret)
+   return ret;
+   if ((val & mask) == mask)
+   return 0;
+
+   udelay(1);
+   }
+
+   WARN(1, "%s didn't enable after voting for it!\n", name);
+   return -ETIMEDOUT;
+}
+
+static int clk_alpha_pll_enable(struct clk_hw *hw)
+{
+   int ret;
+   struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
+   u32 val, mask, off;
+
+   off = pll->offset;
+
+   mask = PLL_OUTCTRL | PLL_RESET_N | PLL_BYPASSNL;
+   ret = regmap_read(pll->clkr.regmap, off + PLL_MODE, );
+   if (ret)
+   return ret;
+
+   /* If in FSM mode, just vote for it */
+   if (val & PLL_VOTE_FSM_ENA) {
+   ret = clk_enable_regmap(hw);
+   if (ret)
+   return ret;
+   return wait_for_pll(pll);
+   }
+
+   /* Skip if already enabled */
+   if ((val & mask) == mask)
+   return 0;
+
+   ret = regmap_update_bits(pll->clkr.regmap, off + PLL_MODE,
+PLL_BYPASSNL, PLL_BYPASSNL);
+   if (ret)
+   return ret;
+
+   /*
+* H/W requires a 5us 

[PATCH 4/4] arm64: dts: qcom: Add pm8994 gpios and MPPs

2015-11-17 Thread Stephen Boyd
Add the gpio and MPP devices to the pm8994 pmic dts.

Signed-off-by: Stephen Boyd 
---
 arch/arm64/boot/dts/qcom/pm8994.dtsi | 43 
 1 file changed, 43 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/pm8994.dtsi 
b/arch/arm64/boot/dts/qcom/pm8994.dtsi
index e61b376f0b7c..1732f1d32f4c 100644
--- a/arch/arm64/boot/dts/qcom/pm8994.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm8994.dtsi
@@ -8,6 +8,49 @@
reg = <0x0 SPMI_USID>;
#address-cells = <1>;
#size-cells = <0>;
+
+   pm8994_gpios: gpios@c000 {
+   compatible = "qcom,pm8994-gpio";
+   reg = <0xc000 0x1500>;
+   gpio-controller;
+   #gpio-cells = <2>;
+   interrupts = <0 0xc0 0 IRQ_TYPE_NONE>,
+<0 0xc1 0 IRQ_TYPE_NONE>,
+<0 0xc2 0 IRQ_TYPE_NONE>,
+<0 0xc3 0 IRQ_TYPE_NONE>,
+<0 0xc4 0 IRQ_TYPE_NONE>,
+<0 0xc5 0 IRQ_TYPE_NONE>,
+<0 0xc6 0 IRQ_TYPE_NONE>,
+<0 0xc7 0 IRQ_TYPE_NONE>,
+<0 0xc8 0 IRQ_TYPE_NONE>,
+<0 0xc9 0 IRQ_TYPE_NONE>,
+<0 0xca 0 IRQ_TYPE_NONE>,
+<0 0xcb 0 IRQ_TYPE_NONE>,
+<0 0xcc 0 IRQ_TYPE_NONE>,
+<0 0xcd 0 IRQ_TYPE_NONE>,
+<0 0xce 0 IRQ_TYPE_NONE>,
+<0 0xd0 0 IRQ_TYPE_NONE>,
+<0 0xd1 0 IRQ_TYPE_NONE>,
+<0 0xd2 0 IRQ_TYPE_NONE>,
+<0 0xd3 0 IRQ_TYPE_NONE>,
+<0 0xd4 0 IRQ_TYPE_NONE>,
+<0 0xd5 0 IRQ_TYPE_NONE>;
+   };
+
+   pm8994_mpps: mpps@a000 {
+   compatible = "qcom,pm8994-mpp";
+   reg = <0xa000 0x700>;
+   gpio-controller;
+   #gpio-cells = <2>;
+   interrupts = <0 0xa0 0 IRQ_TYPE_NONE>,
+<0 0xa1 0 IRQ_TYPE_NONE>,
+<0 0xa2 0 IRQ_TYPE_NONE>,
+<0 0xa3 0 IRQ_TYPE_NONE>,
+<0 0xa4 0 IRQ_TYPE_NONE>,
+<0 0xa5 0 IRQ_TYPE_NONE>,
+<0 0xa6 0 IRQ_TYPE_NONE>,
+<0 0xa7 0 IRQ_TYPE_NONE>;
+   };
};
 
pmic@1 {
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 5/5] clk: qcom: Add MSM8996 Multimedia Clock Controller (MMCC) driver

2015-11-17 Thread Stephen Boyd
Add a driver for the multimedia clock controller found on MSM8996
based devices. This should allow most multimedia device drivers
to probe and control their clocks.

Signed-off-by: Stephen Boyd 
---
 .../devicetree/bindings/clock/qcom,mmcc.txt|1 +
 drivers/clk/qcom/Kconfig   |9 +
 drivers/clk/qcom/Makefile  |1 +
 drivers/clk/qcom/mmcc-msm8996.c| 3209 
 include/dt-bindings/clock/qcom,mmcc-msm8996.h  |  285 ++
 5 files changed, 3505 insertions(+)
 create mode 100644 drivers/clk/qcom/mmcc-msm8996.c
 create mode 100644 include/dt-bindings/clock/qcom,mmcc-msm8996.h

diff --git a/Documentation/devicetree/bindings/clock/qcom,mmcc.txt 
b/Documentation/devicetree/bindings/clock/qcom,mmcc.txt
index 34e7614d5074..8b0f7841af8d 100644
--- a/Documentation/devicetree/bindings/clock/qcom,mmcc.txt
+++ b/Documentation/devicetree/bindings/clock/qcom,mmcc.txt
@@ -9,6 +9,7 @@ Required properties :
"qcom,mmcc-msm8660"
"qcom,mmcc-msm8960"
"qcom,mmcc-msm8974"
+   "qcom,mmcc-msm8996"
 
 - reg : shall contain base register location and length
 - #clock-cells : shall contain 1
diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index fb2b499c647d..b552eceec2be 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -114,3 +114,12 @@ config MSM_GCC_8996
  Support for the global clock controller on msm8996 devices.
  Say Y if you want to use peripheral devices such as UART, SPI,
  i2c, USB, UFS, SD/eMMC, PCIe, etc.
+
+config MSM_MMCC_8996
+   tristate "MSM8996 Multimedia Clock Controller"
+   select MSM_GCC_8996
+   depends on COMMON_CLK_QCOM
+   help
+ Support for the multimedia clock controller on msm8996 devices.
+ Say Y if you want to support multimedia devices such as display,
+ graphics, video encode/decode, camera, etc.
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index 42dca6799414..dc4280b85db1 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -24,3 +24,4 @@ obj-$(CONFIG_MSM_GCC_8974) += gcc-msm8974.o
 obj-$(CONFIG_MSM_GCC_8996) += gcc-msm8996.o
 obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8960.o
 obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o
+obj-$(CONFIG_MSM_MMCC_8996) += mmcc-msm8996.o
diff --git a/drivers/clk/qcom/mmcc-msm8996.c b/drivers/clk/qcom/mmcc-msm8996.c
new file mode 100644
index ..b2329096cd7c
--- /dev/null
+++ b/drivers/clk/qcom/mmcc-msm8996.c
@@ -0,0 +1,3209 @@
+/*x
+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "common.h"
+#include "clk-regmap.h"
+#include "clk-regmap-divider.h"
+#include "clk-alpha-pll.h"
+#include "clk-rcg.h"
+#include "clk-branch.h"
+#include "reset.h"
+
+#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
+
+enum {
+   P_XO,
+   P_MMPLL0,
+   P_GPLL0,
+   P_GPLL0_DIV,
+   P_MMPLL1,
+   P_MMPLL9,
+   P_MMPLL2,
+   P_MMPLL8,
+   P_MMPLL3,
+   P_DSI0PLL,
+   P_DSI1PLL,
+   P_MMPLL5,
+   P_HDMIPLL,
+   P_DSI0PLL_BYTE,
+   P_DSI1PLL_BYTE,
+   P_MMPLL4,
+};
+
+static const struct parent_map mmss_xo_hdmi_map[] = {
+   { P_XO, 0 },
+   { P_HDMIPLL, 1 }
+};
+
+static const char * const mmss_xo_hdmi[] = {
+   "xo",
+   "hdmipll"
+};
+
+static const struct parent_map mmss_xo_dsi0pll_dsi1pll_map[] = {
+   { P_XO, 0 },
+   { P_DSI0PLL, 1 },
+   { P_DSI1PLL, 2 }
+};
+
+static const char * const mmss_xo_dsi0pll_dsi1pll[] = {
+   "xo",
+   "dsi0pll",
+   "dsi1pll"
+};
+
+static const struct parent_map mmss_xo_gpll0_gpll0_div_map[] = {
+   { P_XO, 0 },
+   { P_GPLL0, 5 },
+   { P_GPLL0_DIV, 6 }
+};
+
+static const char * const mmss_xo_gpll0_gpll0_div[] = {
+   "xo",
+   "gpll0",
+   "gpll0_div"
+};
+
+static const struct parent_map mmss_xo_dsibyte_map[] = {
+   { P_XO, 0 },
+   { P_DSI0PLL_BYTE, 1 },
+   { P_DSI1PLL_BYTE, 2 }
+};
+
+static const char * const mmss_xo_dsibyte[] = {
+   "xo",
+   "dsi0pllbyte",
+   "dsi1pllbyte"
+};
+
+static const struct parent_map mmss_xo_mmpll0_gpll0_gpll0_div_map[] = {
+   { P_XO, 0 },
+   { P_MMPLL0, 1 },
+   

[PATCH 0/5] Add support for MSM8996 clock controllers

2015-11-17 Thread Stephen Boyd
These patches add support for the global and multimedia clock controllers
found on MSM8996 devices. The first patch allows us to implement a
"power of two" divider of different widths with a table based divider.
The second patch adds support for Alpha PLLs and the 3rd and 5th patches
add support for the two clock controllers. The fourth patch is
a new type of clock ops for the graphics clock that does some custom
ping-pong between different PLLs when switching graphics frequencies.

Some work is still pending, mostly adding GDSCs and configuring the
multimedia PLLs for FSM voting mode vs. manually enabling and
disabling them. So a v2 is probably going to come out after
some more testing is done.

Cc: Rajendra Nayak 

Stephen Boyd (5):
  clk: divider: Cap table divider values to 'width' member
  clk: qcom: Add Alpha PLL support
  clk: qcom: Add MSM8996 Global Clock Control (GCC) driver
  clk: qcom: Add gfx3d ping-pong PLL frequency switching
  clk: qcom: Add MSM8996 Multimedia Clock Controller (MMCC) driver

 .../devicetree/bindings/clock/qcom,gcc.txt |1 +
 .../devicetree/bindings/clock/qcom,mmcc.txt|1 +
 drivers/clk/clk-divider.c  |9 +-
 drivers/clk/qcom/Kconfig   |   17 +
 drivers/clk/qcom/Makefile  |3 +
 drivers/clk/qcom/clk-alpha-pll.c   |  355 +++
 drivers/clk/qcom/clk-alpha-pll.h   |   57 +
 drivers/clk/qcom/clk-rcg.h |1 +
 drivers/clk/qcom/clk-rcg2.c|   87 +
 drivers/clk/qcom/gcc-msm8996.c | 3332 
 drivers/clk/qcom/mmcc-msm8996.c| 3209 +++
 include/dt-bindings/clock/qcom,gcc-msm8996.h   |  333 ++
 include/dt-bindings/clock/qcom,mmcc-msm8996.h  |  285 ++
 13 files changed, 7686 insertions(+), 4 deletions(-)
 create mode 100644 drivers/clk/qcom/clk-alpha-pll.c
 create mode 100644 drivers/clk/qcom/clk-alpha-pll.h
 create mode 100644 drivers/clk/qcom/gcc-msm8996.c
 create mode 100644 drivers/clk/qcom/mmcc-msm8996.c
 create mode 100644 include/dt-bindings/clock/qcom,gcc-msm8996.h
 create mode 100644 include/dt-bindings/clock/qcom,mmcc-msm8996.h

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

--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/4] arm64: dts: Add msm8996 SoC and MTP board support

2015-11-17 Thread Stephen Boyd
Add initial device tree support for the Qualcomm MSM8996 SoC and
MTP8996 evaluation board.

Signed-off-by: Stephen Boyd 
---
 arch/arm64/boot/dts/qcom/Makefile |   1 +
 arch/arm64/boot/dts/qcom/msm8996-mtp.dts  |  21 +++
 arch/arm64/boot/dts/qcom/msm8996-mtp.dtsi |  30 
 arch/arm64/boot/dts/qcom/msm8996.dtsi | 267 ++
 4 files changed, 319 insertions(+)
 create mode 100644 arch/arm64/boot/dts/qcom/msm8996-mtp.dts
 create mode 100644 arch/arm64/boot/dts/qcom/msm8996-mtp.dtsi
 create mode 100644 arch/arm64/boot/dts/qcom/msm8996.dtsi

diff --git a/arch/arm64/boot/dts/qcom/Makefile 
b/arch/arm64/boot/dts/qcom/Makefile
index 8e94af64ee94..fa1f661f 100644
--- a/arch/arm64/boot/dts/qcom/Makefile
+++ b/arch/arm64/boot/dts/qcom/Makefile
@@ -1,4 +1,5 @@
 dtb-$(CONFIG_ARCH_QCOM)+= apq8016-sbc.dtb msm8916-mtp.dtb
+dtb-$(CONFIG_ARCH_QCOM)+= msm8996-mtp.dtb
 
 always := $(dtb-y)
 subdir-y   := $(dts-dirs)
diff --git a/arch/arm64/boot/dts/qcom/msm8996-mtp.dts 
b/arch/arm64/boot/dts/qcom/msm8996-mtp.dts
new file mode 100644
index ..619af44a595d
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8996-mtp.dts
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+
+#include "msm8996-mtp.dtsi"
+
+/ {
+   model = "Qualcomm Technologies, Inc. MSM 8996 MTP";
+   compatible = "qcom,msm8996-mtp";
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8996-mtp.dtsi 
b/arch/arm64/boot/dts/qcom/msm8996-mtp.dtsi
new file mode 100644
index ..9bab5c011c07
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8996-mtp.dtsi
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include "msm8996.dtsi"
+
+/ {
+   aliases {
+   serial0 = _uart1;
+   };
+
+   chosen {
+   stdout-path = "serial0";
+   };
+
+   soc {
+   serial@75b {
+   status = "okay";
+   };
+   };
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi 
b/arch/arm64/boot/dts/qcom/msm8996.dtsi
new file mode 100644
index ..cf5d361283de
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi
@@ -0,0 +1,267 @@
+/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+
+/ {
+   model = "Qualcomm Technologies, Inc. MSM8996";
+
+   interrupt-parent = <>;
+
+   #address-cells = <2>;
+   #size-cells = <2>;
+
+   chosen { };
+
+   memory {
+   device_type = "memory";
+   /* We expect the bootloader to fill in the reg */
+   reg = <0 0 0 0>;
+   };
+
+   cpus {
+   #address-cells = <2>;
+   #size-cells = <0>;
+
+   CPU0: cpu@0 {
+   device_type = "cpu";
+   compatible = "qcom,kryo";
+   reg = <0x0 0x0>;
+   enable-method = "psci";
+   next-level-cache = <_0>;
+   L2_0: l2-cache {
+ compatible = "cache";
+ cache-level = <2>;
+   };
+   };
+
+   CPU1: cpu@1 {
+   device_type = "cpu";
+   compatible = "qcom,kryo";
+   reg = <0x0 0x1>;
+   enable-method = "psci";
+   next-level-cache = <_0>;
+   };
+
+  

[PATCH 1/4] devicetree: bindings: Document Kryo cpu

2015-11-17 Thread Stephen Boyd
Document the compatible string for the Kryo family of qcom cpus.

Cc: 
Signed-off-by: Stephen Boyd 
---
 Documentation/devicetree/bindings/arm/cpus.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/arm/cpus.txt 
b/Documentation/devicetree/bindings/arm/cpus.txt
index 3a07a87fef20..6008b99ccb2b 100644
--- a/Documentation/devicetree/bindings/arm/cpus.txt
+++ b/Documentation/devicetree/bindings/arm/cpus.txt
@@ -177,6 +177,7 @@ nodes to be present and contain the properties described 
below.
"marvell,sheeva-v5"
"nvidia,tegra132-denver"
"qcom,krait"
+   "qcom,kryo"
"qcom,scorpion"
- enable-method
Value type: 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/4] arm64: dts: qcom: Add pm8994, pmi8994, pm8004 PMIC skeletons

2015-11-17 Thread Stephen Boyd
Add the skeleton nodes for the PMICs found on msm8996-mtp
devices.

Signed-off-by: Stephen Boyd 
---
 arch/arm64/boot/dts/qcom/pm8004.dtsi  | 19 +++
 arch/arm64/boot/dts/qcom/pm8994.dtsi  | 19 +++
 arch/arm64/boot/dts/qcom/pmi8994.dtsi | 19 +++
 3 files changed, 57 insertions(+)
 create mode 100644 arch/arm64/boot/dts/qcom/pm8004.dtsi
 create mode 100644 arch/arm64/boot/dts/qcom/pm8994.dtsi
 create mode 100644 arch/arm64/boot/dts/qcom/pmi8994.dtsi

diff --git a/arch/arm64/boot/dts/qcom/pm8004.dtsi 
b/arch/arm64/boot/dts/qcom/pm8004.dtsi
new file mode 100644
index ..ef2207afa86b
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/pm8004.dtsi
@@ -0,0 +1,19 @@
+#include 
+#include 
+
+_bus {
+
+   pmic@4 {
+   compatible = "qcom,pm8004", "qcom,spmi-pmic";
+   reg = <0x4 SPMI_USID>;
+   #address-cells = <1>;
+   #size-cells = <0>;
+   };
+
+   pmic@5 {
+   compatible = "qcom,pm8004", "qcom,spmi-pmic";
+   reg = <0x5 SPMI_USID>;
+   #address-cells = <1>;
+   #size-cells = <0>;
+   };
+};
diff --git a/arch/arm64/boot/dts/qcom/pm8994.dtsi 
b/arch/arm64/boot/dts/qcom/pm8994.dtsi
new file mode 100644
index ..e61b376f0b7c
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/pm8994.dtsi
@@ -0,0 +1,19 @@
+#include 
+#include 
+
+_bus {
+
+   pmic@0 {
+   compatible = "qcom,pm8994", "qcom,spmi-pmic";
+   reg = <0x0 SPMI_USID>;
+   #address-cells = <1>;
+   #size-cells = <0>;
+   };
+
+   pmic@1 {
+   compatible = "qcom,pm8994", "qcom,spmi-pmic";
+   reg = <0x1 SPMI_USID>;
+   #address-cells = <1>;
+   #size-cells = <0>;
+   };
+};
diff --git a/arch/arm64/boot/dts/qcom/pmi8994.dtsi 
b/arch/arm64/boot/dts/qcom/pmi8994.dtsi
new file mode 100644
index ..d3879a4e8076
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/pmi8994.dtsi
@@ -0,0 +1,19 @@
+#include 
+#include 
+
+_bus {
+
+   pmic@2 {
+   compatible = "qcom,pmi8994", "qcom,spmi-pmic";
+   reg = <0x2 SPMI_USID>;
+   #address-cells = <1>;
+   #size-cells = <0>;
+   };
+
+   pmic@3 {
+   compatible = "qcom,pmi8994", "qcom,spmi-pmic";
+   reg = <0x3 SPMI_USID>;
+   #address-cells = <1>;
+   #size-cells = <0>;
+   };
+};
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 0/4] Add DTS for MSM8996 SoC and MTP

2015-11-17 Thread Stephen Boyd
These patches add the initial dts files for the MSM8996 SoC and
MTP evaluation board.

Stephen Boyd (4):
  devicetree: bindings: Document Kryo cpu
  arm64: dts: Add msm8996 SoC and MTP board support
  arm64: dts: qcom: Add pm8994, pmi8994, pm8004 PMIC skeletons
  arm64: dts: qcom: Add pm8994 gpios and MPPs

 Documentation/devicetree/bindings/arm/cpus.txt |   1 +
 arch/arm64/boot/dts/qcom/Makefile  |   1 +
 arch/arm64/boot/dts/qcom/msm8996-mtp.dts   |  21 ++
 arch/arm64/boot/dts/qcom/msm8996-mtp.dtsi  |  30 +++
 arch/arm64/boot/dts/qcom/msm8996.dtsi  | 267 +
 arch/arm64/boot/dts/qcom/pm8004.dtsi   |  19 ++
 arch/arm64/boot/dts/qcom/pm8994.dtsi   |  62 ++
 arch/arm64/boot/dts/qcom/pmi8994.dtsi  |  19 ++
 8 files changed, 420 insertions(+)
 create mode 100644 arch/arm64/boot/dts/qcom/msm8996-mtp.dts
 create mode 100644 arch/arm64/boot/dts/qcom/msm8996-mtp.dtsi
 create mode 100644 arch/arm64/boot/dts/qcom/msm8996.dtsi
 create mode 100644 arch/arm64/boot/dts/qcom/pm8004.dtsi
 create mode 100644 arch/arm64/boot/dts/qcom/pm8994.dtsi
 create mode 100644 arch/arm64/boot/dts/qcom/pmi8994.dtsi

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

--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2] mmc: sdhci-msm: Boost controller core clock

2015-11-17 Thread Stephen Boyd
On 11/16, Ulf Hansson wrote:
> [...]
> 
> 
> >
> > In case you're wondering, the max frequency for sdc1 on 8974ac is
> > 400MHz. If it's just a plain 8974pro then the max frequency is
> > 200MHz. Otherwise, sdc2 maxes out at 200Mhz and sdc3 and sdc4 max
> > out at 100MHz.
> 
> When you say that sdc1 supports 400MHz, what does that mean? That it
> actually can cope with that clock rate when communicating with the MMC
> card?

I suspect there must be some internal divider in the sdc IP
itself so that it doesn't put out 400MHz on the bus, but I really
don't know. What I mean is that the clock going into the IP from
the clock controller is running at 400MHz, after it goes into the
IP it could be divided, etc. before exiting the SoC on some pin.

> 
> This makes me wonder how you deal with power management (DVFS).
> 
> For example when you have the possibility to gate this clock (at
> request inactivity) when the rate is set to 400 MHz and OPP is
> increased, how will then that clock gating affect the OPP?

Sorry I'm not really following the question here. The gate will
disable the clock in the clock controller, cutting the signal off
upstream of the sdc IP. When we do DVFS we'll stop considering
this clock as part of the overall power level for the voltage
associated with the frequency. When all other clocks that are
using the same voltage and are on and running at frequencies that
don't need that high of voltage we can reduce the voltage and
drop down to something lower.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/4] arm64: dts: Add msm8996 SoC and MTP board support

2015-11-17 Thread kbuild test robot
Hi Stephen,

[auto build test ERROR on robh/for-next]
[also build test ERROR on v4.4-rc1 next-20151117]

url:
https://github.com/0day-ci/linux/commits/Stephen-Boyd/devicetree-bindings-Document-Kryo-cpu/20151118-091558
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux for-next
config: arm64-allmodconfig (attached as .config)
reproduce:
wget 
https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross
 -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=arm64 

All errors (new ones prefixed by >>):

   In file included from arch/arm64/boot/dts/qcom/msm8996-mtp.dtsi:14:0,
from arch/arm64/boot/dts/qcom/msm8996-mtp.dts:16:
>> arch/arm64/boot/dts/qcom/msm8996.dtsi:14:48: fatal error: 
>> dt-bindings/clock/qcom,gcc-msm8996.h: No such file or directory
#include 
   ^
   compilation terminated.

vim +14 arch/arm64/boot/dts/qcom/msm8996.dtsi

 8   * but WITHOUT ANY WARRANTY; without even the implied warranty of
 9   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10   * GNU General Public License for more details.
11   */
12  
13  #include 
  > 14  #include 
15  #include 
16  
17  / {

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation


.config.gz
Description: Binary data


Re: [PATCH 0/5] Add support for MSM8996 clock controllers

2015-11-17 Thread Rajendra Nayak

On 11/18/2015 06:37 AM, Stephen Boyd wrote:
> These patches add support for the global and multimedia clock controllers
> found on MSM8996 devices. The first patch allows us to implement a
> "power of two" divider of different widths with a table based divider.
> The second patch adds support for Alpha PLLs and the 3rd and 5th patches
> add support for the two clock controllers. The fourth patch is
> a new type of clock ops for the graphics clock that does some custom
> ping-pong between different PLLs when switching graphics frequencies.
> 
> Some work is still pending, mostly adding GDSCs and configuring the

I have the GDSC support patches done on top. Will post once I 
get some reasonable testing done.

> multimedia PLLs for FSM voting mode vs. manually enabling and
> disabling them. So a v2 is probably going to come out after
> some more testing is done.
> 
> Cc: Rajendra Nayak 
> 
> Stephen Boyd (5):
>   clk: divider: Cap table divider values to 'width' member
>   clk: qcom: Add Alpha PLL support
>   clk: qcom: Add MSM8996 Global Clock Control (GCC) driver
>   clk: qcom: Add gfx3d ping-pong PLL frequency switching
>   clk: qcom: Add MSM8996 Multimedia Clock Controller (MMCC) driver
> 
>  .../devicetree/bindings/clock/qcom,gcc.txt |1 +
>  .../devicetree/bindings/clock/qcom,mmcc.txt|1 +
>  drivers/clk/clk-divider.c  |9 +-
>  drivers/clk/qcom/Kconfig   |   17 +
>  drivers/clk/qcom/Makefile  |3 +
>  drivers/clk/qcom/clk-alpha-pll.c   |  355 +++
>  drivers/clk/qcom/clk-alpha-pll.h   |   57 +
>  drivers/clk/qcom/clk-rcg.h |1 +
>  drivers/clk/qcom/clk-rcg2.c|   87 +
>  drivers/clk/qcom/gcc-msm8996.c | 3332 
> 
>  drivers/clk/qcom/mmcc-msm8996.c| 3209 +++
>  include/dt-bindings/clock/qcom,gcc-msm8996.h   |  333 ++
>  include/dt-bindings/clock/qcom,mmcc-msm8996.h  |  285 ++
>  13 files changed, 7686 insertions(+), 4 deletions(-)
>  create mode 100644 drivers/clk/qcom/clk-alpha-pll.c
>  create mode 100644 drivers/clk/qcom/clk-alpha-pll.h
>  create mode 100644 drivers/clk/qcom/gcc-msm8996.c
>  create mode 100644 drivers/clk/qcom/mmcc-msm8996.c
>  create mode 100644 include/dt-bindings/clock/qcom,gcc-msm8996.h
>  create mode 100644 include/dt-bindings/clock/qcom,mmcc-msm8996.h
> 

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation
--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC/PATCH] pinctrl: qcom: Add generic ssbi and spmi GPIO/MPP bindings

2015-11-17 Thread Andy Gross
On Tue, Nov 17, 2015 at 05:00:26PM -0800, Stephen Boyd wrote:
> The drivers don't really need to know which PMIC they're for, so
> make a generic binding for them. This alleviates us from updating
> the drivers every time a new PMIC comes out. It's still
> recommended that we update the binding with new PMIC models and
> always specify the specific model for the MPPs and gpios before
> the generic compatible string in devicetree, but this at least
> cuts down on adding more and more compatible strings to the
> drivers until we actually need them.
> 
> Cc: 
> Cc: "Ivan T. Ivanov" 
> Cc: Bjorn Andersson 
> Signed-off-by: Stephen Boyd 

Reviewed-by: Andy Gross 

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

--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 0/4] Add DTS for MSM8996 SoC and MTP

2015-11-17 Thread Andy Gross
On Tue, Nov 17, 2015 at 05:12:25PM -0800, Stephen Boyd wrote:
> These patches add the initial dts files for the MSM8996 SoC and
> MTP evaluation board.
> 

These all look fine.

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

--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH RFC 00/27] PM/Domains: Cluster idle support for ARM SoCs

2015-11-17 Thread Lina Iyer
Hi all,

This series is an attempt at doing an end-to-end PSCI OS initiated solution for
SoC/Cluster idle for ARM v8 SoCs. The series is based on PM domains for CPUs
[1], which lays the foundation for IRQ safe domains and CPU domains that use
the IRQ safe property of a domain to power ON/OFF the domain when the CPUs are
in idle (either cpuidle or hotplug). This patchset is superset of [1] providing
a better picture of how the CPU domains are defined and used.  

The gist of this series is that the topology of CPU and the hierarchy is
provided in the DT for an SoC. A common library of functions help parse the DT
to initialize the generic PM domains and attach sub-domains and CPU devices to
those domains. On an ARM v8 SoC, the PSCI f/w controls the domains for low
power modes when the CPUs are in idle. CPUs call runtime PM suspend when
entering idle, which calls generic PM domains (genpd) that reference counts the
domain usage by devices/sub-domains in the domain. When the last CPU in the
domain powers down, genpd calls CPU PM domain core to power down the domain,
which in turn sets up PSCI core to pass the cluster idle states along with the
CPU idle state to the f/w.

PSCI v1.0 supports Platform coordinated and OS initiated modes. Platform
coordinated PSCI lets PSCI determine the state of the cluster based on votes
from individual CPUs. This simple solution may sometimes be inefficient, as the
PSCI f/w is unaware of the CPU and cluster sleep length and the QoS requirement
laid on the CPUs. OS initiated PSCI on the other hand lets Linux determine the
state of the cluster and the coherency domain and pass them as arguments to the
PSCI call when the last CPU enters idle. The complexity of determining the
state of the cluster and last-man reference counting rests with the kernel.

By defining CPU domains using genpd, both ARM v7 and v8 based architectures can
take advantage of the last man reference counting and cluster idle state
determination in genpd to save power - by opportunistically flushing CPU
caches, turning off supplementary hardware and powering off the CPU domain.
This patchset makes it easy for ARM v8 based PSCI f/w that supports OS
initiated do all that is needed from Linux by just specifying the CPU domain
hierarchy and idle states supported by the CPU domains in DT. ARM v7 SoCs that
control domains in Linux could still use this series in setting up CPU PM
domains for the CPUs, however, they would setup the hierarchy and supply the
domain power on/off callbacks.

This patchset builds upon genpd patches for multiple idle states from Axel [2]
and Marc [3] and Lorenzo to unify cpuidle signatures across ARM 32 and 64 [4].
I made a few amends to their patches to split the key parts relevant to this
efforts and rebase on top of 4.4-rc1. I have re-based this [7] on top of
v4.4-rc1 and tested using Kumar's patches, which has since then been replaced
with [5]. This series [7] has been tested on a QCOM APQ8016 Dragonboard with a
PSCI f/w that supports OS initiated mode.
 
Key topics for focus -
1. DT definition of cluster node in topology node.
2. DT definition of domain idle states - in comparison to arm,idle-state
3. Determining the next wake up of the CPU therefore the cluster from clock 
events.
4. Gen PD governor for CPU clusters.
5. Some parts are currently ARM specific (like the cpuidle parts), they could be
arch agnostic.
6. Optimizations to speed up the entire series.

Concerns -
Previous patches had raise concerns with latency added to the idle path. I have
not addressed them in this series. I focused on getting the full solution in
place at this time. A previous attempt at using runtime PM and genpd without
the use of locks is here [6]. I will re-focus my effort of making this suitable
for -RT kernel and optimizing the runtime paths and integrating them into a
future version.

Thanks,
Lina

[1]. https://lwn.net/Articles/656793/
[2]. https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1001509.html
[3]. https://lwn.net/Articles/658461/
[4]. http://www.spinics.net/lists/arm-kernel/msg451502.html
[5]. https://lkml.org/lkml/2015/10/26/651
[6]. https://patches.linaro.org/54565/
[7]. 
https://git.linaro.org/people/lina.iyer/linux-next.git/shortlog/refs/heads/genpd-psci-3

Axel Haslam (3):
  PM / Domains: core changes for multiple states
  PM / Domains: make governor select deepest state
  PM / Domains: remove old power on/off latencies.

Kumar Gala (2):
  arm64: dts: Add Qualcomm MSM8916, MTP8916, APQ8016, SBC8016 ids
  devicetree: bindings: Document qcom,msm-id and qcom,board-id

Lina Iyer (19):
  PM / Domain: Add additional state specific param
  PM / Domains: Read domain residency from DT
  PM / Domains: Support IRQ safe PM domains
  PM / Domains: Attempt runtime suspend of IRQ safe parent domain
  drivers: power: Introduce PM domains for CPUs/clusters
  drivers: cpu: Define CPU devices as IRQ safe
  ARM: cpuidle: Add runtime PM support for CPU idle
  tick: get next wakeup event for the 

[PATCH RFC 09/27] PM / Domains: Attempt runtime suspend of IRQ safe parent domain

2015-11-17 Thread Lina Iyer
When a sub-domain is powered off, attempt powering off the parent
domains to maximize power savings. A sub-domain that is IRQ safe may
however have a parent that is not IRQ safe and therefore cannot be
powered down in atomic context that the sub-domain may be powered off.

An IRQ safe sub-domain may attempt to power down the parent domain in a
synchronous call, if the parent is also IRQ safe.

Signed-off-by: Lina Iyer 
---
 drivers/base/power/domain.c | 16 
 1 file changed, 16 insertions(+)

diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index 8df43f8..0310e2b 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -44,6 +44,8 @@ static int pm_genpd_alloc_states_names(struct 
generic_pm_domain *genpd,
 static LIST_HEAD(gpd_list);
 static DEFINE_MUTEX(gpd_list_lock);
 
+static int genpd_poweroff(struct generic_pm_domain *genpd, bool is_async);
+
 static inline int genpd_lock_nosleep(struct generic_pm_domain *genpd,
unsigned int subclass)
__acquires(>slock)
@@ -298,6 +300,13 @@ static int __genpd_poweron(struct generic_pm_domain *genpd)
>slave_links,
slave_node) {
genpd_sd_counter_dec(link->master);
+
+   /* Assume masters that are non-irq safe are always-on */
+   if (genpd->irq_safe && link->master->irq_safe) {
+   genpd_poweroff(link->master, false);
+   continue;
+   }
+
genpd_queue_power_off_work(link->master);
}
 
@@ -448,6 +457,13 @@ static int genpd_poweroff(struct generic_pm_domain *genpd, 
bool is_async)
 
list_for_each_entry(link, >slave_links, slave_node) {
genpd_sd_counter_dec(link->master);
+
+   /* Assume masters that are non-irq safe are always-on */
+   if (genpd->irq_safe && link->master->irq_safe) {
+   genpd_poweroff(link->master, false);
+   continue;
+   }
+
genpd_queue_power_off_work(link->master);
}
 
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH RFC 08/27] PM / Domains: Support IRQ safe PM domains

2015-11-17 Thread Lina Iyer
Generic Power Domains currently support turning on/off only in process
context. This prevents the usage of PM domains for domains that could be
powered on/off in a context where IRQs are disabled. Many such domains
exist today and do not get powered off, when the IRQ safe devices in
that domain are powered off, because of this limitation.

However, not all domains can operate in IRQ safe contexts. Genpd
therefore, has to support both cases where the domain may or may not
operate in IRQ safe contexts. Configuring genpd to use an appropriate
lock for that domain, would allow domains that have IRQ safe devices to
runtime suspend and resume, in atomic context.

To achieve domain specific locking, set the domain's ->flag to
GENPD_FLAG_IRQ_SAFE while defining the domain. This indicates that genpd
should use a spinlock instead of a mutex for locking the domain. Locking
is abstracted through genpd_lock() and genpd_unlock() functions that use
the flag to determine the appropriate lock to be used for that domain.
Domains that have lower latency to suspend and resume and can operate
with IRQs disabled may now be able to save power, when the component
devices and sub-domains are idle at runtime.

The restriction this imposes on the domain hierarchy is that sub-domains
and all devices in the IRQ safe domain's hierarchy also have to be IRQ
safe, so that we dont try to lock a mutex, while holding a spinlock.
Non-IRQ safe domains may continue to have devices and sub-domains that
may or may not be IRQ safe.

Cc: Ulf Hansson 
Cc: Kevin Hilman 
Cc: Rafael J. Wysocki 
Cc: Geert Uytterhoeven 
Cc: Krzysztof Kozłowski 
Signed-off-by: Lina Iyer 
---
 Documentation/power/devices.txt |  11 ++-
 drivers/base/power/domain.c | 197 
 include/linux/pm_domain.h   |  12 ++-
 3 files changed, 178 insertions(+), 42 deletions(-)

diff --git a/Documentation/power/devices.txt b/Documentation/power/devices.txt
index 8ba6625..bde6141 100644
--- a/Documentation/power/devices.txt
+++ b/Documentation/power/devices.txt
@@ -607,7 +607,16 @@ individually.  Instead, a set of devices sharing a power 
resource can be put
 into a low-power state together at the same time by turning off the shared
 power resource.  Of course, they also need to be put into the full-power state
 together, by turning the shared power resource on.  A set of devices with this
-property is often referred to as a power domain.
+property is often referred to as a power domain. A power domain may also be
+nested inside another power domain.
+
+Devices, by default, operate in process context and if a device can operate in
+IRQ safe context, has to be explicitly set as IRQ safe. Power domains by
+default, operate in process context but could have devices that are IRQ safe.
+Such power domains cannot be powered on/off during runtime PM. On the other
+hand, an IRQ safe PM domain that can be powered on/off and suspended or resumed
+in an atomic context, may contain IRQ safe devices. Such domains may only
+contain IRQ safe devices or IRQ safe sub-domains.
 
 Support for power domains is provided through the pm_domain field of struct
 device.  This field is a pointer to an object of type struct dev_pm_domain,
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index abc81bd..8df43f8 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -44,6 +44,80 @@ static int pm_genpd_alloc_states_names(struct 
generic_pm_domain *genpd,
 static LIST_HEAD(gpd_list);
 static DEFINE_MUTEX(gpd_list_lock);
 
+static inline int genpd_lock_nosleep(struct generic_pm_domain *genpd,
+   unsigned int subclass)
+   __acquires(>slock)
+{
+   unsigned long flags;
+
+   if (subclass > 0)
+   spin_lock_irqsave_nested(>slock, flags, subclass);
+   else
+   spin_lock_irqsave(>slock, flags);
+
+   genpd->lock_flags = flags;
+   return 0;
+}
+
+static inline void genpd_unlock_nosleep(struct generic_pm_domain *genpd)
+   __releases(>slock)
+{
+   spin_unlock_irqrestore(>slock, genpd->lock_flags);
+}
+
+static inline int genpd_lock_irq(struct generic_pm_domain *genpd,
+   unsigned int subclass)
+   __acquires(>mlock)
+{
+   if (subclass > 0)
+   mutex_lock_nested(>mlock, subclass);
+   else
+   mutex_lock(>mlock);
+   return 0;
+}
+
+static inline int genpd_lock_interruptible_irq(struct generic_pm_domain *genpd)
+   __acquires(>mlock)
+{
+   return mutex_lock_interruptible(>mlock);
+}
+
+static inline void genpd_unlock_irq(struct generic_pm_domain *genpd)
+   __releases(>mlock)
+{
+   mutex_unlock(>mlock);
+}
+
+static inline int genpd_lock(struct generic_pm_domain *genpd)
+{
+   return genpd->irq_safe ? 

[PATCH RFC 02/27] PM / Domains: Allow domain power states to be read from DT

2015-11-17 Thread Lina Iyer
From: Marc Titinger 

From: Marc Titinger 

This patch allows cluster-level idle-states to being soaked in as
generic domain power states, in order for the domain governor to chose
the most efficient power state compatible with the device constraints.
Similarly, devices can register power-states into the cluster domain, in
a manner consistent with idle-states.

This is a attempt to address device-retention states for devices that
are not hooked to runtime-pm, but feature a retention state handled by
the same firmware that handles idle-states. For instance a L2 caches.

With Juno, in this example the idle-state 'cluster-sleep-0 ' is known
from each cluster generic domain, as the deepest sate.

cat /sys/kernel/debug/pm_genpd/*

Domain State nameEnter (ns) / Exit (ns)
-
a53_pd   cluster-sleep-0  150 / 80
a57_pd   cluster-sleep-0  150 / 80

domain  status pstate slaves
/device  runtime status
---
a53_pd  on
/devices/system/cpu/cpu0active
/devices/system/cpu/cpu3suspended
/devices/system/cpu/cpu4suspended
/devices/system/cpu/cpu5suspended
/devices/platform/D1suspended
a57_pd  cluster-sleep-0
/devices/system/cpu/cpu1suspended
/devices/system/cpu/cpu2suspended

Signed-off-by: Marc Titinger 
Signed-off-by: Lina Iyer 
[Lina: removed dependency on dynamic states, simplified initalization,
added of_pm_genpd_init() API]
---
 .../devicetree/bindings/power/power_domain.txt |  63 ++
 drivers/base/power/domain.c| 128 +
 include/linux/pm_domain.h  |   6 +
 3 files changed, 197 insertions(+)

diff --git a/Documentation/devicetree/bindings/power/power_domain.txt 
b/Documentation/devicetree/bindings/power/power_domain.txt
index 025b5e7..e2f542e 100644
--- a/Documentation/devicetree/bindings/power/power_domain.txt
+++ b/Documentation/devicetree/bindings/power/power_domain.txt
@@ -29,6 +29,44 @@ Optional properties:
specified by this binding. More details about power domain specifier are
available in the next section.
 
+- power-states : A phandle of an idle-state that shall be soaked into a
+generic domain power state. The power-state shall be
+   compatible with "linux,domain-state".
+
+==Power state==
+
+A PM domain power state describes an idle state of a domain and must be
+have the following properties -
+
+   - compatible
+   Usage: Required
+   Value type: 
+   Definition: Must be "linux,domain-state"
+
+   - entry-latency-us
+   Usage: Not required if wakeup-latency-us is provided.
+   Value type: 
+   Definition: u32 value representing worst case latency in
+   microseconds required to enter the idle state.
+   The exit-latency-us duration may be guaranteed
+   only after entry-latency-us has passed.
+
+   - exit-latency-us
+   Usage: Not required if wakeup-latency-us is provided.
+   Value type: 
+   Definition: u32 value representing worst case latency
+   in microseconds required to exit the idle state.
+
+   - wakeup-latency-us:
+   Usage: Not required if entry-latency-us and exit-latency-us
+   are provided.
+   Value type: 
+   Definition: u32 value representing maximum delay between the
+   signaling the wakeup of the domain and the domain resuming
+   regular operation.
+   If omitted, this is assumed to be equal to:
+   entry-latency-us + exit-latency-us
+
 Example:
 
power: power-controller@1234 {
@@ -55,6 +93,31 @@ Example 2:
#power-domain-cells = <1>;
};
 
+Example 3:
+
+   pm-domains {
+   a57_pd: a57_pd@ {
+   /* will have a57 platform ARM_PD_METHOD_OF_DECLARE*/
+   compatible = "arm,pd","arm,cortex-a57";
+   #power-domain-cells = <0>;
+   power-states = <_SLEEP_0>;
+   };
+
+   a53_pd: a53_pd@ {
+   /* will have a a53 platform ARM_PD_METHOD_OF_DECLARE*/
+   compatible = "arm,pd","arm,cortex-a53";
+   #power-domain-cells = <0>;
+   power-states = <_SLEEP_0>;
+   };
+
+  

[PATCH RFC 03/27] PM / Domain: Add additional state specific param

2015-11-17 Thread Lina Iyer
Allow domain states to hold additional state related data in a u32
value. This may be used by the platform driver.

Signed-off-by: Lina Iyer 
---
 Documentation/devicetree/bindings/power/power_domain.txt | 6 ++
 drivers/base/power/domain.c  | 6 ++
 include/linux/pm_domain.h| 1 +
 3 files changed, 13 insertions(+)

diff --git a/Documentation/devicetree/bindings/power/power_domain.txt 
b/Documentation/devicetree/bindings/power/power_domain.txt
index e2f542e..ecfaf44 100644
--- a/Documentation/devicetree/bindings/power/power_domain.txt
+++ b/Documentation/devicetree/bindings/power/power_domain.txt
@@ -67,6 +67,12 @@ have the following properties -
If omitted, this is assumed to be equal to:
entry-latency-us + exit-latency-us
 
+   - state-param:
+   Usage: Optional
+   Value type: 
+   Definition: A u32 value as defined by the state. May be used
+   by the driver to hold state related u32 data.
+
 Example:
 
power: power-controller@1234 {
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index fe1be88..3fb4c93 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -1245,6 +1245,7 @@ static int genpd_alloc_states_data(struct 
generic_pm_domain *genpd,
st[i].power_on_latency_ns;
genpd->states[i].power_off_latency_ns =
st[i].power_off_latency_ns;
+   genpd->states[i].param = st[i].param;
}
 
/*
@@ -1527,6 +1528,7 @@ static int of_get_genpd_power_state(struct 
genpd_power_state *genpd_state,
const struct of_device_id *match_id;
int err = 0;
u32 latency;
+   u32 param;
 
match_id = of_match_node(power_state_match, state_node);
if (!match_id)
@@ -1567,6 +1569,10 @@ static int of_get_genpd_power_state(struct 
genpd_power_state *genpd_state,
return -EINVAL;
}
 
+   err = of_property_read_u32(state_node, "state-param", );
+   if (!err)
+   genpd_state->param = param;
+
genpd_state->power_off_latency_ns = 1000 * latency;
 
return 0;
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index e425911..15df24c 100644
--- a/include/linux/pm_domain.h
+++ b/include/linux/pm_domain.h
@@ -41,6 +41,7 @@ struct genpd_power_state {
char *name;
s64 power_off_latency_ns;
s64 power_on_latency_ns;
+   u32 param;
 };
 
 struct generic_pm_domain {
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH RFC 06/27] PM / Domains: add debugfs 'states' and 'timings' seq files

2015-11-17 Thread Lina Iyer
From: Marc Titinger 

This purpose of these debug seq-files is to help investigate
generic power domain state transitions, based on device constraints.
requires the "multiple states" patches from Axel Haslam.

also rename 'summary' from 'pm_genpd_summary'

sample output for 'states'
==

  Domain State nameEval = 2200nter + Exit = Min_off_on (ns)
---
a53_pd   cluster-sleep-0  150+80=230
a57_pd   d1-retention 100+80=180
a57_pd   cluster-sleep-0  150+80=230

sample output for 'timings'
===

Domain Devices, Timings in ns
   Stop/Start Save/Restore, Effective
  ---
a53_pd
/cpus/cpu@1001060  /6601580  /1940  ,0 (cached stop)
/cpus/cpu@1011060  /7401520  /1600  ,0 (cached stop)
/cpus/cpu@102880   /6201380  /1780  ,0 (cached stop)
/cpus/cpu@1031080  /6401340  /1600  ,0 (cached stop)
a57_pd
/cpus/cpu@0  1160  /7403280  /1800  ,0 (cached stop)
/cpus/cpu@1  780   /1400   1440  /2080  ,0 (cached stop)
/D1  600   /5407140  /6420  ,2199460 (cached stop)

Signed-off-by: Marc Titinger 
---
 drivers/base/power/domain.c | 115 +---
 1 file changed, 107 insertions(+), 8 deletions(-)

diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index c300293..9a0df09 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -2169,21 +2169,120 @@ static const struct file_operations 
pm_genpd_summary_fops = {
.release = single_release,
 };
 
+static int pm_genpd_states_show(struct seq_file *s, void *data)
+{
+   struct generic_pm_domain *genpd;
+
+   seq_puts(s,
+"\n  Domain State nameEnter + Exit = 
Min_off_on (ns)\n");
+   seq_puts(s,
+
"---\n");
+
+   list_for_each_entry(genpd, _list, gpd_list_node) {
+
+   int i;
+
+   for (i = 0; i < genpd->state_count; i++) {
+   seq_printf(s, "%-20s %-20s %lld+%lld=%lld\n",
+  genpd->name,
+  genpd->states[i].name,
+  genpd->states[i].power_on_latency_ns,
+  genpd->states[i].power_off_latency_ns,
+  genpd->states[i].power_off_latency_ns
+  + genpd->states[i].power_on_latency_ns);
+   }
+
+   }
+
+   seq_puts(s, "\n");
+
+   return 0;
+}
+
+static int pm_genpd_states_open(struct inode *inode, struct file *file)
+{
+   return single_open(file, pm_genpd_states_show, NULL);
+}
+
+static const struct file_operations pm_genpd_states_fops = {
+   .open = pm_genpd_states_open,
+   .read = seq_read,
+   .llseek = seq_lseek,
+   .release = single_release,
+};
+
+static int pm_genpd_timing_show(struct seq_file *s, void *data)
+{
+   struct generic_pm_domain *genpd;
+
+   seq_puts(s, "\nDomain Devices, Timings in ns\n");
+   seq_puts(s,
+"   Stop/Start Save/Restore, Effective\n");
+   seq_puts(s,
+"  ---\n");
+
+   list_for_each_entry(genpd, _list, gpd_list_node) {
+   struct pm_domain_data *pm_data;
+
+   seq_printf(s, "%-30s", genpd->name);
+
+   list_for_each_entry(pm_data, >dev_list, list_node) {
+   struct gpd_timing_data *td = _gpd_data(pm_data)->td;
+
+   if (!pm_data->dev->of_node)
+   continue;
+
+   seq_printf(s,
+  "\n%-20s %-6lld/%-6lld 
%-6lld/%-6lld,%lld %s%s",
+  pm_data->dev->of_node->full_name,
+  td->stop_latency_ns, td->start_latency_ns,
+  td->save_state_latency_ns,
+  td->restore_state_latency_ns,
+  td->effective_constraint_ns,
+  td->cached_stop_ok ? "(cached stop) " : "",
+  td->constraint_changed ? "(changed)" : "");
+   }
+   seq_puts(s, "\n");
+   }
+   return 0;
+}
+
+static int pm_genpd_timing_open(struct inode *inode, struct file *file)
+{
+   return single_open(file, pm_genpd_timing_show, NULL);
+}
+
+static const struct file_operations pm_genpd_timing_fops = {
+   .open = 

[PATCH RFC 07/27] PM / Domains: Read domain residency from DT

2015-11-17 Thread Lina Iyer
Domains that have expensive suspend resume operations, may require a
certain amount of time be spent in an idle state to reap the power
saving benefit. Such domains, may provide the residency requirement for
a domain state.

Read the residency for a domain state from the DT. A domain governor may
use this information in determining the state for the domain.

Cc: Axel Haslam 
Cc: Marc Titinger 
Signed-off-by: Lina Iyer 
---
 Documentation/devicetree/bindings/power/power_domain.txt | 7 +++
 drivers/base/power/domain.c  | 6 ++
 include/linux/pm_domain.h| 1 +
 3 files changed, 14 insertions(+)

diff --git a/Documentation/devicetree/bindings/power/power_domain.txt 
b/Documentation/devicetree/bindings/power/power_domain.txt
index ecfaf44..d71da29 100644
--- a/Documentation/devicetree/bindings/power/power_domain.txt
+++ b/Documentation/devicetree/bindings/power/power_domain.txt
@@ -67,6 +67,13 @@ have the following properties -
If omitted, this is assumed to be equal to:
entry-latency-us + exit-latency-us
 
+   - residency-us:
+   Usage: Optional
+   Value type: 
+   Definition: A u32 value representing the time for which a
+   domain must be idle in the state to reap power saving benefits
+   of entering the state.
+
- state-param:
Usage: Optional
Value type: 
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index 9a0df09..abc81bd 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -1245,6 +1245,7 @@ static int genpd_alloc_states_data(struct 
generic_pm_domain *genpd,
st[i].power_on_latency_ns;
genpd->states[i].power_off_latency_ns =
st[i].power_off_latency_ns;
+   genpd->states[i].residency_ns = st[i].residency_ns;
genpd->states[i].param = st[i].param;
}
 
@@ -1513,6 +1514,7 @@ static int of_get_genpd_power_state(struct 
genpd_power_state *genpd_state,
const struct of_device_id *match_id;
int err = 0;
u32 latency;
+   u32 residency;
u32 param;
 
match_id = of_match_node(power_state_match, state_node);
@@ -1554,6 +1556,10 @@ static int of_get_genpd_power_state(struct 
genpd_power_state *genpd_state,
return -EINVAL;
}
 
+   err = of_property_read_u32(state_node, "residency-us", );
+   if (!err)
+   genpd_state->residency_ns = 1000 * residency;
+
err = of_property_read_u32(state_node, "state-param", );
if (!err)
genpd_state->param = param;
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index 108a4b3..fed024a 100644
--- a/include/linux/pm_domain.h
+++ b/include/linux/pm_domain.h
@@ -41,6 +41,7 @@ struct genpd_power_state {
char *name;
s64 power_off_latency_ns;
s64 power_on_latency_ns;
+   s64 residency_ns;
u32 param;
 };
 
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH RFC 05/27] PM / Domains: remove old power on/off latencies.

2015-11-17 Thread Lina Iyer
From: Axel Haslam 

Now that all known users have been converted to use state latencies,
we can remove the latency field in the generic_pm_domain structure.

Signed-off-by: Axel Haslam 
---
 drivers/base/power/domain.c | 15 ---
 include/linux/pm_domain.h   |  2 --
 2 files changed, 17 deletions(-)

diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index 3fb4c93..c300293 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -1248,21 +1248,6 @@ static int genpd_alloc_states_data(struct 
generic_pm_domain *genpd,
genpd->states[i].param = st[i].param;
}
 
-   /*
-* Copy the latency values To keep compatibility with
-* platforms that are not converted to use the multiple states.
-* This will be removed once all platforms are converted to use
-* multiple states. note that non converted platforms will use the
-* default single off state.
-*/
-   if (genpd->power_on_latency_ns != 0)
-   genpd->states[0].power_on_latency_ns =
-   genpd->power_on_latency_ns;
-
-   if (genpd->power_off_latency_ns != 0)
-   genpd->states[0].power_off_latency_ns =
-   genpd->power_off_latency_ns;
-
genpd->state_count = st_count;
 
/* to save memory, Name allocation will happen if debug is enabled */
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index 15df24c..108a4b3 100644
--- a/include/linux/pm_domain.h
+++ b/include/linux/pm_domain.h
@@ -61,9 +61,7 @@ struct generic_pm_domain {
unsigned int prepared_count;/* Suspend counter of prepared devices 
*/
bool suspend_power_off; /* Power status before system suspend */
int (*power_off)(struct generic_pm_domain *domain);
-   s64 power_off_latency_ns;
int (*power_on)(struct generic_pm_domain *domain);
-   s64 power_on_latency_ns;
struct gpd_dev_ops dev_ops;
s64 max_off_time_ns;/* Maximum allowed "suspended" time. */
bool max_off_time_changed;
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH RFC 04/27] PM / Domains: make governor select deepest state

2015-11-17 Thread Lina Iyer
From: Axel Haslam 

Now that the structures of genpd can support multiple state definitions,
add the logic in the governor to select the deepest possible state when
powering down.

For this, create the new function power_down_ok_for_state which will test
if a particular state will not violate the devices and sub-domains
constraints.

default_power_down_ok is modified to try each state starting from the
deepest until a valid state is found or there are no more states to test.

the resulting state will be valid until there are latency or constraint
changes, thus, we can avoid looping every power_down, and use the cached
results instead.

Signed-off-by: Axel Haslam 
---
 drivers/base/power/domain_governor.c | 75 +---
 1 file changed, 45 insertions(+), 30 deletions(-)

diff --git a/drivers/base/power/domain_governor.c 
b/drivers/base/power/domain_governor.c
index b4984f5..ad69dc0 100644
--- a/drivers/base/power/domain_governor.c
+++ b/drivers/base/power/domain_governor.c
@@ -98,7 +98,8 @@ static bool default_stop_ok(struct device *dev)
  *
  * This routine must be executed under the PM domain's lock.
  */
-static bool default_power_down_ok(struct dev_pm_domain *pd)
+static bool power_down_ok_for_state(struct dev_pm_domain *pd,
+unsigned int state)
 {
struct generic_pm_domain *genpd = pd_to_genpd(pd);
struct gpd_link *link;
@@ -106,31 +107,9 @@ static bool default_power_down_ok(struct dev_pm_domain *pd)
s64 min_off_time_ns;
s64 off_on_time_ns;
 
-   if (genpd->max_off_time_changed) {
-   struct gpd_link *link;
+   off_on_time_ns = genpd->states[state].power_off_latency_ns +
+   genpd->states[state].power_on_latency_ns;
 
-   /*
-* We have to invalidate the cached results for the masters, so
-* use the observation that default_power_down_ok() is not
-* going to be called for any master until this instance
-* returns.
-*/
-   list_for_each_entry(link, >slave_links, slave_node)
-   link->master->max_off_time_changed = true;
-
-   genpd->max_off_time_changed = false;
-   genpd->cached_power_down_ok = false;
-   genpd->max_off_time_ns = -1;
-   } else {
-   return genpd->cached_power_down_ok;
-   }
-
-   /*
-* Use the only available state, until multiple state support is added
-* to the governor.
-*/
-   off_on_time_ns = genpd->states[0].power_off_latency_ns +
-   genpd->states[0].power_on_latency_ns;
 
min_off_time_ns = -1;
/*
@@ -193,8 +172,6 @@ static bool default_power_down_ok(struct dev_pm_domain *pd)
min_off_time_ns = constraint_ns;
}
 
-   genpd->cached_power_down_ok = true;
-
/*
 * If the computed minimum device off time is negative, there are no
 * latency constraints, so the domain can spend arbitrary time in the
@@ -207,14 +184,52 @@ static bool default_power_down_ok(struct dev_pm_domain 
*pd)
 * The difference between the computed minimum subdomain or device off
 * time and the time needed to turn the domain on is the maximum
 * theoretical time this domain can spend in the "off" state.
-* Use the only available state, until multiple state support is added
-* to the governor.
 */
genpd->max_off_time_ns = min_off_time_ns -
-   genpd->states[0].power_on_latency_ns;
+   genpd->states[state].power_on_latency_ns;
return true;
 }
 
+static bool default_power_down_ok(struct dev_pm_domain *pd)
+{
+   struct generic_pm_domain *genpd = pd_to_genpd(pd);
+   unsigned int last_state_idx = genpd->state_count - 1;
+   struct gpd_link *link;
+   bool retval = false;
+   unsigned int i;
+
+   /*
+* if there was no change on max_off_time, we can return the
+* cached value and we dont need to find a new target_state
+*/
+   if (!genpd->max_off_time_changed)
+   return genpd->cached_power_down_ok;
+
+   /*
+* We have to invalidate the cached results for the masters, so
+* use the observation that default_power_down_ok() is not
+* going to be called for any master until this instance
+* returns.
+*/
+   list_for_each_entry(link, >slave_links, slave_node)
+   link->master->max_off_time_changed = true;
+
+   genpd->max_off_time_ns = -1;
+   genpd->max_off_time_changed = false;
+
+   /* find a state to power down to, starting from the deepest */
+   for (i = 0; i < genpd->state_count; i++) {
+   if (power_down_ok_for_state(pd, last_state_idx - i)) {
+   

[PATCH RFC 01/27] PM / Domains: core changes for multiple states

2015-11-17 Thread Lina Iyer
From: Axel Haslam 

From: Axel Haslam 

Add the core changes to be able to declare multiple states.
When trying to set a power domain to off, genpd will be able to choose
from an array of states declared by the platform. The power on and off
latencies are now tied to a state.

States should be declared in ascending order from shallowest to deepest,
deepest meaning the state which takes longer to enter and exit.

the power_off and power_on function can use the 'state_idx' field of the
generic_pm_domain structure, to distinguish between the different states
and act accordingly.

Example:

static int pd1_power_on(struct generic_pm_domain *domain)
{
/* domain->state_idx = state the domain is coming from */
}

static int pd1_power_off(struct generic_pm_domain *domain)
{
/* domain->state_idx = desired powered off state */
}

const struct genpd_power_state pd_states[] = {
{
.name = "RET",
.power_on_latency_ns = ON_LATENCY_FAST,
.power_off_latency_ns = OFF_LATENCY_FAST,
},
{
.name = "DEEP_RET",
.power_on_latency_ns = ON_LATENCY_MED,
.power_off_latency_ns = OFF_LATENCY_MED,
},
{
.name = "OFF",
.power_on_latency_ns = ON_LATENCY_SLOW,
.power_off_latency_ns = OFF_LATENCY_SLOW,
}
};

struct generic_pm_domain pd1 = {
.name = "PD1",
.power_on = pd1_power_on,
.power_off = pd1_power_off,
[...]
};

int xxx_init_pm_domain(){

pd1->state = copy_of(pd_states);
pd1->state_count = ARRAY_SIZE(pd_states);
pm_genpd_init(pd1, true);

}

Signed-off-by: Axel Haslam 
Signed-off-by: Lina Iyer 
[Lina: Modified genpd state initialization and remove use of
save_state_latency_ns in genpd timing data]

Signed-off-by: Lina Iyer 
---
 drivers/base/power/domain.c  | 136 +--
 drivers/base/power/domain_governor.c |  13 +++-
 include/linux/pm_domain.h|  10 +++
 3 files changed, 151 insertions(+), 8 deletions(-)

diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index e03b1ad..3242854 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -34,6 +34,12 @@
__ret;  \
 })
 
+#define GENPD_MAX_NAME_SIZE 20
+
+static int pm_genpd_alloc_states_names(struct generic_pm_domain *genpd,
+  const struct genpd_power_state *st,
+  unsigned int st_count);
+
 static LIST_HEAD(gpd_list);
 static DEFINE_MUTEX(gpd_list_lock);
 
@@ -102,6 +108,7 @@ static void genpd_sd_counter_inc(struct generic_pm_domain 
*genpd)
 
 static int genpd_power_on(struct generic_pm_domain *genpd, bool timed)
 {
+   unsigned int state_idx = genpd->state_idx;
ktime_t time_start;
s64 elapsed_ns;
int ret;
@@ -118,10 +125,10 @@ static int genpd_power_on(struct generic_pm_domain 
*genpd, bool timed)
return ret;
 
elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start));
-   if (elapsed_ns <= genpd->power_on_latency_ns)
+   if (elapsed_ns <= genpd->states[state_idx].power_on_latency_ns)
return ret;
 
-   genpd->power_on_latency_ns = elapsed_ns;
+   genpd->states[state_idx].power_on_latency_ns = elapsed_ns;
genpd->max_off_time_changed = true;
pr_debug("%s: Power-%s latency exceeded, new value %lld ns\n",
 genpd->name, "on", elapsed_ns);
@@ -131,6 +138,7 @@ static int genpd_power_on(struct generic_pm_domain *genpd, 
bool timed)
 
 static int genpd_power_off(struct generic_pm_domain *genpd, bool timed)
 {
+   unsigned int state_idx = genpd->state_idx;
ktime_t time_start;
s64 elapsed_ns;
int ret;
@@ -147,10 +155,10 @@ static int genpd_power_off(struct generic_pm_domain 
*genpd, bool timed)
return ret;
 
elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start));
-   if (elapsed_ns <= genpd->power_off_latency_ns)
+   if (elapsed_ns <= genpd->states[state_idx].power_off_latency_ns)
return ret;
 
-   genpd->power_off_latency_ns = elapsed_ns;
+   genpd->states[state_idx].power_off_latency_ns = elapsed_ns;
genpd->max_off_time_changed = true;
pr_debug("%s: Power-%s latency exceeded, new value %lld ns\n",
 genpd->name, "off", elapsed_ns);
@@ -582,6 +590,8 @@ static void pm_genpd_sync_poweroff(struct generic_pm_domain 
*genpd,
|| atomic_read(>sd_count) > 0)
return;
 
+   /* Choose the deepest state when suspending */
+   genpd->state_idx = genpd->state_count - 1;
genpd_power_off(genpd, timed);
 
genpd->status =