mmc: rtsx: add support for sdio card
Subsystems (2)
v4 cover mmc: rtsx: add support for sdio card
From: Micky Ching <[email protected]>
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(-)
Signature · 1 line
1.9.1
PATCH v4 1/6 mfd: rtsx: add func to split u32 into register
From: Micky Ching <[email protected]>
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.
--- include/linux/mfd/rtsx_pci.h | 9 +++++++++ 1 file changed, 9 insertions(+)
include/linux/mfd/rtsx_pci.h +9 -0
@@ -558,6 +558,7 @@#define SD_SAMPLE_POINT_CTL 0xFDA7#define SD_PUSH_POINT_CTL 0xFDA8#define SD_CMD0 0xFDA9 +#define SD_CMD_START 0x40#define SD_CMD1 0xFDAA#define SD_CMD2 0xFDAB#define SD_CMD3 0xFDAC
@@ -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
Signature · 1 line
1.9.1
Re: [PATCH v4 1/6] mfd: rtsx: add func to split u32 into register
Hi Lee,
this patch can be applied if you think it is ok, it doesn't depends other patches.
regards.
micky.
Quoted 36 lines · On 12/05/2014 01:54 PM, [email protected] wrote:
From: Micky Ching <[email protected]>
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 <[email protected]>Acked-by Lee Jones <[email protected]>--- include/linux/mfd/rtsx_pci.h | 9 +++++++++ 1 file changed, 9 insertions(+)include/linux/mfd/rtsx_pci.h +9
-0@@ -558,6 +558,7 @@#define SD_SAMPLE_POINT_CTL 0xFDA7#define SD_PUSH_POINT_CTL 0xFDA8#define SD_CMD0 0xFDA9 +#define SD_CMD_START 0x40#define SD_CMD1 0xFDAA#define SD_CMD2 0xFDAB#define SD_CMD3 0xFDAC@@ -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
Re: [PATCH v4 1/6] mfd: rtsx: add func to split u32 into register
In reply to [email protected]Quoted 16 lines · On Fri, 05 Dec 2014, [email protected] wrote:
From: Micky Ching <[email protected]>
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 <[email protected]>Acked-by Lee Jones <[email protected]>--- include/linux/mfd/rtsx_pci.h | 9 +++++++++ 1 file changed, 9 insertions(+)include/linux/mfd/rtsx_pci.h +0
-0
include/linux/mfd/rtsx_pci.h line 561
Quoted 4 lines
include/linux/mfd/rtsx_pci.h +1
-0@@ -558,6 +558,7 @@#define SD_SAMPLE_POINT_CTL 0xFDA7#define SD_PUSH_POINT_CTL 0xFDA8#define SD_CMD0 0xFDA9 +#define SD_CMD_START 0x40
This is a different format at the others in the group on two counts; firstly you have 3 whitespace characters after the #define and secondly all of the other hex digits in the set are 4 a breast. Please add the leading zeros to conform to this format.
Quoted 16 lines
include/linux/mfd/rtsx_pci.h +8
-0#define SD_CMD1 0xFDAA#define SD_CMD2 0xFDAB#define SD_CMD3 0xFDAC@@ -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
Signature · 4 lines
Lee Jones Linaro STMicroelectronics Landing Team Lead Linaro.org │ Open source software for ARM SoCs Follow Linaro: Facebook | Twitter | Blog
Re: [PATCH v4 1/6] mfd: rtsx: add func to split u32 into register
Quoted 14 lines · Lee Jones
Quoted 9 lines
include/linux/mfd/rtsx_pci.h +0
-0include/linux/mfd/rtsx_pci.h line 561
Quoted 8 lines
index 74346d5..9234449 100644
include/linux/mfd/rtsx_pci.h +1
-0@@ -558,6 +558,7 @@#define SD_SAMPLE_POINT_CTL 0xFDA7#define SD_PUSH_POINT_CTL 0xFDA8#define SD_CMD0 0xFDA9 +#define SD_CMD_START 0x40This is a different format at the others in the group on two counts; firstly you have 3 whitespace characters after the #define and secondly all of the other hex digits in the set are 4 a breast. Please add the leading zeros to conform to this format.
Hi lee,
This format is more readable, add 2 space means this value is in groups under register SD_CMD0, and each register value is u8 type, so use 2 hex digits is right.
The original file make register address and its related value separated, and group register together.
But I like to write register address and value together,
add 2 space for value to indicate this value is related to above register.
If we add new address/value, I recommend write register define format as below:
#define REGISTER addr #define REG_VAL1 val1 #define REG_VAL2 val2
regards.
micky.
Re: [PATCH v4 1/6] mfd: rtsx: add func to split u32 into register
Quoted 28 lines · 敬锐
Quoted 14 lines · Lee Jones
Quoted 9 lines
include/linux/mfd/rtsx_pci.h +0
-0include/linux/mfd/rtsx_pci.h line 561
Quoted 8 lines
index 74346d5..9234449 100644
include/linux/mfd/rtsx_pci.h +1
-0@@ -558,6 +558,7 @@#define SD_SAMPLE_POINT_CTL 0xFDA7#define SD_PUSH_POINT_CTL 0xFDA8#define SD_CMD0 0xFDA9 +#define SD_CMD_START 0x40This is a different format at the others in the group on two counts; firstly you have 3 whitespace characters after the #define and secondly all of the other hex digits in the set are 4 a breast. Please add the leading zeros to conform to this format.
Hi lee,
This format is more readable, add 2 space means this value is in groups under register
SD_CMD0, and each register value is u8 type, so use 2 hex digits is right.The original file make register address and its related value separated, and group register together.
But I like to write register address and value together,
add 2 space for value to indicate this value is related to above register.
Quoted 6 lines
If we add new address/value, I recommend write register define format as below:
#define REGISTER addr #define REG_VAL1 val1 #define REG_VAL2 val2
Okay, I see that there are other occurrences using this format in that file. Please consider converting the entire file into this format. I don't mind it either way, but it looks odd if they are mixed.
Signature · 4 lines
Lee Jones Linaro STMicroelectronics Landing Team Lead Linaro.org │ Open source software for ARM SoCs Follow Linaro: Facebook | Twitter | Blog
Re: [PATCH v4 1/6] mfd: rtsx: add func to split u32 into register
Quoted 32 lines · Lee Jones
Quoted 30 lines · 敬锐
Quoted 14 lines · Lee Jones
Quoted 9 lines
include/linux/mfd/rtsx_pci.h +0
-0include/linux/mfd/rtsx_pci.h line 561
Quoted 8 lines
index 74346d5..9234449 100644
include/linux/mfd/rtsx_pci.h +1
-0@@ -558,6 +558,7 @@#define SD_SAMPLE_POINT_CTL 0xFDA7#define SD_PUSH_POINT_CTL 0xFDA8#define SD_CMD0 0xFDA9 +#define SD_CMD_START 0x40This is a different format at the others in the group on two counts; firstly you have 3 whitespace characters after the #define and secondly all of the other hex digits in the set are 4 a breast. Please add the leading zeros to conform to this format.
Hi lee,
This format is more readable, add 2 space means this value is in groups under register
SD_CMD0, and each register value is u8 type, so use 2 hex digits is right.The original file make register address and its related value separated, and group register together.
But I like to write register address and value together,
add 2 space for value to indicate this value is related to above register.If we add new address/value, I recommend write register define format as below:
Quoted 7 lines
Quoted 3 lines
#define REGISTER addr #define REG_VAL1 val1 #define REG_VAL2 val2Okay, I see that there are other occurrences using this format in that file. Please consider converting the entire file into this format. I don't mind it either way, but it looks odd if they are mixed.
we will reformat it in the near future.
regards.
_______________________________________________
devel mailing list
[email protected]
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Lee Jones
AppliedRe: [PATCH v4 1/6] mfd: rtsx: add func to split u32 into register
In reply to [email protected]Quoted 10 lines · On Fri, 05 Dec 2014, [email protected] wrote:
From: Micky Ching <[email protected]>
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 <[email protected]>Acked-by Lee Jones <[email protected]>--- include/linux/mfd/rtsx_pci.h | 9 +++++++++ 1 file changed, 9 insertions(+)
Applied, thanks.
Quoted 25 lines
include/linux/mfd/rtsx_pci.h +9
-0@@ -558,6 +558,7 @@#define SD_SAMPLE_POINT_CTL 0xFDA7#define SD_PUSH_POINT_CTL 0xFDA8#define SD_CMD0 0xFDA9 +#define SD_CMD_START 0x40#define SD_CMD1 0xFDAA#define SD_CMD2 0xFDAB#define SD_CMD3 0xFDAC@@ -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
Signature · 8 lines
Lee Jones Linaro STMicroelectronics Landing Team Lead Linaro.org │ Open source software for ARM SoCs Follow Linaro: Facebook | Twitter | Blog _______________________________________________ devel mailing list [email protected] http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v4 1/6] mfd: rtsx: add func to split u32 into register
Quoted 6 lines · Lee Jones
Quoted 5 lines · On Fri, 05 Dec 2014, [email protected] wrote:
From: Micky Ching <[email protected]>
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.
Quoted 7 lines
Quoted 5 lines
Signed-off-by Micky Ching <[email protected]>Acked-by Lee Jones <[email protected]>--- include/linux/mfd/rtsx_pci.h | 9 +++++++++ 1 file changed, 9 insertions(+)Applied, thanks.
Lee,
I suppose you queued this for 3.19?
I don't intend to queue anything more before the merge window and thus the mmc patches can later be handled without any dependence to mfd, I guess!?
Kind regards
Uffe
Re: [PATCH v4 1/6] mfd: rtsx: add func to split u32 into register
Quoted 15 lines · Ulf Hansson
Quoted 6 lines · Lee Jones
Quoted 5 lines · On Fri, 05 Dec 2014, [email protected] wrote:
From: Micky Ching <[email protected]>
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.
Quoted 7 lines
Quoted 5 lines
Signed-off-by Micky Ching <[email protected]>Acked-by Lee Jones <[email protected]>--- include/linux/mfd/rtsx_pci.h | 9 +++++++++ 1 file changed, 9 insertions(+)Applied, thanks.
Quoted 7 lines
Lee,
I suppose you queued this for 3.19?
I don't intend to queue anything more before the merge window and thus the mmc patches can later be handled without any dependence to mfd, I guess!?
All correct.
Signature · 8 lines
Lee Jones Linaro STMicroelectronics Landing Team Lead Linaro.org │ Open source software for ARM SoCs Follow Linaro: Facebook | Twitter | Blog _______________________________________________ devel mailing list [email protected] http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
PATCH v4 2/6 mmc: rtsx: add dump_reg_range to simplify dump register
In reply to [email protected]From: Micky Ching <[email protected]>
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.
--- drivers/mmc/host/rtsx_pci_sdmmc.c | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-)
drivers/mmc/host/rtsx_pci_sdmmc.c +21 -17
@@ -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)
Signature · 1 line
1.9.1
PATCH v4 3/6 mmc: rtsx: init cookie at probe/card_event
In reply to [email protected]From: Micky Ching <[email protected]>
host->cookie is used for handle async request,
we should init it to negative value when new card inserted, make cookie value invalid.
--- drivers/mmc/host/rtsx_pci_sdmmc.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/mmc/host/rtsx_pci_sdmmc.c +2 -0
@@ -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);
Signature · 1 line
1.9.1
PATCH v4 4/6 mmc: rtsx: add helper function to simplify code
In reply to [email protected]From: Micky Ching <[email protected]>
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.
--- drivers/mmc/host/rtsx_pci_sdmmc.c | 95 +++++++++++++++++++++------------------ 1 file changed, 51 insertions(+), 44 deletions(-)
drivers/mmc/host/rtsx_pci_sdmmc.c +51 -44
@@ -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_REG_CMD , (u16 )i,0 ,0 ); - stat_idx =5 ; }rtsx_pci_add_cmd (pcr,READ_REG_CMD ,SD_STAT1 ,0 ,0 );
Signature · 1 line
1.9.1
PATCH v4 5/6 mmc: rtsx: add support for sdio card
In reply to [email protected]From: Micky Ching <[email protected]>
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.
--- drivers/mmc/host/rtsx_pci_sdmmc.c | 231 ++++++++++++++++++++++---------------- 1 file changed, 135 insertions(+), 96 deletions(-)
drivers/mmc/host/rtsx_pci_sdmmc.c +135 -96
@@ -28,6 +28,7 @@#include <linux/mmc/host.h> #include <linux/mmc/mmc.h> #include <linux/mmc/sd.h> +#include <linux/mmc/sdio.h> #include <linux/mmc/card.h> #include <linux/mfd/rtsx_pci.h> #include <asm/unaligned.h>
@@ -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 (struct realtek_pci_sdmmc *host, +struct mmc_request *mrq) {struct rtsx_pcr *pcr = host->pcr;struct mmc_host *mmc = host->mmc;struct mmc_card *card = mmc->card; +struct mmc_command *cmd = mrq->cmd;struct mmc_data *data = mrq->data;int uhs =mmc_card_uhs (card); -int read = (data->flags &MMC_DATA_READ ) ?1 :0 ; -u8 cfg2, trans_mode; +u8 cfg2 =0 ;int err; +int resp_type;size_t data_len = data->blksz * data->blocks; -if (read) { - cfg2 =SD_CALCULATE_CRC7 |SD_CHECK_CRC16 | -SD_NO_WAIT_BUSY_END |SD_CHECK_CRC7 |SD_RSP_LEN_0 ; - trans_mode =SD_TM_AUTO_READ_3 ; - }else { - cfg2 =SD_NO_CALCULATE_CRC7 |SD_CHECK_CRC16 | -SD_NO_WAIT_BUSY_END |SD_NO_CHECK_CRC7 |SD_RSP_LEN_0 ; - trans_mode =SD_TM_AUTO_WRITE_3 ; - } +dev_dbg (sdmmc_dev (host),"%s: SD/MMC CMD %d, arg = 0x%08x\n" , + __func__, cmd->opcode, cmd->arg); + + resp_type =sd_response_type (cmd); +if (resp_type <0 ) +return resp_type;if (!uhs) cfg2 |=SD_NO_CHECK_WAIT_CRC_TO ;rtsx_pci_init_cmd (pcr); - -rtsx_pci_add_cmd (pcr,WRITE_REG_CMD ,SD_BYTE_CNT_L ,0xFF ,0x00 ); -rtsx_pci_add_cmd (pcr,WRITE_REG_CMD ,SD_BYTE_CNT_H ,0xFF ,0x02 ); -rtsx_pci_add_cmd (pcr,WRITE_REG_CMD ,SD_BLOCK_CNT_L , -0xFF , (u8 )data->blocks); -rtsx_pci_add_cmd (pcr,WRITE_REG_CMD ,SD_BLOCK_CNT_H , -0xFF , (u8)(data->blocks >>8 )); - +sd_cmd_set_sd_cmd (pcr, cmd); +sd_cmd_set_data_len (pcr, data->blocks, data->blksz);rtsx_pci_add_cmd (pcr,WRITE_REG_CMD ,IRQSTAT0 ,DMA_DONE_INT ,DMA_DONE_INT );rtsx_pci_add_cmd (pcr,WRITE_REG_CMD ,DMATC3 , -0xFF , (u8)(data_len >>24 )); +0xFF , (u8)(data_len >>24 ));rtsx_pci_add_cmd (pcr,WRITE_REG_CMD ,DMATC2 , -0xFF , (u8)(data_len >>16 )); +0xFF , (u8)(data_len >>16 ));rtsx_pci_add_cmd (pcr,WRITE_REG_CMD ,DMATC1 , -0xFF , (u8)(data_len >>8 )); +0xFF , (u8)(data_len >>8 ));rtsx_pci_add_cmd (pcr,WRITE_REG_CMD ,DMATC0 ,0xFF , (u8 )data_len); -if (read) { -rtsx_pci_add_cmd (pcr,WRITE_REG_CMD ,DMACTL , -0x03 |DMA_PACK_SIZE_MASK , -DMA_DIR_FROM_CARD |DMA_EN |DMA_512 ); - }else { -rtsx_pci_add_cmd (pcr,WRITE_REG_CMD ,DMACTL , -0x03 |DMA_PACK_SIZE_MASK , -DMA_DIR_TO_CARD |DMA_EN |DMA_512 ); +rtsx_pci_add_cmd (pcr,WRITE_REG_CMD ,DMACTL , +0x03 |DMA_PACK_SIZE_MASK , +DMA_DIR_FROM_CARD |DMA_EN |DMA_512 ); +rtsx_pci_add_cmd (pcr,WRITE_REG_CMD ,CARD_DATA_SOURCE , +0x01 ,RING_BUFFER ); +rtsx_pci_add_cmd (pcr,WRITE_REG_CMD ,SD_CFG2 ,0xFF , cfg2 | resp_type); +rtsx_pci_add_cmd (pcr,WRITE_REG_CMD ,SD_TRANSFER ,0xFF , +SD_TRANSFER_START |SD_TM_AUTO_READ_2 ); +rtsx_pci_add_cmd (pcr,CHECK_REG_CMD ,SD_TRANSFER , +SD_TRANSFER_END ,SD_TRANSFER_END ); +rtsx_pci_send_cmd_no_wait (pcr); + + err =rtsx_pci_dma_transfer (pcr, data->sg, host->sg_count,1 ,10000 ); +if (err <0 ) { +sd_print_debug_regs (host); +sd_clear_error (host); +return err; } +return 0 ; +} + +static int sd_write_long_data (struct realtek_pci_sdmmc *host, +struct mmc_request *mrq) +{ +struct rtsx_pcr *pcr = host->pcr; +struct mmc_host *mmc = host->mmc; +struct mmc_card *card = mmc->card; +struct mmc_command *cmd = mrq->cmd; +struct mmc_data *data = mrq->data; +int uhs =mmc_card_uhs (card); +u8 cfg2; +int err; +size_t data_len = data->blksz * data->blocks; + +sd_send_cmd_get_rsp (host, cmd); +if (cmd->error) +return cmd->error; + +dev_dbg (sdmmc_dev (host),"%s: SD/MMC CMD %d, arg = 0x%08x\n" , + __func__, cmd->opcode, cmd->arg); + + cfg2 =SD_NO_CALCULATE_CRC7 |SD_CHECK_CRC16 | +SD_NO_WAIT_BUSY_END |SD_NO_CHECK_CRC7 |SD_RSP_LEN_0 ; + +if (!uhs) + cfg2 |=SD_NO_CHECK_WAIT_CRC_TO ; + +rtsx_pci_init_cmd (pcr); +sd_cmd_set_data_len (pcr, data->blocks, data->blksz); +rtsx_pci_add_cmd (pcr,WRITE_REG_CMD ,IRQSTAT0 , +DMA_DONE_INT ,DMA_DONE_INT ); +rtsx_pci_add_cmd (pcr,WRITE_REG_CMD ,DMATC3 , +0xFF , (u8)(data_len >>24 )); +rtsx_pci_add_cmd (pcr,WRITE_REG_CMD ,DMATC2 , +0xFF , (u8)(data_len >>16 )); +rtsx_pci_add_cmd (pcr,WRITE_REG_CMD ,DMATC1 , +0xFF , (u8)(data_len >>8 )); +rtsx_pci_add_cmd (pcr,WRITE_REG_CMD ,DMATC0 ,0xFF , (u8 )data_len); +rtsx_pci_add_cmd (pcr,WRITE_REG_CMD ,DMACTL , +0x03 |DMA_PACK_SIZE_MASK , +DMA_DIR_TO_CARD |DMA_EN |DMA_512 );rtsx_pci_add_cmd (pcr,WRITE_REG_CMD ,CARD_DATA_SOURCE ,0x01 ,RING_BUFFER ); -rtsx_pci_add_cmd (pcr,WRITE_REG_CMD ,SD_CFG2 ,0xFF , cfg2);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 ); -rtsx_pci_send_cmd_no_wait (pcr); - - err =rtsx_pci_dma_transfer (pcr, data->sg, host->sg_count, read,10000 ); + err =rtsx_pci_dma_transfer (pcr, data->sg, host->sg_count,0 ,10000 );if (err <0 ) {sd_clear_error (host);return err;
@@ -522,6 +548,16 @@ static int sd_rw_multi(struct realtek_pci_sdmmc *host, struct mmc_request *mrq)return 0 ; } +static int sd_rw_multi (struct realtek_pci_sdmmc *host,struct mmc_request *mrq) +{ +struct mmc_data *data = mrq->data; + +if (data->flags &MMC_DATA_READ ) +return sd_read_long_data (host, mrq); + +return sd_write_long_data (host, mrq); +} +static inline void sd_enable_initial_mode (struct realtek_pci_sdmmc *host) { rtsx_pci_write_register(host->pcr, SD_CFG1,
@@ -539,10 +575,7 @@ static void sd_normal_rw(struct realtek_pci_sdmmc *host, {struct mmc_command *cmd = mrq->cmd;struct mmc_data *data = mrq->data; -u8 _cmd[5 ], *buf; - - _cmd[0 ] =0x40 | (u8 )cmd->opcode; -put_unaligned_be32 (cmd->arg, (u32 *)(&_cmd[1 ])); +u8 *buf; buf =kzalloc (data->blksz,GFP_NOIO );if (!buf) {
@@ -554,7 +587,7 @@ static void sd_normal_rw(struct realtek_pci_sdmmc *host,if (host->initial_mode)sd_disable_initial_mode (host); - cmd->error =sd_read_data (host, _cmd, (u16 )data->blksz, buf, + cmd->error =sd_read_data (host, cmd, (u16 )data->blksz, buf, data->blksz,200 );if (host->initial_mode)
@@ -564,7 +597,7 @@ static void sd_normal_rw(struct realtek_pci_sdmmc *host, }else {sg_copy_to_buffer (data->sg, data->sg_len, buf, data->blksz); - cmd->error =sd_write_data (host, _cmd, (u16 )data->blksz, buf, + cmd->error =sd_write_data (host, cmd, (u16 )data->blksz, buf, data->blksz,200 ); }
@@ -664,14 +697,14 @@ static int sd_tuning_rx_cmd(struct realtek_pci_sdmmc *host, u8 opcode, u8 sample_point) { int err; -u8 cmd[5 ] = {0 }; +struct mmc_command cmd = {0 }; err =sd_change_phase (host, sample_point, true);if (err <0 )return err; - cmd[0 ] =0x40 | opcode; - err =sd_read_data (host, cmd,0x40 ,NULL ,0 ,100 ); + cmd.opcode = opcode; + err =sd_read_data (host, &cmd,0x40 ,NULL ,0 ,100 );if (err <0 ) {/* Wait till SD DATA IDLE */ sd_wait_data_idle (host);
@@ -738,6 +771,12 @@ static int sd_tuning_rx(struct realtek_pci_sdmmc *host, u8 opcode)return 0 ; } +static inline int sdio_extblock_cmd (struct mmc_command *cmd, +struct mmc_data *data) +{ +return (cmd->opcode ==SD_IO_RW_EXTENDED ) && (data->blksz ==512 ); +} +static inline int sd_rw_cmd (struct mmc_command *cmd) { return mmc_op_multi(cmd->opcode) ||
@@ -787,17 +826,15 @@ static void sd_request(struct work_struct *work)if (mrq->data) data_size = data->blocks * data->blksz; -if (!data_size ||sd_rw_cmd (cmd)) { +if (!data_size) {sd_send_cmd_get_rsp (host, cmd); + }else if (sd_rw_cmd (cmd) ||sdio_extblock_cmd (cmd, data)) { + cmd->error =sd_rw_multi (host, mrq); +if (!host->using_cookie) +sdmmc_post_req (host->mmc, host->mrq,0 ); -if (!cmd->error && data_size) { -sd_rw_multi (host, mrq); -if (!host->using_cookie) -sdmmc_post_req (host->mmc, host->mrq,0 ); - -if (mmc_op_multi (cmd->opcode) && mrq->stop) -sd_send_cmd_get_rsp (host, mrq->stop); - } +if (mmc_op_multi (cmd->opcode) && mrq->stop) +sd_send_cmd_get_rsp (host, mrq->stop); }else {sd_normal_rw (host, mrq); }
@@ -812,8 +849,10 @@ static void sd_request(struct work_struct *work)mutex_unlock (&pcr->pcr_mutex); finish: -if (cmd->error) -dev_dbg (sdmmc_dev (host),"cmd->error = %d\n" , cmd->error); +if (cmd->error) { +dev_dbg (sdmmc_dev (host),"CMD %d 0x%08x error(%d)\n" , + cmd->opcode, cmd->arg, cmd->error); + }mutex_lock (&host->host_mutex); host->mrq =NULL ;
@@ -831,7 +870,7 @@ static void sdmmc_request(struct mmc_host *mmc, struct mmc_request *mrq) host->mrq = mrq;mutex_unlock (&host->host_mutex); -if (sd_rw_cmd (mrq->cmd)) +if (sd_rw_cmd (mrq->cmd) ||sdio_extblock_cmd (mrq->cmd, data)) host->using_cookie =sd_pre_dma_transfer (host, data, false);queue_work (host->workq, &host->work);
Signature · 1 line
1.9.1
PATCH v4 6/6 mmc: rtsx: swap function position to avoid pre declaration
In reply to [email protected]From: Micky Ching <[email protected]>
move function sd_read_data()/sd_write_data() behind sd_send_cmd_get_rsp() to avoid pre-declaration.
--- drivers/mmc/host/rtsx_pci_sdmmc.c | 200 +++++++++++++++++++------------------- 1 file changed, 100 insertions(+), 100 deletions(-)
drivers/mmc/host/rtsx_pci_sdmmc.c +100 -100
@@ -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); +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 int sd_read_long_data (struct realtek_pci_sdmmc *host,struct mmc_request *mrq) {
Signature · 1 line
1.9.1
Quoted 34 lines · On 5 December 2014 at 06:54, <[email protected]> wrote:
From: Micky Ching <[email protected]>
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 unusedrtsx_pci_write_le32
- addSD_CMD_START
rtsx_pci_sdmmc.c:
-dump_reg_range
- alloc data on stack
- remove forward declaration
- useSD_CMD_STARTreplace magic number0x40
- move initialize assignment to error handlingThis 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: adddump_reg_rangeto 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
Quoted 7 lines
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
Thanks! Queued for 3.20.
Kind regards
Uffe