diff options
Diffstat (limited to 'board/omap2420h4')
-rwxr-xr-x | board/omap2420h4/Makefile | 47 | ||||
-rwxr-xr-x | board/omap2420h4/config.mk | 28 | ||||
-rwxr-xr-x | board/omap2420h4/flash.c | 537 | ||||
-rwxr-xr-x | board/omap2420h4/lowlevel_init.S | 185 | ||||
-rwxr-xr-x | board/omap2420h4/mem.c | 375 | ||||
-rwxr-xr-x | board/omap2420h4/omap2420h4.c | 868 | ||||
-rwxr-xr-x | board/omap2420h4/sys_info.c | 387 | ||||
-rwxr-xr-x | board/omap2420h4/u-boot.lds | 59 |
8 files changed, 2486 insertions, 0 deletions
diff --git a/board/omap2420h4/Makefile b/board/omap2420h4/Makefile new file mode 100755 index 0000000..ed47868 --- /dev/null +++ b/board/omap2420h4/Makefile @@ -0,0 +1,47 @@ +# +# (C) Copyright 2000, 2001, 2002 +# 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 = lib$(BOARD).a + +OBJS := omap2420h4.o mem.o sys_info.o +SOBJS := lowlevel_init.o + +$(LIB): $(OBJS) $(SOBJS) + $(AR) crv $@ $^ + +clean: + rm -f $(SOBJS) $(OBJS) + +distclean: clean + rm -f $(LIB) core *.bak .depend + +######################################################################### + +.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c) + $(CC) -M $(CPPFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@ + +-include .depend + +######################################################################### diff --git a/board/omap2420h4/config.mk b/board/omap2420h4/config.mk new file mode 100755 index 0000000..3edcde0 --- /dev/null +++ b/board/omap2420h4/config.mk @@ -0,0 +1,28 @@ +# +# (C) Copyright 2004 +# Texas Instruments, <www.ti.com> +# +# TI H4 board with OMAP2420 (ARM1136) cpu +# see http://www.ti.com/ for more information on Texas Instruments +# +# H4 has 1 bank of 32MB or 64MB mDDR-SDRAM on CS0 +# H4 has 1 bank of 32MB or 00MB mDDR-SDRAM on CS1 +# Physical Address: +# 8000'0000 (bank0) +# A000/0000 (bank1) ES2 will be configurable +# Linux-Kernel is expected to be at 8000'8000, entry 8000'8000 +# (mem base + reserved) + +# For use with external or internal boots. +TEXT_BASE = 0x80e80000 + +# Used with full SRAM boot. +# This is either with a GP system or a signed boot image. +# easiest, and safest way to go if you can. +#TEXT_BASE = 0x40270000 + + +# Handy to get symbols to debug ROM version. +#TEXT_BASE = 0x0 +#TEXT_BASE = 0x08000000 +#TEXT_BASE = 0x04000000 diff --git a/board/omap2420h4/flash.c b/board/omap2420h4/flash.c new file mode 100755 index 0000000..d5e106a --- /dev/null +++ b/board/omap2420h4/flash.c @@ -0,0 +1,537 @@ +/* + * (C) Copyright 2001 + * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net + * + * (C) Copyright 2001-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2003 + * Texas Instruments, <www.ti.com> + * Kshitij Gupta <Kshitij@ti.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 <common.h> +#include <asm/arch/sizes.h> +#include <linux/byteorder/swab.h> + +#define PHYS_FLASH_SECT_SIZE SZ_128K +flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */ + +/* Board support for 1 or 2 flash devices */ +#undef FLASH_PORT_WIDTH32 +#define FLASH_PORT_WIDTH16 + +#ifdef FLASH_PORT_WIDTH16 +# define FLASH_PORT_WIDTH ushort +# define FLASH_PORT_WIDTHV vu_short +# define SWAP(x) __swab16(x) +#else +# define FLASH_PORT_WIDTH ulong +# define FLASH_PORT_WIDTHV vu_long +# define SWAP(x) __swab32(x) +#endif + +#define FPW FLASH_PORT_WIDTH +#define FPWV FLASH_PORT_WIDTHV + +#define mb() __asm__ __volatile__ ("" : : : "memory") + + +/* Flash Organization Structure */ +typedef struct OrgDef { + unsigned int sector_number; + unsigned int sector_size; +} OrgDef; + + +/* Flash Organizations */ +OrgDef OrgIntel_28F256L18T[] = { + {4, SZ_32K}, /* 4 * 32kBytes sectors */ + {255, SZ_128K}, /* 255 * 128kBytes sectors */ +}; + + +/*----------------------------------------------------------------------- + * Functions + */ +unsigned long flash_init (void); +static ulong flash_get_size (FPW * addr, flash_info_t * info); +static int write_data (flash_info_t * info, ulong dest, FPW data); +static void flash_get_offsets (ulong base, flash_info_t * info); +void inline spin_wheel (void); +void flash_print_info (flash_info_t * info); +void flash_unprotect_sectors (FPWV * addr); +int flash_erase (flash_info_t * info, int s_first, int s_last); +int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt); +void flash_unlock(flash_info_t * info, int bank); +int flash_probe(void); + +/*----------------------------------------------------------------------- + */ + +/* see if flash is ok */ +int flash_probe(void) +{ + return(flash_get_size ((FPW *) PHYS_FLASH_1, &flash_info[0])); +} + +unsigned long flash_init (void) +{ + int i; + ulong size = 0; + for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) { + switch (i) { + case 0: + flash_get_size ((FPW *) PHYS_FLASH_1, &flash_info[i]); + flash_get_offsets (PHYS_FLASH_1, &flash_info[i]); + /* to reset the lock bit */ + flash_unlock(&flash_info[i],i); + break; + case 1: + flash_get_size ((FPW *) PHYS_FLASH_2, &flash_info[i]); + flash_get_offsets (PHYS_FLASH_2, &flash_info[i]); + /* to reset the lock bit */ + flash_unlock(&flash_info[i],i); + break; + + default: + panic ("configured too many flash banks!\n"); + break; + } + size += flash_info[i].size; + } + +#ifdef CFG_ENV_IS_IN_FLASH + /* Protect monitor and environment sectors + */ + flash_protect (FLAG_PROTECT_SET, + CFG_FLASH_BASE, + CFG_FLASH_BASE + monitor_flash_len - 1, &flash_info[0]); + + flash_protect (FLAG_PROTECT_SET, + CFG_ENV_ADDR, + CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]); +#endif + return size; +} + +/*----------------------------------------------------------------------- + */ +void flash_unlock(flash_info_t * info, int bank) +{ + int j; + if (!bank) + j=2; /* leave 0,1 locked for boot bank */ + else + j=0; /* get the whole bank for #2 */ + + for (;j<CFG_MAX_FLASH_SECT;j++) { + FPWV *addr = (FPWV *) (info->start[j]); + if (addr == NULL) { + printf("Warning Flash probe failed\n"); + break; + } + flash_unprotect_sectors (addr); + *addr = (FPW) 0x00500050;/* clear status register */ + *addr = (FPW) 0x00FF00FF;/* resest to read mode */ + } +} + +/*----------------------------------------------------------------------- + */ +static void flash_get_offsets (ulong base, flash_info_t * info) +{ + int i; + volatile int r; /* gcc 3.4.0-1 strangeness, need to follow up.*/ + + if (info->flash_id == FLASH_UNKNOWN) { + return; + } + + if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) { + for (i = 0; i < info->sector_count; i++) { + if (i > 254) { /* 255,256,257,258 */ + r=i; + info->start[i] = base + (((r-(int)255) * SZ_32K) + (255*PHYS_FLASH_SECT_SIZE)); + info->protect[i] = 0; + } else { + info->start[i] = base + (i * PHYS_FLASH_SECT_SIZE); + info->protect[i] = 0; + } + } + } +} + +/*----------------------------------------------------------------------- + */ +void flash_print_info (flash_info_t * info) +{ + int i; + + if (info->flash_id == FLASH_UNKNOWN) { + printf ("missing or unknown FLASH type\n"); + return; + } + + switch (info->flash_id & FLASH_VENDMASK) { + case FLASH_MAN_INTEL: + printf ("INTEL "); + break; + default: + printf ("Unknown Vendor "); + break; + } + + switch (info->flash_id & FLASH_TYPEMASK) { + case FLASH_28F256L18T: + printf ("FLASH 28F256L18T\n"); + break; + default: + printf ("Unknown Chip Type\n"); + break; + } + + printf (" Size: %ld MB in %d Sectors\n", + info->size >> 20, 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; +} + +/* + * The following code cannot be run from FLASH! + */ +static ulong flash_get_size (FPW * addr, flash_info_t * info) +{ + volatile FPW value; + /* mb(); this one makes ARM11 err go away, but I want it :) as a guide to problems */ + + /* Write auto select command: read Manufacturer ID */ + addr[0x5555] = (FPW) 0x00AA00AA; + addr[0x2AAA] = (FPW) 0x00550055; + addr[0x5555] = (FPW) 0x00900090; + + mb (); + value = addr[0] & 0xFF; /* just looking for 89 (8989 is hw pat)*/ + + switch (value) { + + case (FPW) INTEL_MANUFACT: + info->flash_id = FLASH_MAN_INTEL; + break; + + default: + info->flash_id = FLASH_UNKNOWN; + info->sector_count = 0; + info->size = 0; + addr[0] = (FPW) 0x00FF00FF; /* restore read mode */ + return(0); /* no or unknown flash */ + } + + mb (); + value = addr[1]; /* device ID */ + switch (value) { + + case (FPW) (INTEL_ID_28F256L18T): /* 880D */ + info->flash_id += FLASH_28F256L18T; + info->sector_count = 259; /*0-258*/ + info->size = SZ_32M; + break; /* => 32 MB */ + + default: + info->flash_id = FLASH_UNKNOWN; + break; + } + + if (info->sector_count > CFG_MAX_FLASH_SECT) { + printf ("** ERROR: sector count %d > max (%d) **\n", + info->sector_count, CFG_MAX_FLASH_SECT); + info->sector_count = CFG_MAX_FLASH_SECT; + } + + addr[0] = (FPW) 0x00FF00FF; /* restore read mode */ + + return(info->size); +} + + +/* unprotects a sector for write and erase + * on some intel parts, this unprotects the entire chip, but it + * wont hurt to call this additional times per sector... + */ +void flash_unprotect_sectors (FPWV * addr) +{ +#define PD_FINTEL_WSMS_READY_MASK 0x0080 + + *addr = (FPW) 0x00500050; /* clear status register */ + + /* this sends the clear lock bit command */ + *addr = (FPW) 0x00600060; + *addr = (FPW) 0x00D000D0; +} + + +/*----------------------------------------------------------------------- + */ + +int flash_erase (flash_info_t * info, int s_first, int s_last) +{ + int prot, sect; + ulong type, start, last; + int rcode = 0; +#ifdef CONFIG_USE_IRQ + int iflag; +#endif + + if ((s_first < 0) || (s_first > s_last)) { + if (info->flash_id == FLASH_UNKNOWN) { + printf ("- missing\n"); + } else { + printf ("- no sectors to erase\n"); + } + return 1; + } + + type = (info->flash_id & FLASH_VENDMASK); + if ((type != FLASH_MAN_INTEL)) { + printf ("Can't erase unknown flash type %08lx - aborted\n", + info->flash_id); + return 1; + } + + prot = 0; + for (sect = s_first; sect <= s_last; ++sect) { + if (info->protect[sect]) { + prot++; + } + } + + if (prot) { + printf ("- Warning: %d protected sectors will not be erased!\n", + prot); + } else { + printf ("\n"); + } + + + start = get_timer (0); + last = start; + +#ifdef CONFIG_USE_IRQ + /* Disable interrupts which might cause a timeout here */ + iflag = disable_interrupts (); +#endif + + /* Start erase on unprotected sectors */ + for (sect = s_first; sect <= s_last; sect++) { + if (info->protect[sect] == 0) { /* not protected */ + FPWV *addr = (FPWV *) (info->start[sect]); + FPW status; + + printf ("Erasing sector %2d ... ", sect); + + flash_unprotect_sectors (addr); + + /* arm simple, non interrupt dependent timer */ + reset_timer_masked (); + + *addr = (FPW) 0x00500050;/* clear status register */ + *addr = (FPW) 0x00200020;/* erase setup */ + *addr = (FPW) 0x00D000D0;/* erase confirm */ + + while (((status = + *addr) & (FPW) 0x00800080) != + (FPW) 0x00800080) { + if (get_timer_masked () > + CFG_FLASH_ERASE_TOUT) { + printf ("Timeout\n"); + /* suspend erase */ + *addr = (FPW) 0x00B000B0; + /* reset to read mode */ + *addr = (FPW) 0x00FF00FF; + rcode = 1; + break; + } + } + + /* clear status register cmd. */ + *addr = (FPW) 0x00500050; + *addr = (FPW) 0x00FF00FF;/* resest to read mode */ + printf (" done\n"); + } + } +#ifdef CONFIG_USE_IRQ + if (iflag) + enable_interrupts(); +#endif + + return rcode; +} + +/*----------------------------------------------------------------------- + * Copy memory to flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + * 4 - Flash not identified + */ + +int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt) +{ + ulong cp, wp; + FPW data; + int count, i, l, rc, port_width; + + if (info->flash_id == FLASH_UNKNOWN) { + return 4; + } +/* get lower word aligned address */ +#ifdef FLASH_PORT_WIDTH16 + wp = (addr & ~1); + port_width = 2; +#else + wp = (addr & ~3); + port_width = 4; +#endif + + /* + * handle unaligned start bytes + */ + if ((l = addr - wp) != 0) { + data = 0; + for (i = 0, cp = wp; i < l; ++i, ++cp) { + data = (data << 8) | (*(uchar *) cp); + } + for (; i < port_width && cnt > 0; ++i) { + data = (data << 8) | *src++; + --cnt; + ++cp; + } + for (; cnt == 0 && i < port_width; ++i, ++cp) { + data = (data << 8) | (*(uchar *) cp); + } + + if ((rc = write_data (info, wp, SWAP (data))) != 0) { + return(rc); + } + wp += port_width; + } + + /* + * handle word aligned part + */ + count = 0; + while (cnt >= port_width) { + data = 0; + for (i = 0; i < port_width; ++i) { + data = (data << 8) | *src++; + } + if ((rc = write_data (info, wp, SWAP (data))) != 0) { + return(rc); + } + wp += port_width; + cnt -= port_width; + if (count++ > 0x800) { + spin_wheel (); + count = 0; + } + } + + if (cnt == 0) { + return(0); + } + + /* + * handle unaligned tail bytes + */ + data = 0; + for (i = 0, cp = wp; i < port_width && cnt > 0; ++i, ++cp) { + data = (data << 8) | *src++; + --cnt; + } + for (; i < port_width; ++i, ++cp) { + data = (data << 8) | (*(uchar *) cp); + } + + return(write_data (info, wp, SWAP (data))); +} + +/*----------------------------------------------------------------------- + * Write a word or halfword to Flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + */ +static int write_data (flash_info_t * info, ulong dest, FPW data) +{ + FPWV *addr = (FPWV *) dest; + ulong status; +#ifdef CONFIG_USE_IRQ + int iflag; +#endif + + /* Check if Flash is (sufficiently) erased */ + if ((*addr & data) != data) { + printf ("not erased at %08lx (%x)\n", (ulong) addr, *addr); + return(2); + } + /* Disable interrupts which might cause a timeout here */ +#ifdef CONFIG_USE_IRQ + iflag = disable_interrupts (); +#endif + *addr = (FPW) 0x00400040; /* write setup */ + *addr = data; + + /* arm simple, non interrupt dependent timer */ + reset_timer_masked (); + + /* wait while polling the status register */ + while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) { + if (get_timer_masked () > CFG_FLASH_WRITE_TOUT) { + *addr = (FPW) 0x00FF00FF; /* restore read mode */ + return(1); + } + } + *addr = (FPW) 0x00FF00FF; /* restore read mode */ + +#ifdef CONFIG_USE_IRQ + if (iflag) + enable_interrupts(); +#endif + + return(0); +} + +void inline spin_wheel (void) +{ + static int p = 0; + static char w[] = "\\/-"; + + printf ("\010%c", w[p]); + (++p == 3) ? (p = 0) : 0; +} diff --git a/board/omap2420h4/lowlevel_init.S b/board/omap2420h4/lowlevel_init.S new file mode 100755 index 0000000..9752fc4 --- /dev/null +++ b/board/omap2420h4/lowlevel_init.S @@ -0,0 +1,185 @@ +/* + * Board specific setup info + * + * (C) Copyright 2004 + * Texas Instruments, <www.ti.com> + * Richard Woodruff <r-woodruff2@ti.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 <config.h> +#include <version.h> +#include <asm/arch/omap2420.h> +#include <asm/arch/mem.h> +#include <asm/arch/clocks.h> + +_TEXT_BASE: + .word TEXT_BASE /* sdram load addr from config.mk */ + +/************************************************************************** + * cpy_clk_code: relocates clock code into SRAM where its safer to execute + * R1 = SRAM destination address. + *************************************************************************/ +.global cpy_clk_code + cpy_clk_code: + /* Copy DPLL code into SRAM */ + adr r0, go_to_speed /* get addr of clock setting code */ + mov r2, #384 /* r2 size to copy (div by 32 bytes) */ + mov r1, r1 /* r1 <- dest address (passed in) */ + add r2, r2, r0 /* r2 <- source end address */ +next2: + ldmia r0!, {r3-r10} /* copy from source address [r0] */ + stmia r1!, {r3-r10} /* copy to target address [r1] */ + cmp r0, r2 /* until source end address [r2] */ + bne next2 + mov pc, lr /* back to caller */ + +/* **************************************************************************** + * go_to_speed: -Moves to bypass, -Commits clock dividers, -puts dpll at speed + * -executed from SRAM. + * R0 = PRCM_CLKCFG_CTRL - addr of valid reg + * R1 = CM_CLKEN_PLL - addr dpll ctlr reg + * R2 = dpll value + * R3 = CM_IDLEST_CKGEN - addr dpll lock wait + ******************************************************************************/ +.global go_to_speed + go_to_speed: + sub sp, sp, #0x4 /* get some stack space */ + str r4, [sp] /* save r4's value */ + + /* move into fast relock bypass */ + ldr r8, pll_ctl_add + mov r4, #0x2 + str r4, [r8] + ldr r4, pll_stat +block: + ldr r8, [r4] /* wait for bypass to take effect */ + and r8, r8, #0x3 + cmp r8, #0x1 + bne block + + /* set new dpll dividers _after_ in bypass */ + ldr r4, pll_div_add + ldr r8, pll_div_val + str r8, [r4] + + /* now prepare GPMC (flash) for new dpll speed */ + /* flash needs to be stable when we jump back to it */ + ldr r4, cfg3_0_addr + ldr r8, cfg3_0_val + str r8, [r4] + ldr r4, cfg4_0_addr + ldr r8, cfg4_0_val + str r8, [r4] + ldr r4, cfg1_0_addr + ldr r8, [r4] + orr r8, r8, #0x3 /* up gpmc divider */ + str r8, [r4] + + /* setup to 2x loop though code. The first loop pre-loads the + * icache, the 2nd commits the prcm config, and locks the dpll + */ + mov r4, #0x1000 /* spin spin spin */ + mov r8, #0x4 /* first pass condition & set registers */ + cmp r8, #0x4 +2: + ldrne r8, [r3] /* DPLL lock check */ + and r8, r8, #0x7 + cmp r8, #0x2 + beq 4f +3: + subeq r8, r8, #0x1 + streq r8, [r0] /* commit dividers (2nd time) */ + nop +lloop1: + sub r4, r4, #0x1 /* Loop currently necessary else bad jumps */ + nop + cmp r4, #0x0 + bne lloop1 + mov r4, #0x40000 + cmp r8, #0x1 + nop + streq r2, [r1] /* lock dpll (2nd time) */ + nop +lloop2: + sub r4, r4, #0x1 /* loop currently necessary else bad jumps */ + nop + cmp r4, #0x0 + bne lloop2 + mov r4, #0x40000 + cmp r8, #0x1 + nop + ldreq r8, [r3] /* get lock condition for dpll */ + cmp r8, #0x4 /* first time though? */ + bne 2b + moveq r8, #0x2 /* set to dpll check condition. */ + beq 3b /* if condition not true branch */ +4: + ldr r4, [sp] + add sp, sp, #0x4 /* return stack space */ + mov pc, lr /* back to caller, locked */ + +_go_to_speed: .word go_to_speed + +/* these constants need to be close for PIC code */ +cfg3_0_addr: + .word GPMC_CONFIG3_0 +cfg3_0_val: + .word H4_24XX_GPMC_CONFIG3_0 +cfg4_0_addr: + .word GPMC_CONFIG4_0 +cfg4_0_val: + .word H4_24XX_GPMC_CONFIG4_0 +cfg1_0_addr: + .word GPMC_CONFIG1_0 +pll_ctl_add: + .word CM_CLKEN_PLL +pll_stat: + .word CM_IDLEST_CKGEN +pll_div_add: + .word CM_CLKSEL1_PLL +pll_div_val: + .word DPLL_VAL /* DPLL setting (300MHz default) */ + +.globl lowlevel_init +lowlevel_init: + ldr sp, SRAM_STACK + str ip, [sp] /* stash old link register */ + mov ip, lr /* save link reg across call */ + bl s_init /* go setup pll,mux,memory */ + ldr ip, [sp] /* restore save ip */ + mov lr, ip /* restore link reg */ + + /* map interrupt controller */ + ldr r0, VAL_INTH_SETUP + mcr p15, 0, r0, c15, c2, 4 + + /* back to arch calling code */ + mov pc, lr + + /* the literal pools origin */ + .ltorg + +REG_CONTROL_STATUS: + .word CONTROL_STATUS +VAL_INTH_SETUP: + .word PERIFERAL_PORT_BASE +SRAM_STACK: + .word LOW_LEVEL_SRAM_STACK diff --git a/board/omap2420h4/mem.c b/board/omap2420h4/mem.c new file mode 100755 index 0000000..62eb6e3 --- /dev/null +++ b/board/omap2420h4/mem.c @@ -0,0 +1,375 @@ +/* + * (C) Copyright 2004 + * Texas Instruments, <www.ti.com> + * Richard Woodruff <r-woodruff2@ti.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/arch/omap2420.h> +#include <asm/io.h> +#include <asm/arch/bits.h> +#include <asm/arch/mux.h> +#include <asm/arch/mem.h> +#include <asm/arch/clocks.h> +#include <asm/arch/sys_proto.h> +#include <asm/arch/sys_info.h> + +/************************************************************ + * sdelay() - simple spin loop. Will be constant time as + * its generally used in 12MHz bypass conditions only. This + * is necessary until timers are accessible. + * + * not inline to increase chances its in cache when called + *************************************************************/ +void sdelay (unsigned long loops) +{ + __asm__ volatile ("1:\n" "subs %0, %1, #1\n" + "bne 1b":"=r" (loops):"0" (loops)); +} + +/********************************************************************************* + * prcm_init() - inits clocks for PRCM as defined in clocks.h (config II default). + * -- called from SRAM, or Flash (using temp SRAM stack). + *********************************************************************************/ +void prcm_init(void) +{ + u32 div; + void (*f_lock_pll) (u32, u32, u32, u32); + extern void *_end_vect, *_start; + + f_lock_pll = (void *)((u32)&_end_vect - (u32)&_start + SRAM_VECT_CODE); + + __raw_writel(0, CM_FCLKEN1_CORE); /* stop all clocks to reduce ringing */ + __raw_writel(0, CM_FCLKEN2_CORE); /* may not be necessary */ + __raw_writel(0, CM_ICLKEN1_CORE); + __raw_writel(0, CM_ICLKEN2_CORE); + + __raw_writel(DPLL_OUT, CM_CLKSEL2_PLL); /* set DPLL out */ + __raw_writel(MPU_DIV, CM_CLKSEL_MPU); /* set MPU divider */ + __raw_writel(DSP_DIV, CM_CLKSEL_DSP); /* set dsp and iva dividers */ + __raw_writel(GFX_DIV, CM_CLKSEL_GFX); /* set gfx dividers */ + + div = BUS_DIV; + __raw_writel(div, CM_CLKSEL1_CORE);/* set L3/L4/USB/Display/Vlnc/SSi dividers */ + sdelay(1000); + + if(running_in_sram()){ + /* If running fully from SRAM this is OK. The Flash bus drops out for just a little. + * but then comes back. If running from Flash this sequence kills you, thus you need + * to run it using CONFIG_PARTIAL_SRAM. + */ + __raw_writel(MODE_BYPASS_FAST, CM_CLKEN_PLL); /* go to bypass, fast relock */ + wait_on_value(BIT0|BIT1, BIT0, CM_IDLEST_CKGEN, LDELAY); /* wait till in bypass */ + sdelay(1000); + /* set clock selection and dpll dividers. */ + __raw_writel(DPLL_VAL, CM_CLKSEL1_PLL); /* set pll for target rate */ + __raw_writel(COMMIT_DIVIDERS, PRCM_CLKCFG_CTRL); /* commit dividers */ + sdelay(10000); + __raw_writel(DPLL_LOCK, CM_CLKEN_PLL); /* enable dpll */ + sdelay(10000); + wait_on_value(BIT0|BIT1, BIT1, CM_IDLEST_CKGEN, LDELAY); /*wait for dpll lock */ + }else if(running_in_flash()){ + /* if running from flash, need to jump to small relocated code area in SRAM. + * This is the only safe spot to do configurations from. + */ + (*f_lock_pll)(PRCM_CLKCFG_CTRL, CM_CLKEN_PLL, DPLL_LOCK, CM_IDLEST_CKGEN); + } + + __raw_writel(DPLL_LOCK|APLL_LOCK, CM_CLKEN_PLL); /* enable apll */ + wait_on_value(BIT8, BIT8, CM_IDLEST_CKGEN, LDELAY); /* wait for apll lock */ + sdelay(1000); +} + +/************************************************************************** + * make_cs1_contiguous() - for es2 and above remap cs1 behind cs0 to allow + * command line mem=xyz use all memory with out discontigious support + * compiled in. Could do it at the ATAG, but there really is two banks... + * Called as part of 2nd phase DDR init. + **************************************************************************/ +void make_cs1_contiguous(void) +{ + u32 size, a_add_low, a_add_high; + + size = get_sdr_cs_size(SDRC_CS0_OSET); + size /= SZ_32M; /* find size to offset CS1 */ + a_add_high = (size & 3) << 8; /* set up low field */ + a_add_low = (size & 0x3C) >> 2; /* set up high field */ + __raw_writel((a_add_high|a_add_low),SDRC_CS_CFG); + +} + +/******************************************************** + * mem_ok() - test used to see if timings are correct + * for a part. Helps in gussing which part + * we are currently using. + *******************************************************/ +u32 mem_ok(void) +{ + u32 val1, val2; + u32 pattern = 0x12345678; + + __raw_writel(0x0,OMAP2420_SDRC_CS0+0x400); /* clear pos A */ + __raw_writel(pattern, OMAP2420_SDRC_CS0); /* pattern to pos B */ + __raw_writel(0x0,OMAP2420_SDRC_CS0+4); /* remove pattern off the bus */ + val1 = __raw_readl(OMAP2420_SDRC_CS0+0x400); /* get pos A value */ + val2 = __raw_readl(OMAP2420_SDRC_CS0); /* get val2 */ + + if ((val1 != 0) || (val2 != pattern)) /* see if pos A value changed*/ + return(0); + else + return(1); +} + + +/******************************************************** + * sdrc_init() - init the sdrc chip selects CS0 and CS1 + * - early init routines, called from flash or + * SRAM. + *******************************************************/ +void sdrc_init(void) +{ + #define EARLY_INIT 1 + do_sdrc_init(SDRC_CS0_OSET, EARLY_INIT); /* only init up first bank here */ +} + +/************************************************************************* + * do_sdrc_init(): initialize the SDRAM for use. + * -called from low level code with stack only. + * -code sets up SDRAM timing and muxing for 2422 or 2420. + * -optimal settings can be placed here, or redone after i2c + * inspection of board info + * + * This is a bit ugly, but should handle all memory moduels + * used with the H4. The first time though this code from s_init() + * we configure the first chip select. Later on we come back and + * will configure the 2nd chip select if it exists. + * + **************************************************************************/ +void do_sdrc_init(u32 offset, u32 early) +{ + u32 cpu, dllen=0, rev, common=0, cs0=0, pmask=0, pass_type, mtype; + sdrc_data_t *sdata; /* do not change type */ + u32 a, b, r; + + static const sdrc_data_t sdrc_2422 = + { + H4_2422_SDRC_SHARING, H4_2422_SDRC_MDCFG_0_DDR, 0 , H4_2422_SDRC_ACTIM_CTRLA_0, + H4_2422_SDRC_ACTIM_CTRLB_0, H4_2422_SDRC_RFR_CTRL, H4_2422_SDRC_MR_0_DDR, + 0, H4_2422_SDRC_DLLAB_CTRL + }; + static const sdrc_data_t sdrc_2420 = + { + H4_2420_SDRC_SHARING, H4_2420_SDRC_MDCFG_0_DDR, H4_2420_SDRC_MDCFG_0_SDR, + H4_2420_SDRC_ACTIM_CTRLA_0, H4_2420_SDRC_ACTIM_CTRLB_0, + H4_2420_SDRC_RFR_CTRL, H4_2420_SDRC_MR_0_DDR, H4_2420_SDRC_MR_0_SDR, + H4_2420_SDRC_DLLAB_CTRL + }; + + if (offset == SDRC_CS0_OSET) + cs0 = common = 1; /* int regs shared between both chip select */ + + cpu = get_cpu_type(); + rev = get_cpu_rev(); + + /* warning generated, though code generation is correct. this may bite later, + * but is ok for now. there is only so much C code you can do on stack only + * operation. + */ + if (cpu == CPU_2422){ + sdata = (sdrc_data_t *)&sdrc_2422; + pass_type = STACKED; + } else{ + sdata = (sdrc_data_t *)&sdrc_2420; + pass_type = IP_DDR; + } + + __asm__ __volatile__("": : :"memory"); /* limit compiler scope */ + + /* u-boot is compiled to run in DDR or SRAM at 8xxxxxxx or 4xxxxxxx. + * If we are running in flash prior to relocation and we use data + * here which is not pc relative we need to get the address correct. + * We need to find the current flash mapping to dress up the initial + * pointer load. As long as this is const data we should be ok. + */ + if((early) && running_in_flash()){ + sdata = (sdrc_data_t *)(((u32)sdata & 0x0003FFFF) | get_gpmc0_base()); + /* NOR internal boot offset is 0x4000 from xloader signature */ + if(running_from_internal_boot()) + sdata = (sdrc_data_t *)((u32)sdata + 0x4000); + } + + if (!early && (((mtype = get_mem_type()) == DDR_COMBO)||(mtype == DDR_STACKED))) { + if(mtype == DDR_COMBO){ + pmask = BIT2;/* combo part has a shared CKE signal, can't use feature */ + pass_type = COMBO_DDR; /* CS1 config */ + __raw_writel((__raw_readl(SDRC_POWER)) & ~pmask, SDRC_POWER); + } + if(rev != CPU_2420_2422_ES1) /* for es2 and above smooth things out */ + make_cs1_contiguous(); + } + +next_mem_type: + if (common) { /* do a SDRC reset between types to clear regs*/ + __raw_writel(SOFTRESET, SDRC_SYSCONFIG); /* reset sdrc */ + wait_on_value(BIT0, BIT0, SDRC_STATUS, 12000000);/* wait till reset done set */ + __raw_writel(0, SDRC_SYSCONFIG); /* clear soft reset */ + __raw_writel(sdata->sdrc_sharing, SDRC_SHARING); +#ifdef POWER_SAVE + __raw_writel(__raw_readl(SMS_SYSCONFIG)|SMART_IDLE, SMS_SYSCONFIG); + __raw_writel(sdata->sdrc_sharing|SMART_IDLE, SDRC_SHARING); + __raw_writel((__raw_readl(SDRC_POWER)|BIT6), SDRC_POWER); +#endif + } + + if ((pass_type == IP_DDR) || (pass_type == STACKED)) /* (IP ddr-CS0),(2422-CS0/CS1) */ + __raw_writel(sdata->sdrc_mdcfg_0_ddr, SDRC_MCFG_0+offset); + else if (pass_type == COMBO_DDR){ /* (combo-CS0/CS1) */ + __raw_writel(H4_2420_COMBO_MDCFG_0_DDR,SDRC_MCFG_0+offset); + } else if (pass_type == IP_SDR){ /* ip sdr-CS0 */ + __raw_writel(sdata->sdrc_mdcfg_0_sdr, SDRC_MCFG_0+offset); + } + + a = sdata->sdrc_actim_ctrla_0; + b = sdata->sdrc_actim_ctrlb_0; + r = sdata->sdrc_dllab_ctrl; + + /* work around ES1 DDR issues */ + if((pass_type != IP_SDR) && (rev == CPU_2420_2422_ES1)){ + a = H4_242x_SDRC_ACTIM_CTRLA_0_ES1; + b = H4_242x_SDRC_ACTIM_CTRLB_0_ES1; + r = H4_242x_SDRC_RFR_CTRL_ES1; + } + + if (cs0) { + __raw_writel(a, SDRC_ACTIM_CTRLA_0); + __raw_writel(b, SDRC_ACTIM_CTRLB_0); + } else { + __raw_writel(a, SDRC_ACTIM_CTRLA_1); + __raw_writel(b, SDRC_ACTIM_CTRLB_1); + } + __raw_writel(r, SDRC_RFR_CTRL+offset); + + /* init sequence for mDDR/mSDR using manual commands (DDR is a bit different) */ + __raw_writel(CMD_NOP, SDRC_MANUAL_0+offset); + sdelay(5000); /* susposed to be 100us per design spec for mddr/msdr */ + __raw_writel(CMD_PRECHARGE, SDRC_MANUAL_0+offset); + __raw_writel(CMD_AUTOREFRESH, SDRC_MANUAL_0+offset); + __raw_writel(CMD_AUTOREFRESH, SDRC_MANUAL_0+offset); + + /* + * CSx SDRC Mode Register + * Burst length = (4 - DDR) (2-SDR) + * Serial mode + * CAS latency = x + */ + if(pass_type == IP_SDR) + __raw_writel(sdata->sdrc_mr_0_sdr, SDRC_MR_0+offset); + else + __raw_writel(sdata->sdrc_mr_0_ddr, SDRC_MR_0+offset); + + /* NOTE: ES1 242x _BUG_ DLL + External Bandwidth fix*/ + if (rev == CPU_2420_2422_ES1){ + dllen = (BIT0|BIT3); /* es1 clear both bit0 and bit3 */ + __raw_writel((__raw_readl(SMS_CLASS_ARB0)|BURSTCOMPLETE_GROUP7) + ,SMS_CLASS_ARB0);/* enable bust complete for lcd */ + } + else + dllen = BIT0|BIT1; /* es2, clear bit0, and 1 (set phase to 72) */ + + /* enable & load up DLL with good value for 75MHz, and set phase to 90 + * ES1 recommends 90 phase, ES2 recommends 72 phase. + */ + if (common && (pass_type != IP_SDR)) { + __raw_writel(sdata->sdrc_dllab_ctrl, SDRC_DLLA_CTRL); + __raw_writel(sdata->sdrc_dllab_ctrl & ~(BIT2|dllen), SDRC_DLLA_CTRL); + __raw_writel(sdata->sdrc_dllab_ctrl, SDRC_DLLB_CTRL); + __raw_writel(sdata->sdrc_dllab_ctrl & ~(BIT2|dllen) , SDRC_DLLB_CTRL); + } + sdelay(90000); + + if(mem_ok()) + return; /* STACKED, other configued type */ + ++pass_type; /* IPDDR->COMBODDR->IPSDR for CS0 */ + goto next_mem_type; +} + +/***************************************************** + * gpmc_init(): init gpmc bus + * Init GPMC for x16, MuxMode (SDRAM in x32). + * This code can only be executed from SRAM or SDRAM. + *****************************************************/ +void gpmc_init(void) +{ + u32 mux=0, mtype, mwidth, rev, tval; + + rev = get_cpu_rev(); + if (rev == CPU_2420_2422_ES1) + tval = 1; + else + tval = 0; /* disable bit switched meaning */ + + /* global settings */ + __raw_writel(0x10, GPMC_SYSCONFIG); /* smart idle */ + __raw_writel(0x0, GPMC_IRQENABLE); /* isr's sources masked */ + __raw_writel(tval, GPMC_TIMEOUT_CONTROL);/* timeout disable */ +#ifdef CFG_NAND_BOOT + __raw_writel(0x001, GPMC_CONFIG); /* set nWP, disable limited addr */ +#else + __raw_writel(0x111, GPMC_CONFIG); /* set nWP, disable limited addr */ +#endif + + /* discover bus connection from sysboot */ + if (is_gpmc_muxed() == GPMC_MUXED) + mux = BIT9; + mtype = get_gpmc0_type(); + mwidth = get_gpmc0_width(); + + /* setup cs0 */ + __raw_writel(0x0, GPMC_CONFIG7_0); /* disable current map */ + sdelay(1000); + +#ifdef CFG_NAND_BOOT + __raw_writel(H4_24XX_GPMC_CONFIG1_0|mtype|mwidth, GPMC_CONFIG1_0); +#else + __raw_writel(H4_24XX_GPMC_CONFIG1_0|mux|mtype|mwidth, GPMC_CONFIG1_0); +#endif + +#ifdef PRCM_CONFIG_III + __raw_writel(H4_24XX_GPMC_CONFIG2_0, GPMC_CONFIG2_0); +#endif + __raw_writel(H4_24XX_GPMC_CONFIG3_0, GPMC_CONFIG3_0); + __raw_writel(H4_24XX_GPMC_CONFIG4_0, GPMC_CONFIG4_0); +#ifdef PRCM_CONFIG_III + __raw_writel(H4_24XX_GPMC_CONFIG5_0, GPMC_CONFIG5_0); + __raw_writel(H4_24XX_GPMC_CONFIG6_0, GPMC_CONFIG6_0); +#endif + __raw_writel(H4_24XX_GPMC_CONFIG7_0, GPMC_CONFIG7_0);/* enable new mapping */ + sdelay(2000); + + /* setup cs1 */ + __raw_writel(0, GPMC_CONFIG7_1); /* disable any mapping */ + sdelay(1000); + __raw_writel(H4_24XX_GPMC_CONFIG1_1|mux, GPMC_CONFIG1_1); + __raw_writel(H4_24XX_GPMC_CONFIG2_1, GPMC_CONFIG2_1); + __raw_writel(H4_24XX_GPMC_CONFIG3_1, GPMC_CONFIG3_1); + __raw_writel(H4_24XX_GPMC_CONFIG4_1, GPMC_CONFIG4_1); + __raw_writel(H4_24XX_GPMC_CONFIG5_1, GPMC_CONFIG5_1); + __raw_writel(H4_24XX_GPMC_CONFIG6_1, GPMC_CONFIG6_1); + __raw_writel(H4_24XX_GPMC_CONFIG7_1, GPMC_CONFIG7_1); /* enable mapping */ + sdelay(2000); +} diff --git a/board/omap2420h4/omap2420h4.c b/board/omap2420h4/omap2420h4.c new file mode 100755 index 0000000..6ae1a49 --- /dev/null +++ b/board/omap2420h4/omap2420h4.c @@ -0,0 +1,868 @@ +/* + * (C) Copyright 2004 + * Texas Instruments, <www.ti.com> + * Richard Woodruff <r-woodruff2@ti.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 <common.h> +#include <asm/arch/omap2420.h> +#include <asm/io.h> +#include <asm/arch/bits.h> +#include <asm/arch/mux.h> +#include <asm/arch/sys_proto.h> +#include <asm/arch/sys_info.h> +#include <asm/arch/mem.h> +#include <i2c.h> +#include <asm/mach-types.h> +#if (CONFIG_COMMANDS & CFG_CMD_NAND) +#include <linux/mtd/nand.h> +extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE]; +#endif + + void wait_for_command_complete(unsigned int wd_base); + +/******************************************************* + * Routine: delay + * Description: spinning delay to use before udelay works + ******************************************************/ +static inline void delay (unsigned long loops) +{ + __asm__ volatile ("1:\n" "subs %0, %1, #1\n" + "bne 1b":"=r" (loops):"0" (loops)); +} + +/***************************************** + * Routine: board_init + * Description: Early hardware init. + *****************************************/ +int board_init (void) +{ + DECLARE_GLOBAL_DATA_PTR; + + gpmc_init(); /* in SRAM or SDRM, finish GPMC */ + + gd->bd->bi_arch_number = MACH_TYPE_OMAP_H4; /* board id for linux */ + gd->bd->bi_boot_params = (OMAP2420_SDRC_CS0+0x100); /* adress of boot parameters */ + + return 0; +} + +/********************************************************** + * Routine: try_unlock_sram() + * Description: If chip is GP type, unlock the SRAM for + * general use. + ***********************************************************/ +void try_unlock_sram(void) +{ + /* if GP device unlock device SRAM for general use */ + if (get_device_type() == GP_DEVICE) { + __raw_writel(0xFF, A_REQINFOPERM0); + __raw_writel(0xCFDE, A_READPERM0); + __raw_writel(0xCFDE, A_WRITEPERM0); + } +} + +/********************************************************** + * Routine: s_init + * Description: Does early system init of muxing and clocks. + * - Called path is with sram stack. + **********************************************************/ +void s_init(void) +{ + int in_sdram = running_in_sdram(); + + watchdog_init(); + set_muxconf_regs(); + delay(100); + try_unlock_sram(); + + if(!in_sdram) + prcm_init(); + + peripheral_enable(); + icache_enable(); + if (!in_sdram) + sdrc_init(); +} + +/******************************************************* + * Routine: misc_init_r + * Description: Init ethernet (done here so udelay works) + ********************************************************/ +int misc_init_r (void) +{ + ether_init(); /* better done here so timers are init'ed */ + return(0); +} + +/**************************************** + * Routine: watchdog_init + * Description: Shut down watch dogs + *****************************************/ +void watchdog_init(void) +{ + /* There are 4 watch dogs. 1 secure, and 3 general purpose. + * The ROM takes care of the secure one. Of the 3 GP ones, + * 1 can reset us directly, the other 2 only generate MPU interrupts. + */ + __raw_writel(WD_UNLOCK1 ,WD2_BASE+WSPR); + wait_for_command_complete(WD2_BASE); + __raw_writel(WD_UNLOCK2 ,WD2_BASE+WSPR); + +#if MPU_WD_CLOCKED /* value 0x10 stick on aptix, BIT4 polarity seems oppsite*/ + __raw_writel(WD_UNLOCK1 ,WD3_BASE+WSPR); + wait_for_command_complete(WD3_BASE); + __raw_writel(WD_UNLOCK2 ,WD3_BASE+WSPR); + + __raw_writel(WD_UNLOCK1 ,WD4_BASE+WSPR); + wait_for_command_complete(WD4_BASE); + __raw_writel(WD_UNLOCK2 ,WD4_BASE+WSPR); +#endif +} + +/****************************************************** + * Routine: wait_for_command_complete + * Description: Wait for posting to finish on watchdog + ******************************************************/ +void wait_for_command_complete(unsigned int wd_base) +{ + int pending = 1; + do { + pending = __raw_readl(wd_base+WWPS); + } while (pending); +} + +/******************************************************************* + * Routine:ether_init + * Description: take the Ethernet controller out of reset and wait + * for the EEPROM load to complete. + ******************************************************************/ +void ether_init (void) +{ +#ifdef CONFIG_DRIVER_LAN91C96 + int cnt = 20; + + __raw_writeb(0x3,OMAP2420_CTRL_BASE+0x10a); /*protect->gpio95 */ + + __raw_writew(0x0, LAN_RESET_REGISTER); + do { + __raw_writew(0x1, LAN_RESET_REGISTER); + udelay (100); + if (cnt == 0) + goto h4reset_err_out; + --cnt; + } while (__raw_readw(LAN_RESET_REGISTER) != 0x1); + + cnt = 20; + + do { + __raw_writew(0x0, LAN_RESET_REGISTER); + udelay (100); + if (cnt == 0) + goto h4reset_err_out; + --cnt; + } while (__raw_readw(LAN_RESET_REGISTER) != 0x0000); + udelay (1000); + + *((volatile unsigned char *) ETH_CONTROL_REG) &= ~0x01; + udelay (1000); + + h4reset_err_out: + return; +#endif +} + +/********************************************** + * Routine: dram_init + * Description: sets uboots idea of sdram size + **********************************************/ +int dram_init (void) +{ + DECLARE_GLOBAL_DATA_PTR; + unsigned int size0=0,size1=0; + u32 mtype, btype, rev, cpu; + u8 chg_on = 0x5; /* enable charge of back up battery */ + u8 vmode_on = 0x8C; + #define NOT_EARLY 0 + + i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE); /* need this a bit early */ + + btype = get_board_type(); + mtype = get_mem_type(); + rev = get_cpu_rev(); + cpu = get_cpu_type(); + + display_board_info(btype); + if (btype == BOARD_H4_MENELAUS){ + update_mux(btype,mtype); /* combo part on menelaus */ + i2c_write(I2C_MENELAUS, 0x20, 1, &chg_on, 1); /*fix POR reset bug */ + i2c_write(I2C_MENELAUS, 0x2, 1, &vmode_on, 1); /* VCORE change on VMODE */ + } + + if ((mtype == DDR_COMBO) || (mtype == DDR_STACKED)) { + do_sdrc_init(SDRC_CS1_OSET, NOT_EARLY); /* init other chip select */ + } + size0 = get_sdr_cs_size(SDRC_CS0_OSET); + size1 = get_sdr_cs_size(SDRC_CS1_OSET); + + gd->bd->bi_dram[0].start = PHYS_SDRAM_1; + gd->bd->bi_dram[0].size = size0; + if(rev == CPU_2420_2422_ES1) /* ES1's 128MB remap granularity isn't worth doing */ + gd->bd->bi_dram[1].start = PHYS_SDRAM_2; + else /* ES2 and above can remap at 32MB granularity */ + gd->bd->bi_dram[1].start = PHYS_SDRAM_1+size0; + gd->bd->bi_dram[1].size = size1; + + return 0; +} + +/********************************************************** + * Routine: set_muxconf_regs + * Description: Setting up the configuration Mux registers + * specific to the hardware + *********************************************************/ +void set_muxconf_regs (void) +{ + muxSetupSDRC(); + muxSetupGPMC(); + muxSetupUsb0(); + muxSetupUart3(); + muxSetupI2C1(); + muxSetupUART1(); + muxSetupLCD(); + muxSetupCamera(); + muxSetupMMCSD(); + muxSetupTouchScreen(); + muxSetupHDQ(); +} + +/***************************************************************** + * Routine: peripheral_enable + * Description: Enable the clks & power for perifs (GPT2, UART1,...) + ******************************************************************/ +void peripheral_enable(void) +{ + unsigned int v, if_clks=0, func_clks=0; + + /* Enable GP2 timer.*/ + if_clks |= BIT4; + func_clks |= BIT4; + v = __raw_readl(CM_CLKSEL2_CORE) | 0x4; /* Sys_clk input OMAP2420_GPT2 */ + __raw_writel(v, CM_CLKSEL2_CORE); + __raw_writel(0x1, CM_CLKSEL_WKUP); + +#ifdef CFG_NS16550 + /* Enable UART1 clock */ + func_clks |= BIT21; + if_clks |= BIT21; +#endif + v = __raw_readl(CM_ICLKEN1_CORE) | if_clks; /* Interface clocks on */ + __raw_writel(v,CM_ICLKEN1_CORE ); + v = __raw_readl(CM_FCLKEN1_CORE) | func_clks; /* Functional Clocks on */ + __raw_writel(v, CM_FCLKEN1_CORE); + delay(1000); + +#ifndef KERNEL_UPDATED + { +#define V1 0xffffffff +#define V2 0x00000007 + + __raw_writel(V1, CM_FCLKEN1_CORE); + __raw_writel(V2, CM_FCLKEN2_CORE); + __raw_writel(V1, CM_ICLKEN1_CORE); + __raw_writel(V1, CM_ICLKEN2_CORE); + } +#endif +} + +/**************************************** + * Routine: muxSetupUsb0 (ostboot) + * Description: Setup usb muxing + *****************************************/ +void muxSetupUsb0(void) +{ + volatile uint8 *MuxConfigReg; + volatile uint32 *otgCtrlReg; + + MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_USB0_PUEN; + *MuxConfigReg &= (uint8)(~0x1F); + + MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_USB0_VP; + *MuxConfigReg &= (uint8)(~0x1F); + + MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_USB0_VM; + *MuxConfigReg &= (uint8)(~0x1F); + + MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_USB0_RCV; + *MuxConfigReg &= (uint8)(~0x1F); + + MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_USB0_TXEN; + *MuxConfigReg &= (uint8)(~0x1F); + + MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_USB0_SE0; + *MuxConfigReg &= (uint8)(~0x1F); + + MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_USB0_DAT; + *MuxConfigReg &= (uint8)(~0x1F); + + /* setup for USB VBus detection */ + otgCtrlReg = (volatile uint32 *)USB_OTG_CTRL; + *otgCtrlReg |= 0x00040000; /* bit 18 */ +} + +/**************************************** + * Routine: muxSetupUart3 (ostboot) + * Description: Setup uart3 muxing + *****************************************/ +void muxSetupUart3(void) +{ + volatile uint8 *MuxConfigReg; + + MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_UART3_TX_IRTX; + *MuxConfigReg &= (uint8)(~0x1F); + + MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_UART3_RX_IRRX; + *MuxConfigReg &= (uint8)(~0x1F); +} + +/**************************************** + * Routine: muxSetupI2C1 (ostboot) + * Description: Setup i2c muxing + *****************************************/ +void muxSetupI2C1(void) +{ + volatile unsigned char *MuxConfigReg; + + /* I2C1 Clock pin configuration, PIN = M19 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_I2C1_SCL; + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* I2C1 Data pin configuration, PIN = L15 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_I2C1_SDA; + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* Pull-up required on data line */ + /* external pull-up already present. */ + /* *MuxConfigReg |= 0x18 ;*/ /* Mode = 0, PullTypeSel=PU, PullUDEnable=Enabled */ +} + +/**************************************** + * Routine: muxSetupUART1 (ostboot) + * Description: Set up uart1 muxing + *****************************************/ +void muxSetupUART1(void) +{ + volatile unsigned char *MuxConfigReg; + + /* UART1_CTS pin configuration, PIN = D21 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_UART1_CTS; + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* UART1_RTS pin configuration, PIN = H21 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_UART1_RTS; + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* UART1_TX pin configuration, PIN = L20 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_UART1_TX; + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* UART1_RX pin configuration, PIN = T21 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_UART1_RX; + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ +} + +/**************************************** + * Routine: muxSetupLCD (ostboot) + * Description: Setup lcd muxing + *****************************************/ +void muxSetupLCD(void) +{ + volatile unsigned char *MuxConfigReg; + + /* LCD_D0 pin configuration, PIN = Y7 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D0; + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* LCD_D1 pin configuration, PIN = P10 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D1; + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* LCD_D2 pin configuration, PIN = V8 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D2; + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* LCD_D3 pin configuration, PIN = Y8 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D3; + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* LCD_D4 pin configuration, PIN = W8 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D4; + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* LCD_D5 pin configuration, PIN = R10 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D5; + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* LCD_D6 pin configuration, PIN = Y9 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D6; + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* LCD_D7 pin configuration, PIN = V9 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D7; + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* LCD_D8 pin configuration, PIN = W9 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D8; + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* LCD_D9 pin configuration, PIN = P11 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D9; + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* LCD_D10 pin configuration, PIN = V10 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D10; + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* LCD_D11 pin configuration, PIN = Y10 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D11; + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* LCD_D12 pin configuration, PIN = W10 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D12; + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* LCD_D13 pin configuration, PIN = R11 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D13; + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* LCD_D14 pin configuration, PIN = V11 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D14; + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* LCD_D15 pin configuration, PIN = W11 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D15; + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* LCD_D16 pin configuration, PIN = P12 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D16; + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* LCD_D17 pin configuration, PIN = R12 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D17; + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* LCD_PCLK pin configuration, PIN = W6 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_PCLK; + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* LCD_VSYNC pin configuration, PIN = V7 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_VSYNC; + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* LCD_HSYNC pin configuration, PIN = Y6 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_HSYNC; + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* LCD_ACBIAS pin configuration, PIN = W7 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_ACBIAS; + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ +} + +/**************************************** + * Routine: muxSetupCamera (ostboot) + * Description: Setup camera muxing + *****************************************/ +void muxSetupCamera(void) +{ + volatile unsigned char *MuxConfigReg; + + /* CAMERA_RSTZ pin configuration, PIN = Y16 */ + /* CAM_RST is connected through the I2C IO expander.*/ + /* MuxConfigReg = (volatile unsigned char *), CONTROL_PADCONF_SYS_NRESWARM*/ + /* *MuxConfigReg = 0x00 ; / * Mode = 0, PUPD=Disabled */ + + /* CAMERA_XCLK pin configuration, PIN = U3 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_XCLK; + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* CAMERA_LCLK pin configuration, PIN = V5 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_LCLK; + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* CAMERA_VSYNC pin configuration, PIN = U2 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_VS, + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* CAMERA_HSYNC pin configuration, PIN = T3 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_HS, + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* CAMERA_DAT0 pin configuration, PIN = T4 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_D0, + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* CAMERA_DAT1 pin configuration, PIN = V2 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_D1, + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* CAMERA_DAT2 pin configuration, PIN = V3 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_D2, + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* CAMERA_DAT3 pin configuration, PIN = U4 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_D3, + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* CAMERA_DAT4 pin configuration, PIN = W2 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_D4, + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* CAMERA_DAT5 pin configuration, PIN = V4 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_D5, + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* CAMERA_DAT6 pin configuration, PIN = W3 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_D6, + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* CAMERA_DAT7 pin configuration, PIN = Y2 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_D7, + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* CAMERA_DAT8 pin configuration, PIN = Y4 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_D8, + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* CAMERA_DAT9 pin configuration, PIN = V6 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_D9, + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ +} + +/**************************************** + * Routine: muxSetupMMCSD (ostboot) + * Description: set up MMC muxing + *****************************************/ +void muxSetupMMCSD(void) +{ + volatile unsigned char *MuxConfigReg; + + /* SDMMC_CLKI pin configuration, PIN = H15 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_MMC_CLKI, + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* SDMMC_CLKO pin configuration, PIN = G19 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_MMC_CLKO, + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* SDMMC_CMD pin configuration, PIN = H18 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_MMC_CMD, + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + /* External pull-ups are present. */ + /* *MuxConfigReg |= 0x18 ; #/ PullUDEnable=Enabled, PullTypeSel=PU */ + + /* SDMMC_DAT0 pin configuration, PIN = F20 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_MMC_DAT0, + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + /* External pull-ups are present. */ + /* *MuxConfigReg |= 0x18 ; #/ PullUDEnable=Enabled, PullTypeSel=PU */ + + /* SDMMC_DAT1 pin configuration, PIN = H14 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_MMC_DAT1, + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + /* External pull-ups are present. */ + /* *MuxConfigReg |= 0x18 ; #/ PullUDEnable=Enabled, PullTypeSel=PU */ + + /* SDMMC_DAT2 pin configuration, PIN = E19 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_MMC_DAT2, + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + /* External pull-ups are present. */ + /* *MuxConfigReg |= 0x18 ; #/ PullUDEnable=Enabled, PullTypeSel=PU */ + + /* SDMMC_DAT3 pin configuration, PIN = D19 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_MMC_DAT3, + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + /* External pull-ups are present. */ + /* *MuxConfigReg |= 0x18 ; #/ PullUDEnable=Enabled, PullTypeSel=PU */ + + /* SDMMC_DDIR0 pin configuration, PIN = F19 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_MMC_DAT_DIR0, + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* SDMMC_DDIR1 pin configuration, PIN = E20 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_MMC_DAT_DIR1, + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* SDMMC_DDIR2 pin configuration, PIN = F18 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_MMC_DAT_DIR2, + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* SDMMC_DDIR3 pin configuration, PIN = E18 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_MMC_DAT_DIR3, + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* SDMMC_CDIR pin configuration, PIN = G18 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_MMC_CMD_DIR, + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* MMC_CD pin configuration, PIN = B3 ---2420IP ONLY---*/ + /* MMC_CD for 2422IP=K1 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_SDRC_A14, + *MuxConfigReg = 0x03 ; /* Mode = 3, PUPD=Disabled */ + + /* MMC_WP pin configuration, PIN = B4 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_SDRC_A13, + *MuxConfigReg = 0x03 ; /* Mode = 3, PUPD=Disabled */ +} + +/****************************************** + * Routine: muxSetupTouchScreen (ostboot) + * Description: Set up touch screen muxing + *******************************************/ +void muxSetupTouchScreen(void) +{ + volatile unsigned char *MuxConfigReg; + + /* SPI1_CLK pin configuration, PIN = U18 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_SPI1_CLK, + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* SPI1_MOSI pin configuration, PIN = V20 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_SPI1_SIMO, + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* SPI1_MISO pin configuration, PIN = T18 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_SPI1_SOMI, + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* SPI1_nCS0 pin configuration, PIN = U19 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_SPI1_NCS0, + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* PEN_IRQ pin configuration, PIN = P20 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_MCBSP1_FSR, + *MuxConfigReg = 0x03 ; /* Mode = 3, PUPD=Disabled */ +} + +/**************************************** + * Routine: muxSetupHDQ (ostboot) + * Description: setup 1wire mux + *****************************************/ +void muxSetupHDQ(void) +{ + volatile unsigned char *MuxConfigReg; + + /* HDQ_SIO pin configuration, PIN = N18 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_HDQ_SIO, + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ +} + +/*************************************************************** + * Routine: muxSetupGPMC (ostboot) + * Description: Configures balls which cam up in protected mode + ***************************************************************/ +void muxSetupGPMC(void) +{ + volatile uint8 *MuxConfigReg; + volatile unsigned int *MCR = (volatile unsigned int *)0x4800008C; + + /* gpmc_io_dir */ + *MCR = 0x19000000; + + /* NOR FLASH CS0 */ + /* signal - Gpmc_clk; pin - J4; offset - 0x0088; mode - 0; Byte-3 Pull/up - N/A */ + MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_GPMC_D2_BYTE3, + *MuxConfigReg = 0x00 ; + + /* signal - Gpmc_iodir; pin - n2; offset - 0x008C; mode - 1; Byte-3 Pull/up - N/A */ + MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_GPMC_NCS0_BYTE3, + *MuxConfigReg = 0x01 ; + + /* MPDB(Multi Port Debug Port) CS1 */ + /* signal - gpmc_ncs1; pin - N8; offset - 0x008C; mode - 0; Byte-1 Pull/up - N/A */ + MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_GPMC_NCS0_BYTE1, + *MuxConfigReg = 0x00 ; + + /* signal - Gpmc_ncs2; pin - E2; offset - 0x008C; mode - 0; Byte-2 Pull/up - N/A */ + MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_GPMC_NCS0_BYTE2, + *MuxConfigReg = 0x00 ; +} + +/**************************************************************** + * Routine: muxSetupSDRC (ostboot) + * Description: Configures balls which come up in protected mode + ****************************************************************/ +void muxSetupSDRC(void) +{ + volatile uint8 *MuxConfigReg; + + /* signal - sdrc_ncs1; pin - C12; offset - 0x00A0; mode - 0; Byte-1 Pull/up - N/A */ + MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_SDRC_NCS0_BYTE1, + *MuxConfigReg = 0x00 ; + + /* signal - sdrc_a12; pin - D11; offset - 0x0030; mode - 0; Byte-2 Pull/up - N/A */ + MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_SDRC_A14_BYTE2, + *MuxConfigReg = 0x00 ; + + /* signal - sdrc_cke1; pin - B13; offset - 0x00A0; mode - 0; Byte-3 Pull/up - N/A */ + MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_SDRC_NCS0_BYTE3, + *MuxConfigReg = 0x00; + + if (get_cpu_type() == CPU_2422) { + MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_SDRC_A14_BYTE0, + *MuxConfigReg = 0x1b; + } +} + +/***************************************************************************** + * Routine: update_mux() + * Description: Update balls which are different beween boards. All should be + * updated to match functionaly. However, I'm only updating ones + * which I'll be using for now. When power comes into play they + * all need updating. + *****************************************************************************/ +void update_mux(u32 btype,u32 mtype) +{ + u32 cpu, base = OMAP2420_CTRL_BASE; + cpu = get_cpu_type(); + + if (btype == BOARD_H4_MENELAUS) { + if (cpu == CPU_2420) { + /* PIN = B3, GPIO.0->KBR5, mode 3, (pun?),-DO-*/ + __raw_writeb(0x3, base+0x30); + /* PIN = B13, GPIO.38->KBC6, mode 3, (pun?)-DO-*/ + __raw_writeb(0x3, base+0xa3); + /* PIN = F1, GPIO.25->HSUSBxx mode 3, (for external HS USB)*/ + /* PIN = H1, GPIO.26->HSUSBxx mode 3, (for external HS USB)*/ + /* PIN = K1, GPMC_ncs6 mode 0, (on board nand access)*/ + /* PIN = L2, GPMC_ncs67 mode 0, (for external HS USB)*/ + /* PIN = M1 (HSUSBOTG) */ + /* PIN = P1, GPIO.35->MEN_POK mode 3, (menelaus powerok)-DO-*/ + __raw_writeb(0x3, base+0x9d); + /* PIN = U32, (WLAN_CLKREQ) */ + /* PIN = Y11, WLAN */ + /* PIN = AA4, GPIO.15->KBC2, mode 3, -DO- */ + __raw_writeb(0x3, base+0xe7); + /* PIN = AA8, mDOC */ + /* PIN = AA10, BT */ + /* PIN = AA13, WLAN */ + /* PIN = M18 GPIO.96->MMC2_WP mode 3 -DO- */ + __raw_writeb(0x3, base+0x10e); + /* PIN = N19 GPIO.98->WLAN_INT mode 3 -DO- */ + __raw_writeb(0x3, base+0x110); + /* PIN = J15 HHUSB */ + /* PIN = H19 HSUSB */ + /* PIN = W13, P13, R13, W16 ... */ + /* PIN = V12 GPIO.25->I2C_CAMEN mode 3 -DO- */ + __raw_writeb(0x3, base+0xde); + /* PIN = W19 sys_nirq->MENELAUS_INT mode 0 -DO- */ + __raw_writeb(0x0, base+0x12c); + /* PIN = AA17->sys_clkreq mode 0 -DO- */ + __raw_writeb(0x0, base+0x136); + } else if (cpu == CPU_2422) { + /* PIN = B3, GPIO.0->nc, mode 3, set above (pun?)*/ + /* PIN = B13, GPIO.cke1->nc, mode 0, set above, (pun?)*/ + /* PIN = F1, GPIO.25->HSUSBxx mode 3, (for external HS USB)*/ + /* PIN = H1, GPIO.26->HSUSBxx mode 3, (for external HS USB)*/ + /* PIN = K1, GPMC_ncs6 mode 0, (on board nand access)*/ + __raw_writeb(0x0, base+0x92); + /* PIN = L2, GPMC_ncs67 mode 0, (for external HS USB)*/ + /* PIN = M1 (HSUSBOTG) */ + /* PIN = P1, GPIO.35->MEN_POK mode 3, (menelaus powerok)-DO-*/ + __raw_writeb(0x3, base+0x10c); + /* PIN = U32, (WLAN_CLKREQ) */ + /* PIN = AA4, GPIO.15->KBC2, mode 3, -DO- */ + __raw_writeb(0x3, base+0x30); + /* PIN = AA8, mDOC */ + /* PIN = AA10, BT */ + /* PIN = AA12, WLAN */ + /* PIN = M18 GPIO.96->MMC2_WP mode 3 -DO- */ + __raw_writeb(0x3, base+0x10e); + /* PIN = N19 GPIO.98->WLAN_INT mode 3 -DO- */ + __raw_writeb(0x3, base+0x110); + /* PIN = J15 HHUSB */ + /* PIN = H19 HSUSB */ + /* PIN = W13, P13, R13, W16 ... */ + /* PIN = V12 GPIO.25->I2C_CAMEN mode 3 -DO- */ + __raw_writeb(0x3, base+0xde); + /* PIN = W19 sys_nirq->MENELAUS_INT mode 0 -DO- */ + __raw_writeb(0x0, base+0x12c); + /* PIN = AA17->sys_clkreq mode 0 -DO- */ + __raw_writeb(0x0, base+0x136); + } + + } else if (btype == BOARD_H4_SDP) { + if (cpu == CPU_2420) { + /* PIN = B3, GPIO.0->nc mode 3, set above (pun?)*/ + /* PIN = B13, GPIO.cke1->nc, mode 0, set above, (pun?)*/ + /* Pin = Y11 VLNQ */ + /* Pin = AA4 VLNQ */ + /* Pin = AA6 VLNQ */ + /* Pin = AA8 VLNQ */ + /* Pin = AA10 VLNQ */ + /* Pin = AA12 VLNQ */ + /* PIN = M18 GPIO.96->KBR5 mode 3 -DO- */ + __raw_writeb(0x3, base+0x10e); + /* PIN = N19 GPIO.98->KBC6 mode 3 -DO- */ + __raw_writeb(0x3, base+0x110); + /* PIN = J15 MDOC_nDMAREQ */ + /* PIN = H19 GPIO.100->KBC2 mode 3 -DO- */ + __raw_writeb(0x3, base+0x114); + /* PIN = W13, V12, P13, R13, W19, W16 ... */ + /* PIN = AA17 sys_clkreq->bt_clk_req mode 0 */ + } else if (cpu == CPU_2422) { + /* PIN = B3, GPIO.0->MMC_CD, mode 3, set above */ + /* PIN = B13, GPIO.38->wlan_int, mode 3, (pun?)*/ + /* Pin = Y11 VLNQ */ + /* Pin = AA4 VLNQ */ + /* Pin = AA6 VLNQ */ + /* Pin = AA8 VLNQ */ + /* Pin = AA10 VLNQ */ + /* Pin = AA12 VLNQ */ + /* PIN = M18 GPIO.96->KBR5 mode 3 -DO- */ + __raw_writeb(0x3, base+0x10e); + /* PIN = N19 GPIO.98->KBC6 mode 3 -DO- */ + __raw_writeb(0x3, base+0x110); + /* PIN = J15 MDOC_nDMAREQ */ + /* PIN = H19 GPIO.100->KBC2 mode 3 -DO- */ + __raw_writeb(0x3, base+0x114); + /* PIN = W13, V12, P13, R13, W19, W16 ... */ + /* PIN = AA17 sys_clkreq->bt_clk_req mode 0 */ + } + } +} + +#if (CONFIG_COMMANDS & CFG_CMD_NAND) +void nand_init(void) +{ + extern flash_info_t flash_info[]; + + nand_probe(CFG_NAND_ADDR); + if (nand_dev_desc[0].ChipID != NAND_ChipID_UNKNOWN) { + print_size(nand_dev_desc[0].totlen, "\n"); + } + +#ifdef CFG_JFFS2_MEM_NAND + flash_info[CFG_JFFS2_FIRST_BANK].flash_id = nand_dev_desc[0].id; + flash_info[CFG_JFFS2_FIRST_BANK].size = 1024*1024*2; /* only read kernel single meg partition */ + flash_info[CFG_JFFS2_FIRST_BANK].sector_count = 1024; /* 1024 blocks in 16meg chip (use less for raw/copied partition) */ + flash_info[CFG_JFFS2_FIRST_BANK].start[0] = 0x80200000; /* ?, ram for now, open question, copy to RAM or adapt for NAND */ +#endif +} +#endif diff --git a/board/omap2420h4/sys_info.c b/board/omap2420h4/sys_info.c new file mode 100755 index 0000000..a9f7241 --- /dev/null +++ b/board/omap2420h4/sys_info.c @@ -0,0 +1,387 @@ +/* + * (C) Copyright 2004 + * Texas Instruments, <www.ti.com> + * Richard Woodruff <r-woodruff2@ti.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/arch/omap2420.h> +#include <asm/io.h> +#include <asm/arch/bits.h> +#include <asm/arch/mem.h> /* get mem tables */ +#include <asm/arch/sys_proto.h> +#include <asm/arch/sys_info.h> +#include <i2c.h> + +/************************************************************************** + * get_prod_id() - get id info from chips + ***************************************************************************/ +static u32 get_prod_id(void) +{ + u32 p; + p = __raw_readl(PRODUCTION_ID); /* get production ID */ + return((p & CPU_242X_PID_MASK) >> 16); +} + +/************************************************************************** + * get_cpu_type() - low level get cpu type + * - no C globals yet. + * - just looking to say if this is a 2422 or 2420 or ... + * - to start with we will look at switch settings.. + * - 2422 id's same as 2420 for ES1 will rely on H4 board characteristics + * (mux for 2420, non-mux for 2422). + ***************************************************************************/ +u32 get_cpu_type(void) +{ + u32 v; + + switch(get_prod_id()){ + case 1:;/* 2420 */ + case 2: return(CPU_2420); break; /* 2420 pop */ + case 4: return(CPU_2422); break; + case 8: return(CPU_2423); break; + default: break; /* early 2420/2422's unmarked */ + } + + v = __raw_readl(TAP_IDCODE_REG); + v &= CPU_24XX_ID_MASK; + if (v == CPU_2420_CHIPID) { /* currently 2420 and 2422 have same id */ + if (is_gpmc_muxed() == GPMC_MUXED) /* if mux'ed */ + return(CPU_2420); + else + return(CPU_2422); + } else + return(CPU_2420); /* don't know, say 2420 */ +} + +/****************************************** + * get_cpu_rev(void) - extract version info + ******************************************/ +u32 get_cpu_rev(void) +{ + u32 v; + v = __raw_readl(TAP_IDCODE_REG); + v = v >> 28; + return(v+1); /* currently 2422 and 2420 match up */ +} +/**************************************************** + * is_mem_sdr() - return 1 if mem type in use is SDR + ****************************************************/ +u32 is_mem_sdr(void) +{ + volatile u32 *burst = (volatile u32 *)(SDRC_MR_0+SDRC_CS0_OSET); + if(*burst == H4_2420_SDRC_MR_0_SDR) + return(1); + return(0); +} + +/*********************************************************** + * get_mem_type() - identify type of mDDR part used. + * 2422 uses stacked DDR, 2 parts CS0/CS1. + * 2420 may have 1 or 2, no good way to know...only init 1... + * when eeprom data is up we can select 1 more. + *************************************************************/ +u32 get_mem_type(void) +{ + u32 cpu, sdr = is_mem_sdr(); + + cpu = get_cpu_type(); + if (cpu == CPU_2422 || cpu == CPU_2423) + return(DDR_STACKED); + + if(get_prod_id() == 0x2) + return(XDR_POP); + + if (get_board_type() == BOARD_H4_MENELAUS) + if(sdr) + return(SDR_DISCRETE); + else + return(DDR_COMBO); + else + if(sdr) /* SDP + SDR kit */ + return(SDR_DISCRETE); + else + return(DDR_DISCRETE); /* origional SDP */ +} + +/*********************************************************************** + * get_cs0_size() - get size of chip select 0/1 + ************************************************************************/ +u32 get_sdr_cs_size(u32 offset) +{ + u32 size; + size = __raw_readl(SDRC_MCFG_0+offset) >> 8; /* get ram size field */ + size &= 0x2FF; /* remove unwanted bits */ + size *= SZ_2M; /* find size in MB */ + return(size); +} + +/*********************************************************************** + * get_board_type() - get board type based on current production stats. + * --- NOTE: 2 I2C EEPROMs will someday be populated with proper info. + * when they are available we can get info from there. This should + * be correct of all known boards up until today. + ************************************************************************/ +u32 get_board_type(void) +{ + if (i2c_probe(I2C_MENELAUS) == 0) + return(BOARD_H4_MENELAUS); + else + return(BOARD_H4_SDP); +} + +/****************************************************************** + * get_sysboot_value() - get init word settings (dip switch on h4) + ******************************************************************/ +inline u32 get_sysboot_value(void) +{ + return(0x00000FFF & __raw_readl(CONTROL_STATUS)); +} + +/*************************************************************************** + * get_gpmc0_base() - Return current address hardware will be + * fetching from. The below effectively gives what is correct, its a bit + * mis-leading compared to the TRM. For the most general case the mask + * needs to be also taken into account this does work in practice. + * - for u-boot we currently map: + * -- 0 to nothing, + * -- 4 to flash + * -- 8 to enent + * -- c to wifi + ****************************************************************************/ +u32 get_gpmc0_base(void) +{ + u32 b; + + b = __raw_readl(GPMC_CONFIG7_0); + b &= 0x1F; /* keep base [5:0] */ + b = b << 24; /* ret 0x0b000000 */ + return(b); +} + +/***************************************************************** + * is_gpmc_muxed() - tells if address/data lines are multiplexed + *****************************************************************/ +u32 is_gpmc_muxed(void) +{ + u32 mux; + mux = get_sysboot_value(); + if ((mux & (BIT0 | BIT1 | BIT2 | BIT3)) == (BIT0 | BIT2 | BIT3)) + return(GPMC_MUXED); /* NAND Boot mode */ + if (mux & BIT1) /* if mux'ed */ + return(GPMC_MUXED); + else + return(GPMC_NONMUXED); +} + +/************************************************************************ + * get_gpmc0_type() - read sysboot lines to see type of memory attached + ************************************************************************/ +u32 get_gpmc0_type(void) +{ + u32 type; + type = get_sysboot_value(); + if ((type & (BIT3|BIT2)) == (BIT3|BIT2)) + return(TYPE_NAND); + else + return(TYPE_NOR); +} + +/******************************************************************* + * get_gpmc0_width() - See if bus is in x8 or x16 (mainly for nand) + *******************************************************************/ +u32 get_gpmc0_width(void) +{ + u32 width; + width = get_sysboot_value(); + if ((width & 0xF) == (BIT3|BIT2)) + return(WIDTH_8BIT); + else + return(WIDTH_16BIT); +} + +/********************************************************************* + * wait_on_value() - common routine to allow waiting for changes in + * volatile regs. + *********************************************************************/ +u32 wait_on_value(u32 read_bit_mask, u32 match_value, u32 read_addr, u32 bound) +{ + u32 i = 0, val; + do { + ++i; + val = __raw_readl(read_addr) & read_bit_mask; + if (val == match_value) + return(1); + if (i==bound) + return(0); + } while (1); +} + +/********************************************************************* + * display_board_info() - print banner with board info. + *********************************************************************/ +void display_board_info(u32 btype) +{ + char cpu_2420[] = "2420"; /* cpu type */ + char cpu_2422[] = "2422"; + char cpu_2423[] = "2423"; + char db_men[] = "Menelaus"; /* board type */ + char db_ip[] = "IP"; + char mem_sdr[] = "mSDR"; /* memory type */ + char mem_ddr[] = "mDDR"; + char t_tst[] = "TST"; /* security level */ + char t_emu[] = "EMU"; + char t_hs[] = "HS"; + char t_gp[] = "GP"; + char unk[] = "?"; + + char *cpu_s, *db_s, *mem_s, *sec_s; + u32 cpu, rev, sec; + + rev = get_cpu_rev(); + cpu = get_cpu_type(); + sec = get_device_type(); + + if(is_mem_sdr()) + mem_s = mem_sdr; + else + mem_s = mem_ddr; + + if(cpu == CPU_2423) + cpu_s = cpu_2423; + else if (cpu == CPU_2422) + cpu_s = cpu_2422; + else + cpu_s = cpu_2420; + + if(btype == BOARD_H4_MENELAUS) + db_s = db_men; + else + db_s = db_ip; + + switch(sec){ + case TST_DEVICE: sec_s = t_tst; break; + case EMU_DEVICE: sec_s = t_emu; break; + case HS_DEVICE: sec_s = t_hs; break; + case GP_DEVICE: sec_s = t_gp; break; + default: sec_s = unk; + } + + printf("OMAP%s-%s revision %d\n", cpu_s, sec_s, rev-1); + printf("TI H4 SDP Base Board + %s Daughter Board + %s \n", db_s, mem_s); +} + +/************************************************************************* + * get_board_rev() - setup to pass kernel board revision information + * 0 = 242x IP platform (first 2xx boards) + * 1 = 242x Menelaus platfrom. + *************************************************************************/ +u32 get_board_rev(void) +{ + u32 rev = 0; + u32 btype = get_board_type(); + + if (btype == BOARD_H4_MENELAUS){ + rev = 1; + } + return(rev); +} + +/******************************************************** + * get_base(); get upper addr of current execution + *******************************************************/ +u32 get_base(void) +{ + u32 val; + __asm__ __volatile__("mov %0, pc \n" : "=r" (val) : : "memory"); + val &= 0xF0000000; + val >>= 28; + return(val); +} + +/******************************************************** + * get_base2(); get 2upper addr of current execution + *******************************************************/ +u32 get_base2(void) +{ + u32 val; + __asm__ __volatile__("mov %0, pc \n" : "=r" (val) : : "memory"); + val &= 0xFF000000; + val >>= 24; + return(val); +} + +/******************************************************** + * running_in_flash() - tell if currently running in + * flash. + *******************************************************/ +u32 running_in_flash(void) +{ + if (get_base() < 4) + return(1); /* in flash */ + return(0); /* running in SRAM or SDRAM */ +} + +/******************************************************** + * running_in_sram() - tell if currently running in + * sram. + *******************************************************/ +u32 running_in_sram(void) +{ + if (get_base() == 4) + return(1); /* in SRAM */ + return(0); /* running in FLASH or SDRAM */ +} +/******************************************************** + * running_in_sdram() - tell if currently running in + * flash. + *******************************************************/ +u32 running_in_sdram(void) +{ + if (get_base() > 4) + return(1); /* in sdram */ + return(0); /* running in SRAM or FLASH */ +} + +/************************************************************* + * running_from_internal_boot() - am I a signed NOR image. + *************************************************************/ +u32 running_from_internal_boot(void) +{ + u32 v, base; + + v = get_sysboot_value() & BIT3; + base = get_base2(); + /* if running at mask rom flash address and + * sysboot3 says this was an internal boot + */ + if ((base == 0x08) && v) + return(1); + else + return(0); +} + +/************************************************************* + * get_device_type(): tell if GP/HS/EMU/TST + *************************************************************/ +u32 get_device_type(void) +{ + int mode; + mode = __raw_readl(CONTROL_STATUS) & (BIT10|BIT9|BIT8); + return(mode >>= 8); +} diff --git a/board/omap2420h4/u-boot.lds b/board/omap2420h4/u-boot.lds new file mode 100755 index 0000000..1460adc --- /dev/null +++ b/board/omap2420h4/u-boot.lds @@ -0,0 +1,59 @@ +/* + * January 2004 - Changed to support H4 device + * Copyright (c) 2004 Texas Instruments + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, <gj@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 + */ + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + . = 0x00000000; + + . = ALIGN(4); + .text : + { + cpu/arm1136/start.o (.text) + *(.text) + } + + . = ALIGN(4); + .rodata : { *(.rodata) } + + . = ALIGN(4); + .data : { *(.data) } + + . = ALIGN(4); + .got : { *(.got) } + + . = .; + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + . = ALIGN(4); + __bss_start = .; + .bss : { *(.bss) } + _end = .; +} |