Beispiel #1
0
/*
 * This is the only exported function
 *
 * Call it with the MCI register base address
 */
int atmel_mci_init(void *regs)
{
	struct mmc *mmc = malloc(sizeof(struct mmc));

	if (!mmc)
		return -1;
	strcpy(mmc->name, "mci");
	mmc->priv = regs;
	mmc->send_cmd = mci_send_cmd;
	mmc->set_ios = mci_set_ios;
	mmc->init = mci_init;
	mmc->getcd = NULL;
	mmc->getwp = NULL;

	/* need to be able to pass these in on a board by board basis */
	mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
	mmc->host_caps = MMC_MODE_4BIT;
	/*
	 * min and max frequencies determined by
	 * max and min of clock divider
	 */
	mmc->f_min = get_mci_clk_rate() / (2*256);
	mmc->f_max = get_mci_clk_rate() / (2*1);

	mmc->b_max = 0;

	mmc_register(mmc);

	return 0;
}
Beispiel #2
0
/* Setup for MCI Clock and Block Size */
static void mci_set_mode(struct mmc *mmc, u32 hz, u32 blklen)
{
	atmel_mci_t *mci = (atmel_mci_t *)mmc->priv;
	u32 bus_hz = get_mci_clk_rate();
	u32 clkdiv = 255;

	debug("mci: bus_hz is %u, setting clock %u Hz, block size %u\n",
		bus_hz, hz, blklen);
	if (hz > 0) {
		/* find lowest clkdiv yielding a rate <= than requested */
		for (clkdiv=0; clkdiv<255; clkdiv++) {
			if ((bus_hz / (clkdiv+1) / 2) <= hz)
				break;
		}
	}
	printf("mci: setting clock %u Hz, block size %u\n",
		(bus_hz / (clkdiv+1)) / 2, blklen);

	blklen &= 0xfffc;
	/* On some platforms RDPROOF and WRPROOF are ignored */
	writel((MMCI_BF(CLKDIV, clkdiv)
		 | MMCI_BF(BLKLEN, blklen)
		 | MMCI_BIT(RDPROOF)
		 | MMCI_BIT(WRPROOF)), &mci->mr);
	/*
	 * On some new platforms BLKLEN in mci->mr is ignored.
	 * Should use the BLKLEN in the block register.
	 */
	writel(MMCI_BF(BLKLEN, blklen), &mci->blkr);
	initialized = 1;
}
/* Setup for MCI Clock and Block Size */
static void mci_set_mode(struct mmc *mmc, u32 hz, u32 blklen)
{
	struct atmel_mci_priv *priv = mmc->priv;
	atmel_mci_t *mci = priv->mci;
	u32 bus_hz = get_mci_clk_rate();
	u32 clkdiv = 255;
	unsigned int version = atmel_mci_get_version(mci);
	u32 clkodd = 0;
	u32 mr;

	debug("mci: bus_hz is %u, setting clock %u Hz, block size %u\n",
		bus_hz, hz, blklen);
	if (hz > 0) {
		if (version >= 0x500) {
			clkdiv = DIV_ROUND_UP(bus_hz, hz) - 2;
			if (clkdiv > 511)
				clkdiv = 511;

			clkodd = clkdiv & 1;
			clkdiv >>= 1;

			debug("mci: setting clock %u Hz, block size %u\n",
			      bus_hz / (clkdiv * 2 + clkodd + 2), blklen);
		} else {
			/* find clkdiv yielding a rate <= than requested */
			for (clkdiv = 0; clkdiv < 255; clkdiv++) {
static void mci_set_mode(unsigned long hz, unsigned long blklen)
{
	unsigned long bus_hz;
	unsigned long clkdiv;

	bus_hz = get_mci_clk_rate();
	clkdiv = (bus_hz / hz) / 2 - 1;

	pr_debug("mmc: setting clock %lu Hz, block size %lu\n",
		 hz, blklen);

	if (clkdiv & ~255UL) {
		clkdiv = 255;
		printf("mmc: clock %lu too low; setting CLKDIV to 255\n",
			hz);
	}

	blklen &= 0xfffc;
	mmci_writel(MR, (MMCI_BF(CLKDIV, clkdiv)
			 | MMCI_BF(BLKLEN, blklen)
			 | MMCI_BIT(RDPROOF)
			 | MMCI_BIT(WRPROOF)));
}