summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorWolfgang Denk <wd@denx.de>2010-09-09 21:39:46 +0200
committerWolfgang Denk <wd@denx.de>2010-09-09 21:39:46 +0200
commit8fea51a4acb0c7da6fb375c9a708c50c0a1b66ad (patch)
treef6a3d36e35f8f4d1009c367417e918c210b0baf0 /arch
parent40e74c852b76accfe27d832f23ea3020352bc120 (diff)
parentec99d983418897b120409f71712d41c01a21bf7c (diff)
downloadtalos-obmc-uboot-8fea51a4acb0c7da6fb375c9a708c50c0a1b66ad.tar.gz
talos-obmc-uboot-8fea51a4acb0c7da6fb375c9a708c50c0a1b66ad.zip
Merge branch 'master' of git://git.denx.de/u-boot-arm
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/cpu/arm926ejs/at91/Makefile1
-rw-r--r--arch/arm/cpu/arm926ejs/at91/at91sam9260_devices.c56
-rw-r--r--arch/arm/cpu/arm926ejs/at91/eflash.c271
-rw-r--r--arch/arm/cpu/arm926ejs/at91/reset.c21
-rw-r--r--arch/arm/cpu/arm926ejs/at91/timer.c5
-rw-r--r--arch/arm/cpu/arm926ejs/kirkwood/cpu.c2
-rw-r--r--arch/arm/cpu/arm926ejs/mb86r0x/Makefile47
-rw-r--r--arch/arm/cpu/arm926ejs/mb86r0x/clock.c43
-rw-r--r--arch/arm/cpu/arm926ejs/mb86r0x/reset.c40
-rw-r--r--arch/arm/cpu/arm926ejs/mb86r0x/timer.c142
-rw-r--r--arch/arm/cpu/arm926ejs/orion5x/cpu.c2
-rw-r--r--arch/arm/cpu/armv7/omap-common/Makefile2
-rw-r--r--arch/arm/cpu/armv7/omap-common/reset.S4
-rw-r--r--arch/arm/cpu/armv7/omap-common/syslib.c (renamed from arch/arm/cpu/armv7/omap3/syslib.c)2
-rw-r--r--arch/arm/cpu/armv7/omap3/Makefile1
-rw-r--r--arch/arm/cpu/armv7/omap3/board.c35
-rw-r--r--arch/arm/cpu/armv7/omap3/cache.S101
-rw-r--r--arch/arm/cpu/armv7/omap3/clock.c549
-rw-r--r--arch/arm/cpu/armv7/omap3/lowlevel_init.S69
-rw-r--r--arch/arm/cpu/armv7/omap3/sdrc.c43
-rw-r--r--arch/arm/cpu/armv7/omap3/sys_info.c147
-rw-r--r--arch/arm/cpu/armv7/s5p-common/Makefile46
-rw-r--r--arch/arm/cpu/armv7/s5p-common/cpu_info.c (renamed from arch/arm/cpu/armv7/s5pc1xx/cpu_info.c)11
-rw-r--r--arch/arm/cpu/armv7/s5p-common/timer.c (renamed from arch/arm/cpu/armv7/s5pc1xx/timer.c)23
-rw-r--r--arch/arm/cpu/armv7/s5pc1xx/Makefile2
-rw-r--r--arch/arm/cpu/armv7/s5pc1xx/clock.c51
-rw-r--r--arch/arm/cpu/armv7/s5pc1xx/reset.S2
-rw-r--r--arch/arm/cpu/armv7/s5pc1xx/sromc.c8
-rw-r--r--arch/arm/include/asm/arch-at91/at91_common.h1
-rw-r--r--arch/arm/include/asm/arch-at91/at91_dbu.h41
-rw-r--r--arch/arm/include/asm/arch-at91/at91_eefc.h51
-rw-r--r--arch/arm/include/asm/arch-at91/at91_gpbr.h45
-rw-r--r--arch/arm/include/asm/arch-at91/at91_pit.h2
-rw-r--r--arch/arm/include/asm/arch-at91/at91_rtt.h36
-rw-r--r--arch/arm/include/asm/arch-at91/at91sam9260.h18
-rw-r--r--arch/arm/include/asm/arch-at91/clk.h5
-rw-r--r--arch/arm/include/asm/arch-at91/hardware.h1
-rw-r--r--arch/arm/include/asm/arch-mb86r0x/asm-offsets.h74
-rw-r--r--arch/arm/include/asm/arch-mb86r0x/hardware.h31
-rw-r--r--arch/arm/include/asm/arch-mb86r0x/mb86r0x.h573
-rw-r--r--arch/arm/include/asm/arch-omap3/clocks.h17
-rw-r--r--arch/arm/include/asm/arch-omap3/clocks_omap3.h27
-rw-r--r--arch/arm/include/asm/arch-omap3/cpu.h15
-rw-r--r--arch/arm/include/asm/arch-omap3/omap3.h32
-rw-r--r--arch/arm/include/asm/arch-omap3/sys_proto.h2
-rw-r--r--arch/arm/include/asm/arch-omap4/omap4.h1
-rw-r--r--arch/arm/include/asm/arch-omap4/sys_proto.h3
-rw-r--r--arch/arm/include/asm/arch-orion5x/cpu.h2
-rw-r--r--arch/arm/include/asm/arch-s5pc1xx/clk.h5
-rw-r--r--arch/arm/include/asm/arch-s5pc1xx/cpu.h39
-rw-r--r--arch/arm/include/asm/arch-s5pc1xx/gpio.h172
-rw-r--r--arch/arm/include/asm/arch-s5pc1xx/mmc.h2
-rw-r--r--arch/arm/include/asm/arch-s5pc1xx/pwm.h12
-rw-r--r--arch/avr32/cpu/at32ap700x/Makefile2
-rw-r--r--arch/avr32/cpu/at32ap700x/mmu.c78
-rw-r--r--arch/avr32/cpu/exception.c3
-rw-r--r--arch/avr32/cpu/start.S19
-rw-r--r--arch/avr32/include/asm/arch-at32ap700x/addrspace.h5
-rw-r--r--arch/avr32/include/asm/arch-at32ap700x/mmu.h66
-rw-r--r--arch/avr32/lib/board.c4
60 files changed, 2626 insertions, 484 deletions
diff --git a/arch/arm/cpu/arm926ejs/at91/Makefile b/arch/arm/cpu/arm926ejs/at91/Makefile
index 4f467be91c..def3980b63 100644
--- a/arch/arm/cpu/arm926ejs/at91/Makefile
+++ b/arch/arm/cpu/arm926ejs/at91/Makefile
@@ -34,6 +34,7 @@ COBJS-$(CONFIG_AT91SAM9263) += at91sam9263_devices.o
COBJS-$(CONFIG_AT91SAM9RL) += at91sam9rl_devices.o
COBJS-$(CONFIG_AT91SAM9M10G45) += at91sam9m10g45_devices.o
COBJS-$(CONFIG_AT91SAM9G45) += at91sam9m10g45_devices.o
+COBJS-$(CONFIG_AT91_EFLASH) += eflash.o
COBJS-$(CONFIG_AT91_LED) += led.o
COBJS-y += clock.o
COBJS-y += cpu.o
diff --git a/arch/arm/cpu/arm926ejs/at91/at91sam9260_devices.c b/arch/arm/cpu/arm926ejs/at91/at91sam9260_devices.c
index 77d49ab1c7..87b04426b9 100644
--- a/arch/arm/cpu/arm926ejs/at91/at91sam9260_devices.c
+++ b/arch/arm/cpu/arm926ejs/at91/at91sam9260_devices.c
@@ -28,12 +28,27 @@
#include <asm/arch/gpio.h>
#include <asm/arch/io.h>
+/*
+ * if CONFIG_AT91_GPIO_PULLUP ist set, keep pullups on on all
+ * peripheral pins. Good to have if hardware is soldered optionally
+ * or in case of SPI no slave is selected. Avoid lines to float
+ * needlessly. Use a short local PUP define.
+ *
+ * Due to errata "TXD floats when CTS is inactive" pullups are always
+ * on for TXD pins.
+ */
+#ifdef CONFIG_AT91_GPIO_PULLUP
+# define PUP CONFIG_AT91_GPIO_PULLUP
+#else
+# define PUP 0
+#endif
+
void at91_serial0_hw_init(void)
{
at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE;
at91_set_a_periph(AT91_PIO_PORTB, 4, 1); /* TXD0 */
- at91_set_a_periph(AT91_PIO_PORTB, 5, 0); /* RXD0 */
+ at91_set_a_periph(AT91_PIO_PORTB, 5, PUP); /* RXD0 */
writel(1 << AT91SAM9260_ID_US0, &pmc->pcer);
}
@@ -42,7 +57,7 @@ void at91_serial1_hw_init(void)
at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE;
at91_set_a_periph(AT91_PIO_PORTB, 6, 1); /* TXD1 */
- at91_set_a_periph(AT91_PIO_PORTB, 7, 0); /* RXD1 */
+ at91_set_a_periph(AT91_PIO_PORTB, 7, PUP); /* RXD1 */
writel(1 << AT91SAM9260_ID_US1, &pmc->pcer);
}
@@ -51,7 +66,7 @@ void at91_serial2_hw_init(void)
at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE;
at91_set_a_periph(AT91_PIO_PORTB, 8, 1); /* TXD2 */
- at91_set_a_periph(AT91_PIO_PORTB, 9, 0); /* RXD2 */
+ at91_set_a_periph(AT91_PIO_PORTB, 9, PUP); /* RXD2 */
writel(1 << AT91SAM9260_ID_US2, &pmc->pcer);
}
@@ -59,7 +74,7 @@ void at91_serial3_hw_init(void)
{
at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE;
- at91_set_a_periph(AT91_PIO_PORTB, 14, 0); /* DRXD */
+ at91_set_a_periph(AT91_PIO_PORTB, 14, PUP); /* DRXD */
at91_set_a_periph(AT91_PIO_PORTB, 15, 1); /* DTXD */
writel(1 << AT91_ID_SYS, &pmc->pcer);
}
@@ -88,9 +103,9 @@ void at91_spi0_hw_init(unsigned long cs_mask)
{
at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE;
- at91_set_a_periph(AT91_PIO_PORTA, 0, 0); /* SPI0_MISO */
- at91_set_a_periph(AT91_PIO_PORTA, 1, 0); /* SPI0_MOSI */
- at91_set_a_periph(AT91_PIO_PORTA, 2, 0); /* SPI0_SPCK */
+ at91_set_a_periph(AT91_PIO_PORTA, 0, PUP); /* SPI0_MISO */
+ at91_set_a_periph(AT91_PIO_PORTA, 1, PUP); /* SPI0_MOSI */
+ at91_set_a_periph(AT91_PIO_PORTA, 2, PUP); /* SPI0_SPCK */
/* Enable clock */
writel(1 << AT91SAM9260_ID_SPI0, &pmc->pcer);
@@ -125,9 +140,9 @@ void at91_spi1_hw_init(unsigned long cs_mask)
{
at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE;
- at91_set_a_periph(AT91_PIO_PORTB, 0, 0); /* SPI1_MISO */
- at91_set_a_periph(AT91_PIO_PORTB, 1, 0); /* SPI1_MOSI */
- at91_set_a_periph(AT91_PIO_PORTB, 2, 0); /* SPI1_SPCK */
+ at91_set_a_periph(AT91_PIO_PORTB, 0, PUP); /* SPI1_MISO */
+ at91_set_a_periph(AT91_PIO_PORTB, 1, PUP); /* SPI1_MOSI */
+ at91_set_a_periph(AT91_PIO_PORTB, 2, PUP); /* SPI1_SPCK */
/* Enable clock */
writel(1 << AT91SAM9260_ID_SPI1, &pmc->pcer);
@@ -194,3 +209,24 @@ void at91_macb_hw_init(void)
#endif
}
#endif
+
+#if defined(CONFIG_ATMEL_MCI) || defined(CONFIG_GENERIC_ATMEL_MCI)
+void at91_mci_hw_init(void)
+{
+ at91_set_a_periph(AT91_PIO_PORTA, 8, 1); /* MCCK */
+#if defined(CONFIG_ATMEL_MCI_PORTB)
+ at91_set_b_periph(AT91_PIO_PORTA, 1, 1); /* MCCDB */
+ at91_set_b_periph(AT91_PIO_PORTA, 0, 1); /* MCDB0 */
+ at91_set_b_periph(AT91_PIO_PORTA, 5, 1); /* MCDB1 */
+ at91_set_b_periph(AT91_PIO_PORTA, 4, 1); /* MCDB2 */
+ at91_set_b_periph(AT91_PIO_PORTA, 3, 1); /* MCDB3 */
+#else
+ at91_set_a_periph(AT91_PIO_PORTA, 7, 1); /* MCCDA */
+ at91_set_a_periph(AT91_PIO_PORTA, 6, 1); /* MCDA0 */
+ at91_set_a_periph(AT91_PIO_PORTA, 9, 1); /* MCDA1 */
+ at91_set_a_periph(AT91_PIO_PORTA, 10, 1); /* MCDA2 */
+ at91_set_a_periph(AT91_PIO_PORTA, 11, 1); /* MCDA3 */
+#endif
+}
+#endif
+
diff --git a/arch/arm/cpu/arm926ejs/at91/eflash.c b/arch/arm/cpu/arm926ejs/at91/eflash.c
new file mode 100644
index 0000000000..2e851dbd2c
--- /dev/null
+++ b/arch/arm/cpu/arm926ejs/at91/eflash.c
@@ -0,0 +1,271 @@
+/*
+ * (C) Copyright 2010
+ * Reinhard Meyer, EMK Elektronik, reinhard.meyer@emk-elektronik.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
+ */
+
+/*
+ * this driver supports the enhanced embedded flash in the Atmel
+ * AT91SAM9XE devices with the following geometry:
+ *
+ * AT91SAM9XE128: 1 plane of 8 regions of 32 pages (total 256 pages)
+ * AT91SAM9XE256: 1 plane of 16 regions of 32 pages (total 512 pages)
+ * AT91SAM9XE512: 1 plane of 32 regions of 32 pages (total 1024 pages)
+ * (the exact geometry is read from the flash at runtime, so any
+ * future devices should already be covered)
+ *
+ * Regions can be write/erase protected.
+ * Whole (!) pages can be individually written with erase on the fly.
+ * Writing partial pages will corrupt the rest of the page.
+ *
+ * The flash is presented to u-boot with each region being a sector,
+ * having the following effects:
+ * Each sector can be hardware protected (protect on/off).
+ * Each page in a sector can be rewritten anytime.
+ * Since pages are erased when written, the "erase" does nothing.
+ * The first "CONFIG_EFLASH_PROTSECTORS" cannot be unprotected
+ * by u-Boot commands.
+ *
+ * Note: Redundant environment will not work in this flash since
+ * it does use partial page writes. Make sure the environent spans
+ * whole pages!
+ */
+
+/*
+ * optional TODOs (nice to have features):
+ *
+ * make the driver coexist with other NOR flash drivers
+ * (use an index into flash_info[], requires work
+ * in those other drivers, too)
+ * Make the erase command fill the sectors with 0xff
+ * (if the flashes grow larger in the future and
+ * someone puts a jffs2 into them)
+ * do a read-modify-write for partially programmed pages
+ */
+#include <common.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/io.h>
+#include <asm/arch/at91_common.h>
+#include <asm/arch/at91_eefc.h>
+#include <asm/arch/at91_dbu.h>
+
+/* checks to detect configuration errors */
+#if CONFIG_SYS_MAX_FLASH_BANKS!=1
+#error eflash: this driver can only handle 1 bank
+#endif
+
+/* global structure */
+flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
+static u32 pagesize;
+
+unsigned long flash_init (void)
+{
+ at91_eefc_t *eefc = (at91_eefc_t *) 0xfffffa00;
+ at91_dbu_t *dbu = (at91_dbu_t *) 0xfffff200;
+ u32 id, size, nplanes, planesize, nlocks;
+ u32 addr, i, tmp=0;
+
+ debug("eflash: init\n");
+
+ flash_info[0].flash_id = FLASH_UNKNOWN;
+
+ /* check if its an AT91ARM9XE SoC */
+ if ((readl(&dbu->cidr) & AT91_DBU_CID_ARCH_MASK) != AT91_DBU_CID_ARCH_9XExx) {
+ puts("eflash: not an AT91SAM9XE\n");
+ return 0;
+ }
+
+ /* now query the eflash for its structure */
+ writel(AT91_EEFC_FCR_KEY | AT91_EEFC_FCR_FCMD_GETD, &eefc->fcr);
+ while ((readl(&eefc->fsr) & AT91_EEFC_FSR_FRDY) == 0)
+ ;
+ id = readl(&eefc->frr); /* word 0 */
+ size = readl(&eefc->frr); /* word 1 */
+ pagesize = readl(&eefc->frr); /* word 2 */
+ nplanes = readl(&eefc->frr); /* word 3 */
+ planesize = readl(&eefc->frr); /* word 4 */
+ debug("id=%08x size=%u pagesize=%u planes=%u planesize=%u\n",
+ id, size, pagesize, nplanes, planesize);
+ for (i=1; i<nplanes; i++) {
+ tmp = readl(&eefc->frr); /* words 5..4+nplanes-1 */
+ };
+ nlocks = readl(&eefc->frr); /* word 4+nplanes */
+ debug("nlocks=%u\n", nlocks);
+ /* since we are going to use the lock regions as sectors, check count */
+ if (nlocks > CONFIG_SYS_MAX_FLASH_SECT) {
+ printf("eflash: number of lock regions(%u) "\
+ "> CONFIG_SYS_MAX_FLASH_SECT. reducing...\n",
+ nlocks);
+ nlocks = CONFIG_SYS_MAX_FLASH_SECT;
+ }
+ flash_info[0].size = size;
+ flash_info[0].sector_count = nlocks;
+ flash_info[0].flash_id = id;
+
+ addr = AT91SAM9XE_FLASH_BASE;
+ for (i=0; i<nlocks; i++) {
+ tmp = readl(&eefc->frr); /* words 4+nplanes+1.. */
+ flash_info[0].start[i] = addr;
+ flash_info[0].protect[i] = 0;
+ addr += tmp;
+ };
+
+ /* now read the protection information for all regions */
+ writel(AT91_EEFC_FCR_KEY | AT91_EEFC_FCR_FCMD_GLB, &eefc->fcr);
+ while ((readl(&eefc->fsr) & AT91_EEFC_FSR_FRDY) == 0)
+ ;
+ for (i=0; i<flash_info[0].sector_count; i++) {
+ if (i%32 == 0)
+ tmp = readl(&eefc->frr);
+ flash_info[0].protect[i] = (tmp >> (i%32)) & 1;
+#if defined(CONFIG_EFLASH_PROTSECTORS)
+ if (i < CONFIG_EFLASH_PROTSECTORS)
+ flash_info[0].protect[i] = 1;
+#endif
+ }
+
+ return size;
+}
+
+void flash_print_info (flash_info_t *info)
+{
+ int i;
+
+ puts("AT91SAM9XE embedded flash\n Size: ");
+ print_size(info->size, " in ");
+ printf("%d Sectors\n", info->sector_count);
+
+ printf(" Sector Start Addresses:");
+ for (i=0; i<info->sector_count; ++i) {
+ if ((i % 5) == 0)
+ printf("\n ");
+ printf(" %08lX%s",
+ info->start[i],
+ info->protect[i] ? " (RO)" : " "
+ );
+ }
+ printf ("\n");
+ return;
+}
+
+int flash_real_protect (flash_info_t *info, long sector, int prot)
+{
+ at91_eefc_t *eefc = (at91_eefc_t *) 0xfffffa00;
+ u32 pagenum = (info->start[sector]-AT91SAM9XE_FLASH_BASE)/pagesize;
+ u32 i, tmp=0;
+
+ debug("protect sector=%ld prot=%d\n", sector, prot);
+
+#if defined(CONFIG_EFLASH_PROTSECTORS)
+ if (sector < CONFIG_EFLASH_PROTSECTORS) {
+ if (!prot) {
+ printf("eflash: sector %lu cannot be unprotected\n",
+ sector);
+ }
+ return 1; /* return anyway, caller does not care for result */
+ }
+#endif
+ if (prot) {
+ writel(AT91_EEFC_FCR_KEY | AT91_EEFC_FCR_FCMD_SLB |
+ (pagenum << AT91_EEFC_FCR_FARG_SHIFT), &eefc->fcr);
+ } else {
+ writel(AT91_EEFC_FCR_KEY | AT91_EEFC_FCR_FCMD_CLB |
+ (pagenum << AT91_EEFC_FCR_FARG_SHIFT), &eefc->fcr);
+ }
+ while ((readl(&eefc->fsr) & AT91_EEFC_FSR_FRDY) == 0)
+ ;
+ /* now re-read the protection information for all regions */
+ writel(AT91_EEFC_FCR_KEY | AT91_EEFC_FCR_FCMD_GLB, &eefc->fcr);
+ while ((readl(&eefc->fsr) & AT91_EEFC_FSR_FRDY) == 0)
+ ;
+ for (i=0; i<info->sector_count; i++) {
+ if (i%32 == 0)
+ tmp = readl(&eefc->frr);
+ info->protect[i] = (tmp >> (i%32)) & 1;
+ }
+ return 0;
+}
+
+static u32 erase_write_page (u32 pagenum)
+{
+ at91_eefc_t *eefc = (at91_eefc_t *) 0xfffffa00;
+
+ debug("erase+write page=%u\n", pagenum);
+
+ /* give erase and write page command */
+ writel(AT91_EEFC_FCR_KEY | AT91_EEFC_FCR_FCMD_EWP |
+ (pagenum << AT91_EEFC_FCR_FARG_SHIFT), &eefc->fcr);
+ while ((readl(&eefc->fsr) & AT91_EEFC_FSR_FRDY) == 0)
+ ;
+ /* return status */
+ return readl(&eefc->fsr)
+ & (AT91_EEFC_FSR_FCMDE | AT91_EEFC_FSR_FLOCKE);
+}
+
+int flash_erase (flash_info_t *info, int s_first, int s_last)
+{
+ debug("erase first=%d last=%d\n", s_first, s_last);
+ puts("this flash does not need and support erasing!\n");
+ return 0;
+}
+
+/*
+ * Copy memory to flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ */
+
+int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
+{
+ u32 pagenum;
+ u32 *src32, *dst32;
+ u32 i;
+
+ debug("write src=%08lx addr=%08lx cnt=%lx\n",
+ (ulong)src, addr, cnt);
+
+ /* REQUIRE addr to be on a page start, abort if not */
+ if (addr % pagesize) {
+ printf ("eflash: start %08lx is not on page start\n"\
+ " write aborted\n", addr);
+ return 1;
+ }
+
+ /* now start copying data */
+ pagenum = (addr-AT91SAM9XE_FLASH_BASE)/pagesize;
+ src32 = (u32 *) src;
+ dst32 = (u32 *) addr;
+ while (cnt > 0) {
+ i = pagesize / 4;
+ /* fill page buffer */
+ while (i--)
+ *dst32++ = *src32++;
+ /* write page */
+ if (erase_write_page(pagenum))
+ return 1;
+ pagenum++;
+ if (cnt > pagesize)
+ cnt -= pagesize;
+ else
+ cnt = 0;
+ }
+ return 0;
+}
+
diff --git a/arch/arm/cpu/arm926ejs/at91/reset.c b/arch/arm/cpu/arm926ejs/at91/reset.c
index 1b67e77887..d2569d8bae 100644
--- a/arch/arm/cpu/arm926ejs/at91/reset.c
+++ b/arch/arm/cpu/arm926ejs/at91/reset.c
@@ -27,18 +27,19 @@
#include <asm/arch/at91_rstc.h>
#include <asm/arch/io.h>
-/*
- * Reset the cpu by setting up the watchdog timer and let him time out.
- */
+/* Reset the cpu by telling the reset controller to do so */
void reset_cpu(ulong ignored)
{
at91_rstc_t *rstc = (at91_rstc_t *) AT91_RSTC_BASE;
- /* this is the way Linux does it */
-
- writel(AT91_RSTC_KEY | AT91_RSTC_CR_PROCRST | AT91_RSTC_CR_PERRST,
- &rstc->cr);
-
- while (1);
- /* Never reached */
+ writel(AT91_RSTC_KEY
+ | AT91_RSTC_CR_PROCRST /* Processor Reset */
+ | AT91_RSTC_CR_PERRST /* Peripheral Reset */
+#ifdef CONFIG_AT91RESET_EXTRST
+ | AT91_RSTC_CR_EXTRST /* External Reset (assert nRST pin) */
+#endif
+ , &rstc->cr);
+ /* never reached */
+ while (1)
+ ;
}
diff --git a/arch/arm/cpu/arm926ejs/at91/timer.c b/arch/arm/cpu/arm926ejs/at91/timer.c
index d21eebfb4e..8efc34bcf1 100644
--- a/arch/arm/cpu/arm926ejs/at91/timer.c
+++ b/arch/arm/cpu/arm926ejs/at91/timer.c
@@ -138,8 +138,5 @@ ulong get_timer(ulong base)
*/
ulong get_tbclk(void)
{
- ulong tbclk;
-
- tbclk = CONFIG_SYS_HZ;
- return tbclk;
+ return timer_freq;
}
diff --git a/arch/arm/cpu/arm926ejs/kirkwood/cpu.c b/arch/arm/cpu/arm926ejs/kirkwood/cpu.c
index c63e8641f2..82c978bd93 100644
--- a/arch/arm/cpu/arm926ejs/kirkwood/cpu.c
+++ b/arch/arm/cpu/arm926ejs/kirkwood/cpu.c
@@ -81,7 +81,7 @@ unsigned int kw_winctrl_calcsize(unsigned int sizeval)
unsigned int j = 0;
u32 val = sizeval >> 1;
- for (i = 0; val > 0x10000; i++) {
+ for (i = 0; val >= 0x10000; i++) {
j |= (1 << i);
val = val >> 1;
}
diff --git a/arch/arm/cpu/arm926ejs/mb86r0x/Makefile b/arch/arm/cpu/arm926ejs/mb86r0x/Makefile
new file mode 100644
index 0000000000..ce3e5a5a5a
--- /dev/null
+++ b/arch/arm/cpu/arm926ejs/mb86r0x/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
+
+COBJS = clock.o reset.o timer.o
+SOBJS =
+
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS))
+START := $(addprefix $(obj),$(START))
+
+all: $(obj).depend $(LIB)
+
+$(LIB): $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/arch/arm/cpu/arm926ejs/mb86r0x/clock.c b/arch/arm/cpu/arm926ejs/mb86r0x/clock.c
new file mode 100644
index 0000000000..70c8c8b04a
--- /dev/null
+++ b/arch/arm/cpu/arm926ejs/mb86r0x/clock.c
@@ -0,0 +1,43 @@
+/*
+ * (C) Copyright 2010
+ * Matthias Weisser <weisserm@arcor.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 <common.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+
+/*
+ * Get the peripheral bus frequency depending on pll pin settings
+ */
+ulong get_bus_freq(ulong dummy)
+{
+ struct mb86r0x_crg * crg = (struct mb86r0x_crg *)
+ MB86R0x_CRG_BASE;
+ uint32_t pllmode;
+
+ pllmode = readl(&crg->crpr) & MB86R0x_CRG_CRPR_PLLMODE;
+
+ if (pllmode == MB86R0x_CRG_CRPR_PLLMODE_X20)
+ return 40000000;
+
+ return 41164767;
+}
diff --git a/arch/arm/cpu/arm926ejs/mb86r0x/reset.c b/arch/arm/cpu/arm926ejs/mb86r0x/reset.c
new file mode 100644
index 0000000000..e7f0f6788b
--- /dev/null
+++ b/arch/arm/cpu/arm926ejs/mb86r0x/reset.c
@@ -0,0 +1,40 @@
+/*
+ * (C) Copyright 2010
+ * Matthias Weisser <weisserm@arcor.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 <common.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+
+/*
+ * Reset the cpu by setting software reset request bit
+ */
+void reset_cpu(ulong ignored)
+{
+ struct mb86r0x_crg * crg = (struct mb86r0x_crg *)
+ MB86R0x_CRG_BASE;
+
+ writel(MB86R0x_CRSR_SWRSTREQ, &crg->crsr);
+ while (1)
+ /* NOP */;
+ /* Never reached */
+}
diff --git a/arch/arm/cpu/arm926ejs/mb86r0x/timer.c b/arch/arm/cpu/arm926ejs/mb86r0x/timer.c
new file mode 100644
index 0000000000..9175b71d16
--- /dev/null
+++ b/arch/arm/cpu/arm926ejs/mb86r0x/timer.c
@@ -0,0 +1,142 @@
+/*
+ * (C) Copyright 2007-2008
+ * Stelian Pop <stelian.pop@leadtechdesign.com>
+ * Lead Tech Design <www.leadtechdesign.com>
+ *
+ * (C) Copyright 2010
+ * Matthias Weisser, Graf-Syteco <weisserm@arcor.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 <div64.h>
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+
+#define TIMER_LOAD_VAL 0xffffffff
+#define TIMER_FREQ (CONFIG_MB86R0x_IOCLK / 256)
+
+static unsigned long long timestamp;
+static ulong lastdec;
+
+static inline unsigned long long tick_to_time(unsigned long long tick)
+{
+ tick *= CONFIG_SYS_HZ;
+ do_div(tick, TIMER_FREQ);
+
+ return tick;
+}
+
+static inline unsigned long long usec_to_tick(unsigned long long usec)
+{
+ usec *= TIMER_FREQ;
+ do_div(usec, 1000000);
+
+ return usec;
+}
+
+/* nothing really to do with interrupts, just starts up a counter. */
+int timer_init(void)
+{
+ struct mb86r0x_timer * timer = (struct mb86r0x_timer *)
+ MB86R0x_TIMER_BASE;
+ ulong ctrl = readl(&timer->control);
+
+ writel(TIMER_LOAD_VAL, &timer->load);
+
+ ctrl |= MB86R0x_TIMER_ENABLE | MB86R0x_TIMER_PRS_8S |
+ MB86R0x_TIMER_SIZE_32;
+
+ writel(ctrl, &timer->control);
+
+ reset_timer_masked();
+
+ return 0;
+}
+
+/*
+ * timer without interrupts
+ */
+unsigned long long get_ticks(void)
+{
+ struct mb86r0x_timer * timer = (struct mb86r0x_timer *)
+ MB86R0x_TIMER_BASE;
+ ulong now = readl(&timer->value);
+
+ if (now <= lastdec) {
+ /* normal mode (non roll) */
+ /* move stamp forward with absolut diff ticks */
+ timestamp += lastdec - now;
+ } else {
+ /* we have rollover of incrementer */
+ timestamp += lastdec + TIMER_LOAD_VAL - now;
+ }
+ lastdec = now;
+ return timestamp;
+}
+
+void reset_timer_masked(void)
+{
+ struct mb86r0x_timer * timer = (struct mb86r0x_timer *)
+ MB86R0x_TIMER_BASE;
+
+ /* capture current value time */
+ lastdec = readl(&timer->value);
+ timestamp = 0; /* start "advancing" time stamp from 0 */
+}
+
+ulong get_timer_masked(void)
+{
+ return tick_to_time(get_ticks());
+}
+
+void __udelay(unsigned long usec)
+{
+ unsigned long long tmp;
+ ulong tmo;
+
+ tmo = usec_to_tick(usec);
+ tmp = get_ticks(); /* get current timestamp */
+
+ while ((get_ticks() - tmp) < tmo) /* loop till event */
+ /*NOP*/;
+}
+
+void reset_timer(void)
+{
+ reset_timer_masked();
+}
+
+ulong get_timer(ulong base)
+{
+ return get_timer_masked() - base;
+}
+
+/*
+ * 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)
+{
+ ulong tbclk;
+
+ tbclk = TIMER_FREQ;
+ return tbclk;
+}
diff --git a/arch/arm/cpu/arm926ejs/orion5x/cpu.c b/arch/arm/cpu/arm926ejs/orion5x/cpu.c
index 3740e33e9d..260f88b46e 100644
--- a/arch/arm/cpu/arm926ejs/orion5x/cpu.c
+++ b/arch/arm/cpu/arm926ejs/orion5x/cpu.c
@@ -61,7 +61,7 @@ unsigned int orion5x_winctrl_calcsize(unsigned int sizeval)
unsigned int j = 0;
u32 val = sizeval >> 1;
- for (i = 0; val > 0x10000; i++) {
+ for (i = 0; val >= 0x10000; i++) {
j |= (1 << i);
val = val >> 1;
}
diff --git a/arch/arm/cpu/armv7/omap-common/Makefile b/arch/arm/cpu/armv7/omap-common/Makefile
index 3a4a304e45..caee7263b1 100644
--- a/arch/arm/cpu/armv7/omap-common/Makefile
+++ b/arch/arm/cpu/armv7/omap-common/Makefile
@@ -26,7 +26,9 @@ include $(TOPDIR)/config.mk
LIB = $(obj)libomap-common.a
SOBJS := reset.o
+
COBJS := timer.o
+COBJS += syslib.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
diff --git a/arch/arm/cpu/armv7/omap-common/reset.S b/arch/arm/cpu/armv7/omap-common/reset.S
index a53c408195..838b1221ee 100644
--- a/arch/arm/cpu/armv7/omap-common/reset.S
+++ b/arch/arm/cpu/armv7/omap-common/reset.S
@@ -27,10 +27,12 @@
reset_cpu:
ldr r1, rstctl @ get addr for global reset
@ reg
- mov r3, #0x2 @ full reset pll + mpu
+ ldr r3, rstbit @ sw reset bit
str r3, [r1] @ force reset
mov r0, r0
_loop_forever:
b _loop_forever
rstctl:
.word PRM_RSTCTRL
+rstbit:
+ .word PRM_RSTCTRL_RESET
diff --git a/arch/arm/cpu/armv7/omap3/syslib.c b/arch/arm/cpu/armv7/omap-common/syslib.c
index 9ced495c8d..f9ed9a307b 100644
--- a/arch/arm/cpu/armv7/omap3/syslib.c
+++ b/arch/arm/cpu/armv7/omap-common/syslib.c
@@ -23,8 +23,6 @@
#include <common.h>
#include <asm/io.h>
-#include <asm/arch/mem.h>
-#include <asm/arch/clocks.h>
#include <asm/arch/sys_proto.h>
/************************************************************
diff --git a/arch/arm/cpu/armv7/omap3/Makefile b/arch/arm/cpu/armv7/omap3/Makefile
index 79ae26706e..95526d6893 100644
--- a/arch/arm/cpu/armv7/omap3/Makefile
+++ b/arch/arm/cpu/armv7/omap3/Makefile
@@ -32,7 +32,6 @@ COBJS += board.o
COBJS += clock.o
COBJS += gpio.o
COBJS += mem.o
-COBJS += syslib.o
COBJS += sys_info.o
COBJS-$(CONFIG_EMIF4) += emif4.o
diff --git a/arch/arm/cpu/armv7/omap3/board.c b/arch/arm/cpu/armv7/omap3/board.c
index 69e56f55c5..6c2a132b63 100644
--- a/arch/arm/cpu/armv7/omap3/board.c
+++ b/arch/arm/cpu/armv7/omap3/board.c
@@ -120,41 +120,6 @@ void secureworld_exit()
}
/******************************************************************************
- * Routine: setup_auxcr()
- * Description: Write to AuxCR desired value using SMI.
- * general use.
- *****************************************************************************/
-void setup_auxcr()
-{
- unsigned long i;
- volatile unsigned int j;
- /* Save r0, r12 and restore them after usage */
- __asm__ __volatile__("mov %0, r12":"=r"(j));
- __asm__ __volatile__("mov %0, r0":"=r"(i));
-
- /*
- * GP Device ROM code API usage here
- * r12 = AUXCR Write function and r0 value
- */
- __asm__ __volatile__("mov r12, #0x3");
- __asm__ __volatile__("mrc p15, 0, r0, c1, c0, 1");
- /* Enabling ASA */
- __asm__ __volatile__("orr r0, r0, #0x10");
- /* Enable L1NEON */
- __asm__ __volatile__("orr r0, r0, #1 << 5");
- /* SMI instruction to call ROM Code API */
- __asm__ __volatile__(".word 0xE1600070");
- /* Set PLD_FWD bit in L2AUXCR (Cortex-A8 erratum 725233 workaround) */
- __asm__ __volatile__("mov r12, #0x2");
- __asm__ __volatile__("mrc p15, 1, r0, c9, c0, 2");
- __asm__ __volatile__("orr r0, r0, #1 << 27");
- /* SMI instruction to call ROM Code API */
- __asm__ __volatile__(".word 0xE1600070");
- __asm__ __volatile__("mov r0, %0":"=r"(i));
- __asm__ __volatile__("mov r12, %0":"=r"(j));
-}
-
-/******************************************************************************
* Routine: try_unlock_sram()
* Description: If chip is GP/EMU(special) type, unlock the SRAM for
* general use.
diff --git a/arch/arm/cpu/armv7/omap3/cache.S b/arch/arm/cpu/armv7/omap3/cache.S
index 4b65ac58a5..24e950f38c 100644
--- a/arch/arm/cpu/armv7/omap3/cache.S
+++ b/arch/arm/cpu/armv7/omap3/cache.S
@@ -43,6 +43,7 @@
.global invalidate_dcache
.global l2_cache_enable
.global l2_cache_disable
+.global setup_auxcr
/*
* invalidate_dcache()
@@ -128,64 +129,56 @@ finished_inval:
ldmfd r13!, {r0 - r5, r7, r9 - r12, pc}
-
-l2_cache_enable:
- stmfd r13!, {r0, r1, r2, lr}
- @ ES2 onwards we can disable/enable L2 ourselves
+l2_cache_set:
+ stmfd r13!, {r4 - r6, lr}
+ mov r5, r0
bl get_cpu_rev
- cmp r0, #CPU_3XX_ES20
- blt l2_cache_disable_EARLIER_THAN_ES2
- mrc 15, 0, r3, cr1, cr0, 1
- orr r3, r3, #2
- mcr 15, 0, r3, cr1, cr0, 1
- b l2_cache_enable_END
-l2_cache_enable_EARLIER_THAN_ES2:
- @ Save r0, r12 and restore them after usage
- mov r3, ip
- str r3, [sp, #4]
- mov r3, r0
- @
+ mov r4, r0
+ bl get_cpu_family
+ @ ES2 onwards we can disable/enable L2 ourselves
+ cmp r0, #CPU_OMAP34XX
+ cmpeq r4, #CPU_3XX_ES10
+ mrc 15, 0, r0, cr1, cr0, 1
+ bic r0, r0, #2
+ orr r0, r0, r5, lsl #1
+ mcreq 15, 0, r0, cr1, cr0, 1
@ GP Device ROM code API usage here
@ r12 = AUXCR Write function and r0 value
- @
mov ip, #3
- mrc 15, 0, r0, cr1, cr0, 1
- orr r0, r0, #2
- @ SMI instruction to call ROM Code API
- .word 0xe1600070
- mov r0, r3
- mov ip, r3
- str r3, [sp, #4]
-l2_cache_enable_END:
- ldmfd r13!, {r1, r2, r3, pc}
+ @ SMCNE instruction to call ROM Code API
+ .word 0x11600070
+ ldmfd r13!, {r4 - r6, pc}
+l2_cache_enable:
+ mov r0, #1
+ b l2_cache_set
l2_cache_disable:
- stmfd r13!, {r0, r1, r2, lr}
- @ ES2 onwards we can disable/enable L2 ourselves
- bl get_cpu_rev
- cmp r0, #CPU_3XX_ES20
- blt l2_cache_disable_EARLIER_THAN_ES2
- mrc 15, 0, r3, cr1, cr0, 1
- bic r3, r3, #2
- mcr 15, 0, r3, cr1, cr0, 1
- b l2_cache_disable_END
-l2_cache_disable_EARLIER_THAN_ES2:
- @ Save r0, r12 and restore them after usage
- mov r3, ip
- str r3, [sp, #4]
- mov r3, r0
- @
- @ GP Device ROM code API usage here
- @ r12 = AUXCR Write function and r0 value
- @
- mov ip, #3
- mrc 15, 0, r0, cr1, cr0, 1
- bic r0, r0, #2
- @ SMI instruction to call ROM Code API
- .word 0xe1600070
- mov r0, r3
- mov ip, r3
- str r3, [sp, #4]
-l2_cache_disable_END:
- ldmfd r13!, {r1, r2, r3, pc}
+ mov r0, #0
+ b l2_cache_set
+
+/******************************************************************************
+ * Routine: setup_auxcr()
+ * Description: Write to AuxCR desired value using SMI.
+ * general use.
+ *****************************************************************************/
+setup_auxcr:
+ mrc p15, 0, r0, c0, c0, 0 @ read main ID register
+ and r2, r0, #0x00f00000 @ variant
+ and r3, r0, #0x0000000f @ revision
+ orr r1, r3, r2, lsr #20-4 @ combine variant and revision
+ mov r12, #0x3
+ mrc p15, 0, r0, c1, c0, 1
+ orr r0, r0, #0x10 @ Enable ASA
+ @ Enable L1NEON on pre-r2p1 (erratum 621766 workaround)
+ cmp r1, #0x21
+ orrlt r0, r0, #1 << 5
+ .word 0xE1600070 @ SMC
+ mov r12, #0x2
+ mrc p15, 1, r0, c9, c0, 2
+ @ Set PLD_FWD bit in L2AUXCR on pre-r2p1 (erratum 725233 workaround)
+ cmp r1, #0x21
+ orrlt r0, r0, #1 << 27
+ .word 0xE1600070 @ SMC
+ bx lr
+
diff --git a/arch/arm/cpu/armv7/omap3/clock.c b/arch/arm/cpu/armv7/omap3/clock.c
index 6330c9e5da..2238c52e3b 100644
--- a/arch/arm/cpu/armv7/omap3/clock.c
+++ b/arch/arm/cpu/armv7/omap3/clock.c
@@ -50,12 +50,7 @@ u32 get_osc_clk_speed(void)
if (val & SYSCLKDIV_2)
cdiv = 2;
- else if (val & SYSCLKDIV_1)
- cdiv = 1;
else
- /*
- * Should never reach here! (Assume divider as 1)
- */
cdiv = 1;
/* enable timer2 */
@@ -89,11 +84,7 @@ u32 get_osc_clk_speed(void)
while (readl(&s32k_base->s32k_cr) < (start + 20)) ;
cend = readl(&gpt1_base->tcrr); /* get end sys_clk count */
cdiff = cend - cstart; /* get elapsed ticks */
-
- if (cdiv == 2)
- {
- cdiff *= 2;
- }
+ cdiff *= cdiv;
/* based on number of ticks assign speed */
if (cdiff > 19000)
@@ -135,65 +126,22 @@ void get_sys_clkin_sel(u32 osc_clk, u32 *sys_clkin_sel)
}
}
-/******************************************************************************
- * prcm_init() - inits clocks for PRCM as defined in clocks.h
- * called from SRAM, or Flash (using temp SRAM stack).
- *****************************************************************************/
-void prcm_init(void)
+/*
+ * OMAP34XX/35XX specific functions
+ */
+
+static void dpll3_init_34xx(u32 sil_index, u32 clk_index)
{
+ struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
+ dpll_param *ptr = (dpll_param *) get_core_dpll_param();
void (*f_lock_pll) (u32, u32, u32, u32);
int xip_safe, p0, p1, p2, p3;
- u32 osc_clk = 0, sys_clkin_sel;
- u32 clk_index, sil_index = 0;
- struct prm *prm_base = (struct prm *)PRM_BASE;
- struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
- dpll_param *dpll_param_p;
-
- f_lock_pll = (void *) ((u32) &_end_vect - (u32) &_start +
- SRAM_VECT_CODE);
xip_safe = is_running_in_sram();
- /*
- * Gauge the input clock speed and find out the sys_clkin_sel
- * value corresponding to the input clock.
- */
- osc_clk = get_osc_clk_speed();
- get_sys_clkin_sel(osc_clk, &sys_clkin_sel);
-
- /* set input crystal speed */
- sr32(&prm_base->clksel, 0, 3, sys_clkin_sel);
+ /* Moving to the right sysclk and ES rev base */
+ ptr = ptr + (3 * clk_index) + sil_index;
- /* If the input clock is greater than 19.2M always divide/2 */
- if (sys_clkin_sel > 2) {
- /* input clock divider */
- sr32(&prm_base->clksrc_ctrl, 6, 2, 2);
- clk_index = sys_clkin_sel / 2;
- } else {
- /* input clock divider */
- sr32(&prm_base->clksrc_ctrl, 6, 2, 1);
- clk_index = sys_clkin_sel;
- }
-
- /*
- * The DPLL tables are defined according to sysclk value and
- * silicon revision. The clk_index value will be used to get
- * the values for that input sysclk from the DPLL param table
- * and sil_index will get the values for that SysClk for the
- * appropriate silicon rev.
- */
- if (get_cpu_rev())
- sil_index = 1;
-
- /* Unlock MPU DPLL (slows things down, and needed later) */
- sr32(&prcm_base->clken_pll_mpu, 0, 3, PLL_LOW_POWER_BYPASS);
- wait_on_value(ST_MPU_CLK, 0, &prcm_base->idlest_pll_mpu, LDELAY);
-
- /* Getting the base address of Core DPLL param table */
- dpll_param_p = (dpll_param *) get_core_dpll_param();
-
- /* Moving it to the right sysclk and ES rev base */
- dpll_param_p = dpll_param_p + 3 * clk_index + sil_index;
if (xip_safe) {
/*
* CORE DPLL
@@ -208,34 +156,38 @@ void prcm_init(void)
* work. write another value and then default value.
*/
- /* m3x2 */
- sr32(&prcm_base->clksel1_emu, 16, 5, CORE_M3X2 + 1);
- /* m3x2 */
+ /* CM_CLKSEL1_EMU[DIV_DPLL3] */
+ sr32(&prcm_base->clksel1_emu, 16, 5, (CORE_M3X2 + 1)) ;
sr32(&prcm_base->clksel1_emu, 16, 5, CORE_M3X2);
- /* Set M2 */
- sr32(&prcm_base->clksel1_pll, 27, 2, dpll_param_p->m2);
- /* Set M */
- sr32(&prcm_base->clksel1_pll, 16, 11, dpll_param_p->m);
- /* Set N */
- sr32(&prcm_base->clksel1_pll, 8, 7, dpll_param_p->n);
- /* 96M Src */
+
+ /* M2 (CORE_DPLL_CLKOUT_DIV): CM_CLKSEL1_PLL[27:31] */
+ sr32(&prcm_base->clksel1_pll, 27, 5, ptr->m2);
+
+ /* M (CORE_DPLL_MULT): CM_CLKSEL1_PLL[16:26] */
+ sr32(&prcm_base->clksel1_pll, 16, 11, ptr->m);
+
+ /* N (CORE_DPLL_DIV): CM_CLKSEL1_PLL[8:14] */
+ sr32(&prcm_base->clksel1_pll, 8, 7, ptr->n);
+
+ /* Source is the CM_96M_FCLK: CM_CLKSEL1_PLL[6] */
sr32(&prcm_base->clksel1_pll, 6, 1, 0);
- /* ssi */
+
+ /* SSI */
sr32(&prcm_base->clksel_core, 8, 4, CORE_SSI_DIV);
- /* fsusb */
+ /* FSUSB */
sr32(&prcm_base->clksel_core, 4, 2, CORE_FUSB_DIV);
- /* l4 */
+ /* L4 */
sr32(&prcm_base->clksel_core, 2, 2, CORE_L4_DIV);
- /* l3 */
+ /* L3 */
sr32(&prcm_base->clksel_core, 0, 2, CORE_L3_DIV);
- /* gfx */
- sr32(&prcm_base->clksel_gfx, 0, 3, GFX_DIV);
- /* reset mgr */
+ /* GFX */
+ sr32(&prcm_base->clksel_gfx, 0, 3, GFX_DIV);
+ /* RESET MGR */
sr32(&prcm_base->clksel_wkup, 1, 2, WKUP_RSM);
- /* FREQSEL */
- sr32(&prcm_base->clken_pll, 4, 4, dpll_param_p->fsel);
- /* lock mode */
- sr32(&prcm_base->clken_pll, 0, 3, PLL_LOCK);
+ /* FREQSEL (CORE_DPLL_FREQSEL): CM_CLKEN_PLL[4:7] */
+ sr32(&prcm_base->clken_pll, 4, 4, ptr->fsel);
+ /* LOCK MODE */
+ sr32(&prcm_base->clken_pll, 0, 3, PLL_LOCK);
wait_on_value(ST_CORE_CLK, 1, &prcm_base->idlest_ckgen,
LDELAY);
@@ -244,102 +196,405 @@ void prcm_init(void)
* if running from flash, jump to small relocated code
* area in SRAM.
*/
+ f_lock_pll = (void *) ((u32) &_end_vect - (u32) &_start +
+ SRAM_VECT_CODE);
+
p0 = readl(&prcm_base->clken_pll);
sr32(&p0, 0, 3, PLL_FAST_RELOCK_BYPASS);
- sr32(&p0, 4, 4, dpll_param_p->fsel); /* FREQSEL */
+ /* FREQSEL (CORE_DPLL_FREQSEL): CM_CLKEN_PLL[4:7] */
+ sr32(&p0, 4, 4, ptr->fsel);
p1 = readl(&prcm_base->clksel1_pll);
- sr32(&p1, 27, 2, dpll_param_p->m2); /* Set M2 */
- sr32(&p1, 16, 11, dpll_param_p->m); /* Set M */
- sr32(&p1, 8, 7, dpll_param_p->n); /* Set N */
- sr32(&p1, 6, 1, 0); /* set source for 96M */
+ /* M2 (CORE_DPLL_CLKOUT_DIV): CM_CLKSEL1_PLL[27:31] */
+ sr32(&p1, 27, 5, ptr->m2);
+ /* M (CORE_DPLL_MULT): CM_CLKSEL1_PLL[16:26] */
+ sr32(&p1, 16, 11, ptr->m);
+ /* N (CORE_DPLL_DIV): CM_CLKSEL1_PLL[8:14] */
+ sr32(&p1, 8, 7, ptr->n);
+ /* Source is the CM_96M_FCLK: CM_CLKSEL1_PLL[6] */
+ sr32(&p1, 6, 1, 0);
p2 = readl(&prcm_base->clksel_core);
- sr32(&p2, 8, 4, CORE_SSI_DIV); /* ssi */
- sr32(&p2, 4, 2, CORE_FUSB_DIV); /* fsusb */
- sr32(&p2, 2, 2, CORE_L4_DIV); /* l4 */
- sr32(&p2, 0, 2, CORE_L3_DIV); /* l3 */
+ /* SSI */
+ sr32(&p2, 8, 4, CORE_SSI_DIV);
+ /* FSUSB */
+ sr32(&p2, 4, 2, CORE_FUSB_DIV);
+ /* L4 */
+ sr32(&p2, 2, 2, CORE_L4_DIV);
+ /* L3 */
+ sr32(&p2, 0, 2, CORE_L3_DIV);
p3 = (u32)&prcm_base->idlest_ckgen;
(*f_lock_pll) (p0, p1, p2, p3);
}
+}
- /* PER DPLL */
- sr32(&prcm_base->clken_pll, 16, 3, PLL_STOP);
- wait_on_value(ST_PERIPH_CLK, 0, &prcm_base->idlest_ckgen, LDELAY);
-
- /* Getting the base address to PER DPLL param table */
-
- /* Set N */
- dpll_param_p = (dpll_param *) get_per_dpll_param();
+static void dpll4_init_34xx(u32 sil_index, u32 clk_index)
+{
+ struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
+ dpll_param *ptr = (dpll_param *) get_per_dpll_param();
/* Moving it to the right sysclk base */
- dpll_param_p = dpll_param_p + clk_index;
+ ptr = ptr + clk_index;
+
+ /* EN_PERIPH_DPLL: CM_CLKEN_PLL[16:18] */
+ sr32(&prcm_base->clken_pll, 16, 3, PLL_STOP);
+ wait_on_value(ST_PERIPH_CLK, 0, &prcm_base->idlest_ckgen, LDELAY);
/*
* Errata 1.50 Workaround for OMAP3 ES1.0 only
* If using default divisors, write default divisor + 1
* and then the actual divisor value
*/
- sr32(&prcm_base->clksel1_emu, 24, 5, PER_M6X2 + 1); /* set M6 */
- sr32(&prcm_base->clksel1_emu, 24, 5, PER_M6X2); /* set M6 */
- sr32(&prcm_base->clksel_cam, 0, 5, PER_M5X2 + 1); /* set M5 */
- sr32(&prcm_base->clksel_cam, 0, 5, PER_M5X2); /* set M5 */
- sr32(&prcm_base->clksel_dss, 0, 5, PER_M4X2 + 1); /* set M4 */
- sr32(&prcm_base->clksel_dss, 0, 5, PER_M4X2); /* set M4 */
- sr32(&prcm_base->clksel_dss, 8, 5, PER_M3X2 + 1); /* set M3 */
- sr32(&prcm_base->clksel_dss, 8, 5, PER_M3X2); /* set M3 */
- sr32(&prcm_base->clksel3_pll, 0, 5, dpll_param_p->m2 + 1); /* set M2 */
- sr32(&prcm_base->clksel3_pll, 0, 5, dpll_param_p->m2); /* set M2 */
+ /* M6 */
+ sr32(&prcm_base->clksel1_emu, 24, 5, (PER_M6X2 + 1));
+ sr32(&prcm_base->clksel1_emu, 24, 5, PER_M6X2);
+ /* M5 */
+ sr32(&prcm_base->clksel_cam, 0, 5, (PER_M5X2 + 1));
+ sr32(&prcm_base->clksel_cam, 0, 5, PER_M5X2);
+ /* M4 */
+ sr32(&prcm_base->clksel_dss, 0, 5, (PER_M4X2 + 1));
+ sr32(&prcm_base->clksel_dss, 0, 5, PER_M4X2);
+ /* M3 */
+ sr32(&prcm_base->clksel_dss, 8, 5, (PER_M3X2 + 1));
+ sr32(&prcm_base->clksel_dss, 8, 5, PER_M3X2);
+ /* M2 (DIV_96M): CM_CLKSEL3_PLL[0:4] */
+ sr32(&prcm_base->clksel3_pll, 0, 5, (ptr->m2 + 1));
+ sr32(&prcm_base->clksel3_pll, 0, 5, ptr->m2);
/* Workaround end */
- sr32(&prcm_base->clksel2_pll, 8, 11, dpll_param_p->m); /* set m */
- sr32(&prcm_base->clksel2_pll, 0, 7, dpll_param_p->n); /* set n */
- sr32(&prcm_base->clken_pll, 20, 4, dpll_param_p->fsel); /* FREQSEL */
- sr32(&prcm_base->clken_pll, 16, 3, PLL_LOCK); /* lock mode */
+ /* M (PERIPH_DPLL_MULT): CM_CLKSEL2_PLL[8:18] */
+ sr32(&prcm_base->clksel2_pll, 8, 11, ptr->m);
+
+ /* N (PERIPH_DPLL_DIV): CM_CLKSEL2_PLL[0:6] */
+ sr32(&prcm_base->clksel2_pll, 0, 7, ptr->n);
+
+ /* FREQSEL (PERIPH_DPLL_FREQSEL): CM_CLKEN_PLL[20:23] */
+ sr32(&prcm_base->clken_pll, 20, 4, ptr->fsel);
+
+ /* LOCK MODE (EN_PERIPH_DPLL): CM_CLKEN_PLL[16:18] */
+ sr32(&prcm_base->clken_pll, 16, 3, PLL_LOCK);
wait_on_value(ST_PERIPH_CLK, 2, &prcm_base->idlest_ckgen, LDELAY);
+}
- /* Getting the base address to MPU DPLL param table */
- dpll_param_p = (dpll_param *) get_mpu_dpll_param();
+static void mpu_init_34xx(u32 sil_index, u32 clk_index)
+{
+ struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
+ dpll_param *ptr = (dpll_param *) get_mpu_dpll_param();
- /* Moving it to the right sysclk and ES rev base */
- dpll_param_p = dpll_param_p + 3 * clk_index + sil_index;
+ /* Moving to the right sysclk and ES rev base */
+ ptr = ptr + (3 * clk_index) + sil_index;
/* MPU DPLL (unlocked already) */
- /* Set M2 */
- sr32(&prcm_base->clksel2_pll_mpu, 0, 5, dpll_param_p->m2);
- /* Set M */
- sr32(&prcm_base->clksel1_pll_mpu, 8, 11, dpll_param_p->m);
- /* Set N */
- sr32(&prcm_base->clksel1_pll_mpu, 0, 7, dpll_param_p->n);
- /* FREQSEL */
- sr32(&prcm_base->clken_pll_mpu, 4, 4, dpll_param_p->fsel);
- /* lock mode */
- sr32(&prcm_base->clken_pll_mpu, 0, 3, PLL_LOCK);
- wait_on_value(ST_MPU_CLK, 1, &prcm_base->idlest_pll_mpu, LDELAY);
-
- /* Getting the base address to IVA DPLL param table */
- dpll_param_p = (dpll_param *) get_iva_dpll_param();
-
- /* Moving it to the right sysclk and ES rev base */
- dpll_param_p = dpll_param_p + 3 * clk_index + sil_index;
-
- /* IVA DPLL (set to 12*20=240MHz) */
+ /* M2 (MPU_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_MPU[0:4] */
+ sr32(&prcm_base->clksel2_pll_mpu, 0, 5, ptr->m2);
+
+ /* M (MPU_DPLL_MULT) : CM_CLKSEL2_PLL_MPU[8:18] */
+ sr32(&prcm_base->clksel1_pll_mpu, 8, 11, ptr->m);
+
+ /* N (MPU_DPLL_DIV) : CM_CLKSEL2_PLL_MPU[0:6] */
+ sr32(&prcm_base->clksel1_pll_mpu, 0, 7, ptr->n);
+
+ /* FREQSEL (MPU_DPLL_FREQSEL) : CM_CLKEN_PLL_MPU[4:7] */
+ sr32(&prcm_base->clken_pll_mpu, 4, 4, ptr->fsel);
+}
+
+static void iva_init_34xx(u32 sil_index, u32 clk_index)
+{
+ struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
+ dpll_param *ptr = (dpll_param *) get_iva_dpll_param();
+
+ /* Moving to the right sysclk and ES rev base */
+ ptr = ptr + (3 * clk_index) + sil_index;
+
+ /* IVA DPLL */
+ /* EN_IVA2_DPLL : CM_CLKEN_PLL_IVA2[0:2] */
+ sr32(&prcm_base->clken_pll_iva2, 0, 3, PLL_STOP);
+ wait_on_value(ST_IVA2_CLK, 0, &prcm_base->idlest_pll_iva2, LDELAY);
+
+ /* M2 (IVA2_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_IVA2[0:4] */
+ sr32(&prcm_base->clksel2_pll_iva2, 0, 5, ptr->m2);
+
+ /* M (IVA2_DPLL_MULT) : CM_CLKSEL1_PLL_IVA2[8:18] */
+ sr32(&prcm_base->clksel1_pll_iva2, 8, 11, ptr->m);
+
+ /* N (IVA2_DPLL_DIV) : CM_CLKSEL1_PLL_IVA2[0:6] */
+ sr32(&prcm_base->clksel1_pll_iva2, 0, 7, ptr->n);
+
+ /* FREQSEL (IVA2_DPLL_FREQSEL) : CM_CLKEN_PLL_IVA2[4:7] */
+ sr32(&prcm_base->clken_pll_iva2, 4, 4, ptr->fsel);
+
+ /* LOCK MODE (EN_IVA2_DPLL) : CM_CLKEN_PLL_IVA2[0:2] */
+ sr32(&prcm_base->clken_pll_iva2, 0, 3, PLL_LOCK);
+
+ wait_on_value(ST_IVA2_CLK, 1, &prcm_base->idlest_pll_iva2, LDELAY);
+}
+
+/*
+ * OMAP3630 specific functions
+ */
+
+static void dpll3_init_36xx(u32 sil_index, u32 clk_index)
+{
+ struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
+ dpll_param *ptr = (dpll_param *) get_36x_core_dpll_param();
+ void (*f_lock_pll) (u32, u32, u32, u32);
+ int xip_safe, p0, p1, p2, p3;
+
+ xip_safe = is_running_in_sram();
+
+ /* Moving it to the right sysclk base */
+ ptr += clk_index;
+
+ if (xip_safe) {
+ /* CORE DPLL */
+
+ /* Select relock bypass: CM_CLKEN_PLL[0:2] */
+ sr32(&prcm_base->clken_pll, 0, 3, PLL_FAST_RELOCK_BYPASS);
+ wait_on_value(ST_CORE_CLK, 0, &prcm_base->idlest_ckgen,
+ LDELAY);
+
+ /* CM_CLKSEL1_EMU[DIV_DPLL3] */
+ sr32(&prcm_base->clksel1_emu, 16, 5, CORE_M3X2);
+
+ /* M2 (CORE_DPLL_CLKOUT_DIV): CM_CLKSEL1_PLL[27:31] */
+ sr32(&prcm_base->clksel1_pll, 27, 5, ptr->m2);
+
+ /* M (CORE_DPLL_MULT): CM_CLKSEL1_PLL[16:26] */
+ sr32(&prcm_base->clksel1_pll, 16, 11, ptr->m);
+
+ /* N (CORE_DPLL_DIV): CM_CLKSEL1_PLL[8:14] */
+ sr32(&prcm_base->clksel1_pll, 8, 7, ptr->n);
+
+ /* Source is the CM_96M_FCLK: CM_CLKSEL1_PLL[6] */
+ sr32(&prcm_base->clksel1_pll, 6, 1, 0);
+
+ /* SSI */
+ sr32(&prcm_base->clksel_core, 8, 4, CORE_SSI_DIV);
+ /* FSUSB */
+ sr32(&prcm_base->clksel_core, 4, 2, CORE_FUSB_DIV);
+ /* L4 */
+ sr32(&prcm_base->clksel_core, 2, 2, CORE_L4_DIV);
+ /* L3 */
+ sr32(&prcm_base->clksel_core, 0, 2, CORE_L3_DIV);
+ /* GFX */
+ sr32(&prcm_base->clksel_gfx, 0, 3, GFX_DIV);
+ /* RESET MGR */
+ sr32(&prcm_base->clksel_wkup, 1, 2, WKUP_RSM);
+ /* FREQSEL (CORE_DPLL_FREQSEL): CM_CLKEN_PLL[4:7] */
+ sr32(&prcm_base->clken_pll, 4, 4, ptr->fsel);
+ /* LOCK MODE */
+ sr32(&prcm_base->clken_pll, 0, 3, PLL_LOCK);
+
+ wait_on_value(ST_CORE_CLK, 1, &prcm_base->idlest_ckgen,
+ LDELAY);
+ } else if (is_running_in_flash()) {
+ /*
+ * if running from flash, jump to small relocated code
+ * area in SRAM.
+ */
+ f_lock_pll = (void *) ((u32) &_end_vect - (u32) &_start +
+ SRAM_VECT_CODE);
+
+ p0 = readl(&prcm_base->clken_pll);
+ sr32(&p0, 0, 3, PLL_FAST_RELOCK_BYPASS);
+ /* FREQSEL (CORE_DPLL_FREQSEL): CM_CLKEN_PLL[4:7] */
+ sr32(&p0, 4, 4, ptr->fsel);
+
+ p1 = readl(&prcm_base->clksel1_pll);
+ /* M2 (CORE_DPLL_CLKOUT_DIV): CM_CLKSEL1_PLL[27:31] */
+ sr32(&p1, 27, 5, ptr->m2);
+ /* M (CORE_DPLL_MULT): CM_CLKSEL1_PLL[16:26] */
+ sr32(&p1, 16, 11, ptr->m);
+ /* N (CORE_DPLL_DIV): CM_CLKSEL1_PLL[8:14] */
+ sr32(&p1, 8, 7, ptr->n);
+ /* Source is the CM_96M_FCLK: CM_CLKSEL1_PLL[6] */
+ sr32(&p1, 6, 1, 0);
+
+ p2 = readl(&prcm_base->clksel_core);
+ /* SSI */
+ sr32(&p2, 8, 4, CORE_SSI_DIV);
+ /* FSUSB */
+ sr32(&p2, 4, 2, CORE_FUSB_DIV);
+ /* L4 */
+ sr32(&p2, 2, 2, CORE_L4_DIV);
+ /* L3 */
+ sr32(&p2, 0, 2, CORE_L3_DIV);
+
+ p3 = (u32)&prcm_base->idlest_ckgen;
+
+ (*f_lock_pll) (p0, p1, p2, p3);
+ }
+}
+
+static void dpll4_init_36xx(u32 sil_index, u32 clk_index)
+{
+ struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
+ struct dpll_per_36x_param *ptr;
+
+ ptr = (struct dpll_per_36x_param *)get_36x_per_dpll_param();
+
+ /* Moving it to the right sysclk base */
+ ptr += clk_index;
+
+ /* EN_PERIPH_DPLL: CM_CLKEN_PLL[16:18] */
+ sr32(&prcm_base->clken_pll, 16, 3, PLL_STOP);
+ wait_on_value(ST_PERIPH_CLK, 0, &prcm_base->idlest_ckgen, LDELAY);
+
+ /* M6 (DIV_DPLL4): CM_CLKSEL1_EMU[24:29] */
+ sr32(&prcm_base->clksel1_emu, 24, 6, ptr->m6);
+
+ /* M5 (CLKSEL_CAM): CM_CLKSEL1_EMU[0:5] */
+ sr32(&prcm_base->clksel_cam, 0, 6, ptr->m5);
+
+ /* M4 (CLKSEL_DSS1): CM_CLKSEL_DSS[0:5] */
+ sr32(&prcm_base->clksel_dss, 0, 6, ptr->m4);
+
+ /* M3 (CLKSEL_DSS1): CM_CLKSEL_DSS[8:13] */
+ sr32(&prcm_base->clksel_dss, 8, 6, ptr->m3);
+
+ /* M2 (DIV_96M): CM_CLKSEL3_PLL[0:4] */
+ sr32(&prcm_base->clksel3_pll, 0, 5, ptr->m2);
+
+ /* M (PERIPH_DPLL_MULT): CM_CLKSEL2_PLL[8:19] */
+ sr32(&prcm_base->clksel2_pll, 8, 12, ptr->m);
+
+ /* N (PERIPH_DPLL_DIV): CM_CLKSEL2_PLL[0:6] */
+ sr32(&prcm_base->clksel2_pll, 0, 7, ptr->n);
+
+ /* M2DIV (CLKSEL_96M): CM_CLKSEL_CORE[12:13] */
+ sr32(&prcm_base->clksel_core, 12, 2, ptr->m2div);
+
+ /* LOCK MODE (EN_PERIPH_DPLL): CM_CLKEN_PLL[16:18] */
+ sr32(&prcm_base->clken_pll, 16, 3, PLL_LOCK);
+ wait_on_value(ST_PERIPH_CLK, 2, &prcm_base->idlest_ckgen, LDELAY);
+}
+
+static void mpu_init_36xx(u32 sil_index, u32 clk_index)
+{
+ struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
+ dpll_param *ptr = (dpll_param *) get_36x_mpu_dpll_param();
+
+ /* Moving to the right sysclk */
+ ptr += clk_index;
+
+ /* MPU DPLL (unlocked already */
+
+ /* M2 (MPU_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_MPU[0:4] */
+ sr32(&prcm_base->clksel2_pll_mpu, 0, 5, ptr->m2);
+
+ /* M (MPU_DPLL_MULT) : CM_CLKSEL2_PLL_MPU[8:18] */
+ sr32(&prcm_base->clksel1_pll_mpu, 8, 11, ptr->m);
+
+ /* N (MPU_DPLL_DIV) : CM_CLKSEL2_PLL_MPU[0:6] */
+ sr32(&prcm_base->clksel1_pll_mpu, 0, 7, ptr->n);
+}
+
+static void iva_init_36xx(u32 sil_index, u32 clk_index)
+{
+ struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
+ dpll_param *ptr = (dpll_param *)get_36x_iva_dpll_param();
+
+ /* Moving to the right sysclk */
+ ptr += clk_index;
+
+ /* IVA DPLL */
+ /* EN_IVA2_DPLL : CM_CLKEN_PLL_IVA2[0:2] */
sr32(&prcm_base->clken_pll_iva2, 0, 3, PLL_STOP);
wait_on_value(ST_IVA2_CLK, 0, &prcm_base->idlest_pll_iva2, LDELAY);
- /* set M2 */
- sr32(&prcm_base->clksel2_pll_iva2, 0, 5, dpll_param_p->m2);
- /* set M */
- sr32(&prcm_base->clksel1_pll_iva2, 8, 11, dpll_param_p->m);
- /* set N */
- sr32(&prcm_base->clksel1_pll_iva2, 0, 7, dpll_param_p->n);
- /* FREQSEL */
- sr32(&prcm_base->clken_pll_iva2, 4, 4, dpll_param_p->fsel);
- /* lock mode */
+
+ /* M2 (IVA2_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_IVA2[0:4] */
+ sr32(&prcm_base->clksel2_pll_iva2, 0, 5, ptr->m2);
+
+ /* M (IVA2_DPLL_MULT) : CM_CLKSEL1_PLL_IVA2[8:18] */
+ sr32(&prcm_base->clksel1_pll_iva2, 8, 11, ptr->m);
+
+ /* N (IVA2_DPLL_DIV) : CM_CLKSEL1_PLL_IVA2[0:6] */
+ sr32(&prcm_base->clksel1_pll_iva2, 0, 7, ptr->n);
+
+ /* LOCK (MODE (EN_IVA2_DPLL) : CM_CLKEN_PLL_IVA2[0:2] */
sr32(&prcm_base->clken_pll_iva2, 0, 3, PLL_LOCK);
+
wait_on_value(ST_IVA2_CLK, 1, &prcm_base->idlest_pll_iva2, LDELAY);
+}
+
+/******************************************************************************
+ * prcm_init() - inits clocks for PRCM as defined in clocks.h
+ * called from SRAM, or Flash (using temp SRAM stack).
+ *****************************************************************************/
+void prcm_init(void)
+{
+ u32 osc_clk = 0, sys_clkin_sel;
+ u32 clk_index, sil_index = 0;
+ struct prm *prm_base = (struct prm *)PRM_BASE;
+ struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
+
+ /*
+ * Gauge the input clock speed and find out the sys_clkin_sel
+ * value corresponding to the input clock.
+ */
+ osc_clk = get_osc_clk_speed();
+ get_sys_clkin_sel(osc_clk, &sys_clkin_sel);
+
+ /* set input crystal speed */
+ sr32(&prm_base->clksel, 0, 3, sys_clkin_sel);
+
+ /* If the input clock is greater than 19.2M always divide/2 */
+ if (sys_clkin_sel > 2) {
+ /* input clock divider */
+ sr32(&prm_base->clksrc_ctrl, 6, 2, 2);
+ clk_index = sys_clkin_sel / 2;
+ } else {
+ /* input clock divider */
+ sr32(&prm_base->clksrc_ctrl, 6, 2, 1);
+ clk_index = sys_clkin_sel;
+ }
+
+ if (get_cpu_family() == CPU_OMAP36XX) {
+ /* Unlock MPU DPLL (slows things down, and needed later) */
+ sr32(&prcm_base->clken_pll_mpu, 0, 3, PLL_LOW_POWER_BYPASS);
+ wait_on_value(ST_MPU_CLK, 0, &prcm_base->idlest_pll_mpu,
+ LDELAY);
+
+ dpll3_init_36xx(0, clk_index);
+ dpll4_init_36xx(0, clk_index);
+ iva_init_36xx(0, clk_index);
+ mpu_init_36xx(0, clk_index);
+
+ /* Lock MPU DPLL to set frequency */
+ sr32(&prcm_base->clken_pll_mpu, 0, 3, PLL_LOCK);
+ wait_on_value(ST_MPU_CLK, 1, &prcm_base->idlest_pll_mpu,
+ LDELAY);
+ } else {
+ /*
+ * The DPLL tables are defined according to sysclk value and
+ * silicon revision. The clk_index value will be used to get
+ * the values for that input sysclk from the DPLL param table
+ * and sil_index will get the values for that SysClk for the
+ * appropriate silicon rev.
+ */
+ if (((get_cpu_family() == CPU_OMAP34XX)
+ && (get_cpu_rev() >= CPU_3XX_ES20)) ||
+ (get_cpu_family() == CPU_AM35XX))
+ sil_index = 1;
+
+ /* Unlock MPU DPLL (slows things down, and needed later) */
+ sr32(&prcm_base->clken_pll_mpu, 0, 3, PLL_LOW_POWER_BYPASS);
+ wait_on_value(ST_MPU_CLK, 0, &prcm_base->idlest_pll_mpu,
+ LDELAY);
+
+ dpll3_init_34xx(sil_index, clk_index);
+ dpll4_init_34xx(sil_index, clk_index);
+ iva_init_34xx(sil_index, clk_index);
+ mpu_init_34xx(sil_index, clk_index);
+
+ /* Lock MPU DPLL to set frequency */
+ sr32(&prcm_base->clken_pll_mpu, 0, 3, PLL_LOCK);
+ wait_on_value(ST_MPU_CLK, 1, &prcm_base->idlest_pll_mpu,
+ LDELAY);
+ }
/* Set up GPTimers to sys_clk source only */
sr32(&prcm_base->clksel_per, 0, 8, 0xff);
diff --git a/arch/arm/cpu/armv7/omap3/lowlevel_init.S b/arch/arm/cpu/armv7/omap3/lowlevel_init.S
index 73063ec8e6..91c6dbcc09 100644
--- a/arch/arm/cpu/armv7/omap3/lowlevel_init.S
+++ b/arch/arm/cpu/armv7/omap3/lowlevel_init.S
@@ -359,3 +359,72 @@ per_dpll_param:
get_per_dpll_param:
adr r0, per_dpll_param
mov pc, lr
+
+/*
+ * Tables for 36XX/37XX devices
+ *
+ */
+mpu_36x_dpll_param:
+/* 12MHz */
+.word 50, 0, 0, 1
+/* 13MHz */
+.word 600, 12, 0, 1
+/* 19.2MHz */
+.word 125, 3, 0, 1
+/* 26MHz */
+.word 300, 12, 0, 1
+/* 38.4MHz */
+.word 125, 7, 0, 1
+
+iva_36x_dpll_param:
+/* 12MHz */
+.word 130, 2, 0, 1
+/* 13MHz */
+.word 20, 0, 0, 1
+/* 19.2MHz */
+.word 325, 11, 0, 1
+/* 26MHz */
+.word 10, 0, 0, 1
+/* 38.4MHz */
+.word 325, 23, 0, 1
+
+core_36x_dpll_param:
+/* 12MHz */
+.word 100, 2, 0, 1
+/* 13MHz */
+.word 400, 12, 0, 1
+/* 19.2MHz */
+.word 375, 17, 0, 1
+/* 26MHz */
+.word 200, 12, 0, 1
+/* 38.4MHz */
+.word 375, 35, 0, 1
+
+per_36x_dpll_param:
+/* SYSCLK M N M2 M3 M4 M5 M6 m2DIV */
+.word 12000, 360, 4, 9, 16, 5, 4, 3, 1
+.word 13000, 864, 12, 9, 16, 9, 4, 3, 1
+.word 19200, 360, 7, 9, 16, 5, 4, 3, 1
+.word 26000, 432, 12, 9, 16, 9, 4, 3, 1
+.word 38400, 360, 15, 9, 16, 5, 4, 3, 1
+
+.globl get_36x_mpu_dpll_param
+get_36x_mpu_dpll_param:
+ adr r0, mpu_36x_dpll_param
+ mov pc, lr
+
+.globl get_36x_iva_dpll_param
+get_36x_iva_dpll_param:
+ adr r0, iva_36x_dpll_param
+ mov pc, lr
+
+.globl get_36x_core_dpll_param
+get_36x_core_dpll_param:
+ adr r0, core_36x_dpll_param
+ mov pc, lr
+
+.globl get_36x_per_dpll_param
+get_36x_per_dpll_param:
+ adr r0, per_36x_dpll_param
+ mov pc, lr
+
diff --git a/arch/arm/cpu/armv7/omap3/sdrc.c b/arch/arm/cpu/armv7/omap3/sdrc.c
index 96fd990c71..8905224439 100644
--- a/arch/arm/cpu/armv7/omap3/sdrc.c
+++ b/arch/arm/cpu/armv7/omap3/sdrc.c
@@ -107,18 +107,12 @@ u32 get_sdr_cs_offset(u32 cs)
/*
* do_sdrc_init -
* - Initialize the SDRAM for use.
- * - Sets up SDRC timings for CS0
* - code called once in C-Stack only context for CS0 and a possible 2nd
* time depending on memory configuration from stack+global context
*/
void do_sdrc_init(u32 cs, u32 early)
{
- struct sdrc_actim *sdrc_actim_base;
-
- if (cs)
- sdrc_actim_base = (struct sdrc_actim *)SDRC_ACTIM_CTRL1_BASE;
- else
- sdrc_actim_base = (struct sdrc_actim *)SDRC_ACTIM_CTRL0_BASE;
+ struct sdrc_actim *sdrc_actim_base0, *sdrc_actim_base1;
if (early) {
/* reset sdrc controller */
@@ -138,24 +132,29 @@ void do_sdrc_init(u32 cs, u32 early)
sdelay(0x20000);
}
- writel(RASWIDTH_13BITS | CASWIDTH_10BITS | ADDRMUXLEGACY |
- RAMSIZE_128 | BANKALLOCATION | B32NOT16 | B32NOT16 |
- DEEPPD | DDR_SDRAM, &sdrc_base->cs[cs].mcfg);
- writel(ARCV | ARE_ARCV_1, &sdrc_base->cs[cs].rfr_ctrl);
- writel(V_ACTIMA_165, &sdrc_actim_base->ctrla);
- writel(V_ACTIMB_165, &sdrc_actim_base->ctrlb);
-
- writel(CMD_NOP, &sdrc_base->cs[cs].manual);
- writel(CMD_PRECHARGE, &sdrc_base->cs[cs].manual);
- writel(CMD_AUTOREFRESH, &sdrc_base->cs[cs].manual);
- writel(CMD_AUTOREFRESH, &sdrc_base->cs[cs].manual);
-
/*
- * CAS latency 3, Write Burst = Read Burst, Serial Mode,
- * Burst length = 4
+ * SDRC timings are set up by x-load or config header
+ * We don't need to redo them here.
+ * Older x-loads configure only CS0
+ * configure CS1 to handle this ommission
*/
- writel(CASL3 | BURSTLENGTH4, &sdrc_base->cs[cs].mr);
+ if (cs) {
+ sdrc_actim_base0 = (struct sdrc_actim *)SDRC_ACTIM_CTRL0_BASE;
+ sdrc_actim_base1 = (struct sdrc_actim *)SDRC_ACTIM_CTRL1_BASE;
+ writel(readl(&sdrc_base->cs[CS0].mcfg),
+ &sdrc_base->cs[CS1].mcfg);
+ writel(readl(&sdrc_base->cs[CS0].rfr_ctrl),
+ &sdrc_base->cs[CS1].rfr_ctrl);
+ writel(readl(&sdrc_actim_base0->ctrla),
+ &sdrc_actim_base1->ctrla);
+ writel(readl(&sdrc_actim_base0->ctrlb),
+ &sdrc_actim_base1->ctrlb);
+ }
+ /*
+ * Test ram in this bank
+ * Disable if bad or not present
+ */
if (!mem_ok(cs))
writel(0, &sdrc_base->cs[cs].mcfg);
}
diff --git a/arch/arm/cpu/armv7/omap3/sys_info.c b/arch/arm/cpu/armv7/omap3/sys_info.c
index 1df4401d49..549ac19189 100644
--- a/arch/arm/cpu/armv7/omap3/sys_info.c
+++ b/arch/arm/cpu/armv7/omap3/sys_info.c
@@ -38,7 +38,10 @@ static char *rev_s[CPU_3XX_MAX_REV] = {
"2.0",
"2.1",
"3.0",
- "3.1"};
+ "3.1",
+ "UNKNOWN",
+ "UNKNOWN",
+ "3.1.2"};
/*****************************************************************
* dieid_num_r(void) - read and set die ID
@@ -75,32 +78,81 @@ u32 get_cpu_type(void)
}
/******************************************
- * get_cpu_rev(void) - extract version info
+ * get_cpu_id(void) - extract cpu id
+ * returns 0 for ES1.0, cpuid otherwise
******************************************/
-u32 get_cpu_rev(void)
+u32 get_cpu_id(void)
{
- u32 cpuid = 0;
struct ctrl_id *id_base;
+ u32 cpuid = 0;
/*
* On ES1.0 the IDCODE register is not exposed on L4
* so using CPU ID to differentiate between ES1.0 and > ES1.0.
*/
__asm__ __volatile__("mrc p15, 0, %0, c0, c0, 0":"=r"(cpuid));
- if ((cpuid & 0xf) == 0x0)
- return CPU_3XX_ES10;
- else {
+ if ((cpuid & 0xf) == 0x0) {
+ return 0;
+ } else {
/* Decode the IDs on > ES1.0 */
id_base = (struct ctrl_id *) OMAP34XX_ID_L4_IO_BASE;
- cpuid = (readl(&id_base->idcode) >> CPU_3XX_ID_SHIFT) & 0xf;
+ cpuid = readl(&id_base->idcode);
+ }
- /* Some early ES2.0 seem to report ID 0, fix this */
- if(cpuid == 0)
- cpuid = CPU_3XX_ES20;
+ return cpuid;
+}
- return cpuid;
+/******************************************
+ * get_cpu_family(void) - extract cpu info
+ ******************************************/
+u32 get_cpu_family(void)
+{
+ u16 hawkeye;
+ u32 cpu_family;
+ u32 cpuid = get_cpu_id();
+
+ if (cpuid == 0)
+ return CPU_OMAP34XX;
+
+ hawkeye = (cpuid >> HAWKEYE_SHIFT) & 0xffff;
+ switch (hawkeye) {
+ case HAWKEYE_OMAP34XX:
+ cpu_family = CPU_OMAP34XX;
+ break;
+ case HAWKEYE_AM35XX:
+ cpu_family = CPU_AM35XX;
+ break;
+ case HAWKEYE_OMAP36XX:
+ cpu_family = CPU_OMAP36XX;
+ break;
+ default:
+ cpu_family = CPU_OMAP34XX;
}
+
+ return cpu_family;
+}
+
+/******************************************
+ * get_cpu_rev(void) - extract version info
+ ******************************************/
+u32 get_cpu_rev(void)
+{
+ u32 cpuid = get_cpu_id();
+
+ if (cpuid == 0)
+ return CPU_3XX_ES10;
+ else
+ return (cpuid >> CPU_3XX_ID_SHIFT) & 0xf;
+}
+
+/*****************************************************************
+ * get_sku_id(void) - read sku_id to get info on max clock rate
+ *****************************************************************/
+u32 get_sku_id(void)
+{
+ struct ctrl_id *id_base = (struct ctrl_id *)OMAP34XX_ID_L4_IO_BASE;
+ return readl(&id_base->sku_id) & SKUID_CLK_MASK;
}
/***************************************************************************
@@ -213,24 +265,66 @@ u32 get_device_type(void)
*/
int print_cpuinfo (void)
{
- char *cpu_s, *sec_s;
+ char *cpu_family_s, *cpu_s, *sec_s, *max_clk;
+
+ switch (get_cpu_family()) {
+ case CPU_OMAP34XX:
+ cpu_family_s = "OMAP";
+ switch (get_cpu_type()) {
+ case OMAP3503:
+ cpu_s = "3503";
+ break;
+ case OMAP3515:
+ cpu_s = "3515";
+ break;
+ case OMAP3525:
+ cpu_s = "3525";
+ break;
+ case OMAP3530:
+ cpu_s = "3530";
+ break;
+ default:
+ cpu_s = "35XX";
+ break;
+ }
+ if ((get_cpu_rev() >= CPU_3XX_ES31) &&
+ (get_sku_id() == SKUID_CLK_720MHZ))
+ max_clk = "720 mHz";
+ else
+ max_clk = "600 mHz";
- switch (get_cpu_type()) {
- case OMAP3503:
- cpu_s = "3503";
break;
- case OMAP3515:
- cpu_s = "3515";
+ case CPU_AM35XX:
+ cpu_family_s = "AM";
+ switch (get_cpu_type()) {
+ case AM3505:
+ cpu_s = "3505";
+ break;
+ case AM3517:
+ cpu_s = "3517";
+ break;
+ default:
+ cpu_s = "35XX";
+ break;
+ }
+ max_clk = "600 Mhz";
break;
- case OMAP3525:
- cpu_s = "3525";
- break;
- case OMAP3530:
- cpu_s = "3530";
+ case CPU_OMAP36XX:
+ cpu_family_s = "OMAP";
+ switch (get_cpu_type()) {
+ case OMAP3730:
+ cpu_s = "3630/3730";
+ break;
+ default:
+ cpu_s = "36XX/37XX";
+ break;
+ }
+ max_clk = "1 Ghz";
break;
default:
+ cpu_family_s = "OMAP";
cpu_s = "35XX";
- break;
+ max_clk = "600 Mhz";
}
switch (get_device_type()) {
@@ -250,8 +344,9 @@ int print_cpuinfo (void)
sec_s = "?";
}
- printf("OMAP%s-%s ES%s, CPU-OPP2 L3-165MHz\n",
- cpu_s, sec_s, rev_s[get_cpu_rev()]);
+ printf("%s%s-%s ES%s, CPU-OPP2, L3-165MHz, Max CPU Clock %s\n",
+ cpu_family_s, cpu_s, sec_s,
+ rev_s[get_cpu_rev()], max_clk);
return 0;
}
diff --git a/arch/arm/cpu/armv7/s5p-common/Makefile b/arch/arm/cpu/armv7/s5p-common/Makefile
new file mode 100644
index 0000000000..37371f6fda
--- /dev/null
+++ b/arch/arm/cpu/armv7/s5p-common/Makefile
@@ -0,0 +1,46 @@
+#
+# Copyright (C) 2009 Samsung Electronics
+# Minkyu Kang <mk7.kang@samsung.com>
+#
+# 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)libs5p-common.a
+
+COBJS-y += cpu_info.o
+COBJS-y += timer.o
+
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS-y) $(SOBJS))
+
+all: $(obj).depend $(LIB)
+
+$(LIB): $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/arch/arm/cpu/armv7/s5pc1xx/cpu_info.c b/arch/arm/cpu/armv7/s5p-common/cpu_info.c
index f16c0ff130..2f6c708554 100644
--- a/arch/arm/cpu/armv7/s5pc1xx/cpu_info.c
+++ b/arch/arm/cpu/armv7/s5p-common/cpu_info.c
@@ -25,15 +25,14 @@
#include <asm/arch/clk.h>
/* Default is s5pc100 */
-unsigned int s5pc1xx_cpu_id = 0xC100;
+unsigned int s5p_cpu_id = 0xC100;
#ifdef CONFIG_ARCH_CPU_INIT
int arch_cpu_init(void)
{
- s5pc1xx_cpu_id = readl(S5PC1XX_PRO_ID);
- s5pc1xx_cpu_id = 0xC000 | ((s5pc1xx_cpu_id & 0x00FFF000) >> 12);
+ s5p_set_cpu_id();
- s5pc1xx_clock_init();
+ s5p_clock_init();
return 0;
}
@@ -41,7 +40,7 @@ int arch_cpu_init(void)
u32 get_device_type(void)
{
- return s5pc1xx_cpu_id;
+ return s5p_cpu_id;
}
#ifdef CONFIG_DISPLAY_CPUINFO
@@ -50,7 +49,7 @@ int print_cpuinfo(void)
char buf[32];
printf("CPU:\tS5P%X@%sMHz\n",
- s5pc1xx_cpu_id, strmhz(buf, get_arm_clk()));
+ s5p_cpu_id, strmhz(buf, get_arm_clk()));
return 0;
}
diff --git a/arch/arm/cpu/armv7/s5pc1xx/timer.c b/arch/arm/cpu/armv7/s5p-common/timer.c
index c5df5c5ab5..04906503e6 100644
--- a/arch/arm/cpu/armv7/s5pc1xx/timer.c
+++ b/arch/arm/cpu/armv7/s5p-common/timer.c
@@ -44,23 +44,20 @@ static unsigned long long timestamp; /* Monotonic incrementing timer */
static unsigned long lastdec; /* Last decremneter snapshot */
/* macro to read the 16 bit timer */
-static inline struct s5pc1xx_timer *s5pc1xx_get_base_timer(void)
+static inline struct s5p_timer *s5p_get_base_timer(void)
{
- if (cpu_is_s5pc110())
- return (struct s5pc1xx_timer *)S5PC110_TIMER_BASE;
- else
- return (struct s5pc1xx_timer *)S5PC100_TIMER_BASE;
+ return (struct s5p_timer *)samsung_get_base_timer();
}
int timer_init(void)
{
- struct s5pc1xx_timer *const timer = s5pc1xx_get_base_timer();
+ struct s5p_timer *const timer = s5p_get_base_timer();
u32 val;
/*
* @ PWM Timer 4
* Timer Freq(HZ) =
- * PCLK / { (prescaler_value + 1) * (divider_value) }
+ * PWM_CLK / { (prescaler_value + 1) * (divider_value) }
*/
/* set prescaler : 16 */
@@ -71,7 +68,7 @@ int timer_init(void)
if (count_value == 0) {
/* reset initial value */
/* count_value = 2085937.5(HZ) (per 1 sec)*/
- count_value = get_pclk() / ((PRESCALER_1 + 1) *
+ count_value = get_pwm_clk() / ((PRESCALER_1 + 1) *
(MUX_DIV_2 + 1));
/* count_value / 100 = 20859.375(HZ) (per 10 msec) */
@@ -83,13 +80,13 @@ int timer_init(void)
lastdec = count_value;
val = (readl(&timer->tcon) & ~(0x07 << TCON_TIMER4_SHIFT)) |
- S5PC1XX_TCON4_AUTO_RELOAD;
+ TCON4_AUTO_RELOAD;
/* auto reload & manual update */
- writel(val | S5PC1XX_TCON4_UPDATE, &timer->tcon);
+ writel(val | TCON4_UPDATE, &timer->tcon);
/* start PWM timer 4 */
- writel(val | S5PC1XX_TCON4_START, &timer->tcon);
+ writel(val | TCON4_START, &timer->tcon);
timestamp = 0;
@@ -154,7 +151,7 @@ void __udelay(unsigned long usec)
void reset_timer_masked(void)
{
- struct s5pc1xx_timer *const timer = s5pc1xx_get_base_timer();
+ struct s5p_timer *const timer = s5p_get_base_timer();
/* reset time */
lastdec = readl(&timer->tcnto4);
@@ -163,7 +160,7 @@ void reset_timer_masked(void)
unsigned long get_timer_masked(void)
{
- struct s5pc1xx_timer *const timer = s5pc1xx_get_base_timer();
+ struct s5p_timer *const timer = s5p_get_base_timer();
unsigned long now = readl(&timer->tcnto4);
if (lastdec >= now)
diff --git a/arch/arm/cpu/armv7/s5pc1xx/Makefile b/arch/arm/cpu/armv7/s5pc1xx/Makefile
index 3785593d25..263945f4e7 100644
--- a/arch/arm/cpu/armv7/s5pc1xx/Makefile
+++ b/arch/arm/cpu/armv7/s5pc1xx/Makefile
@@ -32,9 +32,7 @@ SOBJS = cache.o
SOBJS += reset.o
COBJS += clock.o
-COBJS += cpu_info.o
COBJS += sromc.o
-COBJS += timer.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS))
diff --git a/arch/arm/cpu/armv7/s5pc1xx/clock.c b/arch/arm/cpu/armv7/s5pc1xx/clock.c
index 19619f92cd..98a27e551d 100644
--- a/arch/arm/cpu/armv7/s5pc1xx/clock.c
+++ b/arch/arm/cpu/armv7/s5pc1xx/clock.c
@@ -38,14 +38,16 @@
#define CONFIG_SYS_CLK_FREQ_C110 24000000
#endif
-unsigned long (*get_pclk)(void);
+unsigned long (*get_uart_clk)(int dev_index);
+unsigned long (*get_pwm_clk)(void);
unsigned long (*get_arm_clk)(void);
unsigned long (*get_pll_clk)(int);
/* s5pc110: return pll clock frequency */
static unsigned long s5pc100_get_pll_clk(int pllreg)
{
- struct s5pc100_clock *clk = (struct s5pc100_clock *)S5PC1XX_CLOCK_BASE;
+ struct s5pc100_clock *clk =
+ (struct s5pc100_clock *)samsung_get_base_clock();
unsigned long r, m, p, s, mask, fout;
unsigned int freq;
@@ -95,7 +97,8 @@ static unsigned long s5pc100_get_pll_clk(int pllreg)
/* s5pc100: return pll clock frequency */
static unsigned long s5pc110_get_pll_clk(int pllreg)
{
- struct s5pc110_clock *clk = (struct s5pc110_clock *)S5PC1XX_CLOCK_BASE;
+ struct s5pc110_clock *clk =
+ (struct s5pc110_clock *)samsung_get_base_clock();
unsigned long r, m, p, s, mask, fout;
unsigned int freq;
@@ -151,7 +154,8 @@ static unsigned long s5pc110_get_pll_clk(int pllreg)
/* s5pc110: return ARM clock frequency */
static unsigned long s5pc110_get_arm_clk(void)
{
- struct s5pc110_clock *clk = (struct s5pc110_clock *)S5PC1XX_CLOCK_BASE;
+ struct s5pc110_clock *clk =
+ (struct s5pc110_clock *)samsung_get_base_clock();
unsigned long div;
unsigned long dout_apll, armclk;
unsigned int apll_ratio;
@@ -170,7 +174,8 @@ static unsigned long s5pc110_get_arm_clk(void)
/* s5pc100: return ARM clock frequency */
static unsigned long s5pc100_get_arm_clk(void)
{
- struct s5pc100_clock *clk = (struct s5pc100_clock *)S5PC1XX_CLOCK_BASE;
+ struct s5pc100_clock *clk =
+ (struct s5pc100_clock *)samsung_get_base_clock();
unsigned long div;
unsigned long dout_apll, armclk;
unsigned int apll_ratio, arm_ratio;
@@ -191,7 +196,8 @@ static unsigned long s5pc100_get_arm_clk(void)
/* s5pc100: return HCLKD0 frequency */
static unsigned long get_hclk(void)
{
- struct s5pc100_clock *clk = (struct s5pc100_clock *)S5PC1XX_CLOCK_BASE;
+ struct s5pc100_clock *clk =
+ (struct s5pc100_clock *)samsung_get_base_clock();
unsigned long hclkd0;
uint div, d0_bus_ratio;
@@ -207,7 +213,8 @@ static unsigned long get_hclk(void)
/* s5pc100: return PCLKD1 frequency */
static unsigned long get_pclkd1(void)
{
- struct s5pc100_clock *clk = (struct s5pc100_clock *)S5PC1XX_CLOCK_BASE;
+ struct s5pc100_clock *clk =
+ (struct s5pc100_clock *)samsung_get_base_clock();
unsigned long d1_bus, pclkd1;
uint div, d1_bus_ratio, pclkd1_ratio;
@@ -227,7 +234,8 @@ static unsigned long get_pclkd1(void)
/* s5pc110: return HCLKs frequency */
static unsigned long get_hclk_sys(int dom)
{
- struct s5pc110_clock *clk = (struct s5pc110_clock *)S5PC1XX_CLOCK_BASE;
+ struct s5pc110_clock *clk =
+ (struct s5pc110_clock *)samsung_get_base_clock();
unsigned long hclk;
unsigned int div;
unsigned int offset;
@@ -255,7 +263,8 @@ static unsigned long get_hclk_sys(int dom)
/* s5pc110: return PCLKs frequency */
static unsigned long get_pclk_sys(int dom)
{
- struct s5pc110_clock *clk = (struct s5pc110_clock *)S5PC1XX_CLOCK_BASE;
+ struct s5pc110_clock *clk =
+ (struct s5pc110_clock *)samsung_get_base_clock();
unsigned long pclk;
unsigned int div;
unsigned int offset;
@@ -289,15 +298,33 @@ static unsigned long s5pc100_get_pclk(void)
return get_pclkd1();
}
-void s5pc1xx_clock_init(void)
+/* s5pc1xx: return uart clock frequency */
+static unsigned long s5pc1xx_get_uart_clk(int dev_index)
+{
+ if (cpu_is_s5pc110())
+ return s5pc110_get_pclk();
+ else
+ return s5pc100_get_pclk();
+}
+
+/* s5pc1xx: return pwm clock frequency */
+static unsigned long s5pc1xx_get_pwm_clk(void)
+{
+ if (cpu_is_s5pc110())
+ return s5pc110_get_pclk();
+ else
+ return s5pc100_get_pclk();
+}
+
+void s5p_clock_init(void)
{
if (cpu_is_s5pc110()) {
get_pll_clk = s5pc110_get_pll_clk;
get_arm_clk = s5pc110_get_arm_clk;
- get_pclk = s5pc110_get_pclk;
} else {
get_pll_clk = s5pc100_get_pll_clk;
get_arm_clk = s5pc100_get_arm_clk;
- get_pclk = s5pc100_get_pclk;
}
+ get_uart_clk = s5pc1xx_get_uart_clk;
+ get_pwm_clk = s5pc1xx_get_pwm_clk;
}
diff --git a/arch/arm/cpu/armv7/s5pc1xx/reset.S b/arch/arm/cpu/armv7/s5pc1xx/reset.S
index 7f6ff9c35f..70fa146cf3 100644
--- a/arch/arm/cpu/armv7/s5pc1xx/reset.S
+++ b/arch/arm/cpu/armv7/s5pc1xx/reset.S
@@ -28,7 +28,7 @@
.globl reset_cpu
reset_cpu:
- ldr r1, =S5PC1XX_PRO_ID
+ ldr r1, =S5PC100_PRO_ID
ldr r2, [r1]
ldr r4, =0x00010000
and r4, r2, r4
diff --git a/arch/arm/cpu/armv7/s5pc1xx/sromc.c b/arch/arm/cpu/armv7/s5pc1xx/sromc.c
index 380be81be5..044d12298d 100644
--- a/arch/arm/cpu/armv7/s5pc1xx/sromc.c
+++ b/arch/arm/cpu/armv7/s5pc1xx/sromc.c
@@ -35,12 +35,8 @@
void s5pc1xx_config_sromc(u32 srom_bank, u32 smc_bw_conf, u32 smc_bc_conf)
{
u32 tmp;
- struct s5pc1xx_smc *srom;
-
- if (cpu_is_s5pc100())
- srom = (struct s5pc1xx_smc *)S5PC100_SROMC_BASE;
- else
- srom = (struct s5pc1xx_smc *)S5PC110_SROMC_BASE;
+ struct s5pc1xx_smc *srom =
+ (struct s5pc1xx_smc *)samsung_get_base_sromc();
/* Configure SMC_BW register to handle proper SROMC bank */
tmp = srom->bw;
diff --git a/arch/arm/include/asm/arch-at91/at91_common.h b/arch/arm/include/asm/arch-at91/at91_common.h
index 01840eede4..0067190a20 100644
--- a/arch/arm/include/asm/arch-at91/at91_common.h
+++ b/arch/arm/include/asm/arch-at91/at91_common.h
@@ -27,6 +27,7 @@
void at91_can_hw_init(void);
void at91_macb_hw_init(void);
+void at91_mci_hw_init(void);
void at91_serial_hw_init(void);
void at91_serial0_hw_init(void);
void at91_serial1_hw_init(void);
diff --git a/arch/arm/include/asm/arch-at91/at91_dbu.h b/arch/arm/include/asm/arch-at91/at91_dbu.h
new file mode 100644
index 0000000000..3429293535
--- /dev/null
+++ b/arch/arm/include/asm/arch-at91/at91_dbu.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2010
+ * Reinhard Meyer, reinhard.meyer@emk-elektronik.de
+ *
+ * Debug Unit
+ * Based on AT91SAM9XE datasheet
+ *
+ * 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.
+ */
+
+#ifndef AT91_DBU_H
+#define AT91_DBU_H
+
+#ifndef __ASSEMBLY__
+
+typedef struct at91_dbu {
+ u32 cr; /* Control Register WO */
+ u32 mr; /* Mode Register RW */
+ u32 ier; /* Interrupt Enable Register WO */
+ u32 idr; /* Interrupt Disable Register WO */
+ u32 imr; /* Interrupt Mask Register RO */
+ u32 sr; /* Status Register RO */
+ u32 rhr; /* Receive Holding Register RO */
+ u32 thr; /* Transmit Holding Register WO */
+ u32 brgr; /* Baud Rate Generator Register RW */
+ u32 res1[7];/* 0x0024 - 0x003C Reserved */
+ u32 cidr; /* Chip ID Register RO */
+ u32 exid; /* Chip ID Extension Register RO */
+ u32 fnr; /* Force NTRST Register RW */
+} at91_dbu_t;
+
+#endif /* __ASSEMBLY__ */
+
+#define AT91_DBU_CID_ARCH_MASK 0x0ff00000
+#define AT91_DBU_CID_ARCH_9xx 0x01900000
+#define AT91_DBU_CID_ARCH_9XExx 0x02900000
+
+#endif
diff --git a/arch/arm/include/asm/arch-at91/at91_eefc.h b/arch/arm/include/asm/arch-at91/at91_eefc.h
new file mode 100644
index 0000000000..d45b3deca4
--- /dev/null
+++ b/arch/arm/include/asm/arch-at91/at91_eefc.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2010
+ * Reinhard Meyer, reinhard.meyer@emk-elektronik.de
+ *
+ * Enhanced Embedded Flash Controller
+ * Based on AT91SAM9XE datasheet
+ *
+ * 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.
+ */
+
+#ifndef AT91_EEFC_H
+#define AT91_EEFC_H
+
+#ifndef __ASSEMBLY__
+
+typedef struct at91_eefc {
+ u32 fmr; /* Flash Mode Register RW */
+ u32 fcr; /* Flash Command Register WO */
+ u32 fsr; /* Flash Status Register RO */
+ u32 frr; /* Flash Result Register RO */
+} at91_eefc_t;
+
+#endif /* __ASSEMBLY__ */
+
+#define AT91_EEFC_FMR_FWS_MASK 0x00000f00
+#define AT91_EEFC_FMR_FRDY_BIT 0x00000001
+
+#define AT91_EEFC_FCR_KEY 0x5a000000
+#define AT91_EEFC_FCR_FARG_MASK 0x00ffff00
+#define AT91_EEFC_FCR_FARG_SHIFT 8
+#define AT91_EEFC_FCR_FCMD_GETD 0x0
+#define AT91_EEFC_FCR_FCMD_WP 0x1
+#define AT91_EEFC_FCR_FCMD_WPL 0x2
+#define AT91_EEFC_FCR_FCMD_EWP 0x3
+#define AT91_EEFC_FCR_FCMD_EWPL 0x4
+#define AT91_EEFC_FCR_FCMD_EA 0x5
+#define AT91_EEFC_FCR_FCMD_SLB 0x8
+#define AT91_EEFC_FCR_FCMD_CLB 0x9
+#define AT91_EEFC_FCR_FCMD_GLB 0xA
+#define AT91_EEFC_FCR_FCMD_SGPB 0xB
+#define AT91_EEFC_FCR_FCMD_CGPB 0xC
+#define AT91_EEFC_FCR_FCMD_GGPB 0xD
+
+#define AT91_EEFC_FSR_FRDY 1
+#define AT91_EEFC_FSR_FCMDE 2
+#define AT91_EEFC_FSR_FLOCKE 4
+
+#endif
diff --git a/arch/arm/include/asm/arch-at91/at91_gpbr.h b/arch/arm/include/asm/arch-at91/at91_gpbr.h
new file mode 100644
index 0000000000..cf1d790dd9
--- /dev/null
+++ b/arch/arm/include/asm/arch-at91/at91_gpbr.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2010
+ * Reinhard Meyer, reinhard.meyer@emk-elektronik.de
+ *
+ * General Purpose Backup Registers
+ * Based on AT91SAM9XE datasheet
+ *
+ * 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.
+ */
+
+#ifndef AT91_GPBR_H
+#define AT91_GPBR_H
+
+/*
+ * The Atmel AT91SAM9 series has a small resource of 4 nonvolatile
+ * 32 Bit registers (buffered by the Vbu power).
+ *
+ * Please consider carefully before using this resource for tasks
+ * that do not really need nonvolatile registers. Maybe you can
+ * store information in EEPROM or FLASH instead.
+ *
+ * However, if you use a GPBR please document its use here and
+ * reference the define in your code!
+ *
+ * known typical uses of the GPBRs:
+ * GPBR[0]: offset for RTT timekeeping (u-boot, kernel)
+ * GPBR[1]: unused
+ * GPBR[2]: unused
+ * GPBR[3]: bootcount (u-boot)
+ */
+#define AT91_GPBR_INDEX_TIMEOFF 0
+#define AT91_GPBR_INDEX_BOOTCOUNT 3
+
+#ifndef __ASSEMBLY__
+
+typedef struct at91_gpbr {
+ u32 reg[4];
+} at91_gpbr_t;
+
+#endif /* __ASSEMBLY__ */
+
+#endif
diff --git a/arch/arm/include/asm/arch-at91/at91_pit.h b/arch/arm/include/asm/arch-at91/at91_pit.h
index 5615a0206c..61aca79418 100644
--- a/arch/arm/include/asm/arch-at91/at91_pit.h
+++ b/arch/arm/include/asm/arch-at91/at91_pit.h
@@ -25,7 +25,7 @@ typedef struct at91_pit {
#define AT91_PIT_MR_IEN 0x02000000
#define AT91_PIT_MR_EN 0x01000000
-#define AT91_PIT_MR_PIV_MASK (x & 0x000fffff)
+#define AT91_PIT_MR_PIV_MASK(x) (x & 0x000fffff)
#define AT91_PIT_MR_PIV(x) (x & AT91_PIT_MR_PIV_MASK)
#ifdef CONFIG_AT91_LEGACY
diff --git a/arch/arm/include/asm/arch-at91/at91_rtt.h b/arch/arm/include/asm/arch-at91/at91_rtt.h
new file mode 100644
index 0000000000..e0253ef821
--- /dev/null
+++ b/arch/arm/include/asm/arch-at91/at91_rtt.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2010
+ * Reinhard Meyer, reinhard.meyer@emk-elektronik.de
+ *
+ * Real-time Timer
+ * Based on AT91SAM9XE datasheet
+ *
+ * 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.
+ */
+
+#ifndef AT91_RTT_H
+#define AT91_RTT_H
+
+#ifndef __ASSEMBLY__
+
+typedef struct at91_rtt {
+ u32 mr; /* Mode Register RW 0x00008000 */
+ u32 ar; /* Alarm Register RW 0xFFFFFFFF */
+ u32 vr; /* Value Register RO 0x00000000 */
+ u32 sr; /* Status Register RO 0x00000000 */
+} at91_rtt_t;
+
+#endif /* __ASSEMBLY__ */
+
+#define AT91_RTT_MR_RTPRES 0x0000ffff
+#define AT91_RTT_MR_ALMIEN 0x00010000
+#define AT91_RTT_RTTINCIEN 0x00020000
+#define AT91_RTT_RTTRST 0x00040000
+
+#define AT91_RTT_SR_ALMS 0x00000001
+#define AT91_RTT_SR_RTTINC 0x00000002
+
+#endif
diff --git a/arch/arm/include/asm/arch-at91/at91sam9260.h b/arch/arm/include/asm/arch-at91/at91sam9260.h
index ec04318036..cb34a94a3b 100644
--- a/arch/arm/include/asm/arch-at91/at91sam9260.h
+++ b/arch/arm/include/asm/arch-at91/at91sam9260.h
@@ -59,7 +59,15 @@
#define AT91_RTT_BASE 0xfffffd20
#define AT91_PIT_BASE 0xfffffd30
#define AT91_WDT_BASE 0xfffffd40
-#define AT91_GPR_BASE 0xfffffd50
+/*
+ * The AT91SAM9XE has the GPBRs at a different address than
+ * the AT91SAM9260/9G20.
+ */
+#ifdef CONFIG_AT91SAM9XE
+# define AT91_GPR_BASE 0xfffffd60
+#else
+# define AT91_GPR_BASE 0xfffffd50
+#endif
#ifdef CONFIG_AT91_LEGACY
@@ -140,10 +148,12 @@
/*
* Cpu Name
*/
-#if defined(CONFIG_AT91SAM9260)
-#define CONFIG_SYS_AT91_CPU_NAME "AT91SAM9260"
+#if defined(CONFIG_AT91SAM9XE)
+# define CONFIG_SYS_AT91_CPU_NAME "AT91SAM9XE"
+#elif defined(CONFIG_AT91SAM9260)
+# define CONFIG_SYS_AT91_CPU_NAME "AT91SAM9260"
#elif defined(CONFIG_AT91SAM9G20)
-#define CONFIG_SYS_AT91_CPU_NAME "AT91SAM9G20"
+# define CONFIG_SYS_AT91_CPU_NAME "AT91SAM9G20"
#endif
#endif
diff --git a/arch/arm/include/asm/arch-at91/clk.h b/arch/arm/include/asm/arch-at91/clk.h
index f642dd9958..457e6c9b2b 100644
--- a/arch/arm/include/asm/arch-at91/clk.h
+++ b/arch/arm/include/asm/arch-at91/clk.h
@@ -59,5 +59,10 @@ static inline unsigned long get_twi_clk_rate(unsigned int dev_id)
return get_mck_clk_rate();
}
+static inline unsigned long get_mci_clk_rate(void)
+{
+ return get_mck_clk_rate();
+}
+
int at91_clock_init(unsigned long main_clock);
#endif /* __ASM_ARM_ARCH_CLK_H__ */
diff --git a/arch/arm/include/asm/arch-at91/hardware.h b/arch/arm/include/asm/arch-at91/hardware.h
index 4ddb3155d7..9f732a738e 100644
--- a/arch/arm/include/asm/arch-at91/hardware.h
+++ b/arch/arm/include/asm/arch-at91/hardware.h
@@ -20,6 +20,7 @@
#include <asm/arch-at91/at91rm9200.h>
#elif defined(CONFIG_AT91SAM9260) || defined(CONFIG_AT91SAM9G20)
#include <asm/arch/at91sam9260.h>
+#define AT91_BASE_MCI AT91SAM9260_BASE_MCI
#define AT91_BASE_SPI AT91SAM9260_BASE_SPI0
#define AT91_ID_UHP AT91SAM9260_ID_UHP
#define AT91_PMC_UHP AT91SAM926x_PMC_UHP
diff --git a/arch/arm/include/asm/arch-mb86r0x/asm-offsets.h b/arch/arm/include/asm/arch-mb86r0x/asm-offsets.h
new file mode 100644
index 0000000000..0bc5279137
--- /dev/null
+++ b/arch/arm/include/asm/arch-mb86r0x/asm-offsets.h
@@ -0,0 +1,74 @@
+/*
+ * (C) Copyright 2010
+ * Matthias Weisser <weisserm@arcor.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
+ */
+
+#ifndef ASM_OFFSETS_H
+#define ASM_OFFSETS_H
+
+/*
+ * Offset definitions for DDR controller
+ */
+#define DDR2_DRIC 0x00
+#define DDR2_DRIC1 0x02
+#define DDR2_DRIC2 0x04
+#define DDR2_DRCA 0x06
+#define DDR2_DRCM 0x08
+#define DDR2_DRCST1 0x0a
+#define DDR2_DRCST2 0x0c
+#define DDR2_DRCR 0x0e
+#define DDR2_DRCF 0x20
+#define DDR2_DRASR 0x30
+#define DDR2_DRIMS 0x50
+#define DDR2_DROS 0x60
+#define DDR2_DRIBSODT1 0x64
+#define DDR2_DROABA 0x70
+#define DDR2_DROBS 0x84
+
+/*
+ * Offset definitions Chip Control Module
+ */
+#define CCNT_CDCRC 0xec
+
+/*
+ * Offset definitions clock reset generator
+ */
+#define CRG_CRPR 0x00
+#define CRG_CRHA 0x18
+#define CRG_CRPA 0x1c
+#define CRG_CRPB 0x20
+#define CRG_CRHB 0x24
+#define CRG_CRAM 0x28
+
+/*
+ * Offset definitions External bus interface
+ */
+#define MEMC_MCFMODE0 0x00
+#define MEMC_MCFMODE2 0x08
+#define MEMC_MCFMODE4 0x10
+#define MEMC_MCFTIM0 0x20
+#define MEMC_MCFTIM2 0x28
+#define MEMC_MCFTIM4 0x30
+#define MEMC_MCFAREA0 0x40
+#define MEMC_MCFAREA2 0x48
+#define MEMC_MCFAREA4 0x50
+
+#endif /* ASM_OFFSETS_H */
diff --git a/arch/arm/include/asm/arch-mb86r0x/hardware.h b/arch/arm/include/asm/arch-mb86r0x/hardware.h
new file mode 100644
index 0000000000..d1e57c0349
--- /dev/null
+++ b/arch/arm/include/asm/arch-mb86r0x/hardware.h
@@ -0,0 +1,31 @@
+/*
+ * (C) Copyright 2007
+ *
+ * Author : Carsten Schneider, mycable GmbH
+ * <cs@mycable.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
+ */
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <asm/sizes.h>
+#include <asm/arch/mb86r0x.h>
+
+#endif
diff --git a/arch/arm/include/asm/arch-mb86r0x/mb86r0x.h b/arch/arm/include/asm/arch-mb86r0x/mb86r0x.h
new file mode 100644
index 0000000000..36a28b7af3
--- /dev/null
+++ b/arch/arm/include/asm/arch-mb86r0x/mb86r0x.h
@@ -0,0 +1,573 @@
+/*
+ * (C) Copyright 2007
+ *
+ * mb86r0x definitions
+ *
+ * Author : Carsten Schneider, mycable GmbH
+ * <cs@mycable.de>
+ *
+ * (C) Copyright 2010
+ * Matthias Weisser <weisserm@arcor.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
+ */
+
+#ifndef MB86R0X_H
+#define MB86R0X_H
+
+#ifndef __ASSEMBLY__
+
+/* GPIO registers */
+struct mb86r0x_gpio {
+ uint32_t gpdr0;
+ uint32_t gpdr1;
+ uint32_t gpdr2;
+ uint32_t res;
+ uint32_t gpddr0;
+ uint32_t gpddr1;
+ uint32_t gpddr2;
+};
+
+/* PWM registers */
+struct mb86r0x_pwm {
+ uint32_t bcr;
+ uint32_t tpr;
+ uint32_t pr;
+ uint32_t dr;
+ uint32_t cr;
+ uint32_t sr;
+ uint32_t ccr;
+ uint32_t ir;
+};
+
+/* The mb86r0x chip control (CCNT) register set. */
+struct mb86r0x_ccnt {
+ uint32_t ccid;
+ uint32_t csrst;
+ uint32_t pad0[2];
+ uint32_t cist;
+ uint32_t cistm;
+ uint32_t cgpio_ist;
+ uint32_t cgpio_istm;
+ uint32_t cgpio_ip;
+ uint32_t cgpio_im;
+ uint32_t caxi_bw;
+ uint32_t caxi_ps;
+ uint32_t cmux_md;
+ uint32_t cex_pin_st;
+ uint32_t cmlb;
+ uint32_t pad1[1];
+ uint32_t cusb;
+ uint32_t pad2[41];
+ uint32_t cbsc;
+ uint32_t cdcrc;
+ uint32_t cmsr0;
+ uint32_t cmsr1;
+ uint32_t pad3[2];
+};
+
+/* The mb86r0x clock reset generator */
+struct mb86r0x_crg {
+ uint32_t crpr;
+ uint32_t pad0;
+ uint32_t crwr;
+ uint32_t crsr;
+ uint32_t crda;
+ uint32_t crdb;
+ uint32_t crha;
+ uint32_t crpa;
+ uint32_t crpb;
+ uint32_t crhb;
+ uint32_t cram;
+};
+
+/* The mb86r0x timer */
+struct mb86r0x_timer {
+ uint32_t load;
+ uint32_t value;
+ uint32_t control;
+ uint32_t intclr;
+ uint32_t ris;
+ uint32_t mis;
+ uint32_t bgload;
+};
+
+/* mb86r0x gdc display controller */
+struct mb86r0x_gdc_dsp {
+ /* Display settings */
+ uint32_t dcm0;
+ uint16_t pad00;
+ uint16_t htp;
+ uint16_t hdp;
+ uint16_t hdb;
+ uint16_t hsp;
+ uint8_t hsw;
+ uint8_t vsw;
+ uint16_t pad01;
+ uint16_t vtr;
+ uint16_t vsp;
+ uint16_t vdp;
+ uint16_t wx;
+ uint16_t wy;
+ uint16_t ww;
+ uint16_t wh;
+
+ /* Layer 0 */
+ uint32_t l0m;
+ uint32_t l0oa;
+ uint32_t l0da;
+ uint16_t l0dx;
+ uint16_t l0dy;
+
+ /* Layer 1 */
+ uint32_t l1m;
+ uint32_t cbda0;
+ uint32_t cbda1;
+ uint32_t pad02;
+
+ /* Layer 2 */
+ uint32_t l2m;
+ uint32_t l2oa0;
+ uint32_t l2da0;
+ uint32_t l2oa1;
+ uint32_t l2da1;
+ uint16_t l2dx;
+ uint16_t l2dy;
+
+ /* Layer 3 */
+ uint32_t l3m;
+ uint32_t l3oa0;
+ uint32_t l3da0;
+ uint32_t l3oa1;
+ uint32_t l3da1;
+ uint16_t l3dx;
+ uint16_t l3dy;
+
+ /* Layer 4 */
+ uint32_t l4m;
+ uint32_t l4oa0;
+ uint32_t l4da0;
+ uint32_t l4oa1;
+ uint32_t l4da1;
+ uint16_t l4dx;
+ uint16_t l4dy;
+
+ /* Layer 5 */
+ uint32_t l5m;
+ uint32_t l5oa0;
+ uint32_t l5da0;
+ uint32_t l5oa1;
+ uint32_t l5da1;
+ uint16_t l5dx;
+ uint16_t l5dy;
+
+ /* Cursor */
+ uint16_t cutc;
+ uint8_t cpm;
+ uint8_t csize;
+ uint32_t cuoa0;
+ uint16_t cux0;
+ uint16_t cuy0;
+ uint32_t cuoa1;
+ uint16_t cux1;
+ uint16_t cuy1;
+
+ /* Layer blending */
+ uint32_t l0bld;
+ uint32_t pad03;
+ uint32_t l0tc;
+ uint16_t l3tc;
+ uint16_t l2tc;
+ uint32_t pad04[15];
+
+ /* Display settings */
+ uint32_t dcm1;
+ uint32_t dcm2;
+ uint32_t dcm3;
+ uint32_t pad05;
+
+ /* Layer 0 extended */
+ uint32_t l0em;
+ uint16_t l0wx;
+ uint16_t l0wy;
+ uint16_t l0ww;
+ uint16_t l0wh;
+ uint32_t pad06;
+
+ /* Layer 1 extended */
+ uint32_t l1em;
+ uint16_t l1wx;
+ uint16_t l1wy;
+ uint16_t l1ww;
+ uint16_t l1wh;
+ uint32_t pad07;
+
+ /* Layer 2 extended */
+ uint32_t l2em;
+ uint16_t l2wx;
+ uint16_t l2wy;
+ uint16_t l2ww;
+ uint16_t l2wh;
+ uint32_t pad08;
+
+ /* Layer 3 extended */
+ uint32_t l3em;
+ uint16_t l3wx;
+ uint16_t l3wy;
+ uint16_t l3ww;
+ uint16_t l3wh;
+ uint32_t pad09;
+
+ /* Layer 4 extended */
+ uint32_t l4em;
+ uint16_t l4wx;
+ uint16_t l4wy;
+ uint16_t l4ww;
+ uint16_t l4wh;
+ uint32_t pad10;
+
+ /* Layer 5 extended */
+ uint32_t l5em;
+ uint16_t l5wx;
+ uint16_t l5wy;
+ uint16_t l5ww;
+ uint16_t l5wh;
+ uint32_t pad11;
+
+ /* Multi screen control */
+ uint32_t msc;
+ uint32_t pad12[3];
+ uint32_t dls;
+ uint32_t dbgc;
+
+ /* Layer blending */
+ uint32_t l1bld;
+ uint32_t l2bld;
+ uint32_t l3bld;
+ uint32_t l4bld;
+ uint32_t l5bld;
+ uint32_t pad13;
+
+ /* Extended transparency control */
+ uint32_t l0etc;
+ uint32_t l1etc;
+ uint32_t l2etc;
+ uint32_t l3etc;
+ uint32_t l4etc;
+ uint32_t l5etc;
+ uint32_t pad14[10];
+
+ /* YUV coefficients */
+ uint32_t l1ycr0;
+ uint32_t l1ycr1;
+ uint32_t l1ycg0;
+ uint32_t l1ycg1;
+ uint32_t l1ycb0;
+ uint32_t l1ycb1;
+ uint32_t pad15[130];
+
+ /* Layer palletes */
+ uint32_t l0pal[256];
+ uint32_t l1pal[256];
+ uint32_t pad16[256];
+ uint32_t l2pal[256];
+ uint32_t l3pal[256];
+ uint32_t pad17[256];
+
+ /* PWM settings */
+ uint32_t vpwmm;
+ uint16_t vpwms;
+ uint16_t vpwme;
+ uint32_t vpwmc;
+ uint32_t pad18[253];
+};
+
+/* mb86r0x gdc capture controller */
+struct mb86r0x_gdc_cap {
+ uint32_t vcm;
+ uint32_t csc;
+ uint32_t vcs;
+ uint32_t pad01;
+
+ uint32_t cbm;
+ uint32_t cboa;
+ uint32_t cbla;
+ uint16_t cihstr;
+ uint16_t civstr;
+ uint16_t cihend;
+ uint16_t civend;
+ uint32_t pad02;
+
+ uint32_t chp;
+ uint32_t cvp;
+ uint32_t pad03[4];
+
+ uint32_t clpf;
+ uint32_t pad04;
+ uint32_t cmss;
+ uint32_t cmds;
+ uint32_t pad05[12];
+
+ uint32_t rgbhc;
+ uint32_t rgbhen;
+ uint32_t rgbven;
+ uint32_t pad06;
+ uint32_t rgbs;
+ uint32_t pad07[11];
+
+ uint32_t rgbcmy;
+ uint32_t rgbcmcb;
+ uint32_t rgbcmcr;
+ uint32_t rgbcmb;
+ uint32_t pad08[12 + 1984];
+};
+
+/* mb86r0x gdc draw */
+struct mb86r0x_gdc_draw {
+ uint32_t ys;
+ uint32_t xs;
+ uint32_t dxdy;
+ uint32_t xus;
+ uint32_t dxudy;
+ uint32_t xls;
+ uint32_t dxldy;
+ uint32_t usn;
+ uint32_t lsn;
+ uint32_t pad01[7];
+ uint32_t rs;
+ uint32_t drdx;
+ uint32_t drdy;
+ uint32_t gs;
+ uint32_t dgdx;
+ uint32_t dgdy;
+ uint32_t bs;
+ uint32_t dbdx;
+ uint32_t dbdy;
+ uint32_t pad02[7];
+ uint32_t zs;
+ uint32_t dzdx;
+ uint32_t dzdy;
+ uint32_t pad03[13];
+ uint32_t ss;
+ uint32_t dsdx;
+ uint32_t dsdy;
+ uint32_t ts;
+ uint32_t dtdx;
+ uint32_t dtdy;
+ uint32_t qs;
+ uint32_t dqdx;
+ uint32_t dqdy;
+ uint32_t pad04[23];
+ uint32_t lpn;
+ uint32_t lxs;
+ uint32_t lxde;
+ uint32_t lys;
+ uint32_t lyde;
+ uint32_t lzs;
+ uint32_t lzde;
+ uint32_t pad05[13];
+ uint32_t pxdc;
+ uint32_t pydc;
+ uint32_t pzdc;
+ uint32_t pad06[25];
+ uint32_t rxs;
+ uint32_t rys;
+ uint32_t rsizex;
+ uint32_t rsizey;
+ uint32_t pad07[12];
+ uint32_t saddr;
+ uint32_t sstride;
+ uint32_t srx;
+ uint32_t sry;
+ uint32_t daddr;
+ uint32_t dstride;
+ uint32_t drx;
+ uint32_t dry;
+ uint32_t brsizex;
+ uint32_t brsizey;
+ uint32_t tcolor;
+ uint32_t pad08[93];
+ uint32_t blpo;
+ uint32_t pad09[7];
+ uint32_t ctr;
+ uint32_t ifsr;
+ uint32_t ifcnt;
+ uint32_t sst;
+ uint32_t ds;
+ uint32_t pst;
+ uint32_t est;
+ uint32_t pad10;
+ uint32_t mdr0;
+ uint32_t mdr1;
+ uint32_t mdr2;
+ uint32_t mdr3;
+ uint32_t mdr4;
+ uint32_t pad14[2];
+ uint32_t mdr7;
+ uint32_t fbr;
+ uint32_t xres;
+ uint32_t zbr;
+ uint32_t tbr;
+ uint32_t pfbr;
+ uint32_t cxmin;
+ uint32_t cxmax;
+ uint32_t cymin;
+ uint32_t cymax;
+ uint32_t txs;
+ uint32_t tis;
+ uint32_t toa;
+ uint32_t sho;
+ uint32_t abr;
+ uint32_t pad15[2];
+ uint32_t fc;
+ uint32_t bc;
+ uint32_t alf;
+ uint32_t blp;
+ uint32_t pad16;
+ uint32_t tbc;
+ uint32_t pad11[42];
+ uint32_t lx0dc;
+ uint32_t ly0dc;
+ uint32_t lx1dc;
+ uint32_t ly1dc;
+ uint32_t pad12[12];
+ uint32_t x0dc;
+ uint32_t y0dc;
+ uint32_t x1dc;
+ uint32_t y1dc;
+ uint32_t x2dc;
+ uint32_t y2dc;
+ uint32_t pad13[666];
+};
+
+/* mb86r0x gdc geometry engine */
+struct mb86r0x_gdc_geom {
+ uint32_t gctr;
+ uint32_t pad00[15];
+ uint32_t gmdr0;
+ uint32_t gmdr1;
+ uint32_t gmdr2;
+ uint32_t pad01[237];
+ uint32_t dfifog;
+ uint32_t pad02[767];
+};
+
+/* mb86r0x gdc */
+struct mb86r0x_gdc {
+ uint32_t pad00[2];
+ uint32_t lts;
+ uint32_t pad01;
+ uint32_t lsta;
+ uint32_t pad02[3];
+ uint32_t ist;
+ uint32_t imask;
+ uint32_t pad03[6];
+ uint32_t lsa;
+ uint32_t lco;
+ uint32_t lreq;
+
+ uint32_t pad04[16*1024 - 19];
+ struct mb86r0x_gdc_dsp dsp0;
+ struct mb86r0x_gdc_dsp dsp1;
+ uint32_t pad05[4*1024 - 2];
+ uint32_t vccc;
+ uint32_t vcsr;
+ struct mb86r0x_gdc_cap cap0;
+ struct mb86r0x_gdc_cap cap1;
+ uint32_t pad06[4*1024];
+ uint32_t texture_base[16*1024];
+ struct mb86r0x_gdc_draw draw;
+ uint32_t pad07[7*1024];
+ struct mb86r0x_gdc_geom geom;
+ uint32_t pad08[7*1024];
+};
+
+#endif /* __ASSEMBLY__ */
+
+/*
+ * Physical Address Defines
+ */
+#define MB86R0x_DDR2_BASE 0xf3000000
+#define MB86R0x_GDC_BASE 0xf1fc0000
+#define MB86R0x_CCNT_BASE 0xfff42000
+#define MB86R0x_CAN0_BASE 0xfff54000
+#define MB86R0x_CAN1_BASE 0xfff55000
+#define MB86R0x_I2C0_BASE 0xfff56000
+#define MB86R0x_I2C1_BASE 0xfff57000
+#define MB86R0x_EHCI_BASE 0xfff80000
+#define MB86R0x_OHCI_BASE 0xfff81000
+#define MB86R0x_IRC1_BASE 0xfffb0000
+#define MB86R0x_MEMC_BASE 0xfffc0000
+#define MB86R0x_TIMER_BASE 0xfffe0000
+#define MB86R0x_UART0_BASE 0xfffe1000
+#define MB86R0x_UART1_BASE 0xfffe2000
+#define MB86R0x_IRCE_BASE 0xfffe4000
+#define MB86R0x_CRG_BASE 0xfffe7000
+#define MB86R0x_IRC0_BASE 0xfffe8000
+#define MB86R0x_GPIO_BASE 0xfffe9000
+#define MB86R0x_PWM0_BASE 0xfff41000
+#define MB86R0x_PWM1_BASE 0xfff41100
+
+#define MB86R0x_CRSR_SWRSTREQ (1 << 1)
+
+/*
+ * Timer register bits
+ */
+#define MB86R0x_TIMER_ENABLE (1 << 7)
+#define MB86R0x_TIMER_MODE_MSK (1 << 6)
+#define MB86R0x_TIMER_MODE_FR (0 << 6)
+#define MB86R0x_TIMER_MODE_PD (1 << 6)
+
+#define MB86R0x_TIMER_INT_EN (1 << 5)
+#define MB86R0x_TIMER_PRS_MSK (3 << 2)
+#define MB86R0x_TIMER_PRS_4S (1 << 2)
+#define MB86R0x_TIMER_PRS_8S (1 << 3)
+#define MB86R0x_TIMER_SIZE_32 (1 << 1)
+#define MB86R0x_TIMER_ONE_SHT (1 << 0)
+
+/*
+ * Clock reset generator bits
+ */
+#define MB86R0x_CRG_CRPR_PLLRDY (1 << 8)
+#define MB86R0x_CRG_CRPR_PLLMODE (0x1f << 0)
+#define MB86R0x_CRG_CRPR_PLLMODE_X49 (0 << 0)
+#define MB86R0x_CRG_CRPR_PLLMODE_X46 (1 << 0)
+#define MB86R0x_CRG_CRPR_PLLMODE_X37 (2 << 0)
+#define MB86R0x_CRG_CRPR_PLLMODE_X20 (3 << 0)
+#define MB86R0x_CRG_CRPR_PLLMODE_X47 (4 << 0)
+#define MB86R0x_CRG_CRPR_PLLMODE_X44 (5 << 0)
+#define MB86R0x_CRG_CRPR_PLLMODE_X36 (6 << 0)
+#define MB86R0x_CRG_CRPR_PLLMODE_X19 (7 << 0)
+#define MB86R0x_CRG_CRPR_PLLMODE_X39 (8 << 0)
+#define MB86R0x_CRG_CRPR_PLLMODE_X38 (9 << 0)
+#define MB86R0x_CRG_CRPR_PLLMODE_X30 (10 << 0)
+#define MB86R0x_CRG_CRPR_PLLMODE_X15 (11 << 0)
+/*
+ * DDR2 controller bits
+ */
+#define MB86R0x_DDR2_DRCI_DRINI (1 << 15)
+#define MB86R0x_DDR2_DRCI_CKEN (1 << 14)
+#define MB86R0x_DDR2_DRCI_DRCMD (1 << 0)
+#define MB86R0x_DDR2_DRCI_CMD (MB86R0x_DDR2_DRCI_DRINI | \
+ MB86R0x_DDR2_DRCI_CKEN | \
+ MB86R0x_DDR2_DRCI_DRCMD)
+#define MB86R0x_DDR2_DRCI_INIT (MB86R0x_DDR2_DRCI_DRINI | \
+ MB86R0x_DDR2_DRCI_CKEN)
+#define MB86R0x_DDR2_DRCI_NORMAL MB86R0x_DDR2_DRCI_CKEN
+#endif /* MB86R0X_H */
diff --git a/arch/arm/include/asm/arch-omap3/clocks.h b/arch/arm/include/asm/arch-omap3/clocks.h
index 71a0cb6ae4..40f80baf61 100644
--- a/arch/arm/include/asm/arch-omap3/clocks.h
+++ b/arch/arm/include/asm/arch-omap3/clocks.h
@@ -51,12 +51,29 @@ typedef struct {
unsigned int m2;
} dpll_param;
+struct dpll_per_36x_param {
+ unsigned int sys_clk;
+ unsigned int m;
+ unsigned int n;
+ unsigned int m2;
+ unsigned int m3;
+ unsigned int m4;
+ unsigned int m5;
+ unsigned int m6;
+ unsigned int m2div;
+};
+
/* Following functions are exported from lowlevel_init.S */
extern dpll_param *get_mpu_dpll_param(void);
extern dpll_param *get_iva_dpll_param(void);
extern dpll_param *get_core_dpll_param(void);
extern dpll_param *get_per_dpll_param(void);
+extern dpll_param *get_36x_mpu_dpll_param(void);
+extern dpll_param *get_36x_iva_dpll_param(void);
+extern dpll_param *get_36x_core_dpll_param(void);
+extern dpll_param *get_36x_per_dpll_param(void);
+
extern void *_end_vect, *_start;
#endif
diff --git a/arch/arm/include/asm/arch-omap3/clocks_omap3.h b/arch/arm/include/asm/arch-omap3/clocks_omap3.h
index 661407b564..30ef690fa2 100644
--- a/arch/arm/include/asm/arch-omap3/clocks_omap3.h
+++ b/arch/arm/include/asm/arch-omap3/clocks_omap3.h
@@ -282,4 +282,31 @@
#define PER_FSEL_38P4 0x07
#define PER_M2_38P4 0x09
+/* 36XX PER DPLL */
+
+#define PER_36XX_M_12 0x1B0
+#define PER_36XX_N_12 0x05
+#define PER_36XX_FSEL_12 0x07
+#define PER_36XX_M2_12 0x09
+
+#define PER_36XX_M_13 0x360
+#define PER_36XX_N_13 0x0C
+#define PER_36XX_FSEL_13 0x03
+#define PER_36XX_M2_13 0x09
+
+#define PER_36XX_M_19P2 0x1C2
+#define PER_36XX_N_19P2 0x09
+#define PER_36XX_FSEL_19P2 0x07
+#define PER_36XX_M2_19P2 0x09
+
+#define PER_36XX_M_26 0x1B0
+#define PER_36XX_N_26 0x0C
+#define PER_36XX_FSEL_26 0x07
+#define PER_36XX_M2_26 0x09
+
+#define PER_36XX_M_38P4 0x1C2
+#define PER_36XX_N_38P4 0x13
+#define PER_36XX_FSEL_38P4 0x07
+#define PER_36XX_M2_38P4 0x09
+
#endif /* endif _CLOCKS_OMAP3_H_ */
diff --git a/arch/arm/include/asm/arch-omap3/cpu.h b/arch/arm/include/asm/arch-omap3/cpu.h
index 390b007945..962d6d40aa 100644
--- a/arch/arm/include/asm/arch-omap3/cpu.h
+++ b/arch/arm/include/asm/arch-omap3/cpu.h
@@ -60,19 +60,14 @@ struct ctrl {
#endif /* __ASSEMBLY__ */
#endif /* __KERNEL_STRICT_NAMES */
-/* cpu type */
-#define OMAP3503 0x5c00
-#define OMAP3515 0x1c00
-#define OMAP3525 0x4c00
-#define OMAP3530 0x0c00
-
#ifndef __KERNEL_STRICT_NAMES
#ifndef __ASSEMBLY__
struct ctrl_id {
u8 res1[0x4];
u32 idcode; /* 0x04 */
u32 prod_id; /* 0x08 */
- u8 res2[0x0C];
+ u32 sku_id; /* 0x0c */
+ u8 res2[0x08];
u32 die_id_0; /* 0x18 */
u32 die_id_1; /* 0x1C */
u32 die_id_2; /* 0x20 */
@@ -89,6 +84,11 @@ struct ctrl_id {
#define HS_DEVICE 0x2
#define GP_DEVICE 0x3
+/* device speed */
+#define SKUID_CLK_MASK 0xf
+#define SKUID_CLK_600MHZ 0x0
+#define SKUID_CLK_720MHZ 0x8
+
#define GPMC_BASE (OMAP34XX_GPMC_BASE)
#define GPMC_CONFIG_CS0 0x60
#define GPMC_CONFIG_CS0_BASE (GPMC_BASE + GPMC_CONFIG_CS0)
@@ -419,6 +419,7 @@ struct prm {
};
#else /* __ASSEMBLY__ */
#define PRM_RSTCTRL 0x48307250
+#define PRM_RSTCTRL_RESET 0x04
#endif /* __ASSEMBLY__ */
#endif /* __KERNEL_STRICT_NAMES */
diff --git a/arch/arm/include/asm/arch-omap3/omap3.h b/arch/arm/include/asm/arch-omap3/omap3.h
index 12815f694f..3957c796f2 100644
--- a/arch/arm/include/asm/arch-omap3/omap3.h
+++ b/arch/arm/include/asm/arch-omap3/omap3.h
@@ -176,11 +176,41 @@ struct gpio {
#define CPU_3XX_ES21 2
#define CPU_3XX_ES30 3
#define CPU_3XX_ES31 4
-#define CPU_3XX_MAX_REV (CPU_3XX_ES31 + 1)
+#define CPU_3XX_ES312 7
+#define CPU_3XX_MAX_REV 8
#define CPU_3XX_ID_SHIFT 28
#define WIDTH_8BIT 0x0000
#define WIDTH_16BIT 0x1000 /* bit pos for 16 bit in gpmc */
+/*
+ * Hawkeye values
+ */
+#define HAWKEYE_OMAP34XX 0xb7ae
+#define HAWKEYE_AM35XX 0xb868
+#define HAWKEYE_OMAP36XX 0xb891
+
+#define HAWKEYE_SHIFT 12
+
+/*
+ * Define CPU families
+ */
+#define CPU_OMAP34XX 0x3400 /* OMAP34xx/OMAP35 devices */
+#define CPU_AM35XX 0x3500 /* AM35xx devices */
+#define CPU_OMAP36XX 0x3600 /* OMAP36xx devices */
+
+/*
+ * Control status register values corresponding to cpu variants
+ */
+#define OMAP3503 0x5c00
+#define OMAP3515 0x1c00
+#define OMAP3525 0x4c00
+#define OMAP3530 0x0c00
+
+#define AM3505 0x5c00
+#define AM3517 0x1c00
+
+#define OMAP3730 0x0c00
+
#endif
diff --git a/arch/arm/include/asm/arch-omap3/sys_proto.h b/arch/arm/include/asm/arch-omap3/sys_proto.h
index db7b42aed1..4a28ba1c4a 100644
--- a/arch/arm/include/asm/arch-omap3/sys_proto.h
+++ b/arch/arm/include/asm/arch-omap3/sys_proto.h
@@ -41,7 +41,9 @@ void enable_gpmc_cs_config(const u32 *gpmc_config, struct gpmc_cs *cs, u32 base,
void watchdog_init(void);
void set_muxconf_regs(void);
+u32 get_cpu_family(void);
u32 get_cpu_rev(void);
+u32 get_sku_id(void);
u32 get_mem_type(void);
u32 get_sysboot_value(void);
u32 is_gpmc_muxed(void);
diff --git a/arch/arm/include/asm/arch-omap4/omap4.h b/arch/arm/include/asm/arch-omap4/omap4.h
index 79ff22cf31..d0c808d121 100644
--- a/arch/arm/include/asm/arch-omap4/omap4.h
+++ b/arch/arm/include/asm/arch-omap4/omap4.h
@@ -88,6 +88,7 @@
#define PRM_DEVICE_BASE (PRM_BASE + 0x1B00)
#define PRM_RSTCTRL PRM_DEVICE_BASE
+#define PRM_RSTCTRL_RESET 0x01
#ifndef __ASSEMBLY__
diff --git a/arch/arm/include/asm/arch-omap4/sys_proto.h b/arch/arm/include/asm/arch-omap4/sys_proto.h
index ad0c640dfd..4813e9e21d 100644
--- a/arch/arm/include/asm/arch-omap4/sys_proto.h
+++ b/arch/arm/include/asm/arch-omap4/sys_proto.h
@@ -33,6 +33,9 @@ void watchdog_init(void);
u32 get_device_type(void);
void invalidate_dcache(u32);
void set_muxconf_regs(void);
+void sr32(void *, u32, u32, u32);
+u32 wait_on_value(u32, u32, void *, u32);
+void sdelay(unsigned long);
extern const struct omap_sysinfo sysinfo;
diff --git a/arch/arm/include/asm/arch-orion5x/cpu.h b/arch/arm/include/asm/arch-orion5x/cpu.h
index 80717f8a57..6ce02a9212 100644
--- a/arch/arm/include/asm/arch-orion5x/cpu.h
+++ b/arch/arm/include/asm/arch-orion5x/cpu.h
@@ -76,7 +76,7 @@ enum orion5x_cpu_attrib {
/*
* Device Address MAP BAR values
-/*
+ *
* All addresses and sizes not defined by board code
* will be given default values here.
*/
diff --git a/arch/arm/include/asm/arch-s5pc1xx/clk.h b/arch/arm/include/asm/arch-s5pc1xx/clk.h
index 3e59abe78c..3488eb7c15 100644
--- a/arch/arm/include/asm/arch-s5pc1xx/clk.h
+++ b/arch/arm/include/asm/arch-s5pc1xx/clk.h
@@ -29,10 +29,11 @@
#define HPLL 3
#define VPLL 4
-void s5pc1xx_clock_init(void);
+void s5p_clock_init(void);
extern unsigned long (*get_pll_clk)(int pllreg);
extern unsigned long (*get_arm_clk)(void);
-extern unsigned long (*get_pclk)(void);
+extern unsigned long (*get_pwm_clk)(void);
+extern unsigned long (*get_uart_clk)(int dev_index);
#endif
diff --git a/arch/arm/include/asm/arch-s5pc1xx/cpu.h b/arch/arm/include/asm/arch-s5pc1xx/cpu.h
index b3af8cc782..e74959fe22 100644
--- a/arch/arm/include/asm/arch-s5pc1xx/cpu.h
+++ b/arch/arm/include/asm/arch-s5pc1xx/cpu.h
@@ -25,9 +25,9 @@
#define S5PC1XX_ADDR_BASE 0xE0000000
-#define S5PC1XX_CLOCK_BASE 0xE0100000
-
/* S5PC100 */
+#define S5PC100_PRO_ID 0xE0000000
+#define S5PC100_CLOCK_BASE 0xE0100000
#define S5PC100_GPIO_BASE 0xE0300000
#define S5PC100_VIC0_BASE 0xE4000000
#define S5PC100_VIC1_BASE 0xE4100000
@@ -41,6 +41,8 @@
#define S5PC100_MMC_BASE 0xED800000
/* S5PC110 */
+#define S5PC110_PRO_ID 0xE0000000
+#define S5PC110_CLOCK_BASE 0xE0100000
#define S5PC110_GPIO_BASE 0xE0200000
#define S5PC110_PWMTIMER_BASE 0xE2500000
#define S5PC110_WATCHDOG_BASE 0xE2700000
@@ -54,21 +56,44 @@
#define S5PC110_VIC2_BASE 0xF2200000
#define S5PC110_VIC3_BASE 0xF2300000
-/* Chip ID */
-#define S5PC1XX_PRO_ID 0xE0000000
-
#ifndef __ASSEMBLY__
+#include <asm/io.h>
/* CPU detection macros */
-extern unsigned int s5pc1xx_cpu_id;
+extern unsigned int s5p_cpu_id;
+
+static inline void s5p_set_cpu_id(void)
+{
+ s5p_cpu_id = readl(S5PC100_PRO_ID);
+ s5p_cpu_id = 0xC000 | ((s5p_cpu_id & 0x00FFF000) >> 12);
+}
#define IS_SAMSUNG_TYPE(type, id) \
static inline int cpu_is_##type(void) \
{ \
- return s5pc1xx_cpu_id == id ? 1 : 0; \
+ return s5p_cpu_id == id ? 1 : 0; \
}
IS_SAMSUNG_TYPE(s5pc100, 0xc100)
IS_SAMSUNG_TYPE(s5pc110, 0xc110)
+
+#define SAMSUNG_BASE(device, base) \
+static inline unsigned int samsung_get_base_##device(void) \
+{ \
+ if (cpu_is_s5pc100()) \
+ return S5PC100_##base; \
+ else if (cpu_is_s5pc110()) \
+ return S5PC110_##base; \
+ else \
+ return 0; \
+}
+
+SAMSUNG_BASE(clock, CLOCK_BASE)
+SAMSUNG_BASE(gpio, GPIO_BASE)
+SAMSUNG_BASE(pro_id, PRO_ID)
+SAMSUNG_BASE(mmc, MMC_BASE)
+SAMSUNG_BASE(sromc, SROMC_BASE)
+SAMSUNG_BASE(timer, PWMTIMER_BASE)
+SAMSUNG_BASE(uart, UART_BASE)
#endif
#endif /* _S5PC1XX_CPU_H */
diff --git a/arch/arm/include/asm/arch-s5pc1xx/gpio.h b/arch/arm/include/asm/arch-s5pc1xx/gpio.h
index 9a7faed319..2df33a607c 100644
--- a/arch/arm/include/asm/arch-s5pc1xx/gpio.h
+++ b/arch/arm/include/asm/arch-s5pc1xx/gpio.h
@@ -33,96 +33,96 @@ struct s5p_gpio_bank {
};
struct s5pc100_gpio {
- struct s5p_gpio_bank gpio_a0;
- struct s5p_gpio_bank gpio_a1;
- struct s5p_gpio_bank gpio_b;
- struct s5p_gpio_bank gpio_c;
- struct s5p_gpio_bank gpio_d;
- struct s5p_gpio_bank gpio_e0;
- struct s5p_gpio_bank gpio_e1;
- struct s5p_gpio_bank gpio_f0;
- struct s5p_gpio_bank gpio_f1;
- struct s5p_gpio_bank gpio_f2;
- struct s5p_gpio_bank gpio_f3;
- struct s5p_gpio_bank gpio_g0;
- struct s5p_gpio_bank gpio_g1;
- struct s5p_gpio_bank gpio_g2;
- struct s5p_gpio_bank gpio_g3;
- struct s5p_gpio_bank gpio_i;
- struct s5p_gpio_bank gpio_j0;
- struct s5p_gpio_bank gpio_j1;
- struct s5p_gpio_bank gpio_j2;
- struct s5p_gpio_bank gpio_j3;
- struct s5p_gpio_bank gpio_j4;
- struct s5p_gpio_bank gpio_k0;
- struct s5p_gpio_bank gpio_k1;
- struct s5p_gpio_bank gpio_k2;
- struct s5p_gpio_bank gpio_k3;
- struct s5p_gpio_bank gpio_l0;
- struct s5p_gpio_bank gpio_l1;
- struct s5p_gpio_bank gpio_l2;
- struct s5p_gpio_bank gpio_l3;
- struct s5p_gpio_bank gpio_l4;
- struct s5p_gpio_bank gpio_h0;
- struct s5p_gpio_bank gpio_h1;
- struct s5p_gpio_bank gpio_h2;
- struct s5p_gpio_bank gpio_h3;
+ struct s5p_gpio_bank a0;
+ struct s5p_gpio_bank a1;
+ struct s5p_gpio_bank b;
+ struct s5p_gpio_bank c;
+ struct s5p_gpio_bank d;
+ struct s5p_gpio_bank e0;
+ struct s5p_gpio_bank e1;
+ struct s5p_gpio_bank f0;
+ struct s5p_gpio_bank f1;
+ struct s5p_gpio_bank f2;
+ struct s5p_gpio_bank f3;
+ struct s5p_gpio_bank g0;
+ struct s5p_gpio_bank g1;
+ struct s5p_gpio_bank g2;
+ struct s5p_gpio_bank g3;
+ struct s5p_gpio_bank i;
+ struct s5p_gpio_bank j0;
+ struct s5p_gpio_bank j1;
+ struct s5p_gpio_bank j2;
+ struct s5p_gpio_bank j3;
+ struct s5p_gpio_bank j4;
+ struct s5p_gpio_bank k0;
+ struct s5p_gpio_bank k1;
+ struct s5p_gpio_bank k2;
+ struct s5p_gpio_bank k3;
+ struct s5p_gpio_bank l0;
+ struct s5p_gpio_bank l1;
+ struct s5p_gpio_bank l2;
+ struct s5p_gpio_bank l3;
+ struct s5p_gpio_bank l4;
+ struct s5p_gpio_bank h0;
+ struct s5p_gpio_bank h1;
+ struct s5p_gpio_bank h2;
+ struct s5p_gpio_bank h3;
};
struct s5pc110_gpio {
- struct s5p_gpio_bank gpio_a0;
- struct s5p_gpio_bank gpio_a1;
- struct s5p_gpio_bank gpio_b;
- struct s5p_gpio_bank gpio_c0;
- struct s5p_gpio_bank gpio_c1;
- struct s5p_gpio_bank gpio_d0;
- struct s5p_gpio_bank gpio_d1;
- struct s5p_gpio_bank gpio_e0;
- struct s5p_gpio_bank gpio_e1;
- struct s5p_gpio_bank gpio_f0;
- struct s5p_gpio_bank gpio_f1;
- struct s5p_gpio_bank gpio_f2;
- struct s5p_gpio_bank gpio_f3;
- struct s5p_gpio_bank gpio_g0;
- struct s5p_gpio_bank gpio_g1;
- struct s5p_gpio_bank gpio_g2;
- struct s5p_gpio_bank gpio_g3;
- struct s5p_gpio_bank gpio_i;
- struct s5p_gpio_bank gpio_j0;
- struct s5p_gpio_bank gpio_j1;
- struct s5p_gpio_bank gpio_j2;
- struct s5p_gpio_bank gpio_j3;
- struct s5p_gpio_bank gpio_j4;
- struct s5p_gpio_bank gpio_mp0_1;
- struct s5p_gpio_bank gpio_mp0_2;
- struct s5p_gpio_bank gpio_mp0_3;
- struct s5p_gpio_bank gpio_mp0_4;
- struct s5p_gpio_bank gpio_mp0_5;
- struct s5p_gpio_bank gpio_mp0_6;
- struct s5p_gpio_bank gpio_mp0_7;
- struct s5p_gpio_bank gpio_mp1_0;
- struct s5p_gpio_bank gpio_mp1_1;
- struct s5p_gpio_bank gpio_mp1_2;
- struct s5p_gpio_bank gpio_mp1_3;
- struct s5p_gpio_bank gpio_mp1_4;
- struct s5p_gpio_bank gpio_mp1_5;
- struct s5p_gpio_bank gpio_mp1_6;
- struct s5p_gpio_bank gpio_mp1_7;
- struct s5p_gpio_bank gpio_mp1_8;
- struct s5p_gpio_bank gpio_mp2_0;
- struct s5p_gpio_bank gpio_mp2_1;
- struct s5p_gpio_bank gpio_mp2_2;
- struct s5p_gpio_bank gpio_mp2_3;
- struct s5p_gpio_bank gpio_mp2_4;
- struct s5p_gpio_bank gpio_mp2_5;
- struct s5p_gpio_bank gpio_mp2_6;
- struct s5p_gpio_bank gpio_mp2_7;
- struct s5p_gpio_bank gpio_mp2_8;
+ struct s5p_gpio_bank a0;
+ struct s5p_gpio_bank a1;
+ struct s5p_gpio_bank b;
+ struct s5p_gpio_bank c0;
+ struct s5p_gpio_bank c1;
+ struct s5p_gpio_bank d0;
+ struct s5p_gpio_bank d1;
+ struct s5p_gpio_bank e0;
+ struct s5p_gpio_bank e1;
+ struct s5p_gpio_bank f0;
+ struct s5p_gpio_bank f1;
+ struct s5p_gpio_bank f2;
+ struct s5p_gpio_bank f3;
+ struct s5p_gpio_bank g0;
+ struct s5p_gpio_bank g1;
+ struct s5p_gpio_bank g2;
+ struct s5p_gpio_bank g3;
+ struct s5p_gpio_bank i;
+ struct s5p_gpio_bank j0;
+ struct s5p_gpio_bank j1;
+ struct s5p_gpio_bank j2;
+ struct s5p_gpio_bank j3;
+ struct s5p_gpio_bank j4;
+ struct s5p_gpio_bank mp0_1;
+ struct s5p_gpio_bank mp0_2;
+ struct s5p_gpio_bank mp0_3;
+ struct s5p_gpio_bank mp0_4;
+ struct s5p_gpio_bank mp0_5;
+ struct s5p_gpio_bank mp0_6;
+ struct s5p_gpio_bank mp0_7;
+ struct s5p_gpio_bank mp1_0;
+ struct s5p_gpio_bank mp1_1;
+ struct s5p_gpio_bank mp1_2;
+ struct s5p_gpio_bank mp1_3;
+ struct s5p_gpio_bank mp1_4;
+ struct s5p_gpio_bank mp1_5;
+ struct s5p_gpio_bank mp1_6;
+ struct s5p_gpio_bank mp1_7;
+ struct s5p_gpio_bank mp1_8;
+ struct s5p_gpio_bank mp2_0;
+ struct s5p_gpio_bank mp2_1;
+ struct s5p_gpio_bank mp2_2;
+ struct s5p_gpio_bank mp2_3;
+ struct s5p_gpio_bank mp2_4;
+ struct s5p_gpio_bank mp2_5;
+ struct s5p_gpio_bank mp2_6;
+ struct s5p_gpio_bank mp2_7;
+ struct s5p_gpio_bank mp2_8;
struct s5p_gpio_bank res1[48];
- struct s5p_gpio_bank gpio_h0;
- struct s5p_gpio_bank gpio_h1;
- struct s5p_gpio_bank gpio_h2;
- struct s5p_gpio_bank gpio_h3;
+ struct s5p_gpio_bank h0;
+ struct s5p_gpio_bank h1;
+ struct s5p_gpio_bank h2;
+ struct s5p_gpio_bank h3;
};
/* functions */
diff --git a/arch/arm/include/asm/arch-s5pc1xx/mmc.h b/arch/arm/include/asm/arch-s5pc1xx/mmc.h
index ac560c2704..68c59d13e3 100644
--- a/arch/arm/include/asm/arch-s5pc1xx/mmc.h
+++ b/arch/arm/include/asm/arch-s5pc1xx/mmc.h
@@ -56,7 +56,7 @@ struct s5p_mmc {
unsigned int control4;
unsigned char res4[0x6e];
unsigned short hcver;
- unsigned char res5[0xFFF00];
+ unsigned char res5[0xFFF02];
};
struct mmc_host {
diff --git a/arch/arm/include/asm/arch-s5pc1xx/pwm.h b/arch/arm/include/asm/arch-s5pc1xx/pwm.h
index e02a8d8fb3..0369968d4a 100644
--- a/arch/arm/include/asm/arch-s5pc1xx/pwm.h
+++ b/arch/arm/include/asm/arch-s5pc1xx/pwm.h
@@ -22,19 +22,15 @@
#ifndef __ASM_ARM_ARCH_PWM_H_
#define __ASM_ARM_ARCH_PWM_H_
-/* PWM timer addressing */
-#define S5PC100_TIMER_BASE S5PC100_PWMTIMER_BASE
-#define S5PC110_TIMER_BASE S5PC110_PWMTIMER_BASE
-
/* Interval mode(Auto Reload) of PWM Timer 4 */
-#define S5PC1XX_TCON4_AUTO_RELOAD (1 << 22)
+#define TCON4_AUTO_RELOAD (1 << 22)
/* Update TCNTB4 */
-#define S5PC1XX_TCON4_UPDATE (1 << 21)
+#define TCON4_UPDATE (1 << 21)
/* start bit of PWM Timer 4 */
-#define S5PC1XX_TCON4_START (1 << 20)
+#define TCON4_START (1 << 20)
#ifndef __ASSEMBLY__
-struct s5pc1xx_timer {
+struct s5p_timer {
unsigned int tcfg0;
unsigned int tcfg1;
unsigned int tcon;
diff --git a/arch/avr32/cpu/at32ap700x/Makefile b/arch/avr32/cpu/at32ap700x/Makefile
index 46e6ef661a..30ea92590d 100644
--- a/arch/avr32/cpu/at32ap700x/Makefile
+++ b/arch/avr32/cpu/at32ap700x/Makefile
@@ -24,7 +24,7 @@ include $(TOPDIR)/config.mk
LIB := $(obj)lib$(SOC).a
-COBJS := portmux.o clk.o
+COBJS := portmux.o clk.o mmu.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
diff --git a/arch/avr32/cpu/at32ap700x/mmu.c b/arch/avr32/cpu/at32ap700x/mmu.c
new file mode 100644
index 0000000000..c3a1b93679
--- /dev/null
+++ b/arch/avr32/cpu/at32ap700x/mmu.c
@@ -0,0 +1,78 @@
+#include <common.h>
+#include <asm/arch/mmu.h>
+#include <asm/sysreg.h>
+
+void mmu_init_r(unsigned long dest_addr)
+{
+ uintptr_t vmr_table_addr;
+
+ /* Round monitor address down to the nearest page boundary */
+ dest_addr &= PAGE_ADDR_MASK;
+
+ /* Initialize TLB entry 0 to cover the monitor, and lock it */
+ sysreg_write(TLBEHI, dest_addr | SYSREG_BIT(TLBEHI_V));
+ sysreg_write(TLBELO, dest_addr | MMU_VMR_CACHE_WRBACK);
+ sysreg_write(MMUCR, SYSREG_BF(DRP, 0) | SYSREG_BF(DLA, 1)
+ | SYSREG_BIT(MMUCR_S) | SYSREG_BIT(M));
+ __builtin_tlbw();
+
+ /*
+ * Calculate the address of the VM range table in a PC-relative
+ * manner to make sure we hit the SDRAM and not the flash.
+ */
+ vmr_table_addr = (uintptr_t)&mmu_vmr_table;
+ sysreg_write(PTBR, vmr_table_addr);
+ printf("VMR table @ 0x%08x\n", vmr_table_addr);
+
+ /* Enable paging */
+ sysreg_write(MMUCR, SYSREG_BF(DRP, 1) | SYSREG_BF(DLA, 1)
+ | SYSREG_BIT(MMUCR_S) | SYSREG_BIT(M) | SYSREG_BIT(E));
+}
+
+int mmu_handle_tlb_miss(void)
+{
+ const struct mmu_vm_range *vmr_table;
+ const struct mmu_vm_range *vmr;
+ unsigned int fault_pgno;
+ int first, last;
+
+ fault_pgno = sysreg_read(TLBEAR) >> PAGE_SHIFT;
+ vmr_table = (const struct mmu_vm_range *)sysreg_read(PTBR);
+
+ /* Do a binary search through the VM ranges */
+ first = 0;
+ last = CONFIG_SYS_NR_VM_REGIONS;
+ while (first < last) {
+ unsigned int start;
+ int middle;
+
+ /* Pick the entry in the middle of the remaining range */
+ middle = (first + last) >> 1;
+ vmr = &vmr_table[middle];
+ start = vmr->virt_pgno;
+
+ /* Do the bisection thing */
+ if (fault_pgno < start) {
+ last = middle;
+ } else if (fault_pgno >= (start + vmr->nr_pages)) {
+ first = middle + 1;
+ } else {
+ /* Got it; let's slam it into the TLB */
+ uint32_t tlbelo;
+
+ tlbelo = vmr->phys & ~PAGE_ADDR_MASK;
+ tlbelo |= fault_pgno << PAGE_SHIFT;
+ sysreg_write(TLBELO, tlbelo);
+ __builtin_tlbw();
+
+ /* Zero means success */
+ return 0;
+ }
+ }
+
+ /*
+ * Didn't find any matching entries. Return a nonzero value to
+ * indicate that this should be treated as a fatal exception.
+ */
+ return -1;
+}
diff --git a/arch/avr32/cpu/exception.c b/arch/avr32/cpu/exception.c
index dc9c3002a4..b21ef1f928 100644
--- a/arch/avr32/cpu/exception.c
+++ b/arch/avr32/cpu/exception.c
@@ -59,7 +59,8 @@ void do_unknown_exception(unsigned int ecr, struct pt_regs *regs)
{
unsigned int mode;
- printf("\n *** Unhandled exception %u at PC=0x%08lx\n", ecr, regs->pc);
+ printf("\n *** Unhandled exception %u at PC=0x%08lx [%08lx]\n",
+ ecr, regs->pc, regs->pc - gd->reloc_off);
switch (ecr) {
case ECR_BUS_ERROR_WRITE:
diff --git a/arch/avr32/cpu/start.S b/arch/avr32/cpu/start.S
index 99c9e06cb8..06bf4c692d 100644
--- a/arch/avr32/cpu/start.S
+++ b/arch/avr32/cpu/start.S
@@ -82,12 +82,19 @@ _evba:
.org 0x44
rjmp unknown_exception /* DTLB Modified */
- .org 0x50
- rjmp unknown_exception /* ITLB Miss */
- .org 0x60
- rjmp unknown_exception /* DTLB Miss (read) */
- .org 0x70
- rjmp unknown_exception /* DTLB Miss (write) */
+ .org 0x50 /* ITLB Miss */
+ pushm r8-r12,lr
+ rjmp 1f
+ .org 0x60 /* DTLB Miss (read) */
+ pushm r8-r12,lr
+ rjmp 1f
+ .org 0x70 /* DTLB Miss (write) */
+ pushm r8-r12,lr
+1: mov r12, sp
+ rcall mmu_handle_tlb_miss
+ popm r8-r12,lr
+ brne unknown_exception
+ rete
.size _evba, . - _evba
diff --git a/arch/avr32/include/asm/arch-at32ap700x/addrspace.h b/arch/avr32/include/asm/arch-at32ap700x/addrspace.h
index 409eee3536..4edc1bd701 100644
--- a/arch/avr32/include/asm/arch-at32ap700x/addrspace.h
+++ b/arch/avr32/include/asm/arch-at32ap700x/addrspace.h
@@ -75,10 +75,7 @@ static inline void * phys_to_virt(unsigned long address)
static inline void *
map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags)
{
- if (flags == MAP_WRBACK)
- return (void *)P1SEGADDR(paddr);
- else
- return (void *)P2SEGADDR(paddr);
+ return (void *)paddr;
}
#endif /* __ASM_AVR32_ADDRSPACE_H */
diff --git a/arch/avr32/include/asm/arch-at32ap700x/mmu.h b/arch/avr32/include/asm/arch-at32ap700x/mmu.h
new file mode 100644
index 0000000000..fcd9a05609
--- /dev/null
+++ b/arch/avr32/include/asm/arch-at32ap700x/mmu.h
@@ -0,0 +1,66 @@
+/*
+ * In order to deal with the hardcoded u-boot requirement that virtual
+ * addresses are always mapped 1:1 with physical addresses, we implement
+ * a small virtual memory manager so that we can use the MMU hardware in
+ * order to get the caching properties right.
+ *
+ * A few pages (or possibly just one) are locked in the TLB permanently
+ * in order to avoid recursive TLB misses, but most pages are faulted in
+ * on demand.
+ */
+#ifndef __ASM_ARCH_MMU_H
+#define __ASM_ARCH_MMU_H
+
+#include <asm/sysreg.h>
+
+#define PAGE_SHIFT 20
+#define PAGE_SIZE (1UL << PAGE_SHIFT)
+#define PAGE_ADDR_MASK (~(PAGE_SIZE - 1))
+
+#define MMU_VMR_CACHE_NONE \
+ (SYSREG_BF(AP, 3) | SYSREG_BF(SZ, 3) | SYSREG_BIT(TLBELO_D))
+#define MMU_VMR_CACHE_WBUF \
+ (MMU_VMR_CACHE_NONE | SYSREG_BIT(B))
+#define MMU_VMR_CACHE_WRTHRU \
+ (MMU_VMR_CACHE_NONE | SYSREG_BIT(TLBELO_C) | SYSREG_BIT(W))
+#define MMU_VMR_CACHE_WRBACK \
+ (MMU_VMR_CACHE_WBUF | SYSREG_BIT(TLBELO_C))
+
+/*
+ * This structure is used in our "page table". Instead of the usual
+ * x86-inspired radix tree, we let each entry cover an arbitrary-sized
+ * virtual address range and store them in a binary search tree. This is
+ * somewhat slower, but should use significantly less RAM, and we
+ * shouldn't get many TLB misses when using 1 MB pages anyway.
+ *
+ * With 1 MB pages, we need 12 bits to store the page number. In
+ * addition, we stick an Invalid bit in the high bit of virt_pgno (if
+ * set, it cannot possibly match any faulting page), and all the bits
+ * that need to be written to TLBELO in phys_pgno.
+ */
+struct mmu_vm_range {
+ uint16_t virt_pgno;
+ uint16_t nr_pages;
+ uint32_t phys;
+};
+
+/*
+ * An array of mmu_vm_range objects describing all pageable addresses.
+ * The array is sorted by virt_pgno so that the TLB miss exception
+ * handler can do a binary search to find the correct entry.
+ */
+extern struct mmu_vm_range mmu_vmr_table[];
+
+/*
+ * Initialize the MMU. This will set up a fixed TLB entry for the static
+ * u-boot image at dest_addr and enable paging.
+ */
+void mmu_init_r(unsigned long dest_addr);
+
+/*
+ * Handle a TLB miss exception. This function is called directly from
+ * the exception vector table written in assembly.
+ */
+int mmu_handle_tlb_miss(void);
+
+#endif /* __ASM_ARCH_MMU_H */
diff --git a/arch/avr32/lib/board.c b/arch/avr32/lib/board.c
index 9e741d22e2..aa589bb4b0 100644
--- a/arch/avr32/lib/board.c
+++ b/arch/avr32/lib/board.c
@@ -33,6 +33,7 @@
#include <asm/initcalls.h>
#include <asm/sections.h>
+#include <asm/arch/mmu.h>
#ifndef CONFIG_IDENT_STRING
#define CONFIG_IDENT_STRING ""
@@ -265,6 +266,9 @@ void board_init_r(gd_t *new_gd, ulong dest_addr)
gd->flags |= GD_FLG_RELOC;
gd->reloc_off = dest_addr - CONFIG_SYS_MONITOR_BASE;
+ /* Enable the MMU so that we can keep u-boot simple */
+ mmu_init_r(dest_addr);
+
board_early_init_r();
monitor_flash_len = _edata - _text;
OpenPOWER on IntegriCloud