changes as below:

1. update the nandlib to use pll6 as the clk source.
2. update the mmc driver clk config.
This commit is contained in:
zhengjiewen
2013-02-04 16:47:16 +08:00
parent 57e0c8e05e
commit 73a6c733ef
3 changed files with 134 additions and 25 deletions

View File

@ -42,11 +42,11 @@ void fastboot_flash_partition_init(void)
{
fastboot_ptentry fb_part;
int index, part_total;
char partition_sets[512];
char partition_sets[1024];
char part_name[32];
char *pa_index;
int part_name_count;
printf("--------fastboot partitions--------\n");
part_total = sunxi_partition_get_total_num();
if((part_total <= 0) || (part_total > MBR_MAX_PART_COUNT))

View File

@ -127,6 +127,117 @@ struct sunxi_mmc_host {
struct mmc mmc_dev[4];
struct sunxi_mmc_host mmc_host[4];
u32 ccm_get_pll5_dev_clk(void)
{
u32 rval = 0;
u32 n, k,p;
u32 pll5_clk = 0;
rval = readl(SUNXI_CCM_PLL5_CFG);
n = (rval >> 8) & 0x1f;
k = ((rval >> 4) & 3) + 1;
p = 1 << ((rval >> 16) & 3);
pll5_clk = 24000000 * n * k / p;
return pll5_clk;
}
u32 ccm_get_pll6_dev_clk(void)
{
u32 rval = 0;
u32 n, k;
u32 pll6_clk = 0;
rval = readl(SUNXI_CCM_PLL6_CFG);
n = (rval >> 8) & 0x1f;
k = ((rval >> 4) & 3) + 1;
pll6_clk = (24000000 * n * k)>>1;
return pll6_clk;
}
s32 smc_set_card_clk(u32 smc_no, u32 cclk,u32 bus_width)
{
struct sunxi_mmc_host* mmchost = &mmc_host[smc_no];
u32 sclk = 24000000;
u32 div;
u32 rval;
u32 src = 0;
u32 mclk_base = mmchost->mclkbase;
u32 m, n;
u32 outclk_pha = 0;
u32 samclk_pha = 0;
if (cclk > 400000) {
src = 2;//change to you select source:0->LOSC24M;1->PLL6;2->PLL5.
sclk = ccm_get_pll5_dev_clk(); //change to you select source clock
outclk_pha = 0;
samclk_pha = 0;
}else{
src = 0;
sclk = 24000000;
outclk_pha = 0;
samclk_pha = 0;
}
div = (2 * sclk + cclk) / (2 * cclk);
div = div==0 ? 1 : div;
if (div > 128) {
m = 1;
n = 0;
MMCDBG("Source clock is too high\n");
} else if (div > 64) {
n = 3;
m = div >> 3;
} else if (div > 32) {
n = 2;
m = div >> 2;
} else if (div > 16) {
n = 1;
m = div >> 1;
} else {
n = 0;
m = div;
}
rval = (1U << 31) | (src << 24) | (samclk_pha << 20)
| (n << 16) | (outclk_pha << 8) | (m - 1);
writel(rval, mclk_base);
/* clear internal divider */
rval = readl(&mmchost->reg->clkcr) & (~0xff);
writel(rval, &mmchost->reg->clkcr);
switch(n)
{
case 0:
mmchost->mod_clk = sclk/1/m;
MMCDBG("Card clock=%d\n",sclk/1/m);
break;
case 1:
mmchost->mod_clk = sclk/2/m;
MMCDBG("Card clock=%d\n",sclk/2/m);
break;
case 2:
mmchost->mod_clk = sclk/4/m;
MMCDBG("Card clock=%d\n",sclk/4/m);
break;
case 3:
mmchost->mod_clk = sclk/8/m;
MMCDBG("Card clock=%d\n",sclk/8/m);
break;
default:
break;
}
//dumphex32("ccmu", (char*)0x01c20000, 0x100);
return cclk;
}
static int mmc_resource_init(int sdc_no)
{
struct sunxi_mmc_host* mmchost = &mmc_host[sdc_no];
@ -213,20 +324,21 @@ static int mmc_clk_io_on(int sdc_no)
writel(rval, mmchost->hclkbase);
/* config mod clock */
rval = readl(SUNXI_CCM_PLL5_CFG);
n = (rval >> 8) & 0x1f;
k = ((rval >> 4) & 3) + 1;
p = 1 << ((rval >> 16) & 3);
pll5_clk = 24000000 * n * k / p;
MMCDBG("PLL5 clock=%d\n",pll5_clk);
if (pll5_clk > 400000000)
divider = 4;
else
divider = 3;
//is there some problem ??? the phease is zero
writel((1U << 31) | (2U << 24) | divider, mmchost->mclkbase);
mmchost->mod_clk = pll5_clk / (divider + 1);
MMCDBG("mmchost->mod_clk=%d\n",mmchost->mod_clk);
// rval = readl(SUNXI_CCM_PLL5_CFG);
// n = (rval >> 8) & 0x1f;
// k = ((rval >> 4) & 3) + 1;
// p = 1 << ((rval >> 16) & 3);
// pll5_clk = 24000000 * n * k / p;
// MMCDBG("PLL5 clock=%d\n",pll5_clk);
// if (pll5_clk > 400000000)
// divider = 4;
// else
// divider = 3;
// //is there some problem ??? the phease is zero
// writel((1U << 31) | (2U << 24) | divider, mmchost->mclkbase);
// mmchost->mod_clk = pll5_clk / (divider + 1);
smc_set_card_clk(sdc_no,400000,1);
MMCDBG("mmchost->mod_clk=%d\n",mmchost->mod_clk);
dumphex32("ccmu", (char*)SUNXI_CCM_BASE, 0x100);
dumphex32("gpio", (char*)SUNXI_PIO_BASE, 0x100);
dumphex32("mmc", (char*)mmchost->reg, 0x100);
@ -249,7 +361,7 @@ static int mmc_update_clk(struct mmc *mmc)
return 0;
}
static int mmc_config_clock(struct mmc *mmc, unsigned div)
static int mmc_config_clock(struct mmc *mmc)
{
struct sunxi_mmc_host* mmchost = (struct sunxi_mmc_host *)mmc->priv;
unsigned rval = readl(&mmchost->reg->clkcr);
@ -264,12 +376,9 @@ static int mmc_config_clock(struct mmc *mmc, unsigned div)
writel(rval, &mmchost->reg->clkcr);
if(mmc_update_clk(mmc))
return -1;
/* Change Divider Factor */
rval &= ~(0xFF);
rval |= div;
writel(rval, &mmchost->reg->clkcr);
if(mmc_update_clk(mmc))
return -1;
smc_set_card_clk(mmchost->mmc_no,mmc->clock,mmc->bus_width);
/* Re-enable Clock */
rval |= (1 << 16);
writel(rval, &mmchost->reg->clkcr);
@ -286,9 +395,9 @@ static void mmc_set_ios(struct mmc *mmc)
MMCDBG("set ios: bus_width: %x, clock: %d, mod_clk\n", mmc->bus_width, mmc->clock, mmchost->mod_clk);
/* Change clock first */
clkdiv = (mmchost->mod_clk + (mmc->clock>>1))/mmc->clock/2;
//clkdiv = (mmchost->mod_clk + (mmc->clock>>1))/mmc->clock/2;
if (mmc->clock)
if (mmc_config_clock(mmc, clkdiv)) {
if (mmc_config_clock(mmc)) {
mmchost->fatal_err = 1;
return;
}

BIN
nand_sunxi/libnand Normal file → Executable file

Binary file not shown.