コード例 #1
0
ファイル: sdhi-shmobile.c プロジェクト: 01org/KVMGT-kernel
static int sdhi_intr(void __iomem *base)
{
	unsigned long state = sd_ctrl_read32(base, CTL_STATUS);

	if (state & ALL_ERROR) {
		sd_ctrl_write32(base, CTL_STATUS, ~ALL_ERROR);
		sd_ctrl_write32(base, CTL_IRQ_MASK,
				ALL_ERROR |
				sd_ctrl_read32(base, CTL_IRQ_MASK));
		return -EINVAL;
	}
	if (state & TMIO_STAT_CMDRESPEND) {
		sd_ctrl_write32(base, CTL_STATUS, ~TMIO_STAT_CMDRESPEND);
		sd_ctrl_write32(base, CTL_IRQ_MASK,
				TMIO_STAT_CMDRESPEND |
				sd_ctrl_read32(base, CTL_IRQ_MASK));
		return 0;
	}
	if (state & TMIO_STAT_RXRDY) {
		sd_ctrl_write32(base, CTL_STATUS, ~TMIO_STAT_RXRDY);
		sd_ctrl_write32(base, CTL_IRQ_MASK,
				TMIO_STAT_RXRDY | TMIO_STAT_TXUNDERRUN |
				sd_ctrl_read32(base, CTL_IRQ_MASK));
		return 0;
	}
	if (state & TMIO_STAT_DATAEND) {
		sd_ctrl_write32(base, CTL_STATUS, ~TMIO_STAT_DATAEND);
		sd_ctrl_write32(base, CTL_IRQ_MASK,
				TMIO_STAT_DATAEND |
				sd_ctrl_read32(base, CTL_IRQ_MASK));
		return 0;
	}

	return -EAGAIN;
}
コード例 #2
0
ファイル: sdhi-shmobile.c プロジェクト: 01org/KVMGT-kernel
static int sdhi_boot_request(void __iomem *base, struct mmc_command *cmd)
{
	int err, c = cmd->opcode;

	switch (mmc_resp_type(cmd)) {
	case MMC_RSP_NONE: c |= RESP_NONE; break;
	case MMC_RSP_R1:   c |= RESP_R1;   break;
	case MMC_RSP_R1B:  c |= RESP_R1B;  break;
	case MMC_RSP_R2:   c |= RESP_R2;   break;
	case MMC_RSP_R3:   c |= RESP_R3;   break;
	default:
		return -EINVAL;
	}

	/* No interrupts so this may not be cleared */
	sd_ctrl_write32(base, CTL_STATUS, ~TMIO_STAT_CMDRESPEND);

	sd_ctrl_write32(base, CTL_IRQ_MASK, TMIO_STAT_CMDRESPEND |
			sd_ctrl_read32(base, CTL_IRQ_MASK));
	sd_ctrl_write32(base, CTL_ARG_REG, cmd->arg);
	sd_ctrl_write16(base, CTL_SD_CMD, c);


	sd_ctrl_write32(base, CTL_IRQ_MASK,
			~(TMIO_STAT_CMDRESPEND | ALL_ERROR) &
			sd_ctrl_read32(base, CTL_IRQ_MASK));

	err = sdhi_boot_wait_resp_end(base);
	if (err)
		return err;

	cmd->resp[0] = sd_ctrl_read32(base, CTL_RESPONSE);

	return 0;
}
コード例 #3
0
ファイル: sdhi-shmobile.c プロジェクト: 01org/KVMGT-kernel
/* Set MMC clock / power.
 * Note: This controller uses a simple divider scheme therefore it cannot
 * run a MMC card at full speed (20MHz). The max clock is 24MHz on SD, but as
 * MMC wont run that fast, it has to be clocked at 12MHz which is the next
 * slowest setting.
 */
static int sdhi_boot_mmc_set_ios(void __iomem *base, struct mmc_ios *ios)
{
	if (sd_ctrl_read32(base, CTL_STATUS) & TMIO_STAT_CMD_BUSY)
		return -EBUSY;

	if (ios->clock)
		sd_ctrl_write16(base, CTL_SD_CARD_CLK_CTL,
				ios->clock | CLK_MMC_ENABLE);

	/* Power sequence - OFF -> ON -> UP */
	switch (ios->power_mode) {
	case MMC_POWER_OFF: /* power down SD bus */
		sdhi_boot_mmc_clk_stop(base);
		break;
	case MMC_POWER_ON: /* power up SD bus */
		break;
	case MMC_POWER_UP: /* start bus clock */
		sdhi_boot_mmc_clk_start(base);
		break;
	}

	switch (ios->bus_width) {
	case MMC_BUS_WIDTH_1:
		sd_ctrl_write16(base, CTL_SD_MEM_CARD_OPT, 0x80e0);
	break;
	case MMC_BUS_WIDTH_4:
		sd_ctrl_write16(base, CTL_SD_MEM_CARD_OPT, 0x00e0);
	break;
	}

	/* Let things settle. delay taken from winCE driver */
	udelay(140);

	return 0;
}
コード例 #4
0
ファイル: sdhi-shmobile.c プロジェクト: 01org/KVMGT-kernel
static int sdhi_boot_do_read_single(void __iomem *base, int high_capacity,
				    unsigned long block, unsigned short *buf)
{
	int err, i;

	/* CMD17 - Read */
	{
		struct mmc_command cmd;

		cmd.opcode = MMC_READ_SINGLE_BLOCK | \
			     TRANSFER_READ | DATA_PRESENT;
		if (high_capacity)
			cmd.arg = block;
		else
			cmd.arg = block * TMIO_BBS;
		cmd.flags = MMC_RSP_R1;
		err = sdhi_boot_request(base, &cmd);
		if (err)
			return err;
	}

	sd_ctrl_write32(base, CTL_IRQ_MASK,
			~(TMIO_STAT_DATAEND | TMIO_STAT_RXRDY |
			  TMIO_STAT_TXUNDERRUN) &
			sd_ctrl_read32(base, CTL_IRQ_MASK));
	err = sdhi_boot_wait_resp_end(base);
	if (err)
		return err;

	sd_ctrl_write16(base, CTL_SD_XFER_LEN, TMIO_BBS);
	for (i = 0; i < TMIO_BBS / sizeof(*buf); i++)
		*buf++ = sd_ctrl_read16(base, RESP_CMD12);

	err = sdhi_boot_wait_resp_end(base);
	if (err)
		return err;

	return 0;
}
コード例 #5
0
void tmio_mmc_disable_mmc_irqs(struct tmio_mmc_host *host, u32 i)
{
	u32 mask = sd_ctrl_read32(host, CTL_IRQ_MASK) | (i & TMIO_MASK_IRQ);
	sd_ctrl_write32(host, CTL_IRQ_MASK, mask);
}