Re: [PATCH v6 2/4] ARM: pxa168: Add SDHCI support

2013-03-17 Thread Tanmay Upadhyay


On 3/17/13 8:13 PM, Haojian Zhuang wrote:

On Mon, Mar 18, 2013 at 2:18 AM, Tanmay Upadhyay
 wrote:

v2 - clock register for SDHCI are not common across all MMP SoCs.
  So, move PXA168 implementation to pxa168.c

v3 - sdhci-pxav1 driver code is merged with sdhci-pxav2. So, change
  the device name accordingly
- start sdhci device numbering from 1 as other PXA168 devices
  does that

v4 - Use different names for SD clock registers for PXA168 instead
  of redefining them in pxa168.c. Suggested by Haojian Zhuang

v5 - Have two different clock enable functions for clock block 1 & 2
  & don't change indentation in regs-apmu.h as suggested by Haojian
  Zhuang
- Use device name while adding clock as suggested by Russell King

v6 - Rebase for Linux v3.8; de-select COMMON_CLK for PXA168 as its
  SDHCI clocks should be handled differently than others
---
  arch/arm/mach-mmp/Kconfig   |1 -
  arch/arm/mach-mmp/clock-pxa168.c|   47 +++
  arch/arm/mach-mmp/include/mach/pxa168.h |   20 +
  arch/arm/mach-mmp/pxa168.c  |4 +++
  4 files changed, 71 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-mmp/Kconfig b/arch/arm/mach-mmp/Kconfig
index ebdda83..530245c 100644
--- a/arch/arm/mach-mmp/Kconfig
+++ b/arch/arm/mach-mmp/Kconfig
@@ -111,7 +111,6 @@ endmenu

  config CPU_PXA168
 bool
-   select COMMON_CLK
 select CPU_MOHAWK
 help
   Select code specific to PXA168
diff --git a/arch/arm/mach-mmp/clock-pxa168.c b/arch/arm/mach-mmp/clock-pxa168.c
index 5e6c18c..65ea00e 100644
--- a/arch/arm/mach-mmp/clock-pxa168.c
+++ b/arch/arm/mach-mmp/clock-pxa168.c
@@ -31,11 +31,49 @@
  #define APBC_SSP4  APBC_REG(0x858)
  #define APBC_SSP5  APBC_REG(0x85c)

+#define APMU_SDH0  APMU_REG(0x054)
+#define APMU_SDH1  APMU_REG(0x058)
  #define APMU_NAND  APMU_REG(0x060)
  #define APMU_LCD   APMU_REG(0x04c)
+#define APMU_SDH2  APMU_REG(0x0e0)
+#define APMU_SDH3  APMU_REG(0x0e4)
  #define APMU_ETH   APMU_REG(0x0fc)
  #define APMU_USB   APMU_REG(0x05c)

+static void sdh1_clk_enable(struct clk *clk)
+{
+   /* Bits 3 & 0 in registers for host 0 should be set for host 1 also */
+   __raw_writel(__raw_readl(APMU_SDH0) | 0x9, APMU_SDH0);
+
+   __raw_writel(__raw_readl(clk->clk_rst) | clk->enable_val, clk->clk_rst);
+}
+
+static void sdh2_clk_enable(struct clk *clk)
+{
+   /* Bits 3 & 0 in registers for host 2 should be set for host 3 also */
+   __raw_writel(__raw_readl(APMU_SDH2) | 0x9, APMU_SDH2);
+
+   __raw_writel(__raw_readl(clk->clk_rst) | clk->enable_val, clk->clk_rst);
+}
+
+static void sdh_clk_disable(struct clk *clk)
+{
+   __raw_writel(__raw_readl(clk->clk_rst) & ~clk->enable_val,
+   clk->clk_rst);
+}
+
+/* Block 1 for controller 0 & 1 */
+struct clkops sdh1_clk_ops = {
+   .enable = sdh1_clk_enable,
+   .disable= sdh_clk_disable,
+};
+
+/* Block 2 for controller 2 & 3 */
+struct clkops sdh2_clk_ops = {
+   .enable = sdh2_clk_enable,
+   .disable= sdh_clk_disable,
+};
+
  /* APB peripheral clocks */
  static APBC_CLK(uart1, UART1, 1, 14745600);
  static APBC_CLK(uart2, UART2, 1, 14745600);
@@ -60,6 +98,11 @@ static APMU_CLK(lcd, LCD, 0x7f, 31200);
  static APMU_CLK(eth, ETH, 0x09, 0);
  static APMU_CLK(usb, USB, 0x12, 0);

+static APMU_CLK_OPS(sdh1, SDH0, 0x12, 4800, &sdh1_clk_ops);
+static APMU_CLK_OPS(sdh2, SDH1, 0x12, 4800, &sdh1_clk_ops);
+static APMU_CLK_OPS(sdh3, SDH2, 0x12, 4800, &sdh2_clk_ops);
+static APMU_CLK_OPS(sdh4, SDH3, 0x12, 4800, &sdh2_clk_ops);
+
  /* device and clock bindings */
  static struct clk_lookup pxa168_clkregs[] = {
 INIT_CLKREG(&clk_uart1, "pxa2xx-uart.0", NULL),
@@ -83,6 +126,10 @@ static struct clk_lookup pxa168_clkregs[] = {
 INIT_CLKREG(&clk_eth, "pxa168-eth", "MFUCLK"),
 INIT_CLKREG(&clk_usb, NULL, "PXA168-USBCLK"),
 INIT_CLKREG(&clk_rtc, "sa1100-rtc", NULL),
+   INIT_CLKREG(&clk_sdh1, "sdhci-pxav2.0", "PXA-SDHCLK"),
+   INIT_CLKREG(&clk_sdh2, "sdhci-pxav2.1", "PXA-SDHCLK"),
+   INIT_CLKREG(&clk_sdh3, "sdhci-pxav2.2", "PXA-SDHCLK"),
+   INIT_CLKREG(&clk_sdh4, "sdhci-pxav2.3", "PXA-SDHCLK"),
  };

  void __init pxa168_clk_init(void)
diff --git a/arch/arm/mach-mmp/include/mach/pxa168.h 
b/arch/arm/mach-mmp/include/mach/pxa168.h
index 37632d9..805117e 100644
--- a/arch/arm/mach-mmp/include/mach/pxa168.h
+++ b/arch/arm/mach-mmp/include/mach/pxa168.h
@@ -17,6 +17,7 @@ extern void pxa168_clear_keypad_wakeup(void);
  #include 
  #include 
  #include 
+#include 

  extern struct pxa_device_desc pxa168_device_uart1;
  e

[PATCH v2 4/4] ARM: pxa168/gplugd: Add support for SD port 1

2013-03-17 Thread Tanmay Upadhyay
v2 - after sdhci-pxav1 driver is merged with sdhci-pxav2, pass
 pxav1_controller = 1
   - as sdhci device numbering now starts from 1, call
 pxa168_add_sdh accordingly

Signed-off-by: Tanmay Upadhyay 
Reviewed-by: Philip Rakity 
---
 arch/arm/mach-mmp/gplugd.c |6 ++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm/mach-mmp/gplugd.c b/arch/arm/mach-mmp/gplugd.c
index 5c3d61e..d821368 100644
--- a/arch/arm/mach-mmp/gplugd.c
+++ b/arch/arm/mach-mmp/gplugd.c
@@ -155,6 +155,11 @@ struct pxa168_eth_platform_data gplugd_eth_platform_data = 
{
.init= gplugd_eth_init,
 };
 
+struct sdhci_pxa_platdata gplugd_sdh_platdata = {
+   .delay_in_ms = 5,
+   .pxav1_controller = 1,
+};
+
 static void __init select_disp_freq(void)
 {
/* set GPIO 35 & clear GPIO 85 to set LCD External Clock to 74.25 MHz */
@@ -188,6 +193,7 @@ static void __init gplugd_init(void)
platform_device_register(&pxa168_device_gpio);
 
pxa168_add_eth(&gplugd_eth_platform_data);
+   pxa168_add_sdh(1, &gplugd_sdh_platdata);
 }
 
 MACHINE_START(GPLUGD, "PXA168-based GuruPlug Display (gplugD) Platform")
-- 
1.7.9.5

*
eInfochips Business Disclaimer : This e-mail message and all attachments 
transmitted with it are intended solely for the use of the addressee and may 
contain legally privileged and confidential information. If the reader of this 
message is not the intended recipient, or an employee or agent responsible for 
delivering this message to the intended recipient, you are hereby notified that 
any dissemination, distribution, copying, or other use of this message or its 
attachments is strictly prohibited. If you have received this message in error, 
please notify the sender immediately by replying to this message and please 
delete it from your computer. Any views expressed in this message are those of 
the individual sender unless otherwise stated. Company has taken enough 
precautions to prevent the spread of viruses. However the company accepts no 
liability for any damage caused by any virus transmitted by this email.
*


-
Notice: 
This message has been scanned by Trend Micro Mail Security scanner and is 
believed to be clean
-N‹§˛ćěr¸›yúčšŘb˛XŹśÇ§vŘ^–)Ţş{.nÇ+‰ˇĽŠ{ąšg"žŘ^n‡rĄöŚzˁëh™¨č­Ú&˘řŽGŤéhŽ(­éšŽŠÝ˘j"úśm§˙ďęäzšŢ–ŠŕţfŁ˘ˇhšˆ§~ˆmš

[PATCH v2 3/4] mmc: sdhci-pxa: Add SDHCI driver for PXA16x

2013-03-17 Thread Tanmay Upadhyay
PXA16x devices uses SDHCI controller v1. As it's not much different
than v2 controller, v1 driver is merged with sdhci-pxav2 driver

v2 - instead of having separate file sdhci-pxav1, merge code with
 sdhci-pxav2 driver code as suggested by Chris Ball

Signed-off-by: Philip Rakity 
Signed-off-by: Tanmay Upadhyay 
---
 drivers/mmc/host/Kconfig|7 ---
 drivers/mmc/host/sdhci-pxav2.c  |   30 +-
 drivers/mmc/host/sdhci.c|3 +++
 drivers/mmc/host/sdhci.h|1 +
 include/linux/platform_data/pxa_sdhci.h |2 ++
 5 files changed, 39 insertions(+), 4 deletions(-)

diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index e5faed8..875e2475 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -207,14 +207,15 @@ config MMC_SDHCI_PXAV3
  If unsure, say N.
 
 config MMC_SDHCI_PXAV2
-   tristate "Marvell PXA9XX SD Host Controller support (PXAV2)"
+   tristate "Marvell PXA16X/PXA9XX SD Host Controller support (PXAV1/V2)"
depends on CLKDEV_LOOKUP
select MMC_SDHCI
select MMC_SDHCI_PLTFM
default y if CPU_PXA910
+   default y if CPU_PXA168
help
- This selects the Marvell(R) PXAV2 SD Host Controller.
- If you have a PXA9XX platform with SD Host Controller
+ This selects the Marvell(R) PXAV1/V2 SD Host Controller.
+ If you have a PXA16X or PXA9XX platform with SD Host Controller
  and a card slot, say Y or M here.
 
  If unsure, say N.
diff --git a/drivers/mmc/host/sdhci-pxav2.c b/drivers/mmc/host/sdhci-pxav2.c
index ac854aa..5af7d46 100644
--- a/drivers/mmc/host/sdhci-pxav2.c
+++ b/drivers/mmc/host/sdhci-pxav2.c
@@ -30,6 +30,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "sdhci.h"
 #include "sdhci-pltfm.h"
@@ -75,7 +76,13 @@ static void pxav2_set_private_registers(struct sdhci_host 
*host, u8 mask)
writew(tmp, host->ioaddr + SD_CLOCK_BURST_SIZE_SETUP);
}
 
-   if (pdata && (pdata->flags & PXA_FLAG_ENABLE_CLOCK_GATING)) {
+   if (pdata && pdata->pxav1_controller) {
+   /* no clock gating */
+   tmp = readw(host->ioaddr + SD_FIFO_PARAM);
+   tmp |= DIS_PAD_SD_CLK_GATE;
+   writew(tmp, host->ioaddr + SD_FIFO_PARAM);
+   } else if (pdata && (pdata->flags
+   & PXA_FLAG_ENABLE_CLOCK_GATING)) {
tmp = readw(host->ioaddr + SD_FIFO_PARAM);
tmp &= ~CLK_GATE_SETTING_BITS;
writew(tmp, host->ioaddr + SD_FIFO_PARAM);
@@ -118,6 +125,20 @@ static u32 pxav2_get_max_clock(struct sdhci_host *host)
return clk_get_rate(pltfm_host->clk);
 }
 
+/*
+ * we cannot talk to controller for 8 bus cycles according to sdio spec
+ * at lowest speed this is 100,000 HZ per cycle or 800,000 cycles
+ * which is quite a LONG TIME on a fast cpu -- so delay if needed
+ */
+static void platform_specific_completion(struct sdhci_host *host)
+{
+   struct platform_device *pdev = to_platform_device(mmc_dev(host->mmc));
+   struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data;
+
+   if (host->clock < 320 && pdata && pdata->delay_in_ms)
+   mdelay(pdata->delay_in_ms);
+}
+
 static struct sdhci_ops pxav2_sdhci_ops = {
.get_max_clock = pxav2_get_max_clock,
.platform_reset_exit = pxav2_set_private_registers,
@@ -218,6 +239,13 @@ static int sdhci_pxav2_probe(struct platform_device *pdev)
if (pdata->flags & PXA_FLAG_SD_8_BIT_CAPABLE_SLOT)
host->mmc->caps |= MMC_CAP_8_BIT_DATA;
 
+   if (pdata->pxav1_controller) {
+   host->quirks |= SDHCI_QUIRK_NO_BUSY_IRQ
+   | SDHCI_QUIRK_32BIT_DMA_SIZE;
+   pxav2_sdhci_ops.platform_specific_completion
+   = platform_specific_completion;
+   }
+
if (pdata->quirks)
host->quirks |= pdata->quirks;
if (pdata->host_caps)
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 6f0bfc0..430eabd 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1001,6 +1001,9 @@ static void sdhci_send_command(struct sdhci_host *host, 
struct mmc_command *cmd)
mdelay(1);
}
 
+   if (host->ops->platform_specific_completion)
+   host->ops->platform_specific_completion(host);
+
mod_timer(&host->timer, jiffies + 10 * HZ);
 
host->cmd = cmd;
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sd

[PATCH 0/4] Add SD support for PXA168 & gplugD

2013-03-17 Thread Tanmay Upadhyay
This patch series adds support for on-chip SD controller on PXA168

Tanmay Upadhyay (4):
  mmc: sdhci-pxa: Trivial fix in Kconfig
  ARM: pxa168: Add SDHCI support
  mmc: sdhci-pxa: Add SDHCI driver for PXA16x
  ARM: pxa168/gplugd: Add support for SD port 1

 arch/arm/mach-mmp/Kconfig   |1 -
 arch/arm/mach-mmp/clock-pxa168.c|   47 +++
 arch/arm/mach-mmp/gplugd.c  |6 
 arch/arm/mach-mmp/include/mach/pxa168.h |   20 +
 arch/arm/mach-mmp/pxa168.c  |4 +++
 drivers/mmc/host/Kconfig|   11 
 drivers/mmc/host/sdhci-pxav2.c  |   30 +++-
 drivers/mmc/host/sdhci.c|3 ++
 drivers/mmc/host/sdhci.h|1 +
 include/linux/platform_data/pxa_sdhci.h |2 ++
 10 files changed, 118 insertions(+), 7 deletions(-)

-- 
1.7.9.5

*
eInfochips Business Disclaimer : This e-mail message and all attachments 
transmitted with it are intended solely for the use of the addressee and may 
contain legally privileged and confidential information. If the reader of this 
message is not the intended recipient, or an employee or agent responsible for 
delivering this message to the intended recipient, you are hereby notified that 
any dissemination, distribution, copying, or other use of this message or its 
attachments is strictly prohibited. If you have received this message in error, 
please notify the sender immediately by replying to this message and please 
delete it from your computer. Any views expressed in this message are those of 
the individual sender unless otherwise stated. Company has taken enough 
precautions to prevent the spread of viruses. However the company accepts no 
liability for any damage caused by any virus transmitted by this email.
*


-
Notice: 
This message has been scanned by Trend Micro Mail Security scanner and is 
believed to be clean
-

[PATCH 1/4] mmc: sdhci-pxa: Trivial fix in Kconfig

2013-03-17 Thread Tanmay Upadhyay
Select MMC_SDHCI_PXAV3 by default if CPU is MMP2
Select MMC_SDHCI_PXAV2 by default if CPU is PXA910

Signed-off-by: Tanmay Upadhyay 
Reviewed-by: Philip Rakity 
---
 drivers/mmc/host/Kconfig |4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 8d13c65..e5faed8 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -198,7 +198,7 @@ config MMC_SDHCI_PXAV3
depends on CLKDEV_LOOKUP
select MMC_SDHCI
select MMC_SDHCI_PLTFM
-   default CPU_MMP2
+   default y if CPU_MMP2
help
  This selects the Marvell(R) PXAV3 SD Host Controller.
  If you have a MMP2 platform with SD Host Controller
@@ -211,7 +211,7 @@ config MMC_SDHCI_PXAV2
depends on CLKDEV_LOOKUP
select MMC_SDHCI
select MMC_SDHCI_PLTFM
-   default CPU_PXA910
+   default y if CPU_PXA910
help
  This selects the Marvell(R) PXAV2 SD Host Controller.
  If you have a PXA9XX platform with SD Host Controller
-- 
1.7.9.5

*
eInfochips Business Disclaimer : This e-mail message and all attachments 
transmitted with it are intended solely for the use of the addressee and may 
contain legally privileged and confidential information. If the reader of this 
message is not the intended recipient, or an employee or agent responsible for 
delivering this message to the intended recipient, you are hereby notified that 
any dissemination, distribution, copying, or other use of this message or its 
attachments is strictly prohibited. If you have received this message in error, 
please notify the sender immediately by replying to this message and please 
delete it from your computer. Any views expressed in this message are those of 
the individual sender unless otherwise stated. Company has taken enough 
precautions to prevent the spread of viruses. However the company accepts no 
liability for any damage caused by any virus transmitted by this email.
*


-
Notice: 
This message has been scanned by Trend Micro Mail Security scanner and is 
believed to be clean
-

[PATCH v6 2/4] ARM: pxa168: Add SDHCI support

2013-03-17 Thread Tanmay Upadhyay
v2 - clock register for SDHCI are not common across all MMP SoCs.
 So, move PXA168 implementation to pxa168.c

v3 - sdhci-pxav1 driver code is merged with sdhci-pxav2. So, change
 the device name accordingly
   - start sdhci device numbering from 1 as other PXA168 devices
 does that

v4 - Use different names for SD clock registers for PXA168 instead
 of redefining them in pxa168.c. Suggested by Haojian Zhuang

v5 - Have two different clock enable functions for clock block 1 & 2
 & don't change indentation in regs-apmu.h as suggested by Haojian
 Zhuang
   - Use device name while adding clock as suggested by Russell King

v6 - Rebase for Linux v3.8; de-select COMMON_CLK for PXA168 as its
 SDHCI clocks should be handled differently than others
---
 arch/arm/mach-mmp/Kconfig   |1 -
 arch/arm/mach-mmp/clock-pxa168.c|   47 +++
 arch/arm/mach-mmp/include/mach/pxa168.h |   20 +
 arch/arm/mach-mmp/pxa168.c  |4 +++
 4 files changed, 71 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-mmp/Kconfig b/arch/arm/mach-mmp/Kconfig
index ebdda83..530245c 100644
--- a/arch/arm/mach-mmp/Kconfig
+++ b/arch/arm/mach-mmp/Kconfig
@@ -111,7 +111,6 @@ endmenu
 
 config CPU_PXA168
bool
-   select COMMON_CLK
select CPU_MOHAWK
help
  Select code specific to PXA168
diff --git a/arch/arm/mach-mmp/clock-pxa168.c b/arch/arm/mach-mmp/clock-pxa168.c
index 5e6c18c..65ea00e 100644
--- a/arch/arm/mach-mmp/clock-pxa168.c
+++ b/arch/arm/mach-mmp/clock-pxa168.c
@@ -31,11 +31,49 @@
 #define APBC_SSP4  APBC_REG(0x858)
 #define APBC_SSP5  APBC_REG(0x85c)
 
+#define APMU_SDH0  APMU_REG(0x054)
+#define APMU_SDH1  APMU_REG(0x058)
 #define APMU_NAND  APMU_REG(0x060)
 #define APMU_LCD   APMU_REG(0x04c)
+#define APMU_SDH2  APMU_REG(0x0e0)
+#define APMU_SDH3  APMU_REG(0x0e4)
 #define APMU_ETH   APMU_REG(0x0fc)
 #define APMU_USB   APMU_REG(0x05c)
 
+static void sdh1_clk_enable(struct clk *clk)
+{
+   /* Bits 3 & 0 in registers for host 0 should be set for host 1 also */
+   __raw_writel(__raw_readl(APMU_SDH0) | 0x9, APMU_SDH0);
+
+   __raw_writel(__raw_readl(clk->clk_rst) | clk->enable_val, clk->clk_rst);
+}
+
+static void sdh2_clk_enable(struct clk *clk)
+{
+   /* Bits 3 & 0 in registers for host 2 should be set for host 3 also */
+   __raw_writel(__raw_readl(APMU_SDH2) | 0x9, APMU_SDH2);
+
+   __raw_writel(__raw_readl(clk->clk_rst) | clk->enable_val, clk->clk_rst);
+}
+
+static void sdh_clk_disable(struct clk *clk)
+{
+   __raw_writel(__raw_readl(clk->clk_rst) & ~clk->enable_val,
+   clk->clk_rst);
+}
+
+/* Block 1 for controller 0 & 1 */
+struct clkops sdh1_clk_ops = {
+   .enable = sdh1_clk_enable,
+   .disable= sdh_clk_disable,
+};
+
+/* Block 2 for controller 2 & 3 */
+struct clkops sdh2_clk_ops = {
+   .enable = sdh2_clk_enable,
+   .disable= sdh_clk_disable,
+};
+
 /* APB peripheral clocks */
 static APBC_CLK(uart1, UART1, 1, 14745600);
 static APBC_CLK(uart2, UART2, 1, 14745600);
@@ -60,6 +98,11 @@ static APMU_CLK(lcd, LCD, 0x7f, 31200);
 static APMU_CLK(eth, ETH, 0x09, 0);
 static APMU_CLK(usb, USB, 0x12, 0);
 
+static APMU_CLK_OPS(sdh1, SDH0, 0x12, 4800, &sdh1_clk_ops);
+static APMU_CLK_OPS(sdh2, SDH1, 0x12, 4800, &sdh1_clk_ops);
+static APMU_CLK_OPS(sdh3, SDH2, 0x12, 4800, &sdh2_clk_ops);
+static APMU_CLK_OPS(sdh4, SDH3, 0x12, 4800, &sdh2_clk_ops);
+
 /* device and clock bindings */
 static struct clk_lookup pxa168_clkregs[] = {
INIT_CLKREG(&clk_uart1, "pxa2xx-uart.0", NULL),
@@ -83,6 +126,10 @@ static struct clk_lookup pxa168_clkregs[] = {
INIT_CLKREG(&clk_eth, "pxa168-eth", "MFUCLK"),
INIT_CLKREG(&clk_usb, NULL, "PXA168-USBCLK"),
INIT_CLKREG(&clk_rtc, "sa1100-rtc", NULL),
+   INIT_CLKREG(&clk_sdh1, "sdhci-pxav2.0", "PXA-SDHCLK"),
+   INIT_CLKREG(&clk_sdh2, "sdhci-pxav2.1", "PXA-SDHCLK"),
+   INIT_CLKREG(&clk_sdh3, "sdhci-pxav2.2", "PXA-SDHCLK"),
+   INIT_CLKREG(&clk_sdh4, "sdhci-pxav2.3", "PXA-SDHCLK"),
 };
 
 void __init pxa168_clk_init(void)
diff --git a/arch/arm/mach-mmp/include/mach/pxa168.h 
b/arch/arm/mach-mmp/include/mach/pxa168.h
index 37632d9..805117e 100644
--- a/arch/arm/mach-mmp/include/mach/pxa168.h
+++ b/arch/arm/mach-mmp/include/mach/pxa168.h
@@ -17,6 +17,7 @@ extern void pxa168_clear_keypad_wakeup(void);
 #include 
 #include 
 #include 
+#include 
 
 extern struct pxa_device_desc pxa168_device_uart1;
 extern struct pxa_device_desc pxa168_device_uart2;
@@ -36,6 +37,10 @@ extern struct pxa_device_desc pxa168_device_nand;
 extern struct pxa_device_desc pxa168_device_fb;
 extern struct pxa_device_desc pxa168_device_keypad;
 extern struct pxa_device_desc pxa168_device_eth;
+extern struct pxa_device_desc pxa168_device_sdh1;
+extern struct pxa_device_desc pxa168_device_sdh2;
+extern str

Re: [PATCH 2/4] ARM: pxa168: Add SDHCI support

2012-01-23 Thread Tanmay Upadhyay



On Thursday 29 December 2011 06:36 PM, Haojian Zhuang wrote:

On Thu, Dec 29, 2011 at 9:43 PM, Tanmay Upadhyay
  wrote:

v2 - clock register for SDHCI are not common across all MMP SoCs.
 So, move PXA168 implementation to pxa168.c

v3 - sdhci-pxav1 driver code is merged with sdhci-pxav2. So, change
 the device name accordingly
   - start sdhci device numbering from 1 as other PXA168 devices
 does that

v4 - Use different names for SD clock registers for PXA168 instead
 of redefining them in pxa168.c. Suggested by Haojian Zhuang

v5 - Have two different clock enable functions for clock block 1&  2
 &  don't change indentation in regs-apmu.h as suggested by Haojian
 Zhuang
   - Use device name while adding clock as suggested by Russell King

Signed-off-by: Tanmay Upadhyay
Reviewed-by: Philip Rakity
---

Acked-by: Haojian Zhuang


Hi Eric, Jason,

Does this look good to you?

Thanks,

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



[PATCH 2/4] ARM: pxa168: Add SDHCI support

2011-12-29 Thread Tanmay Upadhyay
v2 - clock register for SDHCI are not common across all MMP SoCs.
 So, move PXA168 implementation to pxa168.c

v3 - sdhci-pxav1 driver code is merged with sdhci-pxav2. So, change
 the device name accordingly
   - start sdhci device numbering from 1 as other PXA168 devices
 does that

v4 - Use different names for SD clock registers for PXA168 instead
 of redefining them in pxa168.c. Suggested by Haojian Zhuang

v5 - Have two different clock enable functions for clock block 1 & 2
 & don't change indentation in regs-apmu.h as suggested by Haojian
 Zhuang
   - Use device name while adding clock as suggested by Russell King

Signed-off-by: Tanmay Upadhyay 
Reviewed-by: Philip Rakity 
---
 arch/arm/mach-mmp/include/mach/pxa168.h|   20 
 arch/arm/mach-mmp/include/mach/regs-apmu.h |2 +
 arch/arm/mach-mmp/pxa168.c |   47 
 3 files changed, 69 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-mmp/include/mach/pxa168.h 
b/arch/arm/mach-mmp/include/mach/pxa168.h
index 7fb568d..a181608 100644
--- a/arch/arm/mach-mmp/include/mach/pxa168.h
+++ b/arch/arm/mach-mmp/include/mach/pxa168.h
@@ -15,6 +15,7 @@ extern void pxa168_clear_keypad_wakeup(void);
 #include 
 #include 
 #include 
+#include 
 
 extern struct pxa_device_desc pxa168_device_uart1;
 extern struct pxa_device_desc pxa168_device_uart2;
@@ -34,6 +35,10 @@ extern struct pxa_device_desc pxa168_device_nand;
 extern struct pxa_device_desc pxa168_device_fb;
 extern struct pxa_device_desc pxa168_device_keypad;
 extern struct pxa_device_desc pxa168_device_eth;
+extern struct pxa_device_desc pxa168_device_sdh1;
+extern struct pxa_device_desc pxa168_device_sdh2;
+extern struct pxa_device_desc pxa168_device_sdh3;
+extern struct pxa_device_desc pxa168_device_sdh4;
 
 struct pxa168_usb_pdata {
/* If NULL, default phy init routine for PXA168 would be called */
@@ -132,4 +137,19 @@ static inline int pxa168_add_eth(struct 
pxa168_eth_platform_data *data)
 {
return pxa_register_device(&pxa168_device_eth, data, sizeof(*data));
 }
+
+static inline int pxa168_add_sdh(int id, struct sdhci_pxa_platdata *data)
+{
+   struct pxa_device_desc *d = NULL;
+
+   switch (id) {
+   case 1: d = &pxa168_device_sdh1; break;
+   case 2: d = &pxa168_device_sdh2; break;
+   case 3: d = &pxa168_device_sdh3; break;
+   case 4: d = &pxa168_device_sdh4; break;
+   default:
+   return -EINVAL;
+   }
+   return pxa_register_device(d, data, sizeof(*data));
+}
 #endif /* __ASM_MACH_PXA168_H */
diff --git a/arch/arm/mach-mmp/include/mach/regs-apmu.h 
b/arch/arm/mach-mmp/include/mach/regs-apmu.h
index 8447ac6..db55618 100644
--- a/arch/arm/mach-mmp/include/mach/regs-apmu.h
+++ b/arch/arm/mach-mmp/include/mach/regs-apmu.h
@@ -27,6 +27,8 @@
 #define APMU_DMA   APMU_REG(0x064)
 #define APMU_GEU   APMU_REG(0x068)
 #define APMU_BUS   APMU_REG(0x06c)
+#define APMU_PXA168_SDH2   APMU_REG(0x0e0)
+#define APMU_PXA168_SDH3   APMU_REG(0x0e4)
 #define APMU_SDH2  APMU_REG(0x0e8)
 #define APMU_SDH3  APMU_REG(0x0ec)
 #define APMU_ETH   APMU_REG(0x0fc)
diff --git a/arch/arm/mach-mmp/pxa168.c b/arch/arm/mach-mmp/pxa168.c
index 76ca15c..d7d7143 100644
--- a/arch/arm/mach-mmp/pxa168.c
+++ b/arch/arm/mach-mmp/pxa168.c
@@ -65,6 +65,40 @@ void __init pxa168_init_irq(void)
pxa168_init_gpio();
 }
 
+static void sdh1_clk_enable(struct clk *clk)
+{
+   /* Bits 3 & 0 in registers for host 0 should be set for host 1 also */
+   __raw_writel(__raw_readl(APMU_SDH0) | 0x9, APMU_SDH0);
+
+   __raw_writel(__raw_readl(clk->clk_rst) | clk->enable_val, clk->clk_rst);
+}
+
+static void sdh2_clk_enable(struct clk *clk)
+{
+   /* Bits 3 & 0 in registers for host 2 should be set for host 3 also */
+   __raw_writel(__raw_readl(APMU_PXA168_SDH2) | 0x9, APMU_PXA168_SDH2);
+
+   __raw_writel(__raw_readl(clk->clk_rst) | clk->enable_val, clk->clk_rst);
+}
+
+static void sdh_clk_disable(struct clk *clk)
+{
+   __raw_writel(__raw_readl(clk->clk_rst) & ~clk->enable_val,
+   clk->clk_rst);
+}
+
+/* Block 1 for controller 0 & 1 */
+struct clkops sdh1_clk_ops = {
+   .enable = sdh1_clk_enable,
+   .disable= sdh_clk_disable,
+};
+
+/* Block 2 for controller 2 & 3 */
+struct clkops sdh2_clk_ops = {
+   .enable = sdh2_clk_enable,
+   .disable= sdh_clk_disable,
+};
+
 /* APB peripheral clocks */
 static APBC_CLK(uart1, PXA168_UART1, 1, 14745600);
 static APBC_CLK(uart2, PXA168_UART2, 1, 14745600);
@@ -87,6 +121,11 @@ static APMU_CLK(lcd, LCD, 0x7f, 31200);
 static APMU_CLK(eth, ETH, 0x09, 0);
 static APMU_CLK(usb, USB, 0x12, 0);
 
+static APMU_CLK_OPS(sdh1, SDH0, 0x12, 4800, &sdh1_clk_ops);
+static APMU_CLK_OPS(sdh2, SDH1, 0x12, 4800, &sdh1_clk_ops);
+static APMU_CLK_OPS(s

Re: [PATCH v4 2/4] ARM: pxa168: Add SDHCI support

2011-12-20 Thread Tanmay Upadhyay



On Tuesday 20 December 2011 07:08 PM, Haojian Zhuang wrote:

On Tue, Dec 20, 2011 at 9:25 PM, Haojian Zhuang
  wrote:

On Tue, Dec 20, 2011 at 9:13 PM, Tanmay Upadhyay
  wrote:

v2 - clock register for SDHCI are not common across all MMP SoCs.
 So, move PXA168 implementation to pxa168.c

v3 - sdhci-pxav1 driver code is merged with sdhci-pxav2. So, change
 the device name accordingly
   - start sdhci device numbering from 1 as other PXA168 devices
 does that

v4 - Use different names for SD clock registers for PXA168 instead
 of redefining them in pxa168.c. Suggested by Haojian Zhuang

Signed-off-by: Tanmay Upadhyay
Reviewed-by: Philip Rakity
---
  arch/arm/mach-mmp/include/mach/pxa168.h|   20 ++
  arch/arm/mach-mmp/include/mach/regs-apmu.h |   40 ++-
  arch/arm/mach-mmp/pxa168.c |   39 +++
  3 files changed, 80 insertions(+), 19 deletions(-)

diff --git a/arch/arm/mach-mmp/include/mach/pxa168.h 
b/arch/arm/mach-mmp/include/mach/pxa168.h
index 7fb568d..a181608 100644
--- a/arch/arm/mach-mmp/include/mach/pxa168.h
+++ b/arch/arm/mach-mmp/include/mach/pxa168.h
@@ -15,6 +15,7 @@ extern void pxa168_clear_keypad_wakeup(void);
  #include
  #include
  #include
+#include

  extern struct pxa_device_desc pxa168_device_uart1;
  extern struct pxa_device_desc pxa168_device_uart2;
@@ -34,6 +35,10 @@ extern struct pxa_device_desc pxa168_device_nand;
  extern struct pxa_device_desc pxa168_device_fb;
  extern struct pxa_device_desc pxa168_device_keypad;
  extern struct pxa_device_desc pxa168_device_eth;
+extern struct pxa_device_desc pxa168_device_sdh1;
+extern struct pxa_device_desc pxa168_device_sdh2;
+extern struct pxa_device_desc pxa168_device_sdh3;
+extern struct pxa_device_desc pxa168_device_sdh4;

  struct pxa168_usb_pdata {
/* If NULL, default phy init routine for PXA168 would be called */
@@ -132,4 +137,19 @@ static inline int pxa168_add_eth(struct 
pxa168_eth_platform_data *data)
  {
return pxa_register_device(&pxa168_device_eth, data, sizeof(*data));
  }
+
+static inline int pxa168_add_sdh(int id, struct sdhci_pxa_platdata *data)
+{
+   struct pxa_device_desc *d = NULL;
+
+   switch (id) {
+   case 1: d =&pxa168_device_sdh1; break;
+   case 2: d =&pxa168_device_sdh2; break;
+   case 3: d =&pxa168_device_sdh3; break;
+   case 4: d =&pxa168_device_sdh4; break;
+   default:
+   return -EINVAL;
+   }
+   return pxa_register_device(d, data, sizeof(*data));
+}
  #endif /* __ASM_MACH_PXA168_H */
diff --git a/arch/arm/mach-mmp/include/mach/regs-apmu.h 
b/arch/arm/mach-mmp/include/mach/regs-apmu.h
index 8447ac6..a84de77 100644
--- a/arch/arm/mach-mmp/include/mach/regs-apmu.h
+++ b/arch/arm/mach-mmp/include/mach/regs-apmu.h
@@ -17,27 +17,29 @@
  #define APMU_REG(x)(APMU_VIRT_BASE + (x))

  /* Clock Reset Control */
-#define APMU_IRE   APMU_REG(0x048)
-#define APMU_LCD   APMU_REG(0x04c)
-#define APMU_CCIC  APMU_REG(0x050)
-#define APMU_SDH0  APMU_REG(0x054)
-#define APMU_SDH1  APMU_REG(0x058)
-#define APMU_USB   APMU_REG(0x05c)
-#define APMU_NAND  APMU_REG(0x060)
-#define APMU_DMA   APMU_REG(0x064)
-#define APMU_GEU   APMU_REG(0x068)
-#define APMU_BUS   APMU_REG(0x06c)
-#define APMU_SDH2  APMU_REG(0x0e8)
-#define APMU_SDH3  APMU_REG(0x0ec)
-#define APMU_ETH   APMU_REG(0x0fc)
-
-#define APMU_FNCLK_EN  (1<<  4)
-#define APMU_AXICLK_EN (1<<  3)
-#define APMU_FNRST_DIS (1<<  1)
-#define APMU_AXIRST_DIS(1<<  0)
+#define APMU_IRE   APMU_REG(0x048)
+#define APMU_LCD   APMU_REG(0x04c)
+#define APMU_CCIC  APMU_REG(0x050)
+#define APMU_SDH0  APMU_REG(0x054)
+#define APMU_SDH1  APMU_REG(0x058)
+#define APMU_USB   APMU_REG(0x05c)
+#define APMU_NAND  APMU_REG(0x060)
+#define APMU_DMA   APMU_REG(0x064)
+#define APMU_GEU   APMU_REG(0x068)
+#define APMU_BUS   APMU_REG(0x06c)
+#define APMU_PXA168_SDH2   APMU_REG(0x0e0)
+#define APMU_PXA168_SDH3   APMU_REG(0x0e4)
+#define APMU_SDH2  APMU_REG(0x0e8)
+#define APMU_SDH3  APMU_REG(0x0ec)
+#define APMU_ETH   APMU_REG(0x0fc)

Since you only append APMU_PXA168_SDH2&  APMU_PXA168_SDH3, you'd
better not touch other registers.
If you want to clean the code, you can submit another patch to handle it.



Ok.

-- Tanmay


+
+#define APMU_FNCLK_EN  (1<<  4)
+#define APMU_AXICLK_EN (1<<  3)
+#define APMU_FNRST_DIS (1<<  1)
+#define APMU_AXIRST_DIS(1<<  0)

  /* Wake Clear Register */
-#define APMU_WAKE_CLR  APMU_REG(0x07c)
+#define APMU_WAKE_CLR  APMU_REG(0x07c)

  #define APMU_PXA168_KP_WAKE_CLR(1<<  7)
  #define APMU_PXA168_CFI_WAKE_CLR   (1<<  6)
diff --git a/ar

Re: [PATCH v4 2/4] ARM: pxa168: Add SDHCI support

2011-12-20 Thread Tanmay Upadhyay



On Tuesday 20 December 2011 06:55 PM, Haojian Zhuang wrote:

On Tue, Dec 20, 2011 at 9:13 PM, Tanmay Upadhyay
  wrote:

v2 - clock register for SDHCI are not common across all MMP SoCs.
 So, move PXA168 implementation to pxa168.c

v3 - sdhci-pxav1 driver code is merged with sdhci-pxav2. So, change
 the device name accordingly
   - start sdhci device numbering from 1 as other PXA168 devices
 does that

v4 - Use different names for SD clock registers for PXA168 instead
 of redefining them in pxa168.c. Suggested by Haojian Zhuang

Signed-off-by: Tanmay Upadhyay
Reviewed-by: Philip Rakity
---
  arch/arm/mach-mmp/include/mach/pxa168.h|   20 ++
  arch/arm/mach-mmp/include/mach/regs-apmu.h |   40 ++-
  arch/arm/mach-mmp/pxa168.c |   39 +++
  3 files changed, 80 insertions(+), 19 deletions(-)

diff --git a/arch/arm/mach-mmp/include/mach/pxa168.h 
b/arch/arm/mach-mmp/include/mach/pxa168.h
index 7fb568d..a181608 100644
--- a/arch/arm/mach-mmp/include/mach/pxa168.h
+++ b/arch/arm/mach-mmp/include/mach/pxa168.h
@@ -15,6 +15,7 @@ extern void pxa168_clear_keypad_wakeup(void);
  #include
  #include
  #include
+#include

  extern struct pxa_device_desc pxa168_device_uart1;
  extern struct pxa_device_desc pxa168_device_uart2;
@@ -34,6 +35,10 @@ extern struct pxa_device_desc pxa168_device_nand;
  extern struct pxa_device_desc pxa168_device_fb;
  extern struct pxa_device_desc pxa168_device_keypad;
  extern struct pxa_device_desc pxa168_device_eth;
+extern struct pxa_device_desc pxa168_device_sdh1;
+extern struct pxa_device_desc pxa168_device_sdh2;
+extern struct pxa_device_desc pxa168_device_sdh3;
+extern struct pxa_device_desc pxa168_device_sdh4;

  struct pxa168_usb_pdata {
/* If NULL, default phy init routine for PXA168 would be called */
@@ -132,4 +137,19 @@ static inline int pxa168_add_eth(struct 
pxa168_eth_platform_data *data)
  {
return pxa_register_device(&pxa168_device_eth, data, sizeof(*data));
  }
+
+static inline int pxa168_add_sdh(int id, struct sdhci_pxa_platdata *data)
+{
+   struct pxa_device_desc *d = NULL;
+
+   switch (id) {
+   case 1: d =&pxa168_device_sdh1; break;
+   case 2: d =&pxa168_device_sdh2; break;
+   case 3: d =&pxa168_device_sdh3; break;
+   case 4: d =&pxa168_device_sdh4; break;
+   default:
+   return -EINVAL;
+   }
+   return pxa_register_device(d, data, sizeof(*data));
+}
  #endif /* __ASM_MACH_PXA168_H */
diff --git a/arch/arm/mach-mmp/include/mach/regs-apmu.h 
b/arch/arm/mach-mmp/include/mach/regs-apmu.h
index 8447ac6..a84de77 100644
--- a/arch/arm/mach-mmp/include/mach/regs-apmu.h
+++ b/arch/arm/mach-mmp/include/mach/regs-apmu.h
@@ -17,27 +17,29 @@
  #define APMU_REG(x)(APMU_VIRT_BASE + (x))

  /* Clock Reset Control */
-#define APMU_IRE   APMU_REG(0x048)
-#define APMU_LCD   APMU_REG(0x04c)
-#define APMU_CCIC  APMU_REG(0x050)
-#define APMU_SDH0  APMU_REG(0x054)
-#define APMU_SDH1  APMU_REG(0x058)
-#define APMU_USB   APMU_REG(0x05c)
-#define APMU_NAND  APMU_REG(0x060)
-#define APMU_DMA   APMU_REG(0x064)
-#define APMU_GEU   APMU_REG(0x068)
-#define APMU_BUS   APMU_REG(0x06c)
-#define APMU_SDH2  APMU_REG(0x0e8)
-#define APMU_SDH3  APMU_REG(0x0ec)
-#define APMU_ETH   APMU_REG(0x0fc)
-
-#define APMU_FNCLK_EN  (1<<  4)
-#define APMU_AXICLK_EN (1<<  3)
-#define APMU_FNRST_DIS (1<<  1)
-#define APMU_AXIRST_DIS(1<<  0)
+#define APMU_IRE   APMU_REG(0x048)
+#define APMU_LCD   APMU_REG(0x04c)
+#define APMU_CCIC  APMU_REG(0x050)
+#define APMU_SDH0  APMU_REG(0x054)
+#define APMU_SDH1  APMU_REG(0x058)
+#define APMU_USB   APMU_REG(0x05c)
+#define APMU_NAND  APMU_REG(0x060)
+#define APMU_DMA   APMU_REG(0x064)
+#define APMU_GEU   APMU_REG(0x068)
+#define APMU_BUS   APMU_REG(0x06c)
+#define APMU_PXA168_SDH2   APMU_REG(0x0e0)
+#define APMU_PXA168_SDH3   APMU_REG(0x0e4)
+#define APMU_SDH2  APMU_REG(0x0e8)
+#define APMU_SDH3  APMU_REG(0x0ec)
+#define APMU_ETH   APMU_REG(0x0fc)
+
+#define APMU_FNCLK_EN  (1<<  4)
+#define APMU_AXICLK_EN (1<<  3)
+#define APMU_FNRST_DIS (1<<  1)
+#define APMU_AXIRST_DIS(1<<  0)

  /* Wake Clear Register */
-#define APMU_WAKE_CLR  APMU_REG(0x07c)
+#define APMU_WAKE_CLR  APMU_REG(0x07c)

  #define APMU_PXA168_KP_WAKE_CLR(1<<  7)
  #define APMU_PXA168_CFI_WAKE_CLR   (1<<  6)
diff --git a/arch/arm/mach-mmp/pxa168.c b/arch/arm/mach-mmp/pxa168.c
index 76ca15c..023659b 100644
--- a/arch/arm/mach-mmp/pxa168.c
+++ b/arch/arm/mach-mmp/pxa168.c
@@ -65,6 +65,32 @@ void __init pxa168_init_irq(void)
pxa168_init_gpio();
  }

+static void sd

[PATCH v4 2/4] ARM: pxa168: Add SDHCI support

2011-12-20 Thread Tanmay Upadhyay
v2 - clock register for SDHCI are not common across all MMP SoCs.
 So, move PXA168 implementation to pxa168.c

v3 - sdhci-pxav1 driver code is merged with sdhci-pxav2. So, change
 the device name accordingly
   - start sdhci device numbering from 1 as other PXA168 devices
 does that

v4 - Use different names for SD clock registers for PXA168 instead
 of redefining them in pxa168.c. Suggested by Haojian Zhuang

Signed-off-by: Tanmay Upadhyay 
Reviewed-by: Philip Rakity 
---
 arch/arm/mach-mmp/include/mach/pxa168.h|   20 ++
 arch/arm/mach-mmp/include/mach/regs-apmu.h |   40 ++-
 arch/arm/mach-mmp/pxa168.c |   39 +++
 3 files changed, 80 insertions(+), 19 deletions(-)

diff --git a/arch/arm/mach-mmp/include/mach/pxa168.h 
b/arch/arm/mach-mmp/include/mach/pxa168.h
index 7fb568d..a181608 100644
--- a/arch/arm/mach-mmp/include/mach/pxa168.h
+++ b/arch/arm/mach-mmp/include/mach/pxa168.h
@@ -15,6 +15,7 @@ extern void pxa168_clear_keypad_wakeup(void);
 #include 
 #include 
 #include 
+#include 
 
 extern struct pxa_device_desc pxa168_device_uart1;
 extern struct pxa_device_desc pxa168_device_uart2;
@@ -34,6 +35,10 @@ extern struct pxa_device_desc pxa168_device_nand;
 extern struct pxa_device_desc pxa168_device_fb;
 extern struct pxa_device_desc pxa168_device_keypad;
 extern struct pxa_device_desc pxa168_device_eth;
+extern struct pxa_device_desc pxa168_device_sdh1;
+extern struct pxa_device_desc pxa168_device_sdh2;
+extern struct pxa_device_desc pxa168_device_sdh3;
+extern struct pxa_device_desc pxa168_device_sdh4;
 
 struct pxa168_usb_pdata {
/* If NULL, default phy init routine for PXA168 would be called */
@@ -132,4 +137,19 @@ static inline int pxa168_add_eth(struct 
pxa168_eth_platform_data *data)
 {
return pxa_register_device(&pxa168_device_eth, data, sizeof(*data));
 }
+
+static inline int pxa168_add_sdh(int id, struct sdhci_pxa_platdata *data)
+{
+   struct pxa_device_desc *d = NULL;
+
+   switch (id) {
+   case 1: d = &pxa168_device_sdh1; break;
+   case 2: d = &pxa168_device_sdh2; break;
+   case 3: d = &pxa168_device_sdh3; break;
+   case 4: d = &pxa168_device_sdh4; break;
+   default:
+   return -EINVAL;
+   }
+   return pxa_register_device(d, data, sizeof(*data));
+}
 #endif /* __ASM_MACH_PXA168_H */
diff --git a/arch/arm/mach-mmp/include/mach/regs-apmu.h 
b/arch/arm/mach-mmp/include/mach/regs-apmu.h
index 8447ac6..a84de77 100644
--- a/arch/arm/mach-mmp/include/mach/regs-apmu.h
+++ b/arch/arm/mach-mmp/include/mach/regs-apmu.h
@@ -17,27 +17,29 @@
 #define APMU_REG(x)(APMU_VIRT_BASE + (x))
 
 /* Clock Reset Control */
-#define APMU_IRE   APMU_REG(0x048)
-#define APMU_LCD   APMU_REG(0x04c)
-#define APMU_CCIC  APMU_REG(0x050)
-#define APMU_SDH0  APMU_REG(0x054)
-#define APMU_SDH1  APMU_REG(0x058)
-#define APMU_USB   APMU_REG(0x05c)
-#define APMU_NAND  APMU_REG(0x060)
-#define APMU_DMA   APMU_REG(0x064)
-#define APMU_GEU   APMU_REG(0x068)
-#define APMU_BUS   APMU_REG(0x06c)
-#define APMU_SDH2  APMU_REG(0x0e8)
-#define APMU_SDH3  APMU_REG(0x0ec)
-#define APMU_ETH   APMU_REG(0x0fc)
-
-#define APMU_FNCLK_EN  (1 << 4)
-#define APMU_AXICLK_EN (1 << 3)
-#define APMU_FNRST_DIS (1 << 1)
-#define APMU_AXIRST_DIS(1 << 0)
+#define APMU_IRE   APMU_REG(0x048)
+#define APMU_LCD   APMU_REG(0x04c)
+#define APMU_CCIC  APMU_REG(0x050)
+#define APMU_SDH0  APMU_REG(0x054)
+#define APMU_SDH1  APMU_REG(0x058)
+#define APMU_USB   APMU_REG(0x05c)
+#define APMU_NAND  APMU_REG(0x060)
+#define APMU_DMA   APMU_REG(0x064)
+#define APMU_GEU   APMU_REG(0x068)
+#define APMU_BUS   APMU_REG(0x06c)
+#define APMU_PXA168_SDH2   APMU_REG(0x0e0)
+#define APMU_PXA168_SDH3   APMU_REG(0x0e4)
+#define APMU_SDH2  APMU_REG(0x0e8)
+#define APMU_SDH3  APMU_REG(0x0ec)
+#define APMU_ETH   APMU_REG(0x0fc)
+
+#define APMU_FNCLK_EN  (1 << 4)
+#define APMU_AXICLK_EN (1 << 3)
+#define APMU_FNRST_DIS (1 << 1)
+#define APMU_AXIRST_DIS(1 << 0)
 
 /* Wake Clear Register */
-#define APMU_WAKE_CLR  APMU_REG(0x07c)
+#define APMU_WAKE_CLR  APMU_REG(0x07c)
 
 #define APMU_PXA168_KP_WAKE_CLR(1 << 7)
 #define APMU_PXA168_CFI_WAKE_CLR   (1 << 6)
diff --git a/arch/arm/mach-mmp/pxa168.c b/arch/arm/mach-mmp/pxa168.c
index 76ca15c..023659b 100644
--- a/arch/arm/mach-mmp/pxa168.c
+++ b/arch/arm/mach-mmp/pxa168.c
@@ -65,6 +65,32 @@ void __init pxa168_init_irq(void)
pxa168_init_gpio();
 }
 
+static void sdh_clk_enable(struct clk *clk)
+{
+   void __iomem *reg_offset = clk->clk_rst;
+
+   /* Can't see any clean way to do t

Re: [PATCH v3 2/4] ARM: pxa168: Add SDHCI support

2011-12-18 Thread Tanmay Upadhyay



On Monday 19 December 2011 10:32 AM, Haojian Zhuang wrote:

On Mon, Dec 19, 2011 at 12:55 PM, Tanmay Upadhyay
  wrote:


On Monday 19 December 2011 10:15 AM, Haojian Zhuang wrote:

On Fri, Dec 16, 2011 at 7:15 AM, Chris Ballwrote:

Hi Eric and Jason,

On Thu, Dec 01 2011, Chris Ball wrote:

Hi Eric, Jason,

Please could you ACK this patch if you agree with it, and I'll take it
and the rest of the series via the MMC tree?  Thanks.

Ping?

Thanks,

- Chris.


NACK.


+/* Offset defined in arch/arm/mach-mmp/include/mach/regs-apmu.h are
for MMP2
+ * PXA168 has different offset */
+#undef APMU_SDH2
+#undef APMU_SDH3
+
+#define APMU_SDH2   APMU_REG(0xe0)
+#define APMU_SDH3   APMU_REG(0xe4)
+

Please don't use #undef at here. If the register setting is different,
I prefer to use two different clk operations.


Sorry I couldn't get you. Could you please elaborate? Here regs-apmu.h
defines clock register offsets. They are correct for MMP2, but not for
PXA168. So I thought to correct them in a PXA168 specific file. Could you
please point me a better way?

Thanks,

Tanmay

APMU_PXA168_SDH2
APMU_MMP2_SDH2

I think this is better.



Thanks for the suggestion. This looks a better option. However, I would 
like add here that not only the register offset, but also the register 
bits are different for MMP2 & PXA168. So, the code that would control 
SD/MMC clock will be architecture specific & hence in different 
architecture specific files. Hope this solution looks good to all of you 
in that case as well.


Thanks,

Tanmay
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" 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 2/4] ARM: pxa168: Add SDHCI support

2011-12-18 Thread Tanmay Upadhyay



On Monday 19 December 2011 10:15 AM, Haojian Zhuang wrote:

On Fri, Dec 16, 2011 at 7:15 AM, Chris Ball  wrote:

Hi Eric and Jason,

On Thu, Dec 01 2011, Chris Ball wrote:

Hi Eric, Jason,

Please could you ACK this patch if you agree with it, and I'll take it
and the rest of the series via the MMC tree?  Thanks.

Ping?

Thanks,

- Chris.


NACK.


+/* Offset defined in arch/arm/mach-mmp/include/mach/regs-apmu.h are for MMP2
+ * PXA168 has different offset */
+#undef APMU_SDH2
+#undef APMU_SDH3
+
+#define APMU_SDH2   APMU_REG(0xe0)
+#define APMU_SDH3   APMU_REG(0xe4)
+

Please don't use #undef at here. If the register setting is different,
I prefer to use two different clk operations.



Sorry I couldn't get you. Could you please elaborate? Here regs-apmu.h 
defines clock register offsets. They are correct for MMP2, but not for 
PXA168. So I thought to correct them in a PXA168 specific file. Could 
you please point me a better way?


Thanks,

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


[PATCH v2 4/4] ARM: pxa168/gplugd: Add support for SD port 1

2011-11-20 Thread Tanmay Upadhyay
v2 - after sdhci-pxav1 driver is merged with sdhci-pxav2, pass
 pxav1_controller = 1
   - as sdhci device numbering now starts from 1, call
 pxa168_add_sdh accordingly

Signed-off-by: Tanmay Upadhyay 
Reviewed-by: Philip Rakity 
---
 arch/arm/mach-mmp/gplugd.c |6 ++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-mmp/gplugd.c b/arch/arm/mach-mmp/gplugd.c
index 6915656..d7947e7 100644
--- a/arch/arm/mach-mmp/gplugd.c
+++ b/arch/arm/mach-mmp/gplugd.c
@@ -154,6 +154,11 @@ struct pxa168_eth_platform_data gplugd_eth_platform_data = 
{
.init= gplugd_eth_init,
 };
 
+struct sdhci_pxa_platdata gplugd_sdh_platdata = {
+   .delay_in_ms = 5,
+   .pxav1_controller = 1,
+};
+
 static void __init select_disp_freq(void)
 {
/* set GPIO 35 & clear GPIO 85 to set LCD External Clock to 74.25 MHz */
@@ -186,6 +191,7 @@ static void __init gplugd_init(void)
pxa168_add_twsi(0, NULL, ARRAY_AND_SIZE(gplugd_i2c_board_info));
 
pxa168_add_eth(&gplugd_eth_platform_data);
+   pxa168_add_sdh(1, &gplugd_sdh_platdata);
 }
 
 MACHINE_START(GPLUGD, "PXA168-based GuruPlug Display (gplugD) Platform")
-- 
1.7.0.4

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


[PATCH v2 3/4] mmc: sdhci-pxa: Add SDHCI driver for PXA16x

2011-11-20 Thread Tanmay Upadhyay
PXA16x devices uses SDHCI controller v1. As it's not much different
than v2 controller, v1 driver is merged with sdhci-pxav2 driver

v2 - instead of having separate file sdhci-pxav1, merge code with
 sdhci-pxav2 driver code as suggested by Chris Ball

Signed-off-by: Philip Rakity 
Signed-off-by: Tanmay Upadhyay 
---
 drivers/mmc/host/Kconfig|7 ---
 drivers/mmc/host/sdhci-pxav2.c  |   30 +-
 drivers/mmc/host/sdhci.c|3 +++
 drivers/mmc/host/sdhci.h|1 +
 include/linux/platform_data/pxa_sdhci.h |2 ++
 5 files changed, 39 insertions(+), 4 deletions(-)

diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 21b4149..77541f5 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -195,14 +195,15 @@ config MMC_SDHCI_PXAV3
  If unsure, say N.
 
 config MMC_SDHCI_PXAV2
-   tristate "Marvell PXA9XX SD Host Controller support (PXAV2)"
+   tristate "Marvell PXA16X/PXA9XX SD Host Controller support (PXAV1/V2)"
depends on CLKDEV_LOOKUP
select MMC_SDHCI
select MMC_SDHCI_PLTFM
default y if CPU_PXA910
+   default y if CPU_PXA168
help
- This selects the Marvell(R) PXAV2 SD Host Controller.
- If you have a PXA9XX platform with SD Host Controller
+ This selects the Marvell(R) PXAV1/V2 SD Host Controller.
+ If you have a PXA16X or PXA9XX platform with SD Host Controller
  and a card slot, say Y or M here.
 
  If unsure, say N.
diff --git a/drivers/mmc/host/sdhci-pxav2.c b/drivers/mmc/host/sdhci-pxav2.c
index d4bf6d3..633cc77 100644
--- a/drivers/mmc/host/sdhci-pxav2.c
+++ b/drivers/mmc/host/sdhci-pxav2.c
@@ -28,6 +28,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "sdhci.h"
 #include "sdhci-pltfm.h"
 
@@ -72,7 +73,13 @@ static void pxav2_set_private_registers(struct sdhci_host 
*host, u8 mask)
writew(tmp, host->ioaddr + SD_CLOCK_BURST_SIZE_SETUP);
}
 
-   if (pdata && (pdata->flags & PXA_FLAG_ENABLE_CLOCK_GATING)) {
+   if (pdata && pdata->pxav1_controller) {
+   /* no clock gating */
+   tmp = readw(host->ioaddr + SD_FIFO_PARAM);
+   tmp |= DIS_PAD_SD_CLK_GATE;
+   writew(tmp, host->ioaddr + SD_FIFO_PARAM);
+   } else if (pdata && (pdata->flags
+   & PXA_FLAG_ENABLE_CLOCK_GATING)) {
tmp = readw(host->ioaddr + SD_FIFO_PARAM);
tmp &= ~CLK_GATE_SETTING_BITS;
writew(tmp, host->ioaddr + SD_FIFO_PARAM);
@@ -115,6 +122,20 @@ static u32 pxav2_get_max_clock(struct sdhci_host *host)
return clk_get_rate(pltfm_host->clk);
 }
 
+/*
+ * we cannot talk to controller for 8 bus cycles according to sdio spec
+ * at lowest speed this is 100,000 HZ per cycle or 800,000 cycles
+ * which is quite a LONG TIME on a fast cpu -- so delay if needed
+ */
+static void platform_specific_completion(struct sdhci_host *host)
+{
+   struct platform_device *pdev = to_platform_device(mmc_dev(host->mmc));
+   struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data;
+
+   if (host->clock < 320 && pdata && pdata->delay_in_ms)
+   mdelay(pdata->delay_in_ms);
+}
+
 static struct sdhci_ops pxav2_sdhci_ops = {
.get_max_clock = pxav2_get_max_clock,
.platform_reset_exit = pxav2_set_private_registers,
@@ -167,6 +188,13 @@ static int __devinit sdhci_pxav2_probe(struct 
platform_device *pdev)
if (pdata->flags & PXA_FLAG_SD_8_BIT_CAPABLE_SLOT)
host->mmc->caps |= MMC_CAP_8_BIT_DATA;
 
+   if (pdata->pxav1_controller) {
+   host->quirks |= SDHCI_QUIRK_NO_BUSY_IRQ
+   | SDHCI_QUIRK_32BIT_DMA_SIZE;
+   pxav2_sdhci_ops.platform_specific_completion
+   = platform_specific_completion;
+   }
+
if (pdata->quirks)
host->quirks |= pdata->quirks;
if (pdata->host_caps)
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 6d8eea3..c6b52b8 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -983,6 +983,9 @@ static void sdhci_send_command(struct sdhci_host *host, 
struct mmc_command *cmd)
mdelay(1);
}
 
+   if (host->ops->platform_specific_completion)
+   host->ops->platform_specific_completion(host);
+
mod_timer(&host->timer, jiffies + 10 * HZ);
 
host->cmd = cmd;
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.

[PATCH v3 2/4] ARM: pxa168: Add SDHCI support

2011-11-20 Thread Tanmay Upadhyay
v2 - clock register for SDHCI are not common across all MMP SoCs.
 So, move PXA168 implementation to pxa168.c

v3 - sdhci-pxav1 driver code is merged with sdhci-pxav2. So, change
 the device name accordingly
   - start sdhci device numbering from 1 as other PXA168 devices
 does that

Signed-off-by: Tanmay Upadhyay 
Reviewed-by: Philip Rakity 
---
 arch/arm/mach-mmp/include/mach/pxa168.h |   20 +
 arch/arm/mach-mmp/pxa168.c  |   46 +++
 2 files changed, 66 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-mmp/include/mach/pxa168.h 
b/arch/arm/mach-mmp/include/mach/pxa168.h
index 7fb568d..a181608 100644
--- a/arch/arm/mach-mmp/include/mach/pxa168.h
+++ b/arch/arm/mach-mmp/include/mach/pxa168.h
@@ -15,6 +15,7 @@ extern void pxa168_clear_keypad_wakeup(void);
 #include 
 #include 
 #include 
+#include 
 
 extern struct pxa_device_desc pxa168_device_uart1;
 extern struct pxa_device_desc pxa168_device_uart2;
@@ -34,6 +35,10 @@ extern struct pxa_device_desc pxa168_device_nand;
 extern struct pxa_device_desc pxa168_device_fb;
 extern struct pxa_device_desc pxa168_device_keypad;
 extern struct pxa_device_desc pxa168_device_eth;
+extern struct pxa_device_desc pxa168_device_sdh1;
+extern struct pxa_device_desc pxa168_device_sdh2;
+extern struct pxa_device_desc pxa168_device_sdh3;
+extern struct pxa_device_desc pxa168_device_sdh4;
 
 struct pxa168_usb_pdata {
/* If NULL, default phy init routine for PXA168 would be called */
@@ -132,4 +137,19 @@ static inline int pxa168_add_eth(struct 
pxa168_eth_platform_data *data)
 {
return pxa_register_device(&pxa168_device_eth, data, sizeof(*data));
 }
+
+static inline int pxa168_add_sdh(int id, struct sdhci_pxa_platdata *data)
+{
+   struct pxa_device_desc *d = NULL;
+
+   switch (id) {
+   case 1: d = &pxa168_device_sdh1; break;
+   case 2: d = &pxa168_device_sdh2; break;
+   case 3: d = &pxa168_device_sdh3; break;
+   case 4: d = &pxa168_device_sdh4; break;
+   default:
+   return -EINVAL;
+   }
+   return pxa_register_device(d, data, sizeof(*data));
+}
 #endif /* __ASM_MACH_PXA168_H */
diff --git a/arch/arm/mach-mmp/pxa168.c b/arch/arm/mach-mmp/pxa168.c
index 76ca15c..102f65f 100644
--- a/arch/arm/mach-mmp/pxa168.c
+++ b/arch/arm/mach-mmp/pxa168.c
@@ -45,6 +45,14 @@ static struct mfp_addr_map pxa168_mfp_addr_map[] __initdata =
 
 #define APMASK(i)  (GPIO_REGS_VIRT + BANK_OFF(i) + 0x09c)
 
+/* Offset defined in arch/arm/mach-mmp/include/mach/regs-apmu.h are for MMP2
+ * PXA168 has different offset */
+#undef APMU_SDH2
+#undef APMU_SDH3
+
+#define APMU_SDH2  APMU_REG(0xe0)
+#define APMU_SDH3  APMU_REG(0xe4)
+
 static void __init pxa168_init_gpio(void)
 {
int i;
@@ -65,6 +73,31 @@ void __init pxa168_init_irq(void)
pxa168_init_gpio();
 }
 
+static void sdh_clk_enable(struct clk *clk)
+{
+   void __iomem *clk_reg_offset = clk->clk_rst;
+
+   /* Can't see any clean way to do this: Bits 3 & 0 in registers
+* for host 0 & 2 should be set for host 1 & 3 also */
+   if (clk_reg_offset == APMU_SDH0 || clk_reg_offset == APMU_SDH1)
+   __raw_writel(__raw_readl(APMU_SDH0) | 0x9, APMU_SDH0);
+   if (clk_reg_offset == APMU_SDH2 || clk_reg_offset == APMU_SDH3)
+   __raw_writel(__raw_readl(APMU_SDH2) | 0x9, APMU_SDH2);
+
+   __raw_writel(__raw_readl(clk->clk_rst) | clk->enable_val, clk->clk_rst);
+}
+
+static void sdh_clk_disable(struct clk *clk)
+{
+   __raw_writel(__raw_readl(clk->clk_rst) & ~(clk->enable_val),
+   clk->clk_rst);
+}
+
+struct clkops sdh_clk_ops = {
+   .enable = sdh_clk_enable,
+   .disable= sdh_clk_disable,
+};
+
 /* APB peripheral clocks */
 static APBC_CLK(uart1, PXA168_UART1, 1, 14745600);
 static APBC_CLK(uart2, PXA168_UART2, 1, 14745600);
@@ -87,6 +120,11 @@ static APMU_CLK(lcd, LCD, 0x7f, 31200);
 static APMU_CLK(eth, ETH, 0x09, 0);
 static APMU_CLK(usb, USB, 0x12, 0);
 
+static APMU_CLK_OPS(sdh1, SDH0, 0x12, 4800, &sdh_clk_ops);
+static APMU_CLK_OPS(sdh2, SDH1, 0x12, 4800, &sdh_clk_ops);
+static APMU_CLK_OPS(sdh3, SDH2, 0x12, 4800, &sdh_clk_ops);
+static APMU_CLK_OPS(sdh4, SDH3, 0x12, 4800, &sdh_clk_ops);
+
 /* device and clock bindings */
 static struct clk_lookup pxa168_clkregs[] = {
INIT_CLKREG(&clk_uart1, "pxa2xx-uart.0", NULL),
@@ -108,6 +146,10 @@ static struct clk_lookup pxa168_clkregs[] = {
INIT_CLKREG(&clk_keypad, "pxa27x-keypad", NULL),
INIT_CLKREG(&clk_eth, "pxa168-eth", "MFUCLK"),
INIT_CLKREG(&clk_usb, "pxa168-ehci", "PXA168-USBCLK"),
+   INIT_CLKREG(&clk_sdh1, NULL, "PXA-SDHCLK"),
+   INIT_CLKREG(&clk_sdh2, NULL, "PXA-SDHCLK"),
+   INIT_CLKREG(&cl

[PATCH 1/4] mmc: sdhci-pxa: Trivial fix in Kconfig

2011-11-20 Thread Tanmay Upadhyay
Select MMC_SDHCI_PXAV3 by default if CPU is MMP2
Select MMC_SDHCI_PXAV2 by default if CPU is PXA910

Signed-off-by: Tanmay Upadhyay 
Reviewed-by: Philip Rakity 
---
 drivers/mmc/host/Kconfig |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index cf444b0..21b4149 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -186,7 +186,7 @@ config MMC_SDHCI_PXAV3
depends on CLKDEV_LOOKUP
select MMC_SDHCI
select MMC_SDHCI_PLTFM
-   default CPU_MMP2
+   default y if CPU_MMP2
help
  This selects the Marvell(R) PXAV3 SD Host Controller.
  If you have a MMP2 platform with SD Host Controller
@@ -199,7 +199,7 @@ config MMC_SDHCI_PXAV2
depends on CLKDEV_LOOKUP
select MMC_SDHCI
select MMC_SDHCI_PLTFM
-   default CPU_PXA910
+   default y if CPU_PXA910
help
  This selects the Marvell(R) PXAV2 SD Host Controller.
  If you have a PXA9XX platform with SD Host Controller
-- 
1.7.0.4

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


[PATCH v2 1/3] ARM: pxa168: Add SDHCI support

2011-11-04 Thread Tanmay Upadhyay
v2 - clock register for SDHCI are not common across all MMP SoCs.
So, move PXA168 implementation to pxa168.c

Signed-off-by: Tanmay Upadhyay 
---
 arch/arm/mach-mmp/clock.c   |1 +
 arch/arm/mach-mmp/clock.h   |1 +
 arch/arm/mach-mmp/include/mach/pxa168.h |   20 +
 arch/arm/mach-mmp/pxa168.c  |   46 +++
 4 files changed, 68 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-mmp/clock.c b/arch/arm/mach-mmp/clock.c
index 7c6f95f..eefefea 100644
--- a/arch/arm/mach-mmp/clock.c
+++ b/arch/arm/mach-mmp/clock.c
@@ -14,6 +14,7 @@
 #include 
 
 #include 
+#include 
 #include "clock.h"
 
 static void apbc_clk_enable(struct clk *clk)
diff --git a/arch/arm/mach-mmp/clock.h b/arch/arm/mach-mmp/clock.h
index 3143e99..1243e4d 100644
--- a/arch/arm/mach-mmp/clock.h
+++ b/arch/arm/mach-mmp/clock.h
@@ -27,6 +27,7 @@ struct clk {
 
 extern struct clkops apbc_clk_ops;
 extern struct clkops apmu_clk_ops;
+extern struct clkops sdh_clk_ops;
 
 #define APBC_CLK(_name, _reg, _fnclksel, _rate)\
 struct clk clk_##_name = { \
diff --git a/arch/arm/mach-mmp/include/mach/pxa168.h 
b/arch/arm/mach-mmp/include/mach/pxa168.h
index 7f00584..390a550 100644
--- a/arch/arm/mach-mmp/include/mach/pxa168.h
+++ b/arch/arm/mach-mmp/include/mach/pxa168.h
@@ -15,6 +15,7 @@ extern void pxa168_clear_keypad_wakeup(void);
 #include 
 #include 
 #include 
+#include 
 
 extern struct pxa_device_desc pxa168_device_uart1;
 extern struct pxa_device_desc pxa168_device_uart2;
@@ -34,6 +35,10 @@ extern struct pxa_device_desc pxa168_device_nand;
 extern struct pxa_device_desc pxa168_device_fb;
 extern struct pxa_device_desc pxa168_device_keypad;
 extern struct pxa_device_desc pxa168_device_eth;
+extern struct pxa_device_desc pxa168_device_sdh0;
+extern struct pxa_device_desc pxa168_device_sdh1;
+extern struct pxa_device_desc pxa168_device_sdh2;
+extern struct pxa_device_desc pxa168_device_sdh3;
 
 static inline int pxa168_add_uart(int id)
 {
@@ -125,4 +130,19 @@ static inline int pxa168_add_eth(struct 
pxa168_eth_platform_data *data)
 {
return pxa_register_device(&pxa168_device_eth, data, sizeof(*data));
 }
+
+static inline int pxa168_add_sdh(int id, struct sdhci_pxa_platdata *data)
+{
+   struct pxa_device_desc *d = NULL;
+
+   switch (id) {
+   case 0: d = &pxa168_device_sdh0; break;
+   case 1: d = &pxa168_device_sdh1; break;
+   case 2: d = &pxa168_device_sdh2; break;
+   case 3: d = &pxa168_device_sdh3; break;
+   default:
+   return -EINVAL;
+   }
+   return pxa_register_device(d, data, sizeof(*data));
+}
 #endif /* __ASM_MACH_PXA168_H */
diff --git a/arch/arm/mach-mmp/pxa168.c b/arch/arm/mach-mmp/pxa168.c
index 0156f53..868605d 100644
--- a/arch/arm/mach-mmp/pxa168.c
+++ b/arch/arm/mach-mmp/pxa168.c
@@ -43,6 +43,14 @@ static struct mfp_addr_map pxa168_mfp_addr_map[] __initdata =
 
 #define APMASK(i)  (GPIO_REGS_VIRT + BANK_OFF(i) + 0x09c)
 
+/* Offset defined in arch/arm/mach-mmp/include/mach/regs-apmu.h are for MMP2
+ * PXA168 has different offset */
+#undef APMU_SDH2
+#undef APMU_SDH3
+
+#define APMU_SDH2  APMU_REG(0xe0)
+#define APMU_SDH3  APMU_REG(0xe4)
+
 static void __init pxa168_init_gpio(void)
 {
int i;
@@ -63,6 +71,31 @@ void __init pxa168_init_irq(void)
pxa168_init_gpio();
 }
 
+static void sdh_clk_enable(struct clk *clk)
+{
+   unsigned long clk_reg_offset = (unsigned long) clk->clk_rst;
+
+   /* Can't see any clean way to do this: Bits 3 & 0 in registers
+* for host 0 & 2 should be set for host 1 & 3 also */
+   if (clk_reg_offset == APMU_SDH0 || clk_reg_offset == APMU_SDH1)
+   __raw_writel(__raw_readl(APMU_SDH0) | 0x9, APMU_SDH0);
+   if (clk_reg_offset == APMU_SDH2 || clk_reg_offset == APMU_SDH3)
+   __raw_writel(__raw_readl(APMU_SDH2) | 0x9, APMU_SDH2);
+
+   __raw_writel(__raw_readl(clk->clk_rst) | clk->enable_val, clk->clk_rst);
+}
+
+static void sdh_clk_disable(struct clk *clk)
+{
+   __raw_writel(__raw_readl(clk->clk_rst) & ~(clk->enable_val),
+   clk->clk_rst);
+}
+
+struct clkops sdh_clk_ops = {
+   .enable = sdh_clk_enable,
+   .disable= sdh_clk_disable,
+};
+
 /* APB peripheral clocks */
 static APBC_CLK(uart1, PXA168_UART1, 1, 14745600);
 static APBC_CLK(uart2, PXA168_UART2, 1, 14745600);
@@ -84,6 +117,11 @@ static APMU_CLK(nand, NAND, 0x19b, 15600);
 static APMU_CLK(lcd, LCD, 0x7f, 31200);
 static APMU_CLK(eth, ETH, 0x09, 0);
 
+static APMU_CLK_OPS(sdh0, SDH0, 0x12, 4800, &sdh_clk_ops);
+static APMU_CLK_OPS(sdh1, SDH1, 0x12, 4800, &sdh_clk_ops);
+static APMU_CLK_OPS(sdh2, SDH2, 0x12, 4800, &sdh_clk_ops);
+static APMU_CLK_OPS(sdh3, SDH3, 0x12, 4800, &sdh_clk_ops);
+
 /* device and clock b

[PATCH 2/3] mmc: sdhci-pxa: Add SDHCI driver for PXA16x

2011-10-25 Thread Tanmay Upadhyay
Signed-off-by: Philip Rakity 
Signed-off-by: Tanmay Upadhyay 
---
 drivers/mmc/host/Kconfig|   13 ++
 drivers/mmc/host/Makefile   |1 +
 drivers/mmc/host/sdhci-pxav1.c  |  256 +++
 drivers/mmc/host/sdhci.c|3 +
 drivers/mmc/host/sdhci.h|1 +
 include/linux/platform_data/pxa_sdhci.h |1 +
 6 files changed, 275 insertions(+), 0 deletions(-)
 create mode 100644 drivers/mmc/host/sdhci-pxav1.c

diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 8c87096..9c9b73a 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -207,6 +207,19 @@ config MMC_SDHCI_PXAV2
 
  If unsure, say N.
 
+config MMC_SDHCI_PXAV1
+   tristate "Marvell PXA16X SD Host Controller support (PXAV1)"
+   depends on CLKDEV_LOOKUP
+   select MMC_SDHCI
+   select MMC_SDHCI_PLTFM
+   default CPU_PXA168
+   help
+ This selects the Marvell(R) PXAV1 SD Host Controller.
+ If you have a PXA16X platform with SD Host Controller
+ and a card slot, say Y or M here.
+
+ If unsure, say N.
+
 config MMC_SDHCI_SPEAR
tristate "SDHCI support on ST SPEAr platform"
depends on MMC_SDHCI && PLAT_SPEAR
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index b4b83f3..5094af8 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_MMC_SDHCI)   += sdhci.o
 obj-$(CONFIG_MMC_SDHCI_PCI)+= sdhci-pci.o
 obj-$(CONFIG_MMC_SDHCI_PXAV3)  += sdhci-pxav3.o
 obj-$(CONFIG_MMC_SDHCI_PXAV2)  += sdhci-pxav2.o
+obj-$(CONFIG_MMC_SDHCI_PXAV1)  += sdhci-pxav1.o
 obj-$(CONFIG_MMC_SDHCI_S3C)+= sdhci-s3c.o
 obj-$(CONFIG_MMC_SDHCI_SPEAR)  += sdhci-spear.o
 obj-$(CONFIG_MMC_WBSD) += wbsd.o
diff --git a/drivers/mmc/host/sdhci-pxav1.c b/drivers/mmc/host/sdhci-pxav1.c
new file mode 100644
index 000..a0f6285
--- /dev/null
+++ b/drivers/mmc/host/sdhci-pxav1.c
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2011 Marvell International Ltd.
+ * Zhangfei Gao 
+ * Kevin Wang 
+ * Jun Nie 
+ * Qiming Wu 
+ * Philip Rakity 
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "sdhci.h"
+#include "sdhci-pltfm.h"
+
+#define SD_FIFO_PARAM  0xe0
+#define DIS_PAD_SD_CLK_GATE0x0400 /* Turn on/off Dynamic SD Clock Gating */
+#define CLK_GATE_SETTING_BITS  DIS_PAD_SD_CLK_GATE
+
+#define SD_CLOCK_BURST_SIZE_SETUP  0xe6
+#define SDCLK_SEL_SHIFT8
+#define SDCLK_SEL_MASK 0x3
+#define SDCLK_DELAY_SHIFT  10
+#define SDCLK_DELAY_MASK   0x3c
+
+#define SD_CE_ATA_20xea
+#define MMC_CARD   0x1000
+#define MMC_WIDTH  0x0100
+
+
+static void pxav1_set_private_registers(struct sdhci_host *host, u8 mask)
+{
+   struct platform_device *pdev = to_platform_device(mmc_dev(host->mmc));
+   struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data;
+
+   if (mask == SDHCI_RESET_ALL) {
+   u16 tmp = 0;
+
+   /*
+* tune timing of read data/command when crc error happen
+* no performance impact
+*/
+   if (pdata && pdata->clk_delay_sel) {
+   tmp = readw(host->ioaddr + SD_CLOCK_BURST_SIZE_SETUP);
+
+   tmp &= ~(SDCLK_DELAY_MASK << SDCLK_DELAY_SHIFT);
+   tmp |= (pdata->clk_delay_cycles & SDCLK_DELAY_MASK)
+   << SDCLK_DELAY_SHIFT;
+   tmp &= ~(SDCLK_SEL_MASK << SDCLK_SEL_SHIFT);
+   tmp |= (pdata->clk_delay_sel & SDCLK_SEL_MASK)
+   << SDCLK_SEL_SHIFT;
+
+   writew(tmp, host->ioaddr + SD_CLOCK_BURST_SIZE_SETUP);
+   }
+
+   /* no clock gating */
+   tmp = readw(host->ioaddr + SD_FIFO_PARAM);
+   tmp |= DIS_PAD_SD_CLK_GATE;
+   writew(tmp, host->ioaddr + SD_FIFO_PARAM);
+   }
+}
+
+static int pxav1_mmc_set_width(struct sdhci_host *host, int width)
+{
+   u8 ctrl;
+   u16 tmp;
+
+   ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL);
+   tmp = readw(host->ioaddr + SD_CE_ATA_2);

[PATCH 3/3] ARM: pxa168/gplugd: Add support for SD port 1

2011-10-25 Thread Tanmay Upadhyay
Signed-off-by: Tanmay Upadhyay 
---
 arch/arm/mach-mmp/gplugd.c |7 +++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-mmp/gplugd.c b/arch/arm/mach-mmp/gplugd.c
index 98e25d9..f453561 100644
--- a/arch/arm/mach-mmp/gplugd.c
+++ b/arch/arm/mach-mmp/gplugd.c
@@ -17,6 +17,8 @@
 #include 
 #include 
 
+#include 
+
 #include "common.h"
 
 static unsigned long gplugd_pin_config[] __initdata = {
@@ -154,6 +156,10 @@ struct pxa168_eth_platform_data gplugd_eth_platform_data = 
{
.init= gplugd_eth_init,
 };
 
+struct sdhci_pxa_platdata gplugd_sdh_platdata = {
+   .delay_in_ms = 4,
+};
+
 static void __init select_disp_freq(void)
 {
/* set GPIO 35 & clear GPIO 85 to set LCD External Clock to 74.25 MHz */
@@ -186,6 +192,7 @@ static void __init gplugd_init(void)
pxa168_add_twsi(0, NULL, ARRAY_AND_SIZE(gplugd_i2c_board_info));
 
pxa168_add_eth(&gplugd_eth_platform_data);
+   pxa168_add_sdh(0, &gplugd_sdh_platdata);
 }
 
 MACHINE_START(SHEEVAD, "PXA168-based GuruPlug Display (gplugD) Platform")
-- 
1.6.3.3

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


[PATCH 1/3] ARM: pxa168: Add SDHCI support

2011-10-25 Thread Tanmay Upadhyay
Signed-off-by: Tanmay Upadhyay 
---
 arch/arm/mach-mmp/clock.c   |   26 ++
 arch/arm/mach-mmp/clock.h   |1 +
 arch/arm/mach-mmp/include/mach/pxa168.h |   20 
 arch/arm/mach-mmp/pxa168.c  |   13 +
 4 files changed, 60 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-mmp/clock.c b/arch/arm/mach-mmp/clock.c
index 7c6f95f..6e615cc 100644
--- a/arch/arm/mach-mmp/clock.c
+++ b/arch/arm/mach-mmp/clock.c
@@ -14,6 +14,7 @@
 #include 
 
 #include 
+#include 
 #include "clock.h"
 
 static void apbc_clk_enable(struct clk *clk)
@@ -49,6 +50,31 @@ struct clkops apmu_clk_ops = {
.disable= apmu_clk_disable,
 };
 
+static void sdh_clk_enable(struct clk *clk)
+{
+   unsigned long clk_reg_offset = (unsigned long) clk->clk_rst;
+
+   /* Can't see any clean way to do this: Bits 3 & 0 in registers
+* for host 0 & 2 should be set for host 1 & 3 also */
+   if (clk_reg_offset == APMU_SDH0 || clk_reg_offset == APMU_SDH1)
+   __raw_writel(__raw_readl(APMU_SDH0) | 0x9, APMU_SDH0);
+   if (clk_reg_offset == APMU_SDH2 || clk_reg_offset == APMU_SDH3)
+   __raw_writel(__raw_readl(APMU_SDH2) | 0x9, APMU_SDH2);
+
+   __raw_writel(__raw_readl(clk->clk_rst) | clk->enable_val, clk->clk_rst);
+}
+
+static void sdh_clk_disable(struct clk *clk)
+{
+   __raw_writel(__raw_readl(clk->clk_rst) & ~(clk->enable_val),
+   clk->clk_rst);
+}
+
+struct clkops sdh_clk_ops = {
+   .enable = sdh_clk_enable,
+   .disable= sdh_clk_disable,
+};
+
 static DEFINE_SPINLOCK(clocks_lock);
 
 int clk_enable(struct clk *clk)
diff --git a/arch/arm/mach-mmp/clock.h b/arch/arm/mach-mmp/clock.h
index 3143e99..1243e4d 100644
--- a/arch/arm/mach-mmp/clock.h
+++ b/arch/arm/mach-mmp/clock.h
@@ -27,6 +27,7 @@ struct clk {
 
 extern struct clkops apbc_clk_ops;
 extern struct clkops apmu_clk_ops;
+extern struct clkops sdh_clk_ops;
 
 #define APBC_CLK(_name, _reg, _fnclksel, _rate)\
 struct clk clk_##_name = { \
diff --git a/arch/arm/mach-mmp/include/mach/pxa168.h 
b/arch/arm/mach-mmp/include/mach/pxa168.h
index 7f00584..390a550 100644
--- a/arch/arm/mach-mmp/include/mach/pxa168.h
+++ b/arch/arm/mach-mmp/include/mach/pxa168.h
@@ -15,6 +15,7 @@ extern void pxa168_clear_keypad_wakeup(void);
 #include 
 #include 
 #include 
+#include 
 
 extern struct pxa_device_desc pxa168_device_uart1;
 extern struct pxa_device_desc pxa168_device_uart2;
@@ -34,6 +35,10 @@ extern struct pxa_device_desc pxa168_device_nand;
 extern struct pxa_device_desc pxa168_device_fb;
 extern struct pxa_device_desc pxa168_device_keypad;
 extern struct pxa_device_desc pxa168_device_eth;
+extern struct pxa_device_desc pxa168_device_sdh0;
+extern struct pxa_device_desc pxa168_device_sdh1;
+extern struct pxa_device_desc pxa168_device_sdh2;
+extern struct pxa_device_desc pxa168_device_sdh3;
 
 static inline int pxa168_add_uart(int id)
 {
@@ -125,4 +130,19 @@ static inline int pxa168_add_eth(struct 
pxa168_eth_platform_data *data)
 {
return pxa_register_device(&pxa168_device_eth, data, sizeof(*data));
 }
+
+static inline int pxa168_add_sdh(int id, struct sdhci_pxa_platdata *data)
+{
+   struct pxa_device_desc *d = NULL;
+
+   switch (id) {
+   case 0: d = &pxa168_device_sdh0; break;
+   case 1: d = &pxa168_device_sdh1; break;
+   case 2: d = &pxa168_device_sdh2; break;
+   case 3: d = &pxa168_device_sdh3; break;
+   default:
+   return -EINVAL;
+   }
+   return pxa_register_device(d, data, sizeof(*data));
+}
 #endif /* __ASM_MACH_PXA168_H */
diff --git a/arch/arm/mach-mmp/pxa168.c b/arch/arm/mach-mmp/pxa168.c
index 0156f53..9da21fd 100644
--- a/arch/arm/mach-mmp/pxa168.c
+++ b/arch/arm/mach-mmp/pxa168.c
@@ -84,6 +84,11 @@ static APMU_CLK(nand, NAND, 0x19b, 15600);
 static APMU_CLK(lcd, LCD, 0x7f, 31200);
 static APMU_CLK(eth, ETH, 0x09, 0);
 
+static APMU_CLK_OPS(sdh0, SDH0, 0x12, 4800, &sdh_clk_ops);
+static APMU_CLK_OPS(sdh1, SDH1, 0x12, 4800, &sdh_clk_ops);
+static APMU_CLK_OPS(sdh2, SDH2, 0x12, 4800, &sdh_clk_ops);
+static APMU_CLK_OPS(sdh3, SDH3, 0x12, 4800, &sdh_clk_ops);
+
 /* device and clock bindings */
 static struct clk_lookup pxa168_clkregs[] = {
INIT_CLKREG(&clk_uart1, "pxa2xx-uart.0", NULL),
@@ -104,6 +109,10 @@ static struct clk_lookup pxa168_clkregs[] = {
INIT_CLKREG(&clk_lcd, "pxa168-fb", NULL),
INIT_CLKREG(&clk_keypad, "pxa27x-keypad", NULL),
INIT_CLKREG(&clk_eth, "pxa168-eth", "MFUCLK"),
+   INIT_CLKREG(&clk_sdh0, "sdhci-pxav1.0", "PXA-SDHCLK"),
+   INIT_CLKREG(&clk_sdh1, "sdhci-pxav1.1", "PXA-SDHCLK"),

[PATCH] mmc: sdhci-pxa: Check pdata before using its members

2011-09-13 Thread Tanmay Upadhyay
Signed-off-by: Tanmay Upadhyay 
---
 drivers/mmc/host/sdhci-pxav2.c |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/sdhci-pxav2.c b/drivers/mmc/host/sdhci-pxav2.c
index 38f5899..1114fe2 100644
--- a/drivers/mmc/host/sdhci-pxav2.c
+++ b/drivers/mmc/host/sdhci-pxav2.c
@@ -59,7 +59,7 @@ static void pxav2_set_private_registers(struct sdhci_host 
*host, u8 mask)
 * tune timing of read data/command when crc error happen
 * no performance impact
 */
-   if (pdata->clk_delay_sel == 1) {
+   if (pdata && pdata->clk_delay_sel == 1) {
tmp = readw(host->ioaddr + SD_CLOCK_BURST_SIZE_SETUP);
 
tmp &= ~(SDCLK_DELAY_MASK << SDCLK_DELAY_SHIFT);
@@ -71,7 +71,7 @@ static void pxav2_set_private_registers(struct sdhci_host 
*host, u8 mask)
writew(tmp, host->ioaddr + SD_CLOCK_BURST_SIZE_SETUP);
}
 
-   if (pdata->flags & PXA_FLAG_ENABLE_CLOCK_GATING) {
+   if (pdata && (pdata->flags & PXA_FLAG_ENABLE_CLOCK_GATING)) {
tmp = readw(host->ioaddr + SD_FIFO_PARAM);
tmp &= ~CLK_GATE_SETTING_BITS;
writew(tmp, host->ioaddr + SD_FIFO_PARAM);
-- 
1.7.0.4

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