aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorPierre Ossman <drzeus-list@drzeus.cx>2005-09-06 18:18:53 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-09-07 19:57:50 -0400
commitb57c43ad81602589afca3948a5a7121e40026e17 (patch)
tree39592e326f498231b39e95c299ad6fcd559341ef /drivers/mmc
parenta00fc09029f02ca833cf90e5d5625f08c4ac4f51 (diff)
[PATCH] sd: SCR register
Read the SD specific SCR register from the card. Signed-off-by: Pierre Ossman <drzeus@drzeus.cx> Cc: Russell King <rmk@arm.linux.org.uk> Cc: David Brownell <david-b@pacbell.net> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/mmc.c143
1 files changed, 133 insertions, 10 deletions
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 725c6ad3eb64..21d4fb3314f8 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -16,6 +16,8 @@
16#include <linux/delay.h> 16#include <linux/delay.h>
17#include <linux/pagemap.h> 17#include <linux/pagemap.h>
18#include <linux/err.h> 18#include <linux/err.h>
19#include <asm/scatterlist.h>
20#include <linux/scatterlist.h>
19 21
20#include <linux/mmc/card.h> 22#include <linux/mmc/card.h>
21#include <linux/mmc/host.h> 23#include <linux/mmc/host.h>
@@ -246,6 +248,8 @@ int mmc_wait_for_app_cmd(struct mmc_host *host, unsigned int rca,
246 248
247EXPORT_SYMBOL(mmc_wait_for_app_cmd); 249EXPORT_SYMBOL(mmc_wait_for_app_cmd);
248 250
251static int mmc_select_card(struct mmc_host *host, struct mmc_card *card);
252
249/** 253/**
250 * __mmc_claim_host - exclusively claim a host 254 * __mmc_claim_host - exclusively claim a host
251 * @host: mmc host to claim 255 * @host: mmc host to claim
@@ -278,16 +282,10 @@ int __mmc_claim_host(struct mmc_host *host, struct mmc_card *card)
278 spin_unlock_irqrestore(&host->lock, flags); 282 spin_unlock_irqrestore(&host->lock, flags);
279 remove_wait_queue(&host->wq, &wait); 283 remove_wait_queue(&host->wq, &wait);
280 284
281 if (card != (void *)-1 && host->card_selected != card) { 285 if (card != (void *)-1) {
282 struct mmc_command cmd; 286 err = mmc_select_card(host, card);
283 287 if (err != MMC_ERR_NONE)
284 host->card_selected = card; 288 return err;
285
286 cmd.opcode = MMC_SELECT_CARD;
287 cmd.arg = card->rca << 16;
288 cmd.flags = MMC_RSP_R1;
289
290 err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
291 } 289 }
292 290
293 return err; 291 return err;
@@ -317,6 +315,29 @@ void mmc_release_host(struct mmc_host *host)
317 315
318EXPORT_SYMBOL(mmc_release_host); 316EXPORT_SYMBOL(mmc_release_host);
319 317
318static int mmc_select_card(struct mmc_host *host, struct mmc_card *card)
319{
320 int err;
321 struct mmc_command cmd;
322
323 BUG_ON(host->card_busy == NULL);
324
325 if (host->card_selected == card)
326 return MMC_ERR_NONE;
327
328 host->card_selected = card;
329
330 cmd.opcode = MMC_SELECT_CARD;
331 cmd.arg = card->rca << 16;
332 cmd.flags = MMC_RSP_R1;
333
334 err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
335 if (err != MMC_ERR_NONE)
336 return err;
337
338 return MMC_ERR_NONE;
339}
340
320/* 341/*
321 * Ensure that no card is selected. 342 * Ensure that no card is selected.
322 */ 343 */
@@ -526,6 +547,32 @@ static void mmc_decode_csd(struct mmc_card *card)
526} 547}
527 548
528/* 549/*
550 * Given a 64-bit response, decode to our card SCR structure.
551 */
552static void mmc_decode_scr(struct mmc_card *card)
553{
554 struct sd_scr *scr = &card->scr;
555 unsigned int scr_struct;
556 u32 resp[4];
557
558 BUG_ON(!mmc_card_sd(card));
559
560 resp[3] = card->raw_scr[1];
561 resp[2] = card->raw_scr[0];
562
563 scr_struct = UNSTUFF_BITS(resp, 60, 4);
564 if (scr_struct != 0) {
565 printk("%s: unrecognised SCR structure version %d\n",
566 mmc_hostname(card->host), scr_struct);
567 mmc_card_set_bad(card);
568 return;
569 }
570
571 scr->sda_vsn = UNSTUFF_BITS(resp, 56, 4);
572 scr->bus_widths = UNSTUFF_BITS(resp, 48, 4);
573}
574
575/*
529 * Locate a MMC card on this MMC host given a raw CID. 576 * Locate a MMC card on this MMC host given a raw CID.
530 */ 577 */
531static struct mmc_card *mmc_find_card(struct mmc_host *host, u32 *raw_cid) 578static struct mmc_card *mmc_find_card(struct mmc_host *host, u32 *raw_cid)
@@ -789,6 +836,79 @@ static void mmc_read_csds(struct mmc_host *host)
789 } 836 }
790} 837}
791 838
839static void mmc_read_scrs(struct mmc_host *host)
840{
841 int err;
842 struct mmc_card *card;
843
844 struct mmc_request mrq;
845 struct mmc_command cmd;
846 struct mmc_data data;
847
848 struct scatterlist sg;
849
850 list_for_each_entry(card, &host->cards, node) {
851 if (card->state & (MMC_STATE_DEAD|MMC_STATE_PRESENT))
852 continue;
853 if (!mmc_card_sd(card))
854 continue;
855
856 err = mmc_select_card(host, card);
857 if (err != MMC_ERR_NONE) {
858 mmc_card_set_dead(card);
859 continue;
860 }
861
862 memset(&cmd, 0, sizeof(struct mmc_command));
863
864 cmd.opcode = MMC_APP_CMD;
865 cmd.arg = card->rca << 16;
866 cmd.flags = MMC_RSP_R1;
867
868 err = mmc_wait_for_cmd(host, &cmd, 0);
869 if ((err != MMC_ERR_NONE) || !(cmd.resp[0] & R1_APP_CMD)) {
870 mmc_card_set_dead(card);
871 continue;
872 }
873
874 memset(&cmd, 0, sizeof(struct mmc_command));
875
876 cmd.opcode = SD_APP_SEND_SCR;
877 cmd.arg = 0;
878 cmd.flags = MMC_RSP_R1;
879
880 memset(&data, 0, sizeof(struct mmc_data));
881
882 data.timeout_ns = card->csd.tacc_ns * 10;
883 data.timeout_clks = card->csd.tacc_clks * 10;
884 data.blksz_bits = 3;
885 data.blocks = 1;
886 data.flags = MMC_DATA_READ;
887 data.sg = &sg;
888 data.sg_len = 1;
889
890 memset(&mrq, 0, sizeof(struct mmc_request));
891
892 mrq.cmd = &cmd;
893 mrq.data = &data;
894
895 sg_init_one(&sg, (u8*)card->raw_scr, 8);
896
897 err = mmc_wait_for_req(host, &mrq);
898 if (err != MMC_ERR_NONE) {
899 mmc_card_set_dead(card);
900 continue;
901 }
902
903 card->raw_scr[0] = ntohl(card->raw_scr[0]);
904 card->raw_scr[1] = ntohl(card->raw_scr[1]);
905
906 mmc_decode_scr(card);
907 }
908
909 mmc_deselect_cards(host);
910}
911
792static unsigned int mmc_calculate_clock(struct mmc_host *host) 912static unsigned int mmc_calculate_clock(struct mmc_host *host)
793{ 913{
794 struct mmc_card *card; 914 struct mmc_card *card;
@@ -912,6 +1032,9 @@ static void mmc_setup(struct mmc_host *host)
912 host->ops->set_ios(host, &host->ios); 1032 host->ops->set_ios(host, &host->ios);
913 1033
914 mmc_read_csds(host); 1034 mmc_read_csds(host);
1035
1036 if (host->mode == MMC_MODE_SD)
1037 mmc_read_scrs(host);
915} 1038}
916 1039
917 1040