Пример #1
0
static int mmc_config_clock(struct mmc *mmc, unsigned clk)
{
	struct sunxi_mmc_host* mmchost = (struct sunxi_mmc_host *)mmc->priv;
	unsigned rval = readl(&mmchost->reg->clkcr);
//	unsigned int clkdiv = 0;

	/* Disable Clock */
	rval &= ~(1 << 16);
	writel(rval, &mmchost->reg->clkcr);
	if(mmc_update_clk(mmc)){
		mmcinfo("mmc %d disable clock failed\n",mmchost ->mmc_no);
		return -1;
	}

//	clkdiv = mmchost->mclk/clk/2;
	//disable mclk first
	writel(0,mmchost->mclkbase);
	mmcdbg("mmc %d mclkbase %x\n",mmchost ->mmc_no,readl(mmchost->mclkbase));
	if (clk <=400000) {
	    mmchost->mclk = 400000;
	    writel(0x0002000f, mmchost->mclkbase);
	    mmcdbg("mmc %d mclkbase%x\n",mmchost ->mmc_no,readl(mmchost->mclkbase));
	} else {
	    mmchost->mclk = 12000000;
	    writel(0x00000001, mmchost->mclkbase);
	    mmcdbg("mmc %d mclkbase%x\n",mmchost ->mmc_no,readl(mmchost->mclkbase));
	}
	//re-enable mclk
	writel(readl(mmchost->mclkbase)|(1<<31),mmchost->mclkbase);
	mmcdbg("mmc %d mclkbase%x\n",mmchost ->mmc_no,readl(mmchost->mclkbase));
	/*
	 * CLKCREG[7:0]: divider
	 * CLKCREG[16]:  on/off
	 * CLKCREG[17]:  power save
	 */
	/* Change Divider Factor */
	rval &= ~(0xFF);
	writel(rval, &mmchost->reg->clkcr);
	if(mmc_update_clk(mmc)){
		mmcinfo("mmc %d Change Divider Factor failed\n",mmchost ->mmc_no);
		return -1;
    }
	/* Re-enable Clock */
	rval |= (3 << 16);
	writel(rval, &mmchost->reg->clkcr);
	if(mmc_update_clk(mmc)){
		mmcinfo("mmc %d re-enable clock failed\n",mmchost ->mmc_no);
		return -1;
	}
	return 0;
}
static int mmc_update_phase(struct mmc *mmc)
{
	struct sunxi_mmc_host* mmchost = (struct sunxi_mmc_host *)mmc->priv;

	if (mmchost->timing_mode == SUNXI_MMC_TIMING_MODE_1)
	{
		MMCDBG("mmc re-update_phase\n");
		return mmc_update_clk(mmchost);
	}

	return 0;
}