Skip to content

Commit 1e2d42e

Browse files
committed
sdhctrl: use a 4bit bus
1 parent 9bb8946 commit 1e2d42e

File tree

3 files changed

+62
-35
lines changed

3 files changed

+62
-35
lines changed

sdhc.c

+19-27
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,6 @@ int sdhc_host_maxblklen(sdmmc_chipset_handle_t);
131131
int sdhc_card_detect(sdmmc_chipset_handle_t);
132132
int sdhc_bus_power(sdmmc_chipset_handle_t, u_int32_t);
133133
int sdhc_bus_clock(sdmmc_chipset_handle_t, int);
134-
void sdhc_card_intr_mask(sdmmc_chipset_handle_t, int);
135-
void sdhc_card_intr_ack(sdmmc_chipset_handle_t);
136134
void sdhc_exec_command(sdmmc_chipset_handle_t, struct sdmmc_command *);
137135
int sdhc_start_command(struct sdhc_host *, struct sdmmc_command *);
138136
int sdhc_wait_state(struct sdhc_host *, u_int32_t, u_int32_t);
@@ -141,6 +139,7 @@ int sdhc_wait_intr(struct sdhc_host *, int, int);
141139
void sdhc_transfer_data(struct sdhc_host *, struct sdmmc_command *);
142140
void sdhc_read_data(struct sdhc_host *, u_char *, int);
143141
void sdhc_write_data(struct sdhc_host *, u_char *, int);
142+
void sdhc_set_bus_width(sdmmc_chipset_handle_t, int);
144143

145144
#ifdef SDHC_DEBUG
146145
int sdhcdebug = 2;
@@ -163,9 +162,7 @@ struct sdmmc_chip_functions sdhc_functions = {
163162
sdhc_bus_clock,
164163
/* command execution */
165164
sdhc_exec_command,
166-
/* card interrupt */
167-
sdhc_card_intr_mask,
168-
sdhc_card_intr_ack
165+
sdhc_set_bus_width,
169166
};
170167

171168
/*
@@ -556,28 +553,6 @@ sdhc_bus_clock(sdmmc_chipset_handle_t sch, int freq)
556553
return error;
557554
}
558555

559-
void
560-
sdhc_card_intr_mask(sdmmc_chipset_handle_t sch, int enable)
561-
{
562-
struct sdhc_host *hp = sch;
563-
564-
if (enable) {
565-
HSET2(hp, SDHC_NINTR_STATUS_EN, SDHC_CARD_INTERRUPT);
566-
HSET2(hp, SDHC_NINTR_SIGNAL_EN, SDHC_CARD_INTERRUPT);
567-
} else {
568-
HCLR2(hp, SDHC_NINTR_SIGNAL_EN, SDHC_CARD_INTERRUPT);
569-
HCLR2(hp, SDHC_NINTR_STATUS_EN, SDHC_CARD_INTERRUPT);
570-
}
571-
}
572-
573-
void
574-
sdhc_card_intr_ack(sdmmc_chipset_handle_t sch)
575-
{
576-
struct sdhc_host *hp = sch;
577-
578-
HSET2(hp, SDHC_NINTR_STATUS_EN, SDHC_CARD_INTERRUPT);
579-
}
580-
581556
int
582557
sdhc_wait_state(struct sdhc_host *hp, u_int32_t mask, u_int32_t value)
583558
{
@@ -830,6 +805,23 @@ sdhc_transfer_data(struct sdhc_host *hp, struct sdmmc_command *cmd)
830805
return;
831806
}
832807

808+
void
809+
sdhc_set_bus_width(sdmmc_chipset_handle_t sch, int enable)
810+
{
811+
struct sdhc_host *hp = sch;
812+
u_int16_t hctl;
813+
814+
hctl = HREAD2(hp, SDHC_HOST_CTL);
815+
816+
if (enable)
817+
hctl |= SDHC_4BIT_MODE;
818+
else
819+
hctl &= ~SDHC_4BIT_MODE;
820+
821+
HWRITE2(hp, SDHC_HOST_CTL, hctl);
822+
823+
}
824+
833825
/* Prepare for another command. */
834826
int
835827
sdhc_soft_reset(struct sdhc_host *hp, int mask)

sdmmc.c

+38
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,11 @@ static inline void sdmmc_host_exec_command(struct sdmmc_card *card, struct
8282
{
8383
sdmmc_chip_exec_command(card->functions, card->handle, cmd);
8484
}
85+
static inline void sdmmc_host_set_bus_width(struct sdmmc_card *card, int
86+
enable)
87+
{
88+
sdmmc_chip_set_bus_width(card->functions, card->handle, enable);
89+
}
8590

8691
struct device *sdmmc_attach(struct sdmmc_chip_functions *functions,
8792
sdmmc_chipset_handle_t handle, const char *name, int no)
@@ -307,6 +312,7 @@ void sdmmc_needs_discover(struct device *dev)
307312
}
308313

309314
sdmmc_select(dev);
315+
310316
DPRINTF(2, ("sdmmc: MMC_SET_BLOCKLEN\n"));
311317
memset(&cmd, 0, sizeof(cmd));
312318
cmd.c_opcode = MMC_SET_BLOCKLEN;
@@ -319,11 +325,43 @@ void sdmmc_needs_discover(struct device *dev)
319325
c->inserted = c->selected = 0;
320326
goto out_clock;
321327
}
328+
329+
/* we can assume that every card supports a 4bit bus
330+
* (see Simplified Physical Layer Spec, 5.6 SCR register (page 90),
331+
* SD_BUS_WIDTHS)
332+
*/
333+
memset(&cmd, 0, sizeof(cmd));
334+
cmd.c_opcode = MMC_APP_CMD;
335+
cmd.c_arg = ((u32)c->rca)<<16;
336+
cmd.c_flags = SCF_RSP_R1;
337+
sdmmc_host_exec_command(c, &cmd);
338+
339+
if (cmd.c_error) {
340+
gecko_printf("sdmmc: MMC_APP_CMD failed for "
341+
"card %d with %d\n", no, cmd.c_error);
342+
goto out_power;
343+
}
344+
345+
memset(&cmd, 0, sizeof(cmd));
346+
cmd.c_opcode = SD_APP_SET_BUS_WIDTH;
347+
cmd.c_arg = SD_ARG_BUS_WIDTH_4;
348+
cmd.c_flags = SCF_RSP_R1;
349+
sdmmc_host_exec_command(c, &cmd);
350+
if (cmd.c_error) {
351+
gecko_printf("sdmmc: SD_APP_SET_BUS_WIDTH failed for "
352+
"card %d with %d\n", no, cmd.c_error);
353+
goto out_power;
354+
}
355+
356+
sdmmc_host_set_bus_width(c, 1);
357+
322358
return;
323359

324360
out_clock:
325361
out_power:
362+
c->inserted = c->selected = 0;
326363
sdmmc_host_power(c, 0);
364+
sdmmc_host_reset(c);
327365
out:
328366
return;
329367

sdmmcchip.h

+5-8
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,8 @@ struct sdmmc_chip_functions {
3838
/* command execution */
3939
void (*exec_command)(sdmmc_chipset_handle_t,
4040
struct sdmmc_command *);
41-
/* card interrupt */
42-
void (*card_intr_mask)(sdmmc_chipset_handle_t, int);
43-
void (*card_intr_ack)(sdmmc_chipset_handle_t);
41+
/* bus width */
42+
void (*set_bus_width)(sdmmc_chipset_handle_t, int);
4443
};
4544

4645
/* host controller reset */
@@ -62,11 +61,9 @@ struct sdmmc_chip_functions {
6261
/* command execution */
6362
#define sdmmc_chip_exec_command(tag, handle, cmdp) \
6463
((tag)->exec_command((handle), (cmdp)))
65-
/* card interrupt */
66-
#define sdmmc_chip_card_intr_mask(tag, handle, enable) \
67-
((tag)->card_intr_mask((handle), (enable)))
68-
#define sdmmc_chip_card_intr_ack(tag, handle) \
69-
((tag)->card_intr_ack((handle)))
64+
/* bus widht */
65+
#define sdmmc_chip_set_bus_width(tag, handle, enable) \
66+
((tag)->set_bus_width((handle), (enable)))
7067

7168
/* clock frequencies for sdmmc_chip_bus_clock() */
7269
#define SDMMC_SDCLK_OFF 0

0 commit comments

Comments
 (0)