summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason <r64343@freescale.com>2010-03-25 15:36:28 +0800
committerJason <r64343@freescale.com>2010-03-25 19:46:28 +0800
commit46b29af149c186ed5097ba2b4cc13c2f0d5d0c35 (patch)
tree2e3c4bf595f831ae6533aacaeb96c425633d71e1
parent1842946ef735d969e99be097812bbc383e7f8dc1 (diff)
downloadu-boot-imx-46b29af149c186ed5097ba2b4cc13c2f0d5d0c35.zip
u-boot-imx-46b29af149c186ed5097ba2b4cc13c2f0d5d0c35.tar.gz
u-boot-imx-46b29af149c186ed5097ba2b4cc13c2f0d5d0c35.tar.bz2
ENGR00121976 UBOOT: some fix for SD/MMC card
-Update eSDHC clock setting, -Fix the GPT timer setting, -Fix the boot option pars, -Remove mdelay() function call to improve the performance Signed-off-by:Jason Liu <r64343@freescale.com>
-rw-r--r--board/freescale/mx53_evk/mx53_evk.c49
-rw-r--r--cpu/arm_cortexa8/mx53/generic.c111
-rw-r--r--cpu/arm_cortexa8/mx53/timer.c4
-rw-r--r--drivers/mmc/imx_esdhc.c16
-rw-r--r--include/asm-arm/arch-mx53/mx53.h13
5 files changed, 170 insertions, 23 deletions
diff --git a/board/freescale/mx53_evk/mx53_evk.c b/board/freescale/mx53_evk/mx53_evk.c
index ceef3c3..4804b02 100644
--- a/board/freescale/mx53_evk/mx53_evk.c
+++ b/board/freescale/mx53_evk/mx53_evk.c
@@ -57,15 +57,34 @@ static inline void setup_boot_device(void)
uint bt_mem_type = (soc_sbmr & 0x00000008) >> 3;
switch (bt_mem_ctl) {
- case 0x4:
- boot_dev = MMC_BOOT;
+ case 0x0:
+ if (bt_mem_type)
+ boot_dev = ONE_NAND_BOOT;
+ else
+ boot_dev = WEIM_NOR_BOOT;
break;
- case 0x8:
- boot_dev = NAND_BOOT;
+ case 0x2:
+ if (bt_mem_type)
+ boot_dev = SATA_BOOT;
+ else
+ boot_dev = PATA_BOOT;
break;
case 0x3:
if (bt_mem_type)
boot_dev = SPI_NOR_BOOT;
+ else
+ boot_dev = I2C_BOOT;
+ break;
+ case 0x4:
+ case 0x5:
+ boot_dev = SD_BOOT;
+ break;
+ case 0x6:
+ case 0x7:
+ boot_dev = MMC_BOOT;
+ break;
+ case 0x8 ... 0xf:
+ boot_dev = NAND_BOOT;
break;
default:
boot_dev = UNKNOWN_BOOT;
@@ -505,15 +524,33 @@ int checkboard(void)
printf("Boot Device: ");
switch (get_boot_device()) {
- case NAND_BOOT:
- printf("NAND\n");
+ case WEIM_NOR_BOOT:
+ printf("NOR\n");
+ break;
+ case ONE_NAND_BOOT:
+ printf("ONE NAND\n");
+ break;
+ case PATA_BOOT:
+ printf("PATA\n");
+ break;
+ case SATA_BOOT:
+ printf("SATA\n");
+ break;
+ case I2C_BOOT:
+ printf("I2C\n");
break;
case SPI_NOR_BOOT:
printf("SPI NOR\n");
break;
+ case SD_BOOT:
+ printf("SD\n");
+ break;
case MMC_BOOT:
printf("MMC\n");
break;
+ case NAND_BOOT:
+ printf("NAND\n");
+ break;
case UNKNOWN_BOOT:
default:
printf("UNKNOWN\n");
diff --git a/cpu/arm_cortexa8/mx53/generic.c b/cpu/arm_cortexa8/mx53/generic.c
index f75d15a..cdd9d7c 100644
--- a/cpu/arm_cortexa8/mx53/generic.c
+++ b/cpu/arm_cortexa8/mx53/generic.c
@@ -116,7 +116,7 @@ static u32 __get_ipg_per_clk(void)
/*!
* This function returns the low power audio clock.
*/
-static u32 get_lp_apm(void)
+static u32 __get_lp_apm(void)
{
u32 ret_val = 0;
u32 ccsr = __REG(MXC_CCM_CCSR);
@@ -145,7 +145,7 @@ static u32 __get_uart_clk(void)
freq = __decode_pll(PLL3_CLK, CONFIG_MX53_HCLK_FREQ);
break;
case 0x4:
- freq = get_lp_apm();
+ freq = __get_lp_apm();
break;
default:
break;
@@ -190,7 +190,7 @@ static u32 __get_cspi_clk(void)
ret_val = __decode_pll(PLL3_CLK, CONFIG_MX53_HCLK_FREQ) / div;
break;
default:
- ret_val = get_lp_apm() / div;
+ ret_val = __get_lp_apm() / div;
break;
}
@@ -265,7 +265,100 @@ static u32 __get_ddr_clk(void)
return ret_val;
}
+static u32 __get_esdhc1_clk(void)
+{
+ u32 ret_val = 0, div, pre_pdf, pdf;
+ u32 cscmr1 = __REG(MXC_CCM_CSCMR1);
+ u32 cscdr1 = __REG(MXC_CCM_CSCDR1);
+ u32 esdh1_clk_sel;
+
+ esdh1_clk_sel = (cscmr1 & MXC_CCM_CSCMR1_ESDHC1_MSHC1_CLK_SEL_MASK) \
+ >> MXC_CCM_CSCMR1_ESDHC1_MSHC1_CLK_SEL_OFFSET;
+ pre_pdf = (cscdr1 & MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_MASK) \
+ >> MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_OFFSET;
+ pdf = (cscdr1 & MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PODF_MASK) \
+ >> MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PODF_OFFSET ;
+
+ div = (pre_pdf + 1) * (pdf + 1);
+
+ switch (esdh1_clk_sel) {
+ case 0:
+ ret_val = __decode_pll(PLL1_CLK, CONFIG_MX53_HCLK_FREQ);
+ break;
+ case 1:
+ ret_val = __decode_pll(PLL2_CLK, CONFIG_MX53_HCLK_FREQ);
+ break;
+ case 2:
+ ret_val = __decode_pll(PLL3_CLK, CONFIG_MX53_HCLK_FREQ);
+ break;
+ case 3:
+ ret_val = __get_lp_apm();
+ break;
+ default:
+ break;
+ }
+
+ ret_val /= div;
+
+ return ret_val;
+}
+
+static u32 __get_esdhc3_clk(void)
+{
+ u32 ret_val = 0, div, pre_pdf, pdf;
+ u32 esdh3_clk_sel;
+ u32 cscmr1 = __REG(MXC_CCM_CSCMR1);
+ u32 cscdr1 = __REG(MXC_CCM_CSCDR1);
+ esdh3_clk_sel = (cscmr1 & MXC_CCM_CSCMR1_ESDHC3_MSHC2_CLK_SEL_MASK) \
+ >> MXC_CCM_CSCMR1_ESDHC3_MSHC2_CLK_SEL_OFFSET;
+ pre_pdf = (cscdr1 & MXC_CCM_CSCDR1_ESDHC3_MSHC2_CLK_PRED_MASK) \
+ >> MXC_CCM_CSCDR1_ESDHC3_MSHC2_CLK_PRED_OFFSET;
+ pdf = (cscdr1 & MXC_CCM_CSCDR1_ESDHC3_MSHC2_CLK_PODF_MASK) \
+ >> MXC_CCM_CSCDR1_ESDHC3_MSHC2_CLK_PODF_OFFSET ;
+
+ div = (pre_pdf + 1) * (pdf + 1);
+ switch (esdh3_clk_sel) {
+ case 0:
+ ret_val = __decode_pll(PLL1_CLK, CONFIG_MX53_HCLK_FREQ);
+ break;
+ case 1:
+ ret_val = __decode_pll(PLL2_CLK, CONFIG_MX53_HCLK_FREQ);
+ break;
+ case 2:
+ ret_val = __decode_pll(PLL3_CLK, CONFIG_MX53_HCLK_FREQ);
+ break;
+ case 3:
+ ret_val = __get_lp_apm();
+ break;
+ default:
+ break;
+ }
+
+ ret_val /= div;
+
+ return ret_val;
+}
+
+static u32 __get_esdhc2_clk(void)
+{
+ u32 cscmr1 = __REG(MXC_CCM_CSCMR1);
+ u32 esdh2_clk_sel = cscmr1 & MXC_CCM_CSCMR1_ESDHC2_CLK_SEL;
+ if (esdh2_clk_sel)
+ return __get_esdhc3_clk();
+
+ return __get_esdhc1_clk();
+}
+
+static u32 __get_esdhc4_clk(void)
+{
+ u32 cscmr1 = __REG(MXC_CCM_CSCMR1);
+ u32 esdh4_clk_sel = cscmr1 & MXC_CCM_CSCMR1_ESDHC4_CLK_SEL;
+ if (esdh4_clk_sel)
+ return __get_esdhc3_clk();
+
+ return __get_esdhc1_clk();
+}
unsigned int mxc_get_clock(enum mxc_clock clk)
{
switch (clk) {
@@ -290,7 +383,13 @@ unsigned int mxc_get_clock(enum mxc_clock clk)
case MXC_DDR_CLK:
return __get_ddr_clk();
case MXC_ESDHC_CLK:
- return __decode_pll(PLL3_CLK, CONFIG_MX53_HCLK_FREQ);
+ return __get_esdhc1_clk();
+ case MXC_ESDHC2_CLK:
+ return __get_esdhc2_clk();
+ case MXC_ESDHC3_CLK:
+ return __get_esdhc3_clk();
+ case MXC_ESDHC4_CLK:
+ return __get_esdhc4_clk();
default:
break;
}
@@ -315,6 +414,10 @@ void mxc_dump_clocks(void)
printf("axi_b clock : %dHz\n", mxc_get_clock(MXC_AXI_B_CLK));
printf("emi_slow clock: %dHz\n", mxc_get_clock(MXC_EMI_SLOW_CLK));
printf("ddr clock : %dHz\n", mxc_get_clock(MXC_DDR_CLK));
+ printf("esdhc1 clock : %dHz\n", mxc_get_clock(MXC_ESDHC_CLK));
+ printf("esdhc2 clock : %dHz\n", mxc_get_clock(MXC_ESDHC2_CLK));
+ printf("esdhc3 clock : %dHz\n", mxc_get_clock(MXC_ESDHC3_CLK));
+ printf("esdhc4 clock : %dHz\n", mxc_get_clock(MXC_ESDHC4_CLK));
}
#if defined(CONFIG_DISPLAY_CPUINFO)
diff --git a/cpu/arm_cortexa8/mx53/timer.c b/cpu/arm_cortexa8/mx53/timer.c
index 65ddab9..e6b7846 100644
--- a/cpu/arm_cortexa8/mx53/timer.c
+++ b/cpu/arm_cortexa8/mx53/timer.c
@@ -38,7 +38,7 @@
#define GPTCR_CLKSOURCE_32 (0x100<<6) /* Clock source */
#define GPTCR_CLKSOURCE_IPG (0x001<<6) /* Clock source */
#define GPTCR_TEN (1) /* Timer enable */
-#define GPTPR_VAL (66)
+#define GPTPR_VAL (50)
static inline void setup_gpt(void)
{
@@ -54,7 +54,7 @@ static inline void setup_gpt(void)
GPTCR = GPTCR_SWR;
for (i = 0; i < 100; i++)
GPTCR = 0; /* We have no udelay by now */
- GPTPR = GPTPR_VAL; /* 66Mhz / 66 */
+ GPTPR = GPTPR_VAL; /* 50Mhz / 50 */
/* Freerun Mode, PERCLK1 input */
GPTCR |= GPTCR_CLKSOURCE_IPG | GPTCR_TEN;
}
diff --git a/drivers/mmc/imx_esdhc.c b/drivers/mmc/imx_esdhc.c
index 39a0b49..95eee80 100644
--- a/drivers/mmc/imx_esdhc.c
+++ b/drivers/mmc/imx_esdhc.c
@@ -1,6 +1,6 @@
/*
- * (C) Copyright 2008-2009 Freescale Semiconductor, Inc.
- * Terry Lv
+ * (C) Copyright 2008-2010 Freescale Semiconductor, Inc.
+ * Terry Lv, Jason Liu
*
* Copyright 2007, Freescale Semiconductor, Inc
* Andy Fleming
@@ -184,7 +184,7 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
/* Wait for the bus to be idle */
while ((readl(&regs->prsstat) & PRSSTAT_CICHB) ||
(readl(&regs->prsstat) & PRSSTAT_CIDHB))
- mdelay(1);
+ ;
while (readl(&regs->prsstat) & PRSSTAT_DLA);
@@ -193,7 +193,7 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
* Note: This is way more than 8 cycles, but 1ms seems to
* resolve timing issues with some cards
*/
- mdelay(10);
+ udelay(1000);
/* Set up for a data transfer if we have one */
if (data) {
@@ -211,8 +211,6 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
writel(cmd->cmdarg, &regs->cmdarg);
writel(xfertyp, &regs->xfertyp);
- mdelay(10);
-
/* Mask all irqs */
writel(0, &regs->irqsigen);
@@ -258,7 +256,7 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
for (i = 0; i < (block_cnt); ++i) {
while (!(readl(&regs->irqstat) & IRQSTAT_BRR))
- mdelay(1);
+ ;
for (j = 0; j < (block_size >> 2); ++j, ++tmp_ptr) {
*tmp_ptr = readl(&regs->datport);
@@ -271,8 +269,8 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
tmp_ptr = (u32 *)data->src;
for (i = 0; i < (block_cnt); ++i) {
- while (!(readl(&regs->irqstat) & IRQSTAT_BWR))
- mdelay(1);
+ while (!(readl(&regs->irqstat) & IRQSTAT_BWR))
+ ;
for (j = 0; j < (block_size >> 2); ++j, ++tmp_ptr) {
writel(*tmp_ptr, &regs->datport);
diff --git a/include/asm-arm/arch-mx53/mx53.h b/include/asm-arm/arch-mx53/mx53.h
index e985357..b1f3d27 100644
--- a/include/asm-arm/arch-mx53/mx53.h
+++ b/include/asm-arm/arch-mx53/mx53.h
@@ -379,10 +379,16 @@
#ifndef __ASSEMBLER__
enum boot_device {
- UNKNOWN_BOOT,
- NAND_BOOT,
+ WEIM_NOR_BOOT,
+ ONE_NAND_BOOT,
+ PATA_BOOT,
+ SATA_BOOT,
+ I2C_BOOT,
SPI_NOR_BOOT,
+ SD_BOOT,
MMC_BOOT,
+ NAND_BOOT,
+ UNKNOWN_BOOT
};
enum mxc_clock {
@@ -397,6 +403,9 @@ enum mxc_clock {
MXC_EMI_SLOW_CLK,
MXC_DDR_CLK,
MXC_ESDHC_CLK,
+ MXC_ESDHC2_CLK,
+ MXC_ESDHC3_CLK,
+ MXC_ESDHC4_CLK,
};
enum mxc_peri_clocks {