[PATCH 1/2] mfd: rtsx: add func to split u32 into register

2014-11-26 Thread micky_ching
From: Micky Ching 

Add helper function to write u32 to registers, if we want to put u32
value to 4 continuous register, this can help us reduce tedious work.

Signed-off-by: Micky Ching 
---
 include/linux/mfd/rtsx_pci.h | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/include/linux/mfd/rtsx_pci.h b/include/linux/mfd/rtsx_pci.h
index 74346d5..bf45ea2 100644
--- a/include/linux/mfd/rtsx_pci.h
+++ b/include/linux/mfd/rtsx_pci.h
@@ -967,4 +967,19 @@ static inline u8 *rtsx_pci_get_cmd_data(struct rtsx_pcr 
*pcr)
return (u8 *)(pcr->host_cmds_ptr);
 }
 
+static inline void rtsx_pci_write_be32(struct rtsx_pcr *pcr, u16 reg, u32 val)
+{
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, reg, 0xFF, val >> 24);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, reg + 1, 0xFF, val >> 16);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, reg + 2, 0xFF, val >> 8);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, reg + 3, 0xFF, val);
+}
+
+static inline void rtsx_pci_write_le32(struct rtsx_pcr *pcr, u16 reg, u32 val)
+{
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, reg, 0xFF, val);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, reg + 1, 0xFF, val >> 8);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, reg + 2, 0xFF, val >> 16);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, reg + 3, 0xFF, val >> 24);
+}
 #endif
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 0/2] mmc: rtsx: add support for sdio card

2014-11-26 Thread micky_ching
From: Micky Ching 

This patch is used to change transfer mode for sdio card support
by SD interface.

Micky Ching (2):
  mfd: rtsx: add func to split u32 into register
  mmc: rtsx: add support for sdio card

 drivers/mmc/host/rtsx_pci_sdmmc.c | 366 ++
 include/linux/mfd/rtsx_pci.h  |  15 ++
 2 files changed, 224 insertions(+), 157 deletions(-)

-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 2/2] mmc: rtsx: add support for sdio card

2014-11-26 Thread micky_ching
From: Micky Ching 

Add support for sdio card by SD interface. The main change is data
transfer mode, When read data, host wait data transfer while command
start. When write data, host will start data transfer after command get
response. The transfer mode modify can be applied both for SD/MMC card
and sdio card.

Signed-off-by: Micky Ching 
---
 drivers/mmc/host/rtsx_pci_sdmmc.c | 366 ++
 1 file changed, 209 insertions(+), 157 deletions(-)

diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c 
b/drivers/mmc/host/rtsx_pci_sdmmc.c
index c70b602..a4f62e4 100644
--- a/drivers/mmc/host/rtsx_pci_sdmmc.c
+++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
@@ -28,6 +28,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -71,30 +72,82 @@ static inline void sd_clear_error(struct realtek_pci_sdmmc 
*host)
 }
 
 #ifdef DEBUG
-static void sd_print_debug_regs(struct realtek_pci_sdmmc *host)
+static void dump_reg_range(struct realtek_pci_sdmmc *host, u16 start, u16 end)
 {
-   struct rtsx_pcr *pcr = host->pcr;
-   u16 i;
-   u8 *ptr;
+   u16 len = end - start + 1;
+   int i;
+   u8 *data = kzalloc(8, GFP_KERNEL);
 
-   /* Print SD host internal registers */
-   rtsx_pci_init_cmd(pcr);
-   for (i = 0xFDA0; i <= 0xFDAE; i++)
-   rtsx_pci_add_cmd(pcr, READ_REG_CMD, i, 0, 0);
-   for (i = 0xFD52; i <= 0xFD69; i++)
-   rtsx_pci_add_cmd(pcr, READ_REG_CMD, i, 0, 0);
-   rtsx_pci_send_cmd(pcr, 100);
-
-   ptr = rtsx_pci_get_cmd_data(pcr);
-   for (i = 0xFDA0; i <= 0xFDAE; i++)
-   dev_dbg(sdmmc_dev(host), "0x%04X: 0x%02x\n", i, *(ptr++));
-   for (i = 0xFD52; i <= 0xFD69; i++)
-   dev_dbg(sdmmc_dev(host), "0x%04X: 0x%02x\n", i, *(ptr++));
+   if (!data)
+   return;
+
+   for (i = 0; i < len; i += 8, start += 8) {
+   int j, n = min(8, len - i);
+
+   for (j = 0; j < n; j++)
+   rtsx_pci_read_register(host->pcr, start + j, data + j);
+   dev_dbg(sdmmc_dev(host), "0x%04X(%d): %8ph\n", start, n, data);
+   }
+
+   kfree(data);
+}
+
+static void sd_print_debug_regs(struct realtek_pci_sdmmc *host)
+{
+   dump_reg_range(host, 0xFDA0, 0xFDB3);
+   dump_reg_range(host, 0xFD52, 0xFD69);
 }
 #else
 #define sd_print_debug_regs(host)
 #endif /* DEBUG */
 
+static int sdmmc_get_cd(struct mmc_host *mmc);
+static void sd_send_cmd_get_rsp(struct realtek_pci_sdmmc *host,
+   struct mmc_command *cmd);
+
+static void sd_cmd_set_sd_cmd(struct rtsx_pcr *pcr, struct mmc_command *cmd)
+{
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD0, 0xFF, 0x40 | cmd->opcode);
+   rtsx_pci_write_be32(pcr, SD_CMD1, cmd->arg);
+}
+
+static void sd_cmd_set_data_len(struct rtsx_pcr *pcr, u16 blocks, u16 blksz)
+{
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_L, 0xFF, blocks);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_H, 0xFF, blocks >> 8);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, blksz);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_H, 0xFF, blksz >> 8);
+}
+
+static int sd_response_type(struct mmc_command *cmd)
+{
+   switch (mmc_resp_type(cmd)) {
+   case MMC_RSP_NONE:
+   return SD_RSP_TYPE_R0;
+   case MMC_RSP_R1:
+   return SD_RSP_TYPE_R1;
+   case MMC_RSP_R1 & ~MMC_RSP_CRC:
+   return SD_RSP_TYPE_R1 | SD_NO_CHECK_CRC7;
+   case MMC_RSP_R1B:
+   return SD_RSP_TYPE_R1b;
+   case MMC_RSP_R2:
+   return SD_RSP_TYPE_R2;
+   case MMC_RSP_R3:
+   return SD_RSP_TYPE_R3;
+   default:
+   return -EINVAL;
+   }
+}
+
+static int sd_status_index(int resp_type)
+{
+   if (resp_type == SD_RSP_TYPE_R0)
+   return 0;
+   else if (resp_type == SD_RSP_TYPE_R2)
+   return 16;
+
+   return 5;
+}
 /*
  * sd_pre_dma_transfer - do dma_map_sg() or using cookie
  *
@@ -166,34 +219,27 @@ static void sdmmc_post_req(struct mmc_host *mmc, struct 
mmc_request *mrq,
data->host_cookie = 0;
 }
 
-static int sd_read_data(struct realtek_pci_sdmmc *host, u8 *cmd, u16 byte_cnt,
-   u8 *buf, int buf_len, int timeout)
+static int sd_read_data(struct realtek_pci_sdmmc *host, struct mmc_command 
*cmd,
+   u16 byte_cnt, u8 *buf, int buf_len, int timeout)
 {
struct rtsx_pcr *pcr = host->pcr;
-   int err, i;
+   int err;
u8 trans_mode;
 
-   dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD%d\n", __func__, cmd[0] - 0x40);
+   dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD %d, arg = 0x%08x\n",
+   __func__, cmd->opcode, cmd->arg);
 
if (!buf)
buf_len = 0;
 
-   if ((cmd[0] & 0x3F) == MMC_SEND_TUNING_BLOCK)
+   if (cmd->opcode == MMC_SEND_TUNING_BLOCK)
trans_mode = SD_TM_AUTO_TUNING;
else
trans_mode = SD_TM_NORMAL_RE

[PATCH v2 1/2] mfd: rtsx: add func to split u32 into register

2014-11-27 Thread micky_ching
From: Micky Ching 

Add helper function to write u32 to registers, if we want to put u32
value to 4 continuous register, this can help us reduce tedious work.

Signed-off-by: Micky Ching 
---
 include/linux/mfd/rtsx_pci.h | 9 +
 1 file changed, 9 insertions(+)

diff --git a/include/linux/mfd/rtsx_pci.h b/include/linux/mfd/rtsx_pci.h
index 74346d5..9234449 100644
--- a/include/linux/mfd/rtsx_pci.h
+++ b/include/linux/mfd/rtsx_pci.h
@@ -558,6 +558,7 @@
 #define SD_SAMPLE_POINT_CTL0xFDA7
 #define SD_PUSH_POINT_CTL  0xFDA8
 #define SD_CMD00xFDA9
+#define   SD_CMD_START 0x40
 #define SD_CMD10xFDAA
 #define SD_CMD20xFDAB
 #define SD_CMD30xFDAC
@@ -967,4 +968,12 @@ static inline u8 *rtsx_pci_get_cmd_data(struct rtsx_pcr 
*pcr)
return (u8 *)(pcr->host_cmds_ptr);
 }
 
+static inline void rtsx_pci_write_be32(struct rtsx_pcr *pcr, u16 reg, u32 val)
+{
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, reg, 0xFF, val >> 24);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, reg + 1, 0xFF, val >> 16);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, reg + 2, 0xFF, val >> 8);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, reg + 3, 0xFF, val);
+}
+
 #endif
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v2 2/2] mmc: rtsx: add support for sdio card

2014-11-27 Thread micky_ching
From: Micky Ching 

Add support for sdio card by SD interface. The main change is data
transfer mode, When read data, host wait data transfer while command
start. When write data, host will start data transfer after command get
response. The transfer mode modify can be applied both for SD/MMC card
and sdio card.

Signed-off-by: Micky Ching 
---
 drivers/mmc/host/rtsx_pci_sdmmc.c | 523 +-
 1 file changed, 288 insertions(+), 235 deletions(-)

diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c 
b/drivers/mmc/host/rtsx_pci_sdmmc.c
index c70b602..b780779 100644
--- a/drivers/mmc/host/rtsx_pci_sdmmc.c
+++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
@@ -28,6 +28,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -71,30 +72,79 @@ static inline void sd_clear_error(struct realtek_pci_sdmmc 
*host)
 }
 
 #ifdef DEBUG
-static void sd_print_debug_regs(struct realtek_pci_sdmmc *host)
+static void dump_reg_range(struct realtek_pci_sdmmc *host, u16 start, u16 end)
 {
-   struct rtsx_pcr *pcr = host->pcr;
-   u16 i;
-   u8 *ptr;
+   u16 len = end - start + 1;
+   int i;
+   u8 data[8];
 
-   /* Print SD host internal registers */
-   rtsx_pci_init_cmd(pcr);
-   for (i = 0xFDA0; i <= 0xFDAE; i++)
-   rtsx_pci_add_cmd(pcr, READ_REG_CMD, i, 0, 0);
-   for (i = 0xFD52; i <= 0xFD69; i++)
-   rtsx_pci_add_cmd(pcr, READ_REG_CMD, i, 0, 0);
-   rtsx_pci_send_cmd(pcr, 100);
-
-   ptr = rtsx_pci_get_cmd_data(pcr);
-   for (i = 0xFDA0; i <= 0xFDAE; i++)
-   dev_dbg(sdmmc_dev(host), "0x%04X: 0x%02x\n", i, *(ptr++));
-   for (i = 0xFD52; i <= 0xFD69; i++)
-   dev_dbg(sdmmc_dev(host), "0x%04X: 0x%02x\n", i, *(ptr++));
+   if (!data)
+   return;
+
+   for (i = 0; i < len; i += 8) {
+   int j;
+   int n = min(8, len - i);
+
+   memset(&data, 0, sizeof(data));
+   for (j = 0; j < n; j++)
+   rtsx_pci_read_register(host->pcr, start + i + j,
+   data + j);
+   dev_dbg(sdmmc_dev(host), "0x%04X(%d): %8ph\n", start, n, data);
+   }
+}
+
+static void sd_print_debug_regs(struct realtek_pci_sdmmc *host)
+{
+   dump_reg_range(host, 0xFDA0, 0xFDB3);
+   dump_reg_range(host, 0xFD52, 0xFD69);
 }
 #else
 #define sd_print_debug_regs(host)
 #endif /* DEBUG */
 
+static void sd_cmd_set_sd_cmd(struct rtsx_pcr *pcr, struct mmc_command *cmd)
+{
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD0, 0xFF, SD_CMD_START | 
cmd->opcode);
+   rtsx_pci_write_be32(pcr, SD_CMD1, cmd->arg);
+}
+
+static void sd_cmd_set_data_len(struct rtsx_pcr *pcr, u16 blocks, u16 blksz)
+{
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_L, 0xFF, blocks);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_H, 0xFF, blocks >> 8);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, blksz);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_H, 0xFF, blksz >> 8);
+}
+
+static int sd_response_type(struct mmc_command *cmd)
+{
+   switch (mmc_resp_type(cmd)) {
+   case MMC_RSP_NONE:
+   return SD_RSP_TYPE_R0;
+   case MMC_RSP_R1:
+   return SD_RSP_TYPE_R1;
+   case MMC_RSP_R1 & ~MMC_RSP_CRC:
+   return SD_RSP_TYPE_R1 | SD_NO_CHECK_CRC7;
+   case MMC_RSP_R1B:
+   return SD_RSP_TYPE_R1b;
+   case MMC_RSP_R2:
+   return SD_RSP_TYPE_R2;
+   case MMC_RSP_R3:
+   return SD_RSP_TYPE_R3;
+   default:
+   return -EINVAL;
+   }
+}
+
+static int sd_status_index(int resp_type)
+{
+   if (resp_type == SD_RSP_TYPE_R0)
+   return 0;
+   else if (resp_type == SD_RSP_TYPE_R2)
+   return 16;
+
+   return 5;
+}
 /*
  * sd_pre_dma_transfer - do dma_map_sg() or using cookie
  *
@@ -166,123 +216,6 @@ static void sdmmc_post_req(struct mmc_host *mmc, struct 
mmc_request *mrq,
data->host_cookie = 0;
 }
 
-static int sd_read_data(struct realtek_pci_sdmmc *host, u8 *cmd, u16 byte_cnt,
-   u8 *buf, int buf_len, int timeout)
-{
-   struct rtsx_pcr *pcr = host->pcr;
-   int err, i;
-   u8 trans_mode;
-
-   dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD%d\n", __func__, cmd[0] - 0x40);
-
-   if (!buf)
-   buf_len = 0;
-
-   if ((cmd[0] & 0x3F) == MMC_SEND_TUNING_BLOCK)
-   trans_mode = SD_TM_AUTO_TUNING;
-   else
-   trans_mode = SD_TM_NORMAL_READ;
-
-   rtsx_pci_init_cmd(pcr);
-
-   for (i = 0; i < 5; i++)
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD0 + i, 0xFF, cmd[i]);
-
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, (u8)byte_cnt);
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_H,
-   0xFF, (u8)(byte_cnt >> 8));
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_L, 0xFF, 1);
- 

[PATCH v2 0/2] mmc: rtsx: add support for sdio card

2014-11-27 Thread micky_ching
From: Micky Ching 

v2:
  rtsx_pci.h:
- remove unused rtsx_pci_write_le32
- add SD_CMD_START
  rtsx_pci_sdmmc.c:
- dump_reg_range
  - alloc data on stack
- remove forward declaration
- use SD_CMD_START replace magic number 0x40
- move initialize assignment to error handling

This patch is used to change transfer mode for sdio card support
by SD interface.

Micky Ching (2):
  mfd: rtsx: add func to split u32 into register
  mmc: rtsx: add support for sdio card

 drivers/mmc/host/rtsx_pci_sdmmc.c | 523 +-
 include/linux/mfd/rtsx_pci.h  |   9 +
 2 files changed, 297 insertions(+), 235 deletions(-)

-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v2 1/2] mfd: rtsx: add func to split u32 into register

2014-12-01 Thread micky_ching
From: Micky Ching 

Add helper function to write u32 to registers, if we want to put u32
value to 4 continuous register, this can help us reduce tedious work.

Signed-off-by: Micky Ching 

Acked-by: Lee Jones 
---
 include/linux/mfd/rtsx_pci.h | 9 +
 1 file changed, 9 insertions(+)

diff --git a/include/linux/mfd/rtsx_pci.h b/include/linux/mfd/rtsx_pci.h
index 74346d5..9234449 100644
--- a/include/linux/mfd/rtsx_pci.h
+++ b/include/linux/mfd/rtsx_pci.h
@@ -558,6 +558,7 @@
 #define SD_SAMPLE_POINT_CTL0xFDA7
 #define SD_PUSH_POINT_CTL  0xFDA8
 #define SD_CMD00xFDA9
+#define   SD_CMD_START 0x40
 #define SD_CMD10xFDAA
 #define SD_CMD20xFDAB
 #define SD_CMD30xFDAC
@@ -967,4 +968,12 @@ static inline u8 *rtsx_pci_get_cmd_data(struct rtsx_pcr 
*pcr)
return (u8 *)(pcr->host_cmds_ptr);
 }
 
+static inline void rtsx_pci_write_be32(struct rtsx_pcr *pcr, u16 reg, u32 val)
+{
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, reg, 0xFF, val >> 24);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, reg + 1, 0xFF, val >> 16);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, reg + 2, 0xFF, val >> 8);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, reg + 3, 0xFF, val);
+}
+
 #endif
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v2 0/2] mmc: rtsx: add support for sdio card

2014-12-01 Thread micky_ching
From: Micky Ching 

v3:
  rtsx_pci_sdmmc.c:
- dump_reg_range
  - remove unused pointer check
  - fix start index
v2:
  rtsx_pci.h:
- remove unused rtsx_pci_write_le32
- add SD_CMD_START
  rtsx_pci_sdmmc.c:
- dump_reg_range
  - alloc data on stack
- remove forward declaration
- use SD_CMD_START replace magic number 0x40
- move initialize assignment to error handling

This patch is used to change transfer mode for sdio card support
by SD interface.


Micky Ching (2):
  mfd: rtsx: add func to split u32 into register
  mmc: rtsx: add support for sdio card

 drivers/mmc/host/rtsx_pci_sdmmc.c | 522 +-
 include/linux/mfd/rtsx_pci.h  |   9 +
 2 files changed, 296 insertions(+), 235 deletions(-)

-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v2 2/2] mmc: rtsx: add support for sdio card

2014-12-01 Thread micky_ching
From: Micky Ching 

Add support for sdio card by SD interface. The main change is data
transfer mode, When read data, host wait data transfer while command
start. When write data, host will start data transfer after command get
response. The transfer mode modify can be applied both for SD/MMC card
and sdio card.

Signed-off-by: Micky Ching 
---
 drivers/mmc/host/rtsx_pci_sdmmc.c | 522 +-
 1 file changed, 287 insertions(+), 235 deletions(-)

diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c 
b/drivers/mmc/host/rtsx_pci_sdmmc.c
index c70b602..26c6a7c 100644
--- a/drivers/mmc/host/rtsx_pci_sdmmc.c
+++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
@@ -28,6 +28,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -71,30 +72,78 @@ static inline void sd_clear_error(struct realtek_pci_sdmmc 
*host)
 }
 
 #ifdef DEBUG
-static void sd_print_debug_regs(struct realtek_pci_sdmmc *host)
+static void dump_reg_range(struct realtek_pci_sdmmc *host, u16 start, u16 end)
 {
-   struct rtsx_pcr *pcr = host->pcr;
-   u16 i;
-   u8 *ptr;
+   u16 len = end - start + 1;
+   int i;
+   u8 data[8];
+
+   for (i = 0; i < len; i += 8) {
+   int j;
+   int n = min(8, len - i);
+
+   memset(&data, 0, sizeof(data));
+   for (j = 0; j < n; j++)
+   rtsx_pci_read_register(host->pcr, start + i + j,
+   data + j);
+   dev_dbg(sdmmc_dev(host), "0x%04X(%d): %8ph\n",
+   start + i, n, data);
+   }
+}
 
-   /* Print SD host internal registers */
-   rtsx_pci_init_cmd(pcr);
-   for (i = 0xFDA0; i <= 0xFDAE; i++)
-   rtsx_pci_add_cmd(pcr, READ_REG_CMD, i, 0, 0);
-   for (i = 0xFD52; i <= 0xFD69; i++)
-   rtsx_pci_add_cmd(pcr, READ_REG_CMD, i, 0, 0);
-   rtsx_pci_send_cmd(pcr, 100);
-
-   ptr = rtsx_pci_get_cmd_data(pcr);
-   for (i = 0xFDA0; i <= 0xFDAE; i++)
-   dev_dbg(sdmmc_dev(host), "0x%04X: 0x%02x\n", i, *(ptr++));
-   for (i = 0xFD52; i <= 0xFD69; i++)
-   dev_dbg(sdmmc_dev(host), "0x%04X: 0x%02x\n", i, *(ptr++));
+static void sd_print_debug_regs(struct realtek_pci_sdmmc *host)
+{
+   dump_reg_range(host, 0xFDA0, 0xFDB3);
+   dump_reg_range(host, 0xFD52, 0xFD69);
 }
 #else
 #define sd_print_debug_regs(host)
 #endif /* DEBUG */
 
+static void sd_cmd_set_sd_cmd(struct rtsx_pcr *pcr, struct mmc_command *cmd)
+{
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD0, 0xFF,
+   SD_CMD_START | cmd->opcode);
+   rtsx_pci_write_be32(pcr, SD_CMD1, cmd->arg);
+}
+
+static void sd_cmd_set_data_len(struct rtsx_pcr *pcr, u16 blocks, u16 blksz)
+{
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_L, 0xFF, blocks);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_H, 0xFF, blocks >> 8);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, blksz);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_H, 0xFF, blksz >> 8);
+}
+
+static int sd_response_type(struct mmc_command *cmd)
+{
+   switch (mmc_resp_type(cmd)) {
+   case MMC_RSP_NONE:
+   return SD_RSP_TYPE_R0;
+   case MMC_RSP_R1:
+   return SD_RSP_TYPE_R1;
+   case MMC_RSP_R1 & ~MMC_RSP_CRC:
+   return SD_RSP_TYPE_R1 | SD_NO_CHECK_CRC7;
+   case MMC_RSP_R1B:
+   return SD_RSP_TYPE_R1b;
+   case MMC_RSP_R2:
+   return SD_RSP_TYPE_R2;
+   case MMC_RSP_R3:
+   return SD_RSP_TYPE_R3;
+   default:
+   return -EINVAL;
+   }
+}
+
+static int sd_status_index(int resp_type)
+{
+   if (resp_type == SD_RSP_TYPE_R0)
+   return 0;
+   else if (resp_type == SD_RSP_TYPE_R2)
+   return 16;
+
+   return 5;
+}
 /*
  * sd_pre_dma_transfer - do dma_map_sg() or using cookie
  *
@@ -166,123 +215,6 @@ static void sdmmc_post_req(struct mmc_host *mmc, struct 
mmc_request *mrq,
data->host_cookie = 0;
 }
 
-static int sd_read_data(struct realtek_pci_sdmmc *host, u8 *cmd, u16 byte_cnt,
-   u8 *buf, int buf_len, int timeout)
-{
-   struct rtsx_pcr *pcr = host->pcr;
-   int err, i;
-   u8 trans_mode;
-
-   dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD%d\n", __func__, cmd[0] - 0x40);
-
-   if (!buf)
-   buf_len = 0;
-
-   if ((cmd[0] & 0x3F) == MMC_SEND_TUNING_BLOCK)
-   trans_mode = SD_TM_AUTO_TUNING;
-   else
-   trans_mode = SD_TM_NORMAL_READ;
-
-   rtsx_pci_init_cmd(pcr);
-
-   for (i = 0; i < 5; i++)
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD0 + i, 0xFF, cmd[i]);
-
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, (u8)byte_cnt);
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_H,
-   0xFF, (u8)(byte_cnt >> 8));
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_L, 0xFF, 1);
-   

[PATCH v4 2/6] mmc: rtsx: add dump_reg_range to simplify dump register

2014-12-04 Thread micky_ching
From: Micky Ching 

Add a new function to dump register within a range.
We print 1 register a line before this patch,
this may make debug info too long when we add more register to dump.

The new dump_reg_range() dump to 8 register a line,
and it is easy to use.

Signed-off-by: Micky Ching 
---
 drivers/mmc/host/rtsx_pci_sdmmc.c | 38 +-
 1 file changed, 21 insertions(+), 17 deletions(-)

diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c 
b/drivers/mmc/host/rtsx_pci_sdmmc.c
index c70b602..b1390f0 100644
--- a/drivers/mmc/host/rtsx_pci_sdmmc.c
+++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
@@ -71,25 +71,29 @@ static inline void sd_clear_error(struct realtek_pci_sdmmc 
*host)
 }
 
 #ifdef DEBUG
-static void sd_print_debug_regs(struct realtek_pci_sdmmc *host)
+static void dump_reg_range(struct realtek_pci_sdmmc *host, u16 start, u16 end)
 {
-   struct rtsx_pcr *pcr = host->pcr;
-   u16 i;
-   u8 *ptr;
+   u16 len = end - start + 1;
+   int i;
+   u8 data[8];
+
+   for (i = 0; i < len; i += 8) {
+   int j;
+   int n = min(8, len - i);
+
+   memset(&data, 0, sizeof(data));
+   for (j = 0; j < n; j++)
+   rtsx_pci_read_register(host->pcr, start + i + j,
+   data + j);
+   dev_dbg(sdmmc_dev(host), "0x%04X(%d): %8ph\n",
+   start + i, n, data);
+   }
+}
 
-   /* Print SD host internal registers */
-   rtsx_pci_init_cmd(pcr);
-   for (i = 0xFDA0; i <= 0xFDAE; i++)
-   rtsx_pci_add_cmd(pcr, READ_REG_CMD, i, 0, 0);
-   for (i = 0xFD52; i <= 0xFD69; i++)
-   rtsx_pci_add_cmd(pcr, READ_REG_CMD, i, 0, 0);
-   rtsx_pci_send_cmd(pcr, 100);
-
-   ptr = rtsx_pci_get_cmd_data(pcr);
-   for (i = 0xFDA0; i <= 0xFDAE; i++)
-   dev_dbg(sdmmc_dev(host), "0x%04X: 0x%02x\n", i, *(ptr++));
-   for (i = 0xFD52; i <= 0xFD69; i++)
-   dev_dbg(sdmmc_dev(host), "0x%04X: 0x%02x\n", i, *(ptr++));
+static void sd_print_debug_regs(struct realtek_pci_sdmmc *host)
+{
+   dump_reg_range(host, 0xFDA0, 0xFDB3);
+   dump_reg_range(host, 0xFD52, 0xFD69);
 }
 #else
 #define sd_print_debug_regs(host)
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v4 0/6] mmc: rtsx: add support for sdio card

2014-12-04 Thread micky_ching
From: Micky Ching 

v4:
  split patch in more detailed patches. no code changes diff v3.

v3:
  rtsx_pci_sdmmc.c:
- dump_reg_range
  - remove unused pointer check
  - fix start index
v2:
  rtsx_pci.h:
- remove unused rtsx_pci_write_le32
- add SD_CMD_START
  rtsx_pci_sdmmc.c:
- dump_reg_range
  - alloc data on stack
- remove forward declaration
- use SD_CMD_START replace magic number 0x40
- move initialize assignment to error handling

This patch is used to change transfer mode for sdio card support
by SD interface.



Micky Ching (6):
  mfd: rtsx: add func to split u32 into register
  mmc: rtsx: add dump_reg_range to simplify dump register
  mmc: rtsx: init cookie at probe/card_event
  mmc: rtsx: add helper function to simplify code
  mmc: rtsx: add support for sdio card
  mmc: rtsx: swap function position to avoid pre declaration

 drivers/mmc/host/rtsx_pci_sdmmc.c | 522 +-
 include/linux/mfd/rtsx_pci.h  |   9 +
 2 files changed, 296 insertions(+), 235 deletions(-)

-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v4 4/6] mmc: rtsx: add helper function to simplify code

2014-12-04 Thread micky_ching
From: Micky Ching 

To support sdio card, transfer mode need make a change,
this need to split code and use it in different place,
Add new function to simplify repeat operation.

Signed-off-by: Micky Ching 
---
 drivers/mmc/host/rtsx_pci_sdmmc.c | 95 +--
 1 file changed, 51 insertions(+), 44 deletions(-)

diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c 
b/drivers/mmc/host/rtsx_pci_sdmmc.c
index 90b7b6d..b96c9ed 100644
--- a/drivers/mmc/host/rtsx_pci_sdmmc.c
+++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
@@ -99,6 +99,50 @@ static void sd_print_debug_regs(struct realtek_pci_sdmmc 
*host)
 #define sd_print_debug_regs(host)
 #endif /* DEBUG */
 
+static void sd_cmd_set_sd_cmd(struct rtsx_pcr *pcr, struct mmc_command *cmd)
+{
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD0, 0xFF,
+   SD_CMD_START | cmd->opcode);
+   rtsx_pci_write_be32(pcr, SD_CMD1, cmd->arg);
+}
+
+static void sd_cmd_set_data_len(struct rtsx_pcr *pcr, u16 blocks, u16 blksz)
+{
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_L, 0xFF, blocks);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_H, 0xFF, blocks >> 8);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, blksz);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_H, 0xFF, blksz >> 8);
+}
+
+static int sd_response_type(struct mmc_command *cmd)
+{
+   switch (mmc_resp_type(cmd)) {
+   case MMC_RSP_NONE:
+   return SD_RSP_TYPE_R0;
+   case MMC_RSP_R1:
+   return SD_RSP_TYPE_R1;
+   case MMC_RSP_R1 & ~MMC_RSP_CRC:
+   return SD_RSP_TYPE_R1 | SD_NO_CHECK_CRC7;
+   case MMC_RSP_R1B:
+   return SD_RSP_TYPE_R1b;
+   case MMC_RSP_R2:
+   return SD_RSP_TYPE_R2;
+   case MMC_RSP_R3:
+   return SD_RSP_TYPE_R3;
+   default:
+   return -EINVAL;
+   }
+}
+
+static int sd_status_index(int resp_type)
+{
+   if (resp_type == SD_RSP_TYPE_R0)
+   return 0;
+   else if (resp_type == SD_RSP_TYPE_R2)
+   return 16;
+
+   return 5;
+}
 /*
  * sd_pre_dma_transfer - do dma_map_sg() or using cookie
  *
@@ -297,47 +341,18 @@ static void sd_send_cmd_get_rsp(struct realtek_pci_sdmmc 
*host,
int timeout = 100;
int i;
u8 *ptr;
-   int stat_idx = 0;
-   u8 rsp_type;
-   int rsp_len = 5;
+   int rsp_type;
+   int stat_idx;
bool clock_toggled = false;
 
dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD %d, arg = 0x%08x\n",
__func__, cmd_idx, arg);
 
-   /* Response type:
-* R0
-* R1, R5, R6, R7
-* R1b
-* R2
-* R3, R4
-*/
-   switch (mmc_resp_type(cmd)) {
-   case MMC_RSP_NONE:
-   rsp_type = SD_RSP_TYPE_R0;
-   rsp_len = 0;
-   break;
-   case MMC_RSP_R1:
-   rsp_type = SD_RSP_TYPE_R1;
-   break;
-   case MMC_RSP_R1 & ~MMC_RSP_CRC:
-   rsp_type = SD_RSP_TYPE_R1 | SD_NO_CHECK_CRC7;
-   break;
-   case MMC_RSP_R1B:
-   rsp_type = SD_RSP_TYPE_R1b;
-   break;
-   case MMC_RSP_R2:
-   rsp_type = SD_RSP_TYPE_R2;
-   rsp_len = 16;
-   break;
-   case MMC_RSP_R3:
-   rsp_type = SD_RSP_TYPE_R3;
-   break;
-   default:
-   dev_dbg(sdmmc_dev(host), "cmd->flag is not valid\n");
-   err = -EINVAL;
+   rsp_type = sd_response_type(cmd);
+   if (rsp_type < 0)
goto out;
-   }
+
+   stat_idx = sd_status_index(rsp_type);
 
if (rsp_type == SD_RSP_TYPE_R1b)
timeout = 3000;
@@ -352,13 +367,7 @@ static void sd_send_cmd_get_rsp(struct realtek_pci_sdmmc 
*host,
}
 
rtsx_pci_init_cmd(pcr);
-
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD0, 0xFF, 0x40 | cmd_idx);
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD1, 0xFF, (u8)(arg >> 24));
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD2, 0xFF, (u8)(arg >> 16));
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD3, 0xFF, (u8)(arg >> 8));
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD4, 0xFF, (u8)arg);
-
+   sd_cmd_set_sd_cmd(pcr, cmd);
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG2, 0xFF, rsp_type);
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_DATA_SOURCE,
0x01, PINGPONG_BUFFER);
@@ -372,12 +381,10 @@ static void sd_send_cmd_get_rsp(struct realtek_pci_sdmmc 
*host,
/* Read data from ping-pong buffer */
for (i = PPBUF_BASE2; i < PPBUF_BASE2 + 16; i++)
rtsx_pci_add_cmd(pcr, READ_REG_CMD, (u16)i, 0, 0);
-   stat_idx = 16;
} else if (rsp_type != SD_RSP_TYPE_R0) {
/* Read data from SD_CMDx registers */
for (i = SD_CMD0; i <= SD_CMD4; i++)
rtsx_pci_add_cmd(pcr, READ_

[PATCH v4 5/6] mmc: rtsx: add support for sdio card

2014-12-04 Thread micky_ching
From: Micky Ching 

Modify transfer mode for support sdio card,
send cmd and data at the same time for read data transfer,
but send data after cmd for write data transfer.

Signed-off-by: Micky Ching 
---
 drivers/mmc/host/rtsx_pci_sdmmc.c | 231 ++
 1 file changed, 135 insertions(+), 96 deletions(-)

diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c 
b/drivers/mmc/host/rtsx_pci_sdmmc.c
index b96c9ed..b2dfba2 100644
--- a/drivers/mmc/host/rtsx_pci_sdmmc.c
+++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
@@ -28,6 +28,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -214,34 +215,27 @@ static void sdmmc_post_req(struct mmc_host *mmc, struct 
mmc_request *mrq,
data->host_cookie = 0;
 }
 
-static int sd_read_data(struct realtek_pci_sdmmc *host, u8 *cmd, u16 byte_cnt,
-   u8 *buf, int buf_len, int timeout)
+static int sd_read_data(struct realtek_pci_sdmmc *host, struct mmc_command 
*cmd,
+   u16 byte_cnt, u8 *buf, int buf_len, int timeout)
 {
struct rtsx_pcr *pcr = host->pcr;
-   int err, i;
+   int err;
u8 trans_mode;
 
-   dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD%d\n", __func__, cmd[0] - 0x40);
+   dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD %d, arg = 0x%08x\n",
+   __func__, cmd->opcode, cmd->arg);
 
if (!buf)
buf_len = 0;
 
-   if ((cmd[0] & 0x3F) == MMC_SEND_TUNING_BLOCK)
+   if (cmd->opcode == MMC_SEND_TUNING_BLOCK)
trans_mode = SD_TM_AUTO_TUNING;
else
trans_mode = SD_TM_NORMAL_READ;
 
rtsx_pci_init_cmd(pcr);
-
-   for (i = 0; i < 5; i++)
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD0 + i, 0xFF, cmd[i]);
-
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, (u8)byte_cnt);
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_H,
-   0xFF, (u8)(byte_cnt >> 8));
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_L, 0xFF, 1);
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_H, 0xFF, 0);
-
+   sd_cmd_set_sd_cmd(pcr, cmd);
+   sd_cmd_set_data_len(pcr, 1, byte_cnt);
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG2, 0xFF,
SD_CALCULATE_CRC7 | SD_CHECK_CRC16 |
SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | SD_RSP_LEN_6);
@@ -274,16 +268,23 @@ static int sd_read_data(struct realtek_pci_sdmmc *host, 
u8 *cmd, u16 byte_cnt,
return 0;
 }
 
-static int sd_write_data(struct realtek_pci_sdmmc *host, u8 *cmd, u16 byte_cnt,
-   u8 *buf, int buf_len, int timeout)
+static int sd_write_data(struct realtek_pci_sdmmc *host,
+   struct mmc_command *cmd, u16 byte_cnt, u8 *buf, int buf_len,
+   int timeout)
 {
struct rtsx_pcr *pcr = host->pcr;
-   int err, i;
-   u8 trans_mode;
+   int err;
+
+   dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD %d, arg = 0x%08x\n",
+   __func__, cmd->opcode, cmd->arg);
 
if (!buf)
buf_len = 0;
 
+   sd_send_cmd_get_rsp(host, cmd);
+   if (cmd->error)
+   return cmd->error;
+
if (buf && buf_len) {
err = rtsx_pci_write_ppbuf(pcr, buf, buf_len);
if (err < 0) {
@@ -293,30 +294,13 @@ static int sd_write_data(struct realtek_pci_sdmmc *host, 
u8 *cmd, u16 byte_cnt,
}
}
 
-   trans_mode = cmd ? SD_TM_AUTO_WRITE_2 : SD_TM_AUTO_WRITE_3;
rtsx_pci_init_cmd(pcr);
-
-   if (cmd) {
-   dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD %d\n", __func__,
-   cmd[0] - 0x40);
-
-   for (i = 0; i < 5; i++)
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
-   SD_CMD0 + i, 0xFF, cmd[i]);
-   }
-
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, (u8)byte_cnt);
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_H,
-   0xFF, (u8)(byte_cnt >> 8));
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_L, 0xFF, 1);
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_H, 0xFF, 0);
-
+   sd_cmd_set_data_len(pcr, 1, byte_cnt);
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG2, 0xFF,
SD_CALCULATE_CRC7 | SD_CHECK_CRC16 |
-   SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | SD_RSP_LEN_6);
-
+   SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | SD_RSP_LEN_0);
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_TRANSFER, 0xFF,
-   trans_mode | SD_TRANSFER_START);
+   SD_TRANSFER_START | SD_TM_AUTO_WRITE_3);
rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, SD_TRANSFER,
SD_TRANSFER_END, SD_TRANSFER_END);
 
@@ -449,71 +433,113 @@ out:
SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, 0);
 }
 
-static int sd_rw_multi(struct realtek_pci_sdmmc *host, struct mmc_request *mrq)
+static int sd_read_long_data

[PATCH v4 3/6] mmc: rtsx: init cookie at probe/card_event

2014-12-04 Thread micky_ching
From: Micky Ching 

host->cookie is used for handle async request,
we should init it to negative value when new card inserted,
make cookie value invalid.

Signed-off-by: Micky Ching 
---
 drivers/mmc/host/rtsx_pci_sdmmc.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c 
b/drivers/mmc/host/rtsx_pci_sdmmc.c
index b1390f0..90b7b6d 100644
--- a/drivers/mmc/host/rtsx_pci_sdmmc.c
+++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
@@ -1321,6 +1321,7 @@ static void rtsx_pci_sdmmc_card_event(struct 
platform_device *pdev)
 {
struct realtek_pci_sdmmc *host = platform_get_drvdata(pdev);
 
+   host->cookie = -1;
mmc_detect_change(host->mmc, 0);
 }
 
@@ -1353,6 +1354,7 @@ static int rtsx_pci_sdmmc_drv_probe(struct 
platform_device *pdev)
host->pcr = pcr;
host->mmc = mmc;
host->pdev = pdev;
+   host->cookie = -1;
host->power_state = SDMMC_POWER_OFF;
INIT_WORK(&host->work, sd_request);
platform_set_drvdata(pdev, host);
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v4 6/6] mmc: rtsx: swap function position to avoid pre declaration

2014-12-04 Thread micky_ching
From: Micky Ching 

move function sd_read_data()/sd_write_data() behind
sd_send_cmd_get_rsp() to avoid pre-declaration.

Signed-off-by: Micky Ching 
---
 drivers/mmc/host/rtsx_pci_sdmmc.c | 200 +++---
 1 file changed, 100 insertions(+), 100 deletions(-)

diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c 
b/drivers/mmc/host/rtsx_pci_sdmmc.c
index b2dfba2..26c6a7c 100644
--- a/drivers/mmc/host/rtsx_pci_sdmmc.c
+++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
@@ -215,106 +215,6 @@ static void sdmmc_post_req(struct mmc_host *mmc, struct 
mmc_request *mrq,
data->host_cookie = 0;
 }
 
-static int sd_read_data(struct realtek_pci_sdmmc *host, struct mmc_command 
*cmd,
-   u16 byte_cnt, u8 *buf, int buf_len, int timeout)
-{
-   struct rtsx_pcr *pcr = host->pcr;
-   int err;
-   u8 trans_mode;
-
-   dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD %d, arg = 0x%08x\n",
-   __func__, cmd->opcode, cmd->arg);
-
-   if (!buf)
-   buf_len = 0;
-
-   if (cmd->opcode == MMC_SEND_TUNING_BLOCK)
-   trans_mode = SD_TM_AUTO_TUNING;
-   else
-   trans_mode = SD_TM_NORMAL_READ;
-
-   rtsx_pci_init_cmd(pcr);
-   sd_cmd_set_sd_cmd(pcr, cmd);
-   sd_cmd_set_data_len(pcr, 1, byte_cnt);
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG2, 0xFF,
-   SD_CALCULATE_CRC7 | SD_CHECK_CRC16 |
-   SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | SD_RSP_LEN_6);
-   if (trans_mode != SD_TM_AUTO_TUNING)
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
-   CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER);
-
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_TRANSFER,
-   0xFF, trans_mode | SD_TRANSFER_START);
-   rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, SD_TRANSFER,
-   SD_TRANSFER_END, SD_TRANSFER_END);
-
-   err = rtsx_pci_send_cmd(pcr, timeout);
-   if (err < 0) {
-   sd_print_debug_regs(host);
-   dev_dbg(sdmmc_dev(host),
-   "rtsx_pci_send_cmd fail (err = %d)\n", err);
-   return err;
-   }
-
-   if (buf && buf_len) {
-   err = rtsx_pci_read_ppbuf(pcr, buf, buf_len);
-   if (err < 0) {
-   dev_dbg(sdmmc_dev(host),
-   "rtsx_pci_read_ppbuf fail (err = %d)\n", err);
-   return err;
-   }
-   }
-
-   return 0;
-}
-
-static int sd_write_data(struct realtek_pci_sdmmc *host,
-   struct mmc_command *cmd, u16 byte_cnt, u8 *buf, int buf_len,
-   int timeout)
-{
-   struct rtsx_pcr *pcr = host->pcr;
-   int err;
-
-   dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD %d, arg = 0x%08x\n",
-   __func__, cmd->opcode, cmd->arg);
-
-   if (!buf)
-   buf_len = 0;
-
-   sd_send_cmd_get_rsp(host, cmd);
-   if (cmd->error)
-   return cmd->error;
-
-   if (buf && buf_len) {
-   err = rtsx_pci_write_ppbuf(pcr, buf, buf_len);
-   if (err < 0) {
-   dev_dbg(sdmmc_dev(host),
-   "rtsx_pci_write_ppbuf fail (err = %d)\n", err);
-   return err;
-   }
-   }
-
-   rtsx_pci_init_cmd(pcr);
-   sd_cmd_set_data_len(pcr, 1, byte_cnt);
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG2, 0xFF,
-   SD_CALCULATE_CRC7 | SD_CHECK_CRC16 |
-   SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | SD_RSP_LEN_0);
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_TRANSFER, 0xFF,
-   SD_TRANSFER_START | SD_TM_AUTO_WRITE_3);
-   rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, SD_TRANSFER,
-   SD_TRANSFER_END, SD_TRANSFER_END);
-
-   err = rtsx_pci_send_cmd(pcr, timeout);
-   if (err < 0) {
-   sd_print_debug_regs(host);
-   dev_dbg(sdmmc_dev(host),
-   "rtsx_pci_send_cmd fail (err = %d)\n", err);
-   return err;
-   }
-
-   return 0;
-}
-
 static void sd_send_cmd_get_rsp(struct realtek_pci_sdmmc *host,
struct mmc_command *cmd)
 {
@@ -433,6 +333,106 @@ out:
SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, 0);
 }
 
+static int sd_read_data(struct realtek_pci_sdmmc *host, struct mmc_command 
*cmd,
+   u16 byte_cnt, u8 *buf, int buf_len, int timeout)
+{
+   struct rtsx_pcr *pcr = host->pcr;
+   int err;
+   u8 trans_mode;
+
+   dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD %d, arg = 0x%08x\n",
+   __func__, cmd->opcode, cmd->arg);
+
+   if (!buf)
+   buf_len = 0;
+
+   if (cmd->opcode == MMC_SEND_TUNING_BLOCK)
+   trans_mode = SD_TM_AUTO_TUNING;
+   else
+   trans_mode = SD_TM_NORMAL_READ;
+
+   rtsx_pci_init_cmd(pcr);
+   sd_cmd_set_sd_cmd(pcr, cmd);
+   sd_cmd_set_data_len(pcr, 1, byte_cnt);
+  

[PATCH v4 1/6] mfd: rtsx: add func to split u32 into register

2014-12-04 Thread micky_ching
From: Micky Ching 

Add helper function to write u32 to registers, if we want to put u32
value to 4 continuous register, this can help us reduce tedious work.

Signed-off-by: Micky Ching 
Acked-by: Lee Jones 
---
 include/linux/mfd/rtsx_pci.h | 9 +
 1 file changed, 9 insertions(+)

diff --git a/include/linux/mfd/rtsx_pci.h b/include/linux/mfd/rtsx_pci.h
index 74346d5..9234449 100644
--- a/include/linux/mfd/rtsx_pci.h
+++ b/include/linux/mfd/rtsx_pci.h
@@ -558,6 +558,7 @@
 #define SD_SAMPLE_POINT_CTL0xFDA7
 #define SD_PUSH_POINT_CTL  0xFDA8
 #define SD_CMD00xFDA9
+#define   SD_CMD_START 0x40
 #define SD_CMD10xFDAA
 #define SD_CMD20xFDAB
 #define SD_CMD30xFDAC
@@ -967,4 +968,12 @@ static inline u8 *rtsx_pci_get_cmd_data(struct rtsx_pcr 
*pcr)
return (u8 *)(pcr->host_cmds_ptr);
 }
 
+static inline void rtsx_pci_write_be32(struct rtsx_pcr *pcr, u16 reg, u32 val)
+{
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, reg, 0xFF, val >> 24);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, reg + 1, 0xFF, val >> 16);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, reg + 2, 0xFF, val >> 8);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, reg + 3, 0xFF, val);
+}
+
 #endif
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v5 3/6] mmc: rtsx: init cookie at probe/card_event

2014-12-22 Thread micky_ching
From: Micky Ching 

host->cookie is used for handle async request,
we should init it to negative value when new card inserted,
make cookie value invalid.

Signed-off-by: Micky Ching 
---
 drivers/mmc/host/rtsx_pci_sdmmc.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c 
b/drivers/mmc/host/rtsx_pci_sdmmc.c
index b1390f0..90b7b6d 100644
--- a/drivers/mmc/host/rtsx_pci_sdmmc.c
+++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
@@ -1321,6 +1321,7 @@ static void rtsx_pci_sdmmc_card_event(struct 
platform_device *pdev)
 {
struct realtek_pci_sdmmc *host = platform_get_drvdata(pdev);
 
+   host->cookie = -1;
mmc_detect_change(host->mmc, 0);
 }
 
@@ -1353,6 +1354,7 @@ static int rtsx_pci_sdmmc_drv_probe(struct 
platform_device *pdev)
host->pcr = pcr;
host->mmc = mmc;
host->pdev = pdev;
+   host->cookie = -1;
host->power_state = SDMMC_POWER_OFF;
INIT_WORK(&host->work, sd_request);
platform_set_drvdata(pdev, host);
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v5 2/6] mmc: rtsx: add dump_reg_range to simplify dump register

2014-12-22 Thread micky_ching
From: Micky Ching 

Add a new function to dump register within a range.
We print 1 register a line before this patch,
this may make debug info too long when we add more register to dump.

The new dump_reg_range() dump to 8 register a line,
and it is easy to use.

Signed-off-by: Micky Ching 
---
 drivers/mmc/host/rtsx_pci_sdmmc.c | 38 +-
 1 file changed, 21 insertions(+), 17 deletions(-)

diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c 
b/drivers/mmc/host/rtsx_pci_sdmmc.c
index c70b602..b1390f0 100644
--- a/drivers/mmc/host/rtsx_pci_sdmmc.c
+++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
@@ -71,25 +71,29 @@ static inline void sd_clear_error(struct realtek_pci_sdmmc 
*host)
 }
 
 #ifdef DEBUG
-static void sd_print_debug_regs(struct realtek_pci_sdmmc *host)
+static void dump_reg_range(struct realtek_pci_sdmmc *host, u16 start, u16 end)
 {
-   struct rtsx_pcr *pcr = host->pcr;
-   u16 i;
-   u8 *ptr;
+   u16 len = end - start + 1;
+   int i;
+   u8 data[8];
+
+   for (i = 0; i < len; i += 8) {
+   int j;
+   int n = min(8, len - i);
+
+   memset(&data, 0, sizeof(data));
+   for (j = 0; j < n; j++)
+   rtsx_pci_read_register(host->pcr, start + i + j,
+   data + j);
+   dev_dbg(sdmmc_dev(host), "0x%04X(%d): %8ph\n",
+   start + i, n, data);
+   }
+}
 
-   /* Print SD host internal registers */
-   rtsx_pci_init_cmd(pcr);
-   for (i = 0xFDA0; i <= 0xFDAE; i++)
-   rtsx_pci_add_cmd(pcr, READ_REG_CMD, i, 0, 0);
-   for (i = 0xFD52; i <= 0xFD69; i++)
-   rtsx_pci_add_cmd(pcr, READ_REG_CMD, i, 0, 0);
-   rtsx_pci_send_cmd(pcr, 100);
-
-   ptr = rtsx_pci_get_cmd_data(pcr);
-   for (i = 0xFDA0; i <= 0xFDAE; i++)
-   dev_dbg(sdmmc_dev(host), "0x%04X: 0x%02x\n", i, *(ptr++));
-   for (i = 0xFD52; i <= 0xFD69; i++)
-   dev_dbg(sdmmc_dev(host), "0x%04X: 0x%02x\n", i, *(ptr++));
+static void sd_print_debug_regs(struct realtek_pci_sdmmc *host)
+{
+   dump_reg_range(host, 0xFDA0, 0xFDB3);
+   dump_reg_range(host, 0xFD52, 0xFD69);
 }
 #else
 #define sd_print_debug_regs(host)
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v5 0/6] mmc: rtsx: add support for sdio card

2014-12-22 Thread micky_ching
From: Micky Ching 

v5:
  fix patch(5) building error, no code change diff v4.

v4:
  split patch in more detailed patches. no code changes diff v3.

v3:
  rtsx_pci_sdmmc.c:
- dump_reg_range
  - remove unused pointer check
  - fix start index
v2:
  rtsx_pci.h:
- remove unused rtsx_pci_write_le32
- add SD_CMD_START
  rtsx_pci_sdmmc.c:
- dump_reg_range
  - alloc data on stack
- remove forward declaration
- use SD_CMD_START replace magic number 0x40
- move initialize assignment to error handling

This patch is used to change transfer mode for sdio card support
by SD interface.

Micky Ching (6):
  mfd: rtsx: add func to split u32 into register
  mmc: rtsx: add dump_reg_range to simplify dump register
  mmc: rtsx: init cookie at probe/card_event
  mmc: rtsx: add helper function to simplify code
  mmc: rtsx: add support for sdio card
  mmc: rtsx: swap function position to avoid pre declaration

 drivers/mmc/host/rtsx_pci_sdmmc.c | 522 +-
 include/linux/mfd/rtsx_pci.h  |   9 +
 2 files changed, 296 insertions(+), 235 deletions(-)

-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v5 1/6] mfd: rtsx: add func to split u32 into register

2014-12-22 Thread micky_ching
From: Micky Ching 

Add helper function to write u32 to registers, if we want to put u32
value to 4 continuous register, this can help us reduce tedious work.

Signed-off-by: Micky Ching 
Acked-by: Lee Jones 
---
 include/linux/mfd/rtsx_pci.h | 9 +
 1 file changed, 9 insertions(+)

diff --git a/include/linux/mfd/rtsx_pci.h b/include/linux/mfd/rtsx_pci.h
index 74346d5..9234449 100644
--- a/include/linux/mfd/rtsx_pci.h
+++ b/include/linux/mfd/rtsx_pci.h
@@ -558,6 +558,7 @@
 #define SD_SAMPLE_POINT_CTL0xFDA7
 #define SD_PUSH_POINT_CTL  0xFDA8
 #define SD_CMD00xFDA9
+#define   SD_CMD_START 0x40
 #define SD_CMD10xFDAA
 #define SD_CMD20xFDAB
 #define SD_CMD30xFDAC
@@ -967,4 +968,12 @@ static inline u8 *rtsx_pci_get_cmd_data(struct rtsx_pcr 
*pcr)
return (u8 *)(pcr->host_cmds_ptr);
 }
 
+static inline void rtsx_pci_write_be32(struct rtsx_pcr *pcr, u16 reg, u32 val)
+{
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, reg, 0xFF, val >> 24);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, reg + 1, 0xFF, val >> 16);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, reg + 2, 0xFF, val >> 8);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, reg + 3, 0xFF, val);
+}
+
 #endif
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v5 6/6] mmc: rtsx: swap function position to avoid pre declaration

2014-12-22 Thread micky_ching
From: Micky Ching 

move function sd_read_data()/sd_write_data() behind
sd_send_cmd_get_rsp() to avoid pre-declaration.

Signed-off-by: Micky Ching 
---
 drivers/mmc/host/rtsx_pci_sdmmc.c | 203 +++---
 1 file changed, 100 insertions(+), 103 deletions(-)

diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c 
b/drivers/mmc/host/rtsx_pci_sdmmc.c
index 0217db6..26c6a7c 100644
--- a/drivers/mmc/host/rtsx_pci_sdmmc.c
+++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
@@ -71,9 +71,6 @@ static inline void sd_clear_error(struct realtek_pci_sdmmc 
*host)
SD_STOP | SD_CLR_ERR, SD_STOP | SD_CLR_ERR);
 }
 
-static void sd_send_cmd_get_rsp(struct realtek_pci_sdmmc *host,
-   struct mmc_command *cmd);
-
 #ifdef DEBUG
 static void dump_reg_range(struct realtek_pci_sdmmc *host, u16 start, u16 end)
 {
@@ -218,106 +215,6 @@ static void sdmmc_post_req(struct mmc_host *mmc, struct 
mmc_request *mrq,
data->host_cookie = 0;
 }
 
-static int sd_read_data(struct realtek_pci_sdmmc *host, struct mmc_command 
*cmd,
-   u16 byte_cnt, u8 *buf, int buf_len, int timeout)
-{
-   struct rtsx_pcr *pcr = host->pcr;
-   int err;
-   u8 trans_mode;
-
-   dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD %d, arg = 0x%08x\n",
-   __func__, cmd->opcode, cmd->arg);
-
-   if (!buf)
-   buf_len = 0;
-
-   if (cmd->opcode == MMC_SEND_TUNING_BLOCK)
-   trans_mode = SD_TM_AUTO_TUNING;
-   else
-   trans_mode = SD_TM_NORMAL_READ;
-
-   rtsx_pci_init_cmd(pcr);
-   sd_cmd_set_sd_cmd(pcr, cmd);
-   sd_cmd_set_data_len(pcr, 1, byte_cnt);
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG2, 0xFF,
-   SD_CALCULATE_CRC7 | SD_CHECK_CRC16 |
-   SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | SD_RSP_LEN_6);
-   if (trans_mode != SD_TM_AUTO_TUNING)
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
-   CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER);
-
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_TRANSFER,
-   0xFF, trans_mode | SD_TRANSFER_START);
-   rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, SD_TRANSFER,
-   SD_TRANSFER_END, SD_TRANSFER_END);
-
-   err = rtsx_pci_send_cmd(pcr, timeout);
-   if (err < 0) {
-   sd_print_debug_regs(host);
-   dev_dbg(sdmmc_dev(host),
-   "rtsx_pci_send_cmd fail (err = %d)\n", err);
-   return err;
-   }
-
-   if (buf && buf_len) {
-   err = rtsx_pci_read_ppbuf(pcr, buf, buf_len);
-   if (err < 0) {
-   dev_dbg(sdmmc_dev(host),
-   "rtsx_pci_read_ppbuf fail (err = %d)\n", err);
-   return err;
-   }
-   }
-
-   return 0;
-}
-
-static int sd_write_data(struct realtek_pci_sdmmc *host,
-   struct mmc_command *cmd, u16 byte_cnt, u8 *buf, int buf_len,
-   int timeout)
-{
-   struct rtsx_pcr *pcr = host->pcr;
-   int err;
-
-   dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD %d, arg = 0x%08x\n",
-   __func__, cmd->opcode, cmd->arg);
-
-   if (!buf)
-   buf_len = 0;
-
-   sd_send_cmd_get_rsp(host, cmd);
-   if (cmd->error)
-   return cmd->error;
-
-   if (buf && buf_len) {
-   err = rtsx_pci_write_ppbuf(pcr, buf, buf_len);
-   if (err < 0) {
-   dev_dbg(sdmmc_dev(host),
-   "rtsx_pci_write_ppbuf fail (err = %d)\n", err);
-   return err;
-   }
-   }
-
-   rtsx_pci_init_cmd(pcr);
-   sd_cmd_set_data_len(pcr, 1, byte_cnt);
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG2, 0xFF,
-   SD_CALCULATE_CRC7 | SD_CHECK_CRC16 |
-   SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | SD_RSP_LEN_0);
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_TRANSFER, 0xFF,
-   SD_TRANSFER_START | SD_TM_AUTO_WRITE_3);
-   rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, SD_TRANSFER,
-   SD_TRANSFER_END, SD_TRANSFER_END);
-
-   err = rtsx_pci_send_cmd(pcr, timeout);
-   if (err < 0) {
-   sd_print_debug_regs(host);
-   dev_dbg(sdmmc_dev(host),
-   "rtsx_pci_send_cmd fail (err = %d)\n", err);
-   return err;
-   }
-
-   return 0;
-}
-
 static void sd_send_cmd_get_rsp(struct realtek_pci_sdmmc *host,
struct mmc_command *cmd)
 {
@@ -436,6 +333,106 @@ out:
SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, 0);
 }
 
+static int sd_read_data(struct realtek_pci_sdmmc *host, struct mmc_command 
*cmd,
+   u16 byte_cnt, u8 *buf, int buf_len, int timeout)
+{
+   struct rtsx_pcr *pcr = host->pcr;
+   int err;
+   u8 trans_mode;
+
+   dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD %d, arg = 0x%08x\n",
+   __func__, cm

[PATCH v5 5/6] mmc: rtsx: add support for sdio card

2014-12-22 Thread micky_ching
From: Micky Ching 

Modify transfer mode for support sdio card,
send cmd and data at the same time for read data transfer,
but send data after cmd for write data transfer.

Signed-off-by: Micky Ching 
---
 drivers/mmc/host/rtsx_pci_sdmmc.c | 234 ++
 1 file changed, 138 insertions(+), 96 deletions(-)

diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c 
b/drivers/mmc/host/rtsx_pci_sdmmc.c
index b96c9ed..0217db6 100644
--- a/drivers/mmc/host/rtsx_pci_sdmmc.c
+++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
@@ -28,6 +28,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -70,6 +71,9 @@ static inline void sd_clear_error(struct realtek_pci_sdmmc 
*host)
SD_STOP | SD_CLR_ERR, SD_STOP | SD_CLR_ERR);
 }
 
+static void sd_send_cmd_get_rsp(struct realtek_pci_sdmmc *host,
+   struct mmc_command *cmd);
+
 #ifdef DEBUG
 static void dump_reg_range(struct realtek_pci_sdmmc *host, u16 start, u16 end)
 {
@@ -214,34 +218,27 @@ static void sdmmc_post_req(struct mmc_host *mmc, struct 
mmc_request *mrq,
data->host_cookie = 0;
 }
 
-static int sd_read_data(struct realtek_pci_sdmmc *host, u8 *cmd, u16 byte_cnt,
-   u8 *buf, int buf_len, int timeout)
+static int sd_read_data(struct realtek_pci_sdmmc *host, struct mmc_command 
*cmd,
+   u16 byte_cnt, u8 *buf, int buf_len, int timeout)
 {
struct rtsx_pcr *pcr = host->pcr;
-   int err, i;
+   int err;
u8 trans_mode;
 
-   dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD%d\n", __func__, cmd[0] - 0x40);
+   dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD %d, arg = 0x%08x\n",
+   __func__, cmd->opcode, cmd->arg);
 
if (!buf)
buf_len = 0;
 
-   if ((cmd[0] & 0x3F) == MMC_SEND_TUNING_BLOCK)
+   if (cmd->opcode == MMC_SEND_TUNING_BLOCK)
trans_mode = SD_TM_AUTO_TUNING;
else
trans_mode = SD_TM_NORMAL_READ;
 
rtsx_pci_init_cmd(pcr);
-
-   for (i = 0; i < 5; i++)
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD0 + i, 0xFF, cmd[i]);
-
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, (u8)byte_cnt);
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_H,
-   0xFF, (u8)(byte_cnt >> 8));
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_L, 0xFF, 1);
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_H, 0xFF, 0);
-
+   sd_cmd_set_sd_cmd(pcr, cmd);
+   sd_cmd_set_data_len(pcr, 1, byte_cnt);
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG2, 0xFF,
SD_CALCULATE_CRC7 | SD_CHECK_CRC16 |
SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | SD_RSP_LEN_6);
@@ -274,16 +271,23 @@ static int sd_read_data(struct realtek_pci_sdmmc *host, 
u8 *cmd, u16 byte_cnt,
return 0;
 }
 
-static int sd_write_data(struct realtek_pci_sdmmc *host, u8 *cmd, u16 byte_cnt,
-   u8 *buf, int buf_len, int timeout)
+static int sd_write_data(struct realtek_pci_sdmmc *host,
+   struct mmc_command *cmd, u16 byte_cnt, u8 *buf, int buf_len,
+   int timeout)
 {
struct rtsx_pcr *pcr = host->pcr;
-   int err, i;
-   u8 trans_mode;
+   int err;
+
+   dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD %d, arg = 0x%08x\n",
+   __func__, cmd->opcode, cmd->arg);
 
if (!buf)
buf_len = 0;
 
+   sd_send_cmd_get_rsp(host, cmd);
+   if (cmd->error)
+   return cmd->error;
+
if (buf && buf_len) {
err = rtsx_pci_write_ppbuf(pcr, buf, buf_len);
if (err < 0) {
@@ -293,30 +297,13 @@ static int sd_write_data(struct realtek_pci_sdmmc *host, 
u8 *cmd, u16 byte_cnt,
}
}
 
-   trans_mode = cmd ? SD_TM_AUTO_WRITE_2 : SD_TM_AUTO_WRITE_3;
rtsx_pci_init_cmd(pcr);
-
-   if (cmd) {
-   dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD %d\n", __func__,
-   cmd[0] - 0x40);
-
-   for (i = 0; i < 5; i++)
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
-   SD_CMD0 + i, 0xFF, cmd[i]);
-   }
-
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, (u8)byte_cnt);
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_H,
-   0xFF, (u8)(byte_cnt >> 8));
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_L, 0xFF, 1);
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_H, 0xFF, 0);
-
+   sd_cmd_set_data_len(pcr, 1, byte_cnt);
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG2, 0xFF,
SD_CALCULATE_CRC7 | SD_CHECK_CRC16 |
-   SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | SD_RSP_LEN_6);
-
+   SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | SD_RSP_LEN_0);
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_TRANSFER, 0xFF,
-   trans_mode | SD_TRANSFER_START);
+   SD_TRANSFER_START | 

[PATCH v5 4/6] mmc: rtsx: add helper function to simplify code

2014-12-22 Thread micky_ching
From: Micky Ching 

To support sdio card, transfer mode need make a change,
this need to split code and use it in different place,
Add new function to simplify repeat operation.

Signed-off-by: Micky Ching 
---
 drivers/mmc/host/rtsx_pci_sdmmc.c | 95 +--
 1 file changed, 51 insertions(+), 44 deletions(-)

diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c 
b/drivers/mmc/host/rtsx_pci_sdmmc.c
index 90b7b6d..b96c9ed 100644
--- a/drivers/mmc/host/rtsx_pci_sdmmc.c
+++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
@@ -99,6 +99,50 @@ static void sd_print_debug_regs(struct realtek_pci_sdmmc 
*host)
 #define sd_print_debug_regs(host)
 #endif /* DEBUG */
 
+static void sd_cmd_set_sd_cmd(struct rtsx_pcr *pcr, struct mmc_command *cmd)
+{
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD0, 0xFF,
+   SD_CMD_START | cmd->opcode);
+   rtsx_pci_write_be32(pcr, SD_CMD1, cmd->arg);
+}
+
+static void sd_cmd_set_data_len(struct rtsx_pcr *pcr, u16 blocks, u16 blksz)
+{
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_L, 0xFF, blocks);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_H, 0xFF, blocks >> 8);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, blksz);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_H, 0xFF, blksz >> 8);
+}
+
+static int sd_response_type(struct mmc_command *cmd)
+{
+   switch (mmc_resp_type(cmd)) {
+   case MMC_RSP_NONE:
+   return SD_RSP_TYPE_R0;
+   case MMC_RSP_R1:
+   return SD_RSP_TYPE_R1;
+   case MMC_RSP_R1 & ~MMC_RSP_CRC:
+   return SD_RSP_TYPE_R1 | SD_NO_CHECK_CRC7;
+   case MMC_RSP_R1B:
+   return SD_RSP_TYPE_R1b;
+   case MMC_RSP_R2:
+   return SD_RSP_TYPE_R2;
+   case MMC_RSP_R3:
+   return SD_RSP_TYPE_R3;
+   default:
+   return -EINVAL;
+   }
+}
+
+static int sd_status_index(int resp_type)
+{
+   if (resp_type == SD_RSP_TYPE_R0)
+   return 0;
+   else if (resp_type == SD_RSP_TYPE_R2)
+   return 16;
+
+   return 5;
+}
 /*
  * sd_pre_dma_transfer - do dma_map_sg() or using cookie
  *
@@ -297,47 +341,18 @@ static void sd_send_cmd_get_rsp(struct realtek_pci_sdmmc 
*host,
int timeout = 100;
int i;
u8 *ptr;
-   int stat_idx = 0;
-   u8 rsp_type;
-   int rsp_len = 5;
+   int rsp_type;
+   int stat_idx;
bool clock_toggled = false;
 
dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD %d, arg = 0x%08x\n",
__func__, cmd_idx, arg);
 
-   /* Response type:
-* R0
-* R1, R5, R6, R7
-* R1b
-* R2
-* R3, R4
-*/
-   switch (mmc_resp_type(cmd)) {
-   case MMC_RSP_NONE:
-   rsp_type = SD_RSP_TYPE_R0;
-   rsp_len = 0;
-   break;
-   case MMC_RSP_R1:
-   rsp_type = SD_RSP_TYPE_R1;
-   break;
-   case MMC_RSP_R1 & ~MMC_RSP_CRC:
-   rsp_type = SD_RSP_TYPE_R1 | SD_NO_CHECK_CRC7;
-   break;
-   case MMC_RSP_R1B:
-   rsp_type = SD_RSP_TYPE_R1b;
-   break;
-   case MMC_RSP_R2:
-   rsp_type = SD_RSP_TYPE_R2;
-   rsp_len = 16;
-   break;
-   case MMC_RSP_R3:
-   rsp_type = SD_RSP_TYPE_R3;
-   break;
-   default:
-   dev_dbg(sdmmc_dev(host), "cmd->flag is not valid\n");
-   err = -EINVAL;
+   rsp_type = sd_response_type(cmd);
+   if (rsp_type < 0)
goto out;
-   }
+
+   stat_idx = sd_status_index(rsp_type);
 
if (rsp_type == SD_RSP_TYPE_R1b)
timeout = 3000;
@@ -352,13 +367,7 @@ static void sd_send_cmd_get_rsp(struct realtek_pci_sdmmc 
*host,
}
 
rtsx_pci_init_cmd(pcr);
-
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD0, 0xFF, 0x40 | cmd_idx);
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD1, 0xFF, (u8)(arg >> 24));
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD2, 0xFF, (u8)(arg >> 16));
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD3, 0xFF, (u8)(arg >> 8));
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD4, 0xFF, (u8)arg);
-
+   sd_cmd_set_sd_cmd(pcr, cmd);
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG2, 0xFF, rsp_type);
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_DATA_SOURCE,
0x01, PINGPONG_BUFFER);
@@ -372,12 +381,10 @@ static void sd_send_cmd_get_rsp(struct realtek_pci_sdmmc 
*host,
/* Read data from ping-pong buffer */
for (i = PPBUF_BASE2; i < PPBUF_BASE2 + 16; i++)
rtsx_pci_add_cmd(pcr, READ_REG_CMD, (u16)i, 0, 0);
-   stat_idx = 16;
} else if (rsp_type != SD_RSP_TYPE_R0) {
/* Read data from SD_CMDx registers */
for (i = SD_CMD0; i <= SD_CMD4; i++)
rtsx_pci_add_cmd(pcr, READ_

[PATCH 1/3] memstick: rtsx: dump register using compact format

2015-01-13 Thread micky_ching
From: Micky Ching 

Using more compact format for dump register when error occurs,
this is useful to read debug log and reduce log length.

Signed-off-by: Micky Ching 
---
 drivers/memstick/host/rtsx_pci_ms.c | 37 -
 1 file changed, 20 insertions(+), 17 deletions(-)

diff --git a/drivers/memstick/host/rtsx_pci_ms.c 
b/drivers/memstick/host/rtsx_pci_ms.c
index 818fa94..baf94db 100644
--- a/drivers/memstick/host/rtsx_pci_ms.c
+++ b/drivers/memstick/host/rtsx_pci_ms.c
@@ -54,26 +54,29 @@ static inline void ms_clear_error(struct realtek_pci_ms 
*host)
 }
 
 #ifdef DEBUG
+static void dump_reg_range(struct realtek_pci_ms *host, u16 start, u16 end)
+{
+   u16 len = end - start + 1;
+   int i;
+   u8 data[8];
+
+   for (i = 0; i < len; i += 8) {
+   int j;
+   int n = min(8, len - i);
+
+   memset(&data, 0, sizeof(data));
+   for (j = 0; j < n; j++)
+   rtsx_pci_read_register(host->pcr, start + i + j,
+   data + j);
+   dev_dbg(ms_dev(host), "0x%04X(%d): %8ph\n",
+   start + i, n, data);
+   }
+}
 
 static void ms_print_debug_regs(struct realtek_pci_ms *host)
 {
-   struct rtsx_pcr *pcr = host->pcr;
-   u16 i;
-   u8 *ptr;
-
-   /* Print MS host internal registers */
-   rtsx_pci_init_cmd(pcr);
-   for (i = 0xFD40; i <= 0xFD44; i++)
-   rtsx_pci_add_cmd(pcr, READ_REG_CMD, i, 0, 0);
-   for (i = 0xFD52; i <= 0xFD69; i++)
-   rtsx_pci_add_cmd(pcr, READ_REG_CMD, i, 0, 0);
-   rtsx_pci_send_cmd(pcr, 100);
-
-   ptr = rtsx_pci_get_cmd_data(pcr);
-   for (i = 0xFD40; i <= 0xFD44; i++)
-   dev_dbg(ms_dev(host), "0x%04X: 0x%02x\n", i, *(ptr++));
-   for (i = 0xFD52; i <= 0xFD69; i++)
-   dev_dbg(ms_dev(host), "0x%04X: 0x%02x\n", i, *(ptr++));
+   dump_reg_range(host, 0xFD40, 0xFD44);
+   dump_reg_range(host, 0xFD52, 0xFD69);
 }
 
 #else
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 3/3] memstick: rtsx: move suspend/resume to pm ops

2015-01-13 Thread micky_ching
From: Micky Ching 

Move suspend/resume function to pm ops, make it consistence
with rtsx_usb_ms.c driver.

Signed-off-by: Micky Ching 
---
 drivers/memstick/host/rtsx_pci_ms.c | 25 +++--
 1 file changed, 11 insertions(+), 14 deletions(-)

diff --git a/drivers/memstick/host/rtsx_pci_ms.c 
b/drivers/memstick/host/rtsx_pci_ms.c
index c9981af..475afa8 100644
--- a/drivers/memstick/host/rtsx_pci_ms.c
+++ b/drivers/memstick/host/rtsx_pci_ms.c
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -514,11 +515,11 @@ static int rtsx_pci_ms_set_param(struct memstick_host 
*msh,
return 0;
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 
-static int rtsx_pci_ms_suspend(struct platform_device *pdev, pm_message_t 
state)
+static int rtsx_pci_ms_suspend(struct device *dev)
 {
-   struct realtek_pci_ms *host = platform_get_drvdata(pdev);
+   struct realtek_pci_ms *host = dev_get_drvdata(dev);
struct memstick_host *msh = host->msh;
 
dev_dbg(ms_dev(host), "--> %s\n", __func__);
@@ -527,9 +528,9 @@ static int rtsx_pci_ms_suspend(struct platform_device 
*pdev, pm_message_t state)
return 0;
 }
 
-static int rtsx_pci_ms_resume(struct platform_device *pdev)
+static int rtsx_pci_ms_resume(struct device *dev)
 {
-   struct realtek_pci_ms *host = platform_get_drvdata(pdev);
+   struct realtek_pci_ms *host = dev_get_drvdata(dev);
struct memstick_host *msh = host->msh;
 
dev_dbg(ms_dev(host), "--> %s\n", __func__);
@@ -537,13 +538,7 @@ static int rtsx_pci_ms_resume(struct platform_device *pdev)
memstick_resume_host(msh);
return 0;
 }
-
-#else /* CONFIG_PM */
-
-#define rtsx_pci_ms_suspend NULL
-#define rtsx_pci_ms_resume NULL
-
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
 
 static void rtsx_pci_ms_card_event(struct platform_device *pdev)
 {
@@ -641,6 +636,9 @@ static int rtsx_pci_ms_drv_remove(struct platform_device 
*pdev)
return 0;
 }
 
+static SIMPLE_DEV_PM_OPS(rtsx_pci_ms_pm_ops,
+   rtsx_pci_ms_suspend, rtsx_pci_ms_resume);
+
 static struct platform_device_id rtsx_pci_ms_ids[] = {
{
.name = DRV_NAME_RTSX_PCI_MS,
@@ -654,10 +652,9 @@ static struct platform_driver rtsx_pci_ms_driver = {
.probe  = rtsx_pci_ms_drv_probe,
.remove = rtsx_pci_ms_drv_remove,
.id_table   = rtsx_pci_ms_ids,
-   .suspend= rtsx_pci_ms_suspend,
-   .resume = rtsx_pci_ms_resume,
.driver = {
.name   = DRV_NAME_RTSX_PCI_MS,
+   .pm = &rtsx_pci_ms_pm_ops,
},
 };
 module_platform_driver(rtsx_pci_ms_driver);
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 2/3] memstick: rtsx: finish request if no card exist

2015-01-13 Thread micky_ching
From: Micky Ching 

Check card exist before start request, this method can make card remove
faster. If we found the card is not exist, just return error-code,
not sending request can save much time.

Signed-off-by: Micky Ching 
---
 drivers/memstick/host/rtsx_pci_ms.c | 27 ++-
 1 file changed, 18 insertions(+), 9 deletions(-)

diff --git a/drivers/memstick/host/rtsx_pci_ms.c 
b/drivers/memstick/host/rtsx_pci_ms.c
index baf94db..c9981af 100644
--- a/drivers/memstick/host/rtsx_pci_ms.c
+++ b/drivers/memstick/host/rtsx_pci_ms.c
@@ -85,6 +85,11 @@ static void ms_print_debug_regs(struct realtek_pci_ms *host)
 
 #endif
 
+static inline int ms_get_cd_int(struct realtek_pci_ms *host)
+{
+   return rtsx_pci_readl(host->pcr, RTSX_BIPR) & MS_EXIST;
+}
+
 static int ms_power_on(struct realtek_pci_ms *host)
 {
struct rtsx_pcr *pcr = host->pcr;
@@ -409,6 +414,9 @@ static void rtsx_pci_ms_handle_req(struct work_struct *work)
struct memstick_host *msh = host->msh;
int rc;
 
+   if (host->req)
+   return;
+
mutex_lock(&pcr->pcr_mutex);
 
rtsx_pci_start_run(pcr);
@@ -419,15 +427,16 @@ static void rtsx_pci_ms_handle_req(struct work_struct 
*work)
rtsx_pci_write_register(pcr, CARD_SHARE_MODE,
CARD_SHARE_MASK, CARD_SHARE_48_MS);
 
-   if (!host->req) {
-   do {
-   rc = memstick_next_req(msh, &host->req);
-   dev_dbg(ms_dev(host), "next req %d\n", rc);
-
-   if (!rc)
-   host->req->error = rtsx_pci_ms_issue_cmd(host);
-   } while (!rc);
-   }
+   while (true) {
+   rc = memstick_next_req(msh, &host->req);
+   dev_dbg(ms_dev(host), "next req %d\n", rc);
+   if (rc)
+   break;
+   if (!ms_get_cd_int(host))
+   host->req->error = -ENOMEDIUM;
+   else
+   host->req->error = rtsx_pci_ms_issue_cmd(host);
+   };
 
mutex_unlock(&pcr->pcr_mutex);
 }
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 0/3] memstick: rtsx: finish request faster if no card exist

2015-01-13 Thread micky_ching
From: Micky Ching 

This pathset include some misc coding update.
- dump register using compact format.
  This prevent dump a lot of lines register dump when some error occurs.

- finish request if no card exist
  check card exist before sending any request, When card removed,
  request can returned much faster.

- move suspend/resume to pm ops
  Move suspend/resume pm ops instead of driver.suspend/drivers.resume,
  we tested in some case if we put it in driver.suspend/drivers.resume,
  the function will not called.

Micky Ching (3):
  memstick: rtsx: dump register using compact format
  memstick: rtsx: finish request if no card exist
  memstick: rtsx: move suspend/resume to pm ops

 drivers/memstick/host/rtsx_pci_ms.c | 89 -
 1 file changed, 49 insertions(+), 40 deletions(-)

-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 0/2] mmc: rtsx: add check before sending request

2015-01-13 Thread micky_ching
From: Micky Ching 

Add check before sending request can make request return faster.
- finish request if no card exist
  This can make request finish faster, especial for some sdio card,
  when card removed, there still a lot of command pending,
  if we check card exist and stop request, the card will disappear
  faster in user space.

- check sg_count before long data xfer
  modify sg_count type unsigned -> int, because dma_map_sg() return
  int, and this value can be negative to indicate some error occurs.

Micky Ching (2):
  mmc: rtsx: finish request if no card exist
  mmc: rtsx: check sg_count before long data xfer

 drivers/mmc/host/rtsx_pci_sdmmc.c | 20 
 1 file changed, 16 insertions(+), 4 deletions(-)

-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 1/2] mmc: rtsx: finish request if no card exist

2015-01-13 Thread micky_ching
From: Micky Ching 

Return error-code directly if no card exist, this can
make card remove faster.

Signed-off-by: Micky Ching 
---
 drivers/mmc/host/rtsx_pci_sdmmc.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c 
b/drivers/mmc/host/rtsx_pci_sdmmc.c
index 26c6a7c..b435806 100644
--- a/drivers/mmc/host/rtsx_pci_sdmmc.c
+++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
@@ -100,6 +100,11 @@ static void sd_print_debug_regs(struct realtek_pci_sdmmc 
*host)
 #define sd_print_debug_regs(host)
 #endif /* DEBUG */
 
+static inline int sd_get_cd_int(struct realtek_pci_sdmmc *host)
+{
+   return rtsx_pci_readl(host->pcr, RTSX_BIPR) & SD_EXIST;
+}
+
 static void sd_cmd_set_sd_cmd(struct rtsx_pcr *pcr, struct mmc_command *cmd)
 {
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD0, 0xFF,
@@ -798,7 +803,7 @@ static void sd_request(struct work_struct *work)
unsigned int data_size = 0;
int err;
 
-   if (host->eject) {
+   if (host->eject || !sd_get_cd_int(host)) {
cmd->error = -ENOMEDIUM;
goto finish;
}
@@ -1116,7 +1121,7 @@ static int sdmmc_get_cd(struct mmc_host *mmc)
u32 val;
 
if (host->eject)
-   return -ENOMEDIUM;
+   return cd;
 
mutex_lock(&pcr->pcr_mutex);
 
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 2/2] mmc: rtsx: check sg_count before long data xfer

2015-01-13 Thread micky_ching
From: Micky Ching 

Check sg_count before sending long data xfer.
Because dma_map_sg() return int, and sg_count may be negative,
so using int instead of unsigned.

Signed-off-by: Micky Ching 
---
 drivers/mmc/host/rtsx_pci_sdmmc.c | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c 
b/drivers/mmc/host/rtsx_pci_sdmmc.c
index b435806..1d3d6c4 100644
--- a/drivers/mmc/host/rtsx_pci_sdmmc.c
+++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
@@ -54,9 +54,9 @@ struct realtek_pci_sdmmc {
 #define SDMMC_POWER_ON 1
 #define SDMMC_POWER_OFF0
 
-   unsigned intsg_count;
+   int sg_count;
s32 cookie;
-   unsigned intcookie_sg_count;
+   int cookie_sg_count;
boolusing_cookie;
 };
 
@@ -557,6 +557,13 @@ static int sd_rw_multi(struct realtek_pci_sdmmc *host, 
struct mmc_request *mrq)
 {
struct mmc_data *data = mrq->data;
 
+   if (host->sg_count < 0) {
+   data->error = host->sg_count;
+   dev_dbg(sdmmc_dev(host), "%s: sg_count = %d is invalid\n",
+   __func__, host->sg_count);
+   return data->error;
+   }
+
if (data->flags & MMC_DATA_READ)
return sd_read_long_data(host, mrq);
 
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 01/10] mfd: rtsx: replace TAB by SPC after #define

2015-01-15 Thread micky_ching
From: Micky Ching 

Re-format coding-style, using uniform SPC after "#define" keyword
instead of mixing using TAB and SPC.

Signed-off-by: Micky Ching 
---
 include/linux/mfd/rtsx_pci.h | 254 +--
 1 file changed, 127 insertions(+), 127 deletions(-)

diff --git a/include/linux/mfd/rtsx_pci.h b/include/linux/mfd/rtsx_pci.h
index 0c12628..a9c2a14 100644
--- a/include/linux/mfd/rtsx_pci.h
+++ b/include/linux/mfd/rtsx_pci.h
@@ -175,9 +175,9 @@
 /* CARD_SHARE_MODE */
 #define CARD_SHARE_MASK0x0F
 #define CARD_SHARE_MULTI_LUN   0x00
-#defineCARD_SHARE_NORMAL   0x00
-#defineCARD_SHARE_48_SD0x04
-#defineCARD_SHARE_48_MS0x08
+#define CARD_SHARE_NORMAL  0x00
+#define CARD_SHARE_48_SD   0x04
+#define CARD_SHARE_48_MS   0x08
 /* CARD_SHARE_MODE for barossa */
 #define CARD_SHARE_BAROSSA_SD  0x01
 #define CARD_SHARE_BAROSSA_MS  0x02
@@ -249,76 +249,76 @@
 #define CD_AUTO_DISABLE0x40
 
 /* SD_STAT1 */
-#defineSD_CRC7_ERR 0x80
-#defineSD_CRC16_ERR0x40
-#defineSD_CRC_WRITE_ERR0x20
-#defineSD_CRC_WRITE_ERR_MASK   0x1C
-#defineGET_CRC_TIME_OUT0x02
-#defineSD_TUNING_COMPARE_ERR   0x01
+#define SD_CRC7_ERR0x80
+#define SD_CRC16_ERR   0x40
+#define SD_CRC_WRITE_ERR   0x20
+#define SD_CRC_WRITE_ERR_MASK  0x1C
+#define GET_CRC_TIME_OUT   0x02
+#define SD_TUNING_COMPARE_ERR  0x01
 
 /* SD_STAT2 */
-#defineSD_RSP_80CLK_TIMEOUT0x01
+#define SD_RSP_80CLK_TIMEOUT   0x01
 
 /* SD_BUS_STAT */
-#defineSD_CLK_TOGGLE_EN0x80
-#defineSD_CLK_FORCE_STOP   0x40
-#defineSD_DAT3_STATUS  0x10
-#defineSD_DAT2_STATUS  0x08
-#defineSD_DAT1_STATUS  0x04
-#defineSD_DAT0_STATUS  0x02
-#defineSD_CMD_STATUS   0x01
+#define SD_CLK_TOGGLE_EN   0x80
+#define SD_CLK_FORCE_STOP  0x40
+#define SD_DAT3_STATUS 0x10
+#define SD_DAT2_STATUS 0x08
+#define SD_DAT1_STATUS 0x04
+#define SD_DAT0_STATUS 0x02
+#define SD_CMD_STATUS  0x01
 
 /* SD_PAD_CTL */
-#defineSD_IO_USING_1V8 0x80
-#defineSD_IO_USING_3V3 0x7F
-#defineTYPE_A_DRIVING  0x00
-#defineTYPE_B_DRIVING  0x01
-#defineTYPE_C_DRIVING  0x02
-#defineTYPE_D_DRIVING  0x03
+#define SD_IO_USING_1V80x80
+#define SD_IO_USING_3V30x7F
+#define TYPE_A_DRIVING 0x00
+#define TYPE_B_DRIVING 0x01
+#define TYPE_C_DRIVING 0x02
+#define TYPE_D_DRIVING 0x03
 
 /* SD_SAMPLE_POINT_CTL */
-#defineDDR_FIX_RX_DAT  0x00
-#defineDDR_VAR_RX_DAT  0x80
-#defineDDR_FIX_RX_DAT_EDGE 0x00
-#defineDDR_FIX_RX_DAT_14_DELAY 0x40
-#defineDDR_FIX_RX_CMD  0x00
-#defineDDR_VAR_RX_CMD  0x20
-#defineDDR_FIX_RX_CMD_POS_EDGE 0x00
-#defineDDR_FIX_RX_CMD_14_DELAY 0x10
-#defineSD20_RX_POS_EDGE0x00
-#defineSD20_RX_14_DELAY0x08
+#define DDR_FIX_RX_DAT 0x00
+#define DDR_VAR_RX_DAT 0x80
+#define DDR_FIX_RX_DAT_EDGE0x00
+#define DDR_FIX_RX_DAT_14_DELAY0x40
+#define DDR_FIX_RX_CMD 0x00
+#define DDR_VAR_RX_CMD 0x20
+#define DDR_FIX_RX_CMD_POS_EDGE0x00
+#define DDR_FIX_RX_CMD_14_DELAY0x10
+#define SD20_RX_POS_EDGE   0x00
+#define SD20_RX_14_DELAY   0x08
 #define SD20_RX_SEL_MASK   0x08
 
 /* SD_PUSH_POINT_CTL */
-#defineDDR_FIX_TX_CMD_DAT  0x00
-#defineDDR_VAR_TX_CMD_DAT  0x80
-#defineDDR_FIX_TX_DAT_14_TSU   0x00
-#defineDDR_FIX_TX_DAT_12_TSU   0x40
-#defineDDR_FIX_TX_CMD_NEG_EDGE 0x00
-#defineDDR_FIX_TX_CMD_14_AHEAD 0x20
-#defineSD20_TX_NEG_EDGE0x00
-#defineSD20_TX_14_AHEAD0x10
+#define DDR_FIX_TX_CMD_DAT 0x00
+#define DDR_VAR_TX_CMD_DAT 0x80
+#define DDR_FIX_TX_DAT_14_TSU  0x00
+#define DDR_FIX_TX_DAT_12_TSU  0x40
+#define DDR_FIX_TX_CMD_NEG_EDGE0x00
+#define DDR_FIX_TX_CMD_14_AHEAD0x20
+#define SD20_TX_NEG_EDGE

[PATCH 05/10] mfd: rtsx: update driving settings

2015-01-15 Thread micky_ching
From: Micky Ching 

update card drive settings, This setting can be used for rts5249
rts524A and rts525A.

Signed-off-by: Micky Ching 
---
 drivers/mfd/rts5249.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/mfd/rts5249.c b/drivers/mfd/rts5249.c
index 225ad55..2fe2854 100644
--- a/drivers/mfd/rts5249.c
+++ b/drivers/mfd/rts5249.c
@@ -36,16 +36,16 @@ static u8 rts5249_get_ic_version(struct rtsx_pcr *pcr)
 static void rts5249_fill_driving(struct rtsx_pcr *pcr, u8 voltage)
 {
u8 driving_3v3[4][3] = {
-   {0x11, 0x11, 0x11},
+   {0x11, 0x11, 0x18},
{0x55, 0x55, 0x5C},
-   {0x99, 0x99, 0x92},
-   {0x99, 0x99, 0x92},
+   {0xFF, 0xFF, 0xFF},
+   {0x96, 0x96, 0x96},
};
u8 driving_1v8[4][3] = {
+   {0xC4, 0xC4, 0xC4},
{0x3C, 0x3C, 0x3C},
-   {0xB3, 0xB3, 0xB3},
{0xFE, 0xFE, 0xFE},
-   {0xC4, 0xC4, 0xC4},
+   {0xB3, 0xB3, 0xB3},
};
u8 (*driving)[3], drive_sel;
 
@@ -341,7 +341,7 @@ void rts5249_init_params(struct rtsx_pcr *pcr)
 
pcr->flags = 0;
pcr->card_drive_sel = RTSX_CARD_DRIVE_DEFAULT;
-   pcr->sd30_drive_sel_1v8 = CFG_DRIVER_TYPE_C;
+   pcr->sd30_drive_sel_1v8 = CFG_DRIVER_TYPE_B;
pcr->sd30_drive_sel_3v3 = CFG_DRIVER_TYPE_B;
pcr->aspm_en = ASPM_L1_EN;
pcr->tx_initial_phase = SET_CLOCK_PHASE(1, 29, 16);
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 06/10] mfd: rtsx: update phy register

2015-01-15 Thread micky_ching
From: Micky Ching 

update phy register value and using direct value instead of macros.
It is much easier to debug using constant value than a lot of macros.
We usually need compare the value directly to check the configure.

Signed-off-by: Micky Ching 
---
 drivers/mfd/rts5249.c | 46 ++
 1 file changed, 14 insertions(+), 32 deletions(-)

diff --git a/drivers/mfd/rts5249.c b/drivers/mfd/rts5249.c
index 2fe2854..00208d1 100644
--- a/drivers/mfd/rts5249.c
+++ b/drivers/mfd/rts5249.c
@@ -132,57 +132,39 @@ static int rts5249_optimize_phy(struct rtsx_pcr *pcr)
if (err < 0)
return err;
 
-   err = rtsx_pci_write_phy_register(pcr, PHY_REG_REV,
-   PHY_REG_REV_RESV | PHY_REG_REV_RXIDLE_LATCHED |
-   PHY_REG_REV_P1_EN | PHY_REG_REV_RXIDLE_EN |
-   PHY_REG_REV_RX_PWST | PHY_REG_REV_CLKREQ_DLY_TIMER_1_0 |
-   PHY_REG_REV_STOP_CLKRD | PHY_REG_REV_STOP_CLKWR);
+   err = rtsx_pci_write_phy_register(pcr, 0x19, 0xFE6C);
if (err < 0)
return err;
 
msleep(1);
 
-   err = rtsx_pci_write_phy_register(pcr, PHY_BPCR,
-   PHY_BPCR_IBRXSEL | PHY_BPCR_IBTXSEL |
-   PHY_BPCR_IB_FILTER | PHY_BPCR_CMIRROR_EN);
+   err = rtsx_pci_write_phy_register(pcr, 0x0A, 0x05C0);
if (err < 0)
return err;
-   err = rtsx_pci_write_phy_register(pcr, PHY_PCR,
-   PHY_PCR_FORCE_CODE | PHY_PCR_OOBS_CALI_50 |
-   PHY_PCR_OOBS_VCM_08 | PHY_PCR_OOBS_SEN_90 |
-   PHY_PCR_RSSI_EN);
+
+   err = rtsx_pci_write_phy_register(pcr, 0x00, 0xBA43);
+   if (err < 0)
+   return err;
+   err = rtsx_pci_write_phy_register(pcr, 0x03, 0xC152);
if (err < 0)
return err;
-   err = rtsx_pci_write_phy_register(pcr, PHY_RCR2,
-   PHY_RCR2_EMPHASE_EN | PHY_RCR2_NADJR |
-   PHY_RCR2_CDR_CP_10 | PHY_RCR2_CDR_SR_2 |
-   PHY_RCR2_FREQSEL_12 | PHY_RCR2_CPADJEN |
-   PHY_RCR2_CDR_SC_8 | PHY_RCR2_CALIB_LATE);
+   err = rtsx_pci_write_phy_register(pcr, 0x1E, 0x78EB);
if (err < 0)
return err;
-   err = rtsx_pci_write_phy_register(pcr, PHY_FLD4,
-   PHY_FLD4_FLDEN_SEL | PHY_FLD4_REQ_REF |
-   PHY_FLD4_RXAMP_OFF | PHY_FLD4_REQ_ADDA |
-   PHY_FLD4_BER_COUNT | PHY_FLD4_BER_TIMER |
-   PHY_FLD4_BER_CHK_EN);
+   err = rtsx_pci_write_phy_register(pcr, 0x05, 0x4600);
if (err < 0)
return err;
-   err = rtsx_pci_write_phy_register(pcr, PHY_RDR, PHY_RDR_RXDSEL_1_9);
+   err = rtsx_pci_write_phy_register(pcr, 0x02, 0x041F);
if (err < 0)
return err;
-   err = rtsx_pci_write_phy_register(pcr, PHY_RCR1,
-   PHY_RCR1_ADP_TIME | PHY_RCR1_VCO_COARSE);
+   err = rtsx_pci_write_phy_register(pcr, 0x1D, 0x0824);
if (err < 0)
return err;
-   err = rtsx_pci_write_phy_register(pcr, PHY_FLD3,
-   PHY_FLD3_TIMER_4 | PHY_FLD3_TIMER_6 |
-   PHY_FLD3_RXDELINK);
+   err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4FE4);
if (err < 0)
return err;
-   return rtsx_pci_write_phy_register(pcr, PHY_TUNE,
-   PHY_TUNE_TUNEREF_1_0 | PHY_TUNE_VBGSEL_1252 |
-   PHY_TUNE_SDBUS_33 | PHY_TUNE_TUNED18 |
-   PHY_TUNE_TUNED12);
+
+   return 0;
 }
 
 static int rts5249_turn_on_led(struct rtsx_pcr *pcr)
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 02/10] mfd: rtsx: place register address and values togather

2015-01-15 Thread micky_ching
From: Micky Ching 

It is more readable to place register address and values define
togather. The values define add two leading space indicate belong
to the register address defined above.

Signed-off-by: Micky Ching 
---
 include/linux/mfd/rtsx_pci.h | 836 +++
 1 file changed, 369 insertions(+), 467 deletions(-)

diff --git a/include/linux/mfd/rtsx_pci.h b/include/linux/mfd/rtsx_pci.h
index a9c2a14..e81f2bb 100644
--- a/include/linux/mfd/rtsx_pci.h
+++ b/include/linux/mfd/rtsx_pci.h
@@ -28,74 +28,72 @@
 
 #define MAX_RW_REG_CNT 1024
 
-/* PCI Operation Register Address */
 #define RTSX_HCBAR 0x00
 #define RTSX_HCBCTLR   0x04
+#define   STOP_CMD (0x01 << 28)
+#define   READ_REG_CMD 0
+#define   WRITE_REG_CMD1
+#define   CHECK_REG_CMD2
+
 #define RTSX_HDBAR 0x08
+#define   SG_INT   0x04
+#define   SG_END   0x02
+#define   SG_VALID 0x01
+#define   SG_NO_OP 0x00
+#define   SG_TRANS_DATA(0x02 << 4)
+#define   SG_LINK_DESC (0x03 << 4)
 #define RTSX_HDBCTLR   0x0C
+#define   SDMA_MODE0x00
+#define   ADMA_MODE(0x02 << 26)
+#define   STOP_DMA (0x01 << 28)
+#define   TRIG_DMA (0x01 << 31)
+
 #define RTSX_HAIMR 0x10
-#define RTSX_BIPR  0x14
-#define RTSX_BIER  0x18
+#define   HAIMR_TRANS_START(0x01 << 31)
+#define   HAIMR_READ   0x00
+#define   HAIMR_WRITE  (0x01 << 30)
+#define   HAIMR_READ_START (HAIMR_TRANS_START | HAIMR_READ)
+#define   HAIMR_WRITE_START(HAIMR_TRANS_START | HAIMR_WRITE)
+#define   HAIMR_TRANS_END  (HAIMR_TRANS_START)
 
-/* Host command buffer control register */
-#define STOP_CMD   (0x01 << 28)
-
-/* Host data buffer control register */
-#define SDMA_MODE  0x00
-#define ADMA_MODE  (0x02 << 26)
-#define STOP_DMA   (0x01 << 28)
-#define TRIG_DMA   (0x01 << 31)
-
-/* Host access internal memory register */
-#define HAIMR_TRANS_START  (0x01 << 31)
-#define HAIMR_READ 0x00
-#define HAIMR_WRITE(0x01 << 30)
-#define HAIMR_READ_START   (HAIMR_TRANS_START | HAIMR_READ)
-#define HAIMR_WRITE_START  (HAIMR_TRANS_START | HAIMR_WRITE)
-#define HAIMR_TRANS_END(HAIMR_TRANS_START)
-
-/* Bus interrupt pending register */
-#define CMD_DONE_INT   (1 << 31)
-#define DATA_DONE_INT  (1 << 30)
-#define TRANS_OK_INT   (1 << 29)
-#define TRANS_FAIL_INT (1 << 28)
-#define XD_INT (1 << 27)
-#define MS_INT (1 << 26)
-#define SD_INT (1 << 25)
-#define GPIO0_INT  (1 << 24)
-#define OC_INT (1 << 23)
-#define SD_WRITE_PROTECT   (1 << 19)
-#define XD_EXIST   (1 << 18)
-#define MS_EXIST   (1 << 17)
-#define SD_EXIST   (1 << 16)
-#define DELINK_INT GPIO0_INT
-#define MS_OC_INT  (1 << 23)
-#define SD_OC_INT  (1 << 22)
+#define RTSX_BIPR  0x14
+#define   CMD_DONE_INT (1 << 31)
+#define   DATA_DONE_INT(1 << 30)
+#define   TRANS_OK_INT (1 << 29)
+#define   TRANS_FAIL_INT   (1 << 28)
+#define   XD_INT   (1 << 27)
+#define   MS_INT   (1 << 26)
+#define   SD_INT   (1 << 25)
+#define   GPIO0_INT(1 << 24)
+#define   OC_INT   (1 << 23)
+#define   SD_WRITE_PROTECT (1 << 19)
+#define   XD_EXIST (1 << 18)
+#define   MS_EXIST (1 << 17)
+#define   SD_EXIST (1 << 16)
+#define   DELINK_INT   GPIO0_INT
+#define   MS_OC_INT(1 << 23)
+#define   SD_OC_INT(1 << 22)
 
 #define CARD_INT   (XD_INT | MS_INT | SD_INT)
 #define NEED_COMPLETE_INT  (DATA_DONE_INT | TRANS_OK_INT | TRANS_FAIL_INT)
 #define RTSX_INT   (CMD_DONE_INT | NEED_COMPLETE_INT | \
CARD_INT | GPIO0_INT | OC_INT)
-
 #define CARD_EXIST (XD_EXIST | MS_EXIST | SD_EXIST)
 
-/* Bus interrupt enable register */
-#define CMD_DONE_INT_EN(1 << 31)
-#define DATA_DONE_INT_EN   (1 << 30)
-#define TRANS_OK_INT_EN(1 << 29)
-#defi

[PATCH 03/10] mfd: rtsx: add debug info when access register failed

2015-01-15 Thread micky_ching
From: Micky Ching 

Add debug info when access register failed, this is useful for
debug.

Signed-off-by: Micky Ching 
---
 drivers/mfd/rtsx_pcr.c   | 22 +-
 include/linux/mfd/rtsx_pci.h |  2 ++
 2 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/drivers/mfd/rtsx_pcr.c b/drivers/mfd/rtsx_pcr.c
index 30f7ca8..92f5a41 100644
--- a/drivers/mfd/rtsx_pcr.c
+++ b/drivers/mfd/rtsx_pcr.c
@@ -96,12 +96,16 @@ int rtsx_pci_write_register(struct rtsx_pcr *pcr, u16 addr, 
u8 mask, u8 data)
for (i = 0; i < MAX_RW_REG_CNT; i++) {
val = rtsx_pci_readl(pcr, RTSX_HAIMR);
if ((val & HAIMR_TRANS_END) == 0) {
-   if (data != (u8)val)
+   if (data != (u8)val) {
+   pcr_dbg(pcr, "write register 0x%02x failed\n",
+   addr);
return -EIO;
+   }
return 0;
}
}
 
+   pcr_dbg(pcr, "write register 0x%02x failed\n", addr);
return -ETIMEDOUT;
 }
 EXPORT_SYMBOL_GPL(rtsx_pci_write_register);
@@ -120,8 +124,10 @@ int rtsx_pci_read_register(struct rtsx_pcr *pcr, u16 addr, 
u8 *data)
break;
}
 
-   if (i >= MAX_RW_REG_CNT)
+   if (i >= MAX_RW_REG_CNT) {
+   pcr_dbg(pcr, "read register 0x%02x failed\n", addr);
return -ETIMEDOUT;
+   }
 
if (data)
*data = (u8)(val & 0xFF);
@@ -157,8 +163,10 @@ int rtsx_pci_write_phy_register(struct rtsx_pcr *pcr, u8 
addr, u16 val)
}
}
 
-   if (!finished)
+   if (!finished) {
+   pcr_dbg(pcr, "write phy 0x%x failed\n", addr);
return -ETIMEDOUT;
+   }
 
return 0;
 }
@@ -190,8 +198,10 @@ int rtsx_pci_read_phy_register(struct rtsx_pcr *pcr, u8 
addr, u16 *val)
}
}
 
-   if (!finished)
+   if (!finished) {
+   pcr_dbg(pcr, "read phy 0x%x failed\n", addr);
return -ETIMEDOUT;
+   }
 
rtsx_pci_init_cmd(pcr);
 
@@ -199,8 +209,10 @@ int rtsx_pci_read_phy_register(struct rtsx_pcr *pcr, u8 
addr, u16 *val)
rtsx_pci_add_cmd(pcr, READ_REG_CMD, PHYDATA1, 0, 0);
 
err = rtsx_pci_send_cmd(pcr, 100);
-   if (err < 0)
+   if (err < 0) {
+   pcr_dbg(pcr, "read phy 0x%x failed\n", addr);
return err;
+   }
 
ptr = rtsx_pci_get_cmd_data(pcr);
data = ((u16)ptr[1] << 8) | ptr[0];
diff --git a/include/linux/mfd/rtsx_pci.h b/include/linux/mfd/rtsx_pci.h
index e81f2bb..a680427 100644
--- a/include/linux/mfd/rtsx_pci.h
+++ b/include/linux/mfd/rtsx_pci.h
@@ -838,6 +838,8 @@ struct rtsx_pcr {
 #define PCI_VID(pcr)   ((pcr)->pci->vendor)
 #define PCI_PID(pcr)   ((pcr)->pci->device)
 
+#define pcr_dbg(pcr, fmt, arg...)  \
+   dev_dbg(&(pcr)->pci->dev, fmt, ##arg)
 #define SDR104_PHASE(val)  ((val) & 0xFF)
 #define SDR50_PHASE(val)   (((val) >> 8) & 0xFF)
 #define DDR50_PHASE(val)   (((val) >> 16) & 0xFF)
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 07/10] mfd: rtsx: remove LCTLR defination

2015-01-15 Thread micky_ching
From: Micky Ching 

To enable/disable ASPM we should find LINK CONTROL register
in PCI config space. All old chip use 0x80 address, but new
chip may use another address, so we using pci_find_capability()
to get LINK CONTROL address.

rtsx_gops.c was removed, we consider to put some common operations
to this file, but the actual thing is, only a group of chips
are in common ops1, and another group of chips in common ops2,
it is hard to decide put which ops into generic ops file.

Signed-off-by: Micky Ching 
---
 drivers/mfd/Makefile |  2 +-
 drivers/mfd/rts5227.c|  2 +-
 drivers/mfd/rts5249.c|  3 +--
 drivers/mfd/rtsx_gops.c  | 37 -
 drivers/mfd/rtsx_pcr.c   | 25 -
 include/linux/mfd/rtsx_pci.h |  9 -
 6 files changed, 23 insertions(+), 55 deletions(-)
 delete mode 100644 drivers/mfd/rtsx_gops.c

diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 53467e2..2cd7e74 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -13,7 +13,7 @@ obj-$(CONFIG_MFD_CROS_EC) += cros_ec.o
 obj-$(CONFIG_MFD_CROS_EC_I2C)  += cros_ec_i2c.o
 obj-$(CONFIG_MFD_CROS_EC_SPI)  += cros_ec_spi.o
 
-rtsx_pci-objs  := rtsx_pcr.o rtsx_gops.o rts5209.o rts5229.o 
rtl8411.o rts5227.o rts5249.o
+rtsx_pci-objs  := rtsx_pcr.o rts5209.o rts5229.o rtl8411.o 
rts5227.o rts5249.o
 obj-$(CONFIG_MFD_RTSX_PCI) += rtsx_pci.o
 obj-$(CONFIG_MFD_RTSX_USB) += rtsx_usb.o
 
diff --git a/drivers/mfd/rts5227.c b/drivers/mfd/rts5227.c
index 1f387d4..0c02831 100644
--- a/drivers/mfd/rts5227.c
+++ b/drivers/mfd/rts5227.c
@@ -130,7 +130,7 @@ static int rts5227_optimize_phy(struct rtsx_pcr *pcr)
 {
int err;
 
-   err = rtsx_gops_pm_reset(pcr);
+   err = rtsx_pci_write_register(pcr, PM_CTRL3, D3_DELINK_MODE_EN, 0x00);
if (err < 0)
return err;
 
diff --git a/drivers/mfd/rts5249.c b/drivers/mfd/rts5249.c
index 00208d1..5eb9819 100644
--- a/drivers/mfd/rts5249.c
+++ b/drivers/mfd/rts5249.c
@@ -119,7 +119,6 @@ static int rts5249_extra_init_hw(struct rtsx_pcr *pcr)
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0xB0, 0xB0);
else
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0xB0, 0x80);
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PM_CTRL3, 0x10, 0x00);
 
return rtsx_pci_send_cmd(pcr, 100);
 }
@@ -128,7 +127,7 @@ static int rts5249_optimize_phy(struct rtsx_pcr *pcr)
 {
int err;
 
-   err = rtsx_gops_pm_reset(pcr);
+   err = rtsx_pci_write_register(pcr, PM_CTRL3, D3_DELINK_MODE_EN, 0x00);
if (err < 0)
return err;
 
diff --git a/drivers/mfd/rtsx_gops.c b/drivers/mfd/rtsx_gops.c
deleted file mode 100644
index b1a98c6..000
--- a/drivers/mfd/rtsx_gops.c
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Driver for Realtek PCI-Express card reader
- *
- * Copyright(c) 2009-2013 Realtek Semiconductor Corp. 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 as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * 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.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see .
- *
- * Author:
- *   Micky Ching 
- */
-
-#include 
-#include "rtsx_pcr.h"
-
-int rtsx_gops_pm_reset(struct rtsx_pcr *pcr)
-{
-   int err;
-
-   /* init aspm */
-   rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, 0xFF, 0x00);
-   err = rtsx_pci_update_cfg_byte(pcr, LCTLR, ~LCTLR_ASPM_CTL_MASK, 0x00);
-   if (err < 0)
-   return err;
-
-   /* reset PM_CTRL3 before send buffer cmd */
-   return rtsx_pci_write_register(pcr, PM_CTRL3, D3_DELINK_MODE_EN, 0x00);
-}
diff --git a/drivers/mfd/rtsx_pcr.c b/drivers/mfd/rtsx_pcr.c
index 92f5a41..3065edc 100644
--- a/drivers/mfd/rtsx_pcr.c
+++ b/drivers/mfd/rtsx_pcr.c
@@ -63,6 +63,20 @@ static const struct pci_device_id rtsx_pci_ids[] = {
 
 MODULE_DEVICE_TABLE(pci, rtsx_pci_ids);
 
+static inline void rtsx_pci_enable_aspm(struct rtsx_pcr *pcr)
+{
+   int exp = pci_find_capability(pcr->pci, PCI_CAP_ID_EXP);
+
+   rtsx_pci_update_cfg_byte(pcr, exp + PCI_EXP_LNKCTL, 0xFC, pcr->aspm_en);
+}
+
+static inline void rtsx_pci_disable_aspm(struct rtsx_pcr *pcr)
+{
+   int exp = pci_find_capability(pcr->pci, PCI_CAP_ID_EXP);
+
+   rtsx_pci_update_cfg_byte(pcr, exp + PCI_EXP_LNKCTL, 0xFC, 0);
+}
+
 void rtsx_pci_start_run(struct rtsx_pcr *pcr)
 {
/* If pci device removed, don't queue idle work any more */
@@ -75,7 +89,8 @@ void rtsx_pci_start_run(struct rtsx_pc

[PATCH 00/10] mfd: rtsx: add support for new rts524A and rts525A

2015-01-15 Thread micky_ching
From: Micky Ching 

This patchset including re-format some coding-style and add two new chip
rts524A and rts525A.

Micky Ching (10):
  mfd: rtsx: replace TAB by SPC after #define
  mfd: rtsx: place register address and values togather
  mfd: rtsx: add debug info when access register failed
  mfd: rtsx: update PETXCFG address
  mfd: rtsx: update driving settings
  mfd: rtsx: update phy register
  mfd: rtsx: remove LCTLR defination
  mfd: rtsx: add support for rts524A
  mfd: rtsx: add support for rts525A
  mfd: rtsx: using pcr_dbg replace dev_dbg

 drivers/mfd/Makefile |   2 +-
 drivers/mfd/rtl8411.c|  11 +-
 drivers/mfd/rts5209.c|   4 +-
 drivers/mfd/rts5227.c|  12 +-
 drivers/mfd/rts5229.c|   4 +-
 drivers/mfd/rts5249.c| 274 ++---
 drivers/mfd/rtsx_gops.c  |  37 --
 drivers/mfd/rtsx_pcr.c   | 114 --
 drivers/mfd/rtsx_pcr.h   |   5 +
 include/linux/mfd/rtsx_pci.h | 950 +--
 10 files changed, 778 insertions(+), 635 deletions(-)
 delete mode 100644 drivers/mfd/rtsx_gops.c

-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 04/10] mfd: rtsx: update PETXCFG address

2015-01-15 Thread micky_ching
From: Micky Ching 

PETXCFG is defined at 0xFF03, the old 0xFE49 not used any more.

Signed-off-by: Micky Ching 
---
 drivers/mfd/rts5227.c| 6 ++
 drivers/mfd/rts5249.c| 6 ++
 include/linux/mfd/rtsx_pci.h | 2 +-
 3 files changed, 5 insertions(+), 9 deletions(-)

diff --git a/drivers/mfd/rts5227.c b/drivers/mfd/rts5227.c
index 3240740..1f387d4 100644
--- a/drivers/mfd/rts5227.c
+++ b/drivers/mfd/rts5227.c
@@ -118,11 +118,9 @@ static int rts5227_extra_init_hw(struct rtsx_pcr *pcr)
rts5227_fill_driving(pcr, OUTPUT_3V3);
/* Configure force_clock_req */
if (pcr->flags & PCR_REVERSE_SOCKET)
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
-   AUTOLOAD_CFG_BASE + 3, 0xB8, 0xB8);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0xB8, 0xB8);
else
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
-   AUTOLOAD_CFG_BASE + 3, 0xB8, 0x88);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0xB8, 0x88);
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PM_CTRL3, 0x10, 0x00);
 
return rtsx_pci_send_cmd(pcr, 100);
diff --git a/drivers/mfd/rts5249.c b/drivers/mfd/rts5249.c
index cf425cc..225ad55 100644
--- a/drivers/mfd/rts5249.c
+++ b/drivers/mfd/rts5249.c
@@ -116,11 +116,9 @@ static int rts5249_extra_init_hw(struct rtsx_pcr *pcr)
/* Configure driving */
rts5249_fill_driving(pcr, OUTPUT_3V3);
if (pcr->flags & PCR_REVERSE_SOCKET)
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
-   AUTOLOAD_CFG_BASE + 3, 0xB0, 0xB0);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0xB0, 0xB0);
else
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
-   AUTOLOAD_CFG_BASE + 3, 0xB0, 0x80);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0xB0, 0x80);
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PM_CTRL3, 0x10, 0x00);
 
return rtsx_pci_send_cmd(pcr, 100);
diff --git a/include/linux/mfd/rtsx_pci.h b/include/linux/mfd/rtsx_pci.h
index a680427..80baa10 100644
--- a/include/linux/mfd/rtsx_pci.h
+++ b/include/linux/mfd/rtsx_pci.h
@@ -572,7 +572,6 @@
 #define MSGTXDATA2 0xFE46
 #define MSGTXDATA3 0xFE47
 #define MSGTXCTL   0xFE48
-#define PETXCFG0xFE49
 #define LTR_CTL0xFE4A
 #define OBFF_CFG   0xFE4C
 
@@ -606,6 +605,7 @@
 #define DUMMY_REG_RESET_0  0xFE90
 
 #define AUTOLOAD_CFG_BASE  0xFF00
+#define PETXCFG0xFF03
 
 #define PM_CTRL1   0xFF44
 #define PM_CTRL2   0xFF45
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 09/10] mfd: rtsx: add support for rts525A

2015-01-15 Thread micky_ching
From: Micky Ching 

add support for new chip rts525A.

Signed-off-by: Micky Ching 
---
 drivers/mfd/rts5249.c  | 93 +-
 drivers/mfd/rtsx_pcr.c | 13 +--
 drivers/mfd/rtsx_pcr.h |  1 +
 3 files changed, 103 insertions(+), 4 deletions(-)

diff --git a/drivers/mfd/rts5249.c b/drivers/mfd/rts5249.c
index 1ce03a6..46b6522 100644
--- a/drivers/mfd/rts5249.c
+++ b/drivers/mfd/rts5249.c
@@ -97,7 +97,7 @@ static void rts5249_force_power_down(struct rtsx_pcr *pcr, u8 
pm_state)
rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 3, 0x01, 0);
 
if (pm_state == HOST_ENTER_S3) {
-   if (PCI_PID(pcr) == 0x524A)
+   if (PCI_PID(pcr) == 0x524A || PCI_PID(pcr) == 0x525A)
rtsx_pci_write_register(pcr, RTS524A_PM_CTRL3,
D3_DELINK_MODE_EN, D3_DELINK_MODE_EN);
else if (PCI_PID(pcr) == 0x5249)
@@ -430,3 +430,94 @@ void rts524a_init_params(struct rtsx_pcr *pcr)
pcr->ops = &rts524a_pcr_ops;
 }
 
+static int rts525a_card_power_on(struct rtsx_pcr *pcr, int card)
+{
+   rtsx_pci_write_register(pcr, LDO_VCC_CFG1,
+   LDO_VCC_TUNE_MASK, LDO_VCC_3V3);
+   return rts5249_card_power_on(pcr, card);
+}
+
+static int rts525a_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
+{
+   if (voltage == OUTPUT_3V3) {
+   rtsx_pci_write_register(pcr, LDO_CONFIG2,
+   LDO_D3318_MASK, LDO_D3318_33V);
+   rtsx_pci_write_register(pcr, SD_PAD_CTL, SD_IO_USING_1V8, 0);
+   } else if (voltage == OUTPUT_1V8) {
+   rtsx_pci_write_register(pcr, LDO_CONFIG2,
+   LDO_D3318_MASK, LDO_D3318_18V);
+   rtsx_pci_write_register(pcr, SD_PAD_CTL, SD_IO_USING_1V8,
+   SD_IO_USING_1V8);
+   } else {
+   return -EINVAL;
+   }
+
+   rtsx_pci_init_cmd(pcr);
+   rts5249_fill_driving(pcr, voltage);
+   return rtsx_pci_send_cmd(pcr, 100);
+}
+
+static int rts525a_optimize_phy(struct rtsx_pcr *pcr)
+{
+   int err;
+
+   err = rtsx_pci_write_register(pcr, RTS524A_PM_CTRL3,
+   D3_DELINK_MODE_EN, 0x00);
+   if (err < 0)
+   return err;
+
+   rtsx_pci_write_phy_register(pcr, 0x1D, 0x99FF);
+   rtsx_pci_write_phy_register(pcr, 0x03, 0x2748);
+
+   if (is_version(pcr, 0x525A, IC_VER_A))
+   rtsx_pci_write_phy_register(pcr, 0x19, 0x3902);
+
+   return 0;
+}
+
+static int rts525a_extra_init_hw(struct rtsx_pcr *pcr)
+{
+   rts5249_extra_init_hw(pcr);
+
+   rtsx_pci_write_register(pcr, PCLK_CTL, PCLK_MODE_SEL, PCLK_MODE_SEL);
+   if (is_version(pcr, 0x525A, IC_VER_A)) {
+   rtsx_pci_write_register(pcr, L1SUB_CONFIG2,
+   L1SUB_AUTO_CFG, L1SUB_AUTO_CFG);
+   rtsx_pci_write_register(pcr, RREF_CFG,
+   RREF_VBGSEL_MASK, RREF_VBGSEL_1V25);
+   rtsx_pci_write_register(pcr, LDO_VIO_CFG,
+   LDO_VIO_TUNE_MASK, LDO_VIO_1V7);
+   rtsx_pci_write_register(pcr, LDO_DV12S_CFG,
+   LDO_D12_TUNE_MASK, LDO_D12_TUNE_DF);
+   rtsx_pci_write_register(pcr, LDO_AV12S_CFG,
+   LDO_AV12S_TUNE_MASK, LDO_AV12S_TUNE_DF);
+   rtsx_pci_write_register(pcr, LDO_VCC_CFG0,
+   LDO_VCC_LMTVTH_MASK, LDO_VCC_LMTVTH_2A);
+   rtsx_pci_write_register(pcr, OOBS_CONFIG,
+   OOBS_AUTOK_DIS | OOBS_VAL_MASK, 0x89);
+   }
+
+   return 0;
+}
+
+static const struct pcr_ops rts525a_pcr_ops = {
+   .fetch_vendor_settings = rts5249_fetch_vendor_settings,
+   .extra_init_hw = rts525a_extra_init_hw,
+   .optimize_phy = rts525a_optimize_phy,
+   .turn_on_led = rts5249_turn_on_led,
+   .turn_off_led = rts5249_turn_off_led,
+   .enable_auto_blink = rts5249_enable_auto_blink,
+   .disable_auto_blink = rts5249_disable_auto_blink,
+   .card_power_on = rts525a_card_power_on,
+   .card_power_off = rts5249_card_power_off,
+   .switch_output_voltage = rts525a_switch_output_voltage,
+   .force_power_down = rts5249_force_power_down,
+};
+
+void rts525a_init_params(struct rtsx_pcr *pcr)
+{
+   rts5249_init_params(pcr);
+
+   pcr->ops = &rts525a_pcr_ops;
+}
+
diff --git a/drivers/mfd/rtsx_pcr.c b/drivers/mfd/rtsx_pcr.c
index 17334ba..33aa30b 100644
--- a/drivers/mfd/rtsx_pcr.c
+++ b/drivers/mfd/rtsx_pcr.c
@@ -59,6 +59,7 @@ static const struct pci_device_id rtsx_pci_ids[] = {
{ PCI_DEVICE(0x10EC, 0x5287), PCI_CLASS_OTHERS << 16, 0xFF },
{ PCI_DEVICE(0x10EC, 0x5286), PCI_CLASS_OTHERS << 16, 0xFF },
{ PCI_DEVICE(0x10EC, 0x524A), PCI_CLASS_OTHERS << 16, 0xFF },
+   { PCI_DEVICE(0x10EC, 0x525A), PCI_CLASS_OTHERS << 16, 0xFF },
{ 0, }
 };
 
@@ -1113,6 +1114,10 @@ static int rtsx_pci_init_chip(struct rtsx_pcr *pcr)
   

[PATCH 10/10] mfd: rtsx: using pcr_dbg replace dev_dbg

2015-01-15 Thread micky_ching
From: Micky Ching 

pcr_dbg is a wrapper of dev_dbg, which can save some code,
and help to enable/disable debug message static.

Signed-off-by: Micky Ching 
---
 drivers/mfd/rtl8411.c  | 11 +--
 drivers/mfd/rts5209.c  |  4 ++--
 drivers/mfd/rts5227.c  |  4 ++--
 drivers/mfd/rts5229.c  |  4 ++--
 drivers/mfd/rts5249.c  |  4 ++--
 drivers/mfd/rtsx_pcr.c | 49 ++---
 6 files changed, 35 insertions(+), 41 deletions(-)

diff --git a/drivers/mfd/rtl8411.c b/drivers/mfd/rtl8411.c
index fdd34c8..b3ae659 100644
--- a/drivers/mfd/rtl8411.c
+++ b/drivers/mfd/rtl8411.c
@@ -53,7 +53,7 @@ static void rtl8411_fetch_vendor_settings(struct rtsx_pcr 
*pcr)
u8 reg3 = 0;
 
rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG1, ®1);
-   dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg1);
+   pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg1);
 
if (!rtsx_vendor_setting_valid(reg1))
return;
@@ -65,7 +65,7 @@ static void rtl8411_fetch_vendor_settings(struct rtsx_pcr 
*pcr)
pcr->card_drive_sel |= rtsx_reg_to_card_drive_sel(reg1);
 
rtsx_pci_read_config_byte(pcr, PCR_SETTING_REG3, ®3);
-   dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG3, reg3);
+   pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG3, reg3);
pcr->sd30_drive_sel_3v3 = rtl8411_reg_to_sd30_drive_sel_3v3(reg3);
 }
 
@@ -74,7 +74,7 @@ static void rtl8411b_fetch_vendor_settings(struct rtsx_pcr 
*pcr)
u32 reg = 0;
 
rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG1, ®);
-   dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
+   pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
 
if (!rtsx_vendor_setting_valid(reg))
return;
@@ -260,9 +260,8 @@ static unsigned int rtl8411_cd_deglitch(struct rtsx_pcr 
*pcr)
rtsx_pci_write_register(pcr, CARD_PWR_CTL,
BPP_POWER_MASK, BPP_POWER_OFF);
 
-   dev_dbg(&(pcr->pci->dev),
-   "After CD deglitch, card_exist = 0x%x\n",
-   card_exist);
+   pcr_dbg(pcr, "After CD deglitch, card_exist = 0x%x\n",
+   card_exist);
}
 
if (card_exist & MS_EXIST) {
diff --git a/drivers/mfd/rts5209.c b/drivers/mfd/rts5209.c
index cb04174..373e253 100644
--- a/drivers/mfd/rts5209.c
+++ b/drivers/mfd/rts5209.c
@@ -38,7 +38,7 @@ static void rts5209_fetch_vendor_settings(struct rtsx_pcr 
*pcr)
u32 reg;
 
rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG1, ®);
-   dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
+   pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
 
if (rts5209_vendor_setting1_valid(reg)) {
if (rts5209_reg_check_ms_pmos(reg))
@@ -47,7 +47,7 @@ static void rts5209_fetch_vendor_settings(struct rtsx_pcr 
*pcr)
}
 
rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG2, ®);
-   dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG2, reg);
+   pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG2, reg);
 
if (rts5209_vendor_setting2_valid(reg)) {
pcr->sd30_drive_sel_1v8 =
diff --git a/drivers/mfd/rts5227.c b/drivers/mfd/rts5227.c
index 0c02831..ce012d7 100644
--- a/drivers/mfd/rts5227.c
+++ b/drivers/mfd/rts5227.c
@@ -63,7 +63,7 @@ static void rts5227_fetch_vendor_settings(struct rtsx_pcr 
*pcr)
u32 reg;
 
rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG1, ®);
-   dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
+   pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
 
if (!rtsx_vendor_setting_valid(reg))
return;
@@ -74,7 +74,7 @@ static void rts5227_fetch_vendor_settings(struct rtsx_pcr 
*pcr)
pcr->card_drive_sel |= rtsx_reg_to_card_drive_sel(reg);
 
rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG2, ®);
-   dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG2, reg);
+   pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG2, reg);
pcr->sd30_drive_sel_3v3 = rtsx_reg_to_sd30_drive_sel_3v3(reg);
if (rtsx_reg_check_reverse_socket(reg))
pcr->flags |= PCR_REVERSE_SOCKET;
diff --git a/drivers/mfd/rts5229.c b/drivers/mfd/rts5229.c
index 6353f5d..ace4538 100644
--- a/drivers/mfd/rts5229.c
+++ b/drivers/mfd/rts5229.c
@@ -38,7 +38,7 @@ static void rts5229_fetch_vendor_settings(struct rtsx_pcr 
*pcr)
u32 reg;
 
rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG1, ®);
-   dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
+   pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
 
if (!rtsx_vendor_setting_valid(reg))
return;
@@ -50,7 +50,7 @@ static void rts5229_fetch_vendor_settings(struct rtsx_pcr 
*pcr)
pcr->card_drive_sel |= rtsx_reg_to_card_dr

[PATCH 08/10] mfd: rtsx: add support for rts524A

2015-01-15 Thread micky_ching
From: Micky Ching 

add support for new chip rts524A.

Signed-off-by: Micky Ching 
---
 drivers/mfd/rts5249.c| 112 +++
 drivers/mfd/rtsx_pcr.c   |   5 ++
 drivers/mfd/rtsx_pcr.h   |   4 ++
 include/linux/mfd/rtsx_pci.h |  87 -
 4 files changed, 198 insertions(+), 10 deletions(-)

diff --git a/drivers/mfd/rts5249.c b/drivers/mfd/rts5249.c
index 5eb9819..1ce03a6 100644
--- a/drivers/mfd/rts5249.c
+++ b/drivers/mfd/rts5249.c
@@ -72,8 +72,10 @@ static void rts5249_fetch_vendor_settings(struct rtsx_pcr 
*pcr)
rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG1, ®);
dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
 
-   if (!rtsx_vendor_setting_valid(reg))
+   if (!rtsx_vendor_setting_valid(reg)) {
+   pcr_dbg(pcr, "skip fetch vendor setting\n");
return;
+   }
 
pcr->aspm_en = rtsx_reg_to_aspm(reg);
pcr->sd30_drive_sel_1v8 = rtsx_reg_to_sd30_drive_sel_1v8(reg);
@@ -94,8 +96,14 @@ static void rts5249_force_power_down(struct rtsx_pcr *pcr, 
u8 pm_state)
rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 2, 0xFF, 0);
rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 3, 0x01, 0);
 
-   if (pm_state == HOST_ENTER_S3)
-   rtsx_pci_write_register(pcr, PM_CTRL3, 0x10, 0x10);
+   if (pm_state == HOST_ENTER_S3) {
+   if (PCI_PID(pcr) == 0x524A)
+   rtsx_pci_write_register(pcr, RTS524A_PM_CTRL3,
+   D3_DELINK_MODE_EN, D3_DELINK_MODE_EN);
+   else if (PCI_PID(pcr) == 0x5249)
+   rtsx_pci_write_register(pcr, PM_CTRL3,
+   D3_DELINK_MODE_EN, D3_DELINK_MODE_EN);
+   }
 
rtsx_pci_write_register(pcr, FPDCTL, 0x03, 0x03);
 }
@@ -104,6 +112,8 @@ static int rts5249_extra_init_hw(struct rtsx_pcr *pcr)
 {
rtsx_pci_init_cmd(pcr);
 
+   /* Rest L1SUB Config */
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, L1SUB_CONFIG3, 0xFF, 0x00);
/* Configure GPIO as output */
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, GPIO_CTL, 0x02, 0x02);
/* Reset ASPM state to default value */
@@ -228,14 +238,20 @@ static int rts5249_switch_output_voltage(struct rtsx_pcr 
*pcr, u8 voltage)
int err;
 
if (voltage == OUTPUT_3V3) {
-   err = rtsx_pci_write_phy_register(pcr, PHY_TUNE, 0x4FC0 | 0x24);
+   err = rtsx_pci_update_phy(pcr, PHY_TUNE, 0xFC3F, 0x03C0);
if (err < 0)
return err;
} else if (voltage == OUTPUT_1V8) {
-   err = rtsx_pci_write_phy_register(pcr, PHY_BACR, 0x3C02);
-   if (err < 0)
-   return err;
-   err = rtsx_pci_write_phy_register(pcr, PHY_TUNE, 0x4C40 | 0x24);
+   u16 append = 0x0100;
+
+   if (PCI_PID(pcr) == 0x5249) {
+   err = rtsx_pci_update_phy(pcr, PHY_BACR, 0xFFF3, 0);
+   if (err < 0)
+   return err;
+   append = 0x0080;
+   }
+
+   err = rtsx_pci_update_phy(pcr, PHY_TUNE, 0xFC3F, append);
if (err < 0)
return err;
} else {
@@ -334,3 +350,83 @@ void rts5249_init_params(struct rtsx_pcr *pcr)
pcr->ms_pull_ctl_enable_tbl = rts5249_ms_pull_ctl_enable_tbl;
pcr->ms_pull_ctl_disable_tbl = rts5249_ms_pull_ctl_disable_tbl;
 }
+
+static inline int rts524a_write_phy(struct rtsx_pcr *pcr, u8 addr, u16 val)
+{
+   addr = addr & 0x80 ? (addr & 0x7F) | 0x40 : addr;
+   return rtsx_pci_write_phy_register(pcr, addr, val);
+}
+
+static int rts524a_optimize_phy(struct rtsx_pcr *pcr)
+{
+   int err;
+
+   err = rtsx_pci_write_register(pcr, RTS524A_PM_CTRL3,
+   D3_DELINK_MODE_EN, 0x00);
+   if (err < 0)
+   return err;
+
+   rts524a_write_phy(pcr, 0x00, 0xBA42);
+   rts524a_write_phy(pcr, 0x03, 0x2748);
+
+   if (is_version(pcr, 0x524A, IC_VER_A)) {
+   rts524a_write_phy(pcr, 0x03, 0x2748);
+   rts524a_write_phy(pcr, 0x02, 0x0A1F);
+   rts524a_write_phy(pcr, 0x1A, 0x2546);
+   rts524a_write_phy(pcr, 0x1D, 0x0004);
+   rts524a_write_phy(pcr, 0x1E, 0x5C7F);
+   }
+
+   rts524a_write_phy(pcr, 0x08, 0x57E4);
+
+   return 0;
+}
+
+static int rts524a_extra_init_hw(struct rtsx_pcr *pcr)
+{
+   rts5249_extra_init_hw(pcr);
+
+   rtsx_pci_write_register(pcr, FUNC_FORCE_CTL, 0x02, 0x02);
+   rtsx_pci_write_register(pcr, PM_EVENT_DEBUG, PME_DEBUG_0, PME_DEBUG_0);
+   rtsx_pci_write_register(pcr, LDO_VCC_CFG1, LDO_VCC_LMT_EN,
+   LDO_VCC_LMT_EN);
+   rtsx_pci_write_register(pcr, PCLK_CTL, PCLK_MODE_SEL, PCLK_MODE_SEL);
+   if (is_version(pcr, 0x524A, IC_VER_A)) {
+   rtsx_pci_write_register(pcr,

[PATCH] mfd: rtsx: add support for rts522A

2015-04-16 Thread micky_ching
From: Micky Ching 

rts522a(rts5227s) is derived from rts5227, and mainly same with rts5227.
Add it to file mfd/rts5227.c to support this chip.

Signed-off-by: Micky Ching 
---
 drivers/mfd/rts5227.c| 77 ++--
 drivers/mfd/rtsx_pcr.c   |  5 +++
 drivers/mfd/rtsx_pcr.h   |  3 ++
 include/linux/mfd/rtsx_pci.h |  6 
 4 files changed, 89 insertions(+), 2 deletions(-)

diff --git a/drivers/mfd/rts5227.c b/drivers/mfd/rts5227.c
index ce012d7..cf13e66 100644
--- a/drivers/mfd/rts5227.c
+++ b/drivers/mfd/rts5227.c
@@ -26,6 +26,14 @@
 
 #include "rtsx_pcr.h"
 
+static u8 rts5227_get_ic_version(struct rtsx_pcr *pcr)
+{
+   u8 val;
+
+   rtsx_pci_read_register(pcr, DUMMY_REG_RESET_0, &val);
+   return val & 0x0F;
+}
+
 static void rts5227_fill_driving(struct rtsx_pcr *pcr, u8 voltage)
 {
u8 driving_3v3[4][3] = {
@@ -88,7 +96,7 @@ static void rts5227_force_power_down(struct rtsx_pcr *pcr, u8 
pm_state)
rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 3, 0x01, 0);
 
if (pm_state == HOST_ENTER_S3)
-   rtsx_pci_write_register(pcr, PM_CTRL3, 0x10, 0x10);
+   rtsx_pci_write_register(pcr, pcr->reg_pm_ctrl3, 0x10, 0x10);
 
rtsx_pci_write_register(pcr, FPDCTL, 0x03, 0x03);
 }
@@ -121,7 +129,7 @@ static int rts5227_extra_init_hw(struct rtsx_pcr *pcr)
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0xB8, 0xB8);
else
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0xB8, 0x88);
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PM_CTRL3, 0x10, 0x00);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, pcr->reg_pm_ctrl3, 0x10, 0x00);
 
return rtsx_pci_send_cmd(pcr, 100);
 }
@@ -298,8 +306,73 @@ void rts5227_init_params(struct rtsx_pcr *pcr)
pcr->tx_initial_phase = SET_CLOCK_PHASE(27, 27, 15);
pcr->rx_initial_phase = SET_CLOCK_PHASE(30, 7, 7);
 
+   pcr->ic_version = rts5227_get_ic_version(pcr);
pcr->sd_pull_ctl_enable_tbl = rts5227_sd_pull_ctl_enable_tbl;
pcr->sd_pull_ctl_disable_tbl = rts5227_sd_pull_ctl_disable_tbl;
pcr->ms_pull_ctl_enable_tbl = rts5227_ms_pull_ctl_enable_tbl;
pcr->ms_pull_ctl_disable_tbl = rts5227_ms_pull_ctl_disable_tbl;
+
+   pcr->reg_pm_ctrl3 = PM_CTRL3;
+}
+
+static int rts522a_optimize_phy(struct rtsx_pcr *pcr)
+{
+   int err;
+
+   err = rtsx_pci_write_register(pcr, RTS522A_PM_CTRL3, D3_DELINK_MODE_EN,
+   0x00);
+   if (err < 0)
+   return err;
+
+   if (is_version(pcr, 0x522A, IC_VER_A)) {
+   err = rtsx_pci_write_phy_register(pcr, PHY_RCR2,
+   PHY_RCR2_INIT_27S);
+   if (err)
+   return err;
+
+   rtsx_pci_write_phy_register(pcr, PHY_RCR1, PHY_RCR1_INIT_27S);
+   rtsx_pci_write_phy_register(pcr, PHY_FLD0, PHY_FLD0_INIT_27S);
+   rtsx_pci_write_phy_register(pcr, PHY_FLD3, PHY_FLD3_INIT_27S);
+   rtsx_pci_write_phy_register(pcr, PHY_FLD4, PHY_FLD4_INIT_27S);
+   }
+
+   return 0;
+}
+
+static int rts522a_extra_init_hw(struct rtsx_pcr *pcr)
+{
+   rts5227_extra_init_hw(pcr);
+
+   rtsx_pci_write_register(pcr, FUNC_FORCE_CTL, FUNC_FORCE_UPME_XMT_DBG,
+   FUNC_FORCE_UPME_XMT_DBG);
+   rtsx_pci_write_register(pcr, PCLK_CTL, 0x04, 0x04);
+   rtsx_pci_write_register(pcr, PM_EVENT_DEBUG, PME_DEBUG_0, PME_DEBUG_0);
+   rtsx_pci_write_register(pcr, PM_CLK_FORCE_CTL, 0xFF, 0x11);
+
+   return 0;
+}
+
+/* rts522a operations mainly derived from rts5227, except phy/hw init setting.
+ */
+static const struct pcr_ops rts522a_pcr_ops = {
+   .fetch_vendor_settings = rts5227_fetch_vendor_settings,
+   .extra_init_hw = rts522a_extra_init_hw,
+   .optimize_phy = rts522a_optimize_phy,
+   .turn_on_led = rts5227_turn_on_led,
+   .turn_off_led = rts5227_turn_off_led,
+   .enable_auto_blink = rts5227_enable_auto_blink,
+   .disable_auto_blink = rts5227_disable_auto_blink,
+   .card_power_on = rts5227_card_power_on,
+   .card_power_off = rts5227_card_power_off,
+   .switch_output_voltage = rts5227_switch_output_voltage,
+   .cd_deglitch = NULL,
+   .conv_clk_and_div_n = NULL,
+   .force_power_down = rts5227_force_power_down,
+};
+
+void rts522a_init_params(struct rtsx_pcr *pcr)
+{
+   rts5227_init_params(pcr);
+
+   pcr->reg_pm_ctrl3 = RTS522A_PM_CTRL3;
 }
diff --git a/drivers/mfd/rtsx_pcr.c b/drivers/mfd/rtsx_pcr.c
index a66540a..ccd8918 100644
--- a/drivers/mfd/rtsx_pcr.c
+++ b/drivers/mfd/rtsx_pcr.c
@@ -55,6 +55,7 @@ static const struct pci_device_id rtsx_pci_ids[] = {
{ PCI_DEVICE(0x10EC, 0x5229), PCI_CLASS_OTHERS << 16, 0xFF },
{ PCI_DEVICE(0x10EC, 0x5289), PCI_CLASS_OTHERS << 16, 0xFF },
{ PCI_DEVICE(0x10EC, 0x5227), PCI_CLASS_OTHERS << 16, 0xFF },
+   { PCI_DEVICE(0x10EC, 0x522A), PCI_CLASS_OTHERS << 16, 0xFF },
   

[PATCH v2] mfd: rtsx: add support for rts522A

2015-04-16 Thread micky_ching
From: Micky Ching 

rts522a(rts5227s) is derived from rts5227, and mainly same with rts5227.
Add it to file mfd/rts5227.c to support this chip.

Signed-off-by: Micky Ching 
---
 drivers/mfd/Kconfig  |  7 ++--
 drivers/mfd/rts5227.c| 77 ++--
 drivers/mfd/rtsx_pcr.c   |  5 +++
 drivers/mfd/rtsx_pcr.h   |  3 ++
 include/linux/mfd/rtsx_pci.h |  6 
 5 files changed, 93 insertions(+), 5 deletions(-)

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 38356e3..2c52f93 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -646,9 +646,10 @@ config MFD_RTSX_PCI
select MFD_CORE
help
  This supports for Realtek PCI-Express card reader including rts5209,
- rts5229, rtl8411, etc. Realtek card reader supports access to many
- types of memory cards, such as Memory Stick, Memory Stick Pro,
- Secure Digital and MultiMediaCard.
+ rts5227, rts522A, rts5229, rts5249, rts524A, rts525A, rtl8411, etc.
+ Realtek card reader supports access to many types of memory cards,
+ such as Memory Stick, Memory Stick Pro, Secure Digital and
+ MultiMediaCard.
 
 config MFD_RT5033
tristate "Richtek RT5033 Power Management IC"
diff --git a/drivers/mfd/rts5227.c b/drivers/mfd/rts5227.c
index ce012d7..cf13e66 100644
--- a/drivers/mfd/rts5227.c
+++ b/drivers/mfd/rts5227.c
@@ -26,6 +26,14 @@
 
 #include "rtsx_pcr.h"
 
+static u8 rts5227_get_ic_version(struct rtsx_pcr *pcr)
+{
+   u8 val;
+
+   rtsx_pci_read_register(pcr, DUMMY_REG_RESET_0, &val);
+   return val & 0x0F;
+}
+
 static void rts5227_fill_driving(struct rtsx_pcr *pcr, u8 voltage)
 {
u8 driving_3v3[4][3] = {
@@ -88,7 +96,7 @@ static void rts5227_force_power_down(struct rtsx_pcr *pcr, u8 
pm_state)
rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 3, 0x01, 0);
 
if (pm_state == HOST_ENTER_S3)
-   rtsx_pci_write_register(pcr, PM_CTRL3, 0x10, 0x10);
+   rtsx_pci_write_register(pcr, pcr->reg_pm_ctrl3, 0x10, 0x10);
 
rtsx_pci_write_register(pcr, FPDCTL, 0x03, 0x03);
 }
@@ -121,7 +129,7 @@ static int rts5227_extra_init_hw(struct rtsx_pcr *pcr)
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0xB8, 0xB8);
else
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0xB8, 0x88);
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PM_CTRL3, 0x10, 0x00);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, pcr->reg_pm_ctrl3, 0x10, 0x00);
 
return rtsx_pci_send_cmd(pcr, 100);
 }
@@ -298,8 +306,73 @@ void rts5227_init_params(struct rtsx_pcr *pcr)
pcr->tx_initial_phase = SET_CLOCK_PHASE(27, 27, 15);
pcr->rx_initial_phase = SET_CLOCK_PHASE(30, 7, 7);
 
+   pcr->ic_version = rts5227_get_ic_version(pcr);
pcr->sd_pull_ctl_enable_tbl = rts5227_sd_pull_ctl_enable_tbl;
pcr->sd_pull_ctl_disable_tbl = rts5227_sd_pull_ctl_disable_tbl;
pcr->ms_pull_ctl_enable_tbl = rts5227_ms_pull_ctl_enable_tbl;
pcr->ms_pull_ctl_disable_tbl = rts5227_ms_pull_ctl_disable_tbl;
+
+   pcr->reg_pm_ctrl3 = PM_CTRL3;
+}
+
+static int rts522a_optimize_phy(struct rtsx_pcr *pcr)
+{
+   int err;
+
+   err = rtsx_pci_write_register(pcr, RTS522A_PM_CTRL3, D3_DELINK_MODE_EN,
+   0x00);
+   if (err < 0)
+   return err;
+
+   if (is_version(pcr, 0x522A, IC_VER_A)) {
+   err = rtsx_pci_write_phy_register(pcr, PHY_RCR2,
+   PHY_RCR2_INIT_27S);
+   if (err)
+   return err;
+
+   rtsx_pci_write_phy_register(pcr, PHY_RCR1, PHY_RCR1_INIT_27S);
+   rtsx_pci_write_phy_register(pcr, PHY_FLD0, PHY_FLD0_INIT_27S);
+   rtsx_pci_write_phy_register(pcr, PHY_FLD3, PHY_FLD3_INIT_27S);
+   rtsx_pci_write_phy_register(pcr, PHY_FLD4, PHY_FLD4_INIT_27S);
+   }
+
+   return 0;
+}
+
+static int rts522a_extra_init_hw(struct rtsx_pcr *pcr)
+{
+   rts5227_extra_init_hw(pcr);
+
+   rtsx_pci_write_register(pcr, FUNC_FORCE_CTL, FUNC_FORCE_UPME_XMT_DBG,
+   FUNC_FORCE_UPME_XMT_DBG);
+   rtsx_pci_write_register(pcr, PCLK_CTL, 0x04, 0x04);
+   rtsx_pci_write_register(pcr, PM_EVENT_DEBUG, PME_DEBUG_0, PME_DEBUG_0);
+   rtsx_pci_write_register(pcr, PM_CLK_FORCE_CTL, 0xFF, 0x11);
+
+   return 0;
+}
+
+/* rts522a operations mainly derived from rts5227, except phy/hw init setting.
+ */
+static const struct pcr_ops rts522a_pcr_ops = {
+   .fetch_vendor_settings = rts5227_fetch_vendor_settings,
+   .extra_init_hw = rts522a_extra_init_hw,
+   .optimize_phy = rts522a_optimize_phy,
+   .turn_on_led = rts5227_turn_on_led,
+   .turn_off_led = rts5227_turn_off_led,
+   .enable_auto_blink = rts5227_enable_auto_blink,
+   .disable_auto_blink = rts5227_disable_auto_blink,
+   .card_power_on = rts5227_card_power_on,
+   .card_power_off = rts5227_card_p

[PATCH 02/12] mmc: core: modify mmc_app_cmd interface for SD4.0

2015-04-28 Thread micky_ching
From: Micky Ching 

When card running in SD4.0 mode, ACMD is not need to send two command,
we only need to mark a flag for the CMD which is to be send.

Signed-off-by: Micky Ching 
Signed-off-by: Wei Wang 
---
 drivers/mmc/card/block.c  |  2 +-
 drivers/mmc/core/sd_ops.c | 17 -
 include/linux/mmc/core.h  |  3 ++-
 3 files changed, 15 insertions(+), 7 deletions(-)

diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 2fc4269..a2acf3c 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -532,7 +532,7 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev,
goto cmd_rel_host;
 
if (idata->ic.is_acmd) {
-   err = mmc_app_cmd(card->host, card);
+   err = mmc_app_cmd(card->host, card, &cmd);
if (err)
goto cmd_rel_host;
}
diff --git a/drivers/mmc/core/sd_ops.c b/drivers/mmc/core/sd_ops.c
index 48d0c93..cd37971c 100644
--- a/drivers/mmc/core/sd_ops.c
+++ b/drivers/mmc/core/sd_ops.c
@@ -22,7 +22,8 @@
 #include "core.h"
 #include "sd_ops.h"
 
-int mmc_app_cmd(struct mmc_host *host, struct mmc_card *card)
+int mmc_app_cmd(struct mmc_host *host, struct mmc_card *card,
+   struct mmc_command *next_cmd)
 {
int err;
struct mmc_command cmd = {0};
@@ -30,6 +31,11 @@ int mmc_app_cmd(struct mmc_host *host, struct mmc_card *card)
BUG_ON(!host);
BUG_ON(card && (card->host != host));
 
+   if (card && mmc_card_uhsii(card)) {
+   next_cmd->app_cmd = true;
+   return 0;
+   }
+
cmd.opcode = MMC_APP_CMD;
 
if (card) {
@@ -82,7 +88,7 @@ int mmc_wait_for_app_cmd(struct mmc_host *host, struct 
mmc_card *card,
 * we cannot use the retries field in mmc_command.
 */
for (i = 0;i <= retries;i++) {
-   err = mmc_app_cmd(host, card);
+   err = mmc_app_cmd(host, card, cmd);
if (err) {
/* no point in retrying; no APP commands allowed */
if (mmc_host_is_spi(host)) {
@@ -162,7 +168,8 @@ int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, 
u32 *rocr)
cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R3 | MMC_CMD_BCR;
 
for (i = 100; i; i--) {
-   err = mmc_wait_for_app_cmd(host, NULL, &cmd, MMC_CMD_RETRIES);
+   err = mmc_wait_for_app_cmd(host, host->card,
+   &cmd, MMC_CMD_RETRIES);
if (err)
break;
 
@@ -260,7 +267,7 @@ int mmc_app_send_scr(struct mmc_card *card, u32 *scr)
 
/* NOTE: caller guarantees scr is heap-allocated */
 
-   err = mmc_app_cmd(card->host, card);
+   err = mmc_app_cmd(card->host, card, &cmd);
if (err)
return err;
 
@@ -363,7 +370,7 @@ int mmc_app_sd_status(struct mmc_card *card, void *ssr)
 
/* NOTE: caller guarantees ssr is heap-allocated */
 
-   err = mmc_app_cmd(card->host, card);
+   err = mmc_app_cmd(card->host, card, &cmd);
if (err)
return err;
 
diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h
index 337c6b8..b9821f1 100644
--- a/include/linux/mmc/core.h
+++ b/include/linux/mmc/core.h
@@ -235,7 +235,8 @@ extern struct mmc_async_req *mmc_start_req(struct mmc_host 
*,
 extern int mmc_interrupt_hpi(struct mmc_card *);
 extern void mmc_wait_for_req(struct mmc_host *, struct mmc_request *);
 extern int mmc_wait_for_cmd(struct mmc_host *, struct mmc_command *, int);
-extern int mmc_app_cmd(struct mmc_host *, struct mmc_card *);
+extern int mmc_app_cmd(struct mmc_host *, struct mmc_card *,
+   struct mmc_command *);
 extern int mmc_wait_for_app_cmd(struct mmc_host *, struct mmc_card *,
struct mmc_command *, int);
 extern void mmc_start_bkops(struct mmc_card *card, bool from_exception);
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 03/12] mmc: core: add SD4.0 operation function

2015-04-28 Thread micky_ching
From: Micky Ching 

SD4.0 add some new operations, which include follows:

UHSII interface detect: when UHSII interface is detected, the power is up.
go/exit dormant: enter or exit dormant state.
device init: device init CCMD.
enumerate: enumerate CCMD.
config space read/write CCMD.

when we send SD command in UHSII mode, we need to pack mmc_command to
mmc_tlp_block, using tlp to transfer cmd.

Signed-off-by: Micky Ching 
Signed-off-by: Wei Wang 
---
 drivers/mmc/core/sd.c | 187 +
 drivers/mmc/core/sd.h |   1 +
 drivers/mmc/core/sd_ops.c | 210 ++
 drivers/mmc/core/sd_ops.h |   7 ++
 4 files changed, 405 insertions(+)

diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index 31a9ef2..8dd35d9 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -707,6 +707,38 @@ struct device_type sd_type = {
.groups = sd_std_groups,
 };
 
+static int mmc_sd_switch_uhsii_if(struct mmc_host *host)
+{
+   int err = 0;
+
+   if (!(host->caps & MMC_CAP_UHSII) || !host->ops->switch_uhsii_if)
+   return -ENXIO;
+
+   mmc_host_clk_hold(host);
+   err = host->ops->switch_uhsii_if(host);
+   mmc_host_clk_release(host);
+
+   if (!err)
+   host->ios.power_mode = MMC_POWER_ON;
+
+   mmc_delay(10);
+   return err;
+}
+
+static int mmc_sd_exit_dormant(struct mmc_host *host)
+{
+   int ret;
+
+   if (!(host->caps & MMC_CAP_UHSII) || !host->ops->exit_dormant)
+   return 0;
+
+   mmc_host_clk_hold(host);
+   ret = host->ops->exit_dormant(host);
+   mmc_host_clk_release(host);
+
+   return ret;
+}
+
 /*
  * Fetch CID from card.
  */
@@ -1211,6 +1243,161 @@ static const struct mmc_bus_ops mmc_sd_ops = {
.reset = mmc_sd_reset,
 };
 
+static inline void mmc_set_uhsii_ios(struct mmc_host *host)
+{
+   struct mmc_uhsii_ios *ios = &host->uhsii_ios;
+
+   pr_debug("%s: speedrange %d nfcu %d\n",
+mmc_hostname(host), ios->speed_range, ios->n_fcu);
+
+   host->ops->set_uhsii_ios(host, ios);
+}
+
+int mmc_sd_init_uhsii_card(struct mmc_card *card)
+{
+   struct mmc_host *host = card->host;
+   int err = 0, i;
+   u32 cap[2], setting;
+
+   mmc_card_set_uhsii(card);
+
+   err = mmc_sd_switch_uhsii_if(host);
+   if (err) {
+   mmc_card_clr_uhsii(card);
+   return err;
+   }
+
+   pr_debug("%s: try UHS-II interface\n", mmc_hostname(host));
+
+   for (i = 0; i < 5; i++) {
+   err = mmc_sd_send_device_init_ccmd(card);
+   if (!err)
+   break;
+
+   msleep(20);
+   }
+   if (err)
+   goto poweroff;
+
+   err = mmc_sd_send_enumerate_ccmd(card);
+   if (err)
+   goto poweroff;
+
+   err = mmc_sd_read_cfg_ccmd(card, SD40_IOADR_GEN_CAP_L, 2, cap);
+   if (err)
+   goto poweroff;
+   card->lane_mode = (cap[0] & SD40_LANE_MODE_MASK) >>
+   SD40_LANE_MODE_SHIFT;
+   card->lane_mode &= host->lane_mode;
+   pr_debug("%s: card->lane_mode = 0x%x\n",
+   mmc_hostname(host), card->lane_mode);
+
+   err = mmc_sd_read_cfg_ccmd(card, SD40_IOADR_PHY_CAP_L, 2, cap);
+   if (err)
+   goto poweroff;
+   card->n_lss_dir = (cap[1] & 0xF0) >> 4;
+   card->n_lss_syn = cap[1] & 0x0F;
+   pr_debug("%s: card->n_lss_dir = %d, card->n_lss_syn = %d\n",
+   mmc_hostname(host), card->n_lss_dir, card->n_lss_syn);
+
+   err = mmc_sd_read_cfg_ccmd(card, SD40_IOADR_LINK_CAP_L, 2, cap);
+   if (err)
+   goto poweroff;
+   card->n_fcu = (cap[0] & 0xFF00) >> 8;
+   card->max_retry_num = (cap[0] & 0x3) >> 16;
+   card->max_blklen = (cap[0] & 0xFFF0) >> 20;
+   card->n_data_gap = cap[1] & 0xFF;
+   pr_debug("%s: card->n_fcu = %d\n", mmc_hostname(host), card->n_fcu);
+   pr_debug("%s: card->max_retry_num = %d\n",
+   mmc_hostname(host), card->max_retry_num);
+   pr_debug("%s: card->max_blklen = %d\n",
+   mmc_hostname(host), card->max_blklen);
+   pr_debug("%s: card->n_data_gap = %d\n",
+   mmc_hostname(host), card->n_data_gap);
+
+   if (card->n_lss_dir < host->n_lss_dir)
+   card->n_lss_dir = host->n_lss_dir;
+   if (card->n_lss_syn < host->n_lss_syn)
+   card->n_lss_syn = host->n_lss_syn;
+   setting = ((card->n_lss_dir << 4) & 0xF0) | (card->n_lss_syn & 0x0F);
+   err = mmc_sd_write_cfg_ccmd(card,
+   SD40_IOADR_PHY_SET_H, 1, &setting);
+   if (err)
+   goto poweroff;
+
+   if (card->n_data_gap < host->n_data_gap)
+   card->n_data_gap = host->n_data_gap;
+   setting = card->n_data_gap;
+   err = mmc_sd_write_cfg_ccmd(card,
+   SD40_IOADR_LINK_SET_H, 1, &setting);
+   if (err)
+

[PATCH 07/12] mmc: sdhci: add data structure for SD4.0

2015-04-28 Thread micky_ching
From: Micky Ching 

add SD4.0 register define and host data structure for
handshake with SD4.0 card.

Signed-off-by: Micky Ching 
Signed-off-by: Wei Wang 
---
 drivers/mmc/host/sdhci.h | 136 ++-
 1 file changed, 135 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index e639b7f..659eb64 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -73,6 +73,9 @@
 #define  SDHCI_DATA_LVL_MASK   0x00F0
 #define   SDHCI_DATA_LVL_SHIFT 20
 #define   SDHCI_DATA_0_LVL_MASK0x0010
+#define  SDHCI_IN_DORMANT_STATE0x2000
+#define  SDHCI_LANE_SYNC   0x4000
+#define  SDHCI_STBL_DETECT 0x8000
 
 #define SDHCI_HOST_CONTROL 0x28
 #define  SDHCI_CTRL_LED0x01
@@ -90,6 +93,8 @@
 #define  SDHCI_POWER_180   0x0A
 #define  SDHCI_POWER_300   0x0C
 #define  SDHCI_POWER_330   0x0E
+#define  SDHCI_VDD1_SHIFT  0
+#define  SDHCI_VDD2_SHIFT  4
 
 #define SDHCI_BLOCK_GAP_CONTROL0x2A
 
@@ -162,6 +167,7 @@
 #define   SDHCI_CTRL_UHS_SDR1040x0003
 #define   SDHCI_CTRL_UHS_DDR50 0x0004
 #define   SDHCI_CTRL_HS400 0x0005 /* Non-standard */
+#define   SDHCI_CTRL_UHSII 0x0007
 #define  SDHCI_CTRL_VDD_1800x0008
 #define  SDHCI_CTRL_DRV_TYPE_MASK  0x0030
 #define   SDHCI_CTRL_DRV_TYPE_B0x
@@ -170,6 +176,10 @@
 #define   SDHCI_CTRL_DRV_TYPE_D0x0030
 #define  SDHCI_CTRL_EXEC_TUNING0x0040
 #define  SDHCI_CTRL_TUNED_CLK  0x0080
+#define  SDHCI_CTRL_UHSII_IF_ENABLE0x0100
+#define  SDHCI_CTRL_HOST_V4_ENABLE 0x1000
+#define  SDHCI_CTRL_64BIT_ADDR_ENABLE  0x2000
+#define  SDHCI_CTRL_ASYNC_INT_ENABLE   0x4000
 #define  SDHCI_CTRL_PRESET_VAL_ENABLE  0x8000
 
 #define SDHCI_CAPABILITIES 0x40
@@ -194,6 +204,7 @@
 #define  SDHCI_SUPPORT_SDR50   0x0001
 #define  SDHCI_SUPPORT_SDR104  0x0002
 #define  SDHCI_SUPPORT_DDR50   0x0004
+#define  SDHCI_SUPPORT_UHSII   0x0008
 #define  SDHCI_DRIVER_TYPE_A   0x0010
 #define  SDHCI_DRIVER_TYPE_C   0x0020
 #define  SDHCI_DRIVER_TYPE_D   0x0040
@@ -205,6 +216,8 @@
 #define  SDHCI_CLOCK_MUL_MASK  0x00FF
 #define  SDHCI_CLOCK_MUL_SHIFT 16
 #define  SDHCI_SUPPORT_HS400   0x8000 /* Non-standard */
+#define  SDHCI_CAN_DO_ADMA30x0800
+#define  SDHCI_CAN_VDD2_1800x1000
 
 #define SDHCI_CAPABILITIES_1   0x44
 
@@ -230,7 +243,7 @@
 #define SDHCI_ADMA_ADDRESS 0x58
 #define SDHCI_ADMA_ADDRESS_HI  0x5C
 
-/* 60-FB reserved */
+/* 60-73 reserved */
 
 #define SDHCI_PRESET_FOR_SDR12 0x66
 #define SDHCI_PRESET_FOR_SDR25 0x68
@@ -245,6 +258,71 @@
 #define SDHCI_PRESET_SDCLK_FREQ_MASK   0x3FF
 #define SDHCI_PRESET_SDCLK_FREQ_SHIFT  0
 
+#define SDHCI_PRESET_VALUE_UHSII   0x74
+#define SDHCI_ADMA3_ID_ADDRESS 0x78
+
+#define SDHCI_UHSII_BLOCK_SIZE 0x80
+#define SDHCI_UHSII_BLOCK_COUNT0x84
+
+#define SDHCI_UHSII_CMD_PACKET 0x88
+#define  SDHCI_UHSII_CMD_PACK_LEN  20
+#define SDHCI_UHSII_CMD_HEADER (SDHCI_UHSII_CMD_PACKET)
+#define SDHCI_UHSII_CMD_ARGUMENT   (SDHCI_UHSII_CMD_PACKET + 2)
+#define SDHCI_UHSII_CMD_PAYLOAD(SDHCI_UHSII_CMD_PACKET + 4)
+
+#define SDHCI_UHSII_TRANSFER_MODE  0x9C
+#define  SDHCI_UHSII_TRNS_DMA  0x01
+#define  SDHCI_UHSII_TRNS_BLK_CNT_EN   0x02
+#define  SDHCI_UHSII_TRNS_WRITE0x10
+#define  SDHCI_UHSII_TRNS_BYTE_MODE0x20
+#define  SDHCI_UHSII_TRNS_WAIT_EBSY0x4000
+#define  SDHCI_UHSII_TRANS_2LANE_HD0x8000
+#define SDHCI_UHSII_COMMAND0x9E
+#define  SDHCI_UHSII_DATA_PRESENT  0x0020
+#define  SDHCI_UHSII_NORMAL_COMMAND(0 << 6)
+#define  SDHCI_UHSII_TRANS_ABORT_CCMD  (1 << 6)
+#define  SDHCI_UHSII_ABORT_COMMAND (2 << 6)
+#define  SDHCI_UHSII_GO_DORMANT(3 << 6)
+#define  SDHCI_UHSII_COMMAND_LEN_SHIFT 8
+#define  SDHCI_UHSII_COMMAND_LEN_MASK  0x1F
+
+#define SDHCI_UHSII_RESPONSE   0xA0
+#define  SDHCI_UHSII_RESP_LEN  20
+#define SDHCI_UHSII_RESP_HEADERSDHCI_UHSII_RESPONSE
+#define SDHCI_UHSII_RESP_ARGUMENT  (SDHCI_UHSII_RESPONSE + 2)
+#define SDHCI_UHSII_RESP_PAYLOAD   (SDHCI_UHSII_RESPONSE + 4)
+
+#define SDHCI_UHSII_MSG_SEL0xB4
+#define SDHCI_UHSII_MSG_REG0xB8
+#define SDHCI_UHSII_DEV_INT_STATUS 0xBC
+#define SDHCI_UHSII_DEV_SEL0xBE
+#define SDHCI_UHSII_INT_CODE   0xBF
+#define SDHCI_UHSII_SOFT_RESET 0xC0
+#define  SDHCI_UHSII_HOST_FULL_RESET   0x0001
+#define SDHCI_UHSII_TIMER_CONTROL  0xC2
+#define SDHCI_UHSII_INT_STATUS 0xC4
+#define SDHCI_UHSII_INT_ENABLE 0xC8
+#define SDHCI_UHSII_SIGNAL_ENABLE  0xCC
+#define  SDHCI_UHSII_INT_HEADER0x0001
+#define  SDHCI_UHSII_INT_RES   0x0002
+#define  SDHCI_UHSII_INT_EXPIRED   0x0004
+#define  S

[PATCH 05/12] mmc: core: disable full power cycle for SD4.0

2015-04-28 Thread micky_ching
From: Micky Ching 

We should not do power cycle when card is in SD4.0 mode,
if we power off, we should detect UHSII interface again.
so we can disable it when card is in UHSII mode.

Signed-off-by: Micky Ching 
Signed-off-by: Wei Wang 
---
 drivers/mmc/core/core.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index ebb6fea..4c5433b 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -1550,7 +1550,8 @@ u32 mmc_select_voltage(struct mmc_host *host, u32 ocr)
return 0;
}
 
-   if (host->caps2 & MMC_CAP2_FULL_PWR_CYCLE) {
+   if (!mmc_card_uhsii(host->card) &&
+   (host->caps2 & MMC_CAP2_FULL_PWR_CYCLE)) {
bit = ffs(ocr) - 1;
ocr &= 3 << bit;
mmc_power_cycle(host, ocr);
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 09/12] mmc: sdhci: add tlp handler for SD4.0

2015-04-28 Thread micky_ching
From: Micky Ching 

SD4.0 mode using tlp for cmd/data transfer, add tlp functions to handle
this case.

Signed-off-by: Micky Ching 
Signed-off-by: Wei Wang 
---
 drivers/mmc/host/sdhci.c | 244 ++-
 1 file changed, 220 insertions(+), 24 deletions(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index df1b88d..3c56944 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -976,6 +976,32 @@ static void sdhci_set_transfer_mode(struct sdhci_host 
*host,
sdhci_writew(host, mode, SDHCI_TRANSFER_MODE);
 }
 
+static void sdhci_uhsii_set_transfer_mode(struct sdhci_host *host,
+   struct mmc_command *cmd)
+{
+   u16 mode = 0;
+   struct mmc_data *data = cmd->data;
+
+   if (UHSII_CHK_CCMD(cmd->tlp_send.header)) {
+   if (cmd->flags & MMC_RSP_BUSY)
+   mode |= SDHCI_UHSII_TRNS_WAIT_EBSY;
+   } else {
+   u8 tmode = (cmd->tlp_send.argument & UHSII_ARG_TMODE_MASK) >>
+   UHSII_ARG_TMODE_SHIFT;
+   if (tmode & UHSII_TMODE_DM_HD)
+   mode |= SDHCI_UHSII_TRANS_2LANE_HD;
+   mode |= SDHCI_UHSII_TRNS_BLK_CNT_EN;
+   mode |= SDHCI_UHSII_TRNS_WAIT_EBSY;
+
+   if (data->flags & MMC_DATA_WRITE)
+   mode |= SDHCI_UHSII_TRNS_WRITE;
+   if (host->flags & SDHCI_REQ_USE_DMA)
+   mode |= SDHCI_UHSII_TRNS_DMA;
+   }
+
+   sdhci_writew(host, mode, SDHCI_UHSII_TRANSFER_MODE);
+}
+
 static void sdhci_finish_data(struct sdhci_host *host)
 {
struct mmc_data *data;
@@ -1014,7 +1040,7 @@ static void sdhci_finish_data(struct sdhci_host *host)
 * a) open-ended multiblock transfer (no CMD23)
 * b) error in multiblock transfer
 */
-   if (data->stop &&
+   if (!host->uhsii_if_enabled && data->stop &&
(data->error ||
 !host->mrq->sbc)) {
 
@@ -1032,6 +1058,51 @@ static void sdhci_finish_data(struct sdhci_host *host)
tasklet_schedule(&host->finish_tasklet);
 }
 
+static void sdhci_send_native_tlp(struct sdhci_host *host, struct mmc_tlp *tlp)
+{
+   int i;
+   unsigned long timeout;
+   u16 cmdreg;
+   u8 plen, cmd_len = 4;
+
+   /* Wait max 10 ms */
+   timeout = 10;
+
+   if (sdhci_checkl(host, SDHCI_PRESENT_STATE, SDHCI_CMD_INHIBIT, 0, 10)) {
+   pr_err("%s: cmd busy...\n", mmc_hostname(host->mmc));
+   sdhci_dumpregs(host);
+   tlp->error = -EIO;
+   tasklet_schedule(&host->finish_tasklet);
+   return;
+   }
+
+   mod_timer(&host->timer, jiffies + 10 * HZ);
+
+   host->tlp = tlp;
+
+   plen = (u8)((tlp->tlp_send->argument & UHSII_ARG_PLEN_MASK) >>
+   UHSII_ARG_PLEN_SHIFT);
+
+   sdhci_writew(host, cpu_to_be16(tlp->tlp_send->header),
+   SDHCI_UHSII_CMD_HEADER);
+   sdhci_writew(host, cpu_to_be16(tlp->tlp_send->argument),
+   SDHCI_UHSII_CMD_ARGUMENT);
+   if (tlp->tlp_send->argument & UHSII_ARG_DIR_WRITE) {
+   for (i = 0; i < UHSII_PLEN_DWORDS(plen); i++)
+   sdhci_writel(host,
+   cpu_to_be32(tlp->tlp_send->payload[i]),
+   SDHCI_UHSII_CMD_PAYLOAD + 4 * i);
+
+   cmd_len = UHSII_PLEN_BYTES(plen) + 4;
+   }
+
+   cmdreg = (cmd_len & SDHCI_UHSII_COMMAND_LEN_MASK) <<
+   SDHCI_UHSII_COMMAND_LEN_SHIFT;
+   if (tlp->cmd_type == UHSII_COMMAND_GO_DORMANT)
+   cmdreg |= SDHCI_UHSII_GO_DORMANT;
+   sdhci_writew(host, cmdreg, SDHCI_UHSII_COMMAND);
+}
+
 void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
 {
int flags;
@@ -1077,6 +1148,35 @@ void sdhci_send_command(struct sdhci_host *host, struct 
mmc_command *cmd)
 
sdhci_prepare_data(host, cmd);
 
+   if (cmd->use_tlp) {
+   int i;
+   u16 cmdreg;
+   u8 plen = 1, cmd_len = 8;
+
+   if (!UHSII_CHK_CCMD(cmd->tlp_send.header)) {
+   plen = 2;
+   cmd_len = 12;
+   }
+
+   sdhci_writew(host, cpu_to_be16(cmd->tlp_send.header),
+   SDHCI_UHSII_CMD_HEADER);
+   sdhci_writew(host, cpu_to_be16(cmd->tlp_send.argument),
+   SDHCI_UHSII_CMD_ARGUMENT);
+   for (i = 0; i < plen; i++)
+   sdhci_writel(host,
+   cpu_to_be32(cmd->tlp_send.payload[i]),
+   SDHCI_UHSII_CMD_PAYLOAD + (4 * i));
+
+   sdhci_uhsii_set_transfer_mode(host, cmd);
+
+   cmdreg = (cmd_len & SDHCI_UHSII_COMMAND_LEN_MASK) <<
+   SDHCI_UHSII_COMMAND_LEN_SHIFT;
+   if (cmd->data)
+   cmdreg |= 

[PATCH 06/12] mmc: core: init SD4.0 mode before legacy mode

2015-04-28 Thread micky_ching
From: Micky Ching 

We alloc card before init card, if init UHSII mode failed, then
try to init legacy mode.

Since we card is allocated before do init operations, so mmc/sdio
card init should do some modify. To reduce many diff hunks, the old
labels are reserved(we can remove them in the future).

Signed-off-by: Micky Ching 
Signed-off-by: Wei Wang 
---
 drivers/mmc/core/core.c |  60 +---
 drivers/mmc/core/mmc.c  |  63 +
 drivers/mmc/core/sd.c   |  95 +++-
 drivers/mmc/core/sdio.c | 103 +---
 4 files changed, 169 insertions(+), 152 deletions(-)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 4c5433b..d9e904f 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -2435,16 +2435,8 @@ int mmc_hw_reset(struct mmc_host *host)
 }
 EXPORT_SYMBOL(mmc_hw_reset);
 
-static int mmc_rescan_try_freq(struct mmc_host *host, unsigned freq)
+static int mmc_reset_card(struct mmc_host *host)
 {
-   host->f_init = freq;
-
-#ifdef CONFIG_MMC_DEBUG
-   pr_info("%s: %s: trying to init card at %u Hz\n",
-   mmc_hostname(host), __func__, host->f_init);
-#endif
-   mmc_power_up(host, host->ocr_avail);
-
/*
 * Some eMMCs (with VCCQ always on) may not be reset after power up, so
 * do a hardware reset if possible.
@@ -2473,6 +2465,20 @@ static int mmc_rescan_try_freq(struct mmc_host *host, 
unsigned freq)
return -EIO;
 }
 
+static int mmc_rescan_try_freq(struct mmc_host *host, unsigned freq)
+{
+   host->f_init = freq;
+
+#ifdef CONFIG_MMC_DEBUG
+   pr_info("%s: %s: trying to init card at %u Hz\n",
+   mmc_hostname(host), __func__, host->f_init);
+#endif
+
+   mmc_power_up(host, host->ocr_avail);
+
+   return mmc_reset_card(host);
+}
+
 int _mmc_detect_card_removed(struct mmc_host *host)
 {
int ret;
@@ -2544,7 +2550,8 @@ void mmc_rescan(struct work_struct *work)
 {
struct mmc_host *host =
container_of(work, struct mmc_host, detect.work);
-   int i;
+   struct mmc_card *card;
+   int i, err;
 
if (host->trigger_card_event && host->ops->card_event) {
host->ops->card_event(host);
@@ -2599,14 +2606,37 @@ void mmc_rescan(struct work_struct *work)
}
 
mmc_claim_host(host);
-   for (i = 0; i < ARRAY_SIZE(freqs); i++) {
-   if (!mmc_rescan_try_freq(host, max(freqs[i], host->f_min)))
-   break;
-   if (freqs[i] <= host->f_min)
-   break;
+
+   card = mmc_alloc_card(host, NULL);
+   if (IS_ERR(card)) {
+   mmc_release_host(host);
+   goto out;
}
+   host->card = card;
+
+   mmc_sd_init_uhsii_card(card);
+
+   if (mmc_card_uhsii(card)) {
+   err = mmc_reset_card(host);
+   } else {
+   for (i = 0; i < ARRAY_SIZE(freqs); i++) {
+   err = mmc_rescan_try_freq(host,
+   max(freqs[i], host->f_min));
+   if (!err)
+   break;
+   if (freqs[i] <= host->f_min)
+   break;
+   }
+   }
+
mmc_release_host(host);
 
+   /* Attach fail, free host->card */
+   if (err) {
+   mmc_remove_card(host->card);
+   host->card = NULL;
+   }
+
  out:
if (host->caps & MMC_CAP_NEEDS_POLL)
mmc_schedule_delayed_work(&host->detect, HZ);
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index f36c76f..ddb8831 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -1187,14 +1187,10 @@ static int mmc_hs200_tuning(struct mmc_card *card)
 
 /*
  * Handle the detection and initialisation of a card.
- *
- * In the case of a resume, "oldcard" will contain the card
- * we're trying to reinitialise.
  */
-static int mmc_init_card(struct mmc_host *host, u32 ocr,
-   struct mmc_card *oldcard)
+static int mmc_do_init_card(struct mmc_host *host, u32 ocr,
+   struct mmc_card *card, bool reinit)
 {
-   struct mmc_card *card;
int err;
u32 cid[4];
u32 rocr;
@@ -1239,23 +1235,13 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
if (err)
goto err;
 
-   if (oldcard) {
-   if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) {
+   if (reinit) {
+   if (memcmp(cid, card->raw_cid, sizeof(cid)) != 0) {
err = -ENOENT;
goto err;
}
-
-   card = oldcard;
} else {
-   /*
-* Allocate card structure.
-*/
-   card = mmc_alloc_card(host, &mmc_type);
-   if (IS_ERR(card)) {
-   err = PTR_ERR(card)

[PATCH 04/12] mmc: core: add tlp request handler for SD4.0

2015-04-28 Thread micky_ching
From: Micky Ching 

when card is work in SD4.0 mode, we should send tlp instead of cmd.
add this function to handle tlp request.

Signed-off-by: Micky Ching 
Signed-off-by: Wei Wang 
---
 drivers/mmc/core/core.c | 111 +---
 1 file changed, 104 insertions(+), 7 deletions(-)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index c296bc0..ebb6fea 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -45,6 +45,7 @@
 #include "mmc_ops.h"
 #include "sd_ops.h"
 #include "sdio_ops.h"
+#include "sd.h"
 
 /* If the device is not responding */
 #define MMC_CORE_TIMEOUT_MS(10 * 60 * 1000) /* 10 minute timeout */
@@ -131,7 +132,42 @@ static inline void mmc_should_fail_request(struct mmc_host 
*host,
 void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq)
 {
struct mmc_command *cmd = mrq->cmd;
-   int err = cmd->error;
+   struct mmc_tlp *tlp = mrq->tlp;
+   int err;
+
+   if (tlp && cmd)
+   pr_debug("%s: cmd and native tlp conflict, done native tlp\n",
+   mmc_hostname(host));
+
+   if (tlp) {
+   err = tlp->error;
+   if (err && tlp->retries && !mmc_card_removed(host->card)) {
+   /*
+* Request starter must handle retries - see
+* mmc_wait_for_req_done().
+*/
+   if (mrq->done)
+   mrq->done(mrq);
+   } else {
+   led_trigger_event(host->led, LED_OFF);
+
+   pr_debug("%s: native TLP req done(%d) %04x %04x %08x 
%08x %08x %08x\n",
+   mmc_hostname(host), err,
+   tlp->tlp_back->header, tlp->tlp_back->argument,
+   tlp->tlp_back->payload[0],
+   tlp->tlp_back->payload[1],
+   tlp->tlp_back->payload[2],
+   tlp->tlp_back->payload[3]);
+
+   if (mrq->done)
+   mrq->done(mrq);
+
+   mmc_host_clk_release(host);
+   }
+   return;
+   }
+
+   err = cmd->error;
 
if (err && cmd->retries && mmc_host_is_spi(host)) {
if (cmd->resp[0] & R1_SPI_ILLEGAL_COMMAND)
@@ -201,9 +237,18 @@ static int mmc_start_request(struct mmc_host *host, struct 
mmc_request *mrq)
 mrq->sbc->arg, mrq->sbc->flags);
}
 
-   pr_debug("%s: starting CMD%u arg %08x flags %08x\n",
-mmc_hostname(host), mrq->cmd->opcode,
-mrq->cmd->arg, mrq->cmd->flags);
+   if (mrq->tlp && mrq->cmd)
+   pr_debug("%s: cmd and native tlp conflict, start native tlp\n",
+   mmc_hostname(host));
+
+   if (mrq->tlp)
+   pr_debug("%s: starting native TLP header %04x argument %04x\n",
+mmc_hostname(host), mrq->tlp->tlp_send->header,
+mrq->tlp->tlp_send->argument);
+   else if (mrq->cmd)
+   pr_debug("%s: starting CMD%u arg %08x flags %08x\n",
+mmc_hostname(host), mrq->cmd->opcode,
+mrq->cmd->arg, mrq->cmd->flags);
 
if (mrq->data) {
pr_debug("%s: blksz %d blocks %d flags %08x "
@@ -221,6 +266,8 @@ static int mmc_start_request(struct mmc_host *host, struct 
mmc_request *mrq)
}
 
WARN_ON(!host->claimed);
+   if (!mrq->cmd)
+   goto start;
 
mrq->cmd->error = 0;
mrq->cmd->mrq = mrq;
@@ -250,6 +297,25 @@ static int mmc_start_request(struct mmc_host *host, struct 
mmc_request *mrq)
mrq->stop->mrq = mrq;
}
}
+
+   if (mmc_card_uhsii(host->card)) {
+   mrq->cmd->use_tlp = true;
+   if (mrq->data)
+   mmc_sd_tran_pack_dcmd(host->card, mrq->cmd);
+   else
+   mmc_sd_tran_pack_ccmd(host->card, mrq->cmd);
+
+   if (mrq->sbc) {
+   mrq->sbc->use_tlp = true;
+   mmc_sd_tran_pack_ccmd(host->card, mrq->sbc);
+   }
+   if (mrq->stop) {
+   mrq->stop->use_tlp = true;
+   mmc_sd_tran_pack_ccmd(host->card, mrq->stop);
+   }
+   }
+
+start:
mmc_host_clk_hold(host);
led_trigger_event(host->led, LED_FULL);
host->ops->request(host, mrq);
@@ -356,7 +422,7 @@ static int __mmc_start_data_req(struct mmc_host *host, 
struct mmc_request *mrq)
 
err = mmc_start_request(host, mrq);
if (err) {
-   mrq->cmd->error = err;
+   mmc_set_mrq_error_code(mrq, err);
mmc_wait_data_done(mrq);
}
 
@@ -372,7 +438,7 @@ static int __mmc_st

[PATCH 11/12] mmc: sdhci: set DMA configure for SD4.0 mode

2015-04-28 Thread micky_ching
From: Micky Ching 

SD4.0 mode not using SDMA any more, and UHSII mode using different register
to specify block size/count.

Signed-off-by: Micky Ching 
Signed-off-by: Wei Wang 
---
 drivers/mmc/host/sdhci.c | 22 +-
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 03df58c..15bd7c8 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -883,8 +883,14 @@ static void sdhci_prepare_data(struct sdhci_host *host, 
struct mmc_command *cmd)
host->flags &= ~SDHCI_REQ_USE_DMA;
} else {
WARN_ON(sg_cnt != 1);
-   sdhci_writel(host, sg_dma_address(data->sg),
-   SDHCI_DMA_ADDRESS);
+   if (host->uhsii_if_enabled)
+   sdhci_writel(host,
+   sg_dma_address(data->sg),
+   SDHCI_ADMA_ADDRESS);
+   else
+   sdhci_writel(host,
+   sg_dma_address(data->sg),
+   SDHCI_DMA_ADDRESS);
}
}
}
@@ -924,9 +930,15 @@ static void sdhci_prepare_data(struct sdhci_host *host, 
struct mmc_command *cmd)
sdhci_set_transfer_irqs(host);
 
/* Set the DMA boundary value and block size */
-   sdhci_writew(host, SDHCI_MAKE_BLKSZ(SDHCI_DEFAULT_BOUNDARY_ARG,
-   data->blksz), SDHCI_BLOCK_SIZE);
-   sdhci_writew(host, data->blocks, SDHCI_BLOCK_COUNT);
+   if (host->uhsii_if_enabled) {
+   sdhci_writew(host, SDHCI_MAKE_BLKSZ(SDHCI_DEFAULT_BOUNDARY_ARG,
+   data->blksz), SDHCI_UHSII_BLOCK_SIZE);
+   sdhci_writew(host, data->blocks, SDHCI_UHSII_BLOCK_COUNT);
+   } else {
+   sdhci_writew(host, SDHCI_MAKE_BLKSZ(SDHCI_DEFAULT_BOUNDARY_ARG,
+   data->blksz), SDHCI_BLOCK_SIZE);
+   sdhci_writew(host, data->blocks, SDHCI_BLOCK_COUNT);
+   }
 }
 
 static void sdhci_set_transfer_mode(struct sdhci_host *host,
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 00/12] mmc: core: add SD4.0 support

2015-04-28 Thread micky_ching
From: Micky Ching 

Add support for SD4.0 card, which introduce UHSII mode and tlp transfer.

Micky Ching (12):
  mmc: core: add data structure define for SD4.0
  mmc: core: modify mmc_app_cmd interface for SD4.0
  mmc: core: add SD4.0 operation function
  mmc: core: add tlp request handler for SD4.0
  mmc: core: disable full power cycle for SD4.0
  mmc: core: init SD4.0 mode before legacy mode
  mmc: sdhci: add data structure for SD4.0
  mmc: sdhci: add SD4.0 operations
  mmc: sdhci: add tlp handler for SD4.0
  mmc: sdhci: disable clock control for SD4.0 mode
  mmc: sdhci: set DMA configure for SD4.0 mode
  mmc: sdhci: add SD4.0 support

 drivers/mmc/card/block.c  |   2 +-
 drivers/mmc/core/core.c   | 174 --
 drivers/mmc/core/mmc.c|  63 +++--
 drivers/mmc/core/sd.c | 282 ++
 drivers/mmc/core/sd.h |   1 +
 drivers/mmc/core/sd_ops.c | 227 +-
 drivers/mmc/core/sd_ops.h |   7 +
 drivers/mmc/core/sdio.c   | 103 -
 drivers/mmc/host/sdhci.c  | 579 ++
 drivers/mmc/host/sdhci.h  | 136 ++-
 include/linux/mmc/card.h  |  13 ++
 include/linux/mmc/core.h  |  91 +++-
 include/linux/mmc/host.h  |  33 +++
 include/linux/mmc/sd.h|  73 ++
 14 files changed, 1572 insertions(+), 212 deletions(-)

-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 08/12] mmc: sdhci: add SD4.0 operations

2015-04-28 Thread micky_ching
From: Micky Ching 

SD4.0 operations include UHSII interface detect, go/exit dormant
and uhsii ios settings.

Signed-off-by: Micky Ching 
Signed-off-by: Wei Wang 
---
 drivers/mmc/host/sdhci.c | 183 ++-
 1 file changed, 182 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index c80287a..df1b88d 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -143,6 +143,32 @@ static void sdhci_dumpregs(struct sdhci_host *host)
  *   *
 \*/
 
+static int sdhci_checkw(struct sdhci_host *host, int reg,
+   u16 mask, u16 done, int msec)
+{
+   while (msec > 0) {
+   if ((sdhci_readw(host, reg) & mask) == done)
+   return 0;
+   mdelay(1);
+   msec--;
+   };
+   DBG("check %x(%x) %x failed\n", reg, mask, done);
+   return -ETIMEDOUT;
+}
+
+static int sdhci_checkl(struct sdhci_host *host, int reg,
+   u32 mask, u32 done, int msec)
+{
+   while (msec > 0) {
+   if ((sdhci_readl(host, reg) & mask) == done)
+   return 0;
+   mdelay(1);
+   msec--;
+   };
+   DBG("check %x(%x) %x failed\n", reg, mask, done);
+   return -ETIMEDOUT;
+}
+
 static void sdhci_set_card_detection(struct sdhci_host *host, bool enable)
 {
u32 present;
@@ -2224,6 +2250,158 @@ static void sdhci_card_event(struct mmc_host *mmc)
spin_unlock_irqrestore(&host->lock, flags);
 }
 
+static int sdhci_switch_uhsii_if(struct mmc_host *mmc)
+{
+   struct sdhci_host *host = mmc_priv(mmc);
+   unsigned long flags;
+   int err = 0;
+   u32 present;
+   u16 clk, ctrl2;
+   u8 pwr;
+
+   host->uhsii_if_enabled = false;
+   spin_lock_irqsave(&host->lock, flags);
+
+   clk = SDHCI_CLOCK_INT_EN;
+   sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
+
+   if (sdhci_checkw(host, SDHCI_CLOCK_CONTROL,
+   SDHCI_CLOCK_INT_STABLE,
+   SDHCI_CLOCK_INT_STABLE, 20) < 0) {
+   pr_err("%s: Internal clock not ready.\n",
+   mmc_hostname(host->mmc));
+   sdhci_dumpregs(host);
+   err = -ETIMEDOUT;
+   goto out;
+   }
+
+   ctrl2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
+   ctrl2 |= SDHCI_CTRL_UHSII_IF_ENABLE;
+   sdhci_writew(host, ctrl2, SDHCI_HOST_CONTROL2);
+
+   pwr = (SDHCI_POWER_ON | SDHCI_POWER_330) << SDHCI_VDD1_SHIFT;
+   pwr |= (SDHCI_POWER_ON | SDHCI_POWER_180) << SDHCI_VDD2_SHIFT;
+   sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
+
+   ctrl2 |= SDHCI_CTRL_UHSII;
+   sdhci_writew(host, ctrl2, SDHCI_HOST_CONTROL2);
+
+   /* Wait Power Ramp Up Time */
+   spin_unlock_irqrestore(&host->lock, flags);
+   msleep(20);
+   spin_lock_irqsave(&host->lock, flags);
+
+   clk |= SDHCI_CLOCK_CARD_EN;
+   sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
+
+   udelay(200);
+
+   present = sdhci_readl(host, SDHCI_PRESENT_STATE);
+   if (present & SDHCI_STBL_DETECT) {
+   if (sdhci_checkl(host, SDHCI_PRESENT_STATE,
+   SDHCI_LANE_SYNC,
+   SDHCI_LANE_SYNC, 20) < 0) {
+   pr_err("%s: UHS-II PHY is not initialized\n",
+   mmc_hostname(host->mmc));
+   sdhci_dumpregs(host);
+   err = -ETIMEDOUT;
+   goto out;
+   }
+   host->uhsii_if_enabled = true;
+   } else {
+   pr_info("%s: UHS-II IF is not detected\n",
+   mmc_hostname(host->mmc));
+   goto out;
+   }
+
+out:
+   if (!host->uhsii_if_enabled) {
+   pwr = SDHCI_POWER_330 << SDHCI_VDD1_SHIFT;
+   pwr |= SDHCI_POWER_180 << SDHCI_VDD2_SHIFT;
+   sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
+
+   spin_unlock_irqrestore(&host->lock, flags);
+   msleep(100);
+   spin_lock_irqsave(&host->lock, flags);
+
+   ctrl2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
+   ctrl2 &= ~SDHCI_CTRL_UHSII_IF_ENABLE;
+   ctrl2 &= ~SDHCI_CTRL_UHS_MASK;
+   sdhci_writew(host, ctrl2, SDHCI_HOST_CONTROL2);
+
+   err = -ENXIO;
+   }
+
+   spin_unlock_irqrestore(&host->lock, flags);
+   return err;
+}
+
+static int sdhci_exit_dormant(struct mmc_host *mmc)
+{
+   struct sdhci_host *host = mmc_priv(mmc);
+   u16 clk;
+
+   clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
+   clk |= SDHCI_CLOCK_CARD_EN;
+   sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
+
+   udelay(200);
+
+   if (sdhci_checkl(host, SDHCI_PRESENT_STATE,
+ 

[PATCH 10/12] mmc: sdhci: disable clock control for SD4.0 mode

2015-04-28 Thread micky_ching
From: Micky Ching 

Skip clock control settings for UHSII mode. When card is in UHSII mode,
we only allow poweroff.

Signed-off-by: Micky Ching 
Signed-off-by: Wei Wang 
---
 drivers/mmc/host/sdhci.c | 22 ++
 1 file changed, 14 insertions(+), 8 deletions(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 3c56944..03df58c 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1346,7 +1346,8 @@ void sdhci_set_clock(struct sdhci_host *host, unsigned 
int clock)
 
host->mmc->actual_clock = 0;
 
-   sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
+   if (!host->uhsii_if_enabled)
+   sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
 
if (clock == 0)
return;
@@ -1686,7 +1687,8 @@ static void sdhci_do_set_ios(struct sdhci_host *host, 
struct mmc_ios *ios)
!(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN))
sdhci_enable_preset_value(host, false);
 
-   if (!ios->clock || ios->clock != host->clock) {
+   if (!host->uhsii_if_enabled &&
+   (!ios->clock || ios->clock != host->clock)) {
host->ops->set_clock(host, ios->clock);
host->clock = ios->clock;
 
@@ -1703,7 +1705,8 @@ static void sdhci_do_set_ios(struct sdhci_host *host, 
struct mmc_ios *ios)
}
}
 
-   sdhci_set_power(host, ios->power_mode, ios->vdd);
+   if (!(host->uhsii_if_enabled && (ios->power_mode != MMC_POWER_OFF)))
+   sdhci_set_power(host, ios->power_mode, ios->vdd);
 
if (host->ops->platform_send_init_74_clocks)
host->ops->platform_send_init_74_clocks(host, ios->power_mode);
@@ -1765,10 +1768,12 @@ static void sdhci_do_set_ios(struct sdhci_host *host, 
struct mmc_ios *ios)
host->ops->set_clock(host, host->clock);
}
 
-   /* Reset SD Clock Enable */
-   clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
-   clk &= ~SDHCI_CLOCK_CARD_EN;
-   sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
+   if (!host->uhsii_if_enabled) {
+   /* Reset SD Clock Enable */
+   clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
+   clk &= ~SDHCI_CLOCK_CARD_EN;
+   sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
+   }
 
host->ops->set_uhs_signaling(host, ios->timing);
host->timing = ios->timing;
@@ -1788,7 +1793,8 @@ static void sdhci_do_set_ios(struct sdhci_host *host, 
struct mmc_ios *ios)
}
 
/* Re-enable SD Clock */
-   host->ops->set_clock(host, host->clock);
+   if (!host->uhsii_if_enabled)
+   host->ops->set_clock(host, host->clock);
} else
sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
 
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 12/12] mmc: sdhci: add SD4.0 support

2015-04-28 Thread micky_ching
From: Micky Ching 

Add support for SD4.0 card.

Signed-off-by: Micky Ching 
Signed-off-by: Wei Wang 
---
 drivers/mmc/host/sdhci.c | 108 ---
 1 file changed, 102 insertions(+), 6 deletions(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 15bd7c8..6ba8699 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -256,6 +256,9 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct 
mmc_ios *ios);
 
 static void sdhci_init(struct sdhci_host *host, int soft)
 {
+   if ((host->flags & SDHCI_HOST_V4_ENABLED) && !soft)
+   sdhci_writew(host, SDHCI_UHSII_HOST_FULL_RESET,
+   SDHCI_UHSII_SOFT_RESET);
if (soft)
sdhci_do_reset(host, SDHCI_RESET_CMD|SDHCI_RESET_DATA);
else
@@ -270,6 +273,17 @@ static void sdhci_init(struct sdhci_host *host, int soft)
sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
 
+   if (host->flags & SDHCI_HOST_V4_ENABLED) {
+   u32 ier = SDHCI_UHSII_INT_HEADER | SDHCI_UHSII_INT_RES |
+   SDHCI_UHSII_INT_EXPIRED | SDHCI_UHSII_INT_CRC |
+   SDHCI_UHSII_INT_FRAMING | SDHCI_UHSII_INT_TID |
+   SDHCI_UHSII_INT_UNRECOVERABLE | SDHCI_UHSII_INT_EBSY |
+   SDHCI_UHSII_INT_ADMA | SDHCI_UHSII_INT_TIMEOUT;
+
+   sdhci_writel(host, ier, SDHCI_UHSII_INT_ENABLE);
+   sdhci_writel(host, ier, SDHCI_UHSII_SIGNAL_ENABLE);
+   }
+
if (soft) {
/* force clock reconfiguration */
host->clock = 0;
@@ -2733,11 +2747,12 @@ static void sdhci_tuning_timer(unsigned long data)
  *   *
 \*/
 
-static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask, u32 *mask)
+static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask,
+   u32 uhsii_intmask, u32 *mask)
 {
-   BUG_ON(intmask == 0);
+   BUG_ON(!intmask && !uhsii_intmask);
 
-   if (!host->cmd) {
+   if (!host->cmd && !host->tlp) {
pr_err("%s: Got command interrupt 0x%08x even "
"though no command operation was in progress.\n",
mmc_hostname(host->mmc), (unsigned)intmask);
@@ -2960,6 +2975,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
irqreturn_t result = IRQ_NONE;
struct sdhci_host *host = dev_id;
u32 intmask, mask, unexpected = 0;
+   u32 uhsii_intmask = 0;
int max_loops = 16;
 
spin_lock(&host->lock);
@@ -2970,7 +2986,12 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
}
 
intmask = sdhci_readl(host, SDHCI_INT_STATUS);
-   if (!intmask || intmask == 0x) {
+
+   if (host->flags & SDHCI_HOST_V4_ENABLED)
+   uhsii_intmask = sdhci_readl(host, SDHCI_UHSII_INT_STATUS);
+
+   if ((!intmask || intmask == 0x) &&
+   (!uhsii_intmask || uhsii_intmask == 0x)) {
result = IRQ_NONE;
goto out;
}
@@ -3014,9 +3035,13 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
result = IRQ_WAKE_THREAD;
}
 
+   if (uhsii_intmask)
+   sdhci_writel(host, uhsii_intmask,
+   SDHCI_UHSII_INT_STATUS);
+
if (intmask & SDHCI_INT_CMD_MASK)
sdhci_cmd_irq(host, intmask & SDHCI_INT_CMD_MASK,
- &intmask);
+   uhsii_intmask, &intmask);
 
if (intmask & SDHCI_INT_DATA_MASK)
sdhci_data_irq(host, intmask & SDHCI_INT_DATA_MASK);
@@ -3340,7 +3365,7 @@ int sdhci_add_host(struct sdhci_host *host)
host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
host->version = (host->version & SDHCI_SPEC_VER_MASK)
>> SDHCI_SPEC_VER_SHIFT;
-   if (host->version > SDHCI_SPEC_300) {
+   if (host->version > SDHCI_SPEC_400) {
pr_err("%s: Unknown controller version (%d). "
"You may experience problems.\n", mmc_hostname(mmc),
host->version);
@@ -3598,6 +3623,9 @@ int sdhci_add_host(struct sdhci_host *host)
caps[1] &= ~(SDHCI_SUPPORT_SDR104 | SDHCI_SUPPORT_SDR50 |
   SDHCI_SUPPORT_DDR50);
 
+   if (!(caps[1] & SDHCI_CAN_VDD2_180))
+   caps[1] &= ~SDHCI_SUPPORT_UHSII;
+
/* Any UHS-I mode in caps implies SDR12 and SDR25 support. */
if (caps[1] & (SDHCI_SUPPORT_SDR104 | SDHCI_SUPPORT_SDR50 |
   SDHCI_SUPPORT_DDR50))
@@ -3628,6 +3656,64 @@ int sdhci_add_host(struct sdhci_host *host)
!(h

[PATCH 01/12] mmc: core: add data structure define for SD4.0

2015-04-28 Thread micky_ching
From: Micky Ching 

The new data structure for SD4.0 including follows:

register: SD4.0 IO space register define.
protocol: host and card handshake data.
tlp: tlp request data structure for SD4.0 mode.
uhsii ios: UHSII bus control data structure.

Signed-off-by: Micky Ching 
Signed-off-by: Wei Wang 
---
 include/linux/mmc/card.h | 13 +++
 include/linux/mmc/core.h | 88 
 include/linux/mmc/host.h | 33 ++
 include/linux/mmc/sd.h   | 73 +++
 4 files changed, 207 insertions(+)

diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index a6cf4c0..77baf55 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -262,6 +262,7 @@ struct mmc_card {
 #define MMC_CARD_REMOVED   (1<<4)  /* card has been removed */
 #define MMC_STATE_DOING_BKOPS  (1<<5)  /* card is doing BKOPS */
 #define MMC_STATE_SUSPENDED(1<<6)  /* card is suspended */
+#define MMC_STATE_UHSII(1<<12) /* card is in UHS-II 
mode */
unsigned intquirks; /* card quirks */
 #define MMC_QUIRK_LENIENT_FN0  (1<<0)  /* allow SDIO FN0 writes 
outside of the VS CCCR range */
 #define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1)   /* use func->cur_blksize */
@@ -279,6 +280,15 @@ struct mmc_card {
 #define MMC_QUIRK_SEC_ERASE_TRIM_BROKEN (1<<10)/* Skip secure for 
erase/trim */
 #define MMC_QUIRK_BROKEN_IRQ_POLLING   (1<<11) /* Polling SDIO_CCCR_INTx could 
create a fake interrupt */
 
+   u8  node_id;/* Node ID for UHS-II card */
+   u8  lane_mode;
+   u8  n_data_gap;
+   u8  max_retry_num;
+   u8  n_fcu;
+   u8  n_lss_dir;
+   u8  n_lss_syn;
+   u16 max_blklen;
+
unsigned interase_size; /* erase size in sectors */
unsigned interase_shift;/* if erase unit is power 2 */
unsigned intpref_erase; /* in sectors */
@@ -423,6 +433,7 @@ static inline void __maybe_unused remove_quirk(struct 
mmc_card *card, int data)
 #define mmc_card_present(c)((c)->state & MMC_STATE_PRESENT)
 #define mmc_card_readonly(c)   ((c)->state & MMC_STATE_READONLY)
 #define mmc_card_blockaddr(c)  ((c)->state & MMC_STATE_BLOCKADDR)
+#define mmc_card_uhsii(c)  ((c)->state & MMC_STATE_UHSII)
 #define mmc_card_ext_capacity(c) ((c)->state & MMC_CARD_SDXC)
 #define mmc_card_removed(c)((c) && ((c)->state & MMC_CARD_REMOVED))
 #define mmc_card_doing_bkops(c)((c)->state & MMC_STATE_DOING_BKOPS)
@@ -431,6 +442,8 @@ static inline void __maybe_unused remove_quirk(struct 
mmc_card *card, int data)
 #define mmc_card_set_present(c)((c)->state |= MMC_STATE_PRESENT)
 #define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY)
 #define mmc_card_set_blockaddr(c) ((c)->state |= MMC_STATE_BLOCKADDR)
+#define mmc_card_set_uhsii(c) ((c)->state |= MMC_STATE_UHSII)
+#define mmc_card_clr_uhsii(c) ((c)->state &= ~MMC_STATE_UHSII)
 #define mmc_card_set_ext_capacity(c) ((c)->state |= MMC_CARD_SDXC)
 #define mmc_card_set_removed(c) ((c)->state |= MMC_CARD_REMOVED)
 #define mmc_card_set_doing_bkops(c)((c)->state |= MMC_STATE_DOING_BKOPS)
diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h
index de722d4e..337c6b8 100644
--- a/include/linux/mmc/core.h
+++ b/include/linux/mmc/core.h
@@ -15,6 +15,57 @@ struct request;
 struct mmc_data;
 struct mmc_request;
 
+struct mmc_tlp_block {
+   u16 header;
+
+#define UHSII_HD_NP0x8000
+#define UHSII_HD_TYP_MASK  0x7000
+#define UHSII_HD_TYP_CCMD  (0 << 12)
+#define UHSII_HD_TYP_DCMD  (1 << 12)
+#define UHSII_HD_TYP_RES   (2 << 12)
+#define UHSII_HD_TYP_DATA  (3 << 12)
+#define UHSII_HD_TYP_MSG   (7 << 12)
+#define UHSII_HD_DID_SHIFT 8
+#define UHSII_HD_DID_MASK  (0x0F << UHSII_HD_DID_SHIFT)
+#define UHSII_HD_SID_SHIFT 4
+#define UHSII_HD_SID_MASK  (0x0F << UHSII_HD_SID_SHIFT)
+
+#define UHSII_HD_DID(val) ((val) << UHSII_HD_DID_SHIFT & UHSII_HD_DID_MASK)
+#define UHSII_CHK_CCMD(val) (((val) & UHSII_HD_TYP_MASK) == UHSII_HD_TYP_CCMD)
+#define UHSII_CHK_DCMD(val) (((val) & UHSII_HD_TYP_MASK) == UHSII_HD_TYP_DCMD)
+
+   u16 argument;
+#define UHSII_ARG_DIR_WRITE0x8000
+#define UHSII_ARG_DIR_READ 0
+#define UHSII_ARG_PLEN_SHIFT   12
+#define UHSII_ARG_PLEN_MASK(0x03 << UHSII_ARG_PLEN_SHIFT)
+#define UHSII_ARG_IOADR_MASK   0x0FFF
+#define UHSII_ARG_RES_NACK 0x8000
+#define UHSII_ARG_TMODE_SHIFT  11
+#define UHSII_ARG_TMODE_MASK   (0x0F << UHSII_ARG_TMODE_SHIFT)
+#define  UHSII_TMODE_DM_HD 0x08
+#define  UHSII_TMODE_LM_SPE

[PATCH RESEND 0/3] mmc: rtsx: fix bug and support nonblocking request

2014-02-16 Thread micky_ching
From: Micky Ching 

First we fix the card poweroff bug: the card power is not shutdown when sd/mmc
card removed, this will make UHS-card failed to running in high speed mode if we
insert the card again.

We offer a concise tuning searching method, it is much easier to read.

At last we add support for nonblocking request, which will improve card read
speed at about 10% write speed about 5% normally.

Micky Ching (3):
  mmc: rtsx: fix card poweroff bug
  mmc: rtsx: modify phase searching method for tuning
  mmc: rtsx: add support for pre_req and post_req

 drivers/mfd/rtsx_pcr.c|  132 ++---
 drivers/mmc/host/rtsx_pci_sdmmc.c |  537 ++---
 include/linux/mfd/rtsx_common.h   |1 +
 include/linux/mfd/rtsx_pci.h  |8 +-
 4 files changed, 481 insertions(+), 197 deletions(-)

--
1.7.9.5
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH RESEND 2/3] mmc: rtsx: modify phase searching method for tuning

2014-02-16 Thread micky_ching
From: Micky Ching 

The new phase searching method is more concise and easier to
understand.

Signed-off-by: Micky Ching 
---
 drivers/mmc/host/rtsx_pci_sdmmc.c |  112 +++--
 include/linux/mfd/rtsx_pci.h  |2 +-
 2 files changed, 33 insertions(+), 81 deletions(-)

diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c 
b/drivers/mmc/host/rtsx_pci_sdmmc.c
index c9a7328..7da270b 100644
--- a/drivers/mmc/host/rtsx_pci_sdmmc.c
+++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
@@ -31,16 +31,6 @@
 #include 
 #include 
 
-/* SD Tuning Data Structure
- * Record continuous timing phase path
- */
-struct timing_phase_path {
-   int start;
-   int end;
-   int mid;
-   int len;
-};
-
 struct realtek_pci_sdmmc {
struct platform_device  *pdev;
struct rtsx_pcr *pcr;
@@ -511,85 +501,47 @@ static int sd_change_phase(struct realtek_pci_sdmmc *host,
return 0;
 }
 
-static u8 sd_search_final_phase(struct realtek_pci_sdmmc *host, u32 phase_map)
+static inline u32 test_phase_bit(u32 phase_map, unsigned int bit)
 {
-   struct timing_phase_path path[MAX_PHASE + 1];
-   int i, j, cont_path_cnt;
-   int new_block, max_len, final_path_idx;
-   u8 final_phase = 0xFF;
+   bit %= RTSX_PHASE_MAX;
+   return phase_map & (1 << bit);
+}
 
-   /* Parse phase_map, take it as a bit-ring */
-   cont_path_cnt = 0;
-   new_block = 1;
-   j = 0;
-   for (i = 0; i < MAX_PHASE + 1; i++) {
-   if (phase_map & (1 << i)) {
-   if (new_block) {
-   new_block = 0;
-   j = cont_path_cnt++;
-   path[j].start = i;
-   path[j].end = i;
-   } else {
-   path[j].end = i;
-   }
-   } else {
-   new_block = 1;
-   if (cont_path_cnt) {
-   /* Calculate path length and middle point */
-   int idx = cont_path_cnt - 1;
-   path[idx].len =
-   path[idx].end - path[idx].start + 1;
-   path[idx].mid =
-   path[idx].start + path[idx].len / 2;
-   }
-   }
-   }
+static int sd_get_phase_len(u32 phase_map, unsigned int start_bit)
+{
+   int i;
 
-   if (cont_path_cnt == 0) {
-   dev_dbg(sdmmc_dev(host), "No continuous phase path\n");
-   goto finish;
-   } else {
-   /* Calculate last continuous path length and middle point */
-   int idx = cont_path_cnt - 1;
-   path[idx].len = path[idx].end - path[idx].start + 1;
-   path[idx].mid = path[idx].start + path[idx].len / 2;
+   for (i = 0; i < RTSX_PHASE_MAX; i++) {
+   if (test_phase_bit(phase_map, start_bit + i) == 0)
+   return i;
}
+   return RTSX_PHASE_MAX;
+}
+
+static u8 sd_search_final_phase(struct realtek_pci_sdmmc *host, u32 phase_map)
+{
+   int start = 0, len = 0;
+   int start_final = 0, len_final = 0;
+   u8 final_phase = 0xFF;
 
-   /* Connect the first and last continuous paths if they are adjacent */
-   if (!path[0].start && (path[cont_path_cnt - 1].end == MAX_PHASE)) {
-   /* Using negative index */
-   path[0].start = path[cont_path_cnt - 1].start - MAX_PHASE - 1;
-   path[0].len += path[cont_path_cnt - 1].len;
-   path[0].mid = path[0].start + path[0].len / 2;
-   /* Convert negative middle point index to positive one */
-   if (path[0].mid < 0)
-   path[0].mid += MAX_PHASE + 1;
-   cont_path_cnt--;
+   if (phase_map == 0) {
+   dev_err(sdmmc_dev(host), "phase error: [map:%x]\n", phase_map);
+   return final_phase;
}
 
-   /* Choose the longest continuous phase path */
-   max_len = 0;
-   final_phase = 0;
-   final_path_idx = 0;
-   for (i = 0; i < cont_path_cnt; i++) {
-   if (path[i].len > max_len) {
-   max_len = path[i].len;
-   final_phase = (u8)path[i].mid;
-   final_path_idx = i;
+   while (start < RTSX_PHASE_MAX) {
+   len = sd_get_phase_len(phase_map, start);
+   if (len_final < len) {
+   start_final = start;
+   len_final = len;
}
-
-   dev_dbg(sdmmc_dev(host), "path[%d].start = %d\n",
-   i, path[i].start);
-   dev_dbg(sdmmc_dev(host), "path[%d].end = %d\n",
-   i, path[i].end);
-   dev_dbg(sdmmc_dev(host), "path[%d].len = %d\n",
- 

[PATCH RESEND 3/3] mmc: rtsx: add support for pre_req and post_req

2014-02-16 Thread micky_ching
From: Micky Ching 

Add support for non-blocking request, pre_req() runs dma_map_sg() and
post_req() runs dma_unmap_sg(). This patch can increase card read/write
speed, especially for high speed card and slow CPU(for some embedded
platform).

Users can get a great benefit from this patch. if CPU frequency is 800MHz,
SDR104 or DDR50 card read/write speed may increase more than 15%.

test results:
intel i3(800MHz - 2.3GHz), SD card clock 208MHz

performance mode(2.3GHz):
Before:
dd if=/dev/mmcblk0p1 of=/dev/null bs=64k count=1024
67108864 bytes (67 MB) copied, 1.18191 s, 56.8 MB/s
After:
 dd if=/dev/mmcblk0p1 of=/dev/null bs=64k count=1024
67108864 bytes (67 MB) copied, 1.09276 s, 61.4 MB/s

powersave mode(800MHz):
Before:
dd if=/dev/mmcblk0p1 of=/dev/null bs=64k count=1024
67108864 bytes (67 MB) copied, 1.29569 s, 51.8 MB/s
After:
dd if=/dev/mmcblk0p1 of=/dev/null bs=64k count=1024
67108864 bytes (67 MB) copied, 1.11218 s, 60.3 MB/s

Signed-off-by: Micky Ching 
---
 drivers/mfd/rtsx_pcr.c|  132 
 drivers/mmc/host/rtsx_pci_sdmmc.c |  426 ++---
 include/linux/mfd/rtsx_common.h   |1 +
 include/linux/mfd/rtsx_pci.h  |6 +
 4 files changed, 448 insertions(+), 117 deletions(-)

diff --git a/drivers/mfd/rtsx_pcr.c b/drivers/mfd/rtsx_pcr.c
index 2af55bb..d21c894 100644
--- a/drivers/mfd/rtsx_pcr.c
+++ b/drivers/mfd/rtsx_pcr.c
@@ -338,58 +338,28 @@ int rtsx_pci_transfer_data(struct rtsx_pcr *pcr, struct 
scatterlist *sglist,
int num_sg, bool read, int timeout)
 {
struct completion trans_done;
-   u8 dir;
-   int err = 0, i, count;
+   int err = 0, count;
long timeleft;
unsigned long flags;
-   struct scatterlist *sg;
-   enum dma_data_direction dma_dir;
-   u32 val;
-   dma_addr_t addr;
-   unsigned int len;
-
-   dev_dbg(&(pcr->pci->dev), "--> %s: num_sg = %d\n", __func__, num_sg);
-
-   /* don't transfer data during abort processing */
-   if (pcr->remove_pci)
-   return -EINVAL;
-
-   if ((sglist == NULL) || (num_sg <= 0))
-   return -EINVAL;
 
-   if (read) {
-   dir = DEVICE_TO_HOST;
-   dma_dir = DMA_FROM_DEVICE;
-   } else {
-   dir = HOST_TO_DEVICE;
-   dma_dir = DMA_TO_DEVICE;
-   }
-
-   count = dma_map_sg(&(pcr->pci->dev), sglist, num_sg, dma_dir);
+   count = rtsx_pci_dma_map_sg(pcr, sglist, num_sg, read);
if (count < 1) {
dev_err(&(pcr->pci->dev), "scatterlist map failed\n");
return -EINVAL;
}
dev_dbg(&(pcr->pci->dev), "DMA mapping count: %d\n", count);
 
-   val = ((u32)(dir & 0x01) << 29) | TRIG_DMA | ADMA_MODE;
-   pcr->sgi = 0;
-   for_each_sg(sglist, sg, count, i) {
-   addr = sg_dma_address(sg);
-   len = sg_dma_len(sg);
-   rtsx_pci_add_sg_tbl(pcr, addr, len, i == count - 1);
-   }
 
spin_lock_irqsave(&pcr->lock, flags);
 
pcr->done = &trans_done;
pcr->trans_result = TRANS_NOT_READY;
init_completion(&trans_done);
-   rtsx_pci_writel(pcr, RTSX_HDBAR, pcr->host_sg_tbl_addr);
-   rtsx_pci_writel(pcr, RTSX_HDBCTLR, val);
 
spin_unlock_irqrestore(&pcr->lock, flags);
 
+   rtsx_pci_dma_transfer(pcr, sglist, count, read);
+
timeleft = wait_for_completion_interruptible_timeout(
&trans_done, msecs_to_jiffies(timeout));
if (timeleft <= 0) {
@@ -413,7 +383,7 @@ out:
pcr->done = NULL;
spin_unlock_irqrestore(&pcr->lock, flags);
 
-   dma_unmap_sg(&(pcr->pci->dev), sglist, num_sg, dma_dir);
+   rtsx_pci_dma_unmap_sg(pcr, sglist, num_sg, read);
 
if ((err < 0) && (err != -ENODEV))
rtsx_pci_stop_cmd(pcr);
@@ -425,6 +395,73 @@ out:
 }
 EXPORT_SYMBOL_GPL(rtsx_pci_transfer_data);
 
+int rtsx_pci_dma_map_sg(struct rtsx_pcr *pcr, struct scatterlist *sglist,
+   int num_sg, bool read)
+{
+   enum dma_data_direction dir = read ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
+
+   if (pcr->remove_pci)
+   return -EINVAL;
+
+   if ((sglist == NULL) || num_sg < 1)
+   return -EINVAL;
+
+   return dma_map_sg(&(pcr->pci->dev), sglist, num_sg, dir);
+}
+EXPORT_SYMBOL_GPL(rtsx_pci_dma_map_sg);
+
+int rtsx_pci_dma_unmap_sg(struct rtsx_pcr *pcr, struct scatterlist *sglist,
+   int num_sg, bool read)
+{
+   enum dma_data_direction dir = read ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
+
+   if (pcr->remove_pci)
+   return -EINVAL;
+
+   if (sglist == NULL || num_sg < 1)
+   return -EINVAL;
+
+   dma_unmap_sg(&(pcr->pci->dev), sglist, num_sg, dir);
+   return num_sg;
+}
+EXPORT_SYMBOL_GPL(rtsx_pci_dma_unmap_sg);
+
+int rtsx_pci_dma_transfer(struct rtsx_pcr *pcr, struct scatterlist *sglist,
+   int sg_count, bool read)
+{
+   struct scatterlist 

[PATCH RESEND 1/3] mmc: rtsx: fix card poweroff bug

2014-02-16 Thread micky_ching
From: Micky Ching 

If the host driver removed while card in the slot, the host will not
power off card power correctly. This bug is produced because host
eject flag set before the last mmc_set_ios callback, we should set the
eject flag after power off.

Signed-off-by: Micky Ching 
---
 drivers/mmc/host/rtsx_pci_sdmmc.c |3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c 
b/drivers/mmc/host/rtsx_pci_sdmmc.c
index 375a880e..c9a7328 100644
--- a/drivers/mmc/host/rtsx_pci_sdmmc.c
+++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
@@ -1328,7 +1328,6 @@ static int rtsx_pci_sdmmc_drv_remove(struct 
platform_device *pdev)
pcr->slots[RTSX_SD_CARD].p_dev = NULL;
pcr->slots[RTSX_SD_CARD].card_event = NULL;
mmc = host->mmc;
-   host->eject = true;
 
mutex_lock(&host->host_mutex);
if (host->mrq) {
@@ -1346,6 +1345,8 @@ static int rtsx_pci_sdmmc_drv_remove(struct 
platform_device *pdev)
mutex_unlock(&host->host_mutex);
 
mmc_remove_host(mmc);
+   host->eject = true;
+
mmc_free_host(mmc);
 
dev_dbg(&(pdev->dev),
-- 
1.7.9.5

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v2 1/3] mmc: rtsx: fix card poweroff bug

2014-02-17 Thread micky_ching
From: Micky Ching 

If the host driver removed while card in the slot, the host will not
power off card power correctly. This bug is produced because host
eject flag set before the last mmc_set_ios callback, we should set the
eject flag after power off.

Signed-off-by: Micky Ching 
---
 drivers/mmc/host/rtsx_pci_sdmmc.c |3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c 
b/drivers/mmc/host/rtsx_pci_sdmmc.c
index c46feda..cc80e31 100644
--- a/drivers/mmc/host/rtsx_pci_sdmmc.c
+++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
@@ -1297,7 +1297,6 @@ static int rtsx_pci_sdmmc_drv_remove(struct 
platform_device *pdev)
pcr->slots[RTSX_SD_CARD].p_dev = NULL;
pcr->slots[RTSX_SD_CARD].card_event = NULL;
mmc = host->mmc;
-   host->eject = true;
 
mutex_lock(&host->host_mutex);
if (host->mrq) {
@@ -1315,6 +1314,8 @@ static int rtsx_pci_sdmmc_drv_remove(struct 
platform_device *pdev)
mutex_unlock(&host->host_mutex);
 
mmc_remove_host(mmc);
+   host->eject = true;
+
mmc_free_host(mmc);
 
dev_dbg(&(pdev->dev),
-- 
1.7.9.5

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v2 2/3] mmc: rtsx: modify phase searching method for tuning

2014-02-17 Thread micky_ching
From: Micky Ching 

The new phase searching method is more concise and easier to
understand.

Signed-off-by: Micky Ching 
---
 drivers/mmc/host/rtsx_pci_sdmmc.c |  112 +++--
 include/linux/mfd/rtsx_pci.h  |2 +-
 2 files changed, 33 insertions(+), 81 deletions(-)

diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c 
b/drivers/mmc/host/rtsx_pci_sdmmc.c
index cc80e31..0b9ded1 100644
--- a/drivers/mmc/host/rtsx_pci_sdmmc.c
+++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
@@ -31,16 +31,6 @@
 #include 
 #include 
 
-/* SD Tuning Data Structure
- * Record continuous timing phase path
- */
-struct timing_phase_path {
-   int start;
-   int end;
-   int mid;
-   int len;
-};
-
 struct realtek_pci_sdmmc {
struct platform_device  *pdev;
struct rtsx_pcr *pcr;
@@ -511,85 +501,47 @@ static int sd_change_phase(struct realtek_pci_sdmmc *host,
return 0;
 }
 
-static u8 sd_search_final_phase(struct realtek_pci_sdmmc *host, u32 phase_map)
+static inline u32 test_phase_bit(u32 phase_map, unsigned int bit)
 {
-   struct timing_phase_path path[MAX_PHASE + 1];
-   int i, j, cont_path_cnt;
-   int new_block, max_len, final_path_idx;
-   u8 final_phase = 0xFF;
+   bit %= RTSX_PHASE_MAX;
+   return phase_map & (1 << bit);
+}
 
-   /* Parse phase_map, take it as a bit-ring */
-   cont_path_cnt = 0;
-   new_block = 1;
-   j = 0;
-   for (i = 0; i < MAX_PHASE + 1; i++) {
-   if (phase_map & (1 << i)) {
-   if (new_block) {
-   new_block = 0;
-   j = cont_path_cnt++;
-   path[j].start = i;
-   path[j].end = i;
-   } else {
-   path[j].end = i;
-   }
-   } else {
-   new_block = 1;
-   if (cont_path_cnt) {
-   /* Calculate path length and middle point */
-   int idx = cont_path_cnt - 1;
-   path[idx].len =
-   path[idx].end - path[idx].start + 1;
-   path[idx].mid =
-   path[idx].start + path[idx].len / 2;
-   }
-   }
-   }
+static int sd_get_phase_len(u32 phase_map, unsigned int start_bit)
+{
+   int i;
 
-   if (cont_path_cnt == 0) {
-   dev_dbg(sdmmc_dev(host), "No continuous phase path\n");
-   goto finish;
-   } else {
-   /* Calculate last continuous path length and middle point */
-   int idx = cont_path_cnt - 1;
-   path[idx].len = path[idx].end - path[idx].start + 1;
-   path[idx].mid = path[idx].start + path[idx].len / 2;
+   for (i = 0; i < RTSX_PHASE_MAX; i++) {
+   if (test_phase_bit(phase_map, start_bit + i) == 0)
+   return i;
}
+   return RTSX_PHASE_MAX;
+}
+
+static u8 sd_search_final_phase(struct realtek_pci_sdmmc *host, u32 phase_map)
+{
+   int start = 0, len = 0;
+   int start_final = 0, len_final = 0;
+   u8 final_phase = 0xFF;
 
-   /* Connect the first and last continuous paths if they are adjacent */
-   if (!path[0].start && (path[cont_path_cnt - 1].end == MAX_PHASE)) {
-   /* Using negative index */
-   path[0].start = path[cont_path_cnt - 1].start - MAX_PHASE - 1;
-   path[0].len += path[cont_path_cnt - 1].len;
-   path[0].mid = path[0].start + path[0].len / 2;
-   /* Convert negative middle point index to positive one */
-   if (path[0].mid < 0)
-   path[0].mid += MAX_PHASE + 1;
-   cont_path_cnt--;
+   if (phase_map == 0) {
+   dev_err(sdmmc_dev(host), "phase error: [map:%x]\n", phase_map);
+   return final_phase;
}
 
-   /* Choose the longest continuous phase path */
-   max_len = 0;
-   final_phase = 0;
-   final_path_idx = 0;
-   for (i = 0; i < cont_path_cnt; i++) {
-   if (path[i].len > max_len) {
-   max_len = path[i].len;
-   final_phase = (u8)path[i].mid;
-   final_path_idx = i;
+   while (start < RTSX_PHASE_MAX) {
+   len = sd_get_phase_len(phase_map, start);
+   if (len_final < len) {
+   start_final = start;
+   len_final = len;
}
-
-   dev_dbg(sdmmc_dev(host), "path[%d].start = %d\n",
-   i, path[i].start);
-   dev_dbg(sdmmc_dev(host), "path[%d].end = %d\n",
-   i, path[i].end);
-   dev_dbg(sdmmc_dev(host), "path[%d].len = %d\n",
- 

[PATCH v2 0/3] mmc: rtsx: fix bug and support nonblocking request

2014-02-17 Thread micky_ching
From: Micky Ching 

First we fix the card poweroff bug: the card power is not shutdown when sd/mmc
card removed, this will make UHS-card failed to running in high speed mode if we
insert the card again.

We offer a concise tuning searching method, it is much easier to read.

At last we add support for nonblocking request, which will improve card read
speed at about 10% write speed about 5% normally.

Micky Ching (3):
  mmc: rtsx: fix card poweroff bug
  mmc: rtsx: modify phase searching method for tuning
  mmc: rtsx: add support for pre_req and post_req

 drivers/mfd/rtsx_pcr.c|  132 ++---
 drivers/mmc/host/rtsx_pci_sdmmc.c |  529 ++---
 include/linux/mfd/rtsx_common.h   |1 +
 include/linux/mfd/rtsx_pci.h  |8 +-
 4 files changed, 481 insertions(+), 189 deletions(-)

--
1.7.9.5
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v2 3/3] mmc: rtsx: add support for pre_req and post_req

2014-02-17 Thread micky_ching
From: Micky Ching 

Add support for non-blocking request, pre_req() runs dma_map_sg() and
post_req() runs dma_unmap_sg(). This patch can increase card read/write
speed, especially for high speed card and slow CPU(for some embedded
platform).

Users can get a great benefit from this patch. if CPU frequency is 800MHz,
SDR104 or DDR50 card read/write speed may increase more than 15%.

test results:
intel i3(800MHz - 2.3GHz), SD card clock 208MHz

performance mode(2.3GHz):
Before:
dd if=/dev/mmcblk0p1 of=/dev/null bs=64k count=1024
67108864 bytes (67 MB) copied, 1.18191 s, 56.8 MB/s
After:
 dd if=/dev/mmcblk0p1 of=/dev/null bs=64k count=1024
67108864 bytes (67 MB) copied, 1.09276 s, 61.4 MB/s

powersave mode(800MHz):
Before:
dd if=/dev/mmcblk0p1 of=/dev/null bs=64k count=1024
67108864 bytes (67 MB) copied, 1.29569 s, 51.8 MB/s
After:
dd if=/dev/mmcblk0p1 of=/dev/null bs=64k count=1024
67108864 bytes (67 MB) copied, 1.11218 s, 60.3 MB/s

Signed-off-by: Micky Ching 
---
 drivers/mfd/rtsx_pcr.c|  132 
 drivers/mmc/host/rtsx_pci_sdmmc.c |  418 +++--
 include/linux/mfd/rtsx_common.h   |1 +
 include/linux/mfd/rtsx_pci.h  |6 +
 4 files changed, 448 insertions(+), 109 deletions(-)

diff --git a/drivers/mfd/rtsx_pcr.c b/drivers/mfd/rtsx_pcr.c
index 1d15735..c9de3d5 100644
--- a/drivers/mfd/rtsx_pcr.c
+++ b/drivers/mfd/rtsx_pcr.c
@@ -338,58 +338,28 @@ int rtsx_pci_transfer_data(struct rtsx_pcr *pcr, struct 
scatterlist *sglist,
int num_sg, bool read, int timeout)
 {
struct completion trans_done;
-   u8 dir;
-   int err = 0, i, count;
+   int err = 0, count;
long timeleft;
unsigned long flags;
-   struct scatterlist *sg;
-   enum dma_data_direction dma_dir;
-   u32 val;
-   dma_addr_t addr;
-   unsigned int len;
-
-   dev_dbg(&(pcr->pci->dev), "--> %s: num_sg = %d\n", __func__, num_sg);
-
-   /* don't transfer data during abort processing */
-   if (pcr->remove_pci)
-   return -EINVAL;
-
-   if ((sglist == NULL) || (num_sg <= 0))
-   return -EINVAL;
 
-   if (read) {
-   dir = DEVICE_TO_HOST;
-   dma_dir = DMA_FROM_DEVICE;
-   } else {
-   dir = HOST_TO_DEVICE;
-   dma_dir = DMA_TO_DEVICE;
-   }
-
-   count = dma_map_sg(&(pcr->pci->dev), sglist, num_sg, dma_dir);
+   count = rtsx_pci_dma_map_sg(pcr, sglist, num_sg, read);
if (count < 1) {
dev_err(&(pcr->pci->dev), "scatterlist map failed\n");
return -EINVAL;
}
dev_dbg(&(pcr->pci->dev), "DMA mapping count: %d\n", count);
 
-   val = ((u32)(dir & 0x01) << 29) | TRIG_DMA | ADMA_MODE;
-   pcr->sgi = 0;
-   for_each_sg(sglist, sg, count, i) {
-   addr = sg_dma_address(sg);
-   len = sg_dma_len(sg);
-   rtsx_pci_add_sg_tbl(pcr, addr, len, i == count - 1);
-   }
 
spin_lock_irqsave(&pcr->lock, flags);
 
pcr->done = &trans_done;
pcr->trans_result = TRANS_NOT_READY;
init_completion(&trans_done);
-   rtsx_pci_writel(pcr, RTSX_HDBAR, pcr->host_sg_tbl_addr);
-   rtsx_pci_writel(pcr, RTSX_HDBCTLR, val);
 
spin_unlock_irqrestore(&pcr->lock, flags);
 
+   rtsx_pci_dma_transfer(pcr, sglist, count, read);
+
timeleft = wait_for_completion_interruptible_timeout(
&trans_done, msecs_to_jiffies(timeout));
if (timeleft <= 0) {
@@ -413,7 +383,7 @@ out:
pcr->done = NULL;
spin_unlock_irqrestore(&pcr->lock, flags);
 
-   dma_unmap_sg(&(pcr->pci->dev), sglist, num_sg, dma_dir);
+   rtsx_pci_dma_unmap_sg(pcr, sglist, num_sg, read);
 
if ((err < 0) && (err != -ENODEV))
rtsx_pci_stop_cmd(pcr);
@@ -425,6 +395,73 @@ out:
 }
 EXPORT_SYMBOL_GPL(rtsx_pci_transfer_data);
 
+int rtsx_pci_dma_map_sg(struct rtsx_pcr *pcr, struct scatterlist *sglist,
+   int num_sg, bool read)
+{
+   enum dma_data_direction dir = read ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
+
+   if (pcr->remove_pci)
+   return -EINVAL;
+
+   if ((sglist == NULL) || num_sg < 1)
+   return -EINVAL;
+
+   return dma_map_sg(&(pcr->pci->dev), sglist, num_sg, dir);
+}
+EXPORT_SYMBOL_GPL(rtsx_pci_dma_map_sg);
+
+int rtsx_pci_dma_unmap_sg(struct rtsx_pcr *pcr, struct scatterlist *sglist,
+   int num_sg, bool read)
+{
+   enum dma_data_direction dir = read ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
+
+   if (pcr->remove_pci)
+   return -EINVAL;
+
+   if (sglist == NULL || num_sg < 1)
+   return -EINVAL;
+
+   dma_unmap_sg(&(pcr->pci->dev), sglist, num_sg, dir);
+   return num_sg;
+}
+EXPORT_SYMBOL_GPL(rtsx_pci_dma_unmap_sg);
+
+int rtsx_pci_dma_transfer(struct rtsx_pcr *pcr, struct scatterlist *sglist,
+   int sg_count, bool read)
+{
+   struct scatterlist 

[PATCH] mmc: sdhci: add support for realtek rts5250

2014-02-21 Thread micky_ching
From: Micky Ching 

Add support for realtek rts5250 pci card reader. The card reader have
some problem with DDR50 mode, so add a new quirks2 for broken ddr50.

Signed-off-by: Micky Ching 
---
 drivers/mmc/host/sdhci-pci.c |   20 
 drivers/mmc/host/sdhci.c |3 ++-
 include/linux/mmc/sdhci.h|2 ++
 3 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index 0955777..fdc6121 100644
--- a/drivers/mmc/host/sdhci-pci.c
+++ b/drivers/mmc/host/sdhci-pci.c
@@ -610,6 +610,18 @@ static const struct sdhci_pci_fixes sdhci_via = {
.probe  = via_probe,
 };
 
+static int rtsx_probe_slot(struct sdhci_pci_slot *slot)
+{
+   slot->host->mmc->caps2 |= MMC_CAP2_HS200;
+   return 0;
+}
+
+static const struct sdhci_pci_fixes sdhci_rtsx = {
+   .quirks2= SDHCI_QUIRK2_PRESET_VALUE_BROKEN |
+   SDHCI_QUIRK2_BROKEN_DDR50,
+   .probe_slot = rtsx_probe_slot,
+};
+
 static const struct pci_device_id pci_ids[] = {
{
.vendor = PCI_VENDOR_ID_RICOH,
@@ -732,6 +744,14 @@ static const struct pci_device_id pci_ids[] = {
},
 
{
+   .vendor = PCI_VENDOR_ID_REALTEK,
+   .device = 0x5250,
+   .subvendor  = PCI_ANY_ID,
+   .subdevice  = PCI_ANY_ID,
+   .driver_data= (kernel_ulong_t)&sdhci_rtsx,
+   },
+
+   {
.vendor = PCI_VENDOR_ID_INTEL,
.device = PCI_DEVICE_ID_INTEL_MRST_SD0,
.subvendor  = PCI_ANY_ID,
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 9ddef47..8958edc 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -3020,7 +3020,8 @@ int sdhci_add_host(struct sdhci_host *host)
} else if (caps[1] & SDHCI_SUPPORT_SDR50)
mmc->caps |= MMC_CAP_UHS_SDR50;
 
-   if (caps[1] & SDHCI_SUPPORT_DDR50)
+   if ((caps[1] & SDHCI_SUPPORT_DDR50) &&
+   !(host->quirks2 & SDHCI_QUIRK2_BROKEN_DDR50))
mmc->caps |= MMC_CAP_UHS_DDR50;
 
/* Does the host need tuning for SDR50? */
diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
index 362927c4..7be12b8 100644
--- a/include/linux/mmc/sdhci.h
+++ b/include/linux/mmc/sdhci.h
@@ -100,6 +100,8 @@ struct sdhci_host {
 #define SDHCI_QUIRK2_BROKEN_HOST_CONTROL   (1<<5)
 /* Controller does not support HS200 */
 #define SDHCI_QUIRK2_BROKEN_HS200  (1<<6)
+/* Controller does not support DDR50 */
+#define SDHCI_QUIRK2_BROKEN_DDR50  (1<<7)
 
int irq;/* Device IRQ */
void __iomem *ioaddr;   /* Mapped address */
-- 
1.7.9.5

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 1/2] mmc: rtsx: add R1-no-CRC mmc command type handle

2014-03-17 Thread micky_ching
From: Micky Ching 

commit a27fbf2f067b0cd6f172c8b696b9a44c58bfaa7a

produced a cmd.flags unhandled in realtek pci host driver.
This will make MMC card failed initialize, this patch is
used to handle the new cmd.flags condition and MMC card can be used.

Signed-off-by: Micky Ching 
---
 drivers/mmc/host/rtsx_pci_sdmmc.c |3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c 
b/drivers/mmc/host/rtsx_pci_sdmmc.c
index 5fb994f..0d8904a 100644
--- a/drivers/mmc/host/rtsx_pci_sdmmc.c
+++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
@@ -346,6 +346,9 @@ static void sd_send_cmd(struct realtek_pci_sdmmc *host, 
struct mmc_command *cmd)
case MMC_RSP_R1:
rsp_type = SD_RSP_TYPE_R1;
break;
+   case MMC_RSP_R1 & ~MMC_RSP_CRC:
+   rsp_type = SD_RSP_TYPE_R1 | SD_NO_CHECK_CRC7;
+   break;
case MMC_RSP_R1B:
rsp_type = SD_RSP_TYPE_R1b;
break;
-- 
1.7.9.5

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 0/2] add new cmd type handle and remove smatch warnings

2014-03-17 Thread micky_ching
From: Micky Ching 

Add new command type(R1 without CRC) handle, without this patch mmc card
initialize will be failed.

Using a more careful handle in request timeout, and debug info is printed
using non DMA mode. Smatch warning was removed.

Micky Ching (2):
  mmc: rtsx: add R1-no-CRC mmc command type handle
  mmc: rtsx: modify error handle and remove smatch warnings

 drivers/mmc/host/rtsx_pci_sdmmc.c |  121 -
 1 file changed, 67 insertions(+), 54 deletions(-)

--
1.7.9.5
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 2/2] mmc: rtsx: modify error handle and remove smatch warnings

2014-03-17 Thread micky_ching
From: Micky Ching 

Using non-DMA dump-regs, which would be more exactly for DMA transfer failed.

More careful handle when cmd/data timeout, add stop(CMD12) cmd before go to
finish request when multi-rw timeout.

Remove some static checher warings.
on commit: 
drivers/mmc/host/rtsx_pci_sdmmc.c:194 sd_finish_request()
error: we previously assumed 'mrq' could be null (see line 158)
drivers/mmc/host/rtsx_pci_sdmmc.c:504 sd_get_rsp()
error: we previously assumed 'cmd' could be null (see line 434)
drivers/mmc/host/rtsx_pci_sdmmc.c:525 sd_pre_dma_transfer()
warn: we tested 'next' before and it was 'false'

Signed-off-by: Micky Ching 
---
 drivers/mmc/host/rtsx_pci_sdmmc.c |  118 -
 1 file changed, 64 insertions(+), 54 deletions(-)

diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c 
b/drivers/mmc/host/rtsx_pci_sdmmc.c
index 0d8904a..d00a94e 100644
--- a/drivers/mmc/host/rtsx_pci_sdmmc.c
+++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
@@ -81,25 +81,23 @@ static inline void sd_clear_error(struct realtek_pci_sdmmc 
*host)
 }
 
 #ifdef DEBUG
+static inline void sd_print_reg(struct realtek_pci_sdmmc *host, u16 reg)
+{
+   u8 val;
+   if (rtsx_pci_read_register(host->pcr, reg, &val) < 0)
+   dev_dbg(sdmmc_dev(host), "read 0x%04x failed\n", reg);
+   else
+   dev_dbg(sdmmc_dev(host), "0x%04X: 0x%02x\n", reg, val);
+}
+
 static void sd_print_debug_regs(struct realtek_pci_sdmmc *host)
 {
-   struct rtsx_pcr *pcr = host->pcr;
u16 i;
-   u8 *ptr;
-
-   /* Print SD host internal registers */
-   rtsx_pci_init_cmd(pcr);
-   for (i = 0xFDA0; i <= 0xFDAE; i++)
-   rtsx_pci_add_cmd(pcr, READ_REG_CMD, i, 0, 0);
-   for (i = 0xFD52; i <= 0xFD69; i++)
-   rtsx_pci_add_cmd(pcr, READ_REG_CMD, i, 0, 0);
-   rtsx_pci_send_cmd(pcr, 100);
 
-   ptr = rtsx_pci_get_cmd_data(pcr);
for (i = 0xFDA0; i <= 0xFDAE; i++)
-   dev_dbg(sdmmc_dev(host), "0x%04X: 0x%02x\n", i, *(ptr++));
+   sd_print_reg(host, i);
for (i = 0xFD52; i <= 0xFD69; i++)
-   dev_dbg(sdmmc_dev(host), "0x%04X: 0x%02x\n", i, *(ptr++));
+   sd_print_reg(host, i);
 }
 #else
 #define sd_print_debug_regs(host)
@@ -125,19 +123,27 @@ static void sd_request_timeout(unsigned long host_addr)
spin_lock_irqsave(&host->lock, flags);
 
if (!host->mrq) {
-   dev_err(sdmmc_dev(host), "error: no request exist\n");
-   goto out;
+   dev_err(sdmmc_dev(host), "error: request not exist\n");
+   spin_unlock_irqrestore(&host->lock, flags);
+   return;
}
 
-   if (host->cmd)
+   if (host->cmd && host->data)
+   dev_err(sdmmc_dev(host), "error: cmd and data conflict\n");
+
+   if (host->cmd) {
host->cmd->error = -ETIMEDOUT;
-   if (host->data)
-   host->data->error = -ETIMEDOUT;
+   dev_dbg(sdmmc_dev(host), "timeout for cmd %d\n",
+   host->cmd->opcode);
+   tasklet_schedule(&host->cmd_tasklet);
+   }
 
-   dev_dbg(sdmmc_dev(host), "timeout for request\n");
+   if (host->data) {
+   host->data->error = -ETIMEDOUT;
+   dev_dbg(sdmmc_dev(host), "timeout for data transfer\n");
+   tasklet_schedule(&host->data_tasklet);
+   }
 
-out:
-   tasklet_schedule(&host->finish_tasklet);
spin_unlock_irqrestore(&host->lock, flags);
 }
 
@@ -157,7 +163,8 @@ static void sd_finish_request(unsigned long host_addr)
mrq = host->mrq;
if (!mrq) {
dev_err(sdmmc_dev(host), "error: no request need finish\n");
-   goto out;
+   spin_unlock_irqrestore(&host->lock, flags);
+   return;
}
 
cmd = mrq->cmd;
@@ -167,11 +174,6 @@ static void sd_finish_request(unsigned long host_addr)
(mrq->stop && mrq->stop->error) ||
(cmd && cmd->error) || (data && data->error);
 
-   if (any_error) {
-   rtsx_pci_stop_cmd(pcr);
-   sd_clear_error(host);
-   }
-
if (data) {
if (any_error)
data->bytes_xfered = 0;
@@ -188,7 +190,6 @@ static void sd_finish_request(unsigned long host_addr)
host->cmd = NULL;
host->data = NULL;
 
-out:
spin_unlock_irqrestore(&host->lock, flags);
mutex_unlock(&pcr->pcr_mutex);
mmc_request_done(host->mmc, mrq);
@@ -373,8 +374,11 @@ static void sd_send_cmd(struct realtek_pci_sdmmc *host, 
struct mmc_command *cmd)
if (cmd->opcode == SD_SWITCH_VOLTAGE) {
err = rtsx_pci_write_register(pcr, SD_BUS_STAT,
0xFF, SD_CLK_TOGGLE_EN);
-   if (err < 0)
+   if (err < 0) {
+   rtsx_pci_write_register(pcr, SD_BUS_STAT,
+   SD_CLK_TOGGLE_EN | SD_CLK_FORC

[PATCH 1/2] mmc: rtsx: add R1-no-CRC mmc command type handle

2014-03-23 Thread micky_ching
From: Micky Ching 

commit a27fbf2f067b0cd6f172c8b696b9a44c58bfaa7a

produced a cmd.flags unhandled in realtek pci host driver.
This will make MMC card failed initialize, this patch is
used to handle the new cmd.flags condition and MMC card can be used.

Signed-off-by: Micky Ching 
---
 drivers/mmc/host/rtsx_pci_sdmmc.c |3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c 
b/drivers/mmc/host/rtsx_pci_sdmmc.c
index 5fb994f..0d8904a 100644
--- a/drivers/mmc/host/rtsx_pci_sdmmc.c
+++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
@@ -346,6 +346,9 @@ static void sd_send_cmd(struct realtek_pci_sdmmc *host, 
struct mmc_command *cmd)
case MMC_RSP_R1:
rsp_type = SD_RSP_TYPE_R1;
break;
+   case MMC_RSP_R1 & ~MMC_RSP_CRC:
+   rsp_type = SD_RSP_TYPE_R1 | SD_NO_CHECK_CRC7;
+   break;
case MMC_RSP_R1B:
rsp_type = SD_RSP_TYPE_R1b;
break;
-- 
1.7.9.5

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 2/2] mmc: rtsx: modify error handle and remove smatch warnings

2014-03-23 Thread micky_ching
From: Micky Ching 

Using non-DMA dump-regs, which would be more exactly for DMA transfer failed.

More careful handle when cmd/data timeout, add stop(CMD12) cmd before go to
finish request when multi-rw timeout.

Remove some static checher warings.
on commit: 
drivers/mmc/host/rtsx_pci_sdmmc.c:194 sd_finish_request()
error: we previously assumed 'mrq' could be null (see line 158)
drivers/mmc/host/rtsx_pci_sdmmc.c:504 sd_get_rsp()
error: we previously assumed 'cmd' could be null (see line 434)
drivers/mmc/host/rtsx_pci_sdmmc.c:525 sd_pre_dma_transfer()
warn: we tested 'next' before and it was 'false'

Signed-off-by: Micky Ching 
---
 drivers/mmc/host/rtsx_pci_sdmmc.c |  118 -
 1 file changed, 64 insertions(+), 54 deletions(-)

diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c 
b/drivers/mmc/host/rtsx_pci_sdmmc.c
index 0d8904a..d00a94e 100644
--- a/drivers/mmc/host/rtsx_pci_sdmmc.c
+++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
@@ -81,25 +81,23 @@ static inline void sd_clear_error(struct realtek_pci_sdmmc 
*host)
 }
 
 #ifdef DEBUG
+static inline void sd_print_reg(struct realtek_pci_sdmmc *host, u16 reg)
+{
+   u8 val;
+   if (rtsx_pci_read_register(host->pcr, reg, &val) < 0)
+   dev_dbg(sdmmc_dev(host), "read 0x%04x failed\n", reg);
+   else
+   dev_dbg(sdmmc_dev(host), "0x%04X: 0x%02x\n", reg, val);
+}
+
 static void sd_print_debug_regs(struct realtek_pci_sdmmc *host)
 {
-   struct rtsx_pcr *pcr = host->pcr;
u16 i;
-   u8 *ptr;
-
-   /* Print SD host internal registers */
-   rtsx_pci_init_cmd(pcr);
-   for (i = 0xFDA0; i <= 0xFDAE; i++)
-   rtsx_pci_add_cmd(pcr, READ_REG_CMD, i, 0, 0);
-   for (i = 0xFD52; i <= 0xFD69; i++)
-   rtsx_pci_add_cmd(pcr, READ_REG_CMD, i, 0, 0);
-   rtsx_pci_send_cmd(pcr, 100);
 
-   ptr = rtsx_pci_get_cmd_data(pcr);
for (i = 0xFDA0; i <= 0xFDAE; i++)
-   dev_dbg(sdmmc_dev(host), "0x%04X: 0x%02x\n", i, *(ptr++));
+   sd_print_reg(host, i);
for (i = 0xFD52; i <= 0xFD69; i++)
-   dev_dbg(sdmmc_dev(host), "0x%04X: 0x%02x\n", i, *(ptr++));
+   sd_print_reg(host, i);
 }
 #else
 #define sd_print_debug_regs(host)
@@ -125,19 +123,27 @@ static void sd_request_timeout(unsigned long host_addr)
spin_lock_irqsave(&host->lock, flags);
 
if (!host->mrq) {
-   dev_err(sdmmc_dev(host), "error: no request exist\n");
-   goto out;
+   dev_err(sdmmc_dev(host), "error: request not exist\n");
+   spin_unlock_irqrestore(&host->lock, flags);
+   return;
}
 
-   if (host->cmd)
+   if (host->cmd && host->data)
+   dev_err(sdmmc_dev(host), "error: cmd and data conflict\n");
+
+   if (host->cmd) {
host->cmd->error = -ETIMEDOUT;
-   if (host->data)
-   host->data->error = -ETIMEDOUT;
+   dev_dbg(sdmmc_dev(host), "timeout for cmd %d\n",
+   host->cmd->opcode);
+   tasklet_schedule(&host->cmd_tasklet);
+   }
 
-   dev_dbg(sdmmc_dev(host), "timeout for request\n");
+   if (host->data) {
+   host->data->error = -ETIMEDOUT;
+   dev_dbg(sdmmc_dev(host), "timeout for data transfer\n");
+   tasklet_schedule(&host->data_tasklet);
+   }
 
-out:
-   tasklet_schedule(&host->finish_tasklet);
spin_unlock_irqrestore(&host->lock, flags);
 }
 
@@ -157,7 +163,8 @@ static void sd_finish_request(unsigned long host_addr)
mrq = host->mrq;
if (!mrq) {
dev_err(sdmmc_dev(host), "error: no request need finish\n");
-   goto out;
+   spin_unlock_irqrestore(&host->lock, flags);
+   return;
}
 
cmd = mrq->cmd;
@@ -167,11 +174,6 @@ static void sd_finish_request(unsigned long host_addr)
(mrq->stop && mrq->stop->error) ||
(cmd && cmd->error) || (data && data->error);
 
-   if (any_error) {
-   rtsx_pci_stop_cmd(pcr);
-   sd_clear_error(host);
-   }
-
if (data) {
if (any_error)
data->bytes_xfered = 0;
@@ -188,7 +190,6 @@ static void sd_finish_request(unsigned long host_addr)
host->cmd = NULL;
host->data = NULL;
 
-out:
spin_unlock_irqrestore(&host->lock, flags);
mutex_unlock(&pcr->pcr_mutex);
mmc_request_done(host->mmc, mrq);
@@ -373,8 +374,11 @@ static void sd_send_cmd(struct realtek_pci_sdmmc *host, 
struct mmc_command *cmd)
if (cmd->opcode == SD_SWITCH_VOLTAGE) {
err = rtsx_pci_write_register(pcr, SD_BUS_STAT,
0xFF, SD_CLK_TOGGLE_EN);
-   if (err < 0)
+   if (err < 0) {
+   rtsx_pci_write_register(pcr, SD_BUS_STAT,
+   SD_CLK_TOGGLE_EN | SD_CLK_FORC

mmc: rtsx: add new cmd type handle and modify error handle

2014-03-23 Thread micky_ching
From: Micky Ching 

Add new command type(R1 without CRC) handle, without this
patch mmc card initialize will be failed.

Using a more careful handle in request timeout, this would
improve error recover capability. Debug info is printed
using non DMA mode, this would help print more accurately
for DMA command failed. Smatch warning was removed.

Micky Ching (2):
  mmc: rtsx: add R1-no-CRC mmc command type handle
  mmc: rtsx: modify error handle and remove smatch warnings

 drivers/mmc/host/rtsx_pci_sdmmc.c |  121 -
 1 file changed, 67 insertions(+), 54 deletions(-)

--
1.7.9.5
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 1/2] mmc: rtsx: add R1-no-CRC mmc command type handle

2014-03-25 Thread micky_ching
From: Micky Ching 

commit a27fbf2f067b0cd6f172c8b696b9a44c58bfaa7a

produced a cmd.flags unhandled in realtek pci host driver.
This will make MMC card failed initialize, this patch is
used to handle the new cmd.flags condition and MMC card can be used.

Signed-off-by: Micky Ching 
---
 drivers/mmc/host/rtsx_pci_sdmmc.c |3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c 
b/drivers/mmc/host/rtsx_pci_sdmmc.c
index 5fb994f..0d8904a 100644
--- a/drivers/mmc/host/rtsx_pci_sdmmc.c
+++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
@@ -346,6 +346,9 @@ static void sd_send_cmd(struct realtek_pci_sdmmc *host, 
struct mmc_command *cmd)
case MMC_RSP_R1:
rsp_type = SD_RSP_TYPE_R1;
break;
+   case MMC_RSP_R1 & ~MMC_RSP_CRC:
+   rsp_type = SD_RSP_TYPE_R1 | SD_NO_CHECK_CRC7;
+   break;
case MMC_RSP_R1B:
rsp_type = SD_RSP_TYPE_R1b;
break;
-- 
1.7.9.5

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 0/2] mmc: rtsx: add new cmd type handle and modify error handle

2014-03-25 Thread micky_ching
From: Micky Ching 

Add new command type(R1 without CRC) handle, without this
patch mmc card initialize will be failed.

Using a more careful handle in request timeout, this would
improve error recover capability. Debug info is printed
using non DMA mode, this would help print more accurately
for DMA command failed. Smatch warning was removed.

Micky Ching (2):
  mmc: rtsx: add R1-no-CRC mmc command type handle
  mmc: rtsx: modify error handle and remove smatch warnings

 drivers/mmc/host/rtsx_pci_sdmmc.c |  121 -
 1 file changed, 67 insertions(+), 54 deletions(-)

--
1.7.9.5
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 2/2] mmc: rtsx: modify error handle and remove smatch warnings

2014-03-25 Thread micky_ching
From: Micky Ching 

Using non-DMA dump-regs, which would be more exactly for DMA transfer failed.

More careful handle when cmd/data timeout, add stop(CMD12) cmd before go to
finish request when multi-rw timeout.

Remove some static checher warings.
on commit: 
drivers/mmc/host/rtsx_pci_sdmmc.c:194 sd_finish_request()
error: we previously assumed 'mrq' could be null (see line 158)
drivers/mmc/host/rtsx_pci_sdmmc.c:504 sd_get_rsp()
error: we previously assumed 'cmd' could be null (see line 434)
drivers/mmc/host/rtsx_pci_sdmmc.c:525 sd_pre_dma_transfer()
warn: we tested 'next' before and it was 'false'

Signed-off-by: Micky Ching 
---
 drivers/mmc/host/rtsx_pci_sdmmc.c |  118 -
 1 file changed, 64 insertions(+), 54 deletions(-)

diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c 
b/drivers/mmc/host/rtsx_pci_sdmmc.c
index 0d8904a..d00a94e 100644
--- a/drivers/mmc/host/rtsx_pci_sdmmc.c
+++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
@@ -81,25 +81,23 @@ static inline void sd_clear_error(struct realtek_pci_sdmmc 
*host)
 }
 
 #ifdef DEBUG
+static inline void sd_print_reg(struct realtek_pci_sdmmc *host, u16 reg)
+{
+   u8 val;
+   if (rtsx_pci_read_register(host->pcr, reg, &val) < 0)
+   dev_dbg(sdmmc_dev(host), "read 0x%04x failed\n", reg);
+   else
+   dev_dbg(sdmmc_dev(host), "0x%04X: 0x%02x\n", reg, val);
+}
+
 static void sd_print_debug_regs(struct realtek_pci_sdmmc *host)
 {
-   struct rtsx_pcr *pcr = host->pcr;
u16 i;
-   u8 *ptr;
-
-   /* Print SD host internal registers */
-   rtsx_pci_init_cmd(pcr);
-   for (i = 0xFDA0; i <= 0xFDAE; i++)
-   rtsx_pci_add_cmd(pcr, READ_REG_CMD, i, 0, 0);
-   for (i = 0xFD52; i <= 0xFD69; i++)
-   rtsx_pci_add_cmd(pcr, READ_REG_CMD, i, 0, 0);
-   rtsx_pci_send_cmd(pcr, 100);
 
-   ptr = rtsx_pci_get_cmd_data(pcr);
for (i = 0xFDA0; i <= 0xFDAE; i++)
-   dev_dbg(sdmmc_dev(host), "0x%04X: 0x%02x\n", i, *(ptr++));
+   sd_print_reg(host, i);
for (i = 0xFD52; i <= 0xFD69; i++)
-   dev_dbg(sdmmc_dev(host), "0x%04X: 0x%02x\n", i, *(ptr++));
+   sd_print_reg(host, i);
 }
 #else
 #define sd_print_debug_regs(host)
@@ -125,19 +123,27 @@ static void sd_request_timeout(unsigned long host_addr)
spin_lock_irqsave(&host->lock, flags);
 
if (!host->mrq) {
-   dev_err(sdmmc_dev(host), "error: no request exist\n");
-   goto out;
+   dev_err(sdmmc_dev(host), "error: request not exist\n");
+   spin_unlock_irqrestore(&host->lock, flags);
+   return;
}
 
-   if (host->cmd)
+   if (host->cmd && host->data)
+   dev_err(sdmmc_dev(host), "error: cmd and data conflict\n");
+
+   if (host->cmd) {
host->cmd->error = -ETIMEDOUT;
-   if (host->data)
-   host->data->error = -ETIMEDOUT;
+   dev_dbg(sdmmc_dev(host), "timeout for cmd %d\n",
+   host->cmd->opcode);
+   tasklet_schedule(&host->cmd_tasklet);
+   }
 
-   dev_dbg(sdmmc_dev(host), "timeout for request\n");
+   if (host->data) {
+   host->data->error = -ETIMEDOUT;
+   dev_dbg(sdmmc_dev(host), "timeout for data transfer\n");
+   tasklet_schedule(&host->data_tasklet);
+   }
 
-out:
-   tasklet_schedule(&host->finish_tasklet);
spin_unlock_irqrestore(&host->lock, flags);
 }
 
@@ -157,7 +163,8 @@ static void sd_finish_request(unsigned long host_addr)
mrq = host->mrq;
if (!mrq) {
dev_err(sdmmc_dev(host), "error: no request need finish\n");
-   goto out;
+   spin_unlock_irqrestore(&host->lock, flags);
+   return;
}
 
cmd = mrq->cmd;
@@ -167,11 +174,6 @@ static void sd_finish_request(unsigned long host_addr)
(mrq->stop && mrq->stop->error) ||
(cmd && cmd->error) || (data && data->error);
 
-   if (any_error) {
-   rtsx_pci_stop_cmd(pcr);
-   sd_clear_error(host);
-   }
-
if (data) {
if (any_error)
data->bytes_xfered = 0;
@@ -188,7 +190,6 @@ static void sd_finish_request(unsigned long host_addr)
host->cmd = NULL;
host->data = NULL;
 
-out:
spin_unlock_irqrestore(&host->lock, flags);
mutex_unlock(&pcr->pcr_mutex);
mmc_request_done(host->mmc, mrq);
@@ -373,8 +374,11 @@ static void sd_send_cmd(struct realtek_pci_sdmmc *host, 
struct mmc_command *cmd)
if (cmd->opcode == SD_SWITCH_VOLTAGE) {
err = rtsx_pci_write_register(pcr, SD_BUS_STAT,
0xFF, SD_CLK_TOGGLE_EN);
-   if (err < 0)
+   if (err < 0) {
+   rtsx_pci_write_register(pcr, SD_BUS_STAT,
+   SD_CLK_TOGGLE_EN | SD_CLK_FORC

[PATCH v2 2/2] mmc: rtsx: modify error handle and remove smatch warnings

2014-03-26 Thread micky_ching
From: Micky Ching 

Using non-DMA dump-regs, which would be more exactly for DMA transfer failed.

More careful handle when cmd/data timeout, add stop(CMD12) cmd before go to
finish request when multi-rw timeout.

Remove some static checher warings.
on commit: 
drivers/mmc/host/rtsx_pci_sdmmc.c:194 sd_finish_request()
error: we previously assumed 'mrq' could be null (see line 158)
drivers/mmc/host/rtsx_pci_sdmmc.c:504 sd_get_rsp()
error: we previously assumed 'cmd' could be null (see line 434)
drivers/mmc/host/rtsx_pci_sdmmc.c:525 sd_pre_dma_transfer()
warn: we tested 'next' before and it was 'false'

Signed-off-by: Micky Ching 
---
 drivers/mmc/host/rtsx_pci_sdmmc.c |  119 -
 1 file changed, 65 insertions(+), 54 deletions(-)

diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c 
b/drivers/mmc/host/rtsx_pci_sdmmc.c
index 0d8904a..453e1d4 100644
--- a/drivers/mmc/host/rtsx_pci_sdmmc.c
+++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
@@ -81,25 +81,24 @@ static inline void sd_clear_error(struct realtek_pci_sdmmc 
*host)
 }
 
 #ifdef DEBUG
+static inline void sd_print_reg(struct realtek_pci_sdmmc *host, u16 reg)
+{
+   u8 val = 0;
+
+   if (rtsx_pci_read_register(host->pcr, reg, &val) < 0)
+   dev_dbg(sdmmc_dev(host), "read 0x%04x failed\n", reg);
+   else
+   dev_dbg(sdmmc_dev(host), "0x%04X: 0x%02x\n", reg, val);
+}
+
 static void sd_print_debug_regs(struct realtek_pci_sdmmc *host)
 {
-   struct rtsx_pcr *pcr = host->pcr;
u16 i;
-   u8 *ptr;
-
-   /* Print SD host internal registers */
-   rtsx_pci_init_cmd(pcr);
-   for (i = 0xFDA0; i <= 0xFDAE; i++)
-   rtsx_pci_add_cmd(pcr, READ_REG_CMD, i, 0, 0);
-   for (i = 0xFD52; i <= 0xFD69; i++)
-   rtsx_pci_add_cmd(pcr, READ_REG_CMD, i, 0, 0);
-   rtsx_pci_send_cmd(pcr, 100);
 
-   ptr = rtsx_pci_get_cmd_data(pcr);
for (i = 0xFDA0; i <= 0xFDAE; i++)
-   dev_dbg(sdmmc_dev(host), "0x%04X: 0x%02x\n", i, *(ptr++));
+   sd_print_reg(host, i);
for (i = 0xFD52; i <= 0xFD69; i++)
-   dev_dbg(sdmmc_dev(host), "0x%04X: 0x%02x\n", i, *(ptr++));
+   sd_print_reg(host, i);
 }
 #else
 #define sd_print_debug_regs(host)
@@ -125,19 +124,27 @@ static void sd_request_timeout(unsigned long host_addr)
spin_lock_irqsave(&host->lock, flags);
 
if (!host->mrq) {
-   dev_err(sdmmc_dev(host), "error: no request exist\n");
-   goto out;
+   dev_err(sdmmc_dev(host), "error: request not exist\n");
+   spin_unlock_irqrestore(&host->lock, flags);
+   return;
}
 
-   if (host->cmd)
+   if (host->cmd && host->data)
+   dev_err(sdmmc_dev(host), "error: cmd and data conflict\n");
+
+   if (host->cmd) {
host->cmd->error = -ETIMEDOUT;
-   if (host->data)
-   host->data->error = -ETIMEDOUT;
+   dev_dbg(sdmmc_dev(host), "timeout for cmd %d\n",
+   host->cmd->opcode);
+   tasklet_schedule(&host->cmd_tasklet);
+   }
 
-   dev_dbg(sdmmc_dev(host), "timeout for request\n");
+   if (host->data) {
+   host->data->error = -ETIMEDOUT;
+   dev_dbg(sdmmc_dev(host), "timeout for data transfer\n");
+   tasklet_schedule(&host->data_tasklet);
+   }
 
-out:
-   tasklet_schedule(&host->finish_tasklet);
spin_unlock_irqrestore(&host->lock, flags);
 }
 
@@ -157,7 +164,8 @@ static void sd_finish_request(unsigned long host_addr)
mrq = host->mrq;
if (!mrq) {
dev_err(sdmmc_dev(host), "error: no request need finish\n");
-   goto out;
+   spin_unlock_irqrestore(&host->lock, flags);
+   return;
}
 
cmd = mrq->cmd;
@@ -167,11 +175,6 @@ static void sd_finish_request(unsigned long host_addr)
(mrq->stop && mrq->stop->error) ||
(cmd && cmd->error) || (data && data->error);
 
-   if (any_error) {
-   rtsx_pci_stop_cmd(pcr);
-   sd_clear_error(host);
-   }
-
if (data) {
if (any_error)
data->bytes_xfered = 0;
@@ -188,7 +191,6 @@ static void sd_finish_request(unsigned long host_addr)
host->cmd = NULL;
host->data = NULL;
 
-out:
spin_unlock_irqrestore(&host->lock, flags);
mutex_unlock(&pcr->pcr_mutex);
mmc_request_done(host->mmc, mrq);
@@ -373,8 +375,11 @@ static void sd_send_cmd(struct realtek_pci_sdmmc *host, 
struct mmc_command *cmd)
if (cmd->opcode == SD_SWITCH_VOLTAGE) {
err = rtsx_pci_write_register(pcr, SD_BUS_STAT,
0xFF, SD_CLK_TOGGLE_EN);
-   if (err < 0)
+   if (err < 0) {
+   rtsx_pci_write_register(pcr, SD_BUS_STAT,
+   SD_CLK_TOGGLE_EN | SD_CL

[PATCH v2 1/2] mmc: rtsx: add R1-no-CRC mmc command type handle

2014-03-26 Thread micky_ching
From: Micky Ching 

commit a27fbf2f067b0cd6f172c8b696b9a44c58bfaa7a

produced a cmd.flags unhandled in realtek pci host driver.
This will make MMC card failed initialize, this patch is
used to handle the new cmd.flags condition and MMC card can be used.

Signed-off-by: Micky Ching 
---
 drivers/mmc/host/rtsx_pci_sdmmc.c |3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c 
b/drivers/mmc/host/rtsx_pci_sdmmc.c
index 5fb994f..0d8904a 100644
--- a/drivers/mmc/host/rtsx_pci_sdmmc.c
+++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
@@ -346,6 +346,9 @@ static void sd_send_cmd(struct realtek_pci_sdmmc *host, 
struct mmc_command *cmd)
case MMC_RSP_R1:
rsp_type = SD_RSP_TYPE_R1;
break;
+   case MMC_RSP_R1 & ~MMC_RSP_CRC:
+   rsp_type = SD_RSP_TYPE_R1 | SD_NO_CHECK_CRC7;
+   break;
case MMC_RSP_R1B:
rsp_type = SD_RSP_TYPE_R1b;
break;
-- 
1.7.9.5

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v2 0/2] mmc: rtsx: add new cmd type handle and modify error handle

2014-03-26 Thread micky_ching
From: Micky Ching 

v2:
fix checkpatch warning.
WARNING: Missing a blank line after declarations

v1:
Add new command type(R1 without CRC) handle, without this
patch mmc card initialize will be failed.

Using a more careful handle in request timeout, this would
improve error recover capability. Debug info is printed
using non DMA mode, this would help print more accurately
for DMA command failed. Smatch warning was removed.

Micky Ching (2):
  mmc: rtsx: add R1-no-CRC mmc command type handle
  mmc: rtsx: modify error handle and remove smatch warnings

 drivers/mmc/host/rtsx_pci_sdmmc.c |  122 +
 1 file changed, 68 insertions(+), 54 deletions(-)

--
1.7.9.5
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH] staging: rts5208: fix static checker warnings

2014-04-02 Thread micky_ching
From: Micky Ching 

The patch fa590c222fba: "staging: rts5208: add support for rts5208
and rts5288" from Nov 12, 2013, leads to the following static checker
warning:
drivers/staging/rts5208/rtsx_chip.c:107 rtsx_enable_bus_int()
warn: add curly braces?
This warning is produced because incorrect code indent.

Signed-off-by: Micky Ching 
---
 drivers/staging/rts5208/rtsx_chip.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/staging/rts5208/rtsx_chip.c 
b/drivers/staging/rts5208/rtsx_chip.c
index 6426807..7907e93 100644
--- a/drivers/staging/rts5208/rtsx_chip.c
+++ b/drivers/staging/rts5208/rtsx_chip.c
@@ -104,7 +104,7 @@ void rtsx_enable_bus_int(struct rtsx_chip *chip)
if (chip->ic_version >= IC_VER_C)
reg |= DELINK_INT_EN;
 #ifdef SUPPORT_OCP
-   reg |= OC_INT_EN;
+   reg |= OC_INT_EN;
 #endif
if (!chip->adma_mode)
reg |= DATA_DONE_INT_EN;
-- 
1.7.9.5

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH] mmc: rtsx: fix possible circular locking dependency

2014-04-15 Thread micky_ching
From: Micky Ching 

To avoid dead lock, we need make sure host->lock is always acquire
before pcr->lock. But in irq handler, we acquired pcr->lock in rtsx mfd
driver, and sd_isr_done_transfer() is called during pcr->lock already
acquired. Since in sd_isr_done_transfer() the only work we do is schdule
tasklet, the cmd_tasklet and data_tasklet never conflict, so it is safe
to remove spin_lock() here.

Signed-off-by: Micky Ching 
---
 drivers/mmc/host/rtsx_pci_sdmmc.c |4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c 
b/drivers/mmc/host/rtsx_pci_sdmmc.c
index 453e1d4..40695e0 100644
--- a/drivers/mmc/host/rtsx_pci_sdmmc.c
+++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
@@ -108,12 +108,10 @@ static void sd_isr_done_transfer(struct platform_device 
*pdev)
 {
struct realtek_pci_sdmmc *host = platform_get_drvdata(pdev);
 
-   spin_lock(&host->lock);
if (host->cmd)
tasklet_schedule(&host->cmd_tasklet);
-   if (host->data)
+   else if (host->data)
tasklet_schedule(&host->data_tasklet);
-   spin_unlock(&host->lock);
 }
 
 static void sd_request_timeout(unsigned long host_addr)
-- 
1.7.9.5

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH] mmc: rtsx: Revert "mmc: rtsx: add support for pre_req and post_req"

2014-04-28 Thread micky_ching
From: Micky Ching 

This reverts commit c42deffd5b53c9e583d83c7964854ede2f12410d.

commit  did use
mutex_unlock() in tasklet, but mutex_unlock() can't used in
tasklet(atomic context). The driver need use mutex to avoid concurrency,
so we can't use tasklet here, the patch need to be removed.

The spinlock host->lock and pcr->lock may deadlock, one way to solve the
deadlock is remove host->lock in sd_isr_done_transfer(), but if using
workqueue the we can avoid using the spinlock and also avoid the problem.

Signed-off-by: Micky Ching 
---
 drivers/mfd/rtsx_pcr.c|  132 
 drivers/mmc/host/rtsx_pci_sdmmc.c |  418 ++---
 include/linux/mfd/rtsx_common.h   |1 -
 include/linux/mfd/rtsx_pci.h  |6 -
 4 files changed, 109 insertions(+), 448 deletions(-)

diff --git a/drivers/mfd/rtsx_pcr.c b/drivers/mfd/rtsx_pcr.c
index c9de3d5..1d15735 100644
--- a/drivers/mfd/rtsx_pcr.c
+++ b/drivers/mfd/rtsx_pcr.c
@@ -338,28 +338,58 @@ int rtsx_pci_transfer_data(struct rtsx_pcr *pcr, struct 
scatterlist *sglist,
int num_sg, bool read, int timeout)
 {
struct completion trans_done;
-   int err = 0, count;
+   u8 dir;
+   int err = 0, i, count;
long timeleft;
unsigned long flags;
+   struct scatterlist *sg;
+   enum dma_data_direction dma_dir;
+   u32 val;
+   dma_addr_t addr;
+   unsigned int len;
+
+   dev_dbg(&(pcr->pci->dev), "--> %s: num_sg = %d\n", __func__, num_sg);
+
+   /* don't transfer data during abort processing */
+   if (pcr->remove_pci)
+   return -EINVAL;
+
+   if ((sglist == NULL) || (num_sg <= 0))
+   return -EINVAL;
 
-   count = rtsx_pci_dma_map_sg(pcr, sglist, num_sg, read);
+   if (read) {
+   dir = DEVICE_TO_HOST;
+   dma_dir = DMA_FROM_DEVICE;
+   } else {
+   dir = HOST_TO_DEVICE;
+   dma_dir = DMA_TO_DEVICE;
+   }
+
+   count = dma_map_sg(&(pcr->pci->dev), sglist, num_sg, dma_dir);
if (count < 1) {
dev_err(&(pcr->pci->dev), "scatterlist map failed\n");
return -EINVAL;
}
dev_dbg(&(pcr->pci->dev), "DMA mapping count: %d\n", count);
 
+   val = ((u32)(dir & 0x01) << 29) | TRIG_DMA | ADMA_MODE;
+   pcr->sgi = 0;
+   for_each_sg(sglist, sg, count, i) {
+   addr = sg_dma_address(sg);
+   len = sg_dma_len(sg);
+   rtsx_pci_add_sg_tbl(pcr, addr, len, i == count - 1);
+   }
 
spin_lock_irqsave(&pcr->lock, flags);
 
pcr->done = &trans_done;
pcr->trans_result = TRANS_NOT_READY;
init_completion(&trans_done);
+   rtsx_pci_writel(pcr, RTSX_HDBAR, pcr->host_sg_tbl_addr);
+   rtsx_pci_writel(pcr, RTSX_HDBCTLR, val);
 
spin_unlock_irqrestore(&pcr->lock, flags);
 
-   rtsx_pci_dma_transfer(pcr, sglist, count, read);
-
timeleft = wait_for_completion_interruptible_timeout(
&trans_done, msecs_to_jiffies(timeout));
if (timeleft <= 0) {
@@ -383,7 +413,7 @@ out:
pcr->done = NULL;
spin_unlock_irqrestore(&pcr->lock, flags);
 
-   rtsx_pci_dma_unmap_sg(pcr, sglist, num_sg, read);
+   dma_unmap_sg(&(pcr->pci->dev), sglist, num_sg, dma_dir);
 
if ((err < 0) && (err != -ENODEV))
rtsx_pci_stop_cmd(pcr);
@@ -395,73 +425,6 @@ out:
 }
 EXPORT_SYMBOL_GPL(rtsx_pci_transfer_data);
 
-int rtsx_pci_dma_map_sg(struct rtsx_pcr *pcr, struct scatterlist *sglist,
-   int num_sg, bool read)
-{
-   enum dma_data_direction dir = read ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
-
-   if (pcr->remove_pci)
-   return -EINVAL;
-
-   if ((sglist == NULL) || num_sg < 1)
-   return -EINVAL;
-
-   return dma_map_sg(&(pcr->pci->dev), sglist, num_sg, dir);
-}
-EXPORT_SYMBOL_GPL(rtsx_pci_dma_map_sg);
-
-int rtsx_pci_dma_unmap_sg(struct rtsx_pcr *pcr, struct scatterlist *sglist,
-   int num_sg, bool read)
-{
-   enum dma_data_direction dir = read ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
-
-   if (pcr->remove_pci)
-   return -EINVAL;
-
-   if (sglist == NULL || num_sg < 1)
-   return -EINVAL;
-
-   dma_unmap_sg(&(pcr->pci->dev), sglist, num_sg, dir);
-   return num_sg;
-}
-EXPORT_SYMBOL_GPL(rtsx_pci_dma_unmap_sg);
-
-int rtsx_pci_dma_transfer(struct rtsx_pcr *pcr, struct scatterlist *sglist,
-   int sg_count, bool read)
-{
-   struct scatterlist *sg;
-   dma_addr_t addr;
-   unsigned int len;
-   int i;
-   u32 val;
-   u8 dir = read ? DEVICE_TO_HOST : HOST_TO_DEVICE;
-   unsigned long flags;
-
-   if (pcr->remove_pci)
-   return -EINVAL;
-
-   if ((sglist == NULL) || (sg_count < 1))
-   return -EINVAL;
-
-   val = ((u32)(dir & 0x01) << 29) | TRIG_DMA | ADMA_MODE;
-   pcr->sgi = 0;
-   for_each_sg(sglist, s

[RESEND] mfd: rtsx: add support for rts522A

2015-06-28 Thread micky_ching
From: Micky Ching 

rts522a(rts5227s) is derived from rts5227, and mainly same with rts5227.
Add it to file mfd/rts5227.c to support this chip.

Signed-off-by: Micky Ching 
---
 drivers/mfd/Kconfig  |  7 ++--
 drivers/mfd/rts5227.c| 77 ++--
 drivers/mfd/rtsx_pcr.c   |  5 +++
 drivers/mfd/rtsx_pcr.h   |  3 ++
 include/linux/mfd/rtsx_pci.h |  6 
 5 files changed, 93 insertions(+), 5 deletions(-)

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 6538159..614c146 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -686,9 +686,10 @@ config MFD_RTSX_PCI
select MFD_CORE
help
  This supports for Realtek PCI-Express card reader including rts5209,
- rts5229, rtl8411, etc. Realtek card reader supports access to many
- types of memory cards, such as Memory Stick, Memory Stick Pro,
- Secure Digital and MultiMediaCard.
+ rts5227, rts522A, rts5229, rts5249, rts524A, rts525A, rtl8411, etc.
+ Realtek card reader supports access to many types of memory cards,
+ such as Memory Stick, Memory Stick Pro, Secure Digital and
+ MultiMediaCard.
 
 config MFD_RT5033
tristate "Richtek RT5033 Power Management IC"
diff --git a/drivers/mfd/rts5227.c b/drivers/mfd/rts5227.c
index ce012d7..cf13e66 100644
--- a/drivers/mfd/rts5227.c
+++ b/drivers/mfd/rts5227.c
@@ -26,6 +26,14 @@
 
 #include "rtsx_pcr.h"
 
+static u8 rts5227_get_ic_version(struct rtsx_pcr *pcr)
+{
+   u8 val;
+
+   rtsx_pci_read_register(pcr, DUMMY_REG_RESET_0, &val);
+   return val & 0x0F;
+}
+
 static void rts5227_fill_driving(struct rtsx_pcr *pcr, u8 voltage)
 {
u8 driving_3v3[4][3] = {
@@ -88,7 +96,7 @@ static void rts5227_force_power_down(struct rtsx_pcr *pcr, u8 
pm_state)
rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 3, 0x01, 0);
 
if (pm_state == HOST_ENTER_S3)
-   rtsx_pci_write_register(pcr, PM_CTRL3, 0x10, 0x10);
+   rtsx_pci_write_register(pcr, pcr->reg_pm_ctrl3, 0x10, 0x10);
 
rtsx_pci_write_register(pcr, FPDCTL, 0x03, 0x03);
 }
@@ -121,7 +129,7 @@ static int rts5227_extra_init_hw(struct rtsx_pcr *pcr)
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0xB8, 0xB8);
else
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0xB8, 0x88);
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PM_CTRL3, 0x10, 0x00);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, pcr->reg_pm_ctrl3, 0x10, 0x00);
 
return rtsx_pci_send_cmd(pcr, 100);
 }
@@ -298,8 +306,73 @@ void rts5227_init_params(struct rtsx_pcr *pcr)
pcr->tx_initial_phase = SET_CLOCK_PHASE(27, 27, 15);
pcr->rx_initial_phase = SET_CLOCK_PHASE(30, 7, 7);
 
+   pcr->ic_version = rts5227_get_ic_version(pcr);
pcr->sd_pull_ctl_enable_tbl = rts5227_sd_pull_ctl_enable_tbl;
pcr->sd_pull_ctl_disable_tbl = rts5227_sd_pull_ctl_disable_tbl;
pcr->ms_pull_ctl_enable_tbl = rts5227_ms_pull_ctl_enable_tbl;
pcr->ms_pull_ctl_disable_tbl = rts5227_ms_pull_ctl_disable_tbl;
+
+   pcr->reg_pm_ctrl3 = PM_CTRL3;
+}
+
+static int rts522a_optimize_phy(struct rtsx_pcr *pcr)
+{
+   int err;
+
+   err = rtsx_pci_write_register(pcr, RTS522A_PM_CTRL3, D3_DELINK_MODE_EN,
+   0x00);
+   if (err < 0)
+   return err;
+
+   if (is_version(pcr, 0x522A, IC_VER_A)) {
+   err = rtsx_pci_write_phy_register(pcr, PHY_RCR2,
+   PHY_RCR2_INIT_27S);
+   if (err)
+   return err;
+
+   rtsx_pci_write_phy_register(pcr, PHY_RCR1, PHY_RCR1_INIT_27S);
+   rtsx_pci_write_phy_register(pcr, PHY_FLD0, PHY_FLD0_INIT_27S);
+   rtsx_pci_write_phy_register(pcr, PHY_FLD3, PHY_FLD3_INIT_27S);
+   rtsx_pci_write_phy_register(pcr, PHY_FLD4, PHY_FLD4_INIT_27S);
+   }
+
+   return 0;
+}
+
+static int rts522a_extra_init_hw(struct rtsx_pcr *pcr)
+{
+   rts5227_extra_init_hw(pcr);
+
+   rtsx_pci_write_register(pcr, FUNC_FORCE_CTL, FUNC_FORCE_UPME_XMT_DBG,
+   FUNC_FORCE_UPME_XMT_DBG);
+   rtsx_pci_write_register(pcr, PCLK_CTL, 0x04, 0x04);
+   rtsx_pci_write_register(pcr, PM_EVENT_DEBUG, PME_DEBUG_0, PME_DEBUG_0);
+   rtsx_pci_write_register(pcr, PM_CLK_FORCE_CTL, 0xFF, 0x11);
+
+   return 0;
+}
+
+/* rts522a operations mainly derived from rts5227, except phy/hw init setting.
+ */
+static const struct pcr_ops rts522a_pcr_ops = {
+   .fetch_vendor_settings = rts5227_fetch_vendor_settings,
+   .extra_init_hw = rts522a_extra_init_hw,
+   .optimize_phy = rts522a_optimize_phy,
+   .turn_on_led = rts5227_turn_on_led,
+   .turn_off_led = rts5227_turn_off_led,
+   .enable_auto_blink = rts5227_enable_auto_blink,
+   .disable_auto_blink = rts5227_disable_auto_blink,
+   .card_power_on = rts5227_card_power_on,
+   .card_power_off = rts5227_card_p

[PATCH v2 1/9] mfd: rtsx: replace TAB by SPC after #define

2015-01-21 Thread micky_ching
From: Micky Ching 

Re-format coding-style, using uniform SPC after "#define" keyword
instead of mixing using TAB and SPC.

Signed-off-by: Micky Ching 
---
 include/linux/mfd/rtsx_pci.h | 254 +--
 1 file changed, 127 insertions(+), 127 deletions(-)

diff --git a/include/linux/mfd/rtsx_pci.h b/include/linux/mfd/rtsx_pci.h
index 0c12628..a9c2a14 100644
--- a/include/linux/mfd/rtsx_pci.h
+++ b/include/linux/mfd/rtsx_pci.h
@@ -175,9 +175,9 @@
 /* CARD_SHARE_MODE */
 #define CARD_SHARE_MASK0x0F
 #define CARD_SHARE_MULTI_LUN   0x00
-#defineCARD_SHARE_NORMAL   0x00
-#defineCARD_SHARE_48_SD0x04
-#defineCARD_SHARE_48_MS0x08
+#define CARD_SHARE_NORMAL  0x00
+#define CARD_SHARE_48_SD   0x04
+#define CARD_SHARE_48_MS   0x08
 /* CARD_SHARE_MODE for barossa */
 #define CARD_SHARE_BAROSSA_SD  0x01
 #define CARD_SHARE_BAROSSA_MS  0x02
@@ -249,76 +249,76 @@
 #define CD_AUTO_DISABLE0x40
 
 /* SD_STAT1 */
-#defineSD_CRC7_ERR 0x80
-#defineSD_CRC16_ERR0x40
-#defineSD_CRC_WRITE_ERR0x20
-#defineSD_CRC_WRITE_ERR_MASK   0x1C
-#defineGET_CRC_TIME_OUT0x02
-#defineSD_TUNING_COMPARE_ERR   0x01
+#define SD_CRC7_ERR0x80
+#define SD_CRC16_ERR   0x40
+#define SD_CRC_WRITE_ERR   0x20
+#define SD_CRC_WRITE_ERR_MASK  0x1C
+#define GET_CRC_TIME_OUT   0x02
+#define SD_TUNING_COMPARE_ERR  0x01
 
 /* SD_STAT2 */
-#defineSD_RSP_80CLK_TIMEOUT0x01
+#define SD_RSP_80CLK_TIMEOUT   0x01
 
 /* SD_BUS_STAT */
-#defineSD_CLK_TOGGLE_EN0x80
-#defineSD_CLK_FORCE_STOP   0x40
-#defineSD_DAT3_STATUS  0x10
-#defineSD_DAT2_STATUS  0x08
-#defineSD_DAT1_STATUS  0x04
-#defineSD_DAT0_STATUS  0x02
-#defineSD_CMD_STATUS   0x01
+#define SD_CLK_TOGGLE_EN   0x80
+#define SD_CLK_FORCE_STOP  0x40
+#define SD_DAT3_STATUS 0x10
+#define SD_DAT2_STATUS 0x08
+#define SD_DAT1_STATUS 0x04
+#define SD_DAT0_STATUS 0x02
+#define SD_CMD_STATUS  0x01
 
 /* SD_PAD_CTL */
-#defineSD_IO_USING_1V8 0x80
-#defineSD_IO_USING_3V3 0x7F
-#defineTYPE_A_DRIVING  0x00
-#defineTYPE_B_DRIVING  0x01
-#defineTYPE_C_DRIVING  0x02
-#defineTYPE_D_DRIVING  0x03
+#define SD_IO_USING_1V80x80
+#define SD_IO_USING_3V30x7F
+#define TYPE_A_DRIVING 0x00
+#define TYPE_B_DRIVING 0x01
+#define TYPE_C_DRIVING 0x02
+#define TYPE_D_DRIVING 0x03
 
 /* SD_SAMPLE_POINT_CTL */
-#defineDDR_FIX_RX_DAT  0x00
-#defineDDR_VAR_RX_DAT  0x80
-#defineDDR_FIX_RX_DAT_EDGE 0x00
-#defineDDR_FIX_RX_DAT_14_DELAY 0x40
-#defineDDR_FIX_RX_CMD  0x00
-#defineDDR_VAR_RX_CMD  0x20
-#defineDDR_FIX_RX_CMD_POS_EDGE 0x00
-#defineDDR_FIX_RX_CMD_14_DELAY 0x10
-#defineSD20_RX_POS_EDGE0x00
-#defineSD20_RX_14_DELAY0x08
+#define DDR_FIX_RX_DAT 0x00
+#define DDR_VAR_RX_DAT 0x80
+#define DDR_FIX_RX_DAT_EDGE0x00
+#define DDR_FIX_RX_DAT_14_DELAY0x40
+#define DDR_FIX_RX_CMD 0x00
+#define DDR_VAR_RX_CMD 0x20
+#define DDR_FIX_RX_CMD_POS_EDGE0x00
+#define DDR_FIX_RX_CMD_14_DELAY0x10
+#define SD20_RX_POS_EDGE   0x00
+#define SD20_RX_14_DELAY   0x08
 #define SD20_RX_SEL_MASK   0x08
 
 /* SD_PUSH_POINT_CTL */
-#defineDDR_FIX_TX_CMD_DAT  0x00
-#defineDDR_VAR_TX_CMD_DAT  0x80
-#defineDDR_FIX_TX_DAT_14_TSU   0x00
-#defineDDR_FIX_TX_DAT_12_TSU   0x40
-#defineDDR_FIX_TX_CMD_NEG_EDGE 0x00
-#defineDDR_FIX_TX_CMD_14_AHEAD 0x20
-#defineSD20_TX_NEG_EDGE0x00
-#defineSD20_TX_14_AHEAD0x10
+#define DDR_FIX_TX_CMD_DAT 0x00
+#define DDR_VAR_TX_CMD_DAT 0x80
+#define DDR_FIX_TX_DAT_14_TSU  0x00
+#define DDR_FIX_TX_DAT_12_TSU  0x40
+#define DDR_FIX_TX_CMD_NEG_EDGE0x00
+#define DDR_FIX_TX_CMD_14_AHEAD0x20
+#define SD20_TX_NEG_EDGE

[PATCH v2 3/9] mfd: rtsx: update PETXCFG address

2015-01-21 Thread micky_ching
From: Micky Ching 

PETXCFG is defined at 0xFF03, the old 0xFE49 not used any more.

Signed-off-by: Micky Ching 
---
 drivers/mfd/rts5227.c| 6 ++
 drivers/mfd/rts5249.c| 6 ++
 include/linux/mfd/rtsx_pci.h | 2 +-
 3 files changed, 5 insertions(+), 9 deletions(-)

diff --git a/drivers/mfd/rts5227.c b/drivers/mfd/rts5227.c
index 3240740..1f387d4 100644
--- a/drivers/mfd/rts5227.c
+++ b/drivers/mfd/rts5227.c
@@ -118,11 +118,9 @@ static int rts5227_extra_init_hw(struct rtsx_pcr *pcr)
rts5227_fill_driving(pcr, OUTPUT_3V3);
/* Configure force_clock_req */
if (pcr->flags & PCR_REVERSE_SOCKET)
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
-   AUTOLOAD_CFG_BASE + 3, 0xB8, 0xB8);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0xB8, 0xB8);
else
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
-   AUTOLOAD_CFG_BASE + 3, 0xB8, 0x88);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0xB8, 0x88);
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PM_CTRL3, 0x10, 0x00);
 
return rtsx_pci_send_cmd(pcr, 100);
diff --git a/drivers/mfd/rts5249.c b/drivers/mfd/rts5249.c
index cf425cc..225ad55 100644
--- a/drivers/mfd/rts5249.c
+++ b/drivers/mfd/rts5249.c
@@ -116,11 +116,9 @@ static int rts5249_extra_init_hw(struct rtsx_pcr *pcr)
/* Configure driving */
rts5249_fill_driving(pcr, OUTPUT_3V3);
if (pcr->flags & PCR_REVERSE_SOCKET)
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
-   AUTOLOAD_CFG_BASE + 3, 0xB0, 0xB0);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0xB0, 0xB0);
else
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
-   AUTOLOAD_CFG_BASE + 3, 0xB0, 0x80);
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0xB0, 0x80);
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PM_CTRL3, 0x10, 0x00);
 
return rtsx_pci_send_cmd(pcr, 100);
diff --git a/include/linux/mfd/rtsx_pci.h b/include/linux/mfd/rtsx_pci.h
index e81f2bb..87cff60 100644
--- a/include/linux/mfd/rtsx_pci.h
+++ b/include/linux/mfd/rtsx_pci.h
@@ -572,7 +572,6 @@
 #define MSGTXDATA2 0xFE46
 #define MSGTXDATA3 0xFE47
 #define MSGTXCTL   0xFE48
-#define PETXCFG0xFE49
 #define LTR_CTL0xFE4A
 #define OBFF_CFG   0xFE4C
 
@@ -606,6 +605,7 @@
 #define DUMMY_REG_RESET_0  0xFE90
 
 #define AUTOLOAD_CFG_BASE  0xFF00
+#define PETXCFG0xFF03
 
 #define PM_CTRL1   0xFF44
 #define PM_CTRL2   0xFF45
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v2 5/9] mfd: rtsx: update phy register

2015-01-21 Thread micky_ching
From: Micky Ching 

update phy register value and using direct value instead of macros.
It is much easier to debug using constant value than a lot of macros.
We usually need compare the value directly to check the configure.

Signed-off-by: Micky Ching 
---
 drivers/mfd/rts5249.c|  55 --
 include/linux/mfd/rtsx_pci.h | 109 ++-
 2 files changed, 85 insertions(+), 79 deletions(-)

diff --git a/drivers/mfd/rts5249.c b/drivers/mfd/rts5249.c
index 2fe2854..d8072f6 100644
--- a/drivers/mfd/rts5249.c
+++ b/drivers/mfd/rts5249.c
@@ -132,57 +132,62 @@ static int rts5249_optimize_phy(struct rtsx_pcr *pcr)
if (err < 0)
return err;
 
-   err = rtsx_pci_write_phy_register(pcr, PHY_REG_REV,
-   PHY_REG_REV_RESV | PHY_REG_REV_RXIDLE_LATCHED |
-   PHY_REG_REV_P1_EN | PHY_REG_REV_RXIDLE_EN |
-   PHY_REG_REV_RX_PWST | PHY_REG_REV_CLKREQ_DLY_TIMER_1_0 |
-   PHY_REG_REV_STOP_CLKRD | PHY_REG_REV_STOP_CLKWR);
+   err = rtsx_pci_write_phy_register(pcr, PHY_REV,
+   PHY_REV_RESV | PHY_REV_RXIDLE_LATCHED |
+   PHY_REV_P1_EN | PHY_REV_RXIDLE_EN |
+   PHY_REV_CLKREQ_TX_EN | PHY_REV_RX_PWST |
+   PHY_REV_CLKREQ_DT_1_0 | PHY_REV_STOP_CLKRD |
+   PHY_REV_STOP_CLKWR);
if (err < 0)
return err;
 
msleep(1);
 
err = rtsx_pci_write_phy_register(pcr, PHY_BPCR,
-   PHY_BPCR_IBRXSEL | PHY_BPCR_IBTXSEL |
-   PHY_BPCR_IB_FILTER | PHY_BPCR_CMIRROR_EN);
+   PHY_BPCR_IBRXSEL | PHY_BPCR_IBTXSEL |
+   PHY_BPCR_IB_FILTER | PHY_BPCR_CMIRROR_EN);
if (err < 0)
return err;
+
err = rtsx_pci_write_phy_register(pcr, PHY_PCR,
-   PHY_PCR_FORCE_CODE | PHY_PCR_OOBS_CALI_50 |
-   PHY_PCR_OOBS_VCM_08 | PHY_PCR_OOBS_SEN_90 |
-   PHY_PCR_RSSI_EN);
+   PHY_PCR_FORCE_CODE | PHY_PCR_OOBS_CALI_50 |
+   PHY_PCR_OOBS_VCM_08 | PHY_PCR_OOBS_SEN_90 |
+   PHY_PCR_RSSI_EN | PHY_PCR_RX10K);
if (err < 0)
return err;
+
err = rtsx_pci_write_phy_register(pcr, PHY_RCR2,
-   PHY_RCR2_EMPHASE_EN | PHY_RCR2_NADJR |
-   PHY_RCR2_CDR_CP_10 | PHY_RCR2_CDR_SR_2 |
-   PHY_RCR2_FREQSEL_12 | PHY_RCR2_CPADJEN |
-   PHY_RCR2_CDR_SC_8 | PHY_RCR2_CALIB_LATE);
+   PHY_RCR2_EMPHASE_EN | PHY_RCR2_NADJR |
+   PHY_RCR2_CDR_SR_2 | PHY_RCR2_FREQSEL_12 |
+   PHY_RCR2_CDR_SC_12P | PHY_RCR2_CALIB_LATE);
if (err < 0)
return err;
+
err = rtsx_pci_write_phy_register(pcr, PHY_FLD4,
-   PHY_FLD4_FLDEN_SEL | PHY_FLD4_REQ_REF |
-   PHY_FLD4_RXAMP_OFF | PHY_FLD4_REQ_ADDA |
-   PHY_FLD4_BER_COUNT | PHY_FLD4_BER_TIMER |
-   PHY_FLD4_BER_CHK_EN);
+   PHY_FLD4_FLDEN_SEL | PHY_FLD4_REQ_REF |
+   PHY_FLD4_RXAMP_OFF | PHY_FLD4_REQ_ADDA |
+   PHY_FLD4_BER_COUNT | PHY_FLD4_BER_TIMER |
+   PHY_FLD4_BER_CHK_EN);
if (err < 0)
return err;
-   err = rtsx_pci_write_phy_register(pcr, PHY_RDR, PHY_RDR_RXDSEL_1_9);
+   err = rtsx_pci_write_phy_register(pcr, PHY_RDR,
+   PHY_RDR_RXDSEL_1_9 | PHY_SSC_AUTO_PWD);
if (err < 0)
return err;
err = rtsx_pci_write_phy_register(pcr, PHY_RCR1,
-   PHY_RCR1_ADP_TIME | PHY_RCR1_VCO_COARSE);
+   PHY_RCR1_ADP_TIME_4 | PHY_RCR1_VCO_COARSE);
if (err < 0)
return err;
err = rtsx_pci_write_phy_register(pcr, PHY_FLD3,
-   PHY_FLD3_TIMER_4 | PHY_FLD3_TIMER_6 |
-   PHY_FLD3_RXDELINK);
+   PHY_FLD3_TIMER_4 | PHY_FLD3_TIMER_6 |
+   PHY_FLD3_RXDELINK);
if (err < 0)
return err;
+
return rtsx_pci_write_phy_register(pcr, PHY_TUNE,
-   PHY_TUNE_TUNEREF_1_0 | PHY_TUNE_VBGSEL_1252 |
-   PHY_TUNE_SDBUS_33 | PHY_TUNE_TUNED18 |
-   PHY_TUNE_TUNED12);
+   PHY_TUNE_TUNEREF_1_0 | PHY_TUNE_VBGSEL_1252 |
+   PHY_TUNE_SDBUS_33 | PHY_TUNE_TUNED18 |
+   PHY_TUNE_TUNED12 | PHY_TUNE_TUNEA12);
 }
 
 static int rts5249_turn_on_led(struct rtsx_pcr *pcr)
diff --git a/include/linux/mfd/rtsx_pci.h b/include/linux/mfd/rtsx_pci.h
index 87cff60..0103210 100644
--- a/include/linux/mfd/rtsx_pci.h
+++ b/include/linux/mfd/rtsx_pci.h
@@ -630,16 +630,47 @@
 
 /* Phy register */
 #define PHY_PCR0x00
+#define   PHY_PCR_FORCE_CODE   0xB000
+#define   PHY_PCR_OOBS_CALI_50 0x0800
+#define   PHY_PCR_OOBS_VCM_

[PATCH v2 8/9] mfd: rtsx: add support for rts525A

2015-01-21 Thread micky_ching
From: Micky Ching 

add support for new chip rts525A.

Signed-off-by: Micky Ching 
---
 drivers/mfd/rts5249.c| 104 ++-
 drivers/mfd/rtsx_pcr.c   |  13 --
 drivers/mfd/rtsx_pcr.h   |   1 +
 include/linux/mfd/rtsx_pci.h |  15 +++
 4 files changed, 129 insertions(+), 4 deletions(-)

diff --git a/drivers/mfd/rts5249.c b/drivers/mfd/rts5249.c
index 97dde92..134e03f 100644
--- a/drivers/mfd/rts5249.c
+++ b/drivers/mfd/rts5249.c
@@ -97,7 +97,7 @@ static void rtsx_base_force_power_down(struct rtsx_pcr *pcr, 
u8 pm_state)
rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 3, 0x01, 0);
 
if (pm_state == HOST_ENTER_S3) {
-   if (PCI_PID(pcr) == 0x524A)
+   if (PCI_PID(pcr) == 0x524A || PCI_PID(pcr) == 0x525A)
rtsx_pci_write_register(pcr, RTS524A_PM_CTRL3,
D3_DELINK_MODE_EN, D3_DELINK_MODE_EN);
else if (PCI_PID(pcr) == 0x5249)
@@ -485,3 +485,105 @@ void rts524a_init_params(struct rtsx_pcr *pcr)
pcr->ops = &rts524a_pcr_ops;
 }
 
+static int rts525a_card_power_on(struct rtsx_pcr *pcr, int card)
+{
+   rtsx_pci_write_register(pcr, LDO_VCC_CFG1,
+   LDO_VCC_TUNE_MASK, LDO_VCC_3V3);
+   return rtsx_base_card_power_on(pcr, card);
+}
+
+static int rts525a_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
+{
+   switch (voltage) {
+   case OUTPUT_3V3:
+   rtsx_pci_write_register(pcr, LDO_CONFIG2,
+   LDO_D3318_MASK, LDO_D3318_33V);
+   rtsx_pci_write_register(pcr, SD_PAD_CTL, SD_IO_USING_1V8, 0);
+   break;
+   case OUTPUT_1V8:
+   rtsx_pci_write_register(pcr, LDO_CONFIG2,
+   LDO_D3318_MASK, LDO_D3318_18V);
+   rtsx_pci_write_register(pcr, SD_PAD_CTL, SD_IO_USING_1V8,
+   SD_IO_USING_1V8);
+   break;
+   default:
+   return -EINVAL;
+   }
+
+   rtsx_pci_init_cmd(pcr);
+   rts5249_fill_driving(pcr, voltage);
+   return rtsx_pci_send_cmd(pcr, 100);
+}
+
+static int rts525a_optimize_phy(struct rtsx_pcr *pcr)
+{
+   int err;
+
+   err = rtsx_pci_write_register(pcr, RTS524A_PM_CTRL3,
+   D3_DELINK_MODE_EN, 0x00);
+   if (err < 0)
+   return err;
+
+   rtsx_pci_write_phy_register(pcr, _PHY_FLD0,
+   _PHY_FLD0_CLK_REQ_20C | _PHY_FLD0_RX_IDLE_EN |
+   _PHY_FLD0_BIT_ERR_RSTN | _PHY_FLD0_BER_COUNT |
+   _PHY_FLD0_BER_TIMER | _PHY_FLD0_CHECK_EN);
+
+   rtsx_pci_write_phy_register(pcr, _PHY_ANA03,
+   _PHY_ANA03_TIMER_MAX | _PHY_ANA03_OOBS_DEB_EN |
+   _PHY_CMU_DEBUG_EN);
+
+   if (is_version(pcr, 0x525A, IC_VER_A))
+   rtsx_pci_write_phy_register(pcr, _PHY_REV0,
+   _PHY_REV0_FILTER_OUT | _PHY_REV0_CDR_BYPASS_PFD |
+   _PHY_REV0_CDR_RX_IDLE_BYPASS);
+
+   return 0;
+}
+
+static int rts525a_extra_init_hw(struct rtsx_pcr *pcr)
+{
+   rts5249_extra_init_hw(pcr);
+
+   rtsx_pci_write_register(pcr, PCLK_CTL, PCLK_MODE_SEL, PCLK_MODE_SEL);
+   if (is_version(pcr, 0x525A, IC_VER_A)) {
+   rtsx_pci_write_register(pcr, L1SUB_CONFIG2,
+   L1SUB_AUTO_CFG, L1SUB_AUTO_CFG);
+   rtsx_pci_write_register(pcr, RREF_CFG,
+   RREF_VBGSEL_MASK, RREF_VBGSEL_1V25);
+   rtsx_pci_write_register(pcr, LDO_VIO_CFG,
+   LDO_VIO_TUNE_MASK, LDO_VIO_1V7);
+   rtsx_pci_write_register(pcr, LDO_DV12S_CFG,
+   LDO_D12_TUNE_MASK, LDO_D12_TUNE_DF);
+   rtsx_pci_write_register(pcr, LDO_AV12S_CFG,
+   LDO_AV12S_TUNE_MASK, LDO_AV12S_TUNE_DF);
+   rtsx_pci_write_register(pcr, LDO_VCC_CFG0,
+   LDO_VCC_LMTVTH_MASK, LDO_VCC_LMTVTH_2A);
+   rtsx_pci_write_register(pcr, OOBS_CONFIG,
+   OOBS_AUTOK_DIS | OOBS_VAL_MASK, 0x89);
+   }
+
+   return 0;
+}
+
+static const struct pcr_ops rts525a_pcr_ops = {
+   .fetch_vendor_settings = rtsx_base_fetch_vendor_settings,
+   .extra_init_hw = rts525a_extra_init_hw,
+   .optimize_phy = rts525a_optimize_phy,
+   .turn_on_led = rtsx_base_turn_on_led,
+   .turn_off_led = rtsx_base_turn_off_led,
+   .enable_auto_blink = rtsx_base_enable_auto_blink,
+   .disable_auto_blink = rtsx_base_disable_auto_blink,
+   .card_power_on = rts525a_card_power_on,
+   .card_power_off = rtsx_base_card_power_off,
+   .switch_output_voltage = rts525a_switch_output_voltage,
+   .force_power_down = rtsx_base_force_power_down,
+};
+
+void rts525a_init_params(struct rtsx_pcr *pcr)
+{
+   rts5249_init_params(pcr);
+
+   pcr->ops = &rts525a_pcr_ops;
+}
+
diff --git a/drivers/mfd/rtsx_pcr.c b/drivers/mfd/rtsx_pcr.c
index 69467c6..681e1a6 100644
-

[PATCH v2 6/9] mfd: rtsx: remove LCTLR defination

2015-01-21 Thread micky_ching
From: Micky Ching 

To enable/disable ASPM we should find LINK CONTROL register
in PCI config space. All old chip use 0x80 address, but new
chip may use another address, so we using pci_find_capability()
to get LINK CONTROL address.

rtsx_gops.c was removed, we consider to put some common operations
to this file, but the actual thing is, only a group of chips
are in common ops1, and another group of chips in common ops2,
it is hard to decide put which ops into generic ops file.

Signed-off-by: Micky Ching 
---
 drivers/mfd/Makefile |  2 +-
 drivers/mfd/rts5227.c|  2 +-
 drivers/mfd/rts5249.c|  3 +--
 drivers/mfd/rtsx_gops.c  | 37 -
 drivers/mfd/rtsx_pcr.c   | 23 ++-
 include/linux/mfd/rtsx_pci.h | 10 +-
 6 files changed, 22 insertions(+), 55 deletions(-)
 delete mode 100644 drivers/mfd/rtsx_gops.c

diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 53467e2..2cd7e74 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -13,7 +13,7 @@ obj-$(CONFIG_MFD_CROS_EC) += cros_ec.o
 obj-$(CONFIG_MFD_CROS_EC_I2C)  += cros_ec_i2c.o
 obj-$(CONFIG_MFD_CROS_EC_SPI)  += cros_ec_spi.o
 
-rtsx_pci-objs  := rtsx_pcr.o rtsx_gops.o rts5209.o rts5229.o 
rtl8411.o rts5227.o rts5249.o
+rtsx_pci-objs  := rtsx_pcr.o rts5209.o rts5229.o rtl8411.o 
rts5227.o rts5249.o
 obj-$(CONFIG_MFD_RTSX_PCI) += rtsx_pci.o
 obj-$(CONFIG_MFD_RTSX_USB) += rtsx_usb.o
 
diff --git a/drivers/mfd/rts5227.c b/drivers/mfd/rts5227.c
index 1f387d4..0c02831 100644
--- a/drivers/mfd/rts5227.c
+++ b/drivers/mfd/rts5227.c
@@ -130,7 +130,7 @@ static int rts5227_optimize_phy(struct rtsx_pcr *pcr)
 {
int err;
 
-   err = rtsx_gops_pm_reset(pcr);
+   err = rtsx_pci_write_register(pcr, PM_CTRL3, D3_DELINK_MODE_EN, 0x00);
if (err < 0)
return err;
 
diff --git a/drivers/mfd/rts5249.c b/drivers/mfd/rts5249.c
index d8072f6..3977946 100644
--- a/drivers/mfd/rts5249.c
+++ b/drivers/mfd/rts5249.c
@@ -119,7 +119,6 @@ static int rts5249_extra_init_hw(struct rtsx_pcr *pcr)
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0xB0, 0xB0);
else
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0xB0, 0x80);
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PM_CTRL3, 0x10, 0x00);
 
return rtsx_pci_send_cmd(pcr, 100);
 }
@@ -128,7 +127,7 @@ static int rts5249_optimize_phy(struct rtsx_pcr *pcr)
 {
int err;
 
-   err = rtsx_gops_pm_reset(pcr);
+   err = rtsx_pci_write_register(pcr, PM_CTRL3, D3_DELINK_MODE_EN, 0x00);
if (err < 0)
return err;
 
diff --git a/drivers/mfd/rtsx_gops.c b/drivers/mfd/rtsx_gops.c
deleted file mode 100644
index b1a98c6..000
--- a/drivers/mfd/rtsx_gops.c
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Driver for Realtek PCI-Express card reader
- *
- * Copyright(c) 2009-2013 Realtek Semiconductor Corp. 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 as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * 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.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see .
- *
- * Author:
- *   Micky Ching 
- */
-
-#include 
-#include "rtsx_pcr.h"
-
-int rtsx_gops_pm_reset(struct rtsx_pcr *pcr)
-{
-   int err;
-
-   /* init aspm */
-   rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, 0xFF, 0x00);
-   err = rtsx_pci_update_cfg_byte(pcr, LCTLR, ~LCTLR_ASPM_CTL_MASK, 0x00);
-   if (err < 0)
-   return err;
-
-   /* reset PM_CTRL3 before send buffer cmd */
-   return rtsx_pci_write_register(pcr, PM_CTRL3, D3_DELINK_MODE_EN, 0x00);
-}
diff --git a/drivers/mfd/rtsx_pcr.c b/drivers/mfd/rtsx_pcr.c
index 30f7ca8..717bfd7 100644
--- a/drivers/mfd/rtsx_pcr.c
+++ b/drivers/mfd/rtsx_pcr.c
@@ -63,6 +63,18 @@ static const struct pci_device_id rtsx_pci_ids[] = {
 
 MODULE_DEVICE_TABLE(pci, rtsx_pci_ids);
 
+static inline void rtsx_pci_enable_aspm(struct rtsx_pcr *pcr)
+{
+   rtsx_pci_update_cfg_byte(pcr, pcr->pcie_cap + PCI_EXP_LNKCTL,
+   0xFC, pcr->aspm_en);
+}
+
+static inline void rtsx_pci_disable_aspm(struct rtsx_pcr *pcr)
+{
+   rtsx_pci_update_cfg_byte(pcr, pcr->pcie_cap + PCI_EXP_LNKCTL,
+   0xFC, 0);
+}
+
 void rtsx_pci_start_run(struct rtsx_pcr *pcr)
 {
/* If pci device removed, don't queue idle work any more */
@@ -75,7 +87,8 @@ void rtsx_pci_start_run(struct rtsx_pcr *pcr)
pcr->ops->enable_auto_blink(pcr);
 
   

[PATCH v2 2/9] mfd: rtsx: place register address and values togather

2015-01-21 Thread micky_ching
From: Micky Ching 

It is more readable to place register address and values define
togather. The values define add two leading space indicate belong
to the register address defined above.

Signed-off-by: Micky Ching 
---
 include/linux/mfd/rtsx_pci.h | 836 +++
 1 file changed, 369 insertions(+), 467 deletions(-)

diff --git a/include/linux/mfd/rtsx_pci.h b/include/linux/mfd/rtsx_pci.h
index a9c2a14..e81f2bb 100644
--- a/include/linux/mfd/rtsx_pci.h
+++ b/include/linux/mfd/rtsx_pci.h
@@ -28,74 +28,72 @@
 
 #define MAX_RW_REG_CNT 1024
 
-/* PCI Operation Register Address */
 #define RTSX_HCBAR 0x00
 #define RTSX_HCBCTLR   0x04
+#define   STOP_CMD (0x01 << 28)
+#define   READ_REG_CMD 0
+#define   WRITE_REG_CMD1
+#define   CHECK_REG_CMD2
+
 #define RTSX_HDBAR 0x08
+#define   SG_INT   0x04
+#define   SG_END   0x02
+#define   SG_VALID 0x01
+#define   SG_NO_OP 0x00
+#define   SG_TRANS_DATA(0x02 << 4)
+#define   SG_LINK_DESC (0x03 << 4)
 #define RTSX_HDBCTLR   0x0C
+#define   SDMA_MODE0x00
+#define   ADMA_MODE(0x02 << 26)
+#define   STOP_DMA (0x01 << 28)
+#define   TRIG_DMA (0x01 << 31)
+
 #define RTSX_HAIMR 0x10
-#define RTSX_BIPR  0x14
-#define RTSX_BIER  0x18
+#define   HAIMR_TRANS_START(0x01 << 31)
+#define   HAIMR_READ   0x00
+#define   HAIMR_WRITE  (0x01 << 30)
+#define   HAIMR_READ_START (HAIMR_TRANS_START | HAIMR_READ)
+#define   HAIMR_WRITE_START(HAIMR_TRANS_START | HAIMR_WRITE)
+#define   HAIMR_TRANS_END  (HAIMR_TRANS_START)
 
-/* Host command buffer control register */
-#define STOP_CMD   (0x01 << 28)
-
-/* Host data buffer control register */
-#define SDMA_MODE  0x00
-#define ADMA_MODE  (0x02 << 26)
-#define STOP_DMA   (0x01 << 28)
-#define TRIG_DMA   (0x01 << 31)
-
-/* Host access internal memory register */
-#define HAIMR_TRANS_START  (0x01 << 31)
-#define HAIMR_READ 0x00
-#define HAIMR_WRITE(0x01 << 30)
-#define HAIMR_READ_START   (HAIMR_TRANS_START | HAIMR_READ)
-#define HAIMR_WRITE_START  (HAIMR_TRANS_START | HAIMR_WRITE)
-#define HAIMR_TRANS_END(HAIMR_TRANS_START)
-
-/* Bus interrupt pending register */
-#define CMD_DONE_INT   (1 << 31)
-#define DATA_DONE_INT  (1 << 30)
-#define TRANS_OK_INT   (1 << 29)
-#define TRANS_FAIL_INT (1 << 28)
-#define XD_INT (1 << 27)
-#define MS_INT (1 << 26)
-#define SD_INT (1 << 25)
-#define GPIO0_INT  (1 << 24)
-#define OC_INT (1 << 23)
-#define SD_WRITE_PROTECT   (1 << 19)
-#define XD_EXIST   (1 << 18)
-#define MS_EXIST   (1 << 17)
-#define SD_EXIST   (1 << 16)
-#define DELINK_INT GPIO0_INT
-#define MS_OC_INT  (1 << 23)
-#define SD_OC_INT  (1 << 22)
+#define RTSX_BIPR  0x14
+#define   CMD_DONE_INT (1 << 31)
+#define   DATA_DONE_INT(1 << 30)
+#define   TRANS_OK_INT (1 << 29)
+#define   TRANS_FAIL_INT   (1 << 28)
+#define   XD_INT   (1 << 27)
+#define   MS_INT   (1 << 26)
+#define   SD_INT   (1 << 25)
+#define   GPIO0_INT(1 << 24)
+#define   OC_INT   (1 << 23)
+#define   SD_WRITE_PROTECT (1 << 19)
+#define   XD_EXIST (1 << 18)
+#define   MS_EXIST (1 << 17)
+#define   SD_EXIST (1 << 16)
+#define   DELINK_INT   GPIO0_INT
+#define   MS_OC_INT(1 << 23)
+#define   SD_OC_INT(1 << 22)
 
 #define CARD_INT   (XD_INT | MS_INT | SD_INT)
 #define NEED_COMPLETE_INT  (DATA_DONE_INT | TRANS_OK_INT | TRANS_FAIL_INT)
 #define RTSX_INT   (CMD_DONE_INT | NEED_COMPLETE_INT | \
CARD_INT | GPIO0_INT | OC_INT)
-
 #define CARD_EXIST (XD_EXIST | MS_EXIST | SD_EXIST)
 
-/* Bus interrupt enable register */
-#define CMD_DONE_INT_EN(1 << 31)
-#define DATA_DONE_INT_EN   (1 << 30)
-#define TRANS_OK_INT_EN(1 << 29)
-#defi

[PATCH v2 0/9] mfd: rtsx: add support for new rts524A and rts525A

2015-01-21 Thread micky_ching
From: Micky Ching 

v2:
- remove debug info when access failed.
- using macro list for phy register init.
- rename function for multi chip prefix with rtsx_base_
- save pcie_cap offset when init chip, not calling pci_find_capacity()
  every time.
- add pcr->ops: write_phy/read_phy for special chip.

This patchset including re-format some coding-style and add two new chip
rts524A and rts525A.


Micky Ching (9):
  mfd: rtsx: replace TAB by SPC after #define
  mfd: rtsx: place register address and values togather
  mfd: rtsx: update PETXCFG address
  mfd: rtsx: update driving settings
  mfd: rtsx: update phy register
  mfd: rtsx: remove LCTLR defination
  mfd: rtsx: add support for rts524A
  mfd: rtsx: add support for rts525A
  mfd: rtsx: using pcr_dbg replace dev_dbg

 drivers/mfd/Makefile |2 +-
 drivers/mfd/rtl8411.c|   11 +-
 drivers/mfd/rts5209.c|4 +-
 drivers/mfd/rts5227.c|   12 +-
 drivers/mfd/rts5229.c|4 +-
 drivers/mfd/rts5249.c|  368 +++---
 drivers/mfd/rtsx_gops.c  |   37 --
 drivers/mfd/rtsx_pcr.c   |  110 +++--
 drivers/mfd/rtsx_pcr.h   |8 +
 include/linux/mfd/rtsx_pci.h | 1109 ++
 10 files changed, 966 insertions(+), 699 deletions(-)
 delete mode 100644 drivers/mfd/rtsx_gops.c

-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v2 4/9] mfd: rtsx: update driving settings

2015-01-21 Thread micky_ching
From: Micky Ching 

update card drive settings, This setting can be used for rts5249
rts524A and rts525A.

Signed-off-by: Micky Ching 
---
 drivers/mfd/rts5249.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/mfd/rts5249.c b/drivers/mfd/rts5249.c
index 225ad55..2fe2854 100644
--- a/drivers/mfd/rts5249.c
+++ b/drivers/mfd/rts5249.c
@@ -36,16 +36,16 @@ static u8 rts5249_get_ic_version(struct rtsx_pcr *pcr)
 static void rts5249_fill_driving(struct rtsx_pcr *pcr, u8 voltage)
 {
u8 driving_3v3[4][3] = {
-   {0x11, 0x11, 0x11},
+   {0x11, 0x11, 0x18},
{0x55, 0x55, 0x5C},
-   {0x99, 0x99, 0x92},
-   {0x99, 0x99, 0x92},
+   {0xFF, 0xFF, 0xFF},
+   {0x96, 0x96, 0x96},
};
u8 driving_1v8[4][3] = {
+   {0xC4, 0xC4, 0xC4},
{0x3C, 0x3C, 0x3C},
-   {0xB3, 0xB3, 0xB3},
{0xFE, 0xFE, 0xFE},
-   {0xC4, 0xC4, 0xC4},
+   {0xB3, 0xB3, 0xB3},
};
u8 (*driving)[3], drive_sel;
 
@@ -341,7 +341,7 @@ void rts5249_init_params(struct rtsx_pcr *pcr)
 
pcr->flags = 0;
pcr->card_drive_sel = RTSX_CARD_DRIVE_DEFAULT;
-   pcr->sd30_drive_sel_1v8 = CFG_DRIVER_TYPE_C;
+   pcr->sd30_drive_sel_1v8 = CFG_DRIVER_TYPE_B;
pcr->sd30_drive_sel_3v3 = CFG_DRIVER_TYPE_B;
pcr->aspm_en = ASPM_L1_EN;
pcr->tx_initial_phase = SET_CLOCK_PHASE(1, 29, 16);
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v2 7/9] mfd: rtsx: add support for rts524A

2015-01-21 Thread micky_ching
From: Micky Ching 

add support for new chip rts524A.

Signed-off-by: Micky Ching 
---
 drivers/mfd/rts5249.c| 186 ---
 drivers/mfd/rtsx_pcr.c   |  25 +-
 drivers/mfd/rtsx_pcr.h   |   7 ++
 include/linux/mfd/rtsx_pci.h | 125 -
 4 files changed, 310 insertions(+), 33 deletions(-)

diff --git a/drivers/mfd/rts5249.c b/drivers/mfd/rts5249.c
index 3977946..97dde92 100644
--- a/drivers/mfd/rts5249.c
+++ b/drivers/mfd/rts5249.c
@@ -65,15 +65,17 @@ static void rts5249_fill_driving(struct rtsx_pcr *pcr, u8 
voltage)
0xFF, driving[drive_sel][2]);
 }
 
-static void rts5249_fetch_vendor_settings(struct rtsx_pcr *pcr)
+static void rtsx_base_fetch_vendor_settings(struct rtsx_pcr *pcr)
 {
u32 reg;
 
rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG1, ®);
dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
 
-   if (!rtsx_vendor_setting_valid(reg))
+   if (!rtsx_vendor_setting_valid(reg)) {
+   pcr_dbg(pcr, "skip fetch vendor setting\n");
return;
+   }
 
pcr->aspm_en = rtsx_reg_to_aspm(reg);
pcr->sd30_drive_sel_1v8 = rtsx_reg_to_sd30_drive_sel_1v8(reg);
@@ -87,15 +89,21 @@ static void rts5249_fetch_vendor_settings(struct rtsx_pcr 
*pcr)
pcr->flags |= PCR_REVERSE_SOCKET;
 }
 
-static void rts5249_force_power_down(struct rtsx_pcr *pcr, u8 pm_state)
+static void rtsx_base_force_power_down(struct rtsx_pcr *pcr, u8 pm_state)
 {
/* Set relink_time to 0 */
rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 1, 0xFF, 0);
rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 2, 0xFF, 0);
rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 3, 0x01, 0);
 
-   if (pm_state == HOST_ENTER_S3)
-   rtsx_pci_write_register(pcr, PM_CTRL3, 0x10, 0x10);
+   if (pm_state == HOST_ENTER_S3) {
+   if (PCI_PID(pcr) == 0x524A)
+   rtsx_pci_write_register(pcr, RTS524A_PM_CTRL3,
+   D3_DELINK_MODE_EN, D3_DELINK_MODE_EN);
+   else if (PCI_PID(pcr) == 0x5249)
+   rtsx_pci_write_register(pcr, PM_CTRL3,
+   D3_DELINK_MODE_EN, D3_DELINK_MODE_EN);
+   }
 
rtsx_pci_write_register(pcr, FPDCTL, 0x03, 0x03);
 }
@@ -104,6 +112,8 @@ static int rts5249_extra_init_hw(struct rtsx_pcr *pcr)
 {
rtsx_pci_init_cmd(pcr);
 
+   /* Rest L1SUB Config */
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, L1SUB_CONFIG3, 0xFF, 0x00);
/* Configure GPIO as output */
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, GPIO_CTL, 0x02, 0x02);
/* Reset ASPM state to default value */
@@ -189,27 +199,27 @@ static int rts5249_optimize_phy(struct rtsx_pcr *pcr)
PHY_TUNE_TUNED12 | PHY_TUNE_TUNEA12);
 }
 
-static int rts5249_turn_on_led(struct rtsx_pcr *pcr)
+static int rtsx_base_turn_on_led(struct rtsx_pcr *pcr)
 {
return rtsx_pci_write_register(pcr, GPIO_CTL, 0x02, 0x02);
 }
 
-static int rts5249_turn_off_led(struct rtsx_pcr *pcr)
+static int rtsx_base_turn_off_led(struct rtsx_pcr *pcr)
 {
return rtsx_pci_write_register(pcr, GPIO_CTL, 0x02, 0x00);
 }
 
-static int rts5249_enable_auto_blink(struct rtsx_pcr *pcr)
+static int rtsx_base_enable_auto_blink(struct rtsx_pcr *pcr)
 {
return rtsx_pci_write_register(pcr, OLT_LED_CTL, 0x08, 0x08);
 }
 
-static int rts5249_disable_auto_blink(struct rtsx_pcr *pcr)
+static int rtsx_base_disable_auto_blink(struct rtsx_pcr *pcr)
 {
return rtsx_pci_write_register(pcr, OLT_LED_CTL, 0x08, 0x00);
 }
 
-static int rts5249_card_power_on(struct rtsx_pcr *pcr, int card)
+static int rtsx_base_card_power_on(struct rtsx_pcr *pcr, int card)
 {
int err;
 
@@ -236,7 +246,7 @@ static int rts5249_card_power_on(struct rtsx_pcr *pcr, int 
card)
return 0;
 }
 
-static int rts5249_card_power_off(struct rtsx_pcr *pcr, int card)
+static int rtsx_base_card_power_off(struct rtsx_pcr *pcr, int card)
 {
rtsx_pci_init_cmd(pcr);
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
@@ -246,22 +256,31 @@ static int rts5249_card_power_off(struct rtsx_pcr *pcr, 
int card)
return rtsx_pci_send_cmd(pcr, 100);
 }
 
-static int rts5249_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
+static int rtsx_base_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
 {
int err;
+   u16 append;
 
-   if (voltage == OUTPUT_3V3) {
-   err = rtsx_pci_write_phy_register(pcr, PHY_TUNE, 0x4FC0 | 0x24);
-   if (err < 0)
-   return err;
-   } else if (voltage == OUTPUT_1V8) {
-   err = rtsx_pci_write_phy_register(pcr, PHY_BACR, 0x3C02);
+   switch (voltage) {
+   case OUTPUT_3V3:
+   err = rtsx_pci_update_phy(pcr, PHY_TUNE, 0xFC3F, 0x03C0);
if (err < 0)
return err;
- 

[PATCH v2 9/9] mfd: rtsx: using pcr_dbg replace dev_dbg

2015-01-21 Thread micky_ching
From: Micky Ching 

pcr_dbg is a wrapper of dev_dbg, which can save some code,
and help to enable/disable debug message static.

Signed-off-by: Micky Ching 
---
 drivers/mfd/rtl8411.c  | 11 +--
 drivers/mfd/rts5209.c  |  4 ++--
 drivers/mfd/rts5227.c  |  4 ++--
 drivers/mfd/rts5229.c  |  4 ++--
 drivers/mfd/rts5249.c  |  4 ++--
 drivers/mfd/rtsx_pcr.c | 49 ++---
 6 files changed, 35 insertions(+), 41 deletions(-)

diff --git a/drivers/mfd/rtl8411.c b/drivers/mfd/rtl8411.c
index fdd34c8..b3ae659 100644
--- a/drivers/mfd/rtl8411.c
+++ b/drivers/mfd/rtl8411.c
@@ -53,7 +53,7 @@ static void rtl8411_fetch_vendor_settings(struct rtsx_pcr 
*pcr)
u8 reg3 = 0;
 
rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG1, ®1);
-   dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg1);
+   pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg1);
 
if (!rtsx_vendor_setting_valid(reg1))
return;
@@ -65,7 +65,7 @@ static void rtl8411_fetch_vendor_settings(struct rtsx_pcr 
*pcr)
pcr->card_drive_sel |= rtsx_reg_to_card_drive_sel(reg1);
 
rtsx_pci_read_config_byte(pcr, PCR_SETTING_REG3, ®3);
-   dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG3, reg3);
+   pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG3, reg3);
pcr->sd30_drive_sel_3v3 = rtl8411_reg_to_sd30_drive_sel_3v3(reg3);
 }
 
@@ -74,7 +74,7 @@ static void rtl8411b_fetch_vendor_settings(struct rtsx_pcr 
*pcr)
u32 reg = 0;
 
rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG1, ®);
-   dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
+   pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
 
if (!rtsx_vendor_setting_valid(reg))
return;
@@ -260,9 +260,8 @@ static unsigned int rtl8411_cd_deglitch(struct rtsx_pcr 
*pcr)
rtsx_pci_write_register(pcr, CARD_PWR_CTL,
BPP_POWER_MASK, BPP_POWER_OFF);
 
-   dev_dbg(&(pcr->pci->dev),
-   "After CD deglitch, card_exist = 0x%x\n",
-   card_exist);
+   pcr_dbg(pcr, "After CD deglitch, card_exist = 0x%x\n",
+   card_exist);
}
 
if (card_exist & MS_EXIST) {
diff --git a/drivers/mfd/rts5209.c b/drivers/mfd/rts5209.c
index cb04174..373e253 100644
--- a/drivers/mfd/rts5209.c
+++ b/drivers/mfd/rts5209.c
@@ -38,7 +38,7 @@ static void rts5209_fetch_vendor_settings(struct rtsx_pcr 
*pcr)
u32 reg;
 
rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG1, ®);
-   dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
+   pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
 
if (rts5209_vendor_setting1_valid(reg)) {
if (rts5209_reg_check_ms_pmos(reg))
@@ -47,7 +47,7 @@ static void rts5209_fetch_vendor_settings(struct rtsx_pcr 
*pcr)
}
 
rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG2, ®);
-   dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG2, reg);
+   pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG2, reg);
 
if (rts5209_vendor_setting2_valid(reg)) {
pcr->sd30_drive_sel_1v8 =
diff --git a/drivers/mfd/rts5227.c b/drivers/mfd/rts5227.c
index 0c02831..ce012d7 100644
--- a/drivers/mfd/rts5227.c
+++ b/drivers/mfd/rts5227.c
@@ -63,7 +63,7 @@ static void rts5227_fetch_vendor_settings(struct rtsx_pcr 
*pcr)
u32 reg;
 
rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG1, ®);
-   dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
+   pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
 
if (!rtsx_vendor_setting_valid(reg))
return;
@@ -74,7 +74,7 @@ static void rts5227_fetch_vendor_settings(struct rtsx_pcr 
*pcr)
pcr->card_drive_sel |= rtsx_reg_to_card_drive_sel(reg);
 
rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG2, ®);
-   dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG2, reg);
+   pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG2, reg);
pcr->sd30_drive_sel_3v3 = rtsx_reg_to_sd30_drive_sel_3v3(reg);
if (rtsx_reg_check_reverse_socket(reg))
pcr->flags |= PCR_REVERSE_SOCKET;
diff --git a/drivers/mfd/rts5229.c b/drivers/mfd/rts5229.c
index 6353f5d..ace4538 100644
--- a/drivers/mfd/rts5229.c
+++ b/drivers/mfd/rts5229.c
@@ -38,7 +38,7 @@ static void rts5229_fetch_vendor_settings(struct rtsx_pcr 
*pcr)
u32 reg;
 
rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG1, ®);
-   dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
+   pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
 
if (!rtsx_vendor_setting_valid(reg))
return;
@@ -50,7 +50,7 @@ static void rts5229_fetch_vendor_settings(struct rtsx_pcr 
*pcr)
pcr->card_drive_sel |= rtsx_reg_to_card_dr

[RESEND PATCH v2 5/9] mfd: rtsx: update phy register

2015-01-21 Thread micky_ching
From: Micky Ching 

update phy register value and using direct value instead of macros.
It is much easier to debug using constant value than a lot of macros.
We usually need compare the value directly to check the configure.

Signed-off-by: Micky Ching 
---
 drivers/mfd/rts5249.c|  55 --
 include/linux/mfd/rtsx_pci.h | 109 ++-
 2 files changed, 85 insertions(+), 79 deletions(-)

diff --git a/drivers/mfd/rts5249.c b/drivers/mfd/rts5249.c
index 2fe2854..d8072f6 100644
--- a/drivers/mfd/rts5249.c
+++ b/drivers/mfd/rts5249.c
@@ -132,57 +132,62 @@ static int rts5249_optimize_phy(struct rtsx_pcr *pcr)
if (err < 0)
return err;
 
-   err = rtsx_pci_write_phy_register(pcr, PHY_REG_REV,
-   PHY_REG_REV_RESV | PHY_REG_REV_RXIDLE_LATCHED |
-   PHY_REG_REV_P1_EN | PHY_REG_REV_RXIDLE_EN |
-   PHY_REG_REV_RX_PWST | PHY_REG_REV_CLKREQ_DLY_TIMER_1_0 |
-   PHY_REG_REV_STOP_CLKRD | PHY_REG_REV_STOP_CLKWR);
+   err = rtsx_pci_write_phy_register(pcr, PHY_REV,
+   PHY_REV_RESV | PHY_REV_RXIDLE_LATCHED |
+   PHY_REV_P1_EN | PHY_REV_RXIDLE_EN |
+   PHY_REV_CLKREQ_TX_EN | PHY_REV_RX_PWST |
+   PHY_REV_CLKREQ_DT_1_0 | PHY_REV_STOP_CLKRD |
+   PHY_REV_STOP_CLKWR);
if (err < 0)
return err;
 
msleep(1);
 
err = rtsx_pci_write_phy_register(pcr, PHY_BPCR,
-   PHY_BPCR_IBRXSEL | PHY_BPCR_IBTXSEL |
-   PHY_BPCR_IB_FILTER | PHY_BPCR_CMIRROR_EN);
+   PHY_BPCR_IBRXSEL | PHY_BPCR_IBTXSEL |
+   PHY_BPCR_IB_FILTER | PHY_BPCR_CMIRROR_EN);
if (err < 0)
return err;
+
err = rtsx_pci_write_phy_register(pcr, PHY_PCR,
-   PHY_PCR_FORCE_CODE | PHY_PCR_OOBS_CALI_50 |
-   PHY_PCR_OOBS_VCM_08 | PHY_PCR_OOBS_SEN_90 |
-   PHY_PCR_RSSI_EN);
+   PHY_PCR_FORCE_CODE | PHY_PCR_OOBS_CALI_50 |
+   PHY_PCR_OOBS_VCM_08 | PHY_PCR_OOBS_SEN_90 |
+   PHY_PCR_RSSI_EN | PHY_PCR_RX10K);
if (err < 0)
return err;
+
err = rtsx_pci_write_phy_register(pcr, PHY_RCR2,
-   PHY_RCR2_EMPHASE_EN | PHY_RCR2_NADJR |
-   PHY_RCR2_CDR_CP_10 | PHY_RCR2_CDR_SR_2 |
-   PHY_RCR2_FREQSEL_12 | PHY_RCR2_CPADJEN |
-   PHY_RCR2_CDR_SC_8 | PHY_RCR2_CALIB_LATE);
+   PHY_RCR2_EMPHASE_EN | PHY_RCR2_NADJR |
+   PHY_RCR2_CDR_SR_2 | PHY_RCR2_FREQSEL_12 |
+   PHY_RCR2_CDR_SC_12P | PHY_RCR2_CALIB_LATE);
if (err < 0)
return err;
+
err = rtsx_pci_write_phy_register(pcr, PHY_FLD4,
-   PHY_FLD4_FLDEN_SEL | PHY_FLD4_REQ_REF |
-   PHY_FLD4_RXAMP_OFF | PHY_FLD4_REQ_ADDA |
-   PHY_FLD4_BER_COUNT | PHY_FLD4_BER_TIMER |
-   PHY_FLD4_BER_CHK_EN);
+   PHY_FLD4_FLDEN_SEL | PHY_FLD4_REQ_REF |
+   PHY_FLD4_RXAMP_OFF | PHY_FLD4_REQ_ADDA |
+   PHY_FLD4_BER_COUNT | PHY_FLD4_BER_TIMER |
+   PHY_FLD4_BER_CHK_EN);
if (err < 0)
return err;
-   err = rtsx_pci_write_phy_register(pcr, PHY_RDR, PHY_RDR_RXDSEL_1_9);
+   err = rtsx_pci_write_phy_register(pcr, PHY_RDR,
+   PHY_RDR_RXDSEL_1_9 | PHY_SSC_AUTO_PWD);
if (err < 0)
return err;
err = rtsx_pci_write_phy_register(pcr, PHY_RCR1,
-   PHY_RCR1_ADP_TIME | PHY_RCR1_VCO_COARSE);
+   PHY_RCR1_ADP_TIME_4 | PHY_RCR1_VCO_COARSE);
if (err < 0)
return err;
err = rtsx_pci_write_phy_register(pcr, PHY_FLD3,
-   PHY_FLD3_TIMER_4 | PHY_FLD3_TIMER_6 |
-   PHY_FLD3_RXDELINK);
+   PHY_FLD3_TIMER_4 | PHY_FLD3_TIMER_6 |
+   PHY_FLD3_RXDELINK);
if (err < 0)
return err;
+
return rtsx_pci_write_phy_register(pcr, PHY_TUNE,
-   PHY_TUNE_TUNEREF_1_0 | PHY_TUNE_VBGSEL_1252 |
-   PHY_TUNE_SDBUS_33 | PHY_TUNE_TUNED18 |
-   PHY_TUNE_TUNED12);
+   PHY_TUNE_TUNEREF_1_0 | PHY_TUNE_VBGSEL_1252 |
+   PHY_TUNE_SDBUS_33 | PHY_TUNE_TUNED18 |
+   PHY_TUNE_TUNED12 | PHY_TUNE_TUNEA12);
 }
 
 static int rts5249_turn_on_led(struct rtsx_pcr *pcr)
diff --git a/include/linux/mfd/rtsx_pci.h b/include/linux/mfd/rtsx_pci.h
index 87cff60..0103210 100644
--- a/include/linux/mfd/rtsx_pci.h
+++ b/include/linux/mfd/rtsx_pci.h
@@ -630,16 +630,47 @@
 
 /* Phy register */
 #define PHY_PCR0x00
+#define   PHY_PCR_FORCE_CODE   0xB000
+#define   PHY_PCR_OOBS_CALI_50 0x0800
+#define   PHY_PCR_OOBS_VCM_

[RESEND PATCH v2 0/9] mfd: rtsx: add support for new rts524A and rts525A

2015-01-21 Thread micky_ching
From: Micky Ching 

resend:
- add lee jones ack for some patch.
v2:
- remove debug info when access failed.
- using macro list for phy register init.
- rename function for multi chip prefix with rtsx_base_
- save pcie_cap offset when init chip, not calling pci_find_capacity()
  every time.
- add pcr->ops: write_phy/read_phy for special chip.

This patchset including re-format some coding-style and add two new chip
rts524A and rts525A.


Micky Ching (9):
  mfd: rtsx: replace TAB by SPC after #define
  mfd: rtsx: place register address and values togather
  mfd: rtsx: update PETXCFG address
  mfd: rtsx: update driving settings
  mfd: rtsx: update phy register
  mfd: rtsx: remove LCTLR defination
  mfd: rtsx: add support for rts524A
  mfd: rtsx: add support for rts525A
  mfd: rtsx: using pcr_dbg replace dev_dbg

 drivers/mfd/Makefile |2 +-
 drivers/mfd/rtl8411.c|   11 +-
 drivers/mfd/rts5209.c|4 +-
 drivers/mfd/rts5227.c|   12 +-
 drivers/mfd/rts5229.c|4 +-
 drivers/mfd/rts5249.c|  368 +++---
 drivers/mfd/rtsx_gops.c  |   37 --
 drivers/mfd/rtsx_pcr.c   |  109 +++--
 drivers/mfd/rtsx_pcr.h   |8 +
 include/linux/mfd/rtsx_pci.h | 1109 ++
 10 files changed, 965 insertions(+), 699 deletions(-)
 delete mode 100644 drivers/mfd/rtsx_gops.c

-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[RESEND PATCH v2 4/9] mfd: rtsx: update driving settings

2015-01-21 Thread micky_ching
From: Micky Ching 

update card drive settings, This setting can be used for rts5249
rts524A and rts525A.

Signed-off-by: Micky Ching 
Acked-by: Lee Jones 
---
 drivers/mfd/rts5249.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/mfd/rts5249.c b/drivers/mfd/rts5249.c
index 225ad55..2fe2854 100644
--- a/drivers/mfd/rts5249.c
+++ b/drivers/mfd/rts5249.c
@@ -36,16 +36,16 @@ static u8 rts5249_get_ic_version(struct rtsx_pcr *pcr)
 static void rts5249_fill_driving(struct rtsx_pcr *pcr, u8 voltage)
 {
u8 driving_3v3[4][3] = {
-   {0x11, 0x11, 0x11},
+   {0x11, 0x11, 0x18},
{0x55, 0x55, 0x5C},
-   {0x99, 0x99, 0x92},
-   {0x99, 0x99, 0x92},
+   {0xFF, 0xFF, 0xFF},
+   {0x96, 0x96, 0x96},
};
u8 driving_1v8[4][3] = {
+   {0xC4, 0xC4, 0xC4},
{0x3C, 0x3C, 0x3C},
-   {0xB3, 0xB3, 0xB3},
{0xFE, 0xFE, 0xFE},
-   {0xC4, 0xC4, 0xC4},
+   {0xB3, 0xB3, 0xB3},
};
u8 (*driving)[3], drive_sel;
 
@@ -341,7 +341,7 @@ void rts5249_init_params(struct rtsx_pcr *pcr)
 
pcr->flags = 0;
pcr->card_drive_sel = RTSX_CARD_DRIVE_DEFAULT;
-   pcr->sd30_drive_sel_1v8 = CFG_DRIVER_TYPE_C;
+   pcr->sd30_drive_sel_1v8 = CFG_DRIVER_TYPE_B;
pcr->sd30_drive_sel_3v3 = CFG_DRIVER_TYPE_B;
pcr->aspm_en = ASPM_L1_EN;
pcr->tx_initial_phase = SET_CLOCK_PHASE(1, 29, 16);
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[RESEND PATCH v2 9/9] mfd: rtsx: using pcr_dbg replace dev_dbg

2015-01-21 Thread micky_ching
From: Micky Ching 

pcr_dbg is a wrapper of dev_dbg, which can save some code,
and help to enable/disable debug message static.

Signed-off-by: Micky Ching 
Acked-by: Lee Jones 
---
 drivers/mfd/rtl8411.c  | 11 +--
 drivers/mfd/rts5209.c  |  4 ++--
 drivers/mfd/rts5227.c  |  4 ++--
 drivers/mfd/rts5229.c  |  4 ++--
 drivers/mfd/rts5249.c  |  4 ++--
 drivers/mfd/rtsx_pcr.c | 49 ++---
 6 files changed, 35 insertions(+), 41 deletions(-)

diff --git a/drivers/mfd/rtl8411.c b/drivers/mfd/rtl8411.c
index fdd34c8..b3ae659 100644
--- a/drivers/mfd/rtl8411.c
+++ b/drivers/mfd/rtl8411.c
@@ -53,7 +53,7 @@ static void rtl8411_fetch_vendor_settings(struct rtsx_pcr 
*pcr)
u8 reg3 = 0;
 
rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG1, ®1);
-   dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg1);
+   pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg1);
 
if (!rtsx_vendor_setting_valid(reg1))
return;
@@ -65,7 +65,7 @@ static void rtl8411_fetch_vendor_settings(struct rtsx_pcr 
*pcr)
pcr->card_drive_sel |= rtsx_reg_to_card_drive_sel(reg1);
 
rtsx_pci_read_config_byte(pcr, PCR_SETTING_REG3, ®3);
-   dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG3, reg3);
+   pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG3, reg3);
pcr->sd30_drive_sel_3v3 = rtl8411_reg_to_sd30_drive_sel_3v3(reg3);
 }
 
@@ -74,7 +74,7 @@ static void rtl8411b_fetch_vendor_settings(struct rtsx_pcr 
*pcr)
u32 reg = 0;
 
rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG1, ®);
-   dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
+   pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
 
if (!rtsx_vendor_setting_valid(reg))
return;
@@ -260,9 +260,8 @@ static unsigned int rtl8411_cd_deglitch(struct rtsx_pcr 
*pcr)
rtsx_pci_write_register(pcr, CARD_PWR_CTL,
BPP_POWER_MASK, BPP_POWER_OFF);
 
-   dev_dbg(&(pcr->pci->dev),
-   "After CD deglitch, card_exist = 0x%x\n",
-   card_exist);
+   pcr_dbg(pcr, "After CD deglitch, card_exist = 0x%x\n",
+   card_exist);
}
 
if (card_exist & MS_EXIST) {
diff --git a/drivers/mfd/rts5209.c b/drivers/mfd/rts5209.c
index cb04174..373e253 100644
--- a/drivers/mfd/rts5209.c
+++ b/drivers/mfd/rts5209.c
@@ -38,7 +38,7 @@ static void rts5209_fetch_vendor_settings(struct rtsx_pcr 
*pcr)
u32 reg;
 
rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG1, ®);
-   dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
+   pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
 
if (rts5209_vendor_setting1_valid(reg)) {
if (rts5209_reg_check_ms_pmos(reg))
@@ -47,7 +47,7 @@ static void rts5209_fetch_vendor_settings(struct rtsx_pcr 
*pcr)
}
 
rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG2, ®);
-   dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG2, reg);
+   pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG2, reg);
 
if (rts5209_vendor_setting2_valid(reg)) {
pcr->sd30_drive_sel_1v8 =
diff --git a/drivers/mfd/rts5227.c b/drivers/mfd/rts5227.c
index 0c02831..ce012d7 100644
--- a/drivers/mfd/rts5227.c
+++ b/drivers/mfd/rts5227.c
@@ -63,7 +63,7 @@ static void rts5227_fetch_vendor_settings(struct rtsx_pcr 
*pcr)
u32 reg;
 
rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG1, ®);
-   dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
+   pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
 
if (!rtsx_vendor_setting_valid(reg))
return;
@@ -74,7 +74,7 @@ static void rts5227_fetch_vendor_settings(struct rtsx_pcr 
*pcr)
pcr->card_drive_sel |= rtsx_reg_to_card_drive_sel(reg);
 
rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG2, ®);
-   dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG2, reg);
+   pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG2, reg);
pcr->sd30_drive_sel_3v3 = rtsx_reg_to_sd30_drive_sel_3v3(reg);
if (rtsx_reg_check_reverse_socket(reg))
pcr->flags |= PCR_REVERSE_SOCKET;
diff --git a/drivers/mfd/rts5229.c b/drivers/mfd/rts5229.c
index 6353f5d..ace4538 100644
--- a/drivers/mfd/rts5229.c
+++ b/drivers/mfd/rts5229.c
@@ -38,7 +38,7 @@ static void rts5229_fetch_vendor_settings(struct rtsx_pcr 
*pcr)
u32 reg;
 
rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG1, ®);
-   dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
+   pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
 
if (!rtsx_vendor_setting_valid(reg))
return;
@@ -50,7 +50,7 @@ static void rts5229_fetch_vendor_settings(struct rtsx_pcr 
*pcr)
pcr->card_drive_sel |

[RESEND PATCH v2 2/9] mfd: rtsx: place register address and values togather

2015-01-21 Thread micky_ching
From: Micky Ching 

It is more readable to place register address and values define
togather. The values define add two leading space indicate belong
to the register address defined above.

Signed-off-by: Micky Ching 
Acked-by: Lee Jones 
---
 include/linux/mfd/rtsx_pci.h | 836 +++
 1 file changed, 369 insertions(+), 467 deletions(-)

diff --git a/include/linux/mfd/rtsx_pci.h b/include/linux/mfd/rtsx_pci.h
index a9c2a14..e81f2bb 100644
--- a/include/linux/mfd/rtsx_pci.h
+++ b/include/linux/mfd/rtsx_pci.h
@@ -28,74 +28,72 @@
 
 #define MAX_RW_REG_CNT 1024
 
-/* PCI Operation Register Address */
 #define RTSX_HCBAR 0x00
 #define RTSX_HCBCTLR   0x04
+#define   STOP_CMD (0x01 << 28)
+#define   READ_REG_CMD 0
+#define   WRITE_REG_CMD1
+#define   CHECK_REG_CMD2
+
 #define RTSX_HDBAR 0x08
+#define   SG_INT   0x04
+#define   SG_END   0x02
+#define   SG_VALID 0x01
+#define   SG_NO_OP 0x00
+#define   SG_TRANS_DATA(0x02 << 4)
+#define   SG_LINK_DESC (0x03 << 4)
 #define RTSX_HDBCTLR   0x0C
+#define   SDMA_MODE0x00
+#define   ADMA_MODE(0x02 << 26)
+#define   STOP_DMA (0x01 << 28)
+#define   TRIG_DMA (0x01 << 31)
+
 #define RTSX_HAIMR 0x10
-#define RTSX_BIPR  0x14
-#define RTSX_BIER  0x18
+#define   HAIMR_TRANS_START(0x01 << 31)
+#define   HAIMR_READ   0x00
+#define   HAIMR_WRITE  (0x01 << 30)
+#define   HAIMR_READ_START (HAIMR_TRANS_START | HAIMR_READ)
+#define   HAIMR_WRITE_START(HAIMR_TRANS_START | HAIMR_WRITE)
+#define   HAIMR_TRANS_END  (HAIMR_TRANS_START)
 
-/* Host command buffer control register */
-#define STOP_CMD   (0x01 << 28)
-
-/* Host data buffer control register */
-#define SDMA_MODE  0x00
-#define ADMA_MODE  (0x02 << 26)
-#define STOP_DMA   (0x01 << 28)
-#define TRIG_DMA   (0x01 << 31)
-
-/* Host access internal memory register */
-#define HAIMR_TRANS_START  (0x01 << 31)
-#define HAIMR_READ 0x00
-#define HAIMR_WRITE(0x01 << 30)
-#define HAIMR_READ_START   (HAIMR_TRANS_START | HAIMR_READ)
-#define HAIMR_WRITE_START  (HAIMR_TRANS_START | HAIMR_WRITE)
-#define HAIMR_TRANS_END(HAIMR_TRANS_START)
-
-/* Bus interrupt pending register */
-#define CMD_DONE_INT   (1 << 31)
-#define DATA_DONE_INT  (1 << 30)
-#define TRANS_OK_INT   (1 << 29)
-#define TRANS_FAIL_INT (1 << 28)
-#define XD_INT (1 << 27)
-#define MS_INT (1 << 26)
-#define SD_INT (1 << 25)
-#define GPIO0_INT  (1 << 24)
-#define OC_INT (1 << 23)
-#define SD_WRITE_PROTECT   (1 << 19)
-#define XD_EXIST   (1 << 18)
-#define MS_EXIST   (1 << 17)
-#define SD_EXIST   (1 << 16)
-#define DELINK_INT GPIO0_INT
-#define MS_OC_INT  (1 << 23)
-#define SD_OC_INT  (1 << 22)
+#define RTSX_BIPR  0x14
+#define   CMD_DONE_INT (1 << 31)
+#define   DATA_DONE_INT(1 << 30)
+#define   TRANS_OK_INT (1 << 29)
+#define   TRANS_FAIL_INT   (1 << 28)
+#define   XD_INT   (1 << 27)
+#define   MS_INT   (1 << 26)
+#define   SD_INT   (1 << 25)
+#define   GPIO0_INT(1 << 24)
+#define   OC_INT   (1 << 23)
+#define   SD_WRITE_PROTECT (1 << 19)
+#define   XD_EXIST (1 << 18)
+#define   MS_EXIST (1 << 17)
+#define   SD_EXIST (1 << 16)
+#define   DELINK_INT   GPIO0_INT
+#define   MS_OC_INT(1 << 23)
+#define   SD_OC_INT(1 << 22)
 
 #define CARD_INT   (XD_INT | MS_INT | SD_INT)
 #define NEED_COMPLETE_INT  (DATA_DONE_INT | TRANS_OK_INT | TRANS_FAIL_INT)
 #define RTSX_INT   (CMD_DONE_INT | NEED_COMPLETE_INT | \
CARD_INT | GPIO0_INT | OC_INT)
-
 #define CARD_EXIST (XD_EXIST | MS_EXIST | SD_EXIST)
 
-/* Bus interrupt enable register */
-#define CMD_DONE_INT_EN(1 << 31)
-#define DATA_DONE_INT_EN   (1 << 30)
-#define TRANS_OK_INT_EN   

[RESEND PATCH v2 1/9] mfd: rtsx: replace TAB by SPC after #define

2015-01-21 Thread micky_ching
From: Micky Ching 

Re-format coding-style, using uniform SPC after "#define" keyword
instead of mixing using TAB and SPC.

Signed-off-by: Micky Ching 
Acked-by: Lee Jones 
---
 include/linux/mfd/rtsx_pci.h | 254 +--
 1 file changed, 127 insertions(+), 127 deletions(-)

diff --git a/include/linux/mfd/rtsx_pci.h b/include/linux/mfd/rtsx_pci.h
index 0c12628..a9c2a14 100644
--- a/include/linux/mfd/rtsx_pci.h
+++ b/include/linux/mfd/rtsx_pci.h
@@ -175,9 +175,9 @@
 /* CARD_SHARE_MODE */
 #define CARD_SHARE_MASK0x0F
 #define CARD_SHARE_MULTI_LUN   0x00
-#defineCARD_SHARE_NORMAL   0x00
-#defineCARD_SHARE_48_SD0x04
-#defineCARD_SHARE_48_MS0x08
+#define CARD_SHARE_NORMAL  0x00
+#define CARD_SHARE_48_SD   0x04
+#define CARD_SHARE_48_MS   0x08
 /* CARD_SHARE_MODE for barossa */
 #define CARD_SHARE_BAROSSA_SD  0x01
 #define CARD_SHARE_BAROSSA_MS  0x02
@@ -249,76 +249,76 @@
 #define CD_AUTO_DISABLE0x40
 
 /* SD_STAT1 */
-#defineSD_CRC7_ERR 0x80
-#defineSD_CRC16_ERR0x40
-#defineSD_CRC_WRITE_ERR0x20
-#defineSD_CRC_WRITE_ERR_MASK   0x1C
-#defineGET_CRC_TIME_OUT0x02
-#defineSD_TUNING_COMPARE_ERR   0x01
+#define SD_CRC7_ERR0x80
+#define SD_CRC16_ERR   0x40
+#define SD_CRC_WRITE_ERR   0x20
+#define SD_CRC_WRITE_ERR_MASK  0x1C
+#define GET_CRC_TIME_OUT   0x02
+#define SD_TUNING_COMPARE_ERR  0x01
 
 /* SD_STAT2 */
-#defineSD_RSP_80CLK_TIMEOUT0x01
+#define SD_RSP_80CLK_TIMEOUT   0x01
 
 /* SD_BUS_STAT */
-#defineSD_CLK_TOGGLE_EN0x80
-#defineSD_CLK_FORCE_STOP   0x40
-#defineSD_DAT3_STATUS  0x10
-#defineSD_DAT2_STATUS  0x08
-#defineSD_DAT1_STATUS  0x04
-#defineSD_DAT0_STATUS  0x02
-#defineSD_CMD_STATUS   0x01
+#define SD_CLK_TOGGLE_EN   0x80
+#define SD_CLK_FORCE_STOP  0x40
+#define SD_DAT3_STATUS 0x10
+#define SD_DAT2_STATUS 0x08
+#define SD_DAT1_STATUS 0x04
+#define SD_DAT0_STATUS 0x02
+#define SD_CMD_STATUS  0x01
 
 /* SD_PAD_CTL */
-#defineSD_IO_USING_1V8 0x80
-#defineSD_IO_USING_3V3 0x7F
-#defineTYPE_A_DRIVING  0x00
-#defineTYPE_B_DRIVING  0x01
-#defineTYPE_C_DRIVING  0x02
-#defineTYPE_D_DRIVING  0x03
+#define SD_IO_USING_1V80x80
+#define SD_IO_USING_3V30x7F
+#define TYPE_A_DRIVING 0x00
+#define TYPE_B_DRIVING 0x01
+#define TYPE_C_DRIVING 0x02
+#define TYPE_D_DRIVING 0x03
 
 /* SD_SAMPLE_POINT_CTL */
-#defineDDR_FIX_RX_DAT  0x00
-#defineDDR_VAR_RX_DAT  0x80
-#defineDDR_FIX_RX_DAT_EDGE 0x00
-#defineDDR_FIX_RX_DAT_14_DELAY 0x40
-#defineDDR_FIX_RX_CMD  0x00
-#defineDDR_VAR_RX_CMD  0x20
-#defineDDR_FIX_RX_CMD_POS_EDGE 0x00
-#defineDDR_FIX_RX_CMD_14_DELAY 0x10
-#defineSD20_RX_POS_EDGE0x00
-#defineSD20_RX_14_DELAY0x08
+#define DDR_FIX_RX_DAT 0x00
+#define DDR_VAR_RX_DAT 0x80
+#define DDR_FIX_RX_DAT_EDGE0x00
+#define DDR_FIX_RX_DAT_14_DELAY0x40
+#define DDR_FIX_RX_CMD 0x00
+#define DDR_VAR_RX_CMD 0x20
+#define DDR_FIX_RX_CMD_POS_EDGE0x00
+#define DDR_FIX_RX_CMD_14_DELAY0x10
+#define SD20_RX_POS_EDGE   0x00
+#define SD20_RX_14_DELAY   0x08
 #define SD20_RX_SEL_MASK   0x08
 
 /* SD_PUSH_POINT_CTL */
-#defineDDR_FIX_TX_CMD_DAT  0x00
-#defineDDR_VAR_TX_CMD_DAT  0x80
-#defineDDR_FIX_TX_DAT_14_TSU   0x00
-#defineDDR_FIX_TX_DAT_12_TSU   0x40
-#defineDDR_FIX_TX_CMD_NEG_EDGE 0x00
-#defineDDR_FIX_TX_CMD_14_AHEAD 0x20
-#defineSD20_TX_NEG_EDGE0x00
-#defineSD20_TX_14_AHEAD0x10
+#define DDR_FIX_TX_CMD_DAT 0x00
+#define DDR_VAR_TX_CMD_DAT 0x80
+#define DDR_FIX_TX_DAT_14_TSU  0x00
+#define DDR_FIX_TX_DAT_12_TSU  0x40
+#define DDR_FIX_TX_CMD_NEG_EDGE0x00
+#define DDR_FIX_TX_CMD_14_AHEAD0x20
+#define SD2

[RESEND PATCH v2 8/9] mfd: rtsx: add support for rts525A

2015-01-21 Thread micky_ching
From: Micky Ching 

add support for new chip rts525A.

Signed-off-by: Micky Ching 
---
 drivers/mfd/rts5249.c| 104 ++-
 drivers/mfd/rtsx_pcr.c   |  13 --
 drivers/mfd/rtsx_pcr.h   |   1 +
 include/linux/mfd/rtsx_pci.h |  15 +++
 4 files changed, 129 insertions(+), 4 deletions(-)

diff --git a/drivers/mfd/rts5249.c b/drivers/mfd/rts5249.c
index 97dde92..134e03f 100644
--- a/drivers/mfd/rts5249.c
+++ b/drivers/mfd/rts5249.c
@@ -97,7 +97,7 @@ static void rtsx_base_force_power_down(struct rtsx_pcr *pcr, 
u8 pm_state)
rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 3, 0x01, 0);
 
if (pm_state == HOST_ENTER_S3) {
-   if (PCI_PID(pcr) == 0x524A)
+   if (PCI_PID(pcr) == 0x524A || PCI_PID(pcr) == 0x525A)
rtsx_pci_write_register(pcr, RTS524A_PM_CTRL3,
D3_DELINK_MODE_EN, D3_DELINK_MODE_EN);
else if (PCI_PID(pcr) == 0x5249)
@@ -485,3 +485,105 @@ void rts524a_init_params(struct rtsx_pcr *pcr)
pcr->ops = &rts524a_pcr_ops;
 }
 
+static int rts525a_card_power_on(struct rtsx_pcr *pcr, int card)
+{
+   rtsx_pci_write_register(pcr, LDO_VCC_CFG1,
+   LDO_VCC_TUNE_MASK, LDO_VCC_3V3);
+   return rtsx_base_card_power_on(pcr, card);
+}
+
+static int rts525a_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
+{
+   switch (voltage) {
+   case OUTPUT_3V3:
+   rtsx_pci_write_register(pcr, LDO_CONFIG2,
+   LDO_D3318_MASK, LDO_D3318_33V);
+   rtsx_pci_write_register(pcr, SD_PAD_CTL, SD_IO_USING_1V8, 0);
+   break;
+   case OUTPUT_1V8:
+   rtsx_pci_write_register(pcr, LDO_CONFIG2,
+   LDO_D3318_MASK, LDO_D3318_18V);
+   rtsx_pci_write_register(pcr, SD_PAD_CTL, SD_IO_USING_1V8,
+   SD_IO_USING_1V8);
+   break;
+   default:
+   return -EINVAL;
+   }
+
+   rtsx_pci_init_cmd(pcr);
+   rts5249_fill_driving(pcr, voltage);
+   return rtsx_pci_send_cmd(pcr, 100);
+}
+
+static int rts525a_optimize_phy(struct rtsx_pcr *pcr)
+{
+   int err;
+
+   err = rtsx_pci_write_register(pcr, RTS524A_PM_CTRL3,
+   D3_DELINK_MODE_EN, 0x00);
+   if (err < 0)
+   return err;
+
+   rtsx_pci_write_phy_register(pcr, _PHY_FLD0,
+   _PHY_FLD0_CLK_REQ_20C | _PHY_FLD0_RX_IDLE_EN |
+   _PHY_FLD0_BIT_ERR_RSTN | _PHY_FLD0_BER_COUNT |
+   _PHY_FLD0_BER_TIMER | _PHY_FLD0_CHECK_EN);
+
+   rtsx_pci_write_phy_register(pcr, _PHY_ANA03,
+   _PHY_ANA03_TIMER_MAX | _PHY_ANA03_OOBS_DEB_EN |
+   _PHY_CMU_DEBUG_EN);
+
+   if (is_version(pcr, 0x525A, IC_VER_A))
+   rtsx_pci_write_phy_register(pcr, _PHY_REV0,
+   _PHY_REV0_FILTER_OUT | _PHY_REV0_CDR_BYPASS_PFD |
+   _PHY_REV0_CDR_RX_IDLE_BYPASS);
+
+   return 0;
+}
+
+static int rts525a_extra_init_hw(struct rtsx_pcr *pcr)
+{
+   rts5249_extra_init_hw(pcr);
+
+   rtsx_pci_write_register(pcr, PCLK_CTL, PCLK_MODE_SEL, PCLK_MODE_SEL);
+   if (is_version(pcr, 0x525A, IC_VER_A)) {
+   rtsx_pci_write_register(pcr, L1SUB_CONFIG2,
+   L1SUB_AUTO_CFG, L1SUB_AUTO_CFG);
+   rtsx_pci_write_register(pcr, RREF_CFG,
+   RREF_VBGSEL_MASK, RREF_VBGSEL_1V25);
+   rtsx_pci_write_register(pcr, LDO_VIO_CFG,
+   LDO_VIO_TUNE_MASK, LDO_VIO_1V7);
+   rtsx_pci_write_register(pcr, LDO_DV12S_CFG,
+   LDO_D12_TUNE_MASK, LDO_D12_TUNE_DF);
+   rtsx_pci_write_register(pcr, LDO_AV12S_CFG,
+   LDO_AV12S_TUNE_MASK, LDO_AV12S_TUNE_DF);
+   rtsx_pci_write_register(pcr, LDO_VCC_CFG0,
+   LDO_VCC_LMTVTH_MASK, LDO_VCC_LMTVTH_2A);
+   rtsx_pci_write_register(pcr, OOBS_CONFIG,
+   OOBS_AUTOK_DIS | OOBS_VAL_MASK, 0x89);
+   }
+
+   return 0;
+}
+
+static const struct pcr_ops rts525a_pcr_ops = {
+   .fetch_vendor_settings = rtsx_base_fetch_vendor_settings,
+   .extra_init_hw = rts525a_extra_init_hw,
+   .optimize_phy = rts525a_optimize_phy,
+   .turn_on_led = rtsx_base_turn_on_led,
+   .turn_off_led = rtsx_base_turn_off_led,
+   .enable_auto_blink = rtsx_base_enable_auto_blink,
+   .disable_auto_blink = rtsx_base_disable_auto_blink,
+   .card_power_on = rts525a_card_power_on,
+   .card_power_off = rtsx_base_card_power_off,
+   .switch_output_voltage = rts525a_switch_output_voltage,
+   .force_power_down = rtsx_base_force_power_down,
+};
+
+void rts525a_init_params(struct rtsx_pcr *pcr)
+{
+   rts5249_init_params(pcr);
+
+   pcr->ops = &rts525a_pcr_ops;
+}
+
diff --git a/drivers/mfd/rtsx_pcr.c b/drivers/mfd/rtsx_pcr.c
index e6d97ad..4c47f94 100644
-

[RESEND PATCH v2 7/9] mfd: rtsx: add support for rts524A

2015-01-21 Thread micky_ching
From: Micky Ching 

add support for new chip rts524A.

Signed-off-by: Micky Ching 
---
 drivers/mfd/rts5249.c| 186 ---
 drivers/mfd/rtsx_pcr.c   |  25 +-
 drivers/mfd/rtsx_pcr.h   |   7 ++
 include/linux/mfd/rtsx_pci.h | 125 -
 4 files changed, 310 insertions(+), 33 deletions(-)

diff --git a/drivers/mfd/rts5249.c b/drivers/mfd/rts5249.c
index 3977946..97dde92 100644
--- a/drivers/mfd/rts5249.c
+++ b/drivers/mfd/rts5249.c
@@ -65,15 +65,17 @@ static void rts5249_fill_driving(struct rtsx_pcr *pcr, u8 
voltage)
0xFF, driving[drive_sel][2]);
 }
 
-static void rts5249_fetch_vendor_settings(struct rtsx_pcr *pcr)
+static void rtsx_base_fetch_vendor_settings(struct rtsx_pcr *pcr)
 {
u32 reg;
 
rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG1, ®);
dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
 
-   if (!rtsx_vendor_setting_valid(reg))
+   if (!rtsx_vendor_setting_valid(reg)) {
+   pcr_dbg(pcr, "skip fetch vendor setting\n");
return;
+   }
 
pcr->aspm_en = rtsx_reg_to_aspm(reg);
pcr->sd30_drive_sel_1v8 = rtsx_reg_to_sd30_drive_sel_1v8(reg);
@@ -87,15 +89,21 @@ static void rts5249_fetch_vendor_settings(struct rtsx_pcr 
*pcr)
pcr->flags |= PCR_REVERSE_SOCKET;
 }
 
-static void rts5249_force_power_down(struct rtsx_pcr *pcr, u8 pm_state)
+static void rtsx_base_force_power_down(struct rtsx_pcr *pcr, u8 pm_state)
 {
/* Set relink_time to 0 */
rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 1, 0xFF, 0);
rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 2, 0xFF, 0);
rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 3, 0x01, 0);
 
-   if (pm_state == HOST_ENTER_S3)
-   rtsx_pci_write_register(pcr, PM_CTRL3, 0x10, 0x10);
+   if (pm_state == HOST_ENTER_S3) {
+   if (PCI_PID(pcr) == 0x524A)
+   rtsx_pci_write_register(pcr, RTS524A_PM_CTRL3,
+   D3_DELINK_MODE_EN, D3_DELINK_MODE_EN);
+   else if (PCI_PID(pcr) == 0x5249)
+   rtsx_pci_write_register(pcr, PM_CTRL3,
+   D3_DELINK_MODE_EN, D3_DELINK_MODE_EN);
+   }
 
rtsx_pci_write_register(pcr, FPDCTL, 0x03, 0x03);
 }
@@ -104,6 +112,8 @@ static int rts5249_extra_init_hw(struct rtsx_pcr *pcr)
 {
rtsx_pci_init_cmd(pcr);
 
+   /* Rest L1SUB Config */
+   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, L1SUB_CONFIG3, 0xFF, 0x00);
/* Configure GPIO as output */
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, GPIO_CTL, 0x02, 0x02);
/* Reset ASPM state to default value */
@@ -189,27 +199,27 @@ static int rts5249_optimize_phy(struct rtsx_pcr *pcr)
PHY_TUNE_TUNED12 | PHY_TUNE_TUNEA12);
 }
 
-static int rts5249_turn_on_led(struct rtsx_pcr *pcr)
+static int rtsx_base_turn_on_led(struct rtsx_pcr *pcr)
 {
return rtsx_pci_write_register(pcr, GPIO_CTL, 0x02, 0x02);
 }
 
-static int rts5249_turn_off_led(struct rtsx_pcr *pcr)
+static int rtsx_base_turn_off_led(struct rtsx_pcr *pcr)
 {
return rtsx_pci_write_register(pcr, GPIO_CTL, 0x02, 0x00);
 }
 
-static int rts5249_enable_auto_blink(struct rtsx_pcr *pcr)
+static int rtsx_base_enable_auto_blink(struct rtsx_pcr *pcr)
 {
return rtsx_pci_write_register(pcr, OLT_LED_CTL, 0x08, 0x08);
 }
 
-static int rts5249_disable_auto_blink(struct rtsx_pcr *pcr)
+static int rtsx_base_disable_auto_blink(struct rtsx_pcr *pcr)
 {
return rtsx_pci_write_register(pcr, OLT_LED_CTL, 0x08, 0x00);
 }
 
-static int rts5249_card_power_on(struct rtsx_pcr *pcr, int card)
+static int rtsx_base_card_power_on(struct rtsx_pcr *pcr, int card)
 {
int err;
 
@@ -236,7 +246,7 @@ static int rts5249_card_power_on(struct rtsx_pcr *pcr, int 
card)
return 0;
 }
 
-static int rts5249_card_power_off(struct rtsx_pcr *pcr, int card)
+static int rtsx_base_card_power_off(struct rtsx_pcr *pcr, int card)
 {
rtsx_pci_init_cmd(pcr);
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
@@ -246,22 +256,31 @@ static int rts5249_card_power_off(struct rtsx_pcr *pcr, 
int card)
return rtsx_pci_send_cmd(pcr, 100);
 }
 
-static int rts5249_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
+static int rtsx_base_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
 {
int err;
+   u16 append;
 
-   if (voltage == OUTPUT_3V3) {
-   err = rtsx_pci_write_phy_register(pcr, PHY_TUNE, 0x4FC0 | 0x24);
-   if (err < 0)
-   return err;
-   } else if (voltage == OUTPUT_1V8) {
-   err = rtsx_pci_write_phy_register(pcr, PHY_BACR, 0x3C02);
+   switch (voltage) {
+   case OUTPUT_3V3:
+   err = rtsx_pci_update_phy(pcr, PHY_TUNE, 0xFC3F, 0x03C0);
if (err < 0)
return err;
- 

[RESEND PATCH v2 6/9] mfd: rtsx: remove LCTLR defination

2015-01-21 Thread micky_ching
From: Micky Ching 

To enable/disable ASPM we should find LINK CONTROL register
in PCI config space. All old chip use 0x80 address, but new
chip may use another address, so we using pci_find_capability()
to get LINK CONTROL address.

rtsx_gops.c was removed, we consider to put some common operations
to this file, but the actual thing is, only a group of chips
are in common ops1, and another group of chips in common ops2,
it is hard to decide put which ops into generic ops file.

Signed-off-by: Micky Ching 
---
 drivers/mfd/Makefile |  2 +-
 drivers/mfd/rts5227.c|  2 +-
 drivers/mfd/rts5249.c|  3 +--
 drivers/mfd/rtsx_gops.c  | 37 -
 drivers/mfd/rtsx_pcr.c   | 22 +-
 include/linux/mfd/rtsx_pci.h | 10 +-
 6 files changed, 21 insertions(+), 55 deletions(-)
 delete mode 100644 drivers/mfd/rtsx_gops.c

diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 53467e2..2cd7e74 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -13,7 +13,7 @@ obj-$(CONFIG_MFD_CROS_EC) += cros_ec.o
 obj-$(CONFIG_MFD_CROS_EC_I2C)  += cros_ec_i2c.o
 obj-$(CONFIG_MFD_CROS_EC_SPI)  += cros_ec_spi.o
 
-rtsx_pci-objs  := rtsx_pcr.o rtsx_gops.o rts5209.o rts5229.o 
rtl8411.o rts5227.o rts5249.o
+rtsx_pci-objs  := rtsx_pcr.o rts5209.o rts5229.o rtl8411.o 
rts5227.o rts5249.o
 obj-$(CONFIG_MFD_RTSX_PCI) += rtsx_pci.o
 obj-$(CONFIG_MFD_RTSX_USB) += rtsx_usb.o
 
diff --git a/drivers/mfd/rts5227.c b/drivers/mfd/rts5227.c
index 1f387d4..0c02831 100644
--- a/drivers/mfd/rts5227.c
+++ b/drivers/mfd/rts5227.c
@@ -130,7 +130,7 @@ static int rts5227_optimize_phy(struct rtsx_pcr *pcr)
 {
int err;
 
-   err = rtsx_gops_pm_reset(pcr);
+   err = rtsx_pci_write_register(pcr, PM_CTRL3, D3_DELINK_MODE_EN, 0x00);
if (err < 0)
return err;
 
diff --git a/drivers/mfd/rts5249.c b/drivers/mfd/rts5249.c
index d8072f6..3977946 100644
--- a/drivers/mfd/rts5249.c
+++ b/drivers/mfd/rts5249.c
@@ -119,7 +119,6 @@ static int rts5249_extra_init_hw(struct rtsx_pcr *pcr)
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0xB0, 0xB0);
else
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0xB0, 0x80);
-   rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PM_CTRL3, 0x10, 0x00);
 
return rtsx_pci_send_cmd(pcr, 100);
 }
@@ -128,7 +127,7 @@ static int rts5249_optimize_phy(struct rtsx_pcr *pcr)
 {
int err;
 
-   err = rtsx_gops_pm_reset(pcr);
+   err = rtsx_pci_write_register(pcr, PM_CTRL3, D3_DELINK_MODE_EN, 0x00);
if (err < 0)
return err;
 
diff --git a/drivers/mfd/rtsx_gops.c b/drivers/mfd/rtsx_gops.c
deleted file mode 100644
index b1a98c6..000
--- a/drivers/mfd/rtsx_gops.c
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Driver for Realtek PCI-Express card reader
- *
- * Copyright(c) 2009-2013 Realtek Semiconductor Corp. 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 as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * 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.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see .
- *
- * Author:
- *   Micky Ching 
- */
-
-#include 
-#include "rtsx_pcr.h"
-
-int rtsx_gops_pm_reset(struct rtsx_pcr *pcr)
-{
-   int err;
-
-   /* init aspm */
-   rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, 0xFF, 0x00);
-   err = rtsx_pci_update_cfg_byte(pcr, LCTLR, ~LCTLR_ASPM_CTL_MASK, 0x00);
-   if (err < 0)
-   return err;
-
-   /* reset PM_CTRL3 before send buffer cmd */
-   return rtsx_pci_write_register(pcr, PM_CTRL3, D3_DELINK_MODE_EN, 0x00);
-}
diff --git a/drivers/mfd/rtsx_pcr.c b/drivers/mfd/rtsx_pcr.c
index 30f7ca8..81b9c2c 100644
--- a/drivers/mfd/rtsx_pcr.c
+++ b/drivers/mfd/rtsx_pcr.c
@@ -63,6 +63,18 @@ static const struct pci_device_id rtsx_pci_ids[] = {
 
 MODULE_DEVICE_TABLE(pci, rtsx_pci_ids);
 
+static inline void rtsx_pci_enable_aspm(struct rtsx_pcr *pcr)
+{
+   rtsx_pci_update_cfg_byte(pcr, pcr->pcie_cap + PCI_EXP_LNKCTL,
+   0xFC, pcr->aspm_en);
+}
+
+static inline void rtsx_pci_disable_aspm(struct rtsx_pcr *pcr)
+{
+   rtsx_pci_update_cfg_byte(pcr, pcr->pcie_cap + PCI_EXP_LNKCTL,
+   0xFC, 0);
+}
+
 void rtsx_pci_start_run(struct rtsx_pcr *pcr)
 {
/* If pci device removed, don't queue idle work any more */
@@ -75,7 +87,7 @@ void rtsx_pci_start_run(struct rtsx_pcr *pcr)
pcr->ops->enable_auto_blink(pcr);
 

  1   2   >