Re: [PATCH v2 00/14] Add Qualcomm SD Card Controller support

2014-05-23 Thread Srinivas Kandagatla



On 23/05/14 08:50, Ulf Hansson wrote:

On 23 May 2014 09:13, Srinivas Kandagatla
 wrote:

Hi Ulf,
I like to get this patches for v3.16,  any chance of considering these
patches to v3.16 ?


I promise to have them properly reviewed early next week, sorry for
taking so long. Let's see where this leads us.


Thankyou.


It seems like you had some CRC issues during read/write? Did you
manage to resolve that issue?


Bjorn is using different SOC and board than the IFC6410 Am testing on, 
so its completely different setup.
on IFC6410 we did lot of stress testing and no issues seen. so 
suspecting the issues are very specific to that board or the eMMC Bjorn 
is using.


We are suspecting that the CRC issues are due to the fact that there is 
no code to manage regulators. My test setup uses dummy regulator, and 
the eMMC and external SD cards seems to be Ok with default voltages.


Am not sure if thats the same with Bjorn's board.

Thanks,
srini


Kind regards
Ulf Hansson



--
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 11/14] mmc: mmci: Add support to data commands via variant structure.

2014-05-23 Thread Srinivas Kandagatla

Thanks Linus W.

On 23/05/14 10:09, Linus Walleij wrote:

On Thu, May 15, 2014 at 11:37 AM,   wrote:


From: Srinivas Kandagatla 

On some SOCs like Qcom there are explicit bits in the command register
to specify if its a data transfer command or not. So this patch adds
support to such bits in variant data, giving more flexibility to the
driver.

Signed-off-by: Srinivas Kandagatla 


Reviewed-by: Linus Walleij 

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


Re: [PATCH v2 12/14] mmc: mmci: add support for fbclk to latch data and cmd.

2014-05-23 Thread Srinivas Kandagatla



On 23/05/14 10:12, Linus Walleij wrote:

On Thu, May 15, 2014 at 11:37 AM,   wrote:


From: Srinivas Kandagatla 

This patch adds support to fbclk that is used to latch data and
cmd on some controllers like SD Card controller in Qcom SOC.

Signed-off-by: Srinivas Kandagatla 


(...)

Isn't this overkill?


I totally agree.

Initially I did do it the way you suggested, but wanted to be more 
explicit in what its actually doing and I was also not sure if its Ok to 
add more than one flag in clkreg_enable.




@@ -189,6 +192,7 @@ static struct variant_data variant_qcom = {
  .clkreg = MCI_CLK_ENABLE,
-.clkreg_enable  = MCI_QCOM_CLK_FLOWENA,
+   .clkreg_enable  = MCI_QCOM_CLK_FLOWENA |
MCI_QCOM_CLK_FEEDBACK_CLK,
  .clkreg_8bit_bus_enable = MCI_QCOM_CLK_WIDEBUS_8,




Isn't this achieveing exactly the same thing without the extra fields?
You unconditionally do it at every enable anyway, don't you?

I will fix it and send a new version.

Thanks,
srini


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


Re: [PATCH v2 14/14] mmc: mmci: Add Qcom specific pio_read function.

2014-05-23 Thread Srinivas Kandagatla



On 23/05/14 10:31, Linus Walleij wrote:

On Thu, May 15, 2014 at 11:38 AM,   wrote:


From: Srinivas Kandagatla 

MCIFIFOCNT register behaviour on Qcom chips is very different than the other
pl180 integrations. MCIFIFOCNT register contains the number of
words that are still waiting to be transferred through the FIFO. It keeps
decrementing once the host CPU reads the MCIFIFO. With the existing logic and
the MCIFIFOCNT behaviour, mmci_pio_read will loop forever, as the FIFOCNT
register will always return transfer size before reading the FIFO.

Also the data sheet states that "This register is only useful for debug
purposes and should not be used for normal operation since it does not reflect
data which may or may not be in the pipeline".

This patch implements qcom_pio_read function so as existing mmci_pio_read is
not suitable for Qcom SOCs. qcom_pio_read function is only selected
based on qcom_fifo flag in variant data structure.

Signed-off-by: Srinivas Kandagatla 

(...)


+static int mmci_qcom_pio_read(struct mmci_host *host, char *buffer,
+unsigned int remain)
+{
+   uint32_t*ptr = (uint32_t *) buffer;



Oops..

Sorry Linus, I think this change-set got something different than what I 
did. I remember your comments in the last review, I did take care of 
them but some how It got missed... I will fix these and send a new version.



Just use u32 like the rest of the driver does.


+   int fifo_size = variant->fifosize;
+
+   if (remain % 4)




And another variant is to count the *number or words*
to read from the FIFO rather than the number of bytes! I would do it
like this:

static int mmci_qcom_pio_read(struct mmci_host *host, char *buffer,
 unsigned int remain)
{
u32 *ptr = (u32*) buffer;
unsigned int count = 0;
unsigned int words;
unsigned int fifo_size = host->variant->fifosize;

words = DIV_ROUND_UP(remain, 4);
while (readl(host->base + MMCISTATUS) & MCI_RXDATAAVLBL) {
*ptr = readl(host->base + MMCIFIFO + (count % fifo_size));
ptr++;
count += 4;
remain--;
if (!remain)
break;
}
return count;
}

I guess you will run into additional problems when you come to doing
SDIO. This function can return *more* bytes than asked for, as it rounds
up. It won't happen with MMC/SD transfers since these are always
divisible by 8, but it *will* happen on SDIO!

If you look carefully at the comments in mmci_pio_read() you will
see how this is handled. Are you sure this function cannot be
augmented to handle the qcom variant as well so you don't get this
problem further down the road?


I did try to customize the mmci_pio_read function but I failed all the 
time. The reason being the behaviour of MCI_FIFOCNT register which is 
totally different to the way the function is written. I will give a try 
again.


Thanks,
srini


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


Re: [PATCH v2 14/14] mmc: mmci: Add Qcom specific pio_read function.

2014-05-23 Thread Srinivas Kandagatla

Hi Linus W,

On 23/05/14 10:31, Linus Walleij wrote:

static int mmci_qcom_pio_read(struct mmci_host *host, char *buffer,
 unsigned int remain)
{
u32 *ptr = (u32*) buffer;
unsigned int count = 0;
unsigned int words;
unsigned int fifo_size = host->variant->fifosize;

words = DIV_ROUND_UP(remain, 4);
while (readl(host->base + MMCISTATUS) & MCI_RXDATAAVLBL) {
*ptr = readl(host->base + MMCIFIFO + (count % fifo_size));
ptr++;
count += 4;
remain--;
if (!remain)
break;
}
return count;
}

I guess you will run into additional problems when you come to doing
SDIO. This function can return*more*  bytes than asked for, as it rounds
up. It won't happen with MMC/SD transfers since these are always
divisible by 8, but it*will*  happen on SDIO!

That's a good point,

Qualcomm will need SDIO support in future, so I have slightly modified 
the  code to address this. Other thing I tried was to fit in this in 
mmci_pio_read, It became very ugly, as the FIFOCNT register behaviour is 
totally different and there is no way to tell how many bytes are ready 
to be consumed. So finally I think having a separate pio read for 
qualcomm looks much neater.


final mmci_qcom_pio_read looks like:


static int mmci_qcom_pio_read(struct mmci_host *host, char *buffer,
unsigned int remain)
{
u32 *ptr = (u32*) buffer;
unsigned int count = 0;
unsigned int words, bytes;
unsigned int fifo_size = host->variant->fifosize;

words = remain >> 2;
bytes = remain % 4;
/* read full words followed by leftover bytes */
if (words) {
while (readl(host->base + MMCISTATUS) & MCI_RXDATAAVLBL) {
*ptr = readl(host->base + MMCIFIFO + (count % fifo_size));
ptr++;
count += 4;
words--;
if (!words)
break;
 }
}

/* read leftover bytes */
if (unlikely(bytes)) {
unsigned char buf[4];
if (readl(host->base + MMCISTATUS) & MCI_RXDATAAVLBL) {
*buf = readl(host->base + MMCIFIFO + (count % fifo_size));
memcpy(ptr, buf, bytes);
 count += bytes;
}
}

return count;
}

Thanks,
srini

--
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 v3 00/13] Add Qualcomm SD Card Controller support

2014-05-23 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

Thankyou Linus W and everyone for reviewing RFC to v3 patches.

This patch series adds Qualcomm SD Card Controller support in pl180 mmci
driver. QCom SDCC is basically a pl180, but bit more customized, some of the
register layouts and offsets are different to the ones mentioned in pl180
datasheet. The plan is to totally remove the standalone SDCC driver
drivers/mmc/host/msm_sdcc.* and start using generic mmci driver for all
Qualcomm parts, as we get chance to test on other Qcom boards.

To start using the existing mmci driver, a fake amba id for Qualcomm is added
in patches:
 mmc: mmci: Add Qualcomm Id to amba id table.

Second change is, adding a 3 clock cycle delay for register writes on QCOM SDCC
registers, which is done in patches:
  mmc: mmci: Add register read/write wrappers.
  mmc: mmci: Qcomm: Add 3 clock cycle delay after register write

Third change is to accommodate CLK, DATCTRL and MMCICLK register layout changes
in Qcom SDCC and provide more flexibity in driver to specify these changes via
variant datastructure. Which are done in patches:
  mmc: mmci: Add Qcom datactrl register variant
  mmc: mmci: add ddrmode mask to variant data
  mmc: mmci: add 8bit bus support in variant data
  mmc: mmci: add edge support to data and command out in variant data.
  mmc: mmci: add Qcom specifics of clk and datactrl registers.
  mmc: mmci: Add support to data commands via variant structure.
  mmc: mmci: add explicit clk control

Fourth major change was to add qcom specfic pio read function, the need for
this is because the way MCIFIFOCNT register behaved in QCOM SDCC is very
 different to the one in pl180. This change is done in patch:
  mmc: mmci: Add Qcom specific pio_read function.

Last some Qcom unrelated changes/cleanup to driver are done in patches:
  mmc: mmci: use NSEC_PER_SEC macro
  mmc: mmci: convert register bits to use BIT() macro.

This patches are tested in PIO mode on IFC8064 board with both eMMC and
external SD card. I would like to get this support in v3.16.

Changes from v2:
- merged fbclk latch patch with clkreg_enable patch as suggested by 
Linus W.
- remove qcom prefix for explicit clk control pointed by Linus W.
- cleaned up mmci_qcom_pio_read and consider SDIO as suggested by Linus 
W.

Changes from v1:
- moved most of the SOC specifics to variant parameters as suggested
  by Linus W.
- renamed registers as suggested by Linus W.
- Added comments in the code as suggested by Linus W.
- moved out AMBA ID addition patch from this series.
- rebased the patches to 
git://git.linaro.org/people/ulf.hansson/mmc.git next 
  as suggested by Ulf H.

Changes from RFC:
- moved out clk setup out of spinlock as pointed by Stephen B.

Am hoping to get this for v3.16.

All these patches are tested on IF6410 board on both eMMC and external SD card.

Thanks,
srini

Srinivas Kandagatla (13):
  mmc: mmci: use NSEC_PER_SEC macro
  mmc: mmci: convert register bits to use BIT() macro.
  mmc: mmci: Add Qualcomm Id to amba id table
  mmc: mmci: Add Qcom datactrl register variant
  mmc: mmci: Add register read/write wrappers.
  mmc: mmci: Qcomm: Add 3 clock cycle delay after register write
  mmc: mmci: add ddrmode mask to variant data
  mmc: mmci: add 8bit bus support in variant data
  mmc: mmci: add edge support to data and command out in variant data.
  mmc: mmci: add Qcom specifics of clk and datactrl registers.
  mmc: mmci: Add support to data commands via variant structure.
  mmc: mmci: add explicit clk control
  mmc: mmci: Add Qcom specific pio_read function.

 drivers/mmc/host/mmci.c | 252 
 drivers/mmc/host/mmci.h | 232 
 2 files changed, 318 insertions(+), 166 deletions(-)

-- 
1.9.1

--
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 v3 01/13] mmc: mmci: use NSEC_PER_SEC macro

2014-05-23 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

This patch replaces a constant used in calculating timeout with a proper
macro. This is make code more readable.

Signed-off-by: Srinivas Kandagatla 
Reviewed-by: Linus Walleij 
---
 drivers/mmc/host/mmci.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index a084edd..a38e714 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -718,7 +718,7 @@ static void mmci_start_data(struct mmci_host *host, struct 
mmc_data *data)
data->bytes_xfered = 0;
 
clks = (unsigned long long)data->timeout_ns * host->cclk;
-   do_div(clks, 10UL);
+   do_div(clks, NSEC_PER_SEC);
 
timeout = data->timeout_clks + (unsigned int)clks;
 
-- 
1.9.1

--
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 v3 02/13] mmc: mmci: convert register bits to use BIT() macro.

2014-05-23 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

This patch converts the register bits in the header file to use BIT(()
macro, which looks much neater.

No functional changes done.

Signed-off-by: Srinivas Kandagatla 
---
 drivers/mmc/host/mmci.h | 208 
 1 file changed, 104 insertions(+), 104 deletions(-)

diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h
index 347d942..cd83ca3 100644
--- a/drivers/mmc/host/mmci.h
+++ b/drivers/mmc/host/mmci.h
@@ -11,48 +11,48 @@
 #define MCI_PWR_OFF0x00
 #define MCI_PWR_UP 0x02
 #define MCI_PWR_ON 0x03
-#define MCI_OD (1 << 6)
-#define MCI_ROD(1 << 7)
+#define MCI_OD BIT(6)
+#define MCI_RODBIT(7)
 /*
  * The ST Micro version does not have ROD and reuse the voltage registers for
  * direction settings.
  */
-#define MCI_ST_DATA2DIREN  (1 << 2)
-#define MCI_ST_CMDDIREN(1 << 3)
-#define MCI_ST_DATA0DIREN  (1 << 4)
-#define MCI_ST_DATA31DIREN (1 << 5)
-#define MCI_ST_FBCLKEN (1 << 7)
-#define MCI_ST_DATA74DIREN (1 << 8)
+#define MCI_ST_DATA2DIREN  BIT(2)
+#define MCI_ST_CMDDIRENBIT(3)
+#define MCI_ST_DATA0DIREN  BIT(4)
+#define MCI_ST_DATA31DIREN BIT(5)
+#define MCI_ST_FBCLKEN BIT(7)
+#define MCI_ST_DATA74DIREN BIT(8)
 
 #define MMCICLOCK  0x004
-#define MCI_CLK_ENABLE (1 << 8)
-#define MCI_CLK_PWRSAVE(1 << 9)
-#define MCI_CLK_BYPASS (1 << 10)
-#define MCI_4BIT_BUS   (1 << 11)
+#define MCI_CLK_ENABLE BIT(8)
+#define MCI_CLK_PWRSAVEBIT(9)
+#define MCI_CLK_BYPASS BIT(10)
+#define MCI_4BIT_BUS   BIT(11)
 /*
  * 8bit wide buses, hardware flow contronl, negative edges and clock inversion
  * supported in ST Micro U300 and Ux500 versions
  */
-#define MCI_ST_8BIT_BUS(1 << 12)
-#define MCI_ST_U300_HWFCEN (1 << 13)
-#define MCI_ST_UX500_NEG_EDGE  (1 << 13)
-#define MCI_ST_UX500_HWFCEN(1 << 14)
-#define MCI_ST_UX500_CLK_INV   (1 << 15)
+#define MCI_ST_8BIT_BUSBIT(12)
+#define MCI_ST_U300_HWFCEN BIT(13)
+#define MCI_ST_UX500_NEG_EDGE  BIT(13)
+#define MCI_ST_UX500_HWFCENBIT(14)
+#define MCI_ST_UX500_CLK_INV   BIT(15)
 /* Modified PL180 on Versatile Express platform */
-#define MCI_ARM_HWFCEN (1 << 12)
+#define MCI_ARM_HWFCEN BIT(12)
 
 #define MMCIARGUMENT   0x008
 #define MMCICOMMAND0x00c
-#define MCI_CPSM_RESPONSE  (1 << 6)
-#define MCI_CPSM_LONGRSP   (1 << 7)
-#define MCI_CPSM_INTERRUPT (1 << 8)
-#define MCI_CPSM_PENDING   (1 << 9)
-#define MCI_CPSM_ENABLE(1 << 10)
+#define MCI_CPSM_RESPONSE  BIT(6)
+#define MCI_CPSM_LONGRSP   BIT(7)
+#define MCI_CPSM_INTERRUPT BIT(8)
+#define MCI_CPSM_PENDING   BIT(9)
+#define MCI_CPSM_ENABLEBIT(10)
 /* Argument flag extenstions in the ST Micro versions */
-#define MCI_ST_SDIO_SUSP   (1 << 11)
-#define MCI_ST_ENCMD_COMPL (1 << 12)
-#define MCI_ST_NIEN(1 << 13)
-#define MCI_ST_CE_ATACMD   (1 << 14)
+#define MCI_ST_SDIO_SUSP   BIT(11)
+#define MCI_ST_ENCMD_COMPL BIT(12)
+#define MCI_ST_NIENBIT(13)
+#define MCI_ST_CE_ATACMD   BIT(14)
 
 #define MMCIRESPCMD0x010
 #define MMCIRESPONSE0  0x014
@@ -62,95 +62,95 @@
 #define MMCIDATATIMER  0x024
 #define MMCIDATALENGTH 0x028
 #define MMCIDATACTRL   0x02c
-#define MCI_DPSM_ENABLE(1 << 0)
-#define MCI_DPSM_DIRECTION (1 << 1)
-#define MCI_DPSM_MODE  (1 << 2)
-#define MCI_DPSM_DMAENABLE (1 << 3)
-#define MCI_DPSM_BLOCKSIZE (1 << 4)
+#define MCI_DPSM_ENABLEBIT(0)
+#define MCI_DPSM_DIRECTION BIT(1)
+#define MCI_DPSM_MODE  BIT(2)
+#define MCI_DPSM_DMAENABLE BIT(3)
+#define MCI_DPSM_BLOCKSIZE BIT(4)
 /* Control register extensions in the ST Micro U300 and Ux500 versions */
-#define MCI_ST_DPSM_RWSTART(1 << 8)
-#define MCI_ST_DPSM_RWSTOP (1 << 9)
-#define MCI_ST_DPSM_RWMOD  (1 << 10)
-#define MCI_ST_DPSM_SDIOEN (1 << 11)
+#define MCI_ST_DPSM_RWSTARTBIT(8)
+#define MCI_ST_DPSM_RWSTOP BIT(9)
+#define MCI_ST_DPSM_RWMOD  BIT(10)
+#define MCI_ST_DPSM_SDIOEN BIT(11)
 /* Control register extensions in the ST Micro Ux500 versions */
-#define MCI_ST_DPSM_DMAREQCTL  (1 << 12)
-#define MCI_ST_DPSM_DBOOTMODEEN(1 << 13)
-#define MCI_ST_DPSM_BUSYMODE   (1 << 14)
-#define MCI_ST_DPSM_DDRMODE(1 << 15)
+#define MCI_ST_DPSM_DMAREQCTL  BIT(12)
+#define MCI_ST_DPSM_DBOOTMODEENBIT(13)
+#define MCI_ST_DPSM_BUSYMODE  

[PATCH v3 03/13] mmc: mmci: Add Qualcomm Id to amba id table

2014-05-23 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

This patch adds a fake Qualcomm ID 0x00051180 to the amba_ids, as Qualcomm
SDCC controller is pl180, but amba id registers read 0x0's.
The plan is to remove SDCC driver totally and use mmci as the main SD
controller driver for Qualcomm SOCs.

Signed-off-by: Srinivas Kandagatla 
Reviewed-by: Linus Walleij 
---
 drivers/mmc/host/mmci.c | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index a38e714..7bdf4d3 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -160,6 +160,15 @@ static struct variant_data variant_ux500v2 = {
.pwrreg_nopower = true,
 };
 
+static struct variant_data variant_qcom = {
+   .fifosize   = 16 * 4,
+   .fifohalfsize   = 8 * 4,
+   .clkreg = MCI_CLK_ENABLE,
+   .datalength_bits= 24,
+   .blksz_datactrl4= true,
+   .pwrreg_powerup = MCI_PWR_UP,
+};
+
 static int mmci_card_busy(struct mmc_host *mmc)
 {
struct mmci_host *host = mmc_priv(mmc);
@@ -1750,6 +1759,12 @@ static struct amba_id mmci_ids[] = {
.mask   = 0xf0ff,
.data   = &variant_ux500v2,
},
+   /* Qualcomm variants */
+   {
+   .id = 0x00051180,
+   .mask   = 0x000f,
+   .data   = &variant_qcom,
+   },
{ 0, 0 },
 };
 
-- 
1.9.1

--
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 v3 07/13] mmc: mmci: add ddrmode mask to variant data

2014-05-23 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

This patch adds ddrmode mask to variant structure giving more flexibility
to the driver to support more SOCs which have different datactrl register
layout.

Without this patch datactrl register is updated with wrong ddrmode mask on non
ST SOCs, resulting in card detection failures.

Signed-off-by: Srinivas Kandagatla 
Reviewed-by: Linus Walleij 
---
 drivers/mmc/host/mmci.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 1385554..dec70d2 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -59,6 +59,7 @@ static unsigned int fmax = 515633;
  *   is asserted (likewise for RX)
  * @sdio: variant supports SDIO
  * @st_clkdiv: true if using a ST-specific clock divider algorithm
+ * @datactrl_mask_ddrmode: ddr mode mask in datactrl register.
  * @blksz_datactrl16: true if Block size is at b16..b30 position in datactrl 
register
  * @blksz_datactrl4: true if Block size is at b4..b16 position in datactrl
  *  register
@@ -76,6 +77,7 @@ struct variant_data {
unsigned intdatalength_bits;
unsigned intfifosize;
unsigned intfifohalfsize;
+   unsigned intdatactrl_mask_ddrmode;
boolsdio;
boolst_clkdiv;
boolblksz_datactrl16;
@@ -114,6 +116,7 @@ static struct variant_data variant_u300 = {
.fifosize   = 16 * 4,
.fifohalfsize   = 8 * 4,
.clkreg_enable  = MCI_ST_U300_HWFCEN,
+   .datactrl_mask_ddrmode  = MCI_ST_DPSM_DDRMODE,
.datalength_bits= 16,
.sdio   = true,
.pwrreg_powerup = MCI_PWR_ON,
@@ -126,6 +129,7 @@ static struct variant_data variant_nomadik = {
.fifosize   = 16 * 4,
.fifohalfsize   = 8 * 4,
.clkreg = MCI_CLK_ENABLE,
+   .datactrl_mask_ddrmode  = MCI_ST_DPSM_DDRMODE,
.datalength_bits= 24,
.sdio   = true,
.st_clkdiv  = true,
@@ -140,6 +144,7 @@ static struct variant_data variant_ux500 = {
.fifohalfsize   = 8 * 4,
.clkreg = MCI_CLK_ENABLE,
.clkreg_enable  = MCI_ST_UX500_HWFCEN,
+   .datactrl_mask_ddrmode  = MCI_ST_DPSM_DDRMODE,
.datalength_bits= 24,
.sdio   = true,
.st_clkdiv  = true,
@@ -155,6 +160,7 @@ static struct variant_data variant_ux500v2 = {
.fifohalfsize   = 8 * 4,
.clkreg = MCI_CLK_ENABLE,
.clkreg_enable  = MCI_ST_UX500_HWFCEN,
+   .datactrl_mask_ddrmode  = MCI_ST_DPSM_DDRMODE,
.datalength_bits= 24,
.sdio   = true,
.st_clkdiv  = true,
@@ -800,7 +806,7 @@ static void mmci_start_data(struct mmci_host *host, struct 
mmc_data *data)
}
 
if (host->mmc->ios.timing == MMC_TIMING_UHS_DDR50)
-   datactrl |= MCI_ST_DPSM_DDRMODE;
+   datactrl |= variant->datactrl_mask_ddrmode;
 
/*
 * Attempt to use DMA operation mode, if this
-- 
1.9.1

--
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 v3 13/13] mmc: mmci: Add Qcom specific pio_read function.

2014-05-23 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

MCIFIFOCNT register behaviour on Qcom chips is very different than the other
pl180 integrations. MCIFIFOCNT register contains the number of
words that are still waiting to be transferred through the FIFO. It keeps
decrementing once the host CPU reads the MCIFIFO. With the existing logic and
the MCIFIFOCNT behaviour, mmci_pio_read will loop forever, as the FIFOCNT
register will always return transfer size before reading the FIFO.

Also the data sheet states that "This register is only useful for debug
purposes and should not be used for normal operation since it does not reflect
data which may or may not be in the pipeline".

This patch implements qcom_pio_read function so as existing mmci_pio_read is
not suitable for Qcom SOCs. qcom_pio_read function is only selected
based on qcom_fifo flag in variant data structure.

Signed-off-by: Srinivas Kandagatla 
---
 drivers/mmc/host/mmci.c | 46 --
 1 file changed, 44 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index f6dfd24..51ce493 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -75,6 +75,7 @@ static unsigned int fmax = 515633;
  *  are not ignored.
  * @explicit_mclk_control: enable explicit mclk control in driver.
  * @cclk_is_mclk: enable iff card clock is multimedia card adapter clock.
+ * @qcom_fifo: enables qcom specific fifo pio read function.
  */
 struct variant_data {
unsigned intclkreg;
@@ -98,6 +99,7 @@ struct variant_data {
boolmclk_delayed_writes;
boolexplicit_mclk_control;
boolcclk_is_mclk;
+   boolqcom_fifo;
 };
 
 static struct variant_data variant_arm = {
@@ -208,6 +210,7 @@ static struct variant_data variant_qcom = {
.mclk_delayed_writes= true,
.explicit_mclk_control  = true,
.cclk_is_mclk   = true,
+   .qcom_fifo  = true,
 };
 
 static inline u32 mmci_readl(struct mmci_host *host, u32 off)
@@ -1022,6 +1025,40 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command 
*cmd,
}
 }
 
+static int mmci_qcom_pio_read(struct mmci_host *host, char *buffer,
+   unsigned int remain)
+{
+   u32 *ptr = (u32 *) buffer;
+   unsigned int count = 0;
+   unsigned int words, bytes;
+   unsigned int fsize = host->variant->fifosize;
+
+   words = remain >> 2;
+   bytes = remain % 4;
+   /* read full words followed by leftover bytes */
+   if (words) {
+   while (readl(host->base + MMCISTATUS) & MCI_RXDATAAVLBL) {
+   *ptr = readl(host->base + MMCIFIFO + (count % fsize));
+   ptr++;
+   count += 4;
+   words--;
+   if (!words)
+   break;
+   }
+   }
+
+   if (unlikely(bytes)) {
+   unsigned char buf[4];
+   if (readl(host->base + MMCISTATUS) & MCI_RXDATAAVLBL) {
+   *buf = readl(host->base + MMCIFIFO + (count % fsize));
+   memcpy(ptr, buf, bytes);
+   count += bytes;
+   }
+   }
+
+   return count;
+}
+
 static int mmci_pio_read(struct mmci_host *host, char *buffer, unsigned int 
remain)
 {
void __iomem *base = host->base;
@@ -1143,8 +1180,13 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id)
remain = sg_miter->length;
 
len = 0;
-   if (status & MCI_RXACTIVE)
-   len = mmci_pio_read(host, buffer, remain);
+   if (status & MCI_RXACTIVE) {
+   if (variant->qcom_fifo)
+   len = mmci_qcom_pio_read(host, buffer, remain);
+   else
+   len = mmci_pio_read(host, buffer, remain);
+   }
+
if (status & MCI_TXACTIVE)
len = mmci_pio_write(host, buffer, remain, status);
 
-- 
1.9.1

--
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 v3 11/13] mmc: mmci: Add support to data commands via variant structure.

2014-05-23 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

On some SOCs like Qcom there are explicit bits in the command register
to specify if its a data transfer command or not. So this patch adds
support to such bits in variant data, giving more flexibility to the
driver.

Signed-off-by: Srinivas Kandagatla 
Reviewed-by: Linus Walleij 
---
 drivers/mmc/host/mmci.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 6434f5b1..5cbf644 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -59,6 +59,7 @@ static unsigned int fmax = 515633;
  *   is asserted (likewise for RX)
  * @fifohalfsize: number of bytes that can be written when MCI_TXFIFOHALFEMPTY
  *   is asserted (likewise for RX)
+ * @data_cmd_enable: enable value for data commands.
  * @sdio: variant supports SDIO
  * @st_clkdiv: true if using a ST-specific clock divider algorithm
  * @datactrl_mask_ddrmode: ddr mode mask in datactrl register.
@@ -81,6 +82,7 @@ struct variant_data {
unsigned intdatalength_bits;
unsigned intfifosize;
unsigned intfifohalfsize;
+   unsigned intdata_cmd_enable;
unsigned intdatactrl_mask_ddrmode;
boolsdio;
boolst_clkdiv;
@@ -189,6 +191,7 @@ static struct variant_data variant_qcom = {
  MCI_QCOM_CLK_FEEDBACK_CLK,
.clkreg_8bit_bus_enable = MCI_QCOM_CLK_WIDEBUS_8,
.datactrl_mask_ddrmode  = MCI_QCOM_CLK_DDR_MODE,
+   .data_cmd_enable= MCI_QCOM_CSPM_DATCMD,
.blksz_datactrl4= true,
.datalength_bits= 24,
.blksz_datactrl4= true,
@@ -875,6 +878,9 @@ mmci_start_command(struct mmci_host *host, struct 
mmc_command *cmd, u32 c)
if (/*interrupt*/0)
c |= MCI_CPSM_INTERRUPT;
 
+   if (mmc_cmd_type(cmd) == MMC_CMD_ADTC)
+   c |= host->variant->data_cmd_enable;
+
host->cmd = cmd;
 
mmci_writel(host, cmd->arg, MMCIARGUMENT);
-- 
1.9.1

--
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 v3 12/13] mmc: mmci: add explicit clk control

2014-05-23 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

On Controllers like Qcom SD card controller where cclk is mclk and mclk should
be directly controlled by the driver.

This patch adds support to control mclk directly in the driver, and also
adds explicit_mclk_control and cclk_is_mclk flags in variant structure giving
more flexibility to the driver.

Signed-off-by: Srinivas Kandagatla 
Reviewed-by: Linus Walleij 
---
 drivers/mmc/host/mmci.c | 30 +-
 1 file changed, 25 insertions(+), 5 deletions(-)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 5cbf644..f6dfd24 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -73,6 +73,8 @@ static unsigned int fmax = 515633;
  * @pwrreg_nopower: bits in MMCIPOWER don't controls ext. power supply
  * @mclk_delayed_writes: enable delayed writes to ensure, subsequent updates
  *  are not ignored.
+ * @explicit_mclk_control: enable explicit mclk control in driver.
+ * @cclk_is_mclk: enable iff card clock is multimedia card adapter clock.
  */
 struct variant_data {
unsigned intclkreg;
@@ -94,6 +96,8 @@ struct variant_data {
boolbusy_detect;
boolpwrreg_nopower;
boolmclk_delayed_writes;
+   boolexplicit_mclk_control;
+   boolcclk_is_mclk;
 };
 
 static struct variant_data variant_arm = {
@@ -202,6 +206,8 @@ static struct variant_data variant_qcom = {
 * for 3 clk cycles.
 */
.mclk_delayed_writes= true,
+   .explicit_mclk_control  = true,
+   .cclk_is_mclk   = true,
 };
 
 static inline u32 mmci_readl(struct mmci_host *host, u32 off)
@@ -317,7 +323,9 @@ static void mmci_set_clkreg(struct mmci_host *host, 
unsigned int desired)
host->cclk = 0;
 
if (desired) {
-   if (desired >= host->mclk) {
+   if (variant->cclk_is_mclk) {
+   host->cclk = host->mclk;
+   } else if (desired >= host->mclk) {
clk = MCI_CLK_BYPASS;
if (variant->st_clkdiv)
clk |= MCI_ST_UX500_NEG_EDGE;
@@ -1354,6 +1362,16 @@ static void mmci_set_ios(struct mmc_host *mmc, struct 
mmc_ios *ios)
if (!ios->clock && variant->pwrreg_clkgate)
pwr &= ~MCI_PWR_ON;
 
+   if (ios->clock != host->mclk && host->variant->explicit_mclk_control) {
+   int rc = clk_set_rate(host->clk, ios->clock);
+   if (rc < 0) {
+   dev_err(mmc_dev(host->mmc),
+   "Error setting clock rate (%d)\n", rc);
+   } else {
+   host->mclk = clk_get_rate(host->clk);
+   }
+   }
+
spin_lock_irqsave(&host->lock, flags);
 
mmci_set_clkreg(host, ios->clock);
@@ -1540,10 +1558,12 @@ static int mmci_probe(struct amba_device *dev,
 * is not specified. Either value must not exceed the clock rate into
 * the block, of course.
 */
-   if (mmc->f_max)
-   mmc->f_max = min(host->mclk, mmc->f_max);
-   else
-   mmc->f_max = min(host->mclk, fmax);
+   if (!host->variant->explicit_mclk_control) {
+   if (mmc->f_max)
+   mmc->f_max = min(host->mclk, mmc->f_max);
+   else
+   mmc->f_max = min(host->mclk, fmax);
+   }
dev_dbg(mmc_dev(mmc), "clocking block at %u Hz\n", mmc->f_max);
 
/* Get regulators and the supported OCR mask */
-- 
1.9.1

--
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 v3 10/13] mmc: mmci: add Qcom specifics of clk and datactrl registers.

2014-05-23 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

This patch adds specifics of clk and datactrl register on Qualcomm SD
Card controller. This patch also populates the Qcom variant data with
these new values specific to Qualcomm SD Card Controller.

Signed-off-by: Srinivas Kandagatla 
Reviewed-by: Linus Walleij 
---
 drivers/mmc/host/mmci.c |  4 
 drivers/mmc/host/mmci.h | 24 
 2 files changed, 28 insertions(+)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 17e7f6a..6434f5b1 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -185,6 +185,10 @@ static struct variant_data variant_qcom = {
.fifosize   = 16 * 4,
.fifohalfsize   = 8 * 4,
.clkreg = MCI_CLK_ENABLE,
+   .clkreg_enable  = MCI_QCOM_CLK_FLOWENA |
+ MCI_QCOM_CLK_FEEDBACK_CLK,
+   .clkreg_8bit_bus_enable = MCI_QCOM_CLK_WIDEBUS_8,
+   .datactrl_mask_ddrmode  = MCI_QCOM_CLK_DDR_MODE,
.blksz_datactrl4= true,
.datalength_bits= 24,
.blksz_datactrl4= true,
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h
index cd83ca3..1b93ae7 100644
--- a/drivers/mmc/host/mmci.h
+++ b/drivers/mmc/host/mmci.h
@@ -41,6 +41,22 @@
 /* Modified PL180 on Versatile Express platform */
 #define MCI_ARM_HWFCEN BIT(12)
 
+/* Modified on Qualcomm Integrations */
+#define MCI_QCOM_CLK_WIDEBUS_4 (2 << 10)
+#define MCI_QCOM_CLK_WIDEBUS_8 (3 << 10)
+#define MCI_QCOM_CLK_FLOWENA   BIT(12)
+#define MCI_QCOM_CLK_INVERTOUT BIT(13)
+
+/* select in latch data and command */
+#define MCI_QCOM_CLK_SEL_IN_SHIFT  (14)
+#define MCI_QCOM_CLK_SEL_MASK  (0x3)
+#define MCI_QCOM_CLK_SEL_RISING_EDGE   (1)
+#define MCI_QCOM_CLK_FEEDBACK_CLK  (2 << 14)
+#define MCI_QCOM_CLK_DDR_MODE  (3 << 14)
+
+/* mclk selection */
+#define MCI_QCOM_CLK_SEL_MCLK  (2 << 23)
+
 #define MMCIARGUMENT   0x008
 #define MMCICOMMAND0x00c
 #define MCI_CPSM_RESPONSE  BIT(6)
@@ -54,6 +70,14 @@
 #define MCI_ST_NIENBIT(13)
 #define MCI_ST_CE_ATACMD   BIT(14)
 
+/* Modified on Qualcomm Integrations */
+#define MCI_QCOM_CSPM_DATCMD   BIT(12)
+#define MCI_QCOM_CSPM_MCIABORT BIT(13)
+#define MCI_QCOM_CSPM_CCSENABLEBIT(14)
+#define MCI_QCOM_CSPM_CCSDISABLE   BIT(15)
+#define MCI_QCOM_CSPM_AUTO_CMD19   BIT(16)
+#define MCI_QCOM_CSPM_AUTO_CMD21   BIT(21)
+
 #define MMCIRESPCMD0x010
 #define MMCIRESPONSE0  0x014
 #define MMCIRESPONSE1  0x018
-- 
1.9.1

--
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 v3 05/13] mmc: mmci: Add register read/write wrappers.

2014-05-23 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

This patch adds wrappers for readl/writel functions used in the driver. The
reason for this wrappers is to accommodate SOCs like Qualcomm which has
requirement for delaying the write for few cycles when writing to its SD Card
Controller registers.

Signed-off-by: Srinivas Kandagatla 
Reviewed-by: Linus Walleij 
---
 drivers/mmc/host/mmci.c | 110 ++--
 1 file changed, 59 insertions(+), 51 deletions(-)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 324a886..881bb24 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -173,6 +173,16 @@ static struct variant_data variant_qcom = {
.pwrreg_powerup = MCI_PWR_UP,
 };
 
+static inline u32 mmci_readl(struct mmci_host *host, u32 off)
+{
+   return readl(host->base  + off);
+}
+
+static inline void mmci_writel(struct mmci_host *host, u32 data, u32 off)
+{
+   writel(data, host->base + off);
+}
+
 static int mmci_card_busy(struct mmc_host *mmc)
 {
struct mmci_host *host = mmc_priv(mmc);
@@ -182,7 +192,7 @@ static int mmci_card_busy(struct mmc_host *mmc)
pm_runtime_get_sync(mmc_dev(mmc));
 
spin_lock_irqsave(&host->lock, flags);
-   if (readl(host->base + MMCISTATUS) & MCI_ST_CARDBUSY)
+   if (mmci_readl(host, MMCISTATUS) & MCI_ST_CARDBUSY)
busy = 1;
spin_unlock_irqrestore(&host->lock, flags);
 
@@ -232,7 +242,7 @@ static void mmci_write_clkreg(struct mmci_host *host, u32 
clk)
 {
if (host->clk_reg != clk) {
host->clk_reg = clk;
-   writel(clk, host->base + MMCICLOCK);
+   mmci_writel(host, clk, MMCICLOCK);
}
 }
 
@@ -243,7 +253,7 @@ static void mmci_write_pwrreg(struct mmci_host *host, u32 
pwr)
 {
if (host->pwr_reg != pwr) {
host->pwr_reg = pwr;
-   writel(pwr, host->base + MMCIPOWER);
+   mmci_writel(host, pwr, MMCIPOWER);
}
 }
 
@@ -257,7 +267,7 @@ static void mmci_write_datactrlreg(struct mmci_host *host, 
u32 datactrl)
 
if (host->datactrl_reg != datactrl) {
host->datactrl_reg = datactrl;
-   writel(datactrl, host->base + MMCIDATACTRL);
+   mmci_writel(host, datactrl, MMCIDATACTRL);
}
 }
 
@@ -323,7 +333,7 @@ static void mmci_set_clkreg(struct mmci_host *host, 
unsigned int desired)
 static void
 mmci_request_end(struct mmci_host *host, struct mmc_request *mrq)
 {
-   writel(0, host->base + MMCICOMMAND);
+   mmci_writel(host, 0, MMCICOMMAND);
 
BUG_ON(host->data);
 
@@ -338,18 +348,16 @@ mmci_request_end(struct mmci_host *host, struct 
mmc_request *mrq)
 
 static void mmci_set_mask1(struct mmci_host *host, unsigned int mask)
 {
-   void __iomem *base = host->base;
-
if (host->singleirq) {
-   unsigned int mask0 = readl(base + MMCIMASK0);
+   unsigned int mask0 = mmci_readl(host, MMCIMASK0);
 
mask0 &= ~MCI_IRQ1MASK;
mask0 |= mask;
 
-   writel(mask0, base + MMCIMASK0);
+   mmci_writel(host, mask0, MMCIMASK0);
}
 
-   writel(mask, base + MMCIMASK1);
+   mmci_writel(host, mask, MMCIMASK1);
 }
 
 static void mmci_stop_data(struct mmci_host *host)
@@ -478,7 +486,7 @@ static void mmci_dma_finalize(struct mmci_host *host, 
struct mmc_data *data)
 
/* Wait up to 1ms for the DMA to complete */
for (i = 0; ; i++) {
-   status = readl(host->base + MMCISTATUS);
+   status = mmci_readl(host, MMCISTATUS);
if (!(status & MCI_RXDATAAVLBLMASK) || i >= 100)
break;
udelay(10);
@@ -617,8 +625,8 @@ static int mmci_dma_start_data(struct mmci_host *host, 
unsigned int datactrl)
 * to fire next DMA request. When that happens, MMCI will
 * call mmci_data_end()
 */
-   writel(readl(host->base + MMCIMASK0) | MCI_DATAENDMASK,
-  host->base + MMCIMASK0);
+   mmci_writel(host, mmci_readl(host, MMCIMASK0) | MCI_DATAENDMASK,
+   MMCIMASK0);
return 0;
 }
 
@@ -736,8 +744,8 @@ static void mmci_start_data(struct mmci_host *host, struct 
mmc_data *data)
timeout = data->timeout_clks + (unsigned int)clks;
 
base = host->base;
-   writel(timeout, base + MMCIDATATIMER);
-   writel(host->size, base + MMCIDATALENGTH);
+   mmci_writel(host, timeout, MMCIDATATIMER);
+   mmci_writel(host, host->size, MMCIDATALENGTH);
 
blksz_bits = ffs(data->blksz) - 1;
BUG_ON(1 << blksz_bits != data->blksz);
@@ -811,20 +819,19 @@ static void mmci_start_data(struct mmci_host *host, 
struct mmc_data *data)
}
 
mmci_write_datactrlreg(host, datactrl);
-   writel(readl(base + MMCIMASK

[PATCH v3 09/13] mmc: mmci: add edge support to data and command out in variant data.

2014-05-23 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

This patch adds edge support for data and command out to variant structure
giving more flexibility to the driver to support more SOCs which have
different clock register layout.

Without this patch other new SOCs like Qcom will have to add more code to
special case them

Signed-off-by: Srinivas Kandagatla 
Reviewed-by: Linus Walleij 
---
 drivers/mmc/host/mmci.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index a81f303..17e7f6a 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -53,6 +53,7 @@ static unsigned int fmax = 515633;
  * @clkreg: default value for MCICLOCK register
  * @clkreg_enable: enable value for MMCICLOCK register
  * @clkreg_8bit_bus_enable: enable value for 8 bit bus
+ * @clkreg_neg_edge_enable: enable value for inverted data/cmd output
  * @datalength_bits: number of bits in the MMCIDATALENGTH register
  * @fifosize: number of bytes that can be written when MMCI_TXFIFOEMPTY
  *   is asserted (likewise for RX)
@@ -76,6 +77,7 @@ struct variant_data {
unsigned intclkreg;
unsigned intclkreg_enable;
unsigned intclkreg_8bit_bus_enable;
+   unsigned intclkreg_neg_edge_enable;
unsigned intdatalength_bits;
unsigned intfifosize;
unsigned intfifohalfsize;
@@ -148,6 +150,7 @@ static struct variant_data variant_ux500 = {
.clkreg = MCI_CLK_ENABLE,
.clkreg_enable  = MCI_ST_UX500_HWFCEN,
.clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS,
+   .clkreg_neg_edge_enable = MCI_ST_UX500_NEG_EDGE,
.datactrl_mask_ddrmode  = MCI_ST_DPSM_DDRMODE,
.datalength_bits= 24,
.sdio   = true,
@@ -165,6 +168,7 @@ static struct variant_data variant_ux500v2 = {
.clkreg = MCI_CLK_ENABLE,
.clkreg_enable  = MCI_ST_UX500_HWFCEN,
.clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS,
+   .clkreg_neg_edge_enable = MCI_ST_UX500_NEG_EDGE,
.datactrl_mask_ddrmode  = MCI_ST_DPSM_DDRMODE,
.datalength_bits= 24,
.sdio   = true,
@@ -348,7 +352,7 @@ static void mmci_set_clkreg(struct mmci_host *host, 
unsigned int desired)
clk |= variant->clkreg_8bit_bus_enable;
 
if (host->mmc->ios.timing == MMC_TIMING_UHS_DDR50)
-   clk |= MCI_ST_UX500_NEG_EDGE;
+   clk |= variant->clkreg_neg_edge_enable;
 
mmci_write_clkreg(host, clk);
 }
-- 
1.9.1

--
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 v3 06/13] mmc: mmci: Qcomm: Add 3 clock cycle delay after register write

2014-05-23 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

Most of the Qcomm SD card controller registers must be updated to the MCLK
domain so subsequent writes to registers will be ignored until 3 clock cycles
have passed.

This patch adds a 3 clock cycle delay required after writing to controller
registers on Qualcomm SOCs. Without this delay all the register writes are not
successful, resulting in not detecting cards. The write clock delay is
activated by setting up mclk_delayed_writes variable in variant data.

Signed-off-by: Srinivas Kandagatla 
Reviewed-by: Linus Walleij 
---
 drivers/mmc/host/mmci.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 881bb24..1385554 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -67,6 +67,8 @@ static unsigned int fmax = 515633;
  * @pwrreg_clkgate: MMCIPOWER register must be used to gate the clock
  * @busy_detect: true if busy detection on dat0 is supported
  * @pwrreg_nopower: bits in MMCIPOWER don't controls ext. power supply
+ * @mclk_delayed_writes: enable delayed writes to ensure, subsequent updates
+ *  are not ignored.
  */
 struct variant_data {
unsigned intclkreg;
@@ -83,6 +85,7 @@ struct variant_data {
boolpwrreg_clkgate;
boolbusy_detect;
boolpwrreg_nopower;
+   boolmclk_delayed_writes;
 };
 
 static struct variant_data variant_arm = {
@@ -171,6 +174,12 @@ static struct variant_data variant_qcom = {
.datalength_bits= 24,
.blksz_datactrl4= true,
.pwrreg_powerup = MCI_PWR_UP,
+   /*
+* On QCom SD card controller, registers must be updated to the
+* MCLK domain so subsequent writes to this register will be ignored
+* for 3 clk cycles.
+*/
+   .mclk_delayed_writes= true,
 };
 
 static inline u32 mmci_readl(struct mmci_host *host, u32 off)
@@ -181,6 +190,9 @@ static inline u32 mmci_readl(struct mmci_host *host, u32 
off)
 static inline void mmci_writel(struct mmci_host *host, u32 data, u32 off)
 {
writel(data, host->base + off);
+
+   if (host->variant->mclk_delayed_writes)
+   udelay(DIV_ROUND_UP((3 * USEC_PER_SEC), host->mclk));
 }
 
 static int mmci_card_busy(struct mmc_host *mmc)
-- 
1.9.1

--
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 v3 08/13] mmc: mmci: add 8bit bus support in variant data

2014-05-23 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

This patch adds 8bit bus enable to variant structure giving more flexibility
to the driver to support more SOCs which have different clock register layout.

Without this patch other new SOCs like Qcom will have to add more code
to special case them.

Signed-off-by: Srinivas Kandagatla 
Reviewed-by: Linus Walleij 
---
 drivers/mmc/host/mmci.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index dec70d2..a81f303 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -52,6 +52,7 @@ static unsigned int fmax = 515633;
  * struct variant_data - MMCI variant-specific quirks
  * @clkreg: default value for MCICLOCK register
  * @clkreg_enable: enable value for MMCICLOCK register
+ * @clkreg_8bit_bus_enable: enable value for 8 bit bus
  * @datalength_bits: number of bits in the MMCIDATALENGTH register
  * @fifosize: number of bytes that can be written when MMCI_TXFIFOEMPTY
  *   is asserted (likewise for RX)
@@ -74,6 +75,7 @@ static unsigned int fmax = 515633;
 struct variant_data {
unsigned intclkreg;
unsigned intclkreg_enable;
+   unsigned intclkreg_8bit_bus_enable;
unsigned intdatalength_bits;
unsigned intfifosize;
unsigned intfifohalfsize;
@@ -116,6 +118,7 @@ static struct variant_data variant_u300 = {
.fifosize   = 16 * 4,
.fifohalfsize   = 8 * 4,
.clkreg_enable  = MCI_ST_U300_HWFCEN,
+   .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS,
.datactrl_mask_ddrmode  = MCI_ST_DPSM_DDRMODE,
.datalength_bits= 16,
.sdio   = true,
@@ -144,6 +147,7 @@ static struct variant_data variant_ux500 = {
.fifohalfsize   = 8 * 4,
.clkreg = MCI_CLK_ENABLE,
.clkreg_enable  = MCI_ST_UX500_HWFCEN,
+   .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS,
.datactrl_mask_ddrmode  = MCI_ST_DPSM_DDRMODE,
.datalength_bits= 24,
.sdio   = true,
@@ -160,6 +164,7 @@ static struct variant_data variant_ux500v2 = {
.fifohalfsize   = 8 * 4,
.clkreg = MCI_CLK_ENABLE,
.clkreg_enable  = MCI_ST_UX500_HWFCEN,
+   .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS,
.datactrl_mask_ddrmode  = MCI_ST_DPSM_DDRMODE,
.datalength_bits= 24,
.sdio   = true,
@@ -340,7 +345,7 @@ static void mmci_set_clkreg(struct mmci_host *host, 
unsigned int desired)
if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_4)
clk |= MCI_4BIT_BUS;
if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_8)
-   clk |= MCI_ST_8BIT_BUS;
+   clk |= variant->clkreg_8bit_bus_enable;
 
if (host->mmc->ios.timing == MMC_TIMING_UHS_DDR50)
clk |= MCI_ST_UX500_NEG_EDGE;
-- 
1.9.1

--
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 v3 04/13] mmc: mmci: Add Qcom datactrl register variant

2014-05-23 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

Instance of this IP on Qualcomm's SOCs has bit different layout for datactrl
register. Bit position datactrl[16:4] hold the true block size instead of power
of 2.

Signed-off-by: Srinivas Kandagatla 
Reviewed-by: Linus Walleij 
---
 drivers/mmc/host/mmci.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 7bdf4d3..324a886 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -60,6 +60,8 @@ static unsigned int fmax = 515633;
  * @sdio: variant supports SDIO
  * @st_clkdiv: true if using a ST-specific clock divider algorithm
  * @blksz_datactrl16: true if Block size is at b16..b30 position in datactrl 
register
+ * @blksz_datactrl4: true if Block size is at b4..b16 position in datactrl
+ *  register
  * @pwrreg_powerup: power up value for MMCIPOWER register
  * @signal_direction: input/out direction of bus signals can be indicated
  * @pwrreg_clkgate: MMCIPOWER register must be used to gate the clock
@@ -75,6 +77,7 @@ struct variant_data {
boolsdio;
boolst_clkdiv;
boolblksz_datactrl16;
+   boolblksz_datactrl4;
u32 pwrreg_powerup;
boolsignal_direction;
boolpwrreg_clkgate;
@@ -164,6 +167,7 @@ static struct variant_data variant_qcom = {
.fifosize   = 16 * 4,
.fifohalfsize   = 8 * 4,
.clkreg = MCI_CLK_ENABLE,
+   .blksz_datactrl4= true,
.datalength_bits= 24,
.blksz_datactrl4= true,
.pwrreg_powerup = MCI_PWR_UP,
@@ -740,6 +744,8 @@ static void mmci_start_data(struct mmci_host *host, struct 
mmc_data *data)
 
if (variant->blksz_datactrl16)
datactrl = MCI_DPSM_ENABLE | (data->blksz << 16);
+   else if (variant->blksz_datactrl4)
+   datactrl = MCI_DPSM_ENABLE | (data->blksz << 4);
else
datactrl = MCI_DPSM_ENABLE | blksz_bits << 4;
 
-- 
1.9.1

--
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 v3 03/13] mmc: mmci: Add Qualcomm Id to amba id table

2014-05-26 Thread Srinivas Kandagatla

Hi Ulf,

On 26/05/14 10:10, Ulf Hansson wrote:

Hi Srinivas,



+static struct variant_data variant_qcom = {
+   .fifosize   = 16 * 4,
+   .fifohalfsize   = 8 * 4,
+   .clkreg = MCI_CLK_ENABLE,
+   .datalength_bits= 24,
+   .blksz_datactrl4= true,


You get compile error here.
yes, You are right, I will reorder this patch after the "mmc: mmci: Add 
Qcom datactrl register variant"



Thanks,
srini


Kind regards
Ulf Hansson


--
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 v3 06/13] mmc: mmci: Qcomm: Add 3 clock cycle delay after register write

2014-05-26 Thread Srinivas Kandagatla




I am not sure I like this approach. For each and every writel
(including pio_writes) you will add a few cpu cycles, since you need
to  check for "mclk_delayed_writes" no matter of variant.




How about, adding a new function pointer in the struct mmci_host, for
"writel operations" which you could set up in probe phase instead?



Yes, this is an additional check for other variants. I will try the 
function pointer method that you suggested.


Thanks,
srini



Kind regards
Ulf Hansson


--
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 v3 07/13] mmc: mmci: add ddrmode mask to variant data

2014-05-26 Thread Srinivas Kandagatla



On 26/05/14 10:53, Ulf Hansson wrote:

On 23 May 2014 14:51,   wrote:

From: Srinivas Kandagatla 

This patch adds ddrmode mask to variant structure giving more flexibility
to the driver to support more SOCs which have different datactrl register
layout.

Without this patch datactrl register is updated with wrong ddrmode mask on non
ST SOCs, resulting in card detection failures.

Signed-off-by: Srinivas Kandagatla 
Reviewed-by: Linus Walleij 
---
  drivers/mmc/host/mmci.c | 8 +++-
  1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 1385554..dec70d2 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -59,6 +59,7 @@ static unsigned int fmax = 515633;
   *   is asserted (likewise for RX)
   * @sdio: variant supports SDIO
   * @st_clkdiv: true if using a ST-specific clock divider algorithm
+ * @datactrl_mask_ddrmode: ddr mode mask in datactrl register.
   * @blksz_datactrl16: true if Block size is at b16..b30 position in datactrl 
register
   * @blksz_datactrl4: true if Block size is at b4..b16 position in datactrl
   *  register
@@ -76,6 +77,7 @@ struct variant_data {
 unsigned intdatalength_bits;
 unsigned intfifosize;
 unsigned intfifohalfsize;
+   unsigned intdatactrl_mask_ddrmode;
 boolsdio;
 boolst_clkdiv;
 boolblksz_datactrl16;
@@ -114,6 +116,7 @@ static struct variant_data variant_u300 = {
 .fifosize   = 16 * 4,
 .fifohalfsize   = 8 * 4,
 .clkreg_enable  = MCI_ST_U300_HWFCEN,
+   .datactrl_mask_ddrmode  = MCI_ST_DPSM_DDRMODE,
 .datalength_bits= 16,
 .sdio   = true,
 .pwrreg_powerup = MCI_PWR_ON,
@@ -126,6 +129,7 @@ static struct variant_data variant_nomadik = {
 .fifosize   = 16 * 4,
 .fifohalfsize   = 8 * 4,
 .clkreg = MCI_CLK_ENABLE,
+   .datactrl_mask_ddrmode  = MCI_ST_DPSM_DDRMODE,
 .datalength_bits= 24,
 .sdio   = true,
 .st_clkdiv  = true,
@@ -140,6 +144,7 @@ static struct variant_data variant_ux500 = {
 .fifohalfsize   = 8 * 4,
 .clkreg = MCI_CLK_ENABLE,
 .clkreg_enable  = MCI_ST_UX500_HWFCEN,
+   .datactrl_mask_ddrmode  = MCI_ST_DPSM_DDRMODE,
 .datalength_bits= 24,
 .sdio   = true,
 .st_clkdiv  = true,
@@ -155,6 +160,7 @@ static struct variant_data variant_ux500v2 = {
 .fifohalfsize   = 8 * 4,
 .clkreg = MCI_CLK_ENABLE,
 .clkreg_enable  = MCI_ST_UX500_HWFCEN,
+   .datactrl_mask_ddrmode  = MCI_ST_DPSM_DDRMODE,


Only the ux500v2 supports DDR mode, using the MCI_ST_DPSM_DDRMODE bit.


Thanks for pointing this out, I was not sure which variants actually 
used this bit, so just replicated what was there before this change.


I will add this flag to only ux500v2 in next version.


Thanks,
srini



 .datalength_bits= 24,
 .sdio   = true,
 .st_clkdiv  = true,
@@ -800,7 +806,7 @@ static void mmci_start_data(struct mmci_host *host, struct 
mmc_data *data)
 }

 if (host->mmc->ios.timing == MMC_TIMING_UHS_DDR50)
-   datactrl |= MCI_ST_DPSM_DDRMODE;
+   datactrl |= variant->datactrl_mask_ddrmode;

 /*
  * Attempt to use DMA operation mode, if this
--
1.9.1



Kind regards
Ulf Hansson


--
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 v3 13/13] mmc: mmci: Add Qcom specific pio_read function.

2014-05-26 Thread Srinivas Kandagatla



On 26/05/14 15:34, Ulf Hansson wrote:

This is hot path.

As I suggested for the readl and writel wrapper functions, I think it
would be better to use a function pointer in the struct mmci host,
which you set up in the probe phase. That means the variant data don't
need to be checked each an every time this function gets invoked.


>+
> if (status & MCI_TXACTIVE)
> len = mmci_pio_write(host, buffer, remain, status);

So no changes needed for pio_write at this point? Or those will come later?



Yes, that sounds like more sensible approach to me. I will do this 
change in next version.


Thanks,
srini

>
>--

--
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 v3 10/13] mmc: mmci: add Qcom specifics of clk and datactrl registers.

2014-05-26 Thread Srinivas Kandagatla

Hi Ulf,

Thanks for the comments.

On 26/05/14 14:05, Ulf Hansson wrote:

On 23 May 2014 14:52,   wrote:

From: Srinivas Kandagatla 

This patch adds specifics of clk and datactrl register on Qualcomm SD
Card controller. This patch also populates the Qcom variant data with
these new values specific to Qualcomm SD Card Controller.

Signed-off-by: Srinivas Kandagatla 
Reviewed-by: Linus Walleij 
---
  drivers/mmc/host/mmci.c |  4 
  drivers/mmc/host/mmci.h | 24 
  2 files changed, 28 insertions(+)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 17e7f6a..6434f5b1 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -185,6 +185,10 @@ static struct variant_data variant_qcom = {
 .fifosize   = 16 * 4,
 .fifohalfsize   = 8 * 4,
 .clkreg = MCI_CLK_ENABLE,
+   .clkreg_enable  = MCI_QCOM_CLK_FLOWENA |
+ MCI_QCOM_CLK_FEEDBACK_CLK,


Obviously I don't have the in-depth knowledge about the Qcom variant,
but comparing the ST variant here made me think.

Using the feeback clock internal logic in the ST variant, requires the
corresponding feedback clock pin signal on the board, to be
routed/connected. Typically we used this for SD cards, which involved
using an external level shifter circuit.

Is it correct to enable this bit for all cases, including eMMC?

You are correct, FBCLK should specific to the board, and I will try to 
do something on the same lines as ST variant in next version.



If it is board specific configurations, you should add a DT binding
for it - like there are for the ST variant.


+   .clkreg_8bit_bus_enable = MCI_QCOM_CLK_WIDEBUS_8,
+   .datactrl_mask_ddrmode  = MCI_QCOM_CLK_DDR_MODE,
 .blksz_datactrl4= true,
 .datalength_bits= 24,
 .blksz_datactrl4= true,
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h
index cd83ca3..1b93ae7 100644
--- a/drivers/mmc/host/mmci.h
+++ b/drivers/mmc/host/mmci.h
@@ -41,6 +41,22 @@
  /* Modified PL180 on Versatile Express platform */
  #define MCI_ARM_HWFCEN BIT(12)

+/* Modified on Qualcomm Integrations */
+#define MCI_QCOM_CLK_WIDEBUS_4 (2 << 10)


This is the same as BIT(11), please use MCI_4BIT_BUS instead.

This is not used in the code, I will clean it up as you suggested, just 
to be more consistent.



+#define MCI_QCOM_CLK_WIDEBUS_8 (3 << 10)


Since you converted to use the "BIT" macro a few patches ago, I
suggest we should stick to it. How about something below:

#define MCI_QCOM_CLK_WIDEBUS_8 BIT (BIT(10) | BIT(11))


Sounds good, I will fix all such instances in next version.


Please adopt all defines added in this patch to use the BIT macro.


+#define MCI_QCOM_CLK_FLOWENA   BIT(12)
+#define MCI_QCOM_CLK_INVERTOUT BIT(13)
+
+/* select in latch data and command */
+#define MCI_QCOM_CLK_SEL_IN_SHIFT  (14)


BIT (14)?


+#define MCI_QCOM_CLK_SEL_MASK  (0x3)
+#define MCI_QCOM_CLK_SEL_RISING_EDGE   (1)


BIT(1)?


+#define MCI_QCOM_CLK_FEEDBACK_CLK  (2 << 14)
+#define MCI_QCOM_CLK_DDR_MODE  (3 << 14)
+
+/* mclk selection */
+#define MCI_QCOM_CLK_SEL_MCLK  (2 << 23)


Does this correspond to MCI_CLK_BYPASS? If so, we should maybe state
this in a comment?

No, this is not same as MCI_CLK_BYPASS, its selection between 
FBCLK/gated MCLK/freerunning MCLK.


Thanks,
srini
--
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 v3 12/13] mmc: mmci: add explicit clk control

2014-05-26 Thread Srinivas Kandagatla

Hi Ulf,
Thankyou for the comments.

On 26/05/14 15:21, Ulf Hansson wrote:

On 23 May 2014 14:52,   wrote:

From: Srinivas Kandagatla 

On Controllers like Qcom SD card controller where cclk is mclk and mclk should
be directly controlled by the driver.

This patch adds support to control mclk directly in the driver, and also
adds explicit_mclk_control and cclk_is_mclk flags in variant structure giving
more flexibility to the driver.

Signed-off-by: Srinivas Kandagatla 
Reviewed-by: Linus Walleij 
---
  drivers/mmc/host/mmci.c | 30 +-
  1 file changed, 25 insertions(+), 5 deletions(-)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 5cbf644..f6dfd24 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -73,6 +73,8 @@ static unsigned int fmax = 515633;
   * @pwrreg_nopower: bits in MMCIPOWER don't controls ext. power supply
   * @mclk_delayed_writes: enable delayed writes to ensure, subsequent updates
   *  are not ignored.
+ * @explicit_mclk_control: enable explicit mclk control in driver.
+ * @cclk_is_mclk: enable iff card clock is multimedia card adapter clock.
   */
  struct variant_data {
 unsigned intclkreg;
@@ -94,6 +96,8 @@ struct variant_data {
 boolbusy_detect;
 boolpwrreg_nopower;
 boolmclk_delayed_writes;
+   boolexplicit_mclk_control;
+   boolcclk_is_mclk;


I can't see why you need to have both these new configurations. Aren't
"cclk_is_mclk" just a fact when you use "explicit_mclk_control".





I also believe I would prefer something like "qcom_clkdiv" instead.


There is a subtle difference between both the flags.  Am happy to change 
it to qcom_clkdiv.





  };

  static struct variant_data variant_arm = {
@@ -202,6 +206,8 @@ static struct variant_data variant_qcom = {
  * for 3 clk cycles.
  */
 .mclk_delayed_writes= true,
+   .explicit_mclk_control  = true,
+   .cclk_is_mclk   = true,
  };

  static inline u32 mmci_readl(struct mmci_host *host, u32 off)
@@ -317,7 +323,9 @@ static void mmci_set_clkreg(struct mmci_host *host, 
unsigned int desired)
 host->cclk = 0;

 if (desired) {
-   if (desired >= host->mclk) {
+   if (variant->cclk_is_mclk) {
+   host->cclk = host->mclk;
+   } else if (desired >= host->mclk) {
 clk = MCI_CLK_BYPASS;
 if (variant->st_clkdiv)
 clk |= MCI_ST_UX500_NEG_EDGE;
@@ -1354,6 +1362,16 @@ static void mmci_set_ios(struct mmc_host *mmc, struct 
mmc_ios *ios)
 if (!ios->clock && variant->pwrreg_clkgate)
 pwr &= ~MCI_PWR_ON;

+   if (ios->clock != host->mclk && host->variant->explicit_mclk_control) {


I suggest you should clarify the statement by adding a pair of extra
parentheses. Additionally it seems like a good idea to reverse the
order of the statements, to clarify this is for qcom clock handling
only.

Yes, sure Will fix this in next version.



More important, what I think you really want to do is to compare
"ios->clock" with it's previous value it had when ->set_ios were
invoked. Then let a changed value act as the trigger to set a new clk
rate. Obvoiusly you need to cache the clock rate in the struct mmci
host to handle this.


host->mclk already has this cached value.




+   int rc = clk_set_rate(host->clk, ios->clock);
+   if (rc < 0) {
+   dev_err(mmc_dev(host->mmc),
+   "Error setting clock rate (%d)\n", rc);
+   } else {
+   host->mclk = clk_get_rate(host->clk);


So here you actually find out the new clk rate, but shouldn't you
update "host->mclk" within the spin_lock? Or it might not matter?

I think it does not matter in this case, as this is the only place mclk 
gets modified.

+   }
+   }
+
 spin_lock_irqsave(&host->lock, flags);

 mmci_set_clkreg(host, ios->clock);
@@ -1540,10 +1558,12 @@ static int mmci_probe(struct amba_device *dev,
  * is not specified. Either value must not exceed the clock rate into
  * the block, of course.
  */
-   if (mmc->f_max)
-   mmc->f_max = min(host->mclk, mmc->f_max);
-   else
-   mmc->f_max = min(host->mclk, fmax);
+   if (!host->variant->explicit_mclk_control) {
+   if (mmc->f_max)
+   mmc->f_max = min(host->mclk, mmc->f_max);
+   else
+   mmc->f_max = min(host->mclk, fmax);
+ 

Re: [PATCH v3 12/13] mmc: mmci: add explicit clk control

2014-05-27 Thread Srinivas Kandagatla



On 27/05/14 10:32, Ulf Hansson wrote:

On 27 May 2014 00:39, Srinivas Kandagatla
 wrote:

Hi Ulf,
Thankyou for the comments.


On 26/05/14 15:21, Ulf Hansson wrote:


On 23 May 2014 14:52,   wrote:


From: Srinivas Kandagatla 

On Controllers like Qcom SD card controller where cclk is mclk and mclk
should
be directly controlled by the driver.


...


   * for 3 clk cycles.
   */
  .mclk_delayed_writes= true,
+   .explicit_mclk_control  = true,
+   .cclk_is_mclk   = true,
   };

   static inline u32 mmci_readl(struct mmci_host *host, u32 off)
@@ -317,7 +323,9 @@ static void mmci_set_clkreg(struct mmci_host *host,
unsigned int desired)
  host->cclk = 0;

  if (desired) {
-   if (desired >= host->mclk) {
+   if (variant->cclk_is_mclk) {
+   host->cclk = host->mclk;
+   } else if (desired >= host->mclk) {
  clk = MCI_CLK_BYPASS;
  if (variant->st_clkdiv)
  clk |= MCI_ST_UX500_NEG_EDGE;
@@ -1354,6 +1362,16 @@ static void mmci_set_ios(struct mmc_host *mmc,
struct mmc_ios *ios)
  if (!ios->clock && variant->pwrreg_clkgate)
  pwr &= ~MCI_PWR_ON;

+   if (ios->clock != host->mclk &&
host->variant->explicit_mclk_control) {



I suggest you should clarify the statement by adding a pair of extra
parentheses. Additionally it seems like a good idea to reverse the
order of the statements, to clarify this is for qcom clock handling
only.


Yes, sure Will fix this in next version.




More important, what I think you really want to do is to compare
"ios->clock" with it's previous value it had when ->set_ios were
invoked. Then let a changed value act as the trigger to set a new clk
rate. Obvoiusly you need to cache the clock rate in the struct mmci
host to handle this.



host->mclk already has this cached value.


There are no guarantees clk_set_rate() will manage to set the exact
requested rate as ios->clock. At least if you follow the clk API
documentation.



Yes, I agree. caching ios->clock looks like the best option.








...




+   }
+   }
+
  spin_lock_irqsave(&host->lock, flags);

  mmci_set_clkreg(host, ios->clock);
@@ -1540,10 +1558,12 @@ static int mmci_probe(struct amba_device *dev,
   * is not specified. Either value must not exceed the clock rate
into
   * the block, of course.
   */
-   if (mmc->f_max)
-   mmc->f_max = min(host->mclk, mmc->f_max);
-   else
-   mmc->f_max = min(host->mclk, fmax);
+   if (!host->variant->explicit_mclk_control) {
+   if (mmc->f_max)
+   mmc->f_max = min(host->mclk, mmc->f_max);
+   else
+   mmc->f_max = min(host->mclk, fmax);
+   }



This means your mmc->f_max value will either be zero or the one you
provided through DT. And since zero won't work, that means you
_require_ to get the value from DT. According to the documentation of
this DT binding, f_max is optional.

So unless you fine another way of dynamically at runtime figure out
the value of f_max (using the clk API), you need to update the DT
documentation for mmci.



You are right there is a possibility of f_max to be zero.

This logic could fix it.

if (host->variant->explicit_mclk_control) {
 if (mmc->f_max)
 mmc->f_max = max(host->mclk, mmc->f_max);
 else
 mmc->f_max = max(host->mclk, fmax);
} else {
 if (mmc->f_max)

 mmc->f_max = min(host->mclk, mmc->f_max);
 else

 mmc->f_max = min(host->mclk, fmax);
}



Hmm. Looking a bit deeper into this, we have some additional related
code to fixup. :-)

In ->probe(), we do clk_set_rate(100MHz), if the mclk > 100MHz. That's
due to the current variants don't support higher frequency than this.
It seems like the Qcom variant may support up to 208MHz? Now, if
that's the case, we need to add "f_max" to the struct variant_data to
store this information, so we can respect different values while doing
clk_set_rate() at ->probe().


Yes, qcom SOCs support more than 100Hhz clock.

Probe and clk_set_rate/set_ios should respect this.

On the other thought, Should probe actually care about clocks which are 
explicitly controlled? It should not even attempt to set any frequency 
to start with. mmc-core would set the right frequency depending on the 
mmc state-machine respecting f_min and f_max.
I think for qcom, probe should just check the if f_max and f_min are 
valid and set them to defaults if any in the same lines as existing code.



While updating mmc->f_max for host->varia

Re: [PATCH v3 03/13] mmc: mmci: Add Qualcomm Id to amba id table

2014-05-27 Thread Srinivas Kandagatla



On 26/05/14 18:00, Srinivas Kandagatla wrote:

Hi Ulf,

On 26/05/14 10:10, Ulf Hansson wrote:

Hi Srinivas,



+static struct variant_data variant_qcom = {
+   .fifosize   = 16 * 4,
+   .fifohalfsize   = 8 * 4,
+   .clkreg = MCI_CLK_ENABLE,
+   .datalength_bits= 24,
+   .blksz_datactrl4= true,


You get compile error here.

yes, You are right, I will reorder this patch after the "mmc: mmci: Add
Qcom datactrl register variant"


Actually, blksz_datactrl4 should not be in this patch. it is part of 
"mmc: mmci: Add Qcom datactrl register variant"  will remove it from 
this patch in next version.


--srini



Thanks,
srini


Kind regards
Ulf Hansson


--
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 v3 12/13] mmc: mmci: add explicit clk control

2014-05-27 Thread Srinivas Kandagatla



On 27/05/14 15:07, Ulf Hansson wrote:

Hmm. Looking a bit deeper into this, we have some additional related
code to fixup. :-)

In ->probe(), we do clk_set_rate(100MHz), if the mclk > 100MHz. That's
due to the current variants don't support higher frequency than this.
It seems like the Qcom variant may support up to 208MHz? Now, if
that's the case, we need to add "f_max" to the struct variant_data to
store this information, so we can respect different values while doing
clk_set_rate() at ->probe().


Yes, qcom SOCs support more than 100Hhz clock.

Probe and clk_set_rate/set_ios should respect this.

On the other thought, Should probe actually care about clocks which are
explicitly controlled? It should not even attempt to set any frequency to
start with.


The 100 MHz is related to constraints set by the specification of the
IP block, not the MMC/SD/SDIO spec.

Thus at ->probe() we must perform the clk_set_rate().

I agree its valid for controllers which have this constraints.




mmc-core would set the right frequency depending on the mmc
state-machine respecting f_min and f_max.
I think for qcom, probe should just check the if f_max and f_min are valid
and set them to defaults if any in the same lines as existing code.



While updating mmc->f_max for host->variant->explicit_mclk_control, we
shouldn't care about using the host->mclk as a limiter, instead, use
min(mmc->f_max, host->variant->f_max) and fallback to fmax.


Yes, that's correct, mclk should not be used as limiter. Adding f_max to the
variant looks useful.



Not sure how that will affect the logic. :-)





Additionally, this makes me wonder about f_min. I haven't seen
anywhere in this patch were that value is being set to proper value,
right?



f_min should be 40 for qcom, I think with the default mclk frequency
and
a divider of 512 used for calculating the f_min is bringing down the
f_min
to lessthan 400Kz. Which is why its working fine.
I think the possibility of mclk default frequency being greater than
208Mhz
is very less. so I could either leave it as it is Or force this to 40
all the time for qcom chips.



No, this seems like a wrong approach.

I think you would like to do use the clk_round_rate() find out the
lowest possible rate. Or just use a fixed fallback value somehow.



clk_round_rate(mclk, 0) might be more generic, instead of fixed fallback.
Let the mmc-core figure out what frequency would be best from its table
starting from f_min.


Agree!

clk_round_rate(mclk, 100KHz), might be better though - since that is
actually the lowest request frequency whatsoever.


Perfect.

--srini

Kind regards
Ulf Hansson


--
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 v3 08/13] mmc: mmci: add 8bit bus support in variant data

2014-05-28 Thread Srinivas Kandagatla

Hi Linus W,


On 26/05/14 11:07, Ulf Hansson wrote:

 unsigned intfifosize;
> unsigned intfifohalfsize;
>@@ -116,6 +118,7 @@ static struct variant_data variant_u300 = {
> .fifosize   = 16 * 4,
> .fifohalfsize   = 8 * 4,
> .clkreg_enable  = MCI_ST_U300_HWFCEN,
>+   .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS,

Linus, will have to confirm this. I don't know if the u300 variant
support 8-bit.



Do you know if u300 supports 8BIT bus?

thanks,
srini


Kind regards
Ulf Hansson


--
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 v3 12/13] mmc: mmci: add explicit clk control

2014-05-28 Thread Srinivas Kandagatla



On 28/05/14 09:02, Linus Walleij wrote:

On Tue, May 27, 2014 at 12:39 AM, Srinivas Kandagatla
 wrote:

On 26/05/14 15:21, Ulf Hansson wrote:

On 23 May 2014 14:52,   wrote:




+   boolexplicit_mclk_control;
+   boolcclk_is_mclk;


I can't see why you need to have both these new configurations. Aren't
"cclk_is_mclk" just a fact when you use "explicit_mclk_control".



I also believe I would prefer something like "qcom_clkdiv" instead.


There is a subtle difference between both the flags.  Am happy to change it
to qcom_clkdiv.


I think this was due to me wanting the variant variables to be more about
the actual technical difference they indicate rather than pointing to
a certain vendor or variant where that difference occurs.

Yes, that's correct, I think having these two variables seems to be more 
generic than qcom_clkdiv.


I will keep it as it is and fix other comments from Ulf in next version.


It's a very minor thing though, if you prefer it this way, go for it.



Thanks,
sirni

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


Re: [PATCH v3 13/13] mmc: mmci: Add Qcom specific pio_read function.

2014-05-28 Thread Srinivas Kandagatla



On 28/05/14 09:08, Linus Walleij wrote:

On Fri, May 23, 2014 at 2:53 PM,   wrote:


+   if (unlikely(bytes)) {
+   unsigned char buf[4];

(...)




Please think twice about this.
http://lwn.net/Articles/70473/
http://lwn.net/Articles/420019/
http://lwn.net/Articles/182369/


Thanks for the warning.

You are right. I think having likely/unlikely is not always right here.

thanks,
srini

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


Re: [PATCH v3 10/13] mmc: mmci: add Qcom specifics of clk and datactrl registers.

2014-05-28 Thread Srinivas Kandagatla

Hi Ulf,

On 26/05/14 22:38, Srinivas Kandagatla wrote:

  2 files changed, 28 insertions(+)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 17e7f6a..6434f5b1 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -185,6 +185,10 @@ static struct variant_data variant_qcom = {
 .fifosize   = 16 * 4,
 .fifohalfsize   = 8 * 4,
 .clkreg = MCI_CLK_ENABLE,
+   .clkreg_enable  = MCI_QCOM_CLK_FLOWENA |
+ MCI_QCOM_CLK_FEEDBACK_CLK,


Obviously I don't have the in-depth knowledge about the Qcom variant,
but comparing the ST variant here made me think.

Using the feeback clock internal logic in the ST variant, requires the
corresponding feedback clock pin signal on the board, to be
routed/connected. Typically we used this for SD cards, which involved
using an external level shifter circuit.

Is it correct to enable this bit for all cases, including eMMC?


You are correct, FBCLK should specific to the board, and I will try to
do something on the same lines as ST variant in next version.

I get lot of I/O errors when I remove this flag for test.

I rechecked schematics and datasheet, the feedback clk that we refer 
here is the the feedback clk from CLK pad, there is no separate input 
pad for fbclk. So I think this is internally feedbacked clk.


This selection is configuring bits to latch data and command coming in 
using feedback clock from CLK pad.


I will make sure that the macro is named more appropriately to reflect 
the same.


thanks,
srini
--
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 v4 00/13] Add Qualcomm SD Card Controller support

2014-05-28 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

Thankyou Linus W, Ulf H and everyone for reviewing RFC to v3 patches.

This patch series adds Qualcomm SD Card Controller support in pl180 mmci
driver. QCom SDCC is basically a pl180, but bit more customized, some of the
register layouts and offsets are different to the ones mentioned in pl180
datasheet. The plan is to totally remove the standalone SDCC driver
drivers/mmc/host/msm_sdcc.* and start using generic mmci driver for all
Qualcomm parts, as we get chance to test on other Qcom boards.

To start using the existing mmci driver, a fake amba id for Qualcomm is added
in patches:
 mmc: mmci: Add Qualcomm Id to amba id table.

Second change is, adding a 3 clock cycle delay in between writes to
CLKCTRL/POWER/DATACTRL/COMMAND registers. Most of the delays are taken care with
the existing driver except delay for the COMMAND register was too small. 
This patch fixes it.
  mmc: mmci: Add enough delay between writes to CMD register.

Third change is to accommodate CLK, DATCTRL and MMCICLK register layout changes
in Qcom SDCC and provide more flexibity in driver to specify these changes via
variant datastructure. Which are done in patches:
  mmc: mmci: Add Qcom datactrl register variant
  mmc: mmci: add ddrmode mask to variant data
  mmc: mmci: add 8bit bus support in variant data
  mmc: mmci: add edge support to data and command out in variant data.
  mmc: mmci: add Qcom specifics of clk and datactrl registers.
  mmc: mmci: Add support to data commands via variant structure.
  mmc: mmci: add f_max to variant structure
  mmc: mmci: add explicit clk control

Fourth major change was to add qcom specfic pio read function, the need for
this is because the way MCIFIFOCNT register behaved in QCOM SDCC is very
 different to the one in pl180. This change is done in patch:
  mmc: mmci: Add Qcom specific pio_read function.

Last some Qcom unrelated changes/cleanup to driver are done in patches:
  mmc: mmci: use NSEC_PER_SEC macro
  mmc: mmci: convert register bits to use BIT() macro.

This patches are tested in PIO mode on IFC8064 board with both eMMC and
external SD card. I would like to get this support in v3.16.
Bjorn also confirmed that there are no more CRC errors seen on sony platform.

Changes from v3:
- moved pio_read to a function pointer so as to reduce additional cycles
in hot-path, suggested by Ulf.
- simplify the flags used for explicit mclk control, suggested by Ulf.
- fixed issues in cacluating f_max and f_min pointed and suggested by 
Ulf.
- removed unessary DDR flags on un-supported STE variants.
- used BIT macros as suggested by Ulf.
- removed the read/write wrappers with delays, and used most optimal way
to introduce the delays to the only registers that require delays.

Changes from v2:
- merged fbclk latch patch with clkreg_enable patch as suggested by 
Linus W.
- remove qcom prefix for explicit clk control pointed by Linus W.
- cleaned up mmci_qcom_pio_read and consider SDIO as suggested by Linus 
W.

Changes from v1:
- moved most of the SOC specifics to variant parameters as suggested
  by Linus W.
- renamed registers as suggested by Linus W.
- Added comments in the code as suggested by Linus W.
- moved out AMBA ID addition patch from this series.
- rebased the patches to 
git://git.linaro.org/people/ulf.hansson/mmc.git next 
  as suggested by Ulf H.

Changes from RFC:
- moved out clk setup out of spinlock as pointed by Stephen B.

If its not too late, Am hoping to get this for v3.16.

All these patches are tested on IF6410 board on both eMMC and external SD card.

Thanks,
srini

Srinivas Kandagatla (13):
  mmc: mmci: use NSEC_PER_SEC macro
  mmc: mmci: convert register bits to use BIT() macro.
  mmc: mmci: Add Qualcomm Id to amba id table
  mmc: mmci: Add enough delay between writes to CMD register.
  mmc: mmci: Add Qcom datactrl register variant
  mmc: mmci: add ddrmode mask to variant data
  mmc: mmci: add 8bit bus support in variant data
  mmc: mmci: add edge support to data and command out in variant data.
  mmc: mmci: add Qcom specifics of clk and datactrl registers.
  mmc: mmci: Add support to data commands via variant structure.
  mmc: mmci: add f_max to variant structure
  mmc: mmci: add explicit clk control
  mmc: mmci: Add Qcom specific pio_read function.

 drivers/mmc/host/mmci.c | 203 +-
 drivers/mmc/host/mmci.h | 228 ++--
 2 files changed, 288 insertions(+), 143 deletions(-)

-- 
1.9.1

--
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 v4 01/13] mmc: mmci: use NSEC_PER_SEC macro

2014-05-28 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

This patch replaces a constant used in calculating timeout with a proper
macro. This is make code more readable.

Signed-off-by: Srinivas Kandagatla 
Reviewed-by: Linus Walleij 
---
 drivers/mmc/host/mmci.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index a084edd..a38e714 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -718,7 +718,7 @@ static void mmci_start_data(struct mmci_host *host, struct 
mmc_data *data)
data->bytes_xfered = 0;
 
clks = (unsigned long long)data->timeout_ns * host->cclk;
-   do_div(clks, 10UL);
+   do_div(clks, NSEC_PER_SEC);
 
timeout = data->timeout_clks + (unsigned int)clks;
 
-- 
1.9.1

--
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 v4 05/13] mmc: mmci: Add Qcom datactrl register variant

2014-05-28 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

Instance of this IP on Qualcomm's SOCs has bit different layout for datactrl
register. Bit position datactrl[16:4] hold the true block size instead of power
of 2.

Signed-off-by: Srinivas Kandagatla 
Reviewed-by: Linus Walleij 
---
 drivers/mmc/host/mmci.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index aa2d381..23401b0 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -60,6 +60,8 @@ static unsigned int fmax = 515633;
  * @sdio: variant supports SDIO
  * @st_clkdiv: true if using a ST-specific clock divider algorithm
  * @blksz_datactrl16: true if Block size is at b16..b30 position in datactrl 
register
+ * @blksz_datactrl4: true if Block size is at b4..b16 position in datactrl
+ *  register
  * @pwrreg_powerup: power up value for MMCIPOWER register
  * @signal_direction: input/out direction of bus signals can be indicated
  * @pwrreg_clkgate: MMCIPOWER register must be used to gate the clock
@@ -75,6 +77,7 @@ struct variant_data {
boolsdio;
boolst_clkdiv;
boolblksz_datactrl16;
+   boolblksz_datactrl4;
u32 pwrreg_powerup;
boolsignal_direction;
boolpwrreg_clkgate;
@@ -164,6 +167,7 @@ static struct variant_data variant_qcom = {
.fifosize   = 16 * 4,
.fifohalfsize   = 8 * 4,
.clkreg = MCI_CLK_ENABLE,
+   .blksz_datactrl4= true,
.datalength_bits= 24,
.pwrreg_powerup = MCI_PWR_UP,
 };
@@ -739,6 +743,8 @@ static void mmci_start_data(struct mmci_host *host, struct 
mmc_data *data)
 
if (variant->blksz_datactrl16)
datactrl = MCI_DPSM_ENABLE | (data->blksz << 16);
+   else if (variant->blksz_datactrl4)
+   datactrl = MCI_DPSM_ENABLE | (data->blksz << 4);
else
datactrl = MCI_DPSM_ENABLE | blksz_bits << 4;
 
-- 
1.9.1

--
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 v4 12/13] mmc: mmci: add explicit clk control

2014-05-28 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

On Controllers like Qcom SD card controller where cclk is mclk and mclk should
be directly controlled by the driver.

This patch adds support to control mclk directly in the driver, and also
adds explicit_mclk_control flag in variant structure giving more flexibility
to the driver.

Signed-off-by: Srinivas Kandagatla 
---
 drivers/mmc/host/mmci.c | 96 -
 drivers/mmc/host/mmci.h |  2 ++
 2 files changed, 65 insertions(+), 33 deletions(-)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 202f2d5..6eb0a29 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -72,6 +72,7 @@ static unsigned int fmax = 515633;
  * @pwrreg_clkgate: MMCIPOWER register must be used to gate the clock
  * @busy_detect: true if busy detection on dat0 is supported
  * @pwrreg_nopower: bits in MMCIPOWER don't controls ext. power supply
+ * @explicit_mclk_control: enable explicit mclk control in driver.
  */
 struct variant_data {
unsigned intclkreg;
@@ -93,6 +94,7 @@ struct variant_data {
boolpwrreg_clkgate;
boolbusy_detect;
boolpwrreg_nopower;
+   boolexplicit_mclk_control;
 };
 
 static struct variant_data variant_arm = {
@@ -199,6 +201,7 @@ static struct variant_data variant_qcom = {
.datalength_bits= 24,
.pwrreg_powerup = MCI_PWR_UP,
.f_max  = 20800,
+   .explicit_mclk_control  = true,
 };
 
 static int mmci_card_busy(struct mmc_host *mmc)
@@ -301,7 +304,9 @@ static void mmci_set_clkreg(struct mmci_host *host, 
unsigned int desired)
host->cclk = 0;
 
if (desired) {
-   if (desired >= host->mclk) {
+   if (variant->explicit_mclk_control) {
+   host->cclk = host->mclk;
+   } else if (desired >= host->mclk) {
clk = MCI_CLK_BYPASS;
if (variant->st_clkdiv)
clk |= MCI_ST_UX500_NEG_EDGE;
@@ -1340,6 +1345,18 @@ static void mmci_set_ios(struct mmc_host *mmc, struct 
mmc_ios *ios)
if (!ios->clock && variant->pwrreg_clkgate)
pwr &= ~MCI_PWR_ON;
 
+   if ((host->variant->explicit_mclk_control) &&
+   (ios->clock != host->mclk_req)) {
+   int rc = clk_set_rate(host->clk, ios->clock);
+   if (rc < 0) {
+   dev_err(mmc_dev(host->mmc),
+   "Error setting clock rate (%d)\n", rc);
+   } else {
+   host->mclk = clk_get_rate(host->clk);
+   host->mclk_req = ios->clock;
+   }
+   }
+
spin_lock_irqsave(&host->lock, flags);
 
mmci_set_clkreg(host, ios->clock);
@@ -1490,19 +1507,6 @@ static int mmci_probe(struct amba_device *dev,
host->plat = plat;
host->variant = variant;
host->mclk = clk_get_rate(host->clk);
-   /*
-* According to the spec, mclk is max 100 MHz,
-* so we try to adjust the clock down to this,
-* (if possible).
-*/
-   if (host->mclk > host->variant->f_max) {
-   ret = clk_set_rate(host->clk, host->variant->f_max);
-   if (ret < 0)
-   goto clk_disable;
-   host->mclk = clk_get_rate(host->clk);
-   dev_dbg(mmc_dev(mmc), "eventual mclk rate: %u Hz\n",
-   host->mclk);
-   }
 
host->phybase = dev->res.start;
host->base = devm_ioremap_resource(&dev->dev, &dev->res);
@@ -1511,25 +1515,51 @@ static int mmci_probe(struct amba_device *dev,
goto clk_disable;
}
 
-   /*
-* The ARM and ST versions of the block have slightly different
-* clock divider equations which means that the minimum divider
-* differs too.
-*/
-   if (variant->st_clkdiv)
-   mmc->f_min = DIV_ROUND_UP(host->mclk, 257);
-   else
-   mmc->f_min = DIV_ROUND_UP(host->mclk, 512);
-   /*
-* If no maximum operating frequency is supplied, fall back to use
-* the module parameter, which has a (low) default value in case it
-* is not specified. Either value must not exceed the clock rate into
-* the block, of course.
-*/
-   if (mmc->f_max)
-   mmc->f_max = min(host->mclk, mmc->f_max);
-   else
-   mmc->f_max = min(host->mclk, fmax);
+   if (variant->explicit_mclk_control) {
+   /* get the nearest minimum clock to 100Khz */
+   mmc->f_min = clk_round_rate(host-&

[PATCH v4 11/13] mmc: mmci: add f_max to variant structure

2014-05-28 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

Some of the controller have maximum supported frequency, This patch adds
support in variant data structure to specify such restrictions. This
gives more flexibility in calculating the f_max before passing it to
mmc-core.

Signed-off-by: Srinivas Kandagatla 
---
 drivers/mmc/host/mmci.c | 14 --
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index fd40f9a..202f2d5 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -67,6 +67,7 @@ static unsigned int fmax = 515633;
  * @blksz_datactrl4: true if Block size is at b4..b16 position in datactrl
  *  register
  * @pwrreg_powerup: power up value for MMCIPOWER register
+ * @f_max: maximum clk frequency supported by the controller.
  * @signal_direction: input/out direction of bus signals can be indicated
  * @pwrreg_clkgate: MMCIPOWER register must be used to gate the clock
  * @busy_detect: true if busy detection on dat0 is supported
@@ -87,6 +88,7 @@ struct variant_data {
boolblksz_datactrl16;
boolblksz_datactrl4;
u32 pwrreg_powerup;
+   u32 f_max;
boolsignal_direction;
boolpwrreg_clkgate;
boolbusy_detect;
@@ -98,6 +100,7 @@ static struct variant_data variant_arm = {
.fifohalfsize   = 8 * 4,
.datalength_bits= 16,
.pwrreg_powerup = MCI_PWR_UP,
+   .f_max  = 1,
 };
 
 static struct variant_data variant_arm_extended_fifo = {
@@ -105,6 +108,7 @@ static struct variant_data variant_arm_extended_fifo = {
.fifohalfsize   = 64 * 4,
.datalength_bits= 16,
.pwrreg_powerup = MCI_PWR_UP,
+   .f_max  = 1,
 };
 
 static struct variant_data variant_arm_extended_fifo_hwfc = {
@@ -113,6 +117,7 @@ static struct variant_data variant_arm_extended_fifo_hwfc = 
{
.clkreg_enable  = MCI_ARM_HWFCEN,
.datalength_bits= 16,
.pwrreg_powerup = MCI_PWR_UP,
+   .f_max  = 1,
 };
 
 static struct variant_data variant_u300 = {
@@ -123,6 +128,7 @@ static struct variant_data variant_u300 = {
.datalength_bits= 16,
.sdio   = true,
.pwrreg_powerup = MCI_PWR_ON,
+   .f_max  = 1,
.signal_direction   = true,
.pwrreg_clkgate = true,
.pwrreg_nopower = true,
@@ -136,6 +142,7 @@ static struct variant_data variant_nomadik = {
.sdio   = true,
.st_clkdiv  = true,
.pwrreg_powerup = MCI_PWR_ON,
+   .f_max  = 1,
.signal_direction   = true,
.pwrreg_clkgate = true,
.pwrreg_nopower = true,
@@ -152,6 +159,7 @@ static struct variant_data variant_ux500 = {
.sdio   = true,
.st_clkdiv  = true,
.pwrreg_powerup = MCI_PWR_ON,
+   .f_max  = 1,
.signal_direction   = true,
.pwrreg_clkgate = true,
.busy_detect= true,
@@ -171,6 +179,7 @@ static struct variant_data variant_ux500v2 = {
.st_clkdiv  = true,
.blksz_datactrl16   = true,
.pwrreg_powerup = MCI_PWR_ON,
+   .f_max  = 1,
.signal_direction   = true,
.pwrreg_clkgate = true,
.busy_detect= true,
@@ -189,6 +198,7 @@ static struct variant_data variant_qcom = {
.blksz_datactrl4= true,
.datalength_bits= 24,
.pwrreg_powerup = MCI_PWR_UP,
+   .f_max  = 20800,
 };
 
 static int mmci_card_busy(struct mmc_host *mmc)
@@ -1485,8 +1495,8 @@ static int mmci_probe(struct amba_device *dev,
 * so we try to adjust the clock down to this,
 * (if possible).
 */
-   if (host->mclk > 1) {
-   ret = clk_set_rate(host->clk, 1);
+   if (host->mclk > host->variant->f_max) {
+   ret = clk_set_rate(host->clk, host->variant->f_max);
if (ret < 0)
goto clk_disable;
host->mclk = clk_get_rate(host->clk);
-- 
1.9.1

--
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 v4 08/13] mmc: mmci: add edge support to data and command out in variant data.

2014-05-28 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

This patch adds edge support for data and command out to variant structure
giving more flexibility to the driver to support more SOCs which have
different clock register layout.

Without this patch other new SOCs like Qcom will have to add more code to
special case them

Signed-off-by: Srinivas Kandagatla 
Reviewed-by: Linus Walleij 
---
 drivers/mmc/host/mmci.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 2f4cdf3..8deea4a 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -53,6 +53,7 @@ static unsigned int fmax = 515633;
  * @clkreg: default value for MCICLOCK register
  * @clkreg_enable: enable value for MMCICLOCK register
  * @clkreg_8bit_bus_enable: enable value for 8 bit bus
+ * @clkreg_neg_edge_enable: enable value for inverted data/cmd output
  * @datalength_bits: number of bits in the MMCIDATALENGTH register
  * @fifosize: number of bytes that can be written when MMCI_TXFIFOEMPTY
  *   is asserted (likewise for RX)
@@ -74,6 +75,7 @@ struct variant_data {
unsigned intclkreg;
unsigned intclkreg_enable;
unsigned intclkreg_8bit_bus_enable;
+   unsigned intclkreg_neg_edge_enable;
unsigned intdatalength_bits;
unsigned intfifosize;
unsigned intfifohalfsize;
@@ -143,6 +145,7 @@ static struct variant_data variant_ux500 = {
.clkreg = MCI_CLK_ENABLE,
.clkreg_enable  = MCI_ST_UX500_HWFCEN,
.clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS,
+   .clkreg_neg_edge_enable = MCI_ST_UX500_NEG_EDGE,
.datalength_bits= 24,
.sdio   = true,
.st_clkdiv  = true,
@@ -159,6 +162,7 @@ static struct variant_data variant_ux500v2 = {
.clkreg = MCI_CLK_ENABLE,
.clkreg_enable  = MCI_ST_UX500_HWFCEN,
.clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS,
+   .clkreg_neg_edge_enable = MCI_ST_UX500_NEG_EDGE,
.datactrl_mask_ddrmode  = MCI_ST_DPSM_DDRMODE,
.datalength_bits= 24,
.sdio   = true,
@@ -322,7 +326,7 @@ static void mmci_set_clkreg(struct mmci_host *host, 
unsigned int desired)
clk |= variant->clkreg_8bit_bus_enable;
 
if (host->mmc->ios.timing == MMC_TIMING_UHS_DDR50)
-   clk |= MCI_ST_UX500_NEG_EDGE;
+   clk |= variant->clkreg_neg_edge_enable;
 
mmci_write_clkreg(host, clk);
 }
-- 
1.9.1

--
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 v4 09/13] mmc: mmci: add Qcom specifics of clk and datactrl registers.

2014-05-28 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

This patch adds specifics of clk and datactrl register on Qualcomm SD
Card controller. This patch also populates the Qcom variant data with
these new values specific to Qualcomm SD Card Controller.

Signed-off-by: Srinivas Kandagatla 
Reviewed-by: Linus Walleij 
---
 drivers/mmc/host/mmci.c |  4 
 drivers/mmc/host/mmci.h | 17 +
 2 files changed, 21 insertions(+)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 8deea4a..dbcb952 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -179,6 +179,10 @@ static struct variant_data variant_qcom = {
.fifosize   = 16 * 4,
.fifohalfsize   = 8 * 4,
.clkreg = MCI_CLK_ENABLE,
+   .clkreg_enable  = MCI_QCOM_CLK_FLOWENA |
+ MCI_QCOM_CLK_SELECT_IN_FBCLK,
+   .clkreg_8bit_bus_enable = MCI_QCOM_CLK_WIDEBUS_8,
+   .datactrl_mask_ddrmode  = MCI_QCOM_CLK_SELECT_IN_DDR_MODE,
.blksz_datactrl4= true,
.datalength_bits= 24,
.pwrreg_powerup = MCI_PWR_UP,
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h
index cd83ca3..706eb513 100644
--- a/drivers/mmc/host/mmci.h
+++ b/drivers/mmc/host/mmci.h
@@ -41,6 +41,15 @@
 /* Modified PL180 on Versatile Express platform */
 #define MCI_ARM_HWFCEN BIT(12)
 
+/* Modified on Qualcomm Integrations */
+#define MCI_QCOM_CLK_WIDEBUS_8 (BIT(10) | BIT(11))
+#define MCI_QCOM_CLK_FLOWENA   BIT(12)
+#define MCI_QCOM_CLK_INVERTOUT BIT(13)
+
+/* select in latch data and command in */
+#define MCI_QCOM_CLK_SELECT_IN_FBCLK   BIT(15)
+#define MCI_QCOM_CLK_SELECT_IN_DDR_MODE(BIT(14) | BIT(15))
+
 #define MMCIARGUMENT   0x008
 #define MMCICOMMAND0x00c
 #define MCI_CPSM_RESPONSE  BIT(6)
@@ -54,6 +63,14 @@
 #define MCI_ST_NIENBIT(13)
 #define MCI_ST_CE_ATACMD   BIT(14)
 
+/* Modified on Qualcomm Integrations */
+#define MCI_QCOM_CSPM_DATCMD   BIT(12)
+#define MCI_QCOM_CSPM_MCIABORT BIT(13)
+#define MCI_QCOM_CSPM_CCSENABLEBIT(14)
+#define MCI_QCOM_CSPM_CCSDISABLE   BIT(15)
+#define MCI_QCOM_CSPM_AUTO_CMD19   BIT(16)
+#define MCI_QCOM_CSPM_AUTO_CMD21   BIT(21)
+
 #define MMCIRESPCMD0x010
 #define MMCIRESPONSE0  0x014
 #define MMCIRESPONSE1  0x018
-- 
1.9.1

--
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 v4 10/13] mmc: mmci: Add support to data commands via variant structure.

2014-05-28 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

On some SOCs like Qcom there are explicit bits in the command register
to specify if its a data transfer command or not. So this patch adds
support to such bits in variant data, giving more flexibility to the
driver.

Signed-off-by: Srinivas Kandagatla 
Reviewed-by: Linus Walleij 
---
 drivers/mmc/host/mmci.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index dbcb952..fd40f9a 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -59,6 +59,7 @@ static unsigned int fmax = 515633;
  *   is asserted (likewise for RX)
  * @fifohalfsize: number of bytes that can be written when MCI_TXFIFOHALFEMPTY
  *   is asserted (likewise for RX)
+ * @data_cmd_enable: enable value for data commands.
  * @sdio: variant supports SDIO
  * @st_clkdiv: true if using a ST-specific clock divider algorithm
  * @datactrl_mask_ddrmode: ddr mode mask in datactrl register.
@@ -79,6 +80,7 @@ struct variant_data {
unsigned intdatalength_bits;
unsigned intfifosize;
unsigned intfifohalfsize;
+   unsigned intdata_cmd_enable;
unsigned intdatactrl_mask_ddrmode;
boolsdio;
boolst_clkdiv;
@@ -183,6 +185,7 @@ static struct variant_data variant_qcom = {
  MCI_QCOM_CLK_SELECT_IN_FBCLK,
.clkreg_8bit_bus_enable = MCI_QCOM_CLK_WIDEBUS_8,
.datactrl_mask_ddrmode  = MCI_QCOM_CLK_SELECT_IN_DDR_MODE,
+   .data_cmd_enable= MCI_QCOM_CSPM_DATCMD,
.blksz_datactrl4= true,
.datalength_bits= 24,
.pwrreg_powerup = MCI_PWR_UP,
@@ -852,6 +855,9 @@ mmci_start_command(struct mmci_host *host, struct 
mmc_command *cmd, u32 c)
if (/*interrupt*/0)
c |= MCI_CPSM_INTERRUPT;
 
+   if (mmc_cmd_type(cmd) == MMC_CMD_ADTC)
+   c |= host->variant->data_cmd_enable;
+
host->cmd = cmd;
 
writel(cmd->arg, base + MMCIARGUMENT);
-- 
1.9.1

--
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 v4 07/13] mmc: mmci: add 8bit bus support in variant data

2014-05-28 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

This patch adds 8bit bus enable to variant structure giving more flexibility
to the driver to support more SOCs which have different clock register layout.

Without this patch other new SOCs like Qcom will have to add more code
to special case them.

Signed-off-by: Srinivas Kandagatla 
Reviewed-by: Linus Walleij 
---
 drivers/mmc/host/mmci.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 729105b..2f4cdf3 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -52,6 +52,7 @@ static unsigned int fmax = 515633;
  * struct variant_data - MMCI variant-specific quirks
  * @clkreg: default value for MCICLOCK register
  * @clkreg_enable: enable value for MMCICLOCK register
+ * @clkreg_8bit_bus_enable: enable value for 8 bit bus
  * @datalength_bits: number of bits in the MMCIDATALENGTH register
  * @fifosize: number of bytes that can be written when MMCI_TXFIFOEMPTY
  *   is asserted (likewise for RX)
@@ -72,6 +73,7 @@ static unsigned int fmax = 515633;
 struct variant_data {
unsigned intclkreg;
unsigned intclkreg_enable;
+   unsigned intclkreg_8bit_bus_enable;
unsigned intdatalength_bits;
unsigned intfifosize;
unsigned intfifohalfsize;
@@ -113,6 +115,7 @@ static struct variant_data variant_u300 = {
.fifosize   = 16 * 4,
.fifohalfsize   = 8 * 4,
.clkreg_enable  = MCI_ST_U300_HWFCEN,
+   .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS,
.datalength_bits= 16,
.sdio   = true,
.pwrreg_powerup = MCI_PWR_ON,
@@ -139,6 +142,7 @@ static struct variant_data variant_ux500 = {
.fifohalfsize   = 8 * 4,
.clkreg = MCI_CLK_ENABLE,
.clkreg_enable  = MCI_ST_UX500_HWFCEN,
+   .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS,
.datalength_bits= 24,
.sdio   = true,
.st_clkdiv  = true,
@@ -154,6 +158,7 @@ static struct variant_data variant_ux500v2 = {
.fifohalfsize   = 8 * 4,
.clkreg = MCI_CLK_ENABLE,
.clkreg_enable  = MCI_ST_UX500_HWFCEN,
+   .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS,
.datactrl_mask_ddrmode  = MCI_ST_DPSM_DDRMODE,
.datalength_bits= 24,
.sdio   = true,
@@ -314,7 +319,7 @@ static void mmci_set_clkreg(struct mmci_host *host, 
unsigned int desired)
if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_4)
clk |= MCI_4BIT_BUS;
if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_8)
-   clk |= MCI_ST_8BIT_BUS;
+   clk |= variant->clkreg_8bit_bus_enable;
 
if (host->mmc->ios.timing == MMC_TIMING_UHS_DDR50)
clk |= MCI_ST_UX500_NEG_EDGE;
-- 
1.9.1

--
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 v4 03/13] mmc: mmci: Add Qualcomm Id to amba id table

2014-05-28 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

This patch adds a fake Qualcomm ID 0x00051180 to the amba_ids, as Qualcomm
SDCC controller is pl180, but amba id registers read 0x0's.
The plan is to remove SDCC driver totally and use mmci as the main SD
controller driver for Qualcomm SOCs.

Signed-off-by: Srinivas Kandagatla 
Reviewed-by: Linus Walleij 
---
 drivers/mmc/host/mmci.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index a38e714..86f25a9 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -160,6 +160,14 @@ static struct variant_data variant_ux500v2 = {
.pwrreg_nopower = true,
 };
 
+static struct variant_data variant_qcom = {
+   .fifosize   = 16 * 4,
+   .fifohalfsize   = 8 * 4,
+   .clkreg = MCI_CLK_ENABLE,
+   .datalength_bits= 24,
+   .pwrreg_powerup = MCI_PWR_UP,
+};
+
 static int mmci_card_busy(struct mmc_host *mmc)
 {
struct mmci_host *host = mmc_priv(mmc);
@@ -1750,6 +1758,12 @@ static struct amba_id mmci_ids[] = {
.mask   = 0xf0ff,
.data   = &variant_ux500v2,
},
+   /* Qualcomm variants */
+   {
+   .id = 0x00051180,
+   .mask   = 0x000f,
+   .data   = &variant_qcom,
+   },
{ 0, 0 },
 };
 
-- 
1.9.1

--
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 v4 02/13] mmc: mmci: convert register bits to use BIT() macro.

2014-05-28 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

This patch converts the register bits in the header file to use BIT(()
macro, which looks much neater.

No functional changes done.

Signed-off-by: Srinivas Kandagatla 
---
 drivers/mmc/host/mmci.h | 208 
 1 file changed, 104 insertions(+), 104 deletions(-)

diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h
index 347d942..cd83ca3 100644
--- a/drivers/mmc/host/mmci.h
+++ b/drivers/mmc/host/mmci.h
@@ -11,48 +11,48 @@
 #define MCI_PWR_OFF0x00
 #define MCI_PWR_UP 0x02
 #define MCI_PWR_ON 0x03
-#define MCI_OD (1 << 6)
-#define MCI_ROD(1 << 7)
+#define MCI_OD BIT(6)
+#define MCI_RODBIT(7)
 /*
  * The ST Micro version does not have ROD and reuse the voltage registers for
  * direction settings.
  */
-#define MCI_ST_DATA2DIREN  (1 << 2)
-#define MCI_ST_CMDDIREN(1 << 3)
-#define MCI_ST_DATA0DIREN  (1 << 4)
-#define MCI_ST_DATA31DIREN (1 << 5)
-#define MCI_ST_FBCLKEN (1 << 7)
-#define MCI_ST_DATA74DIREN (1 << 8)
+#define MCI_ST_DATA2DIREN  BIT(2)
+#define MCI_ST_CMDDIRENBIT(3)
+#define MCI_ST_DATA0DIREN  BIT(4)
+#define MCI_ST_DATA31DIREN BIT(5)
+#define MCI_ST_FBCLKEN BIT(7)
+#define MCI_ST_DATA74DIREN BIT(8)
 
 #define MMCICLOCK  0x004
-#define MCI_CLK_ENABLE (1 << 8)
-#define MCI_CLK_PWRSAVE(1 << 9)
-#define MCI_CLK_BYPASS (1 << 10)
-#define MCI_4BIT_BUS   (1 << 11)
+#define MCI_CLK_ENABLE BIT(8)
+#define MCI_CLK_PWRSAVEBIT(9)
+#define MCI_CLK_BYPASS BIT(10)
+#define MCI_4BIT_BUS   BIT(11)
 /*
  * 8bit wide buses, hardware flow contronl, negative edges and clock inversion
  * supported in ST Micro U300 and Ux500 versions
  */
-#define MCI_ST_8BIT_BUS(1 << 12)
-#define MCI_ST_U300_HWFCEN (1 << 13)
-#define MCI_ST_UX500_NEG_EDGE  (1 << 13)
-#define MCI_ST_UX500_HWFCEN(1 << 14)
-#define MCI_ST_UX500_CLK_INV   (1 << 15)
+#define MCI_ST_8BIT_BUSBIT(12)
+#define MCI_ST_U300_HWFCEN BIT(13)
+#define MCI_ST_UX500_NEG_EDGE  BIT(13)
+#define MCI_ST_UX500_HWFCENBIT(14)
+#define MCI_ST_UX500_CLK_INV   BIT(15)
 /* Modified PL180 on Versatile Express platform */
-#define MCI_ARM_HWFCEN (1 << 12)
+#define MCI_ARM_HWFCEN BIT(12)
 
 #define MMCIARGUMENT   0x008
 #define MMCICOMMAND0x00c
-#define MCI_CPSM_RESPONSE  (1 << 6)
-#define MCI_CPSM_LONGRSP   (1 << 7)
-#define MCI_CPSM_INTERRUPT (1 << 8)
-#define MCI_CPSM_PENDING   (1 << 9)
-#define MCI_CPSM_ENABLE(1 << 10)
+#define MCI_CPSM_RESPONSE  BIT(6)
+#define MCI_CPSM_LONGRSP   BIT(7)
+#define MCI_CPSM_INTERRUPT BIT(8)
+#define MCI_CPSM_PENDING   BIT(9)
+#define MCI_CPSM_ENABLEBIT(10)
 /* Argument flag extenstions in the ST Micro versions */
-#define MCI_ST_SDIO_SUSP   (1 << 11)
-#define MCI_ST_ENCMD_COMPL (1 << 12)
-#define MCI_ST_NIEN(1 << 13)
-#define MCI_ST_CE_ATACMD   (1 << 14)
+#define MCI_ST_SDIO_SUSP   BIT(11)
+#define MCI_ST_ENCMD_COMPL BIT(12)
+#define MCI_ST_NIENBIT(13)
+#define MCI_ST_CE_ATACMD   BIT(14)
 
 #define MMCIRESPCMD0x010
 #define MMCIRESPONSE0  0x014
@@ -62,95 +62,95 @@
 #define MMCIDATATIMER  0x024
 #define MMCIDATALENGTH 0x028
 #define MMCIDATACTRL   0x02c
-#define MCI_DPSM_ENABLE(1 << 0)
-#define MCI_DPSM_DIRECTION (1 << 1)
-#define MCI_DPSM_MODE  (1 << 2)
-#define MCI_DPSM_DMAENABLE (1 << 3)
-#define MCI_DPSM_BLOCKSIZE (1 << 4)
+#define MCI_DPSM_ENABLEBIT(0)
+#define MCI_DPSM_DIRECTION BIT(1)
+#define MCI_DPSM_MODE  BIT(2)
+#define MCI_DPSM_DMAENABLE BIT(3)
+#define MCI_DPSM_BLOCKSIZE BIT(4)
 /* Control register extensions in the ST Micro U300 and Ux500 versions */
-#define MCI_ST_DPSM_RWSTART(1 << 8)
-#define MCI_ST_DPSM_RWSTOP (1 << 9)
-#define MCI_ST_DPSM_RWMOD  (1 << 10)
-#define MCI_ST_DPSM_SDIOEN (1 << 11)
+#define MCI_ST_DPSM_RWSTARTBIT(8)
+#define MCI_ST_DPSM_RWSTOP BIT(9)
+#define MCI_ST_DPSM_RWMOD  BIT(10)
+#define MCI_ST_DPSM_SDIOEN BIT(11)
 /* Control register extensions in the ST Micro Ux500 versions */
-#define MCI_ST_DPSM_DMAREQCTL  (1 << 12)
-#define MCI_ST_DPSM_DBOOTMODEEN(1 << 13)
-#define MCI_ST_DPSM_BUSYMODE   (1 << 14)
-#define MCI_ST_DPSM_DDRMODE(1 << 15)
+#define MCI_ST_DPSM_DMAREQCTL  BIT(12)
+#define MCI_ST_DPSM_DBOOTMODEENBIT(13)
+#define MCI_ST_DPSM_BUSYMODE  

[PATCH v4 06/13] mmc: mmci: add ddrmode mask to variant data

2014-05-28 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

This patch adds ddrmode mask to variant structure giving more flexibility
to the driver to support more SOCs which have different datactrl register
layout.

Without this patch datactrl register is updated with wrong ddrmode mask on non
ST SOCs, resulting in card detection failures.

Signed-off-by: Srinivas Kandagatla 
Reviewed-by: Linus Walleij 
---
 drivers/mmc/host/mmci.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 23401b0..729105b 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -59,6 +59,7 @@ static unsigned int fmax = 515633;
  *   is asserted (likewise for RX)
  * @sdio: variant supports SDIO
  * @st_clkdiv: true if using a ST-specific clock divider algorithm
+ * @datactrl_mask_ddrmode: ddr mode mask in datactrl register.
  * @blksz_datactrl16: true if Block size is at b16..b30 position in datactrl 
register
  * @blksz_datactrl4: true if Block size is at b4..b16 position in datactrl
  *  register
@@ -74,6 +75,7 @@ struct variant_data {
unsigned intdatalength_bits;
unsigned intfifosize;
unsigned intfifohalfsize;
+   unsigned intdatactrl_mask_ddrmode;
boolsdio;
boolst_clkdiv;
boolblksz_datactrl16;
@@ -152,6 +154,7 @@ static struct variant_data variant_ux500v2 = {
.fifohalfsize   = 8 * 4,
.clkreg = MCI_CLK_ENABLE,
.clkreg_enable  = MCI_ST_UX500_HWFCEN,
+   .datactrl_mask_ddrmode  = MCI_ST_DPSM_DDRMODE,
.datalength_bits= 24,
.sdio   = true,
.st_clkdiv  = true,
@@ -779,7 +782,7 @@ static void mmci_start_data(struct mmci_host *host, struct 
mmc_data *data)
}
 
if (host->mmc->ios.timing == MMC_TIMING_UHS_DDR50)
-   datactrl |= MCI_ST_DPSM_DDRMODE;
+   datactrl |= variant->datactrl_mask_ddrmode;
 
/*
 * Attempt to use DMA operation mode, if this
-- 
1.9.1

--
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 v4 04/13] mmc: mmci: Add enough delay between writes to CMD register.

2014-05-28 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

On Qcom SD Card controller POWER, CLKCTRL, DATACTRL and COMMAND registers
should be updated in MCLK domain, and writes to these registers must be
separated by three MCLK cycles. This resitriction is not applicable for
other registers. Any subsequent writes to these register will be ignored
until 3 MCLK have passed.

One usec delay between two CMD register writes is not sufficient in the
card identification phase where the CCLK is very low. This patch replaces
a static 1 usec delay to use mmci_reg_delay function which can provide
correct delay depending on the cclk frequency.

Without this patch the card is not detected.

Signed-off-by: Srinivas Kandagatla 
---
 drivers/mmc/host/mmci.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 86f25a9..aa2d381 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -818,7 +818,7 @@ mmci_start_command(struct mmci_host *host, struct 
mmc_command *cmd, u32 c)
 
if (readl(base + MMCICOMMAND) & MCI_CPSM_ENABLE) {
writel(0, base + MMCICOMMAND);
-   udelay(1);
+   mmci_reg_delay(host);
}
 
c |= cmd->opcode | MCI_CPSM_ENABLE;
-- 
1.9.1

--
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 v4 13/13] mmc: mmci: Add Qcom specific pio_read function.

2014-05-28 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

MCIFIFOCNT register behaviour on Qcom chips is very different than the other
pl180 integrations. MCIFIFOCNT register contains the number of
words that are still waiting to be transferred through the FIFO. It keeps
decrementing once the host CPU reads the MCIFIFO. With the existing logic and
the MCIFIFOCNT behaviour, mmci_pio_read will loop forever, as the FIFOCNT
register will always return transfer size before reading the FIFO.

Also the data sheet states that "This register is only useful for debug
purposes and should not be used for normal operation since it does not reflect
data which may or may not be in the pipeline".

This patch implements qcom_pio_read function so as existing mmci_pio_read is
not suitable for Qcom SOCs. qcom_pio_read function is only selected
based on qcom_fifo flag in variant data structure.

Signed-off-by: Srinivas Kandagatla 
---
 drivers/mmc/host/mmci.c | 45 -
 drivers/mmc/host/mmci.h |  1 +
 2 files changed, 45 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 6eb0a29..b68223a 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -73,6 +73,7 @@ static unsigned int fmax = 515633;
  * @busy_detect: true if busy detection on dat0 is supported
  * @pwrreg_nopower: bits in MMCIPOWER don't controls ext. power supply
  * @explicit_mclk_control: enable explicit mclk control in driver.
+ * @qcom_fifo: enables qcom specific fifo pio read function.
  */
 struct variant_data {
unsigned intclkreg;
@@ -95,6 +96,7 @@ struct variant_data {
boolbusy_detect;
boolpwrreg_nopower;
boolexplicit_mclk_control;
+   boolqcom_fifo;
 };
 
 static struct variant_data variant_arm = {
@@ -202,6 +204,7 @@ static struct variant_data variant_qcom = {
.pwrreg_powerup = MCI_PWR_UP,
.f_max  = 20800,
.explicit_mclk_control  = true,
+   .qcom_fifo  = true,
 };
 
 static int mmci_card_busy(struct mmc_host *mmc)
@@ -1006,6 +1009,40 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command 
*cmd,
}
 }
 
+static int mmci_qcom_pio_read(struct mmci_host *host, char *buffer,
+   unsigned int remain)
+{
+   u32 *ptr = (u32 *) buffer;
+   unsigned int count = 0;
+   unsigned int words, bytes;
+   unsigned int fsize = host->variant->fifosize;
+
+   words = remain >> 2;
+   bytes = remain % 4;
+   /* read full words followed by leftover bytes */
+   if (words) {
+   while (readl(host->base + MMCISTATUS) & MCI_RXDATAAVLBL) {
+   *ptr = readl(host->base + MMCIFIFO + (count % fsize));
+   ptr++;
+   count += 4;
+   words--;
+   if (!words)
+   break;
+   }
+   }
+
+   if (bytes) {
+   unsigned char buf[4];
+   if (readl(host->base + MMCISTATUS) & MCI_RXDATAAVLBL) {
+   *buf = readl(host->base + MMCIFIFO + (count % fsize));
+   memcpy(ptr, buf, bytes);
+   count += bytes;
+   }
+   }
+
+   return count;
+}
+
 static int mmci_pio_read(struct mmci_host *host, char *buffer, unsigned int 
remain)
 {
void __iomem *base = host->base;
@@ -1129,7 +1166,8 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id)
 
len = 0;
if (status & MCI_RXACTIVE)
-   len = mmci_pio_read(host, buffer, remain);
+   len = host->pio_read(host, buffer, remain);
+
if (status & MCI_TXACTIVE)
len = mmci_pio_write(host, buffer, remain, status);
 
@@ -1504,6 +1542,11 @@ static int mmci_probe(struct amba_device *dev,
if (ret)
goto host_free;
 
+   if (variant->qcom_fifo)
+   host->pio_read = mmci_qcom_pio_read;
+   else
+   host->pio_read = mmci_pio_read;
+
host->plat = plat;
host->variant = variant;
host->mclk = clk_get_rate(host->clk);
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h
index 1882e20..dc9fe0a 100644
--- a/drivers/mmc/host/mmci.h
+++ b/drivers/mmc/host/mmci.h
@@ -229,6 +229,7 @@ struct mmci_host {
/* pio stuff */
struct sg_mapping_iter  sg_miter;
unsigned intsize;
+   int (*pio_read)(struct mmci_host *h, char *buf, unsigned int remain);
 
 #ifdef CONFIG_DMA_ENGINE
/* DMA stuff */
-- 
1.9.1

--
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 v3 13/13] mmc: mmci: Add Qcom specific pio_read function.

2014-05-28 Thread Srinivas Kandagatla

Sorry Stephen for late reply,
Some reason this mail was filtered in other folders.

On 24/05/14 00:28, Stephen Boyd wrote:

On 05/23/14 05:53, srinivas.kandaga...@linaro.org wrote:

@@ -1022,6 +1025,40 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command 
*cmd,
}
  }

+static int mmci_qcom_pio_read(struct mmci_host *host, char *buffer,
+   unsigned int remain)
+{
+   u32 *ptr = (u32 *) buffer;
+   unsigned int count = 0;
+   unsigned int words, bytes;
+   unsigned int fsize = host->variant->fifosize;
+
+   words = remain >> 2;
+   bytes = remain % 4;
+   /* read full words followed by leftover bytes */
+   if (words) {
+   while (readl(host->base + MMCISTATUS) & MCI_RXDATAAVLBL) {
+   *ptr = readl(host->base + MMCIFIFO + (count % fsize));


This doesn't look endianness agnostic. Shouldn't we use ioread32_rep()
to read this fifo?

Is'nt readl endianess aware?

we can not use ioread32_rep because as we can not reliably know how many 
words we should read? FIFOCNT would have helped but its not advised to 
be use as per the datasheet.




Thanks,
srini



+   ptr++;
+   count += 4;
+   words--;
+   if (!words)
+   break;
+   }
+   }
+
+   if (unlikely(bytes)) {
+   unsigned char buf[4];
+   if (readl(host->base + MMCISTATUS) & MCI_RXDATAAVLBL) {
+   *buf = readl(host->base + MMCIFIFO + (count % fsize));
+   memcpy(ptr, buf, bytes);
+   count += bytes;
+   }
+   }
+
+   return count;
+}
+
  static int mmci_pio_read(struct mmci_host *host, char *buffer, unsigned int 
remain)
  {
void __iomem *base = host->base;




--
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 1/3] mfd: devicetree: bindings: Add Qualcomm RPM DT binding

2014-05-29 Thread Srinivas Kandagatla

Hi Bjorn,

On 27/05/14 18:28, Bjorn Andersson wrote:

Add binding for the Qualcomm Resource Power Manager (RPM) found in 8660, 8960
and 8064 based devices. The binding currently describes the rpm itself and the
regulator subnodes.

Signed-off-by: Bjorn Andersson 
---
  Documentation/devicetree/bindings/mfd/qcom,rpm.txt | 284 +
  include/dt-bindings/mfd/qcom_rpm.h | 142 +++
  2 files changed, 426 insertions(+)
  create mode 100644 Documentation/devicetree/bindings/mfd/qcom,rpm.txt
  create mode 100644 include/dt-bindings/mfd/qcom_rpm.h

diff --git a/Documentation/devicetree/bindings/mfd/qcom,rpm.txt 
b/Documentation/devicetree/bindings/mfd/qcom,rpm.txt
new file mode 100644
index 000..3908a5d
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/qcom,rpm.txt
@@ -0,0 +1,284 @@
+Qualcomm Resource Power Manager (RPM)
+
+This driver is used to interface with the Resource Power Manager (RPM) found in
+various Qualcomm platforms. The RPM allows each component in the system to vote
+for state of the system resources, such as clocks, regulators and bus
+frequencies.
+
+- compatible:
+   Usage: required
+   Value type: 
+   Definition: must be one of:
+   "qcom,rpm-apq8064"
+   "qcom,rpm-msm8660"
+   "qcom,rpm-msm8960"
+
+- reg:
+   Usage: required
+   Value type: 
+   Definition: two entries specifying the RPM's message ram and ipc 
register
+
+- reg-names:
+   Usage: required
+   Value type: 
+   Definition: must contain the following, in order:
+   "msg_ram"
+   "ipc"


+1 for kumar's comment.

cant enforce the order here. should fix it in the driver.


+
+- interrupts:
+   Usage: required
+   Value type: 
+   Definition: three entries specifying the RPM's:
+   1. acknowledgement interrupt
+   2. error interrupt
+   3. wakeup interrupt
+
+- interrupt-names:
+   Usage: required
+   Value type: 
+   Definition: must be the three strings "ack", "err" and "wakeup", in 
order
+
+- #address-cells:
+   Usage: required
+   Value type: 
+   Definition: must be 1
+
+- #size-cells:
+   Usage: required
+   Value type: 
+   Definition: must be 0
+
+
+= SUBDEVICES
+
+The RPM exposes resources to its subnodes. The below bindings specify the set
+of valid subnodes that can operate on these resources.


Why should these devices be on sub nodes?

Any reason not to implement it like this,

rpm: rpm@108000 {
compatible = "qcom,rpm-msm8960";
reg = <0x108000 0x1000 0x2011008 0x4>;

interrupts = <0 19 0>, <0 21 0>, <0 22 0>;
interrupt-names = "ack", "err", "wakeup";
};

pm8921_s1: pm8921-s1 {
compatible = "qcom,rpm-pm8921-smps";

regulator-min-microvolt = <1225000>;
regulator-max-microvolt = <1225000>;
regulator-always-on;

qcom,rpm = <&rpm QCOM_RPM_PM8921_S1>;
qcom,switch-mode-frequency = <320>;
qcom,hpm-threshold = <10>;
};

This would simplify the driver code too and handle the interface neatly 
then depending on device hierarchy.
rpm would be a interface library to the clients. Makes the drivers more 
independent, and re-usable if we do this way.


??



+
+== Switch-mode Power Supply regulator
+
+- compatible:
+   Usage: required
+   Value type: 
+   Definition: must be one of:
+   "qcom,rpm-pm8058-smps"
+   "qcom,rpm-pm8901-ftsmps"
+   "qcom,rpm-pm8921-smps"
+   "qcom,rpm-pm8921-ftsmps"
+
+- reg:
+   Usage: required
+   Value type: 
+   Definition: resource as defined in 
+
+- qcom,switch-mode-frequency:
+   Usage: required
+   Value type: 
+   Definition: Frequency (Hz) of the switch-mode power supply;
+   must be one of:
+   1920, 960, 640, 480, 384, 320,
+   274, 240, 213, 192, 175, 160,
+   148, 137, 128, 120
+
+- qcom,hpm-threshold:
+   Usage: optional
+   Value type: 
+   Definition: indicates the breaking point at which the regulator should
+   switch to high power mode
+
+- qcom,load-bias:
+   Usage: optional
+   Value type: 
+   Definition: specifies a base load on the specific regulator
+
+- qcom,boot-load:
+   Usage: optional
+   Value type: 
+   Definition: specifies the configured load on boot for the specific
+   regulator
+


[...

+- qcom,force-mode-none:
+   Usage: optional (default if no other qcom,force-mode is specified)
+   Value type: 
+   Defintion: indicates that the regulator should not be forced to any
+  particular mode
+
+- qcom,force-mode-lpm:
+   Usage: optional
+   Value type: 
+   Definition: indicates that 

Re: [PATCH 2/3] mfd: qcom-rpm: Driver for the Qualcomm RPM

2014-05-29 Thread Srinivas Kandagatla

Hi Bjorn,

On 27/05/14 18:28, Bjorn Andersson wrote:

Driver for the Resource Power Manager (RPM) found in Qualcomm 8660, 8960 and
8064 based devices. The driver exposes resources that child drivers can operate
on; to implementing regulator, clock and bus frequency drivers.

Signed-off-by: Bjorn Andersson 
---
  drivers/mfd/Kconfig  |  15 ++
  drivers/mfd/Makefile |   1 +
  drivers/mfd/qcom_rpm.c   | 575 +++
  include/linux/mfd/qcom_rpm.h |  12 +
  4 files changed, 603 insertions(+)
  create mode 100644 drivers/mfd/qcom_rpm.c
  create mode 100644 include/linux/mfd/qcom_rpm.h

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 3383412..e5122a7 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -482,6 +482,21 @@ config UCB1400_CORE
  To compile this driver as a module, choose M here: the
  module will be called ucb1400_core.

+config MFD_QCOM_RPM
+   tristate "Qualcomm Resource Power Manager (RPM)
+   depends on ARCH_QCOM && OF
+   select MFD_CORE
+   help
+ If you say yes to this option, support will be included for the
+ Resource Power Manager system found in the Qualcomm 8660, 8960 and
+ 8064 based devices.
+
+ This is required to access many regulators, clocks and bus
+ frequencies controlled by the RPM on these devices.
+
+ Say M here if you want to include support for the Qualcomm RPM as a
+ module. This will build a module called "qcom_rpm".
+
  config MFD_PM8XXX
tristate

diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 2851275..bbe4209 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -150,6 +150,7 @@ obj-$(CONFIG_MFD_SI476X_CORE)   += si476x-core.o

  obj-$(CONFIG_MFD_CS5535)  += cs5535-mfd.o
  obj-$(CONFIG_MFD_OMAP_USB_HOST)   += omap-usb-host.o omap-usb-tll.o
+obj-$(CONFIG_MFD_QCOM_RPM) += qcom_rpm.o
  obj-$(CONFIG_MFD_PM8921_CORE) += pm8921-core.o ssbi.o
  obj-$(CONFIG_TPS65911_COMPARATOR) += tps65911-comparator.o
  obj-$(CONFIG_MFD_TPS65090)+= tps65090.o
diff --git a/drivers/mfd/qcom_rpm.c b/drivers/mfd/qcom_rpm.c
new file mode 100644
index 000..96135ab
--- /dev/null
+++ b/drivers/mfd/qcom_rpm.c
@@ -0,0 +1,575 @@
+/*
+ * Copyright (c) 2014, Sony Mobile Communications AB.
+ * Copyright (c) 2013, 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 
+#include 
+#include 
+
+#include 
+
+#include 
+
+struct qcom_rpm_resource {
+   unsigned target_id;
+   unsigned status_id;
+   unsigned select_id;
+   unsigned size;
+};
+
+struct qcom_rpm {
+   struct device *dev;
+   struct completion ack;
+   struct mutex lock;
+
+   void __iomem *status_regs;
+   void __iomem *ctrl_regs;
+   void __iomem *req_regs;
+
+   void __iomem *ipc_rpm_reg;
+
+   u32 ack_status;
+
+   u32 version;
+
+   const struct qcom_rpm_resource *resource_table;
+   unsigned n_resources;


the line spacing looks bit odd.

+};
+
+#define RPM_STATUS_REG(rpm, i) ((rpm)->status_regs + (i) * 4)
+#define RPM_CTRL_REG(rpm, i)   ((rpm)->ctrl_regs + (i) * 4)
+#define RPM_REQ_REG(rpm, i)((rpm)->req_regs + (i) * 4)


Probably you could make these macros bit more generic by removing the 
rpm and let the calling code dereference it.



+
+#define RPM_REQUEST_TIMEOUT(5 * HZ)
+
+#define RPM_REQUEST_CONTEXT3
+#define RPM_REQ_SELECT 11
+#define RPM_ACK_CONTEXT15
+#define RPM_ACK_SELECTOR   23
+#define RPM_SELECT_SIZE7
+
+#define RPM_ACTIVE_STATE   BIT(0)
+#define RPM_NOTIFICATION   BIT(30)
+#define RPM_REJECTED   BIT(31)
+
+#define RPM_SIGNAL BIT(2)
+
+static const struct qcom_rpm_resource apq8064_rpm_resource_table[] = {
+   [QCOM_RPM_CXO_CLK] ={ 25, 9, 5, 1 },
+   [QCOM_RPM_PXO_CLK] ={ 26, 10, 6, 1 },
+   [QCOM_RPM_APPS_FABRIC_CLK] ={ 27, 11, 8, 1 },
+   [QCOM_RPM_SYS_FABRIC_CLK] = { 28, 12, 9, 1 },
+   [QCOM_RPM_MM_FABRIC_CLK] =  { 29, 13, 10, 1 },
+   [QCOM_RPM_DAYTONA_FABRIC_CLK] = { 30, 14, 11, 1 },
+   [QCOM_RPM_SFPB_CLK] =   { 31, 15, 12, 1 },
+   [QCOM_RPM_CFPB_CLK] =   { 32, 16, 13, 1 },
+   [QCOM_RPM_MMFPB_CLK] =  { 33, 17, 14, 1 },
+   [QCOM_RPM_EBI1_CLK] =   { 34, 18, 16, 1 },
+   [Q

Re: [PATCH 1/3] mfd: devicetree: bindings: Add Qualcomm RPM DT binding

2014-05-29 Thread Srinivas Kandagatla



On 29/05/14 17:30, Kumar Gala wrote:


On May 29, 2014, at 11:19 AM, Srinivas Kandagatla 
 wrote:


+= SUBDEVICES
+
+The RPM exposes resources to its subnodes. The below bindings specify the set
+of valid subnodes that can operate on these resources.


Why should these devices be on sub nodes?

Any reason not to implement it like this,

rpm: rpm@108000 {
compatible = "qcom,rpm-msm8960";
reg = <0x108000 0x1000 0x2011008 0x4>;

interrupts = <0 19 0>, <0 21 0>, <0 22 0>;
interrupt-names = "ack", "err", "wakeup";
};

pm8921_s1: pm8921-s1 {
compatible = "qcom,rpm-pm8921-smps";

regulator-min-microvolt = <1225000>;
regulator-max-microvolt = <1225000>;
regulator-always-on;

qcom,rpm = <&rpm QCOM_RPM_PM8921_S1>;
qcom,switch-mode-frequency = <320>;
qcom,hpm-threshold = <10>;
};

This would simplify the driver code too and handle the interface neatly then 
depending on device hierarchy.
rpm would be a interface library to the clients. Makes the drivers more 
independent, and re-usable if we do this way.

??


One reason to go with sub nodes is it creates a proper driver ordering 
dependency as I assume rpm driver will end up calling of_platform_populate for 
the sub nodes at the point that the RPM driver is ready.  We could do this with 
deferred probe but doing it explicitly is better in my opinion as it limits the 
amount of time between when RPM is ready vs when the children can start doing 
things



I agree, there might be a win. But Am not sure to what extent this win 
is a win to rpm driver, as a side effect this brings other 
responsibilities to the rpm driver like adding sub-device power 
management awareness, device life cycle management to the rpm driver.


Only thing which made me think of this approach is the number of sub 
nodes it would end up with and passing ID using reg property.


Thanks,
srini


- k


--
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 1/3] mfd: devicetree: bindings: Add Qualcomm RPM DT binding

2014-05-29 Thread Srinivas Kandagatla



On 29/05/14 19:38, Bjorn Andersson wrote:

On Thu, May 29, 2014 at 9:19 AM, Srinivas Kandagatla
 wrote:

+- reg:
+   Usage: required
+   Value type: 
+   Definition: two entries specifying the RPM's message ram and ipc
register
+
+- reg-names:
+   Usage: required
+   Value type: 
+   Definition: must contain the following, in order:
+   "msg_ram"
+   "ipc"



+1 for kumar's comment.

cant enforce the order here. should fix it in the driver.



Yes I can, this is as decided by the devicetree maintainers. The order
of e.g. reg and interrupts must be defined.


Does not make sense. Unless Am missing something obvious.
Having reg-names/interrupt-names would give driver flexibility to get 
the resources by name, as long as the order of reg and reg-names match.


So the order of reg is really not really necessary. Unless the driver is 
coded to access it via index.


Hardly 1/2 bindings documents enforce this.



+= SUBDEVICES
+
+The RPM exposes resources to its subnodes. The below bindings specify the
set
+of valid subnodes that can operate on these resources.



Why should these devices be on sub nodes?

Any reason not to implement it like this,

rpm: rpm@108000 {
 compatible = "qcom,rpm-msm8960";

 reg = <0x108000 0x1000 0x2011008 0x4>;

 interrupts = <0 19 0>, <0 21 0>, <0 22 0>;
 interrupt-names = "ack", "err", "wakeup";
};

pm8921_s1: pm8921-s1 {
 compatible = "qcom,rpm-pm8921-smps";

 regulator-min-microvolt = <1225000>;
 regulator-max-microvolt = <1225000>;
 regulator-always-on;

 qcom,rpm = <&rpm QCOM_RPM_PM8921_S1>;
 qcom,switch-mode-frequency = <320>;
 qcom,hpm-threshold = <10>;
};

This would simplify the driver code too and handle the interface neatly then
depending on device hierarchy.
rpm would be a interface library to the clients. Makes the drivers more
independent, and re-usable if we do this way.


The subnodes doesn't describe separate pieces of hardware but rather
pieces of the rpm, that's why they should live inside the rpm. There
will not be any re-use of these drivers outside having a rpm as
parent.

I do have some patches for family b, where I'm moving things around a
little bit in the implementation to be able to re-use child-devices
where that makes sense (clock implementation is the same for the two).
But that is implementation specific and does not affect the dt.


Good point, Am more of thinking of some other SOCs might have similar pmic.



Implementation wise, having the individual subnodes as children in the
device model makes a lot of sense, as the children should be probed
when the rpm appears and when the rpm goes away it should bring down
all subnodes. If there was any power management it would be the same
thing.

Thats great, you have already thought about it.


So I think this makes for a cleaner implementation; all I need to do
is to call of_platform_populate at the end of the probe and in remove
I need to tell the children that they should go away. I do not need to
support any phandle based lookups and separate life cycle management.


Am ok with either approaches.



[...


+- qcom,force-mode-none:
+   Usage: optional (default if no other qcom,force-mode is specified)
+   Value type: 
+   Defintion: indicates that the regulator should not be forced to
any
+  particular mode
+
+- qcom,force-mode-lpm:
+   Usage: optional
+   Value type: 
+   Definition: indicates that the regulator should be forced to
operate in
+   low-power-mode
+
+- qcom,force-mode-auto:
+   Usage: optional (only available for 8960/8064)
+   Value type: 
+   Definition: indicates that the regulator should be automatically
pick
+   operating mode
+
+- qcom,force-mode-hpm:
+   Usage: optional (only available for 8960/8064)
+   Value type: 
+   Definition: indicates that the regulator should be forced to
operate in
+   high-power-mode
+
+- qcom,force-mode-bypass: (only for 8960/8064)
+   Usage: optional (only available for 8960/8064)
+   Value type: 
+   Definition: indicates that the regulator should be forced to
operate in
+   bypass mode
+


...]

Probably qcom,force-mode:
 Usage: optional.
 Value type: 

 Definition: must be one of:
 "none"
 "lpm"
 "auto"
 "hpm"
 "bypass"

Makes it much simpler, as they seems to be mutually exclusive. simillar
comments apply to other bindings too.


Please see my answer to Kumar.


Ok. I don’t have a strong feeling on any of those 3 approaches.

Thanks,
srini


Thanks for the comments!

Regards,
Bjorn


--
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/3] mfd: qcom-rpm: Driver for the Qualcomm RPM

2014-05-29 Thread Srinivas Kandagatla



On 29/05/14 20:45, Bjorn Andersson wrote:

On Thu, May 29, 2014 at 9:19 AM, Srinivas Kandagatla
 wrote:

+++ b/drivers/mfd/qcom_rpm.c



the line spacing looks bit odd.



I'll fix


+};
+
+#define RPM_STATUS_REG(rpm, i) ((rpm)->status_regs + (i) * 4)
+#define RPM_CTRL_REG(rpm, i)   ((rpm)->ctrl_regs + (i) * 4)
+#define RPM_REQ_REG(rpm, i)((rpm)->req_regs + (i) * 4)



Probably you could make these macros bit more generic by removing the rpm
and let the calling code dereference it.




I first open coded them, I then had separate writel/readl wrappers for them and
then I settled for this, as I figured it help clarifying the code. I can have
another look at it, but I don't think that below will make things clearer.

#define RPM_IDX_2_OFFSET(i) ((i) * 4)



Yes, just leave it as it is.

[...]




+static int qcom_rpm_probe(struct platform_device *pdev)
+{
+   const struct of_device_id *match;
+   const struct qcom_rpm *template;
+   struct resource *res;
+   struct qcom_rpm *rpm;
+   u32 fw_version[3];
+   int irq_wakeup;
+   int irq_ack;
+   int irq_err;
+   int ret;
+
+   rpm = devm_kzalloc(&pdev->dev, sizeof(*rpm), GFP_KERNEL);



Sorry If I missed somthing obvious, But why not just use the structure from
of_data. Is the global structure going to be used for something else?

Or make a seperate structure for of_data and not use struct qcom_rpm?





Although we will not have more than one rpm in a system and therefore not
instatiate this driver multiple times I do not want to run it off the global
state.


I agree.

Why not make a separate data structure for the qcom_of_data?


+   if (!rpm) {
+   dev_err(&pdev->dev, "Can't allocate qcom_rpm\n");


message not necessary as kernel will print the alocation failures.



Thanks!


+   return -ENOMEM;
+   }


[...]


+
+   res = platform_get_resource(pdev, IORESOURCE_MEM, 0);


Should't you use the platform_get_resource_byname here?

missed error case checks too.



This is a fairly commonly used construct, to have the error from
platform_get_resource being propagated through devm_ioremap_resource and catch
it there. It gives an extra error print in the log, but I find it very clean.

Sorry I missed that point...


But my point on platform_get_resource_byname is to remove the dependency 
on the resource ordering, It is very difficult to catch errors resulting 
in wrong ordered resources in DT.





+   rpm->status_regs = devm_ioremap_resource(&pdev->dev, res);
+   rpm->ctrl_regs = rpm->status_regs + 0x400;
+   rpm->req_regs = rpm->status_regs + 0x600;
+   if (IS_ERR(rpm->status_regs))
+   return PTR_ERR(rpm->status_regs);
+
+   res = platform_get_resource(pdev, IORESOURCE_MEM, 1);


Dito.



[...]




[ ..


+   ret = irq_set_irq_wake(irq_ack, 1);
+   if (ret)
+   dev_warn(&pdev->dev, "failed to mark ack irq as
wakeup\n");
+


..]

Shouln't these be set as part of the pm suspend call, if the device is
wakeup capable?




Is there any reason to toggle this?

I'm not sure when this interrupt will actually be fired, but I don't see any
harm in keeping it wakup enabled at all times.


Typically the wake-up source is driven/enabled by the user. When the 
system goes to low-power state it would enable the wakeup on the irq. 
And when there is an interrupt it would wake up the system as part of 
resuming from low-power state.


Again if you what this interrupt to wakeup the system, I would expect 
pm_wakeup_event/related calls in the interrupt handler too.




[...]


+++ b/include/linux/mfd/qcom_rpm.h
@@ -0,0 +1,12 @@
+#ifndef __QCOM_RPM_H__
+#define __QCOM_RPM_H__
+
+#include 
+
+struct device;
+struct qcom_rpm;
+
+struct qcom_rpm *dev_get_qcom_rpm(struct device *dev);
+int qcom_rpm_write(struct qcom_rpm *rpm, int resource, u32 *buf, size_t
count);



IMHO, dummy functions for these are required, otherwise you would get a
compilation errors on client drivers.



I didn't expect us to compile the children into a kernel that doesn't have the
rpm, as I see them as one entity. An exception would be if we want to add
COMPILE_TEST to the children, but that would require an extra change anyways.

Thanks for the review!


NP,

Thanks,
srini


Regards,
Bjorn


--
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 v4 03/13] mmc: mmci: Add Qualcomm Id to amba id table

2014-05-30 Thread Srinivas Kandagatla



On 30/05/14 10:39, Ulf Hansson wrote:

On 28 May 2014 15:46,   wrote:

From: Srinivas Kandagatla 

This patch adds a fake Qualcomm ID 0x00051180 to the amba_ids, as Qualcomm
SDCC controller is pl180, but amba id registers read 0x0's.
The plan is to remove SDCC driver totally and use mmci as the main SD
controller driver for Qualcomm SOCs.

Signed-off-by: Srinivas Kandagatla 
Reviewed-by: Linus Walleij 
---
  drivers/mmc/host/mmci.c | 14 ++
  1 file changed, 14 insertions(+)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index a38e714..86f25a9 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -160,6 +160,14 @@ static struct variant_data variant_ux500v2 = {
 .pwrreg_nopower = true,
  };

+static struct variant_data variant_qcom = {
+   .fifosize   = 16 * 4,
+   .fifohalfsize   = 8 * 4,
+   .clkreg = MCI_CLK_ENABLE,
+   .datalength_bits= 24,
+   .pwrreg_powerup = MCI_PWR_UP,
+};
+
  static int mmci_card_busy(struct mmc_host *mmc)
  {
 struct mmci_host *host = mmc_priv(mmc);
@@ -1750,6 +1758,12 @@ static struct amba_id mmci_ids[] = {
 .mask   = 0xf0ff,
 .data   = &variant_ux500v2,
 },
+   /* Qualcomm variants */
+   {
+   .id = 0x00051180,
+   .mask   = 0x000f,
+   .data   = &variant_qcom,
+   },
 { 0, 0 },
  };


Shouldn't this patch be moved to very end of this patchset?

If we would apply this patch on it's own - the Qcom variant wouldn't
work, right?

Yes, I would not work. I will move it to the end of the patchset.

Thanks,
srini


Kind regards
Ulf Hansson



--
1.9.1


--
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 v4 06/13] mmc: mmci: add ddrmode mask to variant data

2014-05-30 Thread Srinivas Kandagatla



On 30/05/14 10:35, Ulf Hansson wrote:

On 28 May 2014 15:46,   wrote:

From: Srinivas Kandagatla 

This patch adds ddrmode mask to variant structure giving more flexibility
to the driver to support more SOCs which have different datactrl register
layout.

Without this patch datactrl register is updated with wrong ddrmode mask on non
ST SOCs, resulting in card detection failures.


The above statement seems not correct. We don't have any issues
currently, right. :-)

I should have said Qualcomm instead of generalizing it to non-ST SOCs.
Will fix this in next version.

Thanks,
srini


Kind regards
Ulf Hansson



Signed-off-by: Srinivas Kandagatla 
Reviewed-by: Linus Walleij 
---
  drivers/mmc/host/mmci.c | 5 -
  1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 23401b0..729105b 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -59,6 +59,7 @@ static unsigned int fmax = 515633;
   *   is asserted (likewise for RX)
   * @sdio: variant supports SDIO
   * @st_clkdiv: true if using a ST-specific clock divider algorithm
+ * @datactrl_mask_ddrmode: ddr mode mask in datactrl register.
   * @blksz_datactrl16: true if Block size is at b16..b30 position in datactrl 
register
   * @blksz_datactrl4: true if Block size is at b4..b16 position in datactrl
   *  register
@@ -74,6 +75,7 @@ struct variant_data {
 unsigned intdatalength_bits;
 unsigned intfifosize;
 unsigned intfifohalfsize;
+   unsigned intdatactrl_mask_ddrmode;
 boolsdio;
 boolst_clkdiv;
 boolblksz_datactrl16;
@@ -152,6 +154,7 @@ static struct variant_data variant_ux500v2 = {
 .fifohalfsize   = 8 * 4,
 .clkreg = MCI_CLK_ENABLE,
 .clkreg_enable  = MCI_ST_UX500_HWFCEN,
+   .datactrl_mask_ddrmode  = MCI_ST_DPSM_DDRMODE,
 .datalength_bits= 24,
 .sdio   = true,
 .st_clkdiv  = true,
@@ -779,7 +782,7 @@ static void mmci_start_data(struct mmci_host *host, struct 
mmc_data *data)
 }

 if (host->mmc->ios.timing == MMC_TIMING_UHS_DDR50)
-   datactrl |= MCI_ST_DPSM_DDRMODE;
+   datactrl |= variant->datactrl_mask_ddrmode;

 /*
  * Attempt to use DMA operation mode, if this
--
1.9.1


--
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 v4 09/13] mmc: mmci: add Qcom specifics of clk and datactrl registers.

2014-05-30 Thread Srinivas Kandagatla



On 30/05/14 10:55, Ulf Hansson wrote:

On 28 May 2014 15:47,   wrote:

From: Srinivas Kandagatla 

This patch adds specifics of clk and datactrl register on Qualcomm SD
Card controller. This patch also populates the Qcom variant data with
these new values specific to Qualcomm SD Card Controller.

Signed-off-by: Srinivas Kandagatla 
Reviewed-by: Linus Walleij 
---
  drivers/mmc/host/mmci.c |  4 
  drivers/mmc/host/mmci.h | 17 +
  2 files changed, 21 insertions(+)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 8deea4a..dbcb952 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -179,6 +179,10 @@ static struct variant_data variant_qcom = {
 .fifosize   = 16 * 4,
 .fifohalfsize   = 8 * 4,
 .clkreg = MCI_CLK_ENABLE,
+   .clkreg_enable  = MCI_QCOM_CLK_FLOWENA |
+ MCI_QCOM_CLK_SELECT_IN_FBCLK,
+   .clkreg_8bit_bus_enable = MCI_QCOM_CLK_WIDEBUS_8,
+   .datactrl_mask_ddrmode  = MCI_QCOM_CLK_SELECT_IN_DDR_MODE,


This stuff should go in patch3.


Yes, I will merge patch3 and this change-set in next version.




 .blksz_datactrl4= true,
 .datalength_bits= 24,
 .pwrreg_powerup = MCI_PWR_UP,
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h
index cd83ca3..706eb513 100644
--- a/drivers/mmc/host/mmci.h
+++ b/drivers/mmc/host/mmci.h
@@ -41,6 +41,15 @@
  /* Modified PL180 on Versatile Express platform */
  #define MCI_ARM_HWFCEN BIT(12)

+/* Modified on Qualcomm Integrations */
+#define MCI_QCOM_CLK_WIDEBUS_8 (BIT(10) | BIT(11))
+#define MCI_QCOM_CLK_FLOWENA   BIT(12)
+#define MCI_QCOM_CLK_INVERTOUT BIT(13)
+
+/* select in latch data and command in */
+#define MCI_QCOM_CLK_SELECT_IN_FBCLK   BIT(15)
+#define MCI_QCOM_CLK_SELECT_IN_DDR_MODE(BIT(14) | BIT(15))
+
  #define MMCIARGUMENT   0x008
  #define MMCICOMMAND0x00c
  #define MCI_CPSM_RESPONSE  BIT(6)
@@ -54,6 +63,14 @@
  #define MCI_ST_NIENBIT(13)
  #define MCI_ST_CE_ATACMD   BIT(14)

+/* Modified on Qualcomm Integrations */
+#define MCI_QCOM_CSPM_DATCMD   BIT(12)
+#define MCI_QCOM_CSPM_MCIABORT BIT(13)
+#define MCI_QCOM_CSPM_CCSENABLEBIT(14)
+#define MCI_QCOM_CSPM_CCSDISABLE   BIT(15)
+#define MCI_QCOM_CSPM_AUTO_CMD19   BIT(16)
+#define MCI_QCOM_CSPM_AUTO_CMD21   BIT(21)
+


Maybe you should have one patch in the beginning of the patchset, that
adds all the new QCOM bits in the header file? Instead of splitting
them up?

Ok, I will do that in next version.

Thanks,
srini



  #define MMCIRESPCMD0x010
  #define MMCIRESPONSE0  0x014
  #define MMCIRESPONSE1  0x018
--
1.9.1



Kind regards
Ulf Hansson


--
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 v4 11/13] mmc: mmci: add f_max to variant structure

2014-05-30 Thread Srinivas Kandagatla

Thanks Ulf,

On 30/05/14 11:28, Ulf Hansson wrote:

  */
>-   if (host->mclk > 1) {
>-   ret = clk_set_rate(host->clk, 1);
>+   if (host->mclk > host->variant->f_max) {

You can use the local variant pointer directly, instead of host->variant.


yes, Will do that in next version.

Thanks,
srini

>+   ret = clk_set_rate(host->clk, host->variant->f_max);
> if (ret < 0)
> goto clk_disable;
> host->mclk = clk_get_rate(host->clk);
>--

--
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 v4 12/13] mmc: mmci: add explicit clk control

2014-05-30 Thread Srinivas Kandagatla

Thanks Ulf for reviewing.

On 30/05/14 11:25, Ulf Hansson wrote:

On 28 May 2014 15:47,   wrote:

From: Srinivas Kandagatla 

On Controllers like Qcom SD card controller where cclk is mclk and mclk should
be directly controlled by the driver.

This patch adds support to control mclk directly in the driver, and also
adds explicit_mclk_control flag in variant structure giving more flexibility
to the driver.

Signed-off-by: Srinivas Kandagatla 
---
  drivers/mmc/host/mmci.c | 96 -
  drivers/mmc/host/mmci.h |  2 ++
  2 files changed, 65 insertions(+), 33 deletions(-)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 202f2d5..6eb0a29 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -72,6 +72,7 @@ static unsigned int fmax = 515633;
   * @pwrreg_clkgate: MMCIPOWER register must be used to gate the clock
   * @busy_detect: true if busy detection on dat0 is supported
   * @pwrreg_nopower: bits in MMCIPOWER don't controls ext. power supply
+ * @explicit_mclk_control: enable explicit mclk control in driver.
   */
  struct variant_data {
 unsigned intclkreg;
@@ -93,6 +94,7 @@ struct variant_data {
 boolpwrreg_clkgate;
 boolbusy_detect;
 boolpwrreg_nopower;
+   boolexplicit_mclk_control;
  };

  static struct variant_data variant_arm = {
@@ -199,6 +201,7 @@ static struct variant_data variant_qcom = {
 .datalength_bits= 24,
 .pwrreg_powerup = MCI_PWR_UP,
 .f_max  = 20800,
+   .explicit_mclk_control  = true,


This should go in patch3 instead.


yes.. will get this in to the patch3 too.




  };

  static int mmci_card_busy(struct mmc_host *mmc)
@@ -301,7 +304,9 @@ static void mmci_set_clkreg(struct mmci_host *host, 
unsigned int desired)
 host->cclk = 0;

 if (desired) {
-   if (desired >= host->mclk) {
+   if (variant->explicit_mclk_control) {
+   host->cclk = host->mclk;
+   } else if (desired >= host->mclk) {
 clk = MCI_CLK_BYPASS;
 if (variant->st_clkdiv)
 clk |= MCI_ST_UX500_NEG_EDGE;
@@ -1340,6 +1345,18 @@ static void mmci_set_ios(struct mmc_host *mmc, struct 
mmc_ios *ios)
 if (!ios->clock && variant->pwrreg_clkgate)
 pwr &= ~MCI_PWR_ON;

+   if ((host->variant->explicit_mclk_control) &&
+   (ios->clock != host->mclk_req)) {
+   int rc = clk_set_rate(host->clk, ios->clock);
+   if (rc < 0) {
+   dev_err(mmc_dev(host->mmc),
+   "Error setting clock rate (%d)\n", rc);
+   } else {
+   host->mclk = clk_get_rate(host->clk);
+   host->mclk_req = ios->clock;
+   }
+   }
+
 spin_lock_irqsave(&host->lock, flags);

 mmci_set_clkreg(host, ios->clock);
@@ -1490,19 +1507,6 @@ static int mmci_probe(struct amba_device *dev,
 host->plat = plat;
 host->variant = variant;
 host->mclk = clk_get_rate(host->clk);
-   /*
-* According to the spec, mclk is max 100 MHz,
-* so we try to adjust the clock down to this,
-* (if possible).
-*/
-   if (host->mclk > host->variant->f_max) {
-   ret = clk_set_rate(host->clk, host->variant->f_max);
-   if (ret < 0)
-   goto clk_disable;
-   host->mclk = clk_get_rate(host->clk);
-   dev_dbg(mmc_dev(mmc), "eventual mclk rate: %u Hz\n",
-   host->mclk);
-   }


The above code is relevant for Qcom as well, I don't think you need
change/move it.

Yes, you are right. I will fix it in next version.




 host->phybase = dev->res.start;
 host->base = devm_ioremap_resource(&dev->dev, &dev->res);
@@ -1511,25 +1515,51 @@ static int mmci_probe(struct amba_device *dev,
 goto clk_disable;
 }

-   /*
-* The ARM and ST versions of the block have slightly different
-* clock divider equations which means that the minimum divider
-* differs too.
-*/
-   if (variant->st_clkdiv)
-   mmc->f_min = DIV_ROUND_UP(host->mclk, 257);


I think you could simplify the change of fixing with f_min and f_max.

Start by, just add another statement here "else if
(variant->explicit_mclk_control)" and do the clk_round_rate()


-   else
-   mmc->f_min = DIV_ROUND_UP(host->mclk, 512);
-   /*
-* If no maximum operating 

Re: [PATCH v4 13/13] mmc: mmci: Add Qcom specific pio_read function.

2014-05-30 Thread Srinivas Kandagatla

Hi Ulf,

On 30/05/14 12:27, Ulf Hansson wrote:

On 28 May 2014 15:48,   wrote:

...


 .f_max  = 20800,
 .explicit_mclk_control  = true,
+   .qcom_fifo  = true,
  };

  static int mmci_card_busy(struct mmc_host *mmc)
@@ -1006,6 +1009,40 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command 
*cmd,
 }
  }

+static int mmci_qcom_pio_read(struct mmci_host *host, char *buffer,
+   unsigned int remain)
+{
+   u32 *ptr = (u32 *) buffer;


Instead of u32 ptr above, I suggest to use a char *ptr. You need it
anyway further down below where you move in step of bytes instead of
words.


+   unsigned int count = 0;
+   unsigned int words, bytes;
+   unsigned int fsize = host->variant->fifosize;
+
+   words = remain >> 2;
+   bytes = remain % 4;
+   /* read full words followed by leftover bytes */
+   if (words) {
+   while (readl(host->base + MMCISTATUS) & MCI_RXDATAAVLBL) {


How about while (words && (readl(host->base + MMCISTATUS) & MCI_RXDATAAVLBL)

That would make it possible the remove the "if", both above and below.


That sounds sensible.. I will try it.



+   *ptr = readl(host->base + MMCIFIFO + (count % fsize));


This looks strange. :-) Depending on the count you will read an offset
into the FIFO? Seems like a very awkward implementation of a FIFO in
the HW. :-)

I got into weird issues when I tried using the mmci_pio_read, the fifo 
implementation seems to be different. I dont have full details on the 
fifo behaviour.


Most of this logic is inherited from 3.4 qcom andriod kernel.


BTW, what does "MCI_RXDATAAVLBL" actually mean for the Qcom variant?


It means, At least 1 word in the RX FIFO. SW can read 1 word only from 
the FIFO.



How much data could you expect in the FIFO when this status is
triggered?



Are there no option of reading a number of words, depending on what
type FIFO IRQ that was raised?
There are RXFIFO_HALF_FULL and RXFIFO_FULL bits in status register, but 
I never tried to use them. Might be worth a try before I send next 
version patches.



I will give a try and keep you posted.
Thanks,
srini



+   ptr++;
+   count += 4;
+   words--;
+   if (!words)
+   break;
+   }
+   }
+
+   if (bytes) {
+   unsigned char buf[4];
+   if (readl(host->base + MMCISTATUS) & MCI_RXDATAAVLBL) {
+   *buf = readl(host->base + MMCIFIFO + (count % fsize));
+   memcpy(ptr, buf, bytes);
+   count += bytes;
+   }
+   }
+
+   return count;
+}
+






Kind regards
Ulf Hansson


--
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 v4 13/13] mmc: mmci: Add Qcom specific pio_read function.

2014-05-30 Thread Srinivas Kandagatla

Hi Ulf,

Managed to reuse the existing mmci_pio_read function with some minor 
modifications, Issue was with reading full fifo sizes which was creating 
the issue.


On 30/05/14 12:44, Srinivas Kandagatla wrote:

That sounds sensible.. I will try it.



+   *ptr = readl(host->base + MMCIFIFO + (count %
fsize));


This looks strange. :-) Depending on the count you will read an offset
into the FIFO? Seems like a very awkward implementation of a FIFO in
the HW. :-)


I got into weird issues when I tried using the mmci_pio_read, the fifo
implementation seems to be different. I dont have full details on the
fifo behaviour.

Most of this logic is inherited from 3.4 qcom andriod kernel.


BTW, what does "MCI_RXDATAAVLBL" actually mean for the Qcom variant?


It means, At least 1 word in the RX FIFO. SW can read 1 word only from
the FIFO.


How much data could you expect in the FIFO when this status is
triggered?



Are there no option of reading a number of words, depending on what
type FIFO IRQ that was raised?

There are RXFIFO_HALF_FULL and RXFIFO_FULL bits in status register, but
I never tried to use them. Might be worth a try before I send next
version patches.


--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -73,6 +73,7 @@ static unsigned int fmax = 515633;
  * @busy_detect: true if busy detection on dat0 is supported
  * @pwrreg_nopower: bits in MMCIPOWER don't controls ext. power supply
  * @explicit_mclk_control: enable explicit mclk control in driver.
+ * @qcom_fifo: enables qcom specific fifo pio read logic.
  */
 struct variant_data {
unsigned intclkreg;
@@ -95,6 +96,7 @@ struct variant_data {
boolbusy_detect;
boolpwrreg_nopower;
boolexplicit_mclk_control;
+   boolqcom_fifo;
 };

 static struct variant_data variant_arm = {
@@ -990,15 +992,33 @@ mmci_cmd_irq(struct mmci_host *host, struct 
mmc_command *cmd,

}
 }

+static int mmci_get_rx_fifocnt(struct mmci_host *host, u32 status, int 
remain)

+{
+   return remain - (readl(host->base + MMCIFIFOCNT) << 2);
+}
+
+static int mmci_qcom_get_rx_fifocnt(struct mmci_host *host, u32 status, 
int r)

+{
+   /*
+* on qcom SDCC4 only 8 words are used in each burst so only 8 
addresses

+* from the fifo range should be used
+*/
+   if (status & MCI_RXFIFOHALFFULL)
+   return host->variant->fifohalfsize;
+   else
+   return 4;
+}
+
 static int mmci_pio_read(struct mmci_host *host, char *buffer, 
unsigned int remain)

 {
void __iomem *base = host->base;
char *ptr = buffer;
-   u32 status;
+   int hf = host->variant->fifohalfsize;
int host_remain = host->size;
+   u32 status = readl(host->base + MMCISTATUS);

do {
-   int count = host_remain - (readl(base + MMCIFIFOCNT) << 2);
+   int count = host->get_rx_fifocnt(host, status, host_remain);

if (count > remain)
count = remain;
@@ -1488,6 +1508,11 @@ static int mmci_probe(struct amba_device *dev,
if (ret)
goto host_free;

+   if (variant->qcom_fifo)
+   host->get_rx_fifocnt = mmci_qcom_get_rx_fifocnt;
+   else
+   host->get_rx_fifocnt = mmci_get_rx_fifocnt;
+
host->plat = plat;
host->variant = variant;
host->mclk = clk_get_rate(host->clk);
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h
index b5f0810..5f76670 100644
--- a/drivers/mmc/host/mmci.h
+++ b/drivers/mmc/host/mmci.h
@@ -229,6 +229,7 @@ struct mmci_host {
/* pio stuff */
struct sg_mapping_iter  sg_miter;
unsigned intsize;
+   int (*get_rx_fifocnt)(struct mmci_host *h, u32 status, int remain);

 #ifdef CONFIG_DMA_ENGINE
--
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 00/13] Add Qualcomm SD Card Controller support

2014-05-30 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

Thankyou Linus W, Ulf H and everyone for reviewing RFC to v4 patches.

This patch series adds Qualcomm SD Card Controller support in pl180 mmci
driver. QCom SDCC is basically a pl180, but bit more customized, some of the
register layouts and offsets are different to the ones mentioned in pl180
datasheet. The plan is to totally remove the standalone SDCC driver
drivers/mmc/host/msm_sdcc.* and start using generic mmci driver for all
Qualcomm parts, as we get chance to test on other Qcom boards.

To start using the existing mmci driver, a fake amba id for Qualcomm is added
in patches:
 mmc: mmci: Add Qualcomm specific register defines.
 mmc: mmci: Add Qualcomm Id to amba id table.

Second change is, adding a 3 clock cycle delay in between writes to
CLKCTRL/POWER/DATACTRL/COMMAND registers. Most of the delays are taken care with
the existing driver except delay for the COMMAND register was too small. 
This patch fixes it.
  mmc: mmci: Add enough delay between writes to CMD register.

Third change is to accommodate CLK, DATCTRL and MMCICLK register layout changes
in Qcom SDCC and provide more flexibity in driver to specify these changes via
variant datastructure. Which are done in patches:
  mmc: mmci: Add Qcom datactrl register variant
  mmc: mmci: add ddrmode mask to variant data
  mmc: mmci: add 8bit bus support in variant data
  mmc: mmci: add edge support to data and command out in variant data.
  mmc: mmci: add Qcom specifics of clk and datactrl registers.
  mmc: mmci: Add support to data commands via variant structure.
  mmc: mmci: add f_max to variant structure
  mmc: mmci: add explicit clk control

Fourth change was to add qcom specfic fifocnt logic, the need for
this is because the way MCIFIFOCNT register behaved in QCOM SDCC is very
 different to the one in pl180. This change is done in patch:
  mmc: mmci: Add Qcom specific rx_fifocnt logic.

Last some Qcom unrelated changes/cleanup to driver are done in patches:
  mmc: mmci: use NSEC_PER_SEC macro
  mmc: mmci: convert register bits to use BIT() macro.

This patches are tested in PIO mode on IFC8064 board with both eMMC and
external SD card. I would like to get this support in v3.16.

Changes from v4:
- moved the amba id table addition to the end of the patchset as 
suggested by Ulf.
- reused the mmci_pio_read function after experimenting with the fifo 
behaviour.
- simplify f_max/f_min calculation logic as suggested by Ulf.
- created a new patch for the register defination as suggested by Ulf.

Changes from v3:
- moved pio_read to a function pointer so as to reduce additional cycles
in hot-path, suggested by Ulf.
- simplify the flags used for explicit mclk control, suggested by Ulf.
- fixed issues in cacluating f_max and f_min pointed and suggested by 
Ulf.
- removed unessary DDR flags on un-supported STE variants.
- used BIT macros as suggested by Ulf.
- removed the read/write wrappers with delays, and used most optimal way
to introduce the delays to the only registers that require delays.

Changes from v2:
- merged fbclk latch patch with clkreg_enable patch as suggested by 
Linus W.
- remove qcom prefix for explicit clk control pointed by Linus W.
- cleaned up mmci_qcom_pio_read and consider SDIO as suggested by Linus 
W.

Changes from v1:
- moved most of the SOC specifics to variant parameters as suggested
  by Linus W.
- renamed registers as suggested by Linus W.
- Added comments in the code as suggested by Linus W.
- moved out AMBA ID addition patch from this series.
- rebased the patches to 
git://git.linaro.org/people/ulf.hansson/mmc.git next 
  as suggested by Ulf H.

Changes from RFC:
- moved out clk setup out of spinlock as pointed by Stephen B.

Am hoping to get this for v3.16.

All these patches are tested on IF6410 board on both eMMC and external SD card.

Thanks,
srini

Srinivas Kandagatla (13):
  mmc: mmci: use NSEC_PER_SEC macro
  mmc: mmci: convert register bits to use BIT() macro.
  mmc: mmci: Add Qualcomm specific register defines.
  mmc: mmci: Add enough delay between writes to CMD register.
  mmc: mmci: Add Qcom datactrl register variant
  mmc: mmci: add ddrmode mask to variant data
  mmc: mmci: add 8bit bus support in variant data
  mmc: mmci: add edge support to data and command out in variant data.
  mmc: mmci: Add support to data commands via variant structure.
  mmc: mmci: add f_max to variant structure
  mmc: mmci: add explicit clk control
  mmc: mmci: Add Qcom specific rx_fifocnt logic.
  mmc: mmci: Add Qualcomm Id to amba id table

 drivers/mmc/host/mmci.c | 129 ---
 drivers/mmc/host/mmci.h | 228 ++--
 2 files changed, 241 insertions(+), 116 deletions(-)

-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubs

[PATCH v5 01/13] mmc: mmci: use NSEC_PER_SEC macro

2014-05-30 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

This patch replaces a constant used in calculating timeout with a proper
macro. This is make code more readable.

Signed-off-by: Srinivas Kandagatla 
Reviewed-by: Linus Walleij 
---
 drivers/mmc/host/mmci.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index a084edd..a38e714 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -718,7 +718,7 @@ static void mmci_start_data(struct mmci_host *host, struct 
mmc_data *data)
data->bytes_xfered = 0;
 
clks = (unsigned long long)data->timeout_ns * host->cclk;
-   do_div(clks, 10UL);
+   do_div(clks, NSEC_PER_SEC);
 
timeout = data->timeout_clks + (unsigned int)clks;
 
-- 
1.9.1

--
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 04/13] mmc: mmci: Add enough delay between writes to CMD register.

2014-05-30 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

On Qcom SD Card controller POWER, CLKCTRL, DATACTRL and COMMAND registers
should be updated in MCLK domain, and writes to these registers must be
separated by three MCLK cycles. This resitriction is not applicable for
other registers. Any subsequent writes to these register will be ignored
until 3 MCLK have passed.

One usec delay between two CMD register writes is not sufficient in the
card identification phase where the CCLK is very low. This patch replaces
a static 1 usec delay to use mmci_reg_delay function which can provide
correct delay depending on the cclk frequency.

Without this patch the card is not detected.

Signed-off-by: Srinivas Kandagatla 
---
 drivers/mmc/host/mmci.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index a38e714..ed20bf5 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -810,7 +810,7 @@ mmci_start_command(struct mmci_host *host, struct 
mmc_command *cmd, u32 c)
 
if (readl(base + MMCICOMMAND) & MCI_CPSM_ENABLE) {
writel(0, base + MMCICOMMAND);
-   udelay(1);
+   mmci_reg_delay(host);
}
 
c |= cmd->opcode | MCI_CPSM_ENABLE;
-- 
1.9.1

--
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 10/13] mmc: mmci: add f_max to variant structure

2014-05-30 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

Some of the controller have maximum supported frequency, This patch adds
support in variant data structure to specify such restrictions. This
gives more flexibility in calculating the f_max before passing it to
mmc-core.

Signed-off-by: Srinivas Kandagatla 
---
 drivers/mmc/host/mmci.c | 13 +++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 8534c29..55d39d2 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -67,6 +67,7 @@ static unsigned int fmax = 515633;
  * @blksz_datactrl4: true if Block size is at b4..b16 position in datactrl
  *  register
  * @pwrreg_powerup: power up value for MMCIPOWER register
+ * @f_max: maximum clk frequency supported by the controller.
  * @signal_direction: input/out direction of bus signals can be indicated
  * @pwrreg_clkgate: MMCIPOWER register must be used to gate the clock
  * @busy_detect: true if busy detection on dat0 is supported
@@ -87,6 +88,7 @@ struct variant_data {
boolblksz_datactrl16;
boolblksz_datactrl4;
u32 pwrreg_powerup;
+   u32 f_max;
boolsignal_direction;
boolpwrreg_clkgate;
boolbusy_detect;
@@ -98,6 +100,7 @@ static struct variant_data variant_arm = {
.fifohalfsize   = 8 * 4,
.datalength_bits= 16,
.pwrreg_powerup = MCI_PWR_UP,
+   .f_max  = 1,
 };
 
 static struct variant_data variant_arm_extended_fifo = {
@@ -105,6 +108,7 @@ static struct variant_data variant_arm_extended_fifo = {
.fifohalfsize   = 64 * 4,
.datalength_bits= 16,
.pwrreg_powerup = MCI_PWR_UP,
+   .f_max  = 1,
 };
 
 static struct variant_data variant_arm_extended_fifo_hwfc = {
@@ -113,6 +117,7 @@ static struct variant_data variant_arm_extended_fifo_hwfc = 
{
.clkreg_enable  = MCI_ARM_HWFCEN,
.datalength_bits= 16,
.pwrreg_powerup = MCI_PWR_UP,
+   .f_max  = 1,
 };
 
 static struct variant_data variant_u300 = {
@@ -123,6 +128,7 @@ static struct variant_data variant_u300 = {
.datalength_bits= 16,
.sdio   = true,
.pwrreg_powerup = MCI_PWR_ON,
+   .f_max  = 1,
.signal_direction   = true,
.pwrreg_clkgate = true,
.pwrreg_nopower = true,
@@ -136,6 +142,7 @@ static struct variant_data variant_nomadik = {
.sdio   = true,
.st_clkdiv  = true,
.pwrreg_powerup = MCI_PWR_ON,
+   .f_max  = 1,
.signal_direction   = true,
.pwrreg_clkgate = true,
.pwrreg_nopower = true,
@@ -152,6 +159,7 @@ static struct variant_data variant_ux500 = {
.sdio   = true,
.st_clkdiv  = true,
.pwrreg_powerup = MCI_PWR_ON,
+   .f_max  = 1,
.signal_direction   = true,
.pwrreg_clkgate = true,
.busy_detect= true,
@@ -171,6 +179,7 @@ static struct variant_data variant_ux500v2 = {
.st_clkdiv  = true,
.blksz_datactrl16   = true,
.pwrreg_powerup = MCI_PWR_ON,
+   .f_max  = 1,
.signal_direction   = true,
.pwrreg_clkgate = true,
.busy_detect= true,
@@ -1471,8 +1480,8 @@ static int mmci_probe(struct amba_device *dev,
 * so we try to adjust the clock down to this,
 * (if possible).
 */
-   if (host->mclk > 1) {
-   ret = clk_set_rate(host->clk, 1);
+   if (host->mclk > variant->f_max) {
+   ret = clk_set_rate(host->clk, variant->f_max);
if (ret < 0)
goto clk_disable;
host->mclk = clk_get_rate(host->clk);
-- 
1.9.1

--
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 12/13] mmc: mmci: Add Qcom specific rx_fifocnt logic.

2014-05-30 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

MCIFIFOCNT register behaviour on Qcom chips is very different than the other
pl180 integrations. MCIFIFOCNT register contains the number of
words that are still waiting to be transferred through the FIFO. It keeps
decrementing once the host CPU reads the MCIFIFO. With the existing logic and
the MCIFIFOCNT behaviour, mmci_pio_read will loop forever, as the FIFOCNT
register will always return transfer size before reading the FIFO.

Also the data sheet states that "This register is only useful for debug
purposes and should not be used for normal operation since it does not reflect
data which may or may not be in the pipeline".

This patch implements a qcom specific get_rx_fifocnt function which is
implemented based on status register flags. Based on qcom_fifo flag in
variant data structure, the corresponding get_rx_fifocnt function is selected.

Signed-off-by: Srinivas Kandagatla 
---
 drivers/mmc/host/mmci.c | 30 --
 drivers/mmc/host/mmci.h |  1 +
 2 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 8b23368..7a11522 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -73,6 +73,7 @@ static unsigned int fmax = 515633;
  * @busy_detect: true if busy detection on dat0 is supported
  * @pwrreg_nopower: bits in MMCIPOWER don't controls ext. power supply
  * @explicit_mclk_control: enable explicit mclk control in driver.
+ * @qcom_fifo: enables qcom specific fifo pio read logic.
  */
 struct variant_data {
unsigned intclkreg;
@@ -95,6 +96,7 @@ struct variant_data {
boolbusy_detect;
boolpwrreg_nopower;
boolexplicit_mclk_control;
+   boolqcom_fifo;
 };
 
 static struct variant_data variant_arm = {
@@ -990,15 +992,34 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command 
*cmd,
}
 }
 
+static int mmci_get_rx_fifocnt(struct mmci_host *host, u32 status, int remain)
+{
+   return remain - (readl(host->base + MMCIFIFOCNT) << 2);
+}
+
+static int mmci_qcom_get_rx_fifocnt(struct mmci_host *host, u32 status, int r)
+{
+   /*
+* on qcom SDCC4 only 8 words are used in each burst so only 8 addresses
+* from the fifo range should be used
+*/
+   if (status & MCI_RXFIFOHALFFULL)
+   return host->variant->fifohalfsize;
+   else if (status & MCI_RXDATAAVLBL)
+   return 4;
+
+   return 0;
+}
+
 static int mmci_pio_read(struct mmci_host *host, char *buffer, unsigned int 
remain)
 {
void __iomem *base = host->base;
char *ptr = buffer;
-   u32 status;
+   u32 status = readl(host->base + MMCISTATUS);
int host_remain = host->size;
 
do {
-   int count = host_remain - (readl(base + MMCIFIFOCNT) << 2);
+   int count = host->get_rx_fifocnt(host, status, host_remain);
 
if (count > remain)
count = remain;
@@ -1488,6 +1509,11 @@ static int mmci_probe(struct amba_device *dev,
if (ret)
goto host_free;
 
+   if (variant->qcom_fifo)
+   host->get_rx_fifocnt = mmci_qcom_get_rx_fifocnt;
+   else
+   host->get_rx_fifocnt = mmci_get_rx_fifocnt;
+
host->plat = plat;
host->variant = variant;
host->mclk = clk_get_rate(host->clk);
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h
index b5f0810..5f76670 100644
--- a/drivers/mmc/host/mmci.h
+++ b/drivers/mmc/host/mmci.h
@@ -229,6 +229,7 @@ struct mmci_host {
/* pio stuff */
struct sg_mapping_iter  sg_miter;
unsigned intsize;
+   int (*get_rx_fifocnt)(struct mmci_host *h, u32 status, int remain);
 
 #ifdef CONFIG_DMA_ENGINE
/* DMA stuff */
-- 
1.9.1

--
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 11/13] mmc: mmci: add explicit clk control

2014-05-30 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

On Controllers like Qcom SD card controller where cclk is mclk and mclk should
be directly controlled by the driver.

This patch adds support to control mclk directly in the driver, and also
adds explicit_mclk_control flag in variant structure giving more flexibility
to the driver.

Signed-off-by: Srinivas Kandagatla 
---
 drivers/mmc/host/mmci.c | 31 ---
 drivers/mmc/host/mmci.h |  2 ++
 2 files changed, 30 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 55d39d2..8b23368 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -72,6 +72,7 @@ static unsigned int fmax = 515633;
  * @pwrreg_clkgate: MMCIPOWER register must be used to gate the clock
  * @busy_detect: true if busy detection on dat0 is supported
  * @pwrreg_nopower: bits in MMCIPOWER don't controls ext. power supply
+ * @explicit_mclk_control: enable explicit mclk control in driver.
  */
 struct variant_data {
unsigned intclkreg;
@@ -93,6 +94,7 @@ struct variant_data {
boolpwrreg_clkgate;
boolbusy_detect;
boolpwrreg_nopower;
+   boolexplicit_mclk_control;
 };
 
 static struct variant_data variant_arm = {
@@ -286,7 +288,9 @@ static void mmci_set_clkreg(struct mmci_host *host, 
unsigned int desired)
host->cclk = 0;
 
if (desired) {
-   if (desired >= host->mclk) {
+   if (variant->explicit_mclk_control) {
+   host->cclk = host->mclk;
+   } else if (desired >= host->mclk) {
clk = MCI_CLK_BYPASS;
if (variant->st_clkdiv)
clk |= MCI_ST_UX500_NEG_EDGE;
@@ -1325,6 +1329,18 @@ static void mmci_set_ios(struct mmc_host *mmc, struct 
mmc_ios *ios)
if (!ios->clock && variant->pwrreg_clkgate)
pwr &= ~MCI_PWR_ON;
 
+   if ((host->variant->explicit_mclk_control) &&
+   (ios->clock != host->clock_cache)) {
+   int rc = clk_set_rate(host->clk, ios->clock);
+   if (rc < 0) {
+   dev_err(mmc_dev(host->mmc),
+   "Error setting clock rate (%d)\n", rc);
+   } else {
+   host->mclk = clk_get_rate(host->clk);
+   host->clock_cache = ios->clock;
+   }
+   }
+
spin_lock_irqsave(&host->lock, flags);
 
mmci_set_clkreg(host, ios->clock);
@@ -1500,9 +1516,12 @@ static int mmci_probe(struct amba_device *dev,
 * The ARM and ST versions of the block have slightly different
 * clock divider equations which means that the minimum divider
 * differs too.
+* on Qualcomm like controllers get the nearest minimum clock to 100Khz
 */
if (variant->st_clkdiv)
mmc->f_min = DIV_ROUND_UP(host->mclk, 257);
+   else if (variant->explicit_mclk_control)
+   mmc->f_min = clk_round_rate(host->clk, 10);
else
mmc->f_min = DIV_ROUND_UP(host->mclk, 512);
/*
@@ -1512,9 +1531,15 @@ static int mmci_probe(struct amba_device *dev,
 * the block, of course.
 */
if (mmc->f_max)
-   mmc->f_max = min(host->mclk, mmc->f_max);
+   mmc->f_max = variant->explicit_mclk_control ?
+   min(variant->f_max, mmc->f_max) :
+   min(host->mclk, mmc->f_max);
else
-   mmc->f_max = min(host->mclk, fmax);
+   mmc->f_max = variant->explicit_mclk_control ?
+   min(variant->f_max, fmax) :
+   min(host->mclk, fmax);
+
+
dev_dbg(mmc_dev(mmc), "clocking block at %u Hz\n", mmc->f_max);
 
/* Get regulators and the supported OCR mask */
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h
index 706eb513..b5f0810 100644
--- a/drivers/mmc/host/mmci.h
+++ b/drivers/mmc/host/mmci.h
@@ -208,6 +208,8 @@ struct mmci_host {
spinlock_t  lock;
 
unsigned intmclk;
+   /* cached value of requested clk in set_ios */
+   unsigned intclock_cache;
unsigned intcclk;
u32 pwr_reg;
u32 pwr_reg_add;
-- 
1.9.1

--
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 13/13] mmc: mmci: Add Qualcomm Id to amba id table

2014-05-30 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

This patch adds a fake Qualcomm ID 0x00051180 to the amba_ids, as Qualcomm
SDCC controller is pl180, but amba id registers read 0x0's.
The plan is to remove SDCC driver totally and use mmci as the main SD
controller driver for Qualcomm SOCs.

Signed-off-by: Srinivas Kandagatla 
---
 drivers/mmc/host/mmci.c | 23 +++
 1 file changed, 23 insertions(+)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 7a11522..b07c3c3 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -190,6 +190,23 @@ static struct variant_data variant_ux500v2 = {
.pwrreg_nopower = true,
 };
 
+static struct variant_data variant_qcom = {
+   .fifosize   = 16 * 4,
+   .fifohalfsize   = 8 * 4,
+   .clkreg = MCI_CLK_ENABLE,
+   .clkreg_enable  = MCI_QCOM_CLK_FLOWENA |
+ MCI_QCOM_CLK_SELECT_IN_FBCLK,
+   .clkreg_8bit_bus_enable = MCI_QCOM_CLK_WIDEBUS_8,
+   .datactrl_mask_ddrmode  = MCI_QCOM_CLK_SELECT_IN_DDR_MODE,
+   .data_cmd_enable= MCI_QCOM_CSPM_DATCMD,
+   .blksz_datactrl4= true,
+   .datalength_bits= 24,
+   .pwrreg_powerup = MCI_PWR_UP,
+   .f_max  = 20800,
+   .explicit_mclk_control  = true,
+   .qcom_fifo  = true,
+};
+
 static int mmci_card_busy(struct mmc_host *mmc)
 {
struct mmci_host *host = mmc_priv(mmc);
@@ -1832,6 +1849,12 @@ static struct amba_id mmci_ids[] = {
.mask   = 0xf0ff,
.data   = &variant_ux500v2,
},
+   /* Qualcomm variants */
+   {
+   .id = 0x00051180,
+   .mask   = 0x000f,
+   .data   = &variant_qcom,
+   },
{ 0, 0 },
 };
 
-- 
1.9.1

--
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 07/13] mmc: mmci: add 8bit bus support in variant data

2014-05-30 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

This patch adds 8bit bus enable to variant structure giving more flexibility
to the driver to support more SOCs which have different clock register layout.

Without this patch other new SOCs like Qcom will have to add more code
to special case them.

Signed-off-by: Srinivas Kandagatla 
Reviewed-by: Linus Walleij 
---
 drivers/mmc/host/mmci.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index ad7e538..fa3ad83 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -52,6 +52,7 @@ static unsigned int fmax = 515633;
  * struct variant_data - MMCI variant-specific quirks
  * @clkreg: default value for MCICLOCK register
  * @clkreg_enable: enable value for MMCICLOCK register
+ * @clkreg_8bit_bus_enable: enable value for 8 bit bus
  * @datalength_bits: number of bits in the MMCIDATALENGTH register
  * @fifosize: number of bytes that can be written when MMCI_TXFIFOEMPTY
  *   is asserted (likewise for RX)
@@ -72,6 +73,7 @@ static unsigned int fmax = 515633;
 struct variant_data {
unsigned intclkreg;
unsigned intclkreg_enable;
+   unsigned intclkreg_8bit_bus_enable;
unsigned intdatalength_bits;
unsigned intfifosize;
unsigned intfifohalfsize;
@@ -113,6 +115,7 @@ static struct variant_data variant_u300 = {
.fifosize   = 16 * 4,
.fifohalfsize   = 8 * 4,
.clkreg_enable  = MCI_ST_U300_HWFCEN,
+   .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS,
.datalength_bits= 16,
.sdio   = true,
.pwrreg_powerup = MCI_PWR_ON,
@@ -139,6 +142,7 @@ static struct variant_data variant_ux500 = {
.fifohalfsize   = 8 * 4,
.clkreg = MCI_CLK_ENABLE,
.clkreg_enable  = MCI_ST_UX500_HWFCEN,
+   .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS,
.datalength_bits= 24,
.sdio   = true,
.st_clkdiv  = true,
@@ -154,6 +158,7 @@ static struct variant_data variant_ux500v2 = {
.fifohalfsize   = 8 * 4,
.clkreg = MCI_CLK_ENABLE,
.clkreg_enable  = MCI_ST_UX500_HWFCEN,
+   .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS,
.datactrl_mask_ddrmode  = MCI_ST_DPSM_DDRMODE,
.datalength_bits= 24,
.sdio   = true,
@@ -305,7 +310,7 @@ static void mmci_set_clkreg(struct mmci_host *host, 
unsigned int desired)
if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_4)
clk |= MCI_4BIT_BUS;
if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_8)
-   clk |= MCI_ST_8BIT_BUS;
+   clk |= variant->clkreg_8bit_bus_enable;
 
if (host->mmc->ios.timing == MMC_TIMING_UHS_DDR50)
clk |= MCI_ST_UX500_NEG_EDGE;
-- 
1.9.1

--
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 09/13] mmc: mmci: Add support to data commands via variant structure.

2014-05-30 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

On some SOCs like Qcom there are explicit bits in the command register
to specify if its a data transfer command or not. So this patch adds
support to such bits in variant data, giving more flexibility to the
driver.

Signed-off-by: Srinivas Kandagatla 
Reviewed-by: Linus Walleij 
---
 drivers/mmc/host/mmci.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 4c95a9b..8534c29 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -59,6 +59,7 @@ static unsigned int fmax = 515633;
  *   is asserted (likewise for RX)
  * @fifohalfsize: number of bytes that can be written when MCI_TXFIFOHALFEMPTY
  *   is asserted (likewise for RX)
+ * @data_cmd_enable: enable value for data commands.
  * @sdio: variant supports SDIO
  * @st_clkdiv: true if using a ST-specific clock divider algorithm
  * @datactrl_mask_ddrmode: ddr mode mask in datactrl register.
@@ -79,6 +80,7 @@ struct variant_data {
unsigned intdatalength_bits;
unsigned intfifosize;
unsigned intfifohalfsize;
+   unsigned intdata_cmd_enable;
unsigned intdatactrl_mask_ddrmode;
boolsdio;
boolst_clkdiv;
@@ -839,6 +841,9 @@ mmci_start_command(struct mmci_host *host, struct 
mmc_command *cmd, u32 c)
if (/*interrupt*/0)
c |= MCI_CPSM_INTERRUPT;
 
+   if (mmc_cmd_type(cmd) == MMC_CMD_ADTC)
+   c |= host->variant->data_cmd_enable;
+
host->cmd = cmd;
 
writel(cmd->arg, base + MMCIARGUMENT);
-- 
1.9.1

--
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 08/13] mmc: mmci: add edge support to data and command out in variant data.

2014-05-30 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

This patch adds edge support for data and command out to variant structure
giving more flexibility to the driver to support more SOCs which have
different clock register layout.

Without this patch other new SOCs like Qcom will have to add more code to
special case them

Signed-off-by: Srinivas Kandagatla 
Reviewed-by: Linus Walleij 
---
 drivers/mmc/host/mmci.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index fa3ad83..4c95a9b 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -53,6 +53,7 @@ static unsigned int fmax = 515633;
  * @clkreg: default value for MCICLOCK register
  * @clkreg_enable: enable value for MMCICLOCK register
  * @clkreg_8bit_bus_enable: enable value for 8 bit bus
+ * @clkreg_neg_edge_enable: enable value for inverted data/cmd output
  * @datalength_bits: number of bits in the MMCIDATALENGTH register
  * @fifosize: number of bytes that can be written when MMCI_TXFIFOEMPTY
  *   is asserted (likewise for RX)
@@ -74,6 +75,7 @@ struct variant_data {
unsigned intclkreg;
unsigned intclkreg_enable;
unsigned intclkreg_8bit_bus_enable;
+   unsigned intclkreg_neg_edge_enable;
unsigned intdatalength_bits;
unsigned intfifosize;
unsigned intfifohalfsize;
@@ -143,6 +145,7 @@ static struct variant_data variant_ux500 = {
.clkreg = MCI_CLK_ENABLE,
.clkreg_enable  = MCI_ST_UX500_HWFCEN,
.clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS,
+   .clkreg_neg_edge_enable = MCI_ST_UX500_NEG_EDGE,
.datalength_bits= 24,
.sdio   = true,
.st_clkdiv  = true,
@@ -159,6 +162,7 @@ static struct variant_data variant_ux500v2 = {
.clkreg = MCI_CLK_ENABLE,
.clkreg_enable  = MCI_ST_UX500_HWFCEN,
.clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS,
+   .clkreg_neg_edge_enable = MCI_ST_UX500_NEG_EDGE,
.datactrl_mask_ddrmode  = MCI_ST_DPSM_DDRMODE,
.datalength_bits= 24,
.sdio   = true,
@@ -313,7 +317,7 @@ static void mmci_set_clkreg(struct mmci_host *host, 
unsigned int desired)
clk |= variant->clkreg_8bit_bus_enable;
 
if (host->mmc->ios.timing == MMC_TIMING_UHS_DDR50)
-   clk |= MCI_ST_UX500_NEG_EDGE;
+   clk |= variant->clkreg_neg_edge_enable;
 
mmci_write_clkreg(host, clk);
 }
-- 
1.9.1

--
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 03/13] mmc: mmci: Add Qualcomm specific register defines.

2014-05-30 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

This patch adds a Qualcomm SD Card controller specific register variations
to header file. Qualcomm SDCC controller is pl180, with slight changes in
the register layout from standard pl180 register set.

Signed-off-by: Srinivas Kandagatla 
---
 drivers/mmc/host/mmci.h | 17 +
 1 file changed, 17 insertions(+)

diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h
index cd83ca3..706eb513 100644
--- a/drivers/mmc/host/mmci.h
+++ b/drivers/mmc/host/mmci.h
@@ -41,6 +41,15 @@
 /* Modified PL180 on Versatile Express platform */
 #define MCI_ARM_HWFCEN BIT(12)
 
+/* Modified on Qualcomm Integrations */
+#define MCI_QCOM_CLK_WIDEBUS_8 (BIT(10) | BIT(11))
+#define MCI_QCOM_CLK_FLOWENA   BIT(12)
+#define MCI_QCOM_CLK_INVERTOUT BIT(13)
+
+/* select in latch data and command in */
+#define MCI_QCOM_CLK_SELECT_IN_FBCLK   BIT(15)
+#define MCI_QCOM_CLK_SELECT_IN_DDR_MODE(BIT(14) | BIT(15))
+
 #define MMCIARGUMENT   0x008
 #define MMCICOMMAND0x00c
 #define MCI_CPSM_RESPONSE  BIT(6)
@@ -54,6 +63,14 @@
 #define MCI_ST_NIENBIT(13)
 #define MCI_ST_CE_ATACMD   BIT(14)
 
+/* Modified on Qualcomm Integrations */
+#define MCI_QCOM_CSPM_DATCMD   BIT(12)
+#define MCI_QCOM_CSPM_MCIABORT BIT(13)
+#define MCI_QCOM_CSPM_CCSENABLEBIT(14)
+#define MCI_QCOM_CSPM_CCSDISABLE   BIT(15)
+#define MCI_QCOM_CSPM_AUTO_CMD19   BIT(16)
+#define MCI_QCOM_CSPM_AUTO_CMD21   BIT(21)
+
 #define MMCIRESPCMD0x010
 #define MMCIRESPONSE0  0x014
 #define MMCIRESPONSE1  0x018
-- 
1.9.1

--
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 02/13] mmc: mmci: convert register bits to use BIT() macro.

2014-05-30 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

This patch converts the register bits in the header file to use BIT(()
macro, which looks much neater.

No functional changes done.

Signed-off-by: Srinivas Kandagatla 
---
 drivers/mmc/host/mmci.h | 208 
 1 file changed, 104 insertions(+), 104 deletions(-)

diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h
index 347d942..cd83ca3 100644
--- a/drivers/mmc/host/mmci.h
+++ b/drivers/mmc/host/mmci.h
@@ -11,48 +11,48 @@
 #define MCI_PWR_OFF0x00
 #define MCI_PWR_UP 0x02
 #define MCI_PWR_ON 0x03
-#define MCI_OD (1 << 6)
-#define MCI_ROD(1 << 7)
+#define MCI_OD BIT(6)
+#define MCI_RODBIT(7)
 /*
  * The ST Micro version does not have ROD and reuse the voltage registers for
  * direction settings.
  */
-#define MCI_ST_DATA2DIREN  (1 << 2)
-#define MCI_ST_CMDDIREN(1 << 3)
-#define MCI_ST_DATA0DIREN  (1 << 4)
-#define MCI_ST_DATA31DIREN (1 << 5)
-#define MCI_ST_FBCLKEN (1 << 7)
-#define MCI_ST_DATA74DIREN (1 << 8)
+#define MCI_ST_DATA2DIREN  BIT(2)
+#define MCI_ST_CMDDIRENBIT(3)
+#define MCI_ST_DATA0DIREN  BIT(4)
+#define MCI_ST_DATA31DIREN BIT(5)
+#define MCI_ST_FBCLKEN BIT(7)
+#define MCI_ST_DATA74DIREN BIT(8)
 
 #define MMCICLOCK  0x004
-#define MCI_CLK_ENABLE (1 << 8)
-#define MCI_CLK_PWRSAVE(1 << 9)
-#define MCI_CLK_BYPASS (1 << 10)
-#define MCI_4BIT_BUS   (1 << 11)
+#define MCI_CLK_ENABLE BIT(8)
+#define MCI_CLK_PWRSAVEBIT(9)
+#define MCI_CLK_BYPASS BIT(10)
+#define MCI_4BIT_BUS   BIT(11)
 /*
  * 8bit wide buses, hardware flow contronl, negative edges and clock inversion
  * supported in ST Micro U300 and Ux500 versions
  */
-#define MCI_ST_8BIT_BUS(1 << 12)
-#define MCI_ST_U300_HWFCEN (1 << 13)
-#define MCI_ST_UX500_NEG_EDGE  (1 << 13)
-#define MCI_ST_UX500_HWFCEN(1 << 14)
-#define MCI_ST_UX500_CLK_INV   (1 << 15)
+#define MCI_ST_8BIT_BUSBIT(12)
+#define MCI_ST_U300_HWFCEN BIT(13)
+#define MCI_ST_UX500_NEG_EDGE  BIT(13)
+#define MCI_ST_UX500_HWFCENBIT(14)
+#define MCI_ST_UX500_CLK_INV   BIT(15)
 /* Modified PL180 on Versatile Express platform */
-#define MCI_ARM_HWFCEN (1 << 12)
+#define MCI_ARM_HWFCEN BIT(12)
 
 #define MMCIARGUMENT   0x008
 #define MMCICOMMAND0x00c
-#define MCI_CPSM_RESPONSE  (1 << 6)
-#define MCI_CPSM_LONGRSP   (1 << 7)
-#define MCI_CPSM_INTERRUPT (1 << 8)
-#define MCI_CPSM_PENDING   (1 << 9)
-#define MCI_CPSM_ENABLE(1 << 10)
+#define MCI_CPSM_RESPONSE  BIT(6)
+#define MCI_CPSM_LONGRSP   BIT(7)
+#define MCI_CPSM_INTERRUPT BIT(8)
+#define MCI_CPSM_PENDING   BIT(9)
+#define MCI_CPSM_ENABLEBIT(10)
 /* Argument flag extenstions in the ST Micro versions */
-#define MCI_ST_SDIO_SUSP   (1 << 11)
-#define MCI_ST_ENCMD_COMPL (1 << 12)
-#define MCI_ST_NIEN(1 << 13)
-#define MCI_ST_CE_ATACMD   (1 << 14)
+#define MCI_ST_SDIO_SUSP   BIT(11)
+#define MCI_ST_ENCMD_COMPL BIT(12)
+#define MCI_ST_NIENBIT(13)
+#define MCI_ST_CE_ATACMD   BIT(14)
 
 #define MMCIRESPCMD0x010
 #define MMCIRESPONSE0  0x014
@@ -62,95 +62,95 @@
 #define MMCIDATATIMER  0x024
 #define MMCIDATALENGTH 0x028
 #define MMCIDATACTRL   0x02c
-#define MCI_DPSM_ENABLE(1 << 0)
-#define MCI_DPSM_DIRECTION (1 << 1)
-#define MCI_DPSM_MODE  (1 << 2)
-#define MCI_DPSM_DMAENABLE (1 << 3)
-#define MCI_DPSM_BLOCKSIZE (1 << 4)
+#define MCI_DPSM_ENABLEBIT(0)
+#define MCI_DPSM_DIRECTION BIT(1)
+#define MCI_DPSM_MODE  BIT(2)
+#define MCI_DPSM_DMAENABLE BIT(3)
+#define MCI_DPSM_BLOCKSIZE BIT(4)
 /* Control register extensions in the ST Micro U300 and Ux500 versions */
-#define MCI_ST_DPSM_RWSTART(1 << 8)
-#define MCI_ST_DPSM_RWSTOP (1 << 9)
-#define MCI_ST_DPSM_RWMOD  (1 << 10)
-#define MCI_ST_DPSM_SDIOEN (1 << 11)
+#define MCI_ST_DPSM_RWSTARTBIT(8)
+#define MCI_ST_DPSM_RWSTOP BIT(9)
+#define MCI_ST_DPSM_RWMOD  BIT(10)
+#define MCI_ST_DPSM_SDIOEN BIT(11)
 /* Control register extensions in the ST Micro Ux500 versions */
-#define MCI_ST_DPSM_DMAREQCTL  (1 << 12)
-#define MCI_ST_DPSM_DBOOTMODEEN(1 << 13)
-#define MCI_ST_DPSM_BUSYMODE   (1 << 14)
-#define MCI_ST_DPSM_DDRMODE(1 << 15)
+#define MCI_ST_DPSM_DMAREQCTL  BIT(12)
+#define MCI_ST_DPSM_DBOOTMODEENBIT(13)
+#define MCI_ST_DPSM_BUSYMODE  

[PATCH v5 06/13] mmc: mmci: add ddrmode mask to variant data

2014-05-30 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

This patch adds ddrmode mask to variant structure giving more flexibility
to the driver to support more SOCs which have different datactrl register
layout.

Without this patch datactrl register is updated with incorrect ddrmode mask,
resulting in failures on Qualcomm SD Card Controller.

Signed-off-by: Srinivas Kandagatla 
Reviewed-by: Linus Walleij 
---
 drivers/mmc/host/mmci.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 72981f6..ad7e538 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -59,6 +59,7 @@ static unsigned int fmax = 515633;
  *   is asserted (likewise for RX)
  * @sdio: variant supports SDIO
  * @st_clkdiv: true if using a ST-specific clock divider algorithm
+ * @datactrl_mask_ddrmode: ddr mode mask in datactrl register.
  * @blksz_datactrl16: true if Block size is at b16..b30 position in datactrl 
register
  * @blksz_datactrl4: true if Block size is at b4..b16 position in datactrl
  *  register
@@ -74,6 +75,7 @@ struct variant_data {
unsigned intdatalength_bits;
unsigned intfifosize;
unsigned intfifohalfsize;
+   unsigned intdatactrl_mask_ddrmode;
boolsdio;
boolst_clkdiv;
boolblksz_datactrl16;
@@ -152,6 +154,7 @@ static struct variant_data variant_ux500v2 = {
.fifohalfsize   = 8 * 4,
.clkreg = MCI_CLK_ENABLE,
.clkreg_enable  = MCI_ST_UX500_HWFCEN,
+   .datactrl_mask_ddrmode  = MCI_ST_DPSM_DDRMODE,
.datalength_bits= 24,
.sdio   = true,
.st_clkdiv  = true,
@@ -770,7 +773,7 @@ static void mmci_start_data(struct mmci_host *host, struct 
mmc_data *data)
}
 
if (host->mmc->ios.timing == MMC_TIMING_UHS_DDR50)
-   datactrl |= MCI_ST_DPSM_DDRMODE;
+   datactrl |= variant->datactrl_mask_ddrmode;
 
/*
 * Attempt to use DMA operation mode, if this
-- 
1.9.1

--
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 05/13] mmc: mmci: Add Qcom datactrl register variant

2014-05-30 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

Instance of this IP on Qualcomm's SOCs has bit different layout for datactrl
register. Bit position datactrl[16:4] hold the true block size instead of power
of 2.

Signed-off-by: Srinivas Kandagatla 
Reviewed-by: Linus Walleij 
---
 drivers/mmc/host/mmci.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index ed20bf5..72981f6 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -60,6 +60,8 @@ static unsigned int fmax = 515633;
  * @sdio: variant supports SDIO
  * @st_clkdiv: true if using a ST-specific clock divider algorithm
  * @blksz_datactrl16: true if Block size is at b16..b30 position in datactrl 
register
+ * @blksz_datactrl4: true if Block size is at b4..b16 position in datactrl
+ *  register
  * @pwrreg_powerup: power up value for MMCIPOWER register
  * @signal_direction: input/out direction of bus signals can be indicated
  * @pwrreg_clkgate: MMCIPOWER register must be used to gate the clock
@@ -75,6 +77,7 @@ struct variant_data {
boolsdio;
boolst_clkdiv;
boolblksz_datactrl16;
+   boolblksz_datactrl4;
u32 pwrreg_powerup;
boolsignal_direction;
boolpwrreg_clkgate;
@@ -731,6 +734,8 @@ static void mmci_start_data(struct mmci_host *host, struct 
mmc_data *data)
 
if (variant->blksz_datactrl16)
datactrl = MCI_DPSM_ENABLE | (data->blksz << 16);
+   else if (variant->blksz_datactrl4)
+   datactrl = MCI_DPSM_ENABLE | (data->blksz << 4);
else
datactrl = MCI_DPSM_ENABLE | blksz_bits << 4;
 
-- 
1.9.1

--
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 v5 11/13] mmc: mmci: add explicit clk control

2014-06-01 Thread Srinivas Kandagatla

Thanks Russell,

On 31/05/14 13:29, Russell King - ARM Linux wrote:


>+   if ((host->variant->explicit_mclk_control) &&
>+   (ios->clock != host->clock_cache)) {

Please explain what use these parens have (or just get rid of them as
they're completely unnecessary - they do nothing for readability.)
I agree, will fix this in next version, It was a left over from my 
previous patches which had one more variable in that first check.


Thanks,
srini
--
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 v5 02/13] mmc: mmci: convert register bits to use BIT() macro.

2014-06-02 Thread Srinivas Kandagatla

Thanks Russell,

On 31/05/14 13:35, Russell King - ARM Linux wrote:

because allegedly it makes it more "readable".  I don't see much benefit
to this patch.

Ok, I will drop this patch in next version.

thanks,
srini

--
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 v6 00/12] Qualcomm SD Card Controller support

2014-06-02 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

Thankyou Linus W, Ulf H, Russell K and everyone for reviewing RFC to v5 patches.

This patch series adds Qualcomm SD Card Controller support in pl180 mmci
driver. QCom SDCC is basically a pl180, but bit more customized, some of the
register layouts and offsets are different to the ones mentioned in pl180
datasheet. The plan is to totally remove the standalone SDCC driver
drivers/mmc/host/msm_sdcc.* and start using generic mmci driver for all
Qualcomm parts, as we get chance to test on other Qcom boards.

To start using the existing mmci driver, a fake amba id for Qualcomm is added
in patches:
 mmc: mmci: Add Qualcomm specific register defines.
 mmc: mmci: Add Qualcomm Id to amba id table.

Second change is, adding a 3 clock cycle delay in between writes to
CLKCTRL/POWER/DATACTRL/COMMAND registers. Most of the delays are taken care with
the existing driver except delay for the COMMAND register was too small. 
This patch fixes it.
  mmc: mmci: Add enough delay between writes to CMD register.

Third change is to accommodate CLK, DATCTRL and MMCICLK register layout changes
in Qcom SDCC and provide more flexibity in driver to specify these changes via
variant datastructure. Which are done in patches:
  mmc: mmci: Add Qcom datactrl register variant
  mmc: mmci: add ddrmode mask to variant data
  mmc: mmci: add 8bit bus support in variant data
  mmc: mmci: add edge support to data and command out in variant data.
  mmc: mmci: add Qcom specifics of clk and datactrl registers.
  mmc: mmci: Add support to data commands via variant structure.
  mmc: mmci: add f_max to variant structure
  mmc: mmci: add explicit clk control

Fourth change was to add qcom specfic fifocnt logic, the need for
this is because the way MCIFIFOCNT register behaved in QCOM SDCC is very
 different to the one in pl180. This change is done in patch:
  mmc: mmci: Add Qcom specific rx_fifocnt logic.

Last some Qcom unrelated changes/cleanup to driver are done in patches:
  mmc: mmci: use NSEC_PER_SEC macro

This patches are tested in PIO mode on IFC8064 board with both eMMC and
external SD card. I would like to get this support in v3.16.

Changes from v5:
- removed BIT conversion patch as suggested by Russell K.
- removed extra parens as pointed by Russell K.
- correct the f_max for explicit clk control

Changes from v4:
- moved the amba id table addition to the end of the patchset as 
suggested by Ulf.
- reused the mmci_pio_read function after experimenting with the fifo 
behaviour.
- simplify f_max/f_min calcuation logic as suggested by Ulf.
- created a new patch for the register defination as suggested by Ulf.

Changes from v3:
- moved pio_read to a function pointer so as to reduce additional cycles
in hot-path, suggested by Ulf.
- simplify the flags used for explicit mclk control, suggested by Ulf.
- fixed issues in cacluating f_max and f_min pointed and suggested by 
Ulf.
- removed unessary DDR flags on un-supported STE variants.
- used BIT macros as suggested by Ulf.
- removed the read/write wrappers with delays, and used most optimal way
to introduce the delays to the only registers that require delays.

Changes from v2:
- merged fbclk latch patch with clkreg_enable patch as suggested by 
Linus W.
- remove qcom prefix for explicit clk control pointed by Linus W.
- cleaned up mmci_qcom_pio_read and consider SDIO as suggested by Linus 
W.

Changes from v1:
- moved most of the SOC specifics to variant parameters as suggested
  by Linus W.
- renamed registers as suggested by Linus W.
- Added comments in the code as suggested by Linus W.
- moved out AMBA ID addition patch from this series.
- rebased the patches to 
git://git.linaro.org/people/ulf.hansson/mmc.git next 
  as suggested by Ulf H.

Changes from RFC:
- moved out clk setup out of spinlock as pointed by Stephen B.

Am hoping to get this for v3.16.

All these patches are tested on IF6410 board on both eMMC and external SD card.

Thanks,
srini


Srinivas Kandagatla (12):
  mmc: mmci: use NSEC_PER_SEC macro
  mmc: mmci: Add Qualcomm specific register defines.
  mmc: mmci: Add enough delay between writes to CMD register.
  mmc: mmci: Add Qcom datactrl register variant
  mmc: mmci: add ddrmode mask to variant data
  mmc: mmci: add 8bit bus support in variant data
  mmc: mmci: add edge support to data and command out in variant data.
  mmc: mmci: Add support to data commands via variant structure.
  mmc: mmci: add f_max to variant structure
  mmc: mmci: add explicit clk control
  mmc: mmci: Add Qcom specific rx_fifocnt logic.
  mmc: mmci: Add Qualcomm Id to amba id table

 drivers/mmc/host/mmci.c | 128 +++-
 drivers/mmc/host/mmci.h |  20 
 2 files changed, 136 insertions(+), 12 deletions

[PATCH v6 01/12] mmc: mmci: use NSEC_PER_SEC macro

2014-06-02 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

This patch replaces a constant used in calculating timeout with a proper
macro. This is make code more readable.

Signed-off-by: Srinivas Kandagatla 
Reviewed-by: Linus Walleij 
---
 drivers/mmc/host/mmci.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index a084edd..a38e714 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -718,7 +718,7 @@ static void mmci_start_data(struct mmci_host *host, struct 
mmc_data *data)
data->bytes_xfered = 0;
 
clks = (unsigned long long)data->timeout_ns * host->cclk;
-   do_div(clks, 10UL);
+   do_div(clks, NSEC_PER_SEC);
 
timeout = data->timeout_clks + (unsigned int)clks;
 
-- 
1.9.1

--
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 v6 09/12] mmc: mmci: add f_max to variant structure

2014-06-02 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

Some of the controller have maximum supported frequency, This patch adds
support in variant data structure to specify such restrictions. This
gives more flexibility in calculating the f_max before passing it to
mmc-core.

Signed-off-by: Srinivas Kandagatla 
---
 drivers/mmc/host/mmci.c | 13 +++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 8534c29..55d39d2 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -67,6 +67,7 @@ static unsigned int fmax = 515633;
  * @blksz_datactrl4: true if Block size is at b4..b16 position in datactrl
  *  register
  * @pwrreg_powerup: power up value for MMCIPOWER register
+ * @f_max: maximum clk frequency supported by the controller.
  * @signal_direction: input/out direction of bus signals can be indicated
  * @pwrreg_clkgate: MMCIPOWER register must be used to gate the clock
  * @busy_detect: true if busy detection on dat0 is supported
@@ -87,6 +88,7 @@ struct variant_data {
boolblksz_datactrl16;
boolblksz_datactrl4;
u32 pwrreg_powerup;
+   u32 f_max;
boolsignal_direction;
boolpwrreg_clkgate;
boolbusy_detect;
@@ -98,6 +100,7 @@ static struct variant_data variant_arm = {
.fifohalfsize   = 8 * 4,
.datalength_bits= 16,
.pwrreg_powerup = MCI_PWR_UP,
+   .f_max  = 1,
 };
 
 static struct variant_data variant_arm_extended_fifo = {
@@ -105,6 +108,7 @@ static struct variant_data variant_arm_extended_fifo = {
.fifohalfsize   = 64 * 4,
.datalength_bits= 16,
.pwrreg_powerup = MCI_PWR_UP,
+   .f_max  = 1,
 };
 
 static struct variant_data variant_arm_extended_fifo_hwfc = {
@@ -113,6 +117,7 @@ static struct variant_data variant_arm_extended_fifo_hwfc = 
{
.clkreg_enable  = MCI_ARM_HWFCEN,
.datalength_bits= 16,
.pwrreg_powerup = MCI_PWR_UP,
+   .f_max  = 1,
 };
 
 static struct variant_data variant_u300 = {
@@ -123,6 +128,7 @@ static struct variant_data variant_u300 = {
.datalength_bits= 16,
.sdio   = true,
.pwrreg_powerup = MCI_PWR_ON,
+   .f_max  = 1,
.signal_direction   = true,
.pwrreg_clkgate = true,
.pwrreg_nopower = true,
@@ -136,6 +142,7 @@ static struct variant_data variant_nomadik = {
.sdio   = true,
.st_clkdiv  = true,
.pwrreg_powerup = MCI_PWR_ON,
+   .f_max  = 1,
.signal_direction   = true,
.pwrreg_clkgate = true,
.pwrreg_nopower = true,
@@ -152,6 +159,7 @@ static struct variant_data variant_ux500 = {
.sdio   = true,
.st_clkdiv  = true,
.pwrreg_powerup = MCI_PWR_ON,
+   .f_max  = 1,
.signal_direction   = true,
.pwrreg_clkgate = true,
.busy_detect= true,
@@ -171,6 +179,7 @@ static struct variant_data variant_ux500v2 = {
.st_clkdiv  = true,
.blksz_datactrl16   = true,
.pwrreg_powerup = MCI_PWR_ON,
+   .f_max  = 1,
.signal_direction   = true,
.pwrreg_clkgate = true,
.busy_detect= true,
@@ -1471,8 +1480,8 @@ static int mmci_probe(struct amba_device *dev,
 * so we try to adjust the clock down to this,
 * (if possible).
 */
-   if (host->mclk > 1) {
-   ret = clk_set_rate(host->clk, 1);
+   if (host->mclk > variant->f_max) {
+   ret = clk_set_rate(host->clk, variant->f_max);
if (ret < 0)
goto clk_disable;
host->mclk = clk_get_rate(host->clk);
-- 
1.9.1

--
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 v6 10/12] mmc: mmci: add explicit clk control

2014-06-02 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

On Controllers like Qcom SD card controller where cclk is mclk and mclk should
be directly controlled by the driver.

This patch adds support to control mclk directly in the driver, and also
adds explicit_mclk_control flag in variant structure giving more flexibility
to the driver.

Signed-off-by: Srinivas Kandagatla 
---
 drivers/mmc/host/mmci.c | 30 +++---
 drivers/mmc/host/mmci.h |  2 ++
 2 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 55d39d2..08715ab 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -72,6 +72,7 @@ static unsigned int fmax = 515633;
  * @pwrreg_clkgate: MMCIPOWER register must be used to gate the clock
  * @busy_detect: true if busy detection on dat0 is supported
  * @pwrreg_nopower: bits in MMCIPOWER don't controls ext. power supply
+ * @explicit_mclk_control: enable explicit mclk control in driver.
  */
 struct variant_data {
unsigned intclkreg;
@@ -93,6 +94,7 @@ struct variant_data {
boolpwrreg_clkgate;
boolbusy_detect;
boolpwrreg_nopower;
+   boolexplicit_mclk_control;
 };
 
 static struct variant_data variant_arm = {
@@ -286,7 +288,9 @@ static void mmci_set_clkreg(struct mmci_host *host, 
unsigned int desired)
host->cclk = 0;
 
if (desired) {
-   if (desired >= host->mclk) {
+   if (variant->explicit_mclk_control) {
+   host->cclk = host->mclk;
+   } else if (desired >= host->mclk) {
clk = MCI_CLK_BYPASS;
if (variant->st_clkdiv)
clk |= MCI_ST_UX500_NEG_EDGE;
@@ -1325,6 +1329,18 @@ static void mmci_set_ios(struct mmc_host *mmc, struct 
mmc_ios *ios)
if (!ios->clock && variant->pwrreg_clkgate)
pwr &= ~MCI_PWR_ON;
 
+   if (host->variant->explicit_mclk_control &&
+   ios->clock != host->clock_cache) {
+   int rc = clk_set_rate(host->clk, ios->clock);
+   if (rc < 0) {
+   dev_err(mmc_dev(host->mmc),
+   "Error setting clock rate (%d)\n", rc);
+   } else {
+   host->mclk = clk_get_rate(host->clk);
+   host->clock_cache = ios->clock;
+   }
+   }
+
spin_lock_irqsave(&host->lock, flags);
 
mmci_set_clkreg(host, ios->clock);
@@ -1500,9 +1516,12 @@ static int mmci_probe(struct amba_device *dev,
 * The ARM and ST versions of the block have slightly different
 * clock divider equations which means that the minimum divider
 * differs too.
+* on Qualcomm like controllers get the nearest minimum clock to 100Khz
 */
if (variant->st_clkdiv)
mmc->f_min = DIV_ROUND_UP(host->mclk, 257);
+   else if (variant->explicit_mclk_control)
+   mmc->f_min = clk_round_rate(host->clk, 10);
else
mmc->f_min = DIV_ROUND_UP(host->mclk, 512);
/*
@@ -1512,9 +1531,14 @@ static int mmci_probe(struct amba_device *dev,
 * the block, of course.
 */
if (mmc->f_max)
-   mmc->f_max = min(host->mclk, mmc->f_max);
+   mmc->f_max = variant->explicit_mclk_control ?
+   min(variant->f_max, mmc->f_max) :
+   min(host->mclk, mmc->f_max);
else
-   mmc->f_max = min(host->mclk, fmax);
+   mmc->f_max = variant->explicit_mclk_control ?
+   fmax : min(host->mclk, fmax);
+
+
dev_dbg(mmc_dev(mmc), "clocking block at %u Hz\n", mmc->f_max);
 
/* Get regulators and the supported OCR mask */
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h
index d38a99d..ef34617 100644
--- a/drivers/mmc/host/mmci.h
+++ b/drivers/mmc/host/mmci.h
@@ -208,6 +208,8 @@ struct mmci_host {
spinlock_t  lock;
 
unsigned intmclk;
+   /* cached value of requested clk in set_ios */
+   unsigned intclock_cache;
unsigned intcclk;
u32 pwr_reg;
u32 pwr_reg_add;
-- 
1.9.1

--
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 v6 12/12] mmc: mmci: Add Qualcomm Id to amba id table

2014-06-02 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

This patch adds a fake Qualcomm ID 0x00051180 to the amba_ids, as Qualcomm
SDCC controller is pl180, but amba id registers read 0x0's.
The plan is to remove SDCC driver totally and use mmci as the main SD
controller driver for Qualcomm SOCs.

Signed-off-by: Srinivas Kandagatla 
---
 drivers/mmc/host/mmci.c | 23 +++
 1 file changed, 23 insertions(+)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 08ff8d2..fa851d5 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -190,6 +190,23 @@ static struct variant_data variant_ux500v2 = {
.pwrreg_nopower = true,
 };
 
+static struct variant_data variant_qcom = {
+   .fifosize   = 16 * 4,
+   .fifohalfsize   = 8 * 4,
+   .clkreg = MCI_CLK_ENABLE,
+   .clkreg_enable  = MCI_QCOM_CLK_FLOWENA |
+ MCI_QCOM_CLK_SELECT_IN_FBCLK,
+   .clkreg_8bit_bus_enable = MCI_QCOM_CLK_WIDEBUS_8,
+   .datactrl_mask_ddrmode  = MCI_QCOM_CLK_SELECT_IN_DDR_MODE,
+   .data_cmd_enable= MCI_QCOM_CSPM_DATCMD,
+   .blksz_datactrl4= true,
+   .datalength_bits= 24,
+   .pwrreg_powerup = MCI_PWR_UP,
+   .f_max  = 20800,
+   .explicit_mclk_control  = true,
+   .qcom_fifo  = true,
+};
+
 static int mmci_card_busy(struct mmc_host *mmc)
 {
struct mmci_host *host = mmc_priv(mmc);
@@ -1831,6 +1848,12 @@ static struct amba_id mmci_ids[] = {
.mask   = 0xf0ff,
.data   = &variant_ux500v2,
},
+   /* Qualcomm variants */
+   {
+   .id = 0x00051180,
+   .mask   = 0x000f,
+   .data   = &variant_qcom,
+   },
{ 0, 0 },
 };
 
-- 
1.9.1

--
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 v6 11/12] mmc: mmci: Add Qcom specific rx_fifocnt logic.

2014-06-02 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

MCIFIFOCNT register behaviour on Qcom chips is very different than the other
pl180 integrations. MCIFIFOCNT register contains the number of
words that are still waiting to be transferred through the FIFO. It keeps
decrementing once the host CPU reads the MCIFIFO. With the existing logic and
the MCIFIFOCNT behaviour, mmci_pio_read will loop forever, as the FIFOCNT
register will always return transfer size before reading the FIFO.

Also the data sheet states that "This register is only useful for debug
purposes and should not be used for normal operation since it does not reflect
data which may or may not be in the pipeline".

This patch implements a qcom specific get_rx_fifocnt function which is
implemented based on status register flags. Based on qcom_fifo flag in
variant data structure, the corresponding get_rx_fifocnt function is selected.

Signed-off-by: Srinivas Kandagatla 
---
 drivers/mmc/host/mmci.c | 30 --
 drivers/mmc/host/mmci.h |  1 +
 2 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 08715ab..08ff8d2 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -73,6 +73,7 @@ static unsigned int fmax = 515633;
  * @busy_detect: true if busy detection on dat0 is supported
  * @pwrreg_nopower: bits in MMCIPOWER don't controls ext. power supply
  * @explicit_mclk_control: enable explicit mclk control in driver.
+ * @qcom_fifo: enables qcom specific fifo pio read logic.
  */
 struct variant_data {
unsigned intclkreg;
@@ -95,6 +96,7 @@ struct variant_data {
boolbusy_detect;
boolpwrreg_nopower;
boolexplicit_mclk_control;
+   boolqcom_fifo;
 };
 
 static struct variant_data variant_arm = {
@@ -990,15 +992,34 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command 
*cmd,
}
 }
 
+static int mmci_get_rx_fifocnt(struct mmci_host *host, u32 status, int remain)
+{
+   return remain - (readl(host->base + MMCIFIFOCNT) << 2);
+}
+
+static int mmci_qcom_get_rx_fifocnt(struct mmci_host *host, u32 status, int r)
+{
+   /*
+* on qcom SDCC4 only 8 words are used in each burst so only 8 addresses
+* from the fifo range should be used
+*/
+   if (status & MCI_RXFIFOHALFFULL)
+   return host->variant->fifohalfsize;
+   else if (status & MCI_RXDATAAVLBL)
+   return 4;
+
+   return 0;
+}
+
 static int mmci_pio_read(struct mmci_host *host, char *buffer, unsigned int 
remain)
 {
void __iomem *base = host->base;
char *ptr = buffer;
-   u32 status;
+   u32 status = readl(host->base + MMCISTATUS);
int host_remain = host->size;
 
do {
-   int count = host_remain - (readl(base + MMCIFIFOCNT) << 2);
+   int count = host->get_rx_fifocnt(host, status, host_remain);
 
if (count > remain)
count = remain;
@@ -1488,6 +1509,11 @@ static int mmci_probe(struct amba_device *dev,
if (ret)
goto host_free;
 
+   if (variant->qcom_fifo)
+   host->get_rx_fifocnt = mmci_qcom_get_rx_fifocnt;
+   else
+   host->get_rx_fifocnt = mmci_get_rx_fifocnt;
+
host->plat = plat;
host->variant = variant;
host->mclk = clk_get_rate(host->clk);
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h
index ef34617..a1f5e4f 100644
--- a/drivers/mmc/host/mmci.h
+++ b/drivers/mmc/host/mmci.h
@@ -229,6 +229,7 @@ struct mmci_host {
/* pio stuff */
struct sg_mapping_iter  sg_miter;
unsigned intsize;
+   int (*get_rx_fifocnt)(struct mmci_host *h, u32 status, int remain);
 
 #ifdef CONFIG_DMA_ENGINE
/* DMA stuff */
-- 
1.9.1

--
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 v6 03/12] mmc: mmci: Add enough delay between writes to CMD register.

2014-06-02 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

On Qcom SD Card controller POWER, CLKCTRL, DATACTRL and COMMAND registers
should be updated in MCLK domain, and writes to these registers must be
separated by three MCLK cycles. This resitriction is not applicable for
other registers. Any subsequent writes to these register will be ignored
until 3 MCLK have passed.

One usec delay between two CMD register writes is not sufficient in the
card identification phase where the CCLK is very low. This patch replaces
a static 1 usec delay to use mmci_reg_delay function which can provide
correct delay depending on the cclk frequency.

Without this patch the card is not detected.

Signed-off-by: Srinivas Kandagatla 
---
 drivers/mmc/host/mmci.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index a38e714..ed20bf5 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -810,7 +810,7 @@ mmci_start_command(struct mmci_host *host, struct 
mmc_command *cmd, u32 c)
 
if (readl(base + MMCICOMMAND) & MCI_CPSM_ENABLE) {
writel(0, base + MMCICOMMAND);
-   udelay(1);
+   mmci_reg_delay(host);
}
 
c |= cmd->opcode | MCI_CPSM_ENABLE;
-- 
1.9.1

--
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 v6 05/12] mmc: mmci: add ddrmode mask to variant data

2014-06-02 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

This patch adds ddrmode mask to variant structure giving more flexibility
to the driver to support more SOCs which have different datactrl register
layout.

Without this patch datactrl register is updated with incorrect ddrmode mask,
resulting in failures on Qualcomm SD Card Controller.

Signed-off-by: Srinivas Kandagatla 
Reviewed-by: Linus Walleij 
---
 drivers/mmc/host/mmci.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 72981f6..ad7e538 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -59,6 +59,7 @@ static unsigned int fmax = 515633;
  *   is asserted (likewise for RX)
  * @sdio: variant supports SDIO
  * @st_clkdiv: true if using a ST-specific clock divider algorithm
+ * @datactrl_mask_ddrmode: ddr mode mask in datactrl register.
  * @blksz_datactrl16: true if Block size is at b16..b30 position in datactrl 
register
  * @blksz_datactrl4: true if Block size is at b4..b16 position in datactrl
  *  register
@@ -74,6 +75,7 @@ struct variant_data {
unsigned intdatalength_bits;
unsigned intfifosize;
unsigned intfifohalfsize;
+   unsigned intdatactrl_mask_ddrmode;
boolsdio;
boolst_clkdiv;
boolblksz_datactrl16;
@@ -152,6 +154,7 @@ static struct variant_data variant_ux500v2 = {
.fifohalfsize   = 8 * 4,
.clkreg = MCI_CLK_ENABLE,
.clkreg_enable  = MCI_ST_UX500_HWFCEN,
+   .datactrl_mask_ddrmode  = MCI_ST_DPSM_DDRMODE,
.datalength_bits= 24,
.sdio   = true,
.st_clkdiv  = true,
@@ -770,7 +773,7 @@ static void mmci_start_data(struct mmci_host *host, struct 
mmc_data *data)
}
 
if (host->mmc->ios.timing == MMC_TIMING_UHS_DDR50)
-   datactrl |= MCI_ST_DPSM_DDRMODE;
+   datactrl |= variant->datactrl_mask_ddrmode;
 
/*
 * Attempt to use DMA operation mode, if this
-- 
1.9.1

--
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 v6 04/12] mmc: mmci: Add Qcom datactrl register variant

2014-06-02 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

Instance of this IP on Qualcomm's SOCs has bit different layout for datactrl
register. Bit position datactrl[16:4] hold the true block size instead of power
of 2.

Signed-off-by: Srinivas Kandagatla 
Reviewed-by: Linus Walleij 
---
 drivers/mmc/host/mmci.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index ed20bf5..72981f6 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -60,6 +60,8 @@ static unsigned int fmax = 515633;
  * @sdio: variant supports SDIO
  * @st_clkdiv: true if using a ST-specific clock divider algorithm
  * @blksz_datactrl16: true if Block size is at b16..b30 position in datactrl 
register
+ * @blksz_datactrl4: true if Block size is at b4..b16 position in datactrl
+ *  register
  * @pwrreg_powerup: power up value for MMCIPOWER register
  * @signal_direction: input/out direction of bus signals can be indicated
  * @pwrreg_clkgate: MMCIPOWER register must be used to gate the clock
@@ -75,6 +77,7 @@ struct variant_data {
boolsdio;
boolst_clkdiv;
boolblksz_datactrl16;
+   boolblksz_datactrl4;
u32 pwrreg_powerup;
boolsignal_direction;
boolpwrreg_clkgate;
@@ -731,6 +734,8 @@ static void mmci_start_data(struct mmci_host *host, struct 
mmc_data *data)
 
if (variant->blksz_datactrl16)
datactrl = MCI_DPSM_ENABLE | (data->blksz << 16);
+   else if (variant->blksz_datactrl4)
+   datactrl = MCI_DPSM_ENABLE | (data->blksz << 4);
else
datactrl = MCI_DPSM_ENABLE | blksz_bits << 4;
 
-- 
1.9.1

--
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 v6 06/12] mmc: mmci: add 8bit bus support in variant data

2014-06-02 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

This patch adds 8bit bus enable to variant structure giving more flexibility
to the driver to support more SOCs which have different clock register layout.

Without this patch other new SOCs like Qcom will have to add more code
to special case them.

Signed-off-by: Srinivas Kandagatla 
Reviewed-by: Linus Walleij 
---
 drivers/mmc/host/mmci.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index ad7e538..fa3ad83 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -52,6 +52,7 @@ static unsigned int fmax = 515633;
  * struct variant_data - MMCI variant-specific quirks
  * @clkreg: default value for MCICLOCK register
  * @clkreg_enable: enable value for MMCICLOCK register
+ * @clkreg_8bit_bus_enable: enable value for 8 bit bus
  * @datalength_bits: number of bits in the MMCIDATALENGTH register
  * @fifosize: number of bytes that can be written when MMCI_TXFIFOEMPTY
  *   is asserted (likewise for RX)
@@ -72,6 +73,7 @@ static unsigned int fmax = 515633;
 struct variant_data {
unsigned intclkreg;
unsigned intclkreg_enable;
+   unsigned intclkreg_8bit_bus_enable;
unsigned intdatalength_bits;
unsigned intfifosize;
unsigned intfifohalfsize;
@@ -113,6 +115,7 @@ static struct variant_data variant_u300 = {
.fifosize   = 16 * 4,
.fifohalfsize   = 8 * 4,
.clkreg_enable  = MCI_ST_U300_HWFCEN,
+   .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS,
.datalength_bits= 16,
.sdio   = true,
.pwrreg_powerup = MCI_PWR_ON,
@@ -139,6 +142,7 @@ static struct variant_data variant_ux500 = {
.fifohalfsize   = 8 * 4,
.clkreg = MCI_CLK_ENABLE,
.clkreg_enable  = MCI_ST_UX500_HWFCEN,
+   .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS,
.datalength_bits= 24,
.sdio   = true,
.st_clkdiv  = true,
@@ -154,6 +158,7 @@ static struct variant_data variant_ux500v2 = {
.fifohalfsize   = 8 * 4,
.clkreg = MCI_CLK_ENABLE,
.clkreg_enable  = MCI_ST_UX500_HWFCEN,
+   .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS,
.datactrl_mask_ddrmode  = MCI_ST_DPSM_DDRMODE,
.datalength_bits= 24,
.sdio   = true,
@@ -305,7 +310,7 @@ static void mmci_set_clkreg(struct mmci_host *host, 
unsigned int desired)
if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_4)
clk |= MCI_4BIT_BUS;
if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_8)
-   clk |= MCI_ST_8BIT_BUS;
+   clk |= variant->clkreg_8bit_bus_enable;
 
if (host->mmc->ios.timing == MMC_TIMING_UHS_DDR50)
clk |= MCI_ST_UX500_NEG_EDGE;
-- 
1.9.1

--
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 v6 07/12] mmc: mmci: add edge support to data and command out in variant data.

2014-06-02 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

This patch adds edge support for data and command out to variant structure
giving more flexibility to the driver to support more SOCs which have
different clock register layout.

Without this patch other new SOCs like Qcom will have to add more code to
special case them

Signed-off-by: Srinivas Kandagatla 
Reviewed-by: Linus Walleij 
---
 drivers/mmc/host/mmci.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index fa3ad83..4c95a9b 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -53,6 +53,7 @@ static unsigned int fmax = 515633;
  * @clkreg: default value for MCICLOCK register
  * @clkreg_enable: enable value for MMCICLOCK register
  * @clkreg_8bit_bus_enable: enable value for 8 bit bus
+ * @clkreg_neg_edge_enable: enable value for inverted data/cmd output
  * @datalength_bits: number of bits in the MMCIDATALENGTH register
  * @fifosize: number of bytes that can be written when MMCI_TXFIFOEMPTY
  *   is asserted (likewise for RX)
@@ -74,6 +75,7 @@ struct variant_data {
unsigned intclkreg;
unsigned intclkreg_enable;
unsigned intclkreg_8bit_bus_enable;
+   unsigned intclkreg_neg_edge_enable;
unsigned intdatalength_bits;
unsigned intfifosize;
unsigned intfifohalfsize;
@@ -143,6 +145,7 @@ static struct variant_data variant_ux500 = {
.clkreg = MCI_CLK_ENABLE,
.clkreg_enable  = MCI_ST_UX500_HWFCEN,
.clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS,
+   .clkreg_neg_edge_enable = MCI_ST_UX500_NEG_EDGE,
.datalength_bits= 24,
.sdio   = true,
.st_clkdiv  = true,
@@ -159,6 +162,7 @@ static struct variant_data variant_ux500v2 = {
.clkreg = MCI_CLK_ENABLE,
.clkreg_enable  = MCI_ST_UX500_HWFCEN,
.clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS,
+   .clkreg_neg_edge_enable = MCI_ST_UX500_NEG_EDGE,
.datactrl_mask_ddrmode  = MCI_ST_DPSM_DDRMODE,
.datalength_bits= 24,
.sdio   = true,
@@ -313,7 +317,7 @@ static void mmci_set_clkreg(struct mmci_host *host, 
unsigned int desired)
clk |= variant->clkreg_8bit_bus_enable;
 
if (host->mmc->ios.timing == MMC_TIMING_UHS_DDR50)
-   clk |= MCI_ST_UX500_NEG_EDGE;
+   clk |= variant->clkreg_neg_edge_enable;
 
mmci_write_clkreg(host, clk);
 }
-- 
1.9.1

--
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 v6 08/12] mmc: mmci: Add support to data commands via variant structure.

2014-06-02 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

On some SOCs like Qcom there are explicit bits in the command register
to specify if its a data transfer command or not. So this patch adds
support to such bits in variant data, giving more flexibility to the
driver.

Signed-off-by: Srinivas Kandagatla 
Reviewed-by: Linus Walleij 
---
 drivers/mmc/host/mmci.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 4c95a9b..8534c29 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -59,6 +59,7 @@ static unsigned int fmax = 515633;
  *   is asserted (likewise for RX)
  * @fifohalfsize: number of bytes that can be written when MCI_TXFIFOHALFEMPTY
  *   is asserted (likewise for RX)
+ * @data_cmd_enable: enable value for data commands.
  * @sdio: variant supports SDIO
  * @st_clkdiv: true if using a ST-specific clock divider algorithm
  * @datactrl_mask_ddrmode: ddr mode mask in datactrl register.
@@ -79,6 +80,7 @@ struct variant_data {
unsigned intdatalength_bits;
unsigned intfifosize;
unsigned intfifohalfsize;
+   unsigned intdata_cmd_enable;
unsigned intdatactrl_mask_ddrmode;
boolsdio;
boolst_clkdiv;
@@ -839,6 +841,9 @@ mmci_start_command(struct mmci_host *host, struct 
mmc_command *cmd, u32 c)
if (/*interrupt*/0)
c |= MCI_CPSM_INTERRUPT;
 
+   if (mmc_cmd_type(cmd) == MMC_CMD_ADTC)
+   c |= host->variant->data_cmd_enable;
+
host->cmd = cmd;
 
writel(cmd->arg, base + MMCIARGUMENT);
-- 
1.9.1

--
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 v6 02/12] mmc: mmci: Add Qualcomm specific register defines.

2014-06-02 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

This patch adds a Qualcomm SD Card controller specific register variations
to header file. Qualcomm SDCC controller is pl180, with slight changes in
the register layout from standard pl180 register set.

Signed-off-by: Srinivas Kandagatla 
---
 drivers/mmc/host/mmci.h | 17 +
 1 file changed, 17 insertions(+)

diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h
index 347d942..d38a99d 100644
--- a/drivers/mmc/host/mmci.h
+++ b/drivers/mmc/host/mmci.h
@@ -41,6 +41,15 @@
 /* Modified PL180 on Versatile Express platform */
 #define MCI_ARM_HWFCEN (1 << 12)
 
+/* Modified on Qualcomm Integrations */
+#define MCI_QCOM_CLK_WIDEBUS_8 (BIT(10) | BIT(11))
+#define MCI_QCOM_CLK_FLOWENA   BIT(12)
+#define MCI_QCOM_CLK_INVERTOUT BIT(13)
+
+/* select in latch data and command in */
+#define MCI_QCOM_CLK_SELECT_IN_FBCLK   BIT(15)
+#define MCI_QCOM_CLK_SELECT_IN_DDR_MODE(BIT(14) | BIT(15))
+
 #define MMCIARGUMENT   0x008
 #define MMCICOMMAND0x00c
 #define MCI_CPSM_RESPONSE  (1 << 6)
@@ -54,6 +63,14 @@
 #define MCI_ST_NIEN(1 << 13)
 #define MCI_ST_CE_ATACMD   (1 << 14)
 
+/* Modified on Qualcomm Integrations */
+#define MCI_QCOM_CSPM_DATCMD   BIT(12)
+#define MCI_QCOM_CSPM_MCIABORT BIT(13)
+#define MCI_QCOM_CSPM_CCSENABLEBIT(14)
+#define MCI_QCOM_CSPM_CCSDISABLE   BIT(15)
+#define MCI_QCOM_CSPM_AUTO_CMD19   BIT(16)
+#define MCI_QCOM_CSPM_AUTO_CMD21   BIT(21)
+
 #define MMCIRESPCMD0x010
 #define MMCIRESPONSE0  0x014
 #define MMCIRESPONSE1  0x018
-- 
1.9.1

--
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] ARM: qcom: select GSBI from mach kconfig

2014-06-10 Thread Srinivas Kandagatla
This patch adds GSBI selection automatically from mach kconfig, As GSBI
seems to be the very basic SOC specific driver and serial driver depends on it.
I think this option should be selected via mach kconfig rather than adding
it to any defconfig.

Without this patch multi_v7_defconfig can not show up console on
IFC6410.

Signed-off-by: Srinivas Kandagatla 
---
 arch/arm/mach-qcom/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/mach-qcom/Kconfig b/arch/arm/mach-qcom/Kconfig
index 5bac591..d68d7ee 100644
--- a/arch/arm/mach-qcom/Kconfig
+++ b/arch/arm/mach-qcom/Kconfig
@@ -7,6 +7,7 @@ config ARCH_QCOM
select GENERIC_CLOCKEVENTS
select HAVE_SMP
select QCOM_SCM if SMP
+   select QCOM_GSBI
help
  Support for Qualcomm's devicetree based systems.
 
-- 
1.9.1

--
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 1/2] soc: qcom: do not disable the iface clock in probe

2014-06-10 Thread Srinivas Kandagatla
The use case here is when we have a bootconsole which is printing the
characters on serial console and gsbi driver comes up after some time.
As gsbi driver disables the clock in probe the bootconsole locks up.

This patch fixes the problem by disabling the clock in platform remove
rather than in probe.

Signed-off-by: Srinivas Kandagatla 
---
 drivers/soc/qcom/qcom_gsbi.c | 46 +++-
 1 file changed, 33 insertions(+), 13 deletions(-)

diff --git a/drivers/soc/qcom/qcom_gsbi.c b/drivers/soc/qcom/qcom_gsbi.c
index ab7b441..64fb298 100644
--- a/drivers/soc/qcom/qcom_gsbi.c
+++ b/drivers/soc/qcom/qcom_gsbi.c
@@ -22,44 +22,63 @@
 #define GSBI_CTRL_REG  0x
 #define GSBI_PROTOCOL_SHIFT4
 
+struct gsbi_info {
+   struct clk *hclk;
+   u32 mode;
+   u32 crci;
+};
+
 static int gsbi_probe(struct platform_device *pdev)
 {
struct device_node *node = pdev->dev.of_node;
struct resource *res;
void __iomem *base;
-   struct clk *hclk;
-   u32 mode, crci = 0;
+   struct gsbi_info *gsbi;
+
+   gsbi = devm_kzalloc(&pdev->dev, sizeof(*gsbi), GFP_KERNEL);
+
+   if (!gsbi)
+   return -ENOMEM;
 
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(base))
return PTR_ERR(base);
 
-   if (of_property_read_u32(node, "qcom,mode", &mode)) {
+   if (of_property_read_u32(node, "qcom,mode", &gsbi->mode)) {
dev_err(&pdev->dev, "missing mode configuration\n");
return -EINVAL;
}
 
/* not required, so default to 0 if not present */
-   of_property_read_u32(node, "qcom,crci", &crci);
+   of_property_read_u32(node, "qcom,crci", &gsbi->crci);
 
-   dev_info(&pdev->dev, "GSBI port protocol: %d crci: %d\n", mode, crci);
+   dev_info(&pdev->dev, "GSBI port protocol: %d crci: %d\n",
+gsbi->mode, gsbi->crci);
+   gsbi->hclk = devm_clk_get(&pdev->dev, "iface");
+   if (IS_ERR(gsbi->hclk))
+   return PTR_ERR(gsbi->hclk);
 
-   hclk = devm_clk_get(&pdev->dev, "iface");
-   if (IS_ERR(hclk))
-   return PTR_ERR(hclk);
+   clk_prepare_enable(gsbi->hclk);
 
-   clk_prepare_enable(hclk);
-
-   writel_relaxed((mode << GSBI_PROTOCOL_SHIFT) | crci,
+   writel_relaxed((gsbi->mode << GSBI_PROTOCOL_SHIFT) | gsbi->crci,
base + GSBI_CTRL_REG);
 
/* make sure the gsbi control write is not reordered */
wmb();
 
-   clk_disable_unprepare(hclk);
+   platform_set_drvdata(pdev, gsbi);
+
+   return of_platform_populate(node, NULL, NULL, &pdev->dev);
+}
+
+static int gsbi_remove(struct platform_device *pdev)
+{
+   struct gsbi_info *gsbi = platform_get_drvdata(pdev);
+
+   clk_disable_unprepare(gsbi->hclk);
 
-   return of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
+   return 0;
 }
 
 static const struct of_device_id gsbi_dt_match[] = {
@@ -76,6 +95,7 @@ static struct platform_driver gsbi_driver = {
.of_match_table = gsbi_dt_match,
},
.probe = gsbi_probe,
+   .remove = gsbi_remove,
 };
 
 module_platform_driver(gsbi_driver);
-- 
1.9.1

--
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 0/2] MSM/QCOM: Fix few race conditions when DEBUG_LL is enabled

2014-06-10 Thread Srinivas Kandagatla
When I started using earlyprintk on IFC6410 I noticed console lockups.

These two patches fix the issues in gsbi and serial driver.
One of the patch is to do with disabling clk while bootconsole is using it and
other is reseting IP while bootconsole is still throwing up characters.

I marked them as RFC for more comments and wanted to know if there are any
other better ways to fix this issue.


--srini

Srinivas Kandagatla (2):
  soc: qcom: do not disable the iface clock in probe
  tty:msm_serial: Do not reset IP if we use bootconsole

 drivers/soc/qcom/qcom_gsbi.c| 46 +
 drivers/tty/serial/msm_serial.c | 18 +++-
 2 files changed, 50 insertions(+), 14 deletions(-)

-- 
1.9.1

--
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 2/2] tty:msm_serial: Do not reset IP if we use bootconsole

2014-06-10 Thread Srinivas Kandagatla
The use case is when we boot the platform with bootconsole enabled. What
I noticed is that the console gets locked sometimes up before the bootconsole
is disabled.

As part of console setup in serial driver it resets that hardware which
is a race condition to bootconsole using the same hardware. This
patch adds a check to see if there is bootconsole before reseting the hardware.

Am sure there are better ways to solve this, so marking this patch as
RFC. Any suggestions are welcome.

Signed-off-by: Srinivas Kandagatla 
---
 drivers/tty/serial/msm_serial.c | 18 +-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c
index 778e376..7078153 100644
--- a/drivers/tty/serial/msm_serial.c
+++ b/drivers/tty/serial/msm_serial.c
@@ -913,6 +913,17 @@ static void msm_console_write(struct console *co, const 
char *s,
spin_unlock(&port->lock);
 }
 
+static int have_boot_console(void)
+{
+   struct console *con;
+
+   for_each_console(con)
+   if (con->flags & CON_BOOT)
+   return 1;
+
+   return 0;
+}
+
 static int __init msm_console_setup(struct console *co, char *options)
 {
struct uart_port *port;
@@ -943,7 +954,12 @@ static int __init msm_console_setup(struct console *co, 
char *options)
baud = 115200;
msm_set_baud_rate(port, baud);
 
-   msm_reset(port);
+   /*
+* do not reset if we are the boot console
+* can result in a lockup from bootconsole
+*/
+   if (have_boot_console())
+   msm_reset(port);
 
if (msm_port->is_uartdm) {
msm_write(port, UART_CR_CMD_PROTECTION_EN, UART_CR);
-- 
1.9.1

--
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 2/2] tty:msm_serial: Do not reset IP if we use bootconsole

2014-06-10 Thread Srinivas Kandagatla



On 10/06/14 15:32, Srinivas Kandagatla wrote:

+* do not reset if we are the boot console
+* can result in a lockup from bootconsole
+*/
+   if (have_boot_console())
+   msm_reset(port);

Oops..

I think I sent a wrong changeset I this patch... this should be.

if (!have_boot_console())
msm_reset(port);


Will fix it in next version..
--
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 1/2] soc: qcom: do not disable the iface clock in probe

2014-06-10 Thread Srinivas Kandagatla



On 10/06/14 18:39, Stephen Boyd wrote:

On 06/10/14 08:20, Kumar Gala wrote:

On Jun 10, 2014, at 9:31 AM, Srinivas Kandagatla 
 wrote:


The use case here is when we have a bootconsole which is printing the
characters on serial console and gsbi driver comes up after some time.
As gsbi driver disables the clock in probe the bootconsole locks up.

This patch fixes the problem by disabling the clock in platform remove
rather than in probe.

Signed-off-by: Srinivas Kandagatla 
---
drivers/soc/qcom/qcom_gsbi.c | 46 +++-
1 file changed, 33 insertions(+), 13 deletions(-)

It seems like we shouldn’t need this change.  Adding Stephen to see if there is 
a reason we don’t have the clk’s enable_count adjusted for how the bootloader 
setup clks.


This is a long standing problem with the clock framework. In our vendor
tree we've added something called "handoff" which basically detects the
state of all clocks upon registration and keeps clocks enabled until
late_init() if the clocks were enabled at the time of registration.

For this case though "handoff" doesn't seem necessary. It's easier to
just disable the clock when the driver is removed. With finer grained
power management this driver can participate in runtime_pm and disable
the ahb clock when the device is runtime suspended; which would only
happen when the child devices (uart/spi/i2c) are also runtime suspended.


I had same thought about gsbi participating in PM.



- k


diff --git a/drivers/soc/qcom/qcom_gsbi.c b/drivers/soc/qcom/qcom_gsbi.c
index ab7b441..64fb298 100644
--- a/drivers/soc/qcom/qcom_gsbi.c
+++ b/drivers/soc/qcom/qcom_gsbi.c
@@ -22,44 +22,63 @@
#define GSBI_CTRL_REG   0x
#define GSBI_PROTOCOL_SHIFT 4

+struct gsbi_info {
+   struct clk *hclk;
+   u32 mode;
+   u32 crci;
+};


What does mode and crci have to do with this patch? Can't we just put
the clock into the platform data?
It has nothing to do with this but, for completeness and we might need 
this if we are doing PM in future. for example pm resume might want to 
reconfigure the gsbi.


Am Ok with either approaches.


--srini




--
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 1/2] clk: qcom: add clocks necessary for apq8064 sdcc

2014-06-11 Thread Srinivas Kandagatla



On 11/06/14 10:14, Andreas Färber wrote:

This patch adds clocks necessary for SD card controller on apq8064 SOC.
>Without this patch the clocks are visible to the sdcc driver.

Was this maybe meant to read "invisible"?


You are correct it was suposed to be not visible, will fix it.



Regards,
Andreas


--
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 v6 00/12] Qualcomm SD Card Controller support

2014-06-11 Thread Srinivas Kandagatla

Hi Ulf,

On 11/06/14 18:35, Ulf Hansson wrote:

Thanks Srinivas, great work!

We didn't reach 3.16, but now I have applied this for my next branch
intended for 3.17.



That's great.



For you information, the v6 patchset needed a minor re-base, and one
of the patches had a checkpatch error. I managed to fix them, hope you
are fine with that.


Thankyou for fixing it.

--srini


Russell, if you have any concerns with the patches - just let me know,
then I can easily drop them.

Kind regards
Uffe

--
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 2/2] tty:msm_serial: Do not reset IP if we use bootconsole

2014-06-17 Thread Srinivas Kandagatla



On 17/06/14 22:09, Stephen Boyd wrote:

On 06/10/14 07:32, Srinivas Kandagatla wrote:

The use case is when we boot the platform with bootconsole enabled. What
I noticed is that the console gets locked sometimes up before the bootconsole
is disabled.

As part of console setup in serial driver it resets that hardware which
is a race condition to bootconsole using the same hardware. This
patch adds a check to see if there is bootconsole before reseting the hardware.

Am sure there are better ways to solve this, so marking this patch as
RFC. Any suggestions are welcome.




Isn't there some way to check and wait for the hardware to be unused
before we reset it?

I recall being able to overcome this "race condition" by removing the
printks in the serial driver setup. Does that work for you?


Good point,
Its possible that removing prints during the transition fixes the issue. 
I will give it a try.



--
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 v3 0/3] Qualcomm Resource Power Manager driver

2014-06-17 Thread Srinivas Kandagatla

Hi Bjorn,

Thankyou for the patches, these were handy for testing USB on APQ8064.

Tested-by: Srinivas Kandagatla 

--srini

On 16/06/14 19:46, Bjorn Andersson wrote:

This series adds a regulator driver for the Resource Power Manager found in
Qualcomm 8660, 8960 and 8064 based devices.

The RPM driver exposes resources to its child devices, that can be accessed to
implement drivers for the regulators, clocks and bus frequency control that's
owned by the RPM in these devices.

Changes since v2:
   - Fix copy-paste error in dt binding
   - Correct incomplete move from mfd to soc
   - Correct const mistake in regulator driver

Changes since v1:
   - Moved rpm driver to drivers/soc
   - Extracted resource table structs from rpm struct, as per Srinivas request
   - Dropped mode setting support for the regulators for now. Unsure if we need
 it and it requires some rework from the codeaurora solution.
   - Using set_voltage_sel instead of rolling my own "snapping", as per Marks
 request
   - Split regulator ops in mV, uV and swtich versions as per Marks request.
   - Added devicetree property to enable pull down.

Bjorn Andersson (3):
   soc: devicetree: bindings: Add Qualcomm RPM DT binding
   soc: qcom-rpm: Driver for the Qualcomm RPM
   regulator: qcom-rpm: Regulator driver for the Qualcomm RPM

  .../devicetree/bindings/soc/qcom/qcom,rpm.txt  | 261 +++
  drivers/regulator/Kconfig  |  12 +
  drivers/regulator/Makefile |   1 +
  drivers/regulator/qcom_rpm-regulator.c | 787 +
  drivers/soc/qcom/Kconfig   |  14 +
  drivers/soc/qcom/Makefile  |   1 +
  drivers/soc/qcom/qcom_rpm.c| 573 +++
  include/dt-bindings/soc/qcom,rpm.h | 142 
  include/linux/soc/qcom_rpm.h   |  12 +
  9 files changed, 1803 insertions(+)
  create mode 100644 Documentation/devicetree/bindings/soc/qcom/qcom,rpm.txt
  create mode 100644 drivers/regulator/qcom_rpm-regulator.c
  create mode 100644 drivers/soc/qcom/qcom_rpm.c
  create mode 100644 include/dt-bindings/soc/qcom,rpm.h
  create mode 100644 include/linux/soc/qcom_rpm.h


--
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 v3 1/3] soc: devicetree: bindings: Add Qualcomm RPM DT binding

2014-06-18 Thread Srinivas Kandagatla



On 18/06/14 00:59, Stephen Boyd wrote:

On 06/16/14 11:46, Bjorn Andersson wrote:

diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,rpm.txt 
b/Documentation/devicetree/bindings/soc/qcom/qcom,rpm.txt
new file mode 100644
index 000..0366533
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/qcom/qcom,rpm.txt
@@ -0,0 +1,260 @@
+Qualcomm Resource Power Manager (RPM)
+

[...]

+
+- reg:
+   Usage: required
+   Value type: 
+   Definition: two entries specifying the RPM's message ram and ipc 
register
+
+- reg-names:
+   Usage: required
+   Value type: 
+   Definition: must contain the following, in order:
+   "msg_ram"
+   "ipc"


ipc is concerning


+   rpm@108000 {
+   compatible = "qcom,rpm-msm8960";
+   reg = <0x108000 0x1000 0x2011008 0x4>;
+


(reg-names is missing from the example)

because ipc is actually a register inside the Krait complex's global
clock control/distribution hardware block (it's located at 0x2011000).
 From what I can tell, this is the only non-clock/power register inside
there. I plan to send out a driver for this hardware block so that I can
switch the L2 aux source mux over to PLL8 instead of PXO (done with a
single register write to 0x2011028) and this mapping/use here is going
to conflict with that unless I only map the single register like is done
here.

I wonder if we'd be better off making this region a separate node and
having some phandle to it here in the RPM node? That way we have a


Can't we use syscon based on regmap here?  syscon is a better way to 
share a common register space across multiple drivers.



driver that provides a clock and some IPC handle the RPM driver can get.
The SMD driver also uses the same register to kick other processors so
having some generic IPC handle may be useful there too.


--
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] ARM: multi_v7_defconfig: Add QCOM GSBI driver

2014-06-18 Thread Srinivas Kandagatla
This patch adds QCOM GSBI config option to multi_v7_defconfig. Serial
driver on QCOM APQ8064 depends on GSBI driver, so without this patch
there is no serial console on IF6410 board using multi_v7_defconfig.

Signed-off-by: Srinivas Kandagatla 
---
 arch/arm/configs/multi_v7_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/multi_v7_defconfig 
b/arch/arm/configs/multi_v7_defconfig
index e2d6204..f71731f 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -352,6 +352,7 @@ CONFIG_MFD_NVEC=y
 CONFIG_KEYBOARD_NVEC=y
 CONFIG_SERIO_NVEC_PS2=y
 CONFIG_NVEC_POWER=y
+CONFIG_QCOM_GSBI=y
 CONFIG_COMMON_CLK_QCOM=y
 CONFIG_MSM_GCC_8660=y
 CONFIG_MSM_MMCC_8960=y
-- 
1.9.1

--
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


  1   2   3   4   5   6   7   >