summaryrefslogtreecommitdiff
path: root/cpu
diff options
context:
space:
mode:
Diffstat (limited to 'cpu')
-rw-r--r--cpu/arm1136/mx31/timer.c2
-rw-r--r--cpu/arm1136/omap24xx/timer.c2
-rw-r--r--cpu/arm1176/s3c64xx/timer.c2
-rw-r--r--cpu/arm720t/interrupts.c4
-rw-r--r--cpu/arm920t/a320/Makefile47
-rw-r--r--cpu/arm920t/a320/ftsmc020.c51
-rw-r--r--cpu/arm920t/a320/reset.S22
-rw-r--r--cpu/arm920t/a320/timer.c193
-rw-r--r--cpu/arm920t/at91rm9200/timer.c2
-rw-r--r--cpu/arm920t/imx/timer.c2
-rw-r--r--cpu/arm920t/ks8695/timer.c2
-rw-r--r--cpu/arm920t/s3c24x0/timer.c4
-rw-r--r--cpu/arm925t/timer.c2
-rw-r--r--cpu/arm926ejs/at91/timer.c2
-rw-r--r--cpu/arm926ejs/davinci/cpu.c50
-rw-r--r--cpu/arm926ejs/davinci/psc.c43
-rw-r--r--cpu/arm926ejs/davinci/timer.c30
-rw-r--r--cpu/arm926ejs/kirkwood/timer.c2
-rw-r--r--cpu/arm926ejs/mx27/timer.c2
-rw-r--r--cpu/arm926ejs/nomadik/timer.c2
-rw-r--r--cpu/arm926ejs/omap/timer.c2
-rwxr-xr-xcpu/arm926ejs/versatile/timer.c2
-rw-r--r--cpu/arm_cortexa8/omap3/board.c2
-rw-r--r--cpu/arm_cortexa8/omap3/mem.c5
-rw-r--r--cpu/arm_cortexa8/omap3/sys_info.c2
-rw-r--r--cpu/arm_cortexa8/omap3/timer.c2
-rw-r--r--cpu/arm_cortexa8/s5pc1xx/timer.c2
-rw-r--r--cpu/at32ap/Makefile2
-rw-r--r--cpu/at32ap/hsdramc.c3
-rw-r--r--cpu/at32ap/interrupts.c2
-rw-r--r--cpu/blackfin/interrupts.c2
-rw-r--r--cpu/i386/Makefile2
-rw-r--r--cpu/i386/cpu.c11
-rw-r--r--cpu/i386/exceptions.c229
-rw-r--r--cpu/i386/interrupts.c439
-rw-r--r--cpu/i386/sc520/sc520_timer.c13
-rw-r--r--cpu/i386/start.S132
-rw-r--r--cpu/ixp/start.S4
-rw-r--r--cpu/ixp/timer.c2
-rw-r--r--cpu/lh7a40x/timer.c2
-rw-r--r--cpu/mcf547x_8x/slicetimer.c2
-rw-r--r--cpu/mpc512x/cpu.c1
-rw-r--r--cpu/mpc5xxx/cpu.c1
-rw-r--r--cpu/mpc8260/cpu.c1
-rw-r--r--cpu/mpc83xx/cpu_init.c73
-rw-r--r--cpu/mpc83xx/spd_sdram.c9
-rw-r--r--cpu/mpc85xx/cpu_init.c6
-rw-r--r--cpu/mpc85xx/fdt.c54
-rw-r--r--cpu/mpc85xx/mp.c9
-rw-r--r--cpu/mpc85xx/release.S29
-rw-r--r--cpu/mpc85xx/speed.c12
-rw-r--r--cpu/mpc85xx/start.S8
-rw-r--r--cpu/mpc85xx/tlb.c80
-rw-r--r--cpu/mpc85xx/u-boot-nand.lds1
-rw-r--r--cpu/mpc8xxx/ddr/ctrl_regs.c40
-rw-r--r--cpu/mpc8xxx/ddr/options.c8
-rw-r--r--cpu/mpc8xxx/pci_cfg.c47
-rw-r--r--cpu/ppc4xx/44x_spd_ddr2.c2
-rw-r--r--cpu/ppc4xx/4xx_pci.c253
-rw-r--r--cpu/ppc4xx/4xx_pcie.c119
-rw-r--r--cpu/ppc4xx/cmd_chip_config.c6
-rw-r--r--cpu/ppc4xx/config.mk3
-rw-r--r--cpu/ppc4xx/cpu.c2
-rw-r--r--cpu/ppc4xx/i2c.c199
-rw-r--r--cpu/ppc4xx/u-boot.lds169
-rw-r--r--cpu/ppc4xx/usbdev.c4
-rw-r--r--cpu/pxa/timer.c2
-rw-r--r--cpu/s3c44b0/timer.c2
-rw-r--r--cpu/sa1100/timer.c2
69 files changed, 1801 insertions, 669 deletions
diff --git a/cpu/arm1136/mx31/timer.c b/cpu/arm1136/mx31/timer.c
index 29b484e..7972ba0 100644
--- a/cpu/arm1136/mx31/timer.c
+++ b/cpu/arm1136/mx31/timer.c
@@ -152,7 +152,7 @@ void set_timer (ulong t)
}
/* delay x useconds AND perserve advance timstamp value */
-void udelay (unsigned long usec)
+void __udelay (unsigned long usec)
{
unsigned long long tmp;
ulong tmo;
diff --git a/cpu/arm1136/omap24xx/timer.c b/cpu/arm1136/omap24xx/timer.c
index 8dd8d7b..6754749 100644
--- a/cpu/arm1136/omap24xx/timer.c
+++ b/cpu/arm1136/omap24xx/timer.c
@@ -74,7 +74,7 @@ void set_timer (ulong t)
}
/* delay x useconds AND perserve advance timstamp value */
-void udelay (unsigned long usec)
+void __udelay (unsigned long usec)
{
ulong tmo, tmp;
diff --git a/cpu/arm1176/s3c64xx/timer.c b/cpu/arm1176/s3c64xx/timer.c
index 85ce9cd..9768319 100644
--- a/cpu/arm1176/s3c64xx/timer.c
+++ b/cpu/arm1176/s3c64xx/timer.c
@@ -164,7 +164,7 @@ void set_timer(ulong t)
timestamp = t * (timer_load_val / (100 * CONFIG_SYS_HZ));
}
-void udelay(unsigned long usec)
+void __udelay(unsigned long usec)
{
unsigned long long tmp;
ulong tmo;
diff --git a/cpu/arm720t/interrupts.c b/cpu/arm720t/interrupts.c
index 91d552c..eb8d425 100644
--- a/cpu/arm720t/interrupts.c
+++ b/cpu/arm720t/interrupts.c
@@ -224,7 +224,7 @@ void set_timer (ulong t)
timestamp = t;
}
-void udelay (unsigned long usec)
+void __udelay (unsigned long usec)
{
ulong tmo;
@@ -296,7 +296,7 @@ ulong get_timer (ulong base)
return timestamp - base;
}
-void udelay (unsigned long usec)
+void __udelay (unsigned long usec)
{
u32 ticks;
diff --git a/cpu/arm920t/a320/Makefile b/cpu/arm920t/a320/Makefile
new file mode 100644
index 0000000..f030c53
--- /dev/null
+++ b/cpu/arm920t/a320/Makefile
@@ -0,0 +1,47 @@
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = $(obj)lib$(SOC).a
+
+SOBJS += reset.o
+COBJS += timer.o
+COBJS += ftsmc020.o
+
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+
+all: $(obj).depend $(LIB)
+
+$(LIB): $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/cpu/arm920t/a320/ftsmc020.c b/cpu/arm920t/a320/ftsmc020.c
new file mode 100644
index 0000000..7646537
--- /dev/null
+++ b/cpu/arm920t/a320/ftsmc020.c
@@ -0,0 +1,51 @@
+/*
+ * (C) Copyright 2009 Faraday Technology
+ * Po-Yu Chuang <ratbert@faraday-tech.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <config.h>
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/ftsmc020.h>
+
+struct ftsmc020_config {
+ unsigned int config;
+ unsigned int timing;
+};
+
+static struct ftsmc020_config config[] = CONFIG_SYS_FTSMC020_CONFIGS;
+
+static struct ftsmc020 *smc = (struct ftsmc020 *)CONFIG_FTSMC020_BASE;
+
+static void ftsmc020_setup_bank(unsigned int bank, struct ftsmc020_config *cfg)
+{
+ if (bank > 3) {
+ printf("bank # %u invalid\n", bank);
+ return;
+ }
+
+ writel(cfg->config, &smc->bank[bank].cr);
+ writel(cfg->timing, &smc->bank[bank].tpr);
+}
+
+void ftsmc020_init(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(config); i++)
+ ftsmc020_setup_bank(i, &config[i]);
+}
diff --git a/cpu/arm920t/a320/reset.S b/cpu/arm920t/a320/reset.S
new file mode 100644
index 0000000..12ca527
--- /dev/null
+++ b/cpu/arm920t/a320/reset.S
@@ -0,0 +1,22 @@
+/*
+ * (C) Copyright 2009 Faraday Technology
+ * Po-Yu Chuang <ratbert@faraday-tech.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+.global reset_cpu
+reset_cpu:
+ b reset_cpu
diff --git a/cpu/arm920t/a320/timer.c b/cpu/arm920t/a320/timer.c
new file mode 100644
index 0000000..bb65593
--- /dev/null
+++ b/cpu/arm920t/a320/timer.c
@@ -0,0 +1,193 @@
+/*
+ * (C) Copyright 2009 Faraday Technology
+ * Po-Yu Chuang <ratbert@faraday-tech.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/ftpmu010.h>
+#include <asm/arch/fttmr010.h>
+
+static ulong timestamp;
+static ulong lastdec;
+
+static struct fttmr010 *tmr = (struct fttmr010 *)CONFIG_FTTMR010_BASE;
+static struct ftpmu010 *pmu = (struct ftpmu010 *)CONFIG_FTPMU010_BASE;
+
+#define TIMER_CLOCK 32768
+#define TIMER_LOAD_VAL 0xffffffff
+
+int timer_init(void)
+{
+ unsigned int oscc;
+ unsigned int cr;
+
+ debug("%s()\n", __func__);
+
+ /* disable timers */
+ writel(0, &tmr->cr);
+
+ /*
+ * use 32768Hz oscillator for RTC, WDT, TIMER
+ */
+
+ /* enable the 32768Hz oscillator */
+ oscc = readl(&pmu->OSCC);
+ oscc &= ~(FTPMU010_OSCC_OSCL_OFF | FTPMU010_OSCC_OSCL_TRI);
+ writel(oscc, &pmu->OSCC);
+
+ /* wait until ready */
+ while (!(readl(&pmu->OSCC) & FTPMU010_OSCC_OSCL_STABLE))
+ ;
+
+ /* select 32768Hz oscillator */
+ oscc = readl(&pmu->OSCC);
+ oscc |= FTPMU010_OSCC_OSCL_RTCLSEL;
+ writel(oscc, &pmu->OSCC);
+
+ /* setup timer */
+ writel(TIMER_LOAD_VAL, &tmr->timer3_load);
+ writel(TIMER_LOAD_VAL, &tmr->timer3_counter);
+ writel(0, &tmr->timer3_match1);
+ writel(0, &tmr->timer3_match2);
+
+ /* we don't want timer to issue interrupts */
+ writel(FTTMR010_TM3_MATCH1 |
+ FTTMR010_TM3_MATCH2 |
+ FTTMR010_TM3_OVERFLOW,
+ &tmr->interrupt_mask);
+
+ cr = readl(&tmr->cr);
+ cr |= FTTMR010_TM3_CLOCK; /* use external clock */
+ cr |= FTTMR010_TM3_ENABLE;
+ writel(cr, &tmr->cr);
+
+ /* init the timestamp and lastdec value */
+ reset_timer_masked();
+
+ return 0;
+}
+
+/*
+ * timer without interrupts
+ */
+
+/*
+ * reset time
+ */
+void reset_timer_masked(void)
+{
+ /* capure current decrementer value time */
+ lastdec = readl(&tmr->timer3_counter) / (TIMER_CLOCK / CONFIG_SYS_HZ);
+ timestamp = 0; /* start "advancing" time stamp from 0 */
+
+ debug("%s(): lastdec = %lx\n", __func__, lastdec);
+}
+
+void reset_timer(void)
+{
+ debug("%s()\n", __func__);
+ reset_timer_masked();
+}
+
+/*
+ * return timer ticks
+ */
+ulong get_timer_masked(void)
+{
+ /* current tick value */
+ ulong now = readl(&tmr->timer3_counter) / (TIMER_CLOCK / CONFIG_SYS_HZ);
+
+ debug("%s(): now = %lx, lastdec = %lx\n", __func__, now, lastdec);
+
+ if (lastdec >= now) {
+ /*
+ * normal mode (non roll)
+ * move stamp fordward with absoulte diff ticks
+ */
+ timestamp += lastdec - now;
+ } else {
+ /*
+ * we have overflow of the count down timer
+ *
+ * nts = ts + ld + (TLV - now)
+ * ts=old stamp, ld=time that passed before passing through -1
+ * (TLV-now) amount of time after passing though -1
+ * nts = new "advancing time stamp"...it could also roll and
+ * cause problems.
+ */
+ timestamp += lastdec + TIMER_LOAD_VAL - now;
+ }
+
+ lastdec = now;
+
+ debug("%s() returns %lx\n", __func__, timestamp);
+
+ return timestamp;
+}
+
+/*
+ * return difference between timer ticks and base
+ */
+ulong get_timer(ulong base)
+{
+ debug("%s(%lx)\n", __func__, base);
+ return get_timer_masked() - base;
+}
+
+void set_timer(ulong t)
+{
+ debug("%s(%lx)\n", __func__, t);
+ timestamp = t;
+}
+
+/* delay x useconds AND perserve advance timstamp value */
+void udelay(unsigned long usec)
+{
+ long tmo = usec * (TIMER_CLOCK / 1000) / 1000;
+ unsigned long now, last = readl(&tmr->timer3_counter);
+
+ debug("%s(%lu)\n", __func__, usec);
+ while (tmo > 0) {
+ now = readl(&tmr->timer3_counter);
+ if (now > last) /* count down timer overflow */
+ tmo -= TIMER_LOAD_VAL + last - now;
+ else
+ tmo -= last - now;
+ last = now;
+ }
+}
+
+/*
+ * This function is derived from PowerPC code (read timebase as long long).
+ * On ARM it just returns the timer value.
+ */
+unsigned long long get_ticks(void)
+{
+ debug("%s()\n", __func__);
+ return get_timer(0);
+}
+
+/*
+ * This function is derived from PowerPC code (timebase clock frequency).
+ * On ARM it returns the number of timer ticks per second.
+ */
+ulong get_tbclk(void)
+{
+ debug("%s()\n", __func__);
+ return CONFIG_SYS_HZ;
+}
diff --git a/cpu/arm920t/at91rm9200/timer.c b/cpu/arm920t/at91rm9200/timer.c
index 235d107..9c54bbe 100644
--- a/cpu/arm920t/at91rm9200/timer.c
+++ b/cpu/arm920t/at91rm9200/timer.c
@@ -87,7 +87,7 @@ void set_timer (ulong t)
timestamp = t;
}
-void udelay (unsigned long usec)
+void __udelay (unsigned long usec)
{
udelay_masked(usec);
}
diff --git a/cpu/arm920t/imx/timer.c b/cpu/arm920t/imx/timer.c
index 31ec588..b06b518 100644
--- a/cpu/arm920t/imx/timer.c
+++ b/cpu/arm920t/imx/timer.c
@@ -89,7 +89,7 @@ void udelay_masked (unsigned long usec)
} while (diff >= 0);
}
-void udelay (unsigned long usec)
+void __udelay (unsigned long usec)
{
udelay_masked(usec);
}
diff --git a/cpu/arm920t/ks8695/timer.c b/cpu/arm920t/ks8695/timer.c
index 22987bc..886e370 100644
--- a/cpu/arm920t/ks8695/timer.c
+++ b/cpu/arm920t/ks8695/timer.c
@@ -81,7 +81,7 @@ void set_timer(ulong t)
timer_ticks = t;
}
-void udelay(ulong usec)
+void __udelay(ulong usec)
{
ulong start = get_timer_masked();
ulong end;
diff --git a/cpu/arm920t/s3c24x0/timer.c b/cpu/arm920t/s3c24x0/timer.c
index cd06f6b..7d47354 100644
--- a/cpu/arm920t/s3c24x0/timer.c
+++ b/cpu/arm920t/s3c24x0/timer.c
@@ -99,7 +99,7 @@ void set_timer(ulong t)
timestamp = t;
}
-void udelay(unsigned long usec)
+void __udelay (unsigned long usec)
{
ulong tmo;
ulong start = get_ticks();
@@ -198,6 +198,8 @@ void reset_cpu(ulong ignored)
struct s3c24x0_watchdog *watchdog;
#ifdef CONFIG_TRAB
+ extern void disable_vfd(void);
+
disable_vfd();
#endif
diff --git a/cpu/arm925t/timer.c b/cpu/arm925t/timer.c
index c16ef25..7dfe2b5 100644
--- a/cpu/arm925t/timer.c
+++ b/cpu/arm925t/timer.c
@@ -81,7 +81,7 @@ void set_timer (ulong t)
}
/* delay x useconds AND preserve advance timestamp value */
-void udelay (unsigned long usec)
+void __udelay (unsigned long usec)
{
int32_t tmo = usec * (TIMER_CLOCK / 1000) / 1000;
uint32_t now, last = __raw_readl(CONFIG_SYS_TIMERBASE + READ_TIM);
diff --git a/cpu/arm926ejs/at91/timer.c b/cpu/arm926ejs/at91/timer.c
index 811bb3c..7352b5c 100644
--- a/cpu/arm926ejs/at91/timer.c
+++ b/cpu/arm926ejs/at91/timer.c
@@ -105,7 +105,7 @@ ulong get_timer_masked(void)
return tick_to_time(get_ticks());
}
-void udelay(unsigned long usec)
+void __udelay(unsigned long usec)
{
unsigned long long tmp;
ulong tmo;
diff --git a/cpu/arm926ejs/davinci/cpu.c b/cpu/arm926ejs/davinci/cpu.c
index 390cab8..fc3551c 100644
--- a/cpu/arm926ejs/davinci/cpu.c
+++ b/cpu/arm926ejs/davinci/cpu.c
@@ -23,7 +23,7 @@
#include <common.h>
#include <netdev.h>
#include <asm/arch/hardware.h>
-
+#include <asm/io.h>
/* offsets from PLL controller base */
#define PLLC_PLLCTL 0x100
@@ -60,6 +60,54 @@
#define DDR_PLLDIV PLLC_PLLDIV1
#endif
+#ifdef CONFIG_SOC_DA8XX
+const dv_reg * const sysdiv[7] = {
+ &davinci_pllc_regs->plldiv1, &davinci_pllc_regs->plldiv2,
+ &davinci_pllc_regs->plldiv3, &davinci_pllc_regs->plldiv4,
+ &davinci_pllc_regs->plldiv5, &davinci_pllc_regs->plldiv6,
+ &davinci_pllc_regs->plldiv7
+};
+
+int clk_get(enum davinci_clk_ids id)
+{
+ int pre_div;
+ int pllm;
+ int post_div;
+ int pll_out;
+
+ pll_out = CONFIG_SYS_OSCIN_FREQ;
+
+ if (id == DAVINCI_AUXCLK_CLKID)
+ goto out;
+
+ /*
+ * Lets keep this simple. Combining operations can result in
+ * unexpected approximations
+ */
+ pre_div = (readl(&davinci_pllc_regs->prediv) &
+ DAVINCI_PLLC_DIV_MASK) + 1;
+ pllm = readl(&davinci_pllc_regs->pllm) + 1;
+
+ pll_out /= pre_div;
+ pll_out *= pllm;
+
+ if (id == DAVINCI_PLLM_CLKID)
+ goto out;
+
+ post_div = (readl(&davinci_pllc_regs->postdiv) &
+ DAVINCI_PLLC_DIV_MASK) + 1;
+
+ pll_out /= post_div;
+
+ if (id == DAVINCI_PLLC_CLKID)
+ goto out;
+
+ pll_out /= (readl(sysdiv[id - 1]) & DAVINCI_PLLC_DIV_MASK) + 1;
+
+out:
+ return pll_out;
+}
+#endif /* CONFIG_SOC_DA8XX */
#ifdef CONFIG_DISPLAY_CPUINFO
diff --git a/cpu/arm926ejs/davinci/psc.c b/cpu/arm926ejs/davinci/psc.c
index 5bb972f..8273a7f 100644
--- a/cpu/arm926ejs/davinci/psc.c
+++ b/cpu/arm926ejs/davinci/psc.c
@@ -25,6 +25,7 @@
#include <common.h>
#include <asm/arch/hardware.h>
+#include <asm/io.h>
/*
* The PSC manages three inputs to a "module" which may be a peripheral or
@@ -47,21 +48,45 @@
/* Works on Always On power domain only (no PD argument) */
void lpsc_on(unsigned int id)
{
- dv_reg_p mdstat, mdctl;
+ dv_reg_p mdstat, mdctl, ptstat, ptcmd;
+#ifdef CONFIG_SOC_DA8XX
+ struct davinci_psc_regs *psc_regs;
+#endif
+#ifndef CONFIG_SOC_DA8XX
if (id >= DAVINCI_LPSC_GEM)
return; /* Don't work on DSP Power Domain */
mdstat = REG_P(PSC_MDSTAT_BASE + (id * 4));
mdctl = REG_P(PSC_MDCTL_BASE + (id * 4));
+ ptstat = REG_P(PSC_PTSTAT);
+ ptcmd = REG_P(PSC_PTCMD);
+#else
+ if (id < DAVINCI_LPSC_PSC1_BASE) {
+ if (id >= PSC_PSC0_MODULE_ID_CNT)
+ return;
+ psc_regs = davinci_psc0_regs;
+ mdstat = &psc_regs->psc0.mdstat[id];
+ mdctl = &psc_regs->psc0.mdctl[id];
+ } else {
+ id -= DAVINCI_LPSC_PSC1_BASE;
+ if (id >= PSC_PSC1_MODULE_ID_CNT)
+ return;
+ psc_regs = davinci_psc1_regs;
+ mdstat = &psc_regs->psc1.mdstat[id];
+ mdctl = &psc_regs->psc1.mdctl[id];
+ }
+ ptstat = &psc_regs->ptstat;
+ ptcmd = &psc_regs->ptcmd;
+#endif
- while (REG(PSC_PTSTAT) & 0x01)
+ while (readl(ptstat) & 0x01)
continue;
- if ((*mdstat & 0x1f) == 0x03)
- return; /* Already on and enabled */
+ if ((readl(mdstat) & 0x1f) == 0x03)
+ return; /* Already on and enabled */
- *mdctl |= 0x03;
+ writel(readl(mdctl) | 0x03, mdctl);
switch (id) {
#ifdef CONFIG_SOC_DM644X
@@ -80,16 +105,16 @@ void lpsc_on(unsigned int id)
case DAVINCI_LPSC_MEMSTICK:
case DAVINCI_LPSC_McBSP:
case DAVINCI_LPSC_GPIO:
- *mdctl |= 0x200;
+ writel(readl(mdctl) | 0x200, mdctl);
break;
#endif
}
- REG(PSC_PTCMD) = 0x01;
+ writel(0x01, ptcmd);
- while (REG(PSC_PTSTAT) & 0x03)
+ while (readl(ptstat) & 0x01)
continue;
- while ((*mdstat & 0x1f) != 0x03) /* Probably an overkill... */
+ while ((readl(mdstat) & 0x1f) != 0x03)
continue;
}
diff --git a/cpu/arm926ejs/davinci/timer.c b/cpu/arm926ejs/davinci/timer.c
index 80751ad..9da7443 100644
--- a/cpu/arm926ejs/davinci/timer.c
+++ b/cpu/arm926ejs/davinci/timer.c
@@ -38,8 +38,9 @@
*/
#include <common.h>
+#include <asm/io.h>
-typedef volatile struct {
+struct davinci_timer {
u_int32_t pid12;
u_int32_t emumgt;
u_int32_t na1;
@@ -51,9 +52,10 @@ typedef volatile struct {
u_int32_t tcr;
u_int32_t tgcr;
u_int32_t wdtcr;
-} davinci_timer;
+};
-davinci_timer *timer = (davinci_timer *)CONFIG_SYS_TIMERBASE;
+static struct davinci_timer * const timer =
+ (struct davinci_timer *)CONFIG_SYS_TIMERBASE;
#define TIMER_LOAD_VAL (CONFIG_SYS_HZ_CLOCK / CONFIG_SYS_HZ)
#define TIM_CLK_DIV 16
@@ -64,30 +66,30 @@ static ulong lastinc;
int timer_init(void)
{
/* We are using timer34 in unchained 32-bit mode, full speed */
- timer->tcr = 0x0;
- timer->tgcr = 0x0;
- timer->tgcr = 0x06 | ((TIM_CLK_DIV - 1) << 8);
- timer->tim34 = 0x0;
- timer->prd34 = TIMER_LOAD_VAL;
+ writel(0x0, &timer->tcr);
+ writel(0x0, &timer->tgcr);
+ writel(0x06 | ((TIM_CLK_DIV - 1) << 8), &timer->tgcr);
+ writel(0x0, &timer->tim34);
+ writel(TIMER_LOAD_VAL, &timer->prd34);
lastinc = 0;
timestamp = 0;
- timer->tcr = 2 << 22;
+ writel(2 << 22, &timer->tcr);
return(0);
}
void reset_timer(void)
{
- timer->tcr = 0x0;
- timer->tim34 = 0;
+ writel(0x0, &timer->tcr);
+ writel(0x0, &timer->tim34);
lastinc = 0;
timestamp = 0;
- timer->tcr = 2 << 22;
+ writel(2 << 22, &timer->tcr);
}
static ulong get_timer_raw(void)
{
- ulong now = timer->tim34;
+ ulong now = readl(&timer->tim34);
if (now >= lastinc) {
/* normal mode */
@@ -110,7 +112,7 @@ void set_timer(ulong t)
timestamp = t;
}
-void udelay(unsigned long usec)
+void __udelay(unsigned long usec)
{
ulong tmo;
ulong endtime;
diff --git a/cpu/arm926ejs/kirkwood/timer.c b/cpu/arm926ejs/kirkwood/timer.c
index 817ff42..2ec6a93 100644
--- a/cpu/arm926ejs/kirkwood/timer.c
+++ b/cpu/arm926ejs/kirkwood/timer.c
@@ -125,7 +125,7 @@ void set_timer(ulong t)
timestamp = t;
}
-void udelay(unsigned long usec)
+void __udelay(unsigned long usec)
{
uint current;
ulong delayticks;
diff --git a/cpu/arm926ejs/mx27/timer.c b/cpu/arm926ejs/mx27/timer.c
index 9011058..8f1d47b 100644
--- a/cpu/arm926ejs/mx27/timer.c
+++ b/cpu/arm926ejs/mx27/timer.c
@@ -177,7 +177,7 @@ void set_timer (ulong t)
}
/* delay x useconds AND preserve advance timstamp value */
-void udelay (unsigned long usec)
+void __udelay (unsigned long usec)
{
unsigned long long tmp;
ulong tmo;
diff --git a/cpu/arm926ejs/nomadik/timer.c b/cpu/arm926ejs/nomadik/timer.c
index 16067c9..047b9e3 100644
--- a/cpu/arm926ejs/nomadik/timer.c
+++ b/cpu/arm926ejs/nomadik/timer.c
@@ -59,7 +59,7 @@ ulong get_timer(ulong base)
}
/* Delay x useconds */
-void udelay(unsigned long usec)
+void __udelay(unsigned long usec)
{
ulong ini, end;
diff --git a/cpu/arm926ejs/omap/timer.c b/cpu/arm926ejs/omap/timer.c
index 392b158..2ac38c4 100644
--- a/cpu/arm926ejs/omap/timer.c
+++ b/cpu/arm926ejs/omap/timer.c
@@ -80,7 +80,7 @@ void set_timer (ulong t)
}
/* delay x useconds AND perserve advance timstamp value */
-void udelay (unsigned long usec)
+void __udelay (unsigned long usec)
{
ulong tmo, tmp;
diff --git a/cpu/arm926ejs/versatile/timer.c b/cpu/arm926ejs/versatile/timer.c
index 50c1335..563db36 100755
--- a/cpu/arm926ejs/versatile/timer.c
+++ b/cpu/arm926ejs/versatile/timer.c
@@ -109,7 +109,7 @@ void set_timer (ulong t)
}
/* delay x useconds AND perserve advance timstamp value */
-void udelay (unsigned long usec)
+void __udelay (unsigned long usec)
{
ulong tmo, tmp;
diff --git a/cpu/arm_cortexa8/omap3/board.c b/cpu/arm_cortexa8/omap3/board.c
index dd2c940..2aa69b3 100644
--- a/cpu/arm_cortexa8/omap3/board.c
+++ b/cpu/arm_cortexa8/omap3/board.c
@@ -328,7 +328,7 @@ usage:
U_BOOT_CMD(
nandecc, 2, 1, do_switch_ecc,
- "nandecc - switch OMAP3 NAND ECC calculation algorithm\n",
+ "switch OMAP3 NAND ECC calculation algorithm",
"[hw/sw] - Switch between NAND hardware (hw) or software (sw) ecc algorithm"
);
diff --git a/cpu/arm_cortexa8/omap3/mem.c b/cpu/arm_cortexa8/omap3/mem.c
index 8b8cd6d..dfb7e4c 100644
--- a/cpu/arm_cortexa8/omap3/mem.c
+++ b/cpu/arm_cortexa8/omap3/mem.c
@@ -161,10 +161,11 @@ void do_sdrc_init(u32 cs, u32 early)
writel(0, &sdrc_base->sysconfig);
/* setup sdrc to ball mux */
- writel(SDP_SDRC_SHARING, &sdrc_base->sharing);
+ writel(SDRC_SHARING, &sdrc_base->sharing);
/* Disable Power Down of CKE cuz of 1 CKE on combo part */
- writel(SRFRONRESET | PAGEPOLICY_HIGH, &sdrc_base->power);
+ writel(WAKEUPPROC | PWDNEN | SRFRONRESET | PAGEPOLICY_HIGH,
+ &sdrc_base->power);
writel(ENADLL | DLLPHASE_90, &sdrc_base->dlla_ctrl);
sdelay(0x20000);
diff --git a/cpu/arm_cortexa8/omap3/sys_info.c b/cpu/arm_cortexa8/omap3/sys_info.c
index 31b2003..08fb32e 100644
--- a/cpu/arm_cortexa8/omap3/sys_info.c
+++ b/cpu/arm_cortexa8/omap3/sys_info.c
@@ -109,7 +109,7 @@ u32 get_cpu_rev(void)
****************************************************/
u32 is_mem_sdr(void)
{
- if (readl(&sdrc_base->cs[CS0].mr) == SDP_SDRC_MR_0_SDR)
+ if (readl(&sdrc_base->cs[CS0].mr) == SDRC_MR_0_SDR)
return 1;
return 0;
}
diff --git a/cpu/arm_cortexa8/omap3/timer.c b/cpu/arm_cortexa8/omap3/timer.c
index 12a16b3..401bfe6 100644
--- a/cpu/arm_cortexa8/omap3/timer.c
+++ b/cpu/arm_cortexa8/omap3/timer.c
@@ -82,7 +82,7 @@ void set_timer(ulong t)
}
/* delay x useconds */
-void udelay(unsigned long usec)
+void __udelay(unsigned long usec)
{
long tmo = usec * (TIMER_CLOCK / 1000) / 1000;
unsigned long now, last = readl(&timer_base->tcrr);
diff --git a/cpu/arm_cortexa8/s5pc1xx/timer.c b/cpu/arm_cortexa8/s5pc1xx/timer.c
index cdba5d9..c5df5c5 100644
--- a/cpu/arm_cortexa8/s5pc1xx/timer.c
+++ b/cpu/arm_cortexa8/s5pc1xx/timer.c
@@ -115,7 +115,7 @@ void set_timer(unsigned long t)
}
/* delay x useconds */
-void udelay(unsigned long usec)
+void __udelay(unsigned long usec)
{
unsigned long tmo, tmp;
diff --git a/cpu/at32ap/Makefile b/cpu/at32ap/Makefile
index e08f273..60899c7 100644
--- a/cpu/at32ap/Makefile
+++ b/cpu/at32ap/Makefile
@@ -30,7 +30,7 @@ LIB := $(obj)lib$(CPU).a
START-y += start.o
COBJS-y += cpu.o
-COBJS-y += hsdramc.o
+COBJS-$(CONFIG_SYS_HSDRAMC) += hsdramc.o
COBJS-y += exception.o
COBJS-y += cache.o
COBJS-y += interrupts.o
diff --git a/cpu/at32ap/hsdramc.c b/cpu/at32ap/hsdramc.c
index f74121c..b6eae66 100644
--- a/cpu/at32ap/hsdramc.c
+++ b/cpu/at32ap/hsdramc.c
@@ -21,7 +21,6 @@
*/
#include <common.h>
-#ifdef CONFIG_SYS_HSDRAMC
#include <asm/io.h>
#include <asm/sdram.h>
@@ -116,5 +115,3 @@ unsigned long sdram_init(void *sdram_base, const struct sdram_config *config)
return sdram_size;
}
-
-#endif /* CONFIG_SYS_HSDRAMC */
diff --git a/cpu/at32ap/interrupts.c b/cpu/at32ap/interrupts.c
index 75cc39e..c6d8d16 100644
--- a/cpu/at32ap/interrupts.c
+++ b/cpu/at32ap/interrupts.c
@@ -96,7 +96,7 @@ void set_timer(unsigned long t)
/*
* For short delays only. It will overflow after a few seconds.
*/
-void udelay(unsigned long usec)
+void __udelay(unsigned long usec)
{
unsigned long cycles;
unsigned long base;
diff --git a/cpu/blackfin/interrupts.c b/cpu/blackfin/interrupts.c
index 19456e5..921bfe0 100644
--- a/cpu/blackfin/interrupts.c
+++ b/cpu/blackfin/interrupts.c
@@ -64,7 +64,7 @@ int disable_interrupts(void)
return 1;
}
-void udelay(unsigned long usec)
+void __udelay(unsigned long usec)
{
unsigned long delay, start, stop;
unsigned long cclk;
diff --git a/cpu/i386/Makefile b/cpu/i386/Makefile
index e98bd3d..c658c6e 100644
--- a/cpu/i386/Makefile
+++ b/cpu/i386/Makefile
@@ -29,7 +29,7 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(CPU).a
START = start.o start16.o resetvec.o
-COBJS = serial.o interrupts.o exceptions.o cpu.o
+COBJS = serial.o interrupts.o cpu.o
SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
diff --git a/cpu/i386/cpu.c b/cpu/i386/cpu.c
index d91e33b..3010519 100644
--- a/cpu/i386/cpu.c
+++ b/cpu/i386/cpu.c
@@ -37,7 +37,7 @@
#include <command.h>
#include <asm/interrupt.h>
-int cpu_init(void)
+int cpu_init_f(void)
{
/* initialize FPU, reset EM, set MP and NE */
asm ("fninit\n" \
@@ -46,10 +46,13 @@ int cpu_init(void)
"orl $0x22, %eax\n" \
"movl %eax, %cr0\n" );
+ return 0;
+}
+
+int cpu_init_r(void)
+{
/* Initialize core interrupt and exception functionality of CPU */
cpu_init_interrupts ();
- cpu_init_exceptions ();
-
return 0;
}
@@ -74,6 +77,8 @@ void __attribute__ ((regparm(0))) generate_gpf(void);
/* segment 0x70 is an arbitrary segment which does not exist */
asm(".globl generate_gpf\n"
+ ".hidden generate_gpf\n"
+ ".type generate_gpf, @function\n"
"generate_gpf:\n"
"ljmp $0x70, $0x47114711\n");
diff --git a/cpu/i386/exceptions.c b/cpu/i386/exceptions.c
deleted file mode 100644
index bc3d434..0000000
--- a/cpu/i386/exceptions.c
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * (C) Copyright 2002
- * Daniel Engström, Omicron Ceti AB, daniel@omicron.se.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <common.h>
-#include <asm/interrupt.h>
-
-asm (".globl exp_return\n"
- "exp_return:\n"
- " addl $12, %esp\n"
- " pop %esp\n"
- " popa\n"
- " iret\n");
-
-char exception_stack[4096];
-
-/*
- * For detailed description of each exception, refer to:
- * Intel® 64 and IA-32 Architectures Software Developer's Manual
- * Volume 1: Basic Architecture
- * Order Number: 253665-029US, November 2008
- * Table 6-1. Exceptions and Interrupts
- */
-DECLARE_EXCEPTION(0, divide_error_entry);
-DECLARE_EXCEPTION(1, debug_entry);
-DECLARE_EXCEPTION(2, nmi_interrupt_entry);
-DECLARE_EXCEPTION(3, breakpoint_entry);
-DECLARE_EXCEPTION(4, overflow_entry);
-DECLARE_EXCEPTION(5, bound_range_exceeded_entry);
-DECLARE_EXCEPTION(6, invalid_opcode_entry);
-DECLARE_EXCEPTION(7, device_not_available_entry);
-DECLARE_EXCEPTION(8, double_fault_entry);
-DECLARE_EXCEPTION(9, coprocessor_segment_overrun_entry);
-DECLARE_EXCEPTION(10, invalid_tss_entry);
-DECLARE_EXCEPTION(11, segment_not_present_entry);
-DECLARE_EXCEPTION(12, stack_segment_fault_entry);
-DECLARE_EXCEPTION(13, general_protection_entry);
-DECLARE_EXCEPTION(14, page_fault_entry);
-DECLARE_EXCEPTION(15, reserved_exception_entry);
-DECLARE_EXCEPTION(16, floating_point_error_entry);
-DECLARE_EXCEPTION(17, alignment_check_entry);
-DECLARE_EXCEPTION(18, machine_check_entry);
-DECLARE_EXCEPTION(19, simd_floating_point_exception_entry);
-DECLARE_EXCEPTION(20, reserved_exception_entry);
-DECLARE_EXCEPTION(21, reserved_exception_entry);
-DECLARE_EXCEPTION(22, reserved_exception_entry);
-DECLARE_EXCEPTION(23, reserved_exception_entry);
-DECLARE_EXCEPTION(24, reserved_exception_entry);
-DECLARE_EXCEPTION(25, reserved_exception_entry);
-DECLARE_EXCEPTION(26, reserved_exception_entry);
-DECLARE_EXCEPTION(27, reserved_exception_entry);
-DECLARE_EXCEPTION(28, reserved_exception_entry);
-DECLARE_EXCEPTION(29, reserved_exception_entry);
-DECLARE_EXCEPTION(30, reserved_exception_entry);
-DECLARE_EXCEPTION(31, reserved_exception_entry);
-
-__isr__ reserved_exception_entry(int cause, int ip, int seg)
-{
- printf("Reserved Exception %d at %04x:%08x\n", cause, seg, ip);
-}
-
-__isr__ divide_error_entry(int cause, int ip, int seg)
-{
- printf("Divide Error (Division by zero) at %04x:%08x\n", seg, ip);
- while(1);
-}
-
-__isr__ debug_entry(int cause, int ip, int seg)
-{
- printf("Debug Interrupt (Single step) at %04x:%08x\n", seg, ip);
-}
-
-__isr__ nmi_interrupt_entry(int cause, int ip, int seg)
-{
- printf("NMI Interrupt at %04x:%08x\n", seg, ip);
-}
-
-__isr__ breakpoint_entry(int cause, int ip, int seg)
-{
- printf("Breakpoint at %04x:%08x\n", seg, ip);
-}
-
-__isr__ overflow_entry(int cause, int ip, int seg)
-{
- printf("Overflow at %04x:%08x\n", seg, ip);
- while(1);
-}
-
-__isr__ bound_range_exceeded_entry(int cause, int ip, int seg)
-{
- printf("BOUND Range Exceeded at %04x:%08x\n", seg, ip);
- while(1);
-}
-
-__isr__ invalid_opcode_entry(int cause, int ip, int seg)
-{
- printf("Invalid Opcode (UnDefined Opcode) at %04x:%08x\n", seg, ip);
- while(1);
-}
-
-__isr__ device_not_available_entry(int cause, int ip, int seg)
-{
- printf("Device Not Available (No Math Coprocessor) at %04x:%08x\n", seg, ip);
- while(1);
-}
-
-__isr__ double_fault_entry(int cause, int ip, int seg)
-{
- printf("Double fault at %04x:%08x\n", seg, ip);
- while(1);
-}
-
-__isr__ coprocessor_segment_overrun_entry(int cause, int ip, int seg)
-{
- printf("Co-processor segment overrun at %04x:%08x\n", seg, ip);
- while(1);
-}
-
-__isr__ invalid_tss_entry(int cause, int ip, int seg)
-{
- printf("Invalid TSS at %04x:%08x\n", seg, ip);
-}
-
-__isr__ segment_not_present_entry(int cause, int ip, int seg)
-{
- printf("Segment Not Present at %04x:%08x\n", seg, ip);
- while(1);
-}
-
-__isr__ stack_segment_fault_entry(int cause, int ip, int seg)
-{
- printf("Stack Segment Fault at %04x:%08x\n", seg, ip);
- while(1);
-}
-
-__isr__ general_protection_entry(int cause, int ip, int seg)
-{
- printf("General Protection at %04x:%08x\n", seg, ip);
-}
-
-__isr__ page_fault_entry(int cause, int ip, int seg)
-{
- printf("Page fault at %04x:%08x\n", seg, ip);
- while(1);
-}
-
-__isr__ floating_point_error_entry(int cause, int ip, int seg)
-{
- printf("Floating-Point Error (Math Fault) at %04x:%08x\n", seg, ip);
-}
-
-__isr__ alignment_check_entry(int cause, int ip, int seg)
-{
- printf("Alignment check at %04x:%08x\n", seg, ip);
-}
-
-__isr__ machine_check_entry(int cause, int ip, int seg)
-{
- printf("Machine Check at %04x:%08x\n", seg, ip);
-}
-
-__isr__ simd_floating_point_exception_entry(int cause, int ip, int seg)
-{
- printf("SIMD Floating-Point Exception at %04x:%08x\n", seg, ip);
-}
-
-int cpu_init_exceptions(void)
-{
- /* Just in case... */
- disable_interrupts();
-
- /* Setup exceptions */
- set_vector(0x00, exp_0);
- set_vector(0x01, exp_1);
- set_vector(0x02, exp_2);
- set_vector(0x03, exp_3);
- set_vector(0x04, exp_4);
- set_vector(0x05, exp_5);
- set_vector(0x06, exp_6);
- set_vector(0x07, exp_7);
- set_vector(0x08, exp_8);
- set_vector(0x09, exp_9);
- set_vector(0x0a, exp_10);
- set_vector(0x0b, exp_11);
- set_vector(0x0c, exp_12);
- set_vector(0x0d, exp_13);
- set_vector(0x0e, exp_14);
- set_vector(0x0f, exp_15);
- set_vector(0x10, exp_16);
- set_vector(0x11, exp_17);
- set_vector(0x12, exp_18);
- set_vector(0x13, exp_19);
- set_vector(0x14, exp_20);
- set_vector(0x15, exp_21);
- set_vector(0x16, exp_22);
- set_vector(0x17, exp_23);
- set_vector(0x18, exp_24);
- set_vector(0x19, exp_25);
- set_vector(0x1a, exp_26);
- set_vector(0x1b, exp_27);
- set_vector(0x1c, exp_28);
- set_vector(0x1d, exp_29);
- set_vector(0x1e, exp_30);
- set_vector(0x1f, exp_31);
-
- /* It is now safe to enable interrupts */
- enable_interrupts();
-
- return 0;
-}
diff --git a/cpu/i386/interrupts.c b/cpu/i386/interrupts.c
index 063ea42..4b57437 100644
--- a/cpu/i386/interrupts.c
+++ b/cpu/i386/interrupts.c
@@ -1,4 +1,7 @@
/*
+ * (C) Copyright 2008
+ * Graeme Russ, graeme.russ@gmail.com.
+ *
* (C) Copyright 2002
* Daniel Engström, Omicron Ceti AB, daniel@omicron.se.
*
@@ -24,6 +27,16 @@
#include <common.h>
#include <asm/interrupt.h>
+#define DECLARE_INTERRUPT(x) \
+ ".globl irq_"#x"\n" \
+ ".hidden irq_"#x"\n" \
+ ".type irq_"#x", @function\n" \
+ "irq_"#x":\n" \
+ "pushl %ebp\n" \
+ "movl %esp,%ebp\n" \
+ "pusha\n" \
+ "pushl $"#x"\n" \
+ "jmp irq_common_entry\n"
struct idt_entry {
u16 base_low;
@@ -33,35 +46,37 @@ struct idt_entry {
u16 base_high;
} __attribute__ ((packed));
+struct desc_ptr {
+ unsigned short size;
+ unsigned long address;
+ unsigned short segment;
+} __attribute__((packed));
struct idt_entry idt[256];
+struct desc_ptr idt_ptr;
-asm (".globl irq_return\n"
- "irq_return:\n"
- " addl $4, %esp\n"
- " popa\n"
- " iret\n");
-
-void __attribute__ ((regparm(0))) default_isr(void);
-asm ("default_isr: iret\n");
-
-asm ("idt_ptr:\n"
- ".word 0x800\n" /* size of the table 8*256 bytes */
- ".long idt\n" /* offset */
- ".word 0x18\n");/* data segment */
+static inline void load_idt(const struct desc_ptr *dtr)
+{
+ asm volatile("cs lidt %0"::"m" (*dtr));
+}
void set_vector(u8 intnum, void *routine)
{
- idt[intnum].base_high = (u16)((u32)(routine + gd->reloc_off) >> 16);
- idt[intnum].base_low = (u16)((u32)(routine + gd->reloc_off) & 0xffff);
+ idt[intnum].base_high = (u16)((u32)(routine) >> 16);
+ idt[intnum].base_low = (u16)((u32)(routine) & 0xffff);
}
+void irq_0(void);
+void irq_1(void);
int cpu_init_interrupts(void)
{
int i;
+ int irq_entry_size = irq_1 - irq_0;
+ void *irq_entry = (void *)irq_0;
+
/* Just in case... */
disable_interrupts();
@@ -70,10 +85,15 @@ int cpu_init_interrupts(void)
idt[i].access = 0x8e;
idt[i].res = 0;
idt[i].selector = 0x10;
- set_vector(i, default_isr);
+ set_vector(i, irq_entry);
+ irq_entry += irq_entry_size;
}
- asm ("cs lidt idt_ptr\n");
+ idt_ptr.size = 256 * 8;
+ idt_ptr.address = (unsigned long) idt;
+ idt_ptr.segment = 0x18;
+
+ load_idt(&idt_ptr);
/* It is now safe to enable interrupts */
enable_interrupts();
@@ -81,6 +101,12 @@ int cpu_init_interrupts(void)
return 0;
}
+void __do_irq(int irq)
+{
+ printf("Unhandled IRQ : %d\n", irq);
+}
+void do_irq(int irq) __attribute__((weak, alias("__do_irq")));
+
void enable_interrupts(void)
{
asm("sti\n");
@@ -94,3 +120,382 @@ int disable_interrupts(void)
return (flags&0x200); /* IE flags is bit 9 */
}
+
+/* IRQ Low-Level Service Routine */
+__isr__ irq_llsr(int ip, int seg, int irq)
+{
+ /*
+ * For detailed description of each exception, refer to:
+ * Intel® 64 and IA-32 Architectures Software Developer's Manual
+ * Volume 1: Basic Architecture
+ * Order Number: 253665-029US, November 2008
+ * Table 6-1. Exceptions and Interrupts
+ */
+ switch (irq) {
+ case 0x00:
+ printf("Divide Error (Division by zero) at %04x:%08x\n", seg, ip);
+ while(1);
+ break;
+ case 0x01:
+ printf("Debug Interrupt (Single step) at %04x:%08x\n", seg, ip);
+ break;
+ case 0x02:
+ printf("NMI Interrupt at %04x:%08x\n", seg, ip);
+ break;
+ case 0x03:
+ printf("Breakpoint at %04x:%08x\n", seg, ip);
+ break;
+ case 0x04:
+ printf("Overflow at %04x:%08x\n", seg, ip);
+ while(1);
+ break;
+ case 0x05:
+ printf("BOUND Range Exceeded at %04x:%08x\n", seg, ip);
+ while(1);
+ break;
+ case 0x06:
+ printf("Invalid Opcode (UnDefined Opcode) at %04x:%08x\n", seg, ip);
+ while(1);
+ break;
+ case 0x07:
+ printf("Device Not Available (No Math Coprocessor) at %04x:%08x\n", seg, ip);
+ while(1);
+ break;
+ case 0x08:
+ printf("Double fault at %04x:%08x\n", seg, ip);
+ while(1);
+ break;
+ case 0x09:
+ printf("Co-processor segment overrun at %04x:%08x\n", seg, ip);
+ while(1);
+ break;
+ case 0x0a:
+ printf("Invalid TSS at %04x:%08x\n", seg, ip);
+ break;
+ case 0x0b:
+ printf("Segment Not Present at %04x:%08x\n", seg, ip);
+ while(1);
+ break;
+ case 0x0c:
+ printf("Stack Segment Fault at %04x:%08x\n", seg, ip);
+ while(1);
+ break;
+ case 0x0d:
+ printf("General Protection at %04x:%08x\n", seg, ip);
+ break;
+ case 0x0e:
+ printf("Page fault at %04x:%08x\n", seg, ip);
+ while(1);
+ break;
+ case 0x0f:
+ printf("Floating-Point Error (Math Fault) at %04x:%08x\n", seg, ip);
+ break;
+ case 0x10:
+ printf("Alignment check at %04x:%08x\n", seg, ip);
+ break;
+ case 0x11:
+ printf("Machine Check at %04x:%08x\n", seg, ip);
+ break;
+ case 0x12:
+ printf("SIMD Floating-Point Exception at %04x:%08x\n", seg, ip);
+ break;
+ case 0x13:
+ case 0x14:
+ case 0x15:
+ case 0x16:
+ case 0x17:
+ case 0x18:
+ case 0x19:
+ case 0x1a:
+ case 0x1b:
+ case 0x1c:
+ case 0x1d:
+ case 0x1e:
+ case 0x1f:
+ printf("Reserved Exception %d at %04x:%08x\n", irq, seg, ip);
+ break;
+
+ default:
+ /* Hardware or User IRQ */
+ do_irq(irq);
+ }
+}
+
+/*
+ * OK - This looks really horrible, but it serves a purpose - It helps create
+ * fully relocatable code.
+ * - The call to irq_llsr will be a relative jump
+ * - The IRQ entries will be guaranteed to be in order
+ * It's a bit annoying that we need to waste 3 bytes per interrupt entry
+ * (total of 768 code bytes), but we MUST create a Stack Frame and this is
+ * the easiest way I could do it. Maybe it can be made better later.
+ */
+asm(".globl irq_common_entry\n" \
+ ".hidden irq_common_entry\n" \
+ ".type irq_common_entry, @function\n" \
+ "irq_common_entry:\n" \
+ "pushl $0\n" \
+ "pushl $0\n" \
+ "call irq_llsr\n" \
+ "popl %eax\n" \
+ "popl %eax\n" \
+ "popl %eax\n" \
+ "popa\n" \
+ "leave\n"\
+ "iret\n" \
+ DECLARE_INTERRUPT(0) \
+ DECLARE_INTERRUPT(1) \
+ DECLARE_INTERRUPT(2) \
+ DECLARE_INTERRUPT(3) \
+ DECLARE_INTERRUPT(4) \
+ DECLARE_INTERRUPT(5) \
+ DECLARE_INTERRUPT(6) \
+ DECLARE_INTERRUPT(7) \
+ DECLARE_INTERRUPT(8) \
+ DECLARE_INTERRUPT(9) \
+ DECLARE_INTERRUPT(10) \
+ DECLARE_INTERRUPT(11) \
+ DECLARE_INTERRUPT(12) \
+ DECLARE_INTERRUPT(13) \
+ DECLARE_INTERRUPT(14) \
+ DECLARE_INTERRUPT(15) \
+ DECLARE_INTERRUPT(16) \
+ DECLARE_INTERRUPT(17) \
+ DECLARE_INTERRUPT(18) \
+ DECLARE_INTERRUPT(19) \
+ DECLARE_INTERRUPT(20) \
+ DECLARE_INTERRUPT(21) \
+ DECLARE_INTERRUPT(22) \
+ DECLARE_INTERRUPT(23) \
+ DECLARE_INTERRUPT(24) \
+ DECLARE_INTERRUPT(25) \
+ DECLARE_INTERRUPT(26) \
+ DECLARE_INTERRUPT(27) \
+ DECLARE_INTERRUPT(28) \
+ DECLARE_INTERRUPT(29) \
+ DECLARE_INTERRUPT(30) \
+ DECLARE_INTERRUPT(31) \
+ DECLARE_INTERRUPT(32) \
+ DECLARE_INTERRUPT(33) \
+ DECLARE_INTERRUPT(34) \
+ DECLARE_INTERRUPT(35) \
+ DECLARE_INTERRUPT(36) \
+ DECLARE_INTERRUPT(37) \
+ DECLARE_INTERRUPT(38) \
+ DECLARE_INTERRUPT(39) \
+ DECLARE_INTERRUPT(40) \
+ DECLARE_INTERRUPT(41) \
+ DECLARE_INTERRUPT(42) \
+ DECLARE_INTERRUPT(43) \
+ DECLARE_INTERRUPT(44) \
+ DECLARE_INTERRUPT(45) \
+ DECLARE_INTERRUPT(46) \
+ DECLARE_INTERRUPT(47) \
+ DECLARE_INTERRUPT(48) \
+ DECLARE_INTERRUPT(49) \
+ DECLARE_INTERRUPT(50) \
+ DECLARE_INTERRUPT(51) \
+ DECLARE_INTERRUPT(52) \
+ DECLARE_INTERRUPT(53) \
+ DECLARE_INTERRUPT(54) \
+ DECLARE_INTERRUPT(55) \
+ DECLARE_INTERRUPT(56) \
+ DECLARE_INTERRUPT(57) \
+ DECLARE_INTERRUPT(58) \
+ DECLARE_INTERRUPT(59) \
+ DECLARE_INTERRUPT(60) \
+ DECLARE_INTERRUPT(61) \
+ DECLARE_INTERRUPT(62) \
+ DECLARE_INTERRUPT(63) \
+ DECLARE_INTERRUPT(64) \
+ DECLARE_INTERRUPT(65) \
+ DECLARE_INTERRUPT(66) \
+ DECLARE_INTERRUPT(67) \
+ DECLARE_INTERRUPT(68) \
+ DECLARE_INTERRUPT(69) \
+ DECLARE_INTERRUPT(70) \
+ DECLARE_INTERRUPT(71) \
+ DECLARE_INTERRUPT(72) \
+ DECLARE_INTERRUPT(73) \
+ DECLARE_INTERRUPT(74) \
+ DECLARE_INTERRUPT(75) \
+ DECLARE_INTERRUPT(76) \
+ DECLARE_INTERRUPT(77) \
+ DECLARE_INTERRUPT(78) \
+ DECLARE_INTERRUPT(79) \
+ DECLARE_INTERRUPT(80) \
+ DECLARE_INTERRUPT(81) \
+ DECLARE_INTERRUPT(82) \
+ DECLARE_INTERRUPT(83) \
+ DECLARE_INTERRUPT(84) \
+ DECLARE_INTERRUPT(85) \
+ DECLARE_INTERRUPT(86) \
+ DECLARE_INTERRUPT(87) \
+ DECLARE_INTERRUPT(88) \
+ DECLARE_INTERRUPT(89) \
+ DECLARE_INTERRUPT(90) \
+ DECLARE_INTERRUPT(91) \
+ DECLARE_INTERRUPT(92) \
+ DECLARE_INTERRUPT(93) \
+ DECLARE_INTERRUPT(94) \
+ DECLARE_INTERRUPT(95) \
+ DECLARE_INTERRUPT(97) \
+ DECLARE_INTERRUPT(96) \
+ DECLARE_INTERRUPT(98) \
+ DECLARE_INTERRUPT(99) \
+ DECLARE_INTERRUPT(100) \
+ DECLARE_INTERRUPT(101) \
+ DECLARE_INTERRUPT(102) \
+ DECLARE_INTERRUPT(103) \
+ DECLARE_INTERRUPT(104) \
+ DECLARE_INTERRUPT(105) \
+ DECLARE_INTERRUPT(106) \
+ DECLARE_INTERRUPT(107) \
+ DECLARE_INTERRUPT(108) \
+ DECLARE_INTERRUPT(109) \
+ DECLARE_INTERRUPT(110) \
+ DECLARE_INTERRUPT(111) \
+ DECLARE_INTERRUPT(112) \
+ DECLARE_INTERRUPT(113) \
+ DECLARE_INTERRUPT(114) \
+ DECLARE_INTERRUPT(115) \
+ DECLARE_INTERRUPT(116) \
+ DECLARE_INTERRUPT(117) \
+ DECLARE_INTERRUPT(118) \
+ DECLARE_INTERRUPT(119) \
+ DECLARE_INTERRUPT(120) \
+ DECLARE_INTERRUPT(121) \
+ DECLARE_INTERRUPT(122) \
+ DECLARE_INTERRUPT(123) \
+ DECLARE_INTERRUPT(124) \
+ DECLARE_INTERRUPT(125) \
+ DECLARE_INTERRUPT(126) \
+ DECLARE_INTERRUPT(127) \
+ DECLARE_INTERRUPT(128) \
+ DECLARE_INTERRUPT(129) \
+ DECLARE_INTERRUPT(130) \
+ DECLARE_INTERRUPT(131) \
+ DECLARE_INTERRUPT(132) \
+ DECLARE_INTERRUPT(133) \
+ DECLARE_INTERRUPT(134) \
+ DECLARE_INTERRUPT(135) \
+ DECLARE_INTERRUPT(136) \
+ DECLARE_INTERRUPT(137) \
+ DECLARE_INTERRUPT(138) \
+ DECLARE_INTERRUPT(139) \
+ DECLARE_INTERRUPT(140) \
+ DECLARE_INTERRUPT(141) \
+ DECLARE_INTERRUPT(142) \
+ DECLARE_INTERRUPT(143) \
+ DECLARE_INTERRUPT(144) \
+ DECLARE_INTERRUPT(145) \
+ DECLARE_INTERRUPT(146) \
+ DECLARE_INTERRUPT(147) \
+ DECLARE_INTERRUPT(148) \
+ DECLARE_INTERRUPT(149) \
+ DECLARE_INTERRUPT(150) \
+ DECLARE_INTERRUPT(151) \
+ DECLARE_INTERRUPT(152) \
+ DECLARE_INTERRUPT(153) \
+ DECLARE_INTERRUPT(154) \
+ DECLARE_INTERRUPT(155) \
+ DECLARE_INTERRUPT(156) \
+ DECLARE_INTERRUPT(157) \
+ DECLARE_INTERRUPT(158) \
+ DECLARE_INTERRUPT(159) \
+ DECLARE_INTERRUPT(160) \
+ DECLARE_INTERRUPT(161) \
+ DECLARE_INTERRUPT(162) \
+ DECLARE_INTERRUPT(163) \
+ DECLARE_INTERRUPT(164) \
+ DECLARE_INTERRUPT(165) \
+ DECLARE_INTERRUPT(166) \
+ DECLARE_INTERRUPT(167) \
+ DECLARE_INTERRUPT(168) \
+ DECLARE_INTERRUPT(169) \
+ DECLARE_INTERRUPT(170) \
+ DECLARE_INTERRUPT(171) \
+ DECLARE_INTERRUPT(172) \
+ DECLARE_INTERRUPT(173) \
+ DECLARE_INTERRUPT(174) \
+ DECLARE_INTERRUPT(175) \
+ DECLARE_INTERRUPT(176) \
+ DECLARE_INTERRUPT(177) \
+ DECLARE_INTERRUPT(178) \
+ DECLARE_INTERRUPT(179) \
+ DECLARE_INTERRUPT(180) \
+ DECLARE_INTERRUPT(181) \
+ DECLARE_INTERRUPT(182) \
+ DECLARE_INTERRUPT(183) \
+ DECLARE_INTERRUPT(184) \
+ DECLARE_INTERRUPT(185) \
+ DECLARE_INTERRUPT(186) \
+ DECLARE_INTERRUPT(187) \
+ DECLARE_INTERRUPT(188) \
+ DECLARE_INTERRUPT(189) \
+ DECLARE_INTERRUPT(190) \
+ DECLARE_INTERRUPT(191) \
+ DECLARE_INTERRUPT(192) \
+ DECLARE_INTERRUPT(193) \
+ DECLARE_INTERRUPT(194) \
+ DECLARE_INTERRUPT(195) \
+ DECLARE_INTERRUPT(196) \
+ DECLARE_INTERRUPT(197) \
+ DECLARE_INTERRUPT(198) \
+ DECLARE_INTERRUPT(199) \
+ DECLARE_INTERRUPT(200) \
+ DECLARE_INTERRUPT(201) \
+ DECLARE_INTERRUPT(202) \
+ DECLARE_INTERRUPT(203) \
+ DECLARE_INTERRUPT(204) \
+ DECLARE_INTERRUPT(205) \
+ DECLARE_INTERRUPT(206) \
+ DECLARE_INTERRUPT(207) \
+ DECLARE_INTERRUPT(208) \
+ DECLARE_INTERRUPT(209) \
+ DECLARE_INTERRUPT(210) \
+ DECLARE_INTERRUPT(211) \
+ DECLARE_INTERRUPT(212) \
+ DECLARE_INTERRUPT(213) \
+ DECLARE_INTERRUPT(214) \
+ DECLARE_INTERRUPT(215) \
+ DECLARE_INTERRUPT(216) \
+ DECLARE_INTERRUPT(217) \
+ DECLARE_INTERRUPT(218) \
+ DECLARE_INTERRUPT(219) \
+ DECLARE_INTERRUPT(220) \
+ DECLARE_INTERRUPT(221) \
+ DECLARE_INTERRUPT(222) \
+ DECLARE_INTERRUPT(223) \
+ DECLARE_INTERRUPT(224) \
+ DECLARE_INTERRUPT(225) \
+ DECLARE_INTERRUPT(226) \
+ DECLARE_INTERRUPT(227) \
+ DECLARE_INTERRUPT(228) \
+ DECLARE_INTERRUPT(229) \
+ DECLARE_INTERRUPT(230) \
+ DECLARE_INTERRUPT(231) \
+ DECLARE_INTERRUPT(232) \
+ DECLARE_INTERRUPT(233) \
+ DECLARE_INTERRUPT(234) \
+ DECLARE_INTERRUPT(235) \
+ DECLARE_INTERRUPT(236) \
+ DECLARE_INTERRUPT(237) \
+ DECLARE_INTERRUPT(238) \
+ DECLARE_INTERRUPT(239) \
+ DECLARE_INTERRUPT(240) \
+ DECLARE_INTERRUPT(241) \
+ DECLARE_INTERRUPT(242) \
+ DECLARE_INTERRUPT(243) \
+ DECLARE_INTERRUPT(244) \
+ DECLARE_INTERRUPT(245) \
+ DECLARE_INTERRUPT(246) \
+ DECLARE_INTERRUPT(247) \
+ DECLARE_INTERRUPT(248) \
+ DECLARE_INTERRUPT(249) \
+ DECLARE_INTERRUPT(250) \
+ DECLARE_INTERRUPT(251) \
+ DECLARE_INTERRUPT(252) \
+ DECLARE_INTERRUPT(253) \
+ DECLARE_INTERRUPT(254) \
+ DECLARE_INTERRUPT(255));
diff --git a/cpu/i386/sc520/sc520_timer.c b/cpu/i386/sc520/sc520_timer.c
index 23de14b..93b5b55 100644
--- a/cpu/i386/sc520/sc520_timer.c
+++ b/cpu/i386/sc520/sc520_timer.c
@@ -35,6 +35,12 @@ void sc520_timer_isr(void)
int timer_init(void)
{
+ /* Register the SC520 specific timer interrupt handler */
+ register_timer_isr (sc520_timer_isr);
+
+ /* Install interrupt handler for GP Timer 1 */
+ irq_install_handler (0, timer_isr, NULL);
+
/* Map GP Timer 1 to Master PIC IR0 */
sc520_mmcr->gp_tmr_int_map[1] = 0x01;
@@ -54,11 +60,6 @@ int timer_init(void)
sc520_mmcr->gptmr1maxcmpa = 100;
sc520_mmcr->gptmr1ctl = 0xe009;
- /* Register the SC520 specific timer interrupt handler */
- register_timer_isr (sc520_timer_isr);
-
- /* Install interrupt handler for GP Timer 1 */
- irq_install_handler (0, timer_isr, NULL);
unmask_irq (0);
/* Clear the GP Timer 1 status register to get the show rolling*/
@@ -67,7 +68,7 @@ int timer_init(void)
return 0;
}
-void udelay(unsigned long usec)
+void __udelay(unsigned long usec)
{
int m = 0;
long u;
diff --git a/cpu/i386/start.S b/cpu/i386/start.S
index 59089ef..25d32e6 100644
--- a/cpu/i386/start.S
+++ b/cpu/i386/start.S
@@ -63,11 +63,8 @@ early_board_init_ret:
jmp mem_init
mem_init_ret:
- /* check ammount of configured memory
- * (we need atleast bss start+bss size+stack size) */
- movl $_i386boot_bss_start, %ecx /* BSS start */
- addl $_i386boot_bss_size, %ecx /* BSS size */
- addl $CONFIG_SYS_STACK_SIZE, %ecx
+ /* Check we have enough memory for stack */
+ movl $CONFIG_SYS_STACK_SIZE, %ecx
cmpl %ecx, %eax
jae mem_ok
@@ -78,6 +75,8 @@ mem_init_ret:
.progress0a:
jmp die
mem_ok:
+ /* Set stack pointer to upper memory limit*/
+ movl %eax, %esp
/* indicate progress */
movw $0x02, %ax
@@ -85,12 +84,7 @@ mem_ok:
jmp show_boot_progress_asm
.progress1:
- /* create a stack after the bss */
- movl $_i386boot_bss_start, %eax
- addl $_i386boot_bss_size, %eax
- addl $CONFIG_SYS_STACK_SIZE, %eax
- movl %eax, %esp
-
+ /* Test the stack */
pushl $0
popl %eax
cmpl $0, %eax
@@ -116,115 +110,19 @@ stack_ok:
jmp show_boot_progress_asm
.progress2:
- /* copy data section to ram, size must be 4-byte aligned */
- movl $_i386boot_romdata_dest, %edi /* destination address */
- movl $_i386boot_romdata_start, %esi /* source address */
- movl $_i386boot_romdata_size, %ecx /* number of bytes to copy */
- movl %ecx, %eax
- andl $3, %eax
- jnz data_fail
-
- shrl $2, %ecx /* copy 4 byte each time */
- cld
- cmpl $0, %ecx
- je data_ok
-data_segment:
- movsl
- loop data_segment
- jmp data_ok
-data_fail:
- /* indicate (lack of) progress */
- movw $0x83, %ax
- movl $.progress2a, %ebp
- jmp show_boot_progress_asm
-.progress2a:
- jmp die
-
-data_ok:
-
- /* indicate progress */
- movw $0x04, %ax
- movl $.progress3, %ebp
- jmp show_boot_progress_asm
-.progress3:
-
- /* clear bss section in ram, size must be 4-byte aligned */
- movl $_i386boot_bss_start, %edi /* MK_CHG BSS start */
- movl $_i386boot_bss_size, %ecx /* BSS size */
- movl %ecx, %eax
- andl $3, %eax
- jnz bss_fail
- shrl $2, %ecx /* clear 4 byte each time */
- cld
- cmpl $0, %ecx
- je bss_ok
-bss:
- movl $0, (%edi)
- add $4, %edi
- loop bss
- jmp bss_ok
-
-bss_fail:
- /* indicate (lack of) progress */
- movw $0x84, %ax
- movl $.progress3a, %ebp
- jmp show_boot_progress_asm
-.progress3a:
- jmp die
-
-bss_ok:
-#ifndef CONFIG_SKIP_RELOCATE_UBOOT
- /* indicate progress */
- movw $0x06, %ax
- movl $.progress6, %ebp
- jmp show_boot_progress_asm
-.progress6:
-
- /* copy text section to ram, size must be 4-byte aligned */
- movl $CONFIG_SYS_BL_START_RAM, %edi /* destination address */
- movl $TEXT_BASE, %esi /* source address */
- movl $_i386boot_text_size, %ecx /* number of bytes to copy */
- movl %ecx, %eax
- andl $3, %eax
- jz text_copy /* Already 4-byte aligned */
- subl $4, %eax /* Add extra bytes to size */
- addl %eax, %ecx
-text_copy:
- shrl $2, %ecx /* copy 4 byte each time */
- cld
- cmpl $0, %ecx
- je text_ok
-text_segment:
- movsl
- loop text_segment
- jmp text_ok
-text_fail:
- /* indicate (lack of) progress */
- movw $0x86, %ax
- movl $.progress5a, %ebp
- jmp show_boot_progress_asm
-.progress5a:
- jmp die
-
-text_ok:
-#endif
wbinvd
+ /* Get upper memory limit */
+ movl %esp, %ecx
+ subl $CONFIG_SYS_STACK_SIZE, %ecx
- /* indicate progress */
- movw $0x05, %ax
- movl $.progress4, %ebp
- jmp show_boot_progress_asm
-.progress4:
-
-#ifndef CONFIG_SKIP_RELOCATE_UBOOT
- /* Jump to the RAM copy of start_i386boot */
- movl $start_i386boot, %ebp
- addl $(CONFIG_SYS_BL_START_RAM - TEXT_BASE), %ebp
- call *%ebp /* Enter, U-boot! */
-#else
- call start_i386boot /* Enter, U-boot! */
-#endif
+ /* Create a Stack Frame */
+ pushl %ebp
+ movl %esp, %ebp
+
+ /* stack_limit parameter */
+ pushl %ecx
+ call board_init_f /* Enter, U-boot! */
/* indicate (lack of) progress */
movw $0x85, %ax
diff --git a/cpu/ixp/start.S b/cpu/ixp/start.S
index 196ba5d..5ebce53 100644
--- a/cpu/ixp/start.S
+++ b/cpu/ixp/start.S
@@ -505,8 +505,8 @@ reset_endless:
/*
* 0 <= r0 <= 2000
*/
-.globl udelay
-udelay:
+.globl __udelay
+__udelay:
mov r2, #0x6800
orr r2, r2, #0x00db
mul r0, r2, r0
diff --git a/cpu/ixp/timer.c b/cpu/ixp/timer.c
index 6856149..edf341f 100644
--- a/cpu/ixp/timer.c
+++ b/cpu/ixp/timer.c
@@ -99,7 +99,7 @@ void ixp425_udelay(unsigned long usec)
while (!(*IXP425_OSST & IXP425_OSST_TIMER_1_PEND));
}
-void udelay (unsigned long usec)
+void __udelay (unsigned long usec)
{
while (usec--) ixp425_udelay(1);
}
diff --git a/cpu/lh7a40x/timer.c b/cpu/lh7a40x/timer.c
index f9b5be0..2691315 100644
--- a/cpu/lh7a40x/timer.c
+++ b/cpu/lh7a40x/timer.c
@@ -90,7 +90,7 @@ void set_timer (ulong t)
timestamp = t;
}
-void udelay (unsigned long usec)
+void __udelay (unsigned long usec)
{
ulong tmo,tmp;
diff --git a/cpu/mcf547x_8x/slicetimer.c b/cpu/mcf547x_8x/slicetimer.c
index 67e8189..8dc010a 100644
--- a/cpu/mcf547x_8x/slicetimer.c
+++ b/cpu/mcf547x_8x/slicetimer.c
@@ -40,7 +40,7 @@ static ulong timestamp;
#endif
extern void dtimer_intr_setup(void);
-void udelay(unsigned long usec)
+void __udelay(unsigned long usec)
{
volatile slt_t *timerp = (slt_t *) (CONFIG_SYS_UDELAY_BASE);
u32 now, freq;
diff --git a/cpu/mpc512x/cpu.c b/cpu/mpc512x/cpu.c
index 42ccd81..dac48db 100644
--- a/cpu/mpc512x/cpu.c
+++ b/cpu/mpc512x/cpu.c
@@ -197,6 +197,7 @@ void ft_cpu_setup(void *blob, bd_t *bd)
#ifdef CONFIG_HAS_ETH0
fdt_fixup_ethernet(blob);
#endif
+ fdt_fixup_memory(blob, (u64)bd->bi_memstart, (u64)bd->bi_memsize);
}
#endif
diff --git a/cpu/mpc5xxx/cpu.c b/cpu/mpc5xxx/cpu.c
index efa64c7..2a28df4 100644
--- a/cpu/mpc5xxx/cpu.c
+++ b/cpu/mpc5xxx/cpu.c
@@ -157,6 +157,7 @@ void ft_cpu_setup(void *blob, bd_t *bd)
}
#endif
+ fdt_fixup_memory(blob, (u64)bd->bi_memstart, (u64)bd->bi_memsize);
}
#endif
diff --git a/cpu/mpc8260/cpu.c b/cpu/mpc8260/cpu.c
index 17e6248..aedbf29 100644
--- a/cpu/mpc8260/cpu.c
+++ b/cpu/mpc8260/cpu.c
@@ -318,6 +318,7 @@ void ft_cpu_setup (void *blob, bd_t *bd)
"timebase-frequency", OF_TBCLK, 1);
do_fixup_by_prop_u32(blob, "device_type", "cpu", 4,
"clock-frequency", bd->bi_intfreq, 1);
+ fdt_fixup_memory(blob, (u64)bd->bi_memstart, (u64)bd->bi_memsize);
}
#endif /* CONFIG_OF_LIBFDT */
diff --git a/cpu/mpc83xx/cpu_init.c b/cpu/mpc83xx/cpu_init.c
index 031e8d5..75b4522 100644
--- a/cpu/mpc83xx/cpu_init.c
+++ b/cpu/mpc83xx/cpu_init.c
@@ -70,6 +70,12 @@ void cpu_init_f (volatile immap_t * im)
#ifdef CONFIG_SYS_ACR_RPTCNT /* Arbiter repeat count */
(ACR_RPTCNT << ACR_RPTCNT_SHIFT) |
#endif
+#ifdef CONFIG_SYS_ACR_APARK /* Arbiter address parking mode */
+ (ACR_APARK << ACR_APARK_SHIFT) |
+#endif
+#ifdef CONFIG_SYS_ACR_PARKM /* Arbiter parking master */
+ (ACR_PARKM << ACR_PARKM_SHIFT) |
+#endif
0;
__be32 acr_val =
#ifdef CONFIG_SYS_ACR_PIPE_DEP /* Arbiter pipeline depth */
@@ -78,6 +84,12 @@ void cpu_init_f (volatile immap_t * im)
#ifdef CONFIG_SYS_ACR_RPTCNT /* Arbiter repeat count */
(CONFIG_SYS_ACR_RPTCNT << ACR_RPTCNT_SHIFT) |
#endif
+#ifdef CONFIG_SYS_ACR_APARK /* Arbiter address parking mode */
+ (CONFIG_SYS_ACR_APARK << ACR_APARK_SHIFT) |
+#endif
+#ifdef CONFIG_SYS_ACR_PARKM /* Arbiter parking master */
+ (CONFIG_SYS_ACR_PARKM << ACR_PARKM_SHIFT) |
+#endif
0;
__be32 spcr_mask =
#ifdef CONFIG_SYS_SPCR_OPT /* Optimize transactions between CSB and other dev */
@@ -171,6 +183,28 @@ void cpu_init_f (volatile immap_t * im)
(CONFIG_SYS_SCCR_SATACM << SCCR_SATACM_SHIFT) |
#endif
0;
+ __be32 lcrr_mask =
+#ifdef CONFIG_SYS_LCRR_DBYP /* PLL bypass */
+ LCRR_DBYP |
+#endif
+#ifdef CONFIG_SYS_LCRR_EADC /* external address delay */
+ LCRR_EADC |
+#endif
+#ifdef CONFIG_SYS_LCRR_CLKDIV /* system clock divider */
+ LCRR_CLKDIV |
+#endif
+ 0;
+ __be32 lcrr_val =
+#ifdef CONFIG_SYS_LCRR_DBYP /* PLL bypass */
+ CONFIG_SYS_LCRR_DBYP |
+#endif
+#ifdef CONFIG_SYS_LCRR_EADC
+ CONFIG_SYS_LCRR_EADC |
+#endif
+#ifdef CONFIG_SYS_LCRR_CLKDIV /* system clock divider */
+ CONFIG_SYS_LCRR_CLKDIV |
+#endif
+ 0;
/* Pointer is writable since we allocated a register for it */
gd = (gd_t *) (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET);
@@ -199,6 +233,13 @@ void cpu_init_f (volatile immap_t * im)
*/
__raw_writel(RMR_CSRE & (1<<RMR_CSRE_SHIFT), &im->reset.rmr);
+ /* LCRR - Clock Ratio Register (10.3.1.16)
+ * write, read, and isync per MPC8379ERM rev.1 CLKDEV field description
+ */
+ clrsetbits_be32(&im->lbus.lcrr, lcrr_mask, lcrr_val);
+ __raw_readl(&im->lbus.lcrr);
+ isync();
+
/* Enable Time Base & Decrementer ( so we will have udelay() )*/
setbits_be32(&im->sysconf.spcr, SPCR_TBEN);
@@ -331,41 +372,9 @@ void cpu_init_f (volatile immap_t * im)
int cpu_init_r (void)
{
- volatile immap_t *im = (volatile immap_t *)CONFIG_SYS_IMMR;
#ifdef CONFIG_QE
uint qe_base = CONFIG_SYS_IMMR + 0x00100000; /* QE immr base */
-#endif
- __be32 lcrr_mask =
-#ifdef CONFIG_SYS_LCRR_DBYP /* PLL bypass */
- LCRR_DBYP |
-#endif
-#ifdef CONFIG_SYS_LCRR_EADC /* external address delay */
- LCRR_EADC |
-#endif
-#ifdef CONFIG_SYS_LCRR_CLKDIV /* system clock divider */
- LCRR_CLKDIV |
-#endif
- 0;
- __be32 lcrr_val =
-#ifdef CONFIG_SYS_LCRR_DBYP /* PLL bypass */
- CONFIG_SYS_LCRR_DBYP |
-#endif
-#ifdef CONFIG_SYS_LCRR_EADC
- CONFIG_SYS_LCRR_EADC |
-#endif
-#ifdef CONFIG_SYS_LCRR_CLKDIV /* system clock divider */
- CONFIG_SYS_LCRR_CLKDIV |
-#endif
- 0;
- /* LCRR - Clock Ratio Register (10.3.1.16)
- * write, read, and isync per MPC8379ERM rev.1 CLKDEV field description
- */
- clrsetbits_be32(&im->lbus.lcrr, lcrr_mask, lcrr_val);
- __raw_readl(&im->lbus.lcrr);
- isync();
-
-#ifdef CONFIG_QE
qe_init(qe_base);
qe_reset();
#endif
diff --git a/cpu/mpc83xx/spd_sdram.c b/cpu/mpc83xx/spd_sdram.c
index 0f61180..44aaa9a 100644
--- a/cpu/mpc83xx/spd_sdram.c
+++ b/cpu/mpc83xx/spd_sdram.c
@@ -29,6 +29,7 @@
#include <common.h>
#include <asm/processor.h>
+#include <asm/io.h>
#include <i2c.h>
#include <spd.h>
#include <asm/mmu.h>
@@ -150,6 +151,14 @@ long int spd_sdram()
unsigned int ddrc_ecc_enable;
unsigned int pvr = get_pvr();
+ /*
+ * First disable the memory controller (could be enabled
+ * by the debugger)
+ */
+ clrsetbits_be32(&ddr->sdram_cfg, SDRAM_CFG_MEM_EN, 0);
+ sync();
+ isync();
+
/* Read SPD parameters with I2C */
CONFIG_SYS_READ_SPD(SPD_EEPROM_ADDRESS, 0, 1, (uchar *) & spd, sizeof (spd));
#ifdef SPD_DEBUG
diff --git a/cpu/mpc85xx/cpu_init.c b/cpu/mpc85xx/cpu_init.c
index 0041a60..e0126d3 100644
--- a/cpu/mpc85xx/cpu_init.c
+++ b/cpu/mpc85xx/cpu_init.c
@@ -246,6 +246,7 @@ void cpu_init_f (void)
#ifdef CONFIG_FSL_CORENET
corenet_tb_init();
#endif
+ init_used_tlb_cams();
}
@@ -357,6 +358,11 @@ int cpu_init_r(void)
while (mfspr(SPRN_L2CSR0) & (L2CSR0_L2FI|L2CSR0_L2LFC))
;
+#ifdef CONFIG_SYS_CACHE_STASHING
+ /* set stash id to (coreID) * 2 + 32 + L2 (1) */
+ mtspr(SPRN_L2CSR1, (32 + 1));
+#endif
+
/* enable the cache */
mtspr(SPRN_L2CSR0, CONFIG_SYS_INIT_L2CSR0);
diff --git a/cpu/mpc85xx/fdt.c b/cpu/mpc85xx/fdt.c
index de2dcac..af0e78e 100644
--- a/cpu/mpc85xx/fdt.c
+++ b/cpu/mpc85xx/fdt.c
@@ -197,6 +197,15 @@ static inline void ft_fixup_l2cache(void *blob)
goto next;
}
+#ifdef CONFIG_SYS_CACHE_STASHING
+ {
+ u32 *reg = (u32 *)fdt_getprop(blob, off, "reg", 0);
+ if (reg)
+ fdt_setprop_cell(blob, l2_off, "cache-stash-id",
+ (*reg * 2) + 32 + 1);
+ }
+#endif
+
fdt_setprop(blob, l2_off, "cache-unified", NULL, 0);
fdt_setprop_cell(blob, l2_off, "cache-block-size", line_size);
fdt_setprop_cell(blob, l2_off, "cache-size", size);
@@ -252,6 +261,15 @@ static inline void ft_fixup_cache(void *blob)
fdt_setprop_cell(blob, off, "d-cache-size", dsize);
fdt_setprop_cell(blob, off, "d-cache-sets", dnum_sets);
+#ifdef CONFIG_SYS_CACHE_STASHING
+ {
+ u32 *reg = (u32 *)fdt_getprop(blob, off, "reg", 0);
+ if (reg)
+ fdt_setprop_cell(blob, off, "cache-stash-id",
+ (*reg * 2) + 32 + 0);
+ }
+#endif
+
/* i-side config */
isize = (l1cfg1 & 0x7ff) * 1024;
inum_ways = ((l1cfg1 >> 11) & 0xff) + 1;
@@ -279,6 +297,40 @@ void fdt_add_enet_stashing(void *fdt)
do_fixup_by_compat_u32(fdt, "gianfar", "rx-stash-idx", 0, 1);
}
+#if defined(CONFIG_SYS_DPAA_FMAN) || defined(CONFIG_SYS_DPAA_PME)
+static void ft_fixup_clks(void *blob, const char *alias, unsigned long freq)
+{
+ const char *path = fdt_get_alias(blob, alias);
+
+ int off = fdt_path_offset(blob, path);
+
+ if (off >= 0) {
+ off = fdt_setprop_cell(blob, off, "clock-frequency", freq);
+ if (off > 0)
+ printf("WARNING enable to set clock-frequency "
+ "for %s: %s\n", alias, fdt_strerror(off));
+ }
+}
+
+static void ft_fixup_dpaa_clks(void *blob)
+{
+ sys_info_t sysinfo;
+
+ get_sys_info(&sysinfo);
+ ft_fixup_clks(blob, "fman0", sysinfo.freqFMan[0]);
+
+#if (CONFIG_SYS_NUM_FMAN == 2)
+ ft_fixup_clks(blob, "fman1", sysinfo.freqFMan[1]);
+#endif
+
+#ifdef CONFIG_SYS_DPAA_PME
+ ft_fixup_clks(blob, "pme", sysinfo.freqPME);
+#endif
+}
+#else
+#define ft_fixup_dpaa_clks(x)
+#endif
+
void ft_cpu_setup(void *blob, bd_t *bd)
{
int off;
@@ -342,4 +394,6 @@ void ft_cpu_setup(void *blob, bd_t *bd)
#if defined(CONFIG_FSL_ESDHC)
fdt_fixup_esdhc(blob, bd);
#endif
+
+ ft_fixup_dpaa_clks(blob);
}
diff --git a/cpu/mpc85xx/mp.c b/cpu/mpc85xx/mp.c
index 00b6450..6530cb1 100644
--- a/cpu/mpc85xx/mp.c
+++ b/cpu/mpc85xx/mp.c
@@ -90,11 +90,7 @@ int cpu_release(int nr, int argc, char *argv[])
return 1;
}
-#ifdef CONFIG_SYS_64BIT_STRTOUL
boot_addr = simple_strtoull(argv[0], NULL, 16);
-#else
- boot_addr = simple_strtoul(argv[0], NULL, 16);
-#endif
/* handle pir, r3, r6 */
for (i = 1; i < 4; i++) {
@@ -169,6 +165,9 @@ static void plat_mp_up(unsigned long bootpg)
e = find_law(bootpg);
out_be32(&ccm->bstrar, LAW_EN | e.trgt_id << 20 | LAW_SIZE_4K);
+ /* readback to sync write */
+ in_be32(&ccm->bstrar);
+
/* disable time base at the platform */
out_be32(&rcpm->ctbenrl, cpu_up_mask);
@@ -313,7 +312,7 @@ void setup_mp(void)
disable_tlb(i);
set_tlb(1, CONFIG_BPTR_VIRT_ADDR, bootpg, /* tlb, epn, rpn */
- MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I, /* perms, wimge */
+ MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, /* perms, wimge */
0, i, BOOKE_PAGESZ_4K, 1); /* ts, esel, tsize, iprot */
memcpy((void *)CONFIG_BPTR_VIRT_ADDR, (void *)fixup, 4096);
diff --git a/cpu/mpc85xx/release.S b/cpu/mpc85xx/release.S
index a1ae78a..00c4c54 100644
--- a/cpu/mpc85xx/release.S
+++ b/cpu/mpc85xx/release.S
@@ -99,21 +99,38 @@ __secondary_start_page:
slwi r8,r4,5
add r10,r3,r8
+#if defined(CONFIG_E500MC) && defined(CONFIG_SYS_CACHE_STASHING)
+ /* set stash id to (coreID) * 2 + 32 + L1 CT (0) */
+ slwi r8,r4,1
+ addi r8,r8,32
+ mtspr L1CSR2,r8
+#endif
+
#ifdef CONFIG_BACKSIDE_L2_CACHE
/* Enable/invalidate the L2 cache */
msync
- lis r3,(L2CSR0_L2FI|L2CSR0_L2LFC)@h
- ori r3,r3,(L2CSR0_L2FI|L2CSR0_L2LFC)@l
- mtspr SPRN_L2CSR0,r3
+ lis r2,(L2CSR0_L2FI|L2CSR0_L2LFC)@h
+ ori r2,r2,(L2CSR0_L2FI|L2CSR0_L2LFC)@l
+ mtspr SPRN_L2CSR0,r2
1:
mfspr r3,SPRN_L2CSR0
- andis. r1,r3,L2CSR0_L2FI@h
+ and. r1,r3,r2
bne 1b
+#ifdef CONFIG_SYS_CACHE_STASHING
+ /* set stash id to (coreID) * 2 + 32 + L2 (1) */
+ addi r3,r8,1
+ mtspr SPRN_L2CSR1,r3
+#endif
+
lis r3,CONFIG_SYS_INIT_L2CSR0@h
ori r3,r3,CONFIG_SYS_INIT_L2CSR0@l
mtspr SPRN_L2CSR0,r3
isync
+2:
+ mfspr r3,SPRN_L2CSR0
+ andis. r1,r3,L2CSR0_L2E@h
+ beq 2b
#endif
#define EPAPR_MAGIC (0x45504150)
@@ -149,8 +166,8 @@ __secondary_start_page:
lis r11,(MAS1_VALID|MAS1_IPROT)@h
ori r11,r11,(MAS1_TS|MAS1_TSIZE(BOOKE_PAGESZ_4K))@l
mtspr SPRN_MAS1,r11
- oris r11,r13,(MAS2_I)@h
- ori r11,r13,(MAS2_I)@l
+ oris r11,r13,(MAS2_I|MAS2_G)@h
+ ori r11,r13,(MAS2_I|MAS2_G)@l
mtspr SPRN_MAS2,r11
oris r11,r13,(MAS3_SX|MAS3_SW|MAS3_SR)@h
ori r11,r13,(MAS3_SX|MAS3_SW|MAS3_SR)@l
diff --git a/cpu/mpc85xx/speed.c b/cpu/mpc85xx/speed.c
index 7959082..2103e2e 100644
--- a/cpu/mpc85xx/speed.c
+++ b/cpu/mpc85xx/speed.c
@@ -103,21 +103,21 @@ void get_sys_info (sys_info_t * sysInfo)
#ifdef CONFIG_SYS_DPAA_PME
if (rcw_tmp & PME_CLK_SEL)
- sysInfo->freqPME = freqCC_PLL[2] / 2;
- else
sysInfo->freqPME = sysInfo->freqSystemBus / 2;
+ else
+ sysInfo->freqPME = freqCC_PLL[2] / 2;
#endif
#ifdef CONFIG_SYS_DPAA_FMAN
if (rcw_tmp & FM1_CLK_SEL)
- sysInfo->freqFMan[0] = freqCC_PLL[2] / 2;
- else
sysInfo->freqFMan[0] = sysInfo->freqSystemBus / 2;
+ else
+ sysInfo->freqFMan[0] = freqCC_PLL[2] / 2;
#if (CONFIG_SYS_NUM_FMAN) == 2
if (rcw_tmp & FM2_CLK_SEL)
- sysInfo->freqFMan[1] = freqCC_PLL[2] / 2;
- else
sysInfo->freqFMan[1] = sysInfo->freqSystemBus / 2;
+ else
+ sysInfo->freqFMan[1] = freqCC_PLL[2] / 2;
#endif
#endif
diff --git a/cpu/mpc85xx/start.S b/cpu/mpc85xx/start.S
index 6a86528..7e60e67 100644
--- a/cpu/mpc85xx/start.S
+++ b/cpu/mpc85xx/start.S
@@ -1,5 +1,5 @@
/*
- * Copyright 2004, 2007-2009 Freescale Semiconductor.
+ * Copyright 2004, 2007-2009 Freescale Semiconductor, Inc.
* Copyright (C) 2003 Motorola,Inc.
*
* See file CREDITS for list of people who contributed to this
@@ -102,6 +102,12 @@ _start_e500:
*
*/
+#if defined(CONFIG_E500MC) && defined(CONFIG_SYS_CACHE_STASHING)
+ /* set stash id to (coreID) * 2 + 32 + L1 CT (0) */
+ li r2,(32 + 0)
+ mtspr L1CSR2,r2
+#endif
+
lis r2,L1CSR0_CPE@H /* enable parity */
ori r2,r2,L1CSR0_DCE
mtspr L1CSR0,r2 /* enable L1 Dcache */
diff --git a/cpu/mpc85xx/tlb.c b/cpu/mpc85xx/tlb.c
index 6e94c23..b3037ac 100644
--- a/cpu/mpc85xx/tlb.c
+++ b/cpu/mpc85xx/tlb.c
@@ -56,12 +56,74 @@ void init_tlbs(void)
}
#ifndef CONFIG_NAND_SPL
+static inline void use_tlb_cam(u8 idx)
+{
+ int i = idx / 32;
+ int bit = idx % 32;
+
+ gd->used_tlb_cams[i] |= (1 << bit);
+}
+
+static inline void free_tlb_cam(u8 idx)
+{
+ int i = idx / 32;
+ int bit = idx % 32;
+
+ gd->used_tlb_cams[i] &= ~(1 << bit);
+}
+
+void init_used_tlb_cams(void)
+{
+ int i;
+ unsigned int num_cam = mfspr(SPRN_TLB1CFG) & 0xfff;
+
+ for (i = 0; i < ((CONFIG_SYS_NUM_TLBCAMS+31)/32); i++)
+ gd->used_tlb_cams[i] = 0;
+
+ /* walk all the entries */
+ for (i = 0; i < num_cam; i++) {
+ u32 _mas1;
+
+ mtspr(MAS0, FSL_BOOKE_MAS0(1, i, 0));
+
+ asm volatile("tlbre;isync");
+ _mas1 = mfspr(MAS1);
+
+ /* if the entry isn't valid skip it */
+ if ((_mas1 & MAS1_VALID))
+ use_tlb_cam(i);
+ }
+}
+
+int find_free_tlbcam(void)
+{
+ int i;
+ u32 idx;
+
+ for (i = 0; i < ((CONFIG_SYS_NUM_TLBCAMS+31)/32); i++) {
+ idx = ffz(gd->used_tlb_cams[i]);
+
+ if (idx != 32)
+ break;
+ }
+
+ idx += i * 32;
+
+ if (idx >= CONFIG_SYS_NUM_TLBCAMS)
+ return -1;
+
+ return idx;
+}
+
void set_tlb(u8 tlb, u32 epn, u64 rpn,
u8 perms, u8 wimge,
u8 ts, u8 esel, u8 tsize, u8 iprot)
{
u32 _mas0, _mas1, _mas2, _mas3, _mas7;
+ if (tlb == 1)
+ use_tlb_cam(esel);
+
_mas0 = FSL_BOOKE_MAS0(tlb, esel, 0);
_mas1 = FSL_BOOKE_MAS1(1, iprot, 0, ts, tsize);
_mas2 = FSL_BOOKE_MAS2(epn, wimge);
@@ -80,6 +142,8 @@ void disable_tlb(u8 esel)
{
u32 _mas0, _mas1, _mas2, _mas3, _mas7;
+ free_tlb_cam(esel);
+
_mas0 = FSL_BOOKE_MAS0(1, esel, 0);
_mas1 = 0;
_mas2 = 0;
@@ -132,10 +196,10 @@ int find_tlb_idx(void *addr, u8 tlbsel)
void init_addr_map(void)
{
int i;
- unsigned int max_cam = (mfspr(SPRN_TLB1CFG) >> 16) & 0xff;
+ unsigned int num_cam = mfspr(SPRN_TLB1CFG) & 0xfff;
/* walk all the entries */
- for (i = 0; i < max_cam; i++) {
+ for (i = 0; i < num_cam; i++) {
unsigned long epn;
u32 tsize, _mas1;
phys_addr_t rpn;
@@ -163,14 +227,10 @@ void init_addr_map(void)
}
#endif
-#ifndef CONFIG_SYS_DDR_TLB_START
-#define CONFIG_SYS_DDR_TLB_START 8
-#endif
-
unsigned int setup_ddr_tlbs(unsigned int memsize_in_meg)
{
+ int i;
unsigned int tlb_size;
- unsigned int ram_tlb_index = CONFIG_SYS_DDR_TLB_START;
unsigned int ram_tlb_address = (unsigned int)CONFIG_SYS_DDR_SDRAM_BASE;
unsigned int max_cam = (mfspr(SPRN_TLB1CFG) >> 16) & 0xf;
u64 size, memsize = (u64)memsize_in_meg << 20;
@@ -180,10 +240,14 @@ unsigned int setup_ddr_tlbs(unsigned int memsize_in_meg)
/* Convert (4^max) kB to (2^max) bytes */
max_cam = max_cam * 2 + 10;
- for (; size && ram_tlb_index < 16; ram_tlb_index++) {
+ for (i = 0; size && i < 8; i++) {
+ int ram_tlb_index = find_free_tlbcam();
u32 camsize = __ilog2_u64(size) & ~1U;
u32 align = __ilog2(ram_tlb_address) & ~1U;
+ if (ram_tlb_index == -1)
+ break;
+
if (align == -2) align = max_cam;
if (camsize > align)
camsize = align;
diff --git a/cpu/mpc85xx/u-boot-nand.lds b/cpu/mpc85xx/u-boot-nand.lds
index a0fc8f1..b4c63e2 100644
--- a/cpu/mpc85xx/u-boot-nand.lds
+++ b/cpu/mpc85xx/u-boot-nand.lds
@@ -58,7 +58,6 @@ SECTIONS
.text :
{
*(.text)
- *(.fixup)
*(.got1)
} :text
_etext = .;
diff --git a/cpu/mpc8xxx/ddr/ctrl_regs.c b/cpu/mpc8xxx/ddr/ctrl_regs.c
index 2505041..adc4f6e 100644
--- a/cpu/mpc8xxx/ddr/ctrl_regs.c
+++ b/cpu/mpc8xxx/ddr/ctrl_regs.c
@@ -188,12 +188,13 @@ static void set_timing_cfg_0(fsl_ddr_cfg_regs_t *ddr)
* The DDR3 spec has not tXARD,
* we use the tXP instead of it.
* tXP=max(3nCK, 7.5ns) for DDR3.
- * we use the tXP=6
* spec has not the tAXPD, we use
* tAXPD=8, need design to confirm.
*/
- act_pd_exit_mclk = 6;
- pre_pd_exit_mclk = 6;
+ int tXP = max((get_memory_clk_period_ps() * 3), 7500); /* unit=ps */
+ act_pd_exit_mclk = picos_to_mclk(tXP);
+ /* Mode register MR0[A12] is '1' - fast exit */
+ pre_pd_exit_mclk = act_pd_exit_mclk;
taxpd_mclk = 8;
tmrd_mclk = 4;
#else /* CONFIG_FSL_DDR2 */
@@ -575,18 +576,22 @@ static void set_ddr_sdram_cfg_2(fsl_ddr_cfg_regs_t *ddr,
}
/* DDR SDRAM Mode configuration 2 (DDR_SDRAM_MODE_2) */
-static void set_ddr_sdram_mode_2(fsl_ddr_cfg_regs_t *ddr)
+static void set_ddr_sdram_mode_2(fsl_ddr_cfg_regs_t *ddr,
+ const memctl_options_t *popts)
{
unsigned short esdmode2 = 0; /* Extended SDRAM mode 2 */
unsigned short esdmode3 = 0; /* Extended SDRAM mode 3 */
#if defined(CONFIG_FSL_DDR3)
- unsigned int rtt_wr = 2; /* 120 ohm Rtt_WR */
+ unsigned int rtt_wr = 0; /* Rtt_WR - dynamic ODT off */
unsigned int srt = 0; /* self-refresh temerature, normal range */
unsigned int asr = 0; /* auto self-refresh disable */
unsigned int cwl = compute_cas_write_latency() - 5;
unsigned int pasr = 0; /* partial array self refresh disable */
+ if (popts->rtt_override)
+ rtt_wr = popts->rtt_wr_override_value;
+
esdmode2 = (0
| ((rtt_wr & 0x3) << 9)
| ((srt & 0x1) << 7)
@@ -1001,8 +1006,8 @@ static void set_ddr_zq_cntl(fsl_ddr_cfg_regs_t *ddr, unsigned int zq_en)
}
/* DDR Write Leveling Control (DDR_WRLVL_CNTL) */
-static void set_ddr_wrlvl_cntl(fsl_ddr_cfg_regs_t *ddr,
- unsigned int wrlvl_en)
+static void set_ddr_wrlvl_cntl(fsl_ddr_cfg_regs_t *ddr, unsigned int wrlvl_en,
+ const memctl_options_t *popts)
{
/*
* First DQS pulse rising edge after margining mode
@@ -1029,8 +1034,9 @@ static void set_ddr_wrlvl_cntl(fsl_ddr_cfg_regs_t *ddr,
/* tWL_DQSEN min = 25 nCK, we set it 32 */
wrlvl_dqsen = 0x5;
/*
- * Write leveling sample time at least need 14 clocks
- * due to tWLO = 9, we set it 15 clocks
+ * Write leveling sample time at least need 6 clocks
+ * higher than tWLO to allow enough time for progagation
+ * delay and sampling the prime data bits.
*/
wrlvl_smpl = 0xf;
/*
@@ -1043,9 +1049,16 @@ static void set_ddr_wrlvl_cntl(fsl_ddr_cfg_regs_t *ddr,
* Write leveling start time
* The value use for the DQS_ADJUST for the first sample
* when write leveling is enabled.
- * we set it 1 clock delay
*/
wrlvl_start = 0x8;
+ /*
+ * Override the write leveling sample and start time
+ * according to specific board
+ */
+ if (popts->wrlvl_override) {
+ wrlvl_smpl = popts->wrlvl_sample;
+ wrlvl_start = popts->wrlvl_start;
+ }
}
ddr->ddr_wrlvl_cntl = (0
@@ -1184,7 +1197,10 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts,
/* Don't set up boundaries for other CS
* other than CS0, if bank interleaving
* is enabled and not CS2+CS3 interleaved.
+ * But we need to set the ODT_RD_CFG and
+ * ODT_WR_CFG for CS1_CONFIG here.
*/
+ set_csn_config(i, ddr, popts, dimm_params);
break;
}
@@ -1321,7 +1337,7 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts,
set_ddr_sdram_cfg_2(ddr, popts);
set_ddr_sdram_mode(ddr, popts, common_dimm,
cas_latency, additive_latency);
- set_ddr_sdram_mode_2(ddr);
+ set_ddr_sdram_mode_2(ddr, popts);
set_ddr_sdram_interval(ddr, popts, common_dimm);
set_ddr_data_init(ddr);
set_ddr_sdram_clk_cntl(ddr, popts);
@@ -1331,7 +1347,7 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts,
set_timing_cfg_5(ddr);
set_ddr_zq_cntl(ddr, zq_en);
- set_ddr_wrlvl_cntl(ddr, wrlvl_en);
+ set_ddr_wrlvl_cntl(ddr, wrlvl_en, popts);
set_ddr_sr_cntr(ddr, sr_it);
diff --git a/cpu/mpc8xxx/ddr/options.c b/cpu/mpc8xxx/ddr/options.c
index db44291..3dcd33d 100644
--- a/cpu/mpc8xxx/ddr/options.c
+++ b/cpu/mpc8xxx/ddr/options.c
@@ -22,9 +22,7 @@ unsigned int populate_memctl_options(int all_DIMMs_registered,
unsigned int ctrl_num)
{
unsigned int i;
-#if (CONFIG_NUM_DDR_CONTROLLERS > 1)
const char *p;
-#endif
/* Chip select options. */
@@ -200,6 +198,7 @@ unsigned int populate_memctl_options(int all_DIMMs_registered,
* meet the tQDSS under different loading.
*/
popts->wrlvl_en = 1;
+ popts->wrlvl_override = 0;
#endif
/*
@@ -242,8 +241,10 @@ unsigned int populate_memctl_options(int all_DIMMs_registered,
simple_strtoul(p, NULL, 0);
}
}
+#endif
- if( (p = getenv("ba_intlv_ctl")) != NULL) {
+ if( ((p = getenv("ba_intlv_ctl")) != NULL) &&
+ (CONFIG_CHIP_SELECTS_PER_CTRL > 1)) {
if (strcmp(p, "cs0_cs1") == 0)
popts->ba_intlv_ctl = FSL_DDR_CS0_CS1;
else if (strcmp(p, "cs2_cs3") == 0)
@@ -283,7 +284,6 @@ unsigned int populate_memctl_options(int all_DIMMs_registered,
break;
}
}
-#endif
fsl_ddr_board_options(popts, pdimm, ctrl_num);
diff --git a/cpu/mpc8xxx/pci_cfg.c b/cpu/mpc8xxx/pci_cfg.c
index 9c7d92c..d53781b 100644
--- a/cpu/mpc8xxx/pci_cfg.c
+++ b/cpu/mpc8xxx/pci_cfg.c
@@ -25,19 +25,14 @@
#include <pci.h>
struct pci_info {
- u16 agent;
u16 cfg;
};
-/* The agent field is a bit mask in which each bit represents the value of
- * cfg_host_agt[] signal and the bit is set of the given interface would be
- * in agent/end-point mode for the given interface.
- *
- * The same idea is true of the cfg field. The bit will be set if the
- * interface would be enabled based on the value of cfg_IO_ports[] signal
+/* The cfg field is a bit mask in which each bit represents the value of
+ * cfg_IO_ports[] signal and the bit is set if the interface would be
+ * enabled based on the value of cfg_IO_ports[] signal
*
* On MPC86xx/PQ3 based systems:
- * we extract cfg_host_agt from GUTS register PORBMSR
* we extract cfg_IO_ports from GUTS register PORDEVSR
*
* cfg_IO_ports only exist on systems w/PCIe (we set cfg 0 for systems
@@ -48,7 +43,6 @@ struct pci_info {
static struct pci_info pci_config_info[] =
{
[LAW_TRGT_IF_PCI] = {
- .agent = (1 << 0) | (1 << 2),
.cfg = 0,
},
};
@@ -56,7 +50,6 @@ static struct pci_info pci_config_info[] =
static struct pci_info pci_config_info[] =
{
[LAW_TRGT_IF_PCI] = {
- .agent = (1 << 0),
.cfg = 0,
},
};
@@ -64,19 +57,15 @@ static struct pci_info pci_config_info[] =
static struct pci_info pci_config_info[] =
{
[LAW_TRGT_IF_PCI] = {
- .agent = (1 << 6),
.cfg = 0,
},
[LAW_TRGT_IF_PCIE_1] = {
- .agent = (1 << 5),
.cfg = (1 << 2) | (1 << 3) | (1 << 5) | (1 << 7),
},
[LAW_TRGT_IF_PCIE_2] = {
- .agent = (1 << 3),
.cfg = (1 << 5) | (1 << 7),
},
[LAW_TRGT_IF_PCIE_3] = {
- .agent = (1 << 1),
.cfg = (1 << 7),
},
};
@@ -84,20 +73,16 @@ static struct pci_info pci_config_info[] =
static struct pci_info pci_config_info[] =
{
[LAW_TRGT_IF_PCI] = {
- .agent = (1 << 6),
.cfg = 0,
},
[LAW_TRGT_IF_PCIE_1] = {
- .agent = (1 << 5),
.cfg = (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5) |
(1 << 6) | (1 << 7),
},
[LAW_TRGT_IF_PCIE_2] = {
- .agent = (1 << 3),
.cfg = (1 << 4) | (1 << 5) | (1 << 6) | (1 << 7),
},
[LAW_TRGT_IF_PCIE_3] = {
- .agent = (1 << 1),
.cfg = (1 << 6) | (1 << 7),
},
};
@@ -105,16 +90,13 @@ static struct pci_info pci_config_info[] =
static struct pci_info pci_config_info[] =
{
[LAW_TRGT_IF_PCI_1] = {
- .agent = (1 << 4) | (1 << 6),
.cfg = 0,
},
[LAW_TRGT_IF_PCI_2] = {
- .agent = (1 << 4) | (1 << 6),
.cfg = 0,
},
/* PCI_2 is always host and we dont use iosel to determine enable/disable */
[LAW_TRGT_IF_PCIE_1] = {
- .agent = (1 << 0) | (1 << 2),
.cfg = (1 << 3) | (1 << 4) | (1 << 7),
},
};
@@ -122,11 +104,9 @@ static struct pci_info pci_config_info[] =
static struct pci_info pci_config_info[] =
{
[LAW_TRGT_IF_PCI] = {
- .agent = (1 << 0) | (1 << 4) | (1 << 6),
.cfg = 0,
},
[LAW_TRGT_IF_PCIE_1] = {
- .agent = (1 << 0) | (1 << 2) | (1 << 4),
.cfg = (1 << 3) | (1 << 4) | (1 << 7),
},
};
@@ -134,7 +114,6 @@ static struct pci_info pci_config_info[] =
static struct pci_info pci_config_info[] =
{
[LAW_TRGT_IF_PCIE_1] = {
- .agent = (1 << 0) | (1 << 6),
.cfg = (1 << 0) | (1 << 4) | (1 << 5) | (1 << 6) | (1 << 7) |
(1 << 8) | (1 << 0xc) | (1 << 0xf),
},
@@ -143,16 +122,13 @@ static struct pci_info pci_config_info[] =
static struct pci_info pci_config_info[] =
{
[LAW_TRGT_IF_PCIE_1] = {
- .agent = (1 << 0) | (1 << 1) | (1 << 4) | (1 << 5),
.cfg = (1 << 2) | (1 << 3) | (1 << 7) |
(1 << 0xb) | (1 << 0xc) | (1 << 0xf),
},
[LAW_TRGT_IF_PCIE_2] = {
- .agent = (1 << 0) | (1 << 2) | (1 << 4) | (1 << 6),
.cfg = (1 << 3) | (1 << 7),
},
[LAW_TRGT_IF_PCIE_3] = {
- .agent = (1 << 0) | (1 << 3) | (1 << 5) | (1 << 6),
.cfg = (1 << 7),
},
};
@@ -160,15 +136,12 @@ static struct pci_info pci_config_info[] =
static struct pci_info pci_config_info[] =
{
[LAW_TRGT_IF_PCI_1] = {
- .agent = (1 << 4) | (1 << 5) | (1 << 6),
.cfg = 0,
},
[LAW_TRGT_IF_PCIE_1] = {
- .agent = (1 << 0) | (1 << 2) | (1 << 5),
.cfg = (1 << 1) | (1 << 4),
},
[LAW_TRGT_IF_PCIE_2] = {
- .agent = (1 << 0) | (1 << 1) | (1 << 4),
.cfg = (1 << 0) | (1 << 4),
},
};
@@ -176,7 +149,6 @@ static struct pci_info pci_config_info[] =
static struct pci_info pci_config_info[] =
{
[LAW_TRGT_IF_PCIE_1] = {
- .agent = 0, /* we dont use agent on 8641 */
.cfg = (1 << 2) | (1 << 3) | (1 << 5) | (1 << 6) |
(1 << 7) | (1 << 0xe) | (1 << 0xf),
},
@@ -185,11 +157,9 @@ static struct pci_info pci_config_info[] =
static struct pci_info pci_config_info[] =
{
[LAW_TRGT_IF_PCIE_1] = {
- .agent = (1 << 0) | (1 << 1),
.cfg = (1 << 0) | (1 << 6) | (1 << 0xe) | (1 << 0xf),
},
[LAW_TRGT_IF_PCIE_2] = {
- .agent = (1 << 0) | (1 << 2),
.cfg = (1 << 0xe),
},
};
@@ -197,29 +167,24 @@ static struct pci_info pci_config_info[] =
static struct pci_info pci_config_info[] =
{
[LAW_TRGT_IF_PCIE_1] = {
- .agent = (1 << 0) | (1 << 1) | (1 << 4) | (1 << 5),
.cfg = (1 << 0) | (1 << 2) | (1 << 4) | (1 << 6) |
(1 << 0xd) | (1 << 0xe) | (1 << 0xf),
},
[LAW_TRGT_IF_PCIE_2] = {
- .agent = (1 << 0) | (1 << 2) | (1 << 4) | (1 << 6),
.cfg = (1 << 2) | (1 << 0xe),
},
[LAW_TRGT_IF_PCIE_3] = {
- .agent = (1 << 0) | (1 << 3) | (1 << 5) | (1 << 6),
.cfg = (1 << 2) | (1 << 4),
},
};
+#elif defined(CONFIG_FSL_CORENET)
#else
#error Need to define pci_config_info for processor
#endif
-int is_fsl_pci_agent(enum law_trgt_if trgt, u32 host_agent)
-{
- return ((1 << host_agent) & pci_config_info[trgt].agent);
-}
-
+#ifndef CONFIG_FSL_CORENET
int is_fsl_pci_cfg(enum law_trgt_if trgt, u32 io_sel)
{
return ((1 << io_sel) & pci_config_info[trgt].cfg);
}
+#endif
diff --git a/cpu/ppc4xx/44x_spd_ddr2.c b/cpu/ppc4xx/44x_spd_ddr2.c
index 3975306..f8aa14a 100644
--- a/cpu/ppc4xx/44x_spd_ddr2.c
+++ b/cpu/ppc4xx/44x_spd_ddr2.c
@@ -3160,7 +3160,7 @@ inline void ppc4xx_ibm_ddr2_register_dump(void)
PPC4xx_IBM_DDR2_DUMP_REGISTER(SDTR3);
PPC4xx_IBM_DDR2_DUMP_REGISTER(MMODE);
PPC4xx_IBM_DDR2_DUMP_REGISTER(MEMODE);
- PPC4xx_IBM_DDR2_DUMP_REGISTER(ECCCR);
+ PPC4xx_IBM_DDR2_DUMP_REGISTER(ECCES);
#if (defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \
defined(CONFIG_460EX) || defined(CONFIG_460GT))
PPC4xx_IBM_DDR2_DUMP_REGISTER(CID);
diff --git a/cpu/ppc4xx/4xx_pci.c b/cpu/ppc4xx/4xx_pci.c
index fa521f0..eed4534 100644
--- a/cpu/ppc4xx/4xx_pci.c
+++ b/cpu/ppc4xx/4xx_pci.c
@@ -73,23 +73,30 @@
#include <common.h>
#include <command.h>
-#if !defined(CONFIG_440)
#include <asm/4xx_pci.h>
-#endif
#include <asm/processor.h>
+#include <asm/io.h>
#include <pci.h>
#ifdef CONFIG_PCI
DECLARE_GLOBAL_DATA_PTR;
+#if defined(CONFIG_405GP) || defined(CONFIG_405EP)
+
+#if defined(CONFIG_PMC405)
+ushort pmc405_pci_subsys_deviceid(void);
+#endif
+
+/*#define DEBUG*/
+
/*
* Board-specific pci initialization
* Platform code can reimplement pci_pre_init() if needed
*/
int __pci_pre_init(struct pci_controller *hose)
{
-#if defined (CONFIG_405EP)
+#if defined(CONFIG_405EP)
/*
* Enable the internal PCI arbiter by default.
*
@@ -105,15 +112,8 @@ int __pci_pre_init(struct pci_controller *hose)
return 1;
}
-int pci_pre_init(struct pci_controller *hose) __attribute__((weak, alias("__pci_pre_init")));
-
-#if defined(CONFIG_405GP) || defined(CONFIG_405EP)
-
-#if defined(CONFIG_PMC405)
-ushort pmc405_pci_subsys_deviceid(void);
-#endif
-
-/*#define DEBUG*/
+int pci_pre_init(struct pci_controller *hose)
+ __attribute__((weak, alias("__pci_pre_init")));
int __is_pci_host(struct pci_controller *hose)
{
@@ -231,7 +231,7 @@ void pci_405gp_init(struct pci_controller *hose)
pciauto_region_init(hose->pci_fb);
/* Let board change/modify hose & do initial checks */
- if (pci_pre_init (hose) == 0) {
+ if (pci_pre_init(hose) == 0) {
printf("PCI: Board-specific initialization failed.\n");
printf("PCI: Configuration aborted.\n");
return;
@@ -478,6 +478,231 @@ void pci_init_board(void)
static struct pci_controller ppc440_hose = {0};
+/*
+ * This routine is called to determine if a pci scan should be
+ * performed. With various hardware environments (especially cPCI and
+ * PPMC) it's insufficient to depend on the state of the arbiter enable
+ * bit in the strap register, or generic host/adapter assumptions.
+ *
+ * Rather than hard-code a bad assumption in the general 440 code, the
+ * 440 pci code requires the board to decide at runtime.
+ *
+ * Return 0 for adapter mode, non-zero for host (monarch) mode.
+ *
+ * Weak default implementation: "Normal" boards implement the PCI
+ * host functionality. This can be overridden for PCI adapter boards.
+ */
+int __is_pci_host(struct pci_controller *hose)
+{
+ return 1;
+}
+int is_pci_host(struct pci_controller *hose)
+ __attribute__((weak, alias("__is_pci_host")));
+
+#if defined(CONFIG_440EP) || defined(CONFIG_440EPX) || \
+ defined(CONFIG_440GR) || defined(CONFIG_440GRX)
+
+#if defined(CONFIG_SYS_PCI_TARGET_INIT)
+/*
+ * pci_target_init
+ *
+ * The bootstrap configuration provides default settings for the pci
+ * inbound map (PIM). But the bootstrap config choices are limited and
+ * may not be sufficient for a given board.
+ */
+void __pci_target_init(struct pci_controller *hose)
+{
+ /*
+ * Set up Direct MMIO registers
+ */
+
+ /*
+ * PowerPC440 EP PCI Master configuration.
+ * Map one 1Gig range of PLB/processor addresses to PCI memory space.
+ * PLB address 0xA0000000-0xDFFFFFFF ==> PCI address 0xA0000000-0xDFFFFFFF
+ * Use byte reversed out routines to handle endianess.
+ * Make this region non-prefetchable.
+ */
+ /* PMM0 Mask/Attribute - disabled b4 setting */
+ out_le32((void *)PCIL0_PMM0MA, 0x00000000);
+ /* PMM0 Local Address */
+ out_le32((void *)PCIL0_PMM0LA, CONFIG_SYS_PCI_MEMBASE);
+ /* PMM0 PCI Low Address */
+ out_le32((void *)PCIL0_PMM0PCILA, CONFIG_SYS_PCI_MEMBASE);
+ /* PMM0 PCI High Address */
+ out_le32((void *)PCIL0_PMM0PCIHA, 0x00000000);
+ /* 512M + No prefetching, and enable region */
+ out_le32((void *)PCIL0_PMM0MA, 0xE0000001);
+
+ /* PMM1 Mask/Attribute - disabled b4 setting */
+ out_le32((void *)PCIL0_PMM1MA, 0x00000000);
+ /* PMM1 Local Address */
+ out_le32((void *)PCIL0_PMM1LA, CONFIG_SYS_PCI_MEMBASE2);
+ /* PMM1 PCI Low Address */
+ out_le32((void *)PCIL0_PMM1PCILA, CONFIG_SYS_PCI_MEMBASE2);
+ /* PMM1 PCI High Address */
+ out_le32((void *)PCIL0_PMM1PCIHA, 0x00000000);
+ /* 512M + No prefetching, and enable region */
+ out_le32((void *)PCIL0_PMM1MA, 0xE0000001);
+
+ out_le32((void *)PCIL0_PTM1MS, 0x00000001); /* Memory Size/Attribute */
+ out_le32((void *)PCIL0_PTM1LA, 0); /* Local Addr. Reg */
+ out_le32((void *)PCIL0_PTM2MS, 0); /* Memory Size/Attribute */
+ out_le32((void *)PCIL0_PTM2LA, 0); /* Local Addr. Reg */
+
+ /*
+ * Set up Configuration registers
+ */
+
+ /* Program the board's subsystem id/vendor id */
+ pci_write_config_word(0, PCI_SUBSYSTEM_VENDOR_ID,
+ CONFIG_SYS_PCI_SUBSYS_VENDORID);
+ pci_write_config_word(0, PCI_SUBSYSTEM_ID, CONFIG_SYS_PCI_SUBSYS_ID);
+
+ /* Configure command register as bus master */
+ pci_write_config_word(0, PCI_COMMAND, PCI_COMMAND_MASTER);
+
+ /* 240nS PCI clock */
+ pci_write_config_word(0, PCI_LATENCY_TIMER, 1);
+
+ /* No error reporting */
+ pci_write_config_word(0, PCI_ERREN, 0);
+
+ pci_write_config_dword(0, PCI_BRDGOPT2, 0x00000101);
+}
+#endif /* CONFIG_SYS_PCI_TARGET_INIT */
+
+/*
+ * pci_pre_init
+ *
+ * This routine is called just prior to registering the hose and gives
+ * the board the opportunity to check things. Returning a value of zero
+ * indicates that things are bad & PCI initialization should be aborted.
+ *
+ * Different boards may wish to customize the pci controller structure
+ * (add regions, override default access routines, etc) or perform
+ * certain pre-initialization actions.
+ *
+ */
+int __pci_pre_init(struct pci_controller *hose)
+{
+ u32 reg;
+
+ /*
+ * Set priority for all PLB3 devices to 0.
+ * Set PLB3 arbiter to fair mode.
+ */
+ mfsdr(SD0_AMP1, reg);
+ mtsdr(SD0_AMP1, (reg & 0x000000FF) | 0x0000FF00);
+ reg = mfdcr(PLB3_ACR);
+ mtdcr(PLB3_ACR, reg | 0x80000000);
+
+ /*
+ * Set priority for all PLB4 devices to 0.
+ */
+ mfsdr(SD0_AMP0, reg);
+ mtsdr(SD0_AMP0, (reg & 0x000000FF) | 0x0000FF00);
+ reg = mfdcr(PLB4_ACR) | 0xa0000000;
+ mtdcr(PLB4_ACR, reg);
+
+ /*
+ * Set Nebula PLB4 arbiter to fair mode.
+ */
+ /* Segment0 */
+ reg = (mfdcr(PLB0_ACR) & ~PLB0_ACR_PPM_MASK) | PLB0_ACR_PPM_FAIR;
+ reg = (reg & ~PLB0_ACR_HBU_MASK) | PLB0_ACR_HBU_ENABLED;
+ reg = (reg & ~PLB0_ACR_RDP_MASK) | PLB0_ACR_RDP_4DEEP;
+ reg = (reg & ~PLB0_ACR_WRP_MASK) | PLB0_ACR_WRP_2DEEP;
+ mtdcr(PLB0_ACR, reg);
+
+ /* Segment1 */
+ reg = (mfdcr(PLB1_ACR) & ~PLB1_ACR_PPM_MASK) | PLB1_ACR_PPM_FAIR;
+ reg = (reg & ~PLB1_ACR_HBU_MASK) | PLB1_ACR_HBU_ENABLED;
+ reg = (reg & ~PLB1_ACR_RDP_MASK) | PLB1_ACR_RDP_4DEEP;
+ reg = (reg & ~PLB1_ACR_WRP_MASK) | PLB1_ACR_WRP_2DEEP;
+ mtdcr(PLB1_ACR, reg);
+
+#if defined(CONFIG_SYS_PCI_BOARD_FIXUP_IRQ)
+ hose->fixup_irq = board_pci_fixup_irq;
+#endif
+
+ return 1;
+}
+
+#else /* defined(CONFIG_440EP) ... */
+
+#if defined(CONFIG_SYS_PCI_TARGET_INIT)
+void __pci_target_init(struct pci_controller * hose)
+{
+ /*
+ * Disable everything
+ */
+ out_le32((void *)PCIL0_PIM0SA, 0); /* disable */
+ out_le32((void *)PCIL0_PIM1SA, 0); /* disable */
+ out_le32((void *)PCIL0_PIM2SA, 0); /* disable */
+ out_le32((void *)PCIL0_EROMBA, 0); /* disable expansion rom */
+
+ /*
+ * Map all of SDRAM to PCI address 0x0000_0000. Note that the 440
+ * strapping options do not support sizes such as 128/256 MB.
+ */
+ out_le32((void *)PCIL0_PIM0LAL, CONFIG_SYS_SDRAM_BASE);
+ out_le32((void *)PCIL0_PIM0LAH, 0);
+ out_le32((void *)PCIL0_PIM0SA, ~(gd->ram_size - 1) | 1);
+ out_le32((void *)PCIL0_BAR0, 0);
+
+ /*
+ * Program the board's subsystem id/vendor id
+ */
+ out_le16((void *)PCIL0_SBSYSVID, CONFIG_SYS_PCI_SUBSYS_VENDORID);
+ out_le16((void *)PCIL0_SBSYSID, CONFIG_SYS_PCI_SUBSYS_DEVICEID);
+
+ out_le16((void *)PCIL0_CMD, in_le16((void *)PCIL0_CMD) |
+ PCI_COMMAND_MEMORY);
+}
+#endif /* CONFIG_SYS_PCI_TARGET_INIT */
+
+int __pci_pre_init(struct pci_controller *hose)
+{
+ /*
+ * This board is always configured as the host & requires the
+ * PCI arbiter to be enabled.
+ */
+ if (!pci_arbiter_enabled()) {
+ printf("PCI: PCI Arbiter disabled!\n");
+ return 0;
+ }
+
+ return 1;
+}
+
+#endif /* defined(CONFIG_440EP) ... */
+
+#if defined(CONFIG_SYS_PCI_TARGET_INIT)
+void pci_target_init(struct pci_controller * hose)
+ __attribute__((weak, alias("__pci_target_init")));
+#endif /* CONFIG_SYS_PCI_TARGET_INIT */
+
+int pci_pre_init(struct pci_controller *hose)
+ __attribute__((weak, alias("__pci_pre_init")));
+
+#if defined(CONFIG_SYS_PCI_MASTER_INIT)
+void __pci_master_init(struct pci_controller *hose)
+{
+ u16 reg;
+
+ /*
+ * Write the PowerPC440 EP PCI Configuration regs.
+ * Enable PowerPC440 EP to be a master on the PCI bus (PMM).
+ * Enable PowerPC440 EP to act as a PCI memory target (PTM).
+ */
+ pci_read_config_word(0, PCI_COMMAND, &reg);
+ pci_write_config_word(0, PCI_COMMAND, reg |
+ PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
+}
+void pci_master_init(struct pci_controller *hose)
+ __attribute__((weak, alias("__pci_master_init")));
+#endif /* CONFIG_SYS_PCI_MASTER_INIT */
int pci_440_init (struct pci_controller *hose)
{
@@ -548,7 +773,7 @@ int pci_440_init (struct pci_controller *hose)
pci_setup_indirect(hose, PCIL0_CFGADR, PCIL0_CFGDATA);
/* Let board change/modify hose & do initial checks */
- if (pci_pre_init (hose) == 0) {
+ if (pci_pre_init(hose) == 0) {
printf("PCI: Board-specific initialization failed.\n");
printf("PCI: Configuration aborted.\n");
return -1;
diff --git a/cpu/ppc4xx/4xx_pcie.c b/cpu/ppc4xx/4xx_pcie.c
index 19d2c7d..d9605c3 100644
--- a/cpu/ppc4xx/4xx_pcie.c
+++ b/cpu/ppc4xx/4xx_pcie.c
@@ -48,6 +48,125 @@ enum {
LNKW_X8 = 0x8
};
+static struct pci_controller pcie_hose[CONFIG_SYS_PCIE_NR_PORTS];
+
+/*
+ * Per default, all cards are present, so we need to check if the
+ * link comes up.
+ */
+int __board_pcie_card_present(int port)
+{
+ return 1;
+}
+int board_pcie_card_present(int port)
+ __attribute__((weak, alias("__board_pcie_card_present")));
+
+/*
+ * Some boards have runtime detection of the first and last PCIe
+ * slot used, so let's provide weak default functions for the
+ * common version.
+ */
+int __board_pcie_first(void)
+{
+ return 0;
+}
+int board_pcie_first(void)
+ __attribute__((weak, alias("__board_pcie_first")));
+
+int __board_pcie_last(void)
+{
+ return CONFIG_SYS_PCIE_NR_PORTS - 1;
+}
+int board_pcie_last(void)
+ __attribute__((weak, alias("__board_pcie_last")));
+
+void __board_pcie_setup_port(int port, int rootpoint)
+{
+ /* noting in this weak default implementation */
+}
+void board_pcie_setup_port(int port, int rootpoint)
+ __attribute__((weak, alias("__board_pcie_setup_port")));
+
+void pcie_setup_hoses(int busno)
+{
+ struct pci_controller *hose;
+ int i, bus;
+ int ret = 0;
+ char *env;
+ unsigned int delay;
+ int first = board_pcie_first();
+ int last = board_pcie_last();
+
+ /*
+ * Assume we're called after the PCI(X) hose(s) are initialized,
+ * which takes bus ID 0... and therefore start numbering PCIe's
+ * from the next number.
+ */
+ bus = busno;
+
+ for (i = first; i <= last; i++) {
+ /*
+ * Some boards (e.g. Katmai) can detects via hardware
+ * if a PCIe card is plugged, so let's check this.
+ */
+ if (!board_pcie_card_present(i))
+ continue;
+
+ if (is_end_point(i)) {
+ board_pcie_setup_port(i, 0);
+ ret = ppc4xx_init_pcie_endport(i);
+ } else {
+ board_pcie_setup_port(i, 1);
+ ret = ppc4xx_init_pcie_rootport(i);
+ }
+ if (ret == -ENODEV)
+ continue;
+ if (ret) {
+ printf("PCIE%d: initialization as %s failed\n", i,
+ is_end_point(i) ? "endpoint" : "root-complex");
+ continue;
+ }
+
+ hose = &pcie_hose[i];
+ hose->first_busno = bus;
+ hose->last_busno = bus;
+ hose->current_busno = bus;
+
+ /* setup mem resource */
+ pci_set_region(hose->regions + 0,
+ CONFIG_SYS_PCIE_MEMBASE + i * CONFIG_SYS_PCIE_MEMSIZE,
+ CONFIG_SYS_PCIE_MEMBASE + i * CONFIG_SYS_PCIE_MEMSIZE,
+ CONFIG_SYS_PCIE_MEMSIZE,
+ PCI_REGION_MEM);
+ hose->region_count = 1;
+ pci_register_hose(hose);
+
+ if (is_end_point(i)) {
+ ppc4xx_setup_pcie_endpoint(hose, i);
+ /*
+ * Reson for no scanning is endpoint can not generate
+ * upstream configuration accesses.
+ */
+ } else {
+ ppc4xx_setup_pcie_rootpoint(hose, i);
+ env = getenv ("pciscandelay");
+ if (env != NULL) {
+ delay = simple_strtoul(env, NULL, 10);
+ if (delay > 5)
+ printf("Warning, expect noticable delay before "
+ "PCIe scan due to 'pciscandelay' value!\n");
+ mdelay(delay * 1000);
+ }
+
+ /*
+ * Config access can only go down stream
+ */
+ hose->last_busno = pci_hose_scan(hose);
+ bus = hose->last_busno + 1;
+ }
+ }
+}
+
static int validate_endpoint(struct pci_controller *hose)
{
if (hose->cfg_data == (u8 *)CONFIG_SYS_PCIE0_CFGBASE)
diff --git a/cpu/ppc4xx/cmd_chip_config.c b/cpu/ppc4xx/cmd_chip_config.c
index d360d5b..ba57211 100644
--- a/cpu/ppc4xx/cmd_chip_config.c
+++ b/cpu/ppc4xx/cmd_chip_config.c
@@ -52,6 +52,12 @@ static int do_chip_config(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
int cur_config_nr = -1;
u8 cur_config[CONFIG_4xx_CONFIG_BLOCKSIZE];
+ /*
+ * First switch to correct I2C bus. This is I2C bus 0
+ * for all currently available 4xx derivats.
+ */
+ I2C_SET_BUS(0);
+
#ifdef CONFIG_CMD_EEPROM
ret = eeprom_read(CONFIG_4xx_CONFIG_I2C_EEPROM_ADDR,
CONFIG_4xx_CONFIG_I2C_EEPROM_OFFSET,
diff --git a/cpu/ppc4xx/config.mk b/cpu/ppc4xx/config.mk
index 00ad39b..979004b 100644
--- a/cpu/ppc4xx/config.mk
+++ b/cpu/ppc4xx/config.mk
@@ -32,3 +32,6 @@ PLATFORM_CPPFLAGS += -Wa,-m440 -mcpu=440
else
PLATFORM_CPPFLAGS += -Wa,-m405 -mcpu=405
endif
+
+# Use default linker script. Board port can override in board/*/config.mk
+LDSCRIPT := $(SRCTREE)/cpu/ppc4xx/u-boot.lds
diff --git a/cpu/ppc4xx/cpu.c b/cpu/ppc4xx/cpu.c
index e1b00a7..73d4d06 100644
--- a/cpu/ppc4xx/cpu.c
+++ b/cpu/ppc4xx/cpu.c
@@ -81,7 +81,7 @@ static int pci_async_enabled(void)
#if defined(CONFIG_PCI) && !defined(CONFIG_IOP480) && \
!defined(CONFIG_405) && !defined(CONFIG_405EX)
-static int pci_arbiter_enabled(void)
+int pci_arbiter_enabled(void)
{
#if defined(CONFIG_405GP)
return (mfdcr(CPC0_PSR) & PSR_PCI_ARBIT_EN);
diff --git a/cpu/ppc4xx/i2c.c b/cpu/ppc4xx/i2c.c
index e3e1bab..7976e75 100644
--- a/cpu/ppc4xx/i2c.c
+++ b/cpu/ppc4xx/i2c.c
@@ -1,5 +1,5 @@
/*
- * (C) Copyright 2007
+ * (C) Copyright 2007-2009
* Stefan Roese, DENX Software Engineering, sr@denx.de.
*
* based on work by Anne Sophie Harnois <anne-sophie.harnois@nextream.fr>
@@ -37,7 +37,8 @@
DECLARE_GLOBAL_DATA_PTR;
#if defined(CONFIG_I2C_MULTI_BUS)
-/* Initialize the bus pointer to whatever one the SPD EEPROM is on.
+/*
+ * Initialize the bus pointer to whatever one the SPD EEPROM is on.
* Default is bus 0. This is necessary because the DDR initialization
* runs from ROM, and we can't switch buses because we can't modify
* the global variables.
@@ -45,59 +46,63 @@ DECLARE_GLOBAL_DATA_PTR;
#ifndef CONFIG_SYS_SPD_BUS_NUM
#define CONFIG_SYS_SPD_BUS_NUM 0
#endif
-static unsigned int i2c_bus_num __attribute__ ((section (".data"))) = CONFIG_SYS_SPD_BUS_NUM;
+static unsigned int i2c_bus_num __attribute__ ((section (".data"))) =
+ CONFIG_SYS_SPD_BUS_NUM;
#endif /* CONFIG_I2C_MULTI_BUS */
static void _i2c_bus_reset(void)
{
+ struct ppc4xx_i2c *i2c = (struct ppc4xx_i2c *)I2C_BASE_ADDR;
int i;
u8 dc;
/* Reset status register */
/* write 1 in SCMP and IRQA to clear these fields */
- out_8((u8 *)IIC_STS, 0x0A);
+ out_8(&i2c->sts, 0x0A);
/* write 1 in IRQP IRQD LA ICT XFRA to clear these fields */
- out_8((u8 *)IIC_EXTSTS, 0x8F);
+ out_8(&i2c->extsts, 0x8F);
/* Place chip in the reset state */
- out_8((u8 *)IIC_XTCNTLSS, IIC_XTCNTLSS_SRST);
+ out_8(&i2c->xtcntlss, IIC_XTCNTLSS_SRST);
/* Check if bus is free */
- dc = in_8((u8 *)IIC_DIRECTCNTL);
+ dc = in_8(&i2c->directcntl);
if (!DIRCTNL_FREE(dc)){
/* Try to set bus free state */
- out_8((u8 *)IIC_DIRECTCNTL, IIC_DIRCNTL_SDAC | IIC_DIRCNTL_SCC);
+ out_8(&i2c->directcntl, IIC_DIRCNTL_SDAC | IIC_DIRCNTL_SCC);
/* Wait until we regain bus control */
for (i = 0; i < 100; ++i) {
- dc = in_8((u8 *)IIC_DIRECTCNTL);
+ dc = in_8(&i2c->directcntl);
if (DIRCTNL_FREE(dc))
break;
/* Toggle SCL line */
dc ^= IIC_DIRCNTL_SCC;
- out_8((u8 *)IIC_DIRECTCNTL, dc);
+ out_8(&i2c->directcntl, dc);
udelay(10);
dc ^= IIC_DIRCNTL_SCC;
- out_8((u8 *)IIC_DIRECTCNTL, dc);
+ out_8(&i2c->directcntl, dc);
}
}
/* Remove reset */
- out_8((u8 *)IIC_XTCNTLSS, 0);
+ out_8(&i2c->xtcntlss, 0);
}
-void i2c_init(int speed, int slaveadd)
+void i2c_init(int speed, int slaveaddr)
{
- unsigned long freqOPB;
+ struct ppc4xx_i2c *i2c = (struct ppc4xx_i2c *)I2C_BASE_ADDR;
int val, divisor;
int bus;
#ifdef CONFIG_SYS_I2C_INIT_BOARD
- /* call board specific i2c bus reset routine before accessing the */
- /* environment, which might be in a chip on that bus. For details */
- /* about this problem see doc/I2C_Edge_Conditions. */
+ /*
+ * Call board specific i2c bus reset routine before accessing the
+ * environment, which might be in a chip on that bus. For details
+ * about this problem see doc/I2C_Edge_Conditions.
+ */
i2c_init_board();
#endif
@@ -109,54 +114,52 @@ void i2c_init(int speed, int slaveadd)
_i2c_bus_reset();
/* clear lo master address */
- out_8((u8 *)IIC_LMADR, 0);
+ out_8(&i2c->lmadr, 0);
/* clear hi master address */
- out_8((u8 *)IIC_HMADR, 0);
+ out_8(&i2c->hmadr, 0);
/* clear lo slave address */
- out_8((u8 *)IIC_LSADR, 0);
+ out_8(&i2c->lsadr, 0);
/* clear hi slave address */
- out_8((u8 *)IIC_HSADR, 0);
+ out_8(&i2c->hsadr, 0);
/* Clock divide Register */
- /* get OPB frequency */
- freqOPB = get_OPB_freq();
- /* set divisor according to freqOPB */
- divisor = (freqOPB - 1) / 10000000;
+ /* set divisor according to freq_opb */
+ divisor = (get_OPB_freq() - 1) / 10000000;
if (divisor == 0)
divisor = 1;
- out_8((u8 *)IIC_CLKDIV, divisor);
+ out_8(&i2c->clkdiv, divisor);
/* no interrupts */
- out_8((u8 *)IIC_INTRMSK, 0);
+ out_8(&i2c->intrmsk, 0);
/* clear transfer count */
- out_8((u8 *)IIC_XFRCNT, 0);
+ out_8(&i2c->xfrcnt, 0);
/* clear extended control & stat */
/* write 1 in SRC SRS SWC SWS to clear these fields */
- out_8((u8 *)IIC_XTCNTLSS, 0xF0);
+ out_8(&i2c->xtcntlss, 0xF0);
/* Mode Control Register
Flush Slave/Master data buffer */
- out_8((u8 *)IIC_MDCNTL, IIC_MDCNTL_FSDB | IIC_MDCNTL_FMDB);
+ out_8(&i2c->mdcntl, IIC_MDCNTL_FSDB | IIC_MDCNTL_FMDB);
- val = in_8((u8 *)IIC_MDCNTL);
+ val = in_8(&i2c->mdcntl);
/* Ignore General Call, slave transfers are ignored,
* disable interrupts, exit unknown bus state, enable hold
* SCL 100kHz normaly or FastMode for 400kHz and above
*/
- val |= IIC_MDCNTL_EUBS|IIC_MDCNTL_HSCL;
+ val |= IIC_MDCNTL_EUBS | IIC_MDCNTL_HSCL;
if (speed >= 400000)
val |= IIC_MDCNTL_FSM;
- out_8((u8 *)IIC_MDCNTL, val);
+ out_8(&i2c->mdcntl, val);
/* clear control reg */
- out_8((u8 *)IIC_CNTL, 0x00);
+ out_8(&i2c->cntl, 0x00);
}
/* set to SPD bus as default bus upon powerup */
@@ -195,13 +198,14 @@ static int i2c_transfer(unsigned char cmd_type,
unsigned char data[],
unsigned short data_len)
{
- unsigned char* ptr;
+ struct ppc4xx_i2c *i2c = (struct ppc4xx_i2c *)I2C_BASE_ADDR;
+ u8 *ptr;
int reading;
- int tran,cnt;
+ int tran, cnt;
int result;
int status;
int i;
- uchar creg;
+ u8 creg;
if (data == 0 || data_len == 0) {
/* Don't support data transfer of no length or to address 0 */
@@ -219,12 +223,13 @@ static int i2c_transfer(unsigned char cmd_type,
}
/* Clear Stop Complete Bit */
- out_8((u8 *)IIC_STS, IIC_STS_SCMP);
+ out_8(&i2c->sts, IIC_STS_SCMP);
+
/* Check init */
i = 10;
do {
/* Get status */
- status = in_8((u8 *)IIC_STS);
+ status = in_8(&i2c->sts);
i--;
} while ((status & IIC_STS_PT) && (i > 0));
@@ -232,13 +237,16 @@ static int i2c_transfer(unsigned char cmd_type,
result = IIC_NOK_TOUT;
return(result);
}
+
/* flush the Master/Slave Databuffers */
- out_8((u8 *)IIC_MDCNTL, ((in_8((u8 *)IIC_MDCNTL))|IIC_MDCNTL_FMDB|IIC_MDCNTL_FSDB));
+ out_8(&i2c->mdcntl, in_8(&i2c->mdcntl) |
+ IIC_MDCNTL_FMDB | IIC_MDCNTL_FSDB);
+
/* need to wait 4 OPB clocks? code below should take that long */
/* 7-bit adressing */
- out_8((u8 *)IIC_HMADR, 0);
- out_8((u8 *)IIC_LMADR, chip);
+ out_8(&i2c->hmadr, 0);
+ out_8(&i2c->lmadr, chip);
tran = 0;
result = IIC_OK;
@@ -247,9 +255,10 @@ static int i2c_transfer(unsigned char cmd_type,
while (tran != cnt && (result == IIC_OK)) {
int bc,j;
- /* Control register =
- * Normal transfer, 7-bits adressing, Transfer up to bc bytes, Normal start,
- * Transfer is a sequence of transfers
+ /*
+ * Control register =
+ * Normal transfer, 7-bits adressing, Transfer up to
+ * bc bytes, Normal start, Transfer is a sequence of transfers
*/
creg |= IIC_CNTL_PT;
@@ -259,32 +268,36 @@ static int i2c_transfer(unsigned char cmd_type,
if ((!cmd_type && (ptr == addr)) || ((tran + bc) != cnt))
creg |= IIC_CNTL_CHT;
- if (reading)
+ if (reading) {
creg |= IIC_CNTL_READ;
- else
- for(j=0; j < bc; j++)
+ } else {
+ for(j = 0; j < bc; j++) {
/* Set buffer */
- out_8((u8 *)IIC_MDBUF, ptr[tran+j]);
- out_8((u8 *)IIC_CNTL, creg);
+ out_8(&i2c->mdbuf, ptr[tran + j]);
+ }
+ }
+ out_8(&i2c->cntl, creg);
- /* Transfer is in progress
+ /*
+ * Transfer is in progress
* we have to wait for upto 5 bytes of data
* 1 byte chip address+r/w bit then bc bytes
* of data.
* udelay(10) is 1 bit time at 100khz
* Doubled for slop. 20 is too small.
*/
- i = 2*5*8;
+ i = 2 * 5 * 8;
do {
/* Get status */
- status = in_8((u8 *)IIC_STS);
+ status = in_8(&i2c->sts);
udelay(10);
i--;
- } while ((status & IIC_STS_PT) && !(status & IIC_STS_ERR) && (i > 0));
+ } while ((status & IIC_STS_PT) && !(status & IIC_STS_ERR) &&
+ (i > 0));
if (status & IIC_STS_ERR) {
result = IIC_NOK;
- status = in_8((u8 *)IIC_EXTSTS);
+ status = in_8(&i2c->extsts);
/* Lost arbitration? */
if (status & IIC_EXTSTS_LA)
result = IIC_NOK_LA;
@@ -297,19 +310,21 @@ static int i2c_transfer(unsigned char cmd_type,
} else if ( status & IIC_STS_PT) {
result = IIC_NOK_TOUT;
}
+
/* Command is reading => get buffer */
if ((reading) && (result == IIC_OK)) {
/* Are there data in buffer */
if (status & IIC_STS_MDBS) {
/*
- * even if we have data we have to wait 4OPB clocks
- * for it to hit the front of the FIFO, after that
- * we can just read. We should check XFCNT here and
- * if the FIFO is full there is no need to wait.
+ * even if we have data we have to wait 4OPB
+ * clocks for it to hit the front of the FIFO,
+ * after that we can just read. We should check
+ * XFCNT here and if the FIFO is full there is
+ * no need to wait.
*/
udelay(1);
- for (j=0; j<bc; j++)
- ptr[tran+j] = in_8((u8 *)IIC_MDBUF);
+ for (j = 0; j < bc; j++)
+ ptr[tran + j] = in_8(&i2c->mdbuf);
} else
result = IIC_NOK_DATA;
}
@@ -324,7 +339,7 @@ static int i2c_transfer(unsigned char cmd_type,
creg = IIC_CNTL_RPST;
}
}
- return (result);
+ return result;
}
int i2c_probe(uchar chip)
@@ -338,17 +353,17 @@ int i2c_probe(uchar chip)
* address was <ACK>ed (i.e. there was a chip at that address which
* drove the data line low).
*/
- return (i2c_transfer(1, chip << 1, 0,0, buf, 1) != 0);
+ return (i2c_transfer(1, chip << 1, 0, 0, buf, 1) != 0);
}
-
-int i2c_read(uchar chip, uint addr, int alen, uchar * buffer, int len)
+static int ppc4xx_i2c_transfer(uchar chip, uint addr, int alen, uchar *buffer,
+ int len, int read)
{
uchar xaddr[4];
int ret;
if (alen > 4) {
- printf ("I2C read: addr len %d not supported\n", alen);
+ printf("I2C: addr len %d not supported\n", alen);
return 1;
}
@@ -373,50 +388,30 @@ int i2c_read(uchar chip, uint addr, int alen, uchar * buffer, int len)
* hidden in the chip address.
*/
if (alen > 0)
- chip |= ((addr >> (alen * 8)) & CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW);
+ chip |= ((addr >> (alen * 8)) &
+ CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW);
#endif
- if ((ret = i2c_transfer(1, chip<<1, &xaddr[4-alen], alen, buffer, len)) != 0) {
- if (gd->have_console)
- printf( "I2c read: failed %d\n", ret);
+ if ((ret = i2c_transfer(read, chip << 1, &xaddr[4 - alen], alen,
+ buffer, len)) != 0) {
+ if (gd->have_console) {
+ printf("I2C %s: failed %d\n",
+ read ? "read" : "write", ret);
+ }
+
return 1;
}
+
return 0;
}
-int i2c_write(uchar chip, uint addr, int alen, uchar * buffer, int len)
+int i2c_read(uchar chip, uint addr, int alen, uchar * buffer, int len)
{
- uchar xaddr[4];
-
- if (alen > 4) {
- printf ("I2C write: addr len %d not supported\n", alen);
- return 1;
-
- }
-
- if (alen > 0) {
- xaddr[0] = (addr >> 24) & 0xFF;
- xaddr[1] = (addr >> 16) & 0xFF;
- xaddr[2] = (addr >> 8) & 0xFF;
- xaddr[3] = addr & 0xFF;
- }
-
-#ifdef CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW
- /*
- * EEPROM chips that implement "address overflow" are ones
- * like Catalyst 24WC04/08/16 which has 9/10/11 bits of
- * address and the extra bits end up in the "chip address"
- * bit slots. This makes a 24WC08 (1Kbyte) chip look like
- * four 256 byte chips.
- *
- * Note that we consider the length of the address field to
- * still be one byte because the extra address bits are
- * hidden in the chip address.
- */
- if (alen > 0)
- chip |= ((addr >> (alen * 8)) & CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW);
-#endif
+ return ppc4xx_i2c_transfer(chip, addr, alen, buffer, len, 1);
+}
- return (i2c_transfer(0, chip<<1, &xaddr[4-alen], alen, buffer, len ) != 0);
+int i2c_write(uchar chip, uint addr, int alen, uchar * buffer, int len)
+{
+ return ppc4xx_i2c_transfer(chip, addr, alen, buffer, len, 0);
}
#if defined(CONFIG_I2C_MULTI_BUS)
diff --git a/cpu/ppc4xx/u-boot.lds b/cpu/ppc4xx/u-boot.lds
new file mode 100644
index 0000000..2b47934
--- /dev/null
+++ b/cpu/ppc4xx/u-boot.lds
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2007-2009 Freescale Semiconductor, Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include "config.h" /* CONFIG_BOARDDIR */
+
+#ifndef RESET_VECTOR_ADDRESS
+#define RESET_VECTOR_ADDRESS 0xfffffffc
+#endif
+
+OUTPUT_ARCH(powerpc)
+/* Do we need any of these for elf?
+ __DYNAMIC = 0; */
+PHDRS
+{
+ text PT_LOAD;
+ bss PT_LOAD;
+}
+
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = + SIZEOF_HEADERS;
+ .interp : { *(.interp) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .rel.text : { *(.rel.text) }
+ .rela.text : { *(.rela.text) }
+ .rel.data : { *(.rel.data) }
+ .rela.data : { *(.rela.data) }
+ .rel.rodata : { *(.rel.rodata) }
+ .rela.rodata : { *(.rela.rodata) }
+ .rel.got : { *(.rel.got) }
+ .rela.got : { *(.rela.got) }
+ .rel.ctors : { *(.rel.ctors) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rel.dtors : { *(.rel.dtors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rel.bss : { *(.rel.bss) }
+ .rela.bss : { *(.rela.bss) }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .init : { *(.init) }
+ .plt : { *(.plt) }
+ .text :
+ {
+ *(.text)
+ *(.got1)
+ } :text
+ _etext = .;
+ PROVIDE (etext = .);
+ .rodata :
+ {
+ *(.eh_frame)
+ *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
+ } :text
+ .fini : { *(.fini) } =0
+ .ctors : { *(.ctors) }
+ .dtors : { *(.dtors) }
+
+ /* Read-write section, merged into data segment: */
+ . = (. + 0x00FF) & 0xFFFFFF00;
+ _erotext = .;
+ PROVIDE (erotext = .);
+ .reloc :
+ {
+ *(.got)
+ _GOT2_TABLE_ = .;
+ *(.got2)
+ _FIXUP_TABLE_ = .;
+ *(.fixup)
+ }
+ __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2;
+ __fixup_entries = (. - _FIXUP_TABLE_) >> 2;
+
+ .data :
+ {
+ *(.data)
+ *(.data1)
+ *(.sdata)
+ *(.sdata2)
+ *(.dynamic)
+ CONSTRUCTORS
+ }
+ _edata = .;
+ PROVIDE (edata = .);
+
+ . = .;
+ __u_boot_cmd_start = .;
+ .u_boot_cmd : { *(.u_boot_cmd) }
+ __u_boot_cmd_end = .;
+
+ . = .;
+ __start___ex_table = .;
+ __ex_table : { *(__ex_table) }
+ __stop___ex_table = .;
+
+ . = ALIGN(256);
+ __init_begin = .;
+ .text.init : { *(.text.init) }
+ .data.init : { *(.data.init) }
+ . = ALIGN(256);
+ __init_end = .;
+
+#ifdef CONFIG_440
+ .bootpg RESET_VECTOR_ADDRESS - 0xffc :
+ {
+ cpu/ppc4xx/start.o (.bootpg)
+
+ /*
+ * PPC440 board need a board specific object with the
+ * TLB definitions. This needs to get included right after
+ * start.o, since the first shadow TLB only covers 4k
+ * of address space.
+ */
+ CONFIG_BOARDDIR/init.o (.bootpg)
+ } :text = 0xffff
+#endif
+
+ .resetvec RESET_VECTOR_ADDRESS :
+ {
+ *(.resetvec)
+ } :text = 0xffff
+
+ . = RESET_VECTOR_ADDRESS + 0x4;
+
+ /*
+ * Make sure that the bss segment isn't linked at 0x0, otherwise its
+ * address won't be updated during relocation fixups. Note that
+ * this is a temporary fix. Code to dynamically the fixup the bss
+ * location will be added in the future. When the bss relocation
+ * fixup code is present this workaround should be removed.
+ */
+#if (RESET_VECTOR_ADDRESS == 0xfffffffc)
+ . |= 0x10;
+#endif
+
+ __bss_start = .;
+ .bss (NOLOAD) :
+ {
+ *(.sbss) *(.scommon)
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ } :bss
+
+ . = ALIGN(4);
+ _end = . ;
+ PROVIDE (end = .);
+}
diff --git a/cpu/ppc4xx/usbdev.c b/cpu/ppc4xx/usbdev.c
index 5bb4f3c..fe398af 100644
--- a/cpu/ppc4xx/usbdev.c
+++ b/cpu/ppc4xx/usbdev.c
@@ -21,7 +21,7 @@ void process_endpoints(unsigned short usb2d0_intrin)
{
/*will hold the packet received */
struct usb_device_descriptor usb_device_packet;
- struct usb_config_descriptor usb_config_packet;
+ struct usb_configuration_descriptor usb_config_packet;
struct usb_string_descriptor usb_string_packet;
struct devrequest setup_packet;
unsigned int *setup_packet_pt;
@@ -99,7 +99,7 @@ void process_endpoints(unsigned short usb2d0_intrin)
usb_config_packet.bConfigurationValue = 1;
usb_config_packet.iConfiguration = 0;
usb_config_packet.bmAttributes = 0x40;
- usb_config_packet.MaxPower = 0;
+ usb_config_packet.bMaxPower = 0;
/*put packet in fifo */
packet_pt = (unsigned char *)&usb_config_packet;
diff --git a/cpu/pxa/timer.c b/cpu/pxa/timer.c
index e2df3a5..8d0f826 100644
--- a/cpu/pxa/timer.c
+++ b/cpu/pxa/timer.c
@@ -78,7 +78,7 @@ void set_timer (ulong t)
/* nop */
}
-void udelay (unsigned long usec)
+void __udelay (unsigned long usec)
{
udelay_masked (usec);
}
diff --git a/cpu/s3c44b0/timer.c b/cpu/s3c44b0/timer.c
index 34184ab..6f1d8f6 100644
--- a/cpu/s3c44b0/timer.c
+++ b/cpu/s3c44b0/timer.c
@@ -75,7 +75,7 @@ void set_timer (ulong t)
timestamp = t;
}
-void udelay (unsigned long usec)
+void __udelay (unsigned long usec)
{
ulong tmo;
diff --git a/cpu/sa1100/timer.c b/cpu/sa1100/timer.c
index 3f77e81..0207501 100644
--- a/cpu/sa1100/timer.c
+++ b/cpu/sa1100/timer.c
@@ -49,7 +49,7 @@ void set_timer (ulong t)
/* nop */
}
-void udelay (unsigned long usec)
+void __udelay (unsigned long usec)
{
udelay_masked (usec);
}