From 8ed9604613398660f9ee855060661da8809d4045 Mon Sep 17 00:00:00 2001 From: wdenk Date: Sun, 9 Jan 2005 23:16:25 +0000 Subject: * Patches by Richard Woodruff, 01 Oct 2004: add support for the TI OMAP2420 processor and its H4 reference board * Patch by Christian Pellegrin, 24 Sep 2004: Added support for NE2000 compatible (DP8390, DP83902) NICs. --- board/omap2420h4/Makefile | 47 +++ board/omap2420h4/config.mk | 26 ++ board/omap2420h4/flash.c | 536 +++++++++++++++++++++++++++ board/omap2420h4/mem.c | 306 ++++++++++++++++ board/omap2420h4/omap2420h4.c | 834 ++++++++++++++++++++++++++++++++++++++++++ board/omap2420h4/platform.S | 237 ++++++++++++ board/omap2420h4/sys_info.c | 202 ++++++++++ board/omap2420h4/u-boot.lds | 58 +++ 8 files changed, 2246 insertions(+) create mode 100644 board/omap2420h4/Makefile create mode 100644 board/omap2420h4/config.mk create mode 100644 board/omap2420h4/flash.c create mode 100644 board/omap2420h4/mem.c create mode 100644 board/omap2420h4/omap2420h4.c create mode 100644 board/omap2420h4/platform.S create mode 100644 board/omap2420h4/sys_info.c create mode 100644 board/omap2420h4/u-boot.lds (limited to 'board/omap2420h4') diff --git a/board/omap2420h4/Makefile b/board/omap2420h4/Makefile new file mode 100644 index 0000000..deab6b6 --- /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 flash.o mem.o sys_info.o +SOBJS := platform.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 100644 index 0000000..1c770f3 --- /dev/null +++ b/board/omap2420h4/config.mk @@ -0,0 +1,26 @@ +# +# (C) Copyright 2004 +# Texas Instruments, +# +# 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. +# CONFIG_PARTIAL_SRAM must be defined to use this. +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. +# Comment out //CONFIG_PARTIAL_SRAM for this one. +# +#TEXT_BASE = 0x40280000 + diff --git a/board/omap2420h4/flash.c b/board/omap2420h4/flash.c new file mode 100644 index 0000000..3b6a69f --- /dev/null +++ b/board/omap2420h4/flash.c @@ -0,0 +1,536 @@ +/* + * (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, + * Kshitij Gupta + * + * 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 +#include +#include + +#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; + } + + /* 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]); + + 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 (;jstart[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/mem.c b/board/omap2420h4/mem.c new file mode 100644 index 0000000..a3b3453 --- /dev/null +++ b/board/omap2420h4/mem.c @@ -0,0 +1,306 @@ +/* + * (C) Copyright 2004 + * Texas Instruments, + * Richard Woodruff + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +/************************************************************ + * 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 rev,div; +#ifdef CONFIG_PARTIAL_SRAM + 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); +#endif + + __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 */ + + rev = get_cpu_rev(); + if (rev == CPU_2420_ES1 || rev == CPU_2422_ES1) + div = BUS_DIV_ES1; + else + div = BUS_DIV; + __raw_writel(div, CM_CLKSEL1_CORE);/* set L3/L4/USB/Display/Vlnc/SSi dividers */ + sdelay(1000); + +#ifndef CONFIG_PARTIAL_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, BIT1, CM_IDLEST_CKGEN, LDELAY); /* wait till in bypass */ + + /* 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, BIT2, CM_IDLEST_CKGEN, LDELAY); /*wait for dpll lock */ +#else +/* 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); +#endif + + __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); +} + +/*********************************************** + * memif_init() - init the gpmc and sdrc + * - early init routines, called from flash or + * SRAM. + ***********************************************/ +void memif_init(void) +{ + sdrc_init(); +#ifndef CONFIG_PARTIAL_SRAM /* don't init if calling from flash */ + gpmc_init(); +#endif +} + +/******************************************************** + * 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 val; + __raw_writel(0x0,OMAP2420_SDRC_CS0+0x400); /* clear pos A */ + __raw_writel(0x12345678, OMAP2420_SDRC_CS0);/* pattern to pos B */ + val = __raw_readl(OMAP2420_SDRC_CS0+0x400); /* get pos A value */ + if (val != 0) /* 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 + * + * !!! When ES1 comes out need to conditionalize RFR value!!! + **********************************************************/ +void do_sdrc_init(u32 offset, u32 early) +{ + u32 cpu, bug=0, rev, shared=0, cs0=0, pmask=0,first=1; + sdrc_data_t *sdata; /* do not change type */ + + static const sdrc_data_t sdrc_2422 = + { + H4_2422_SDRC_SHARING, H4_2422_SDRC_MDCFG_0, H4_2422_SDRC_ACTIM_CTRLA_0, + H4_2422_SDRC_ACTIM_CTRLB_0, H4_2422_SDRC_RFR_CTRL_ES1, H4_2422_SDRC_MR_0, + H4_2422_SDRC_DLLA_CTRL, H4_2422_SDRC_DLLB_CTRL + }; + static const sdrc_data_t sdrc_2420 = + { + H4_2420_SDRC_SHARING, H4_2420_SDRC_MDCFG_0, H4_2420_SDRC_ACTIM_CTRLA_0, + H4_2420_SDRC_ACTIM_CTRLB_0, H4_2420_SDRC_RFR_CTRL_ES1, H4_2420_SDRC_MR_0, + H4_2420_SDRC_DLLA_CTRL, H4_2420_SDRC_DLLB_CTRL + }; + + if (offset == SDRC_CS0_OSET) + cs0 = shared = 1; /* int regs shared between both chip select */ + + cpu = get_cpu_type(); + + /* 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_2422; + else + sdata = &sdrc_2420; + __asm__ __volatile__("": : :"memory"); +#ifdef CONFIG_PARTIAL_SRAM + /* u-boot is compiled to run in DDR at 8xxxxxxx. If 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) + sdata = (sdrc_data_t *)(((u32)sdata & 0x0003FFFF) | get_gpmc0_base()); +#endif + + men_combo: + + if (!early && get_mem_type() == DDR_COMBO) { /* combo part has a shared CKE signal, can't use feature */ + pmask = BIT2; + first = 0; /* trigger ddr_combo init */ + } + + if (shared) { + __raw_writel(__raw_readl(SMS_SYSCONFIG)|SMART_IDLE, SMS_SYSCONFIG); + __raw_writel(SMART_IDLE|SOFTRESET, SDRC_SYSCONFIG); /* reset sdrc */ + wait_on_value(BIT0, BIT0, SDRC_STATUS, 12000000); /* wait till reset done set */ + __raw_writel(SMART_IDLE, SDRC_SYSCONFIG); /* clear soft reset */ + __raw_writel(sdata->sdrc_sharing, SDRC_SHARING); + __raw_writel((__raw_readl(SDRC_POWER)|SMART_IDLE) & ~pmask, SDRC_POWER); + } + if (first) + __raw_writel(sdata->sdrc_mdcfg_0, SDRC_MCFG_0+offset); + else { + __raw_writel((__raw_readl(SDRC_POWER)|SMART_IDLE) & ~pmask, SDRC_POWER); + __raw_writel(H4_2420_COMBO_MDCFG_0,SDRC_MCFG_0+offset); + } + + if (cs0) { + __raw_writel(sdata->sdrc_actim_ctrla_0, SDRC_ACTIM_CTRLA_0); + __raw_writel(sdata->sdrc_actim_ctrlb_0, SDRC_ACTIM_CTRLB_0); + } else { + __raw_writel(sdata->sdrc_actim_ctrla_0, SDRC_ACTIM_CTRLA_1); + __raw_writel(sdata->sdrc_actim_ctrlb_0, SDRC_ACTIM_CTRLB_1); + } + + __raw_writel(sdata->sdrc_rfr_ctrl, SDRC_RFR_CTRL+offset); + + /* init sequence for _mDDR_ 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*/ + __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 memory + * Serial mode + * CAS latency = x + */ + __raw_writel(sdata->sdrc_mr_0, SDRC_MR_0+offset); + + /* NOTE: ES1 242x _BUG_ DLL */ + rev = get_cpu_rev(); + if (rev == CPU_2420_ES1 || rev == CPU_2422_ES1) + bug = BIT0; + /* enable & load up DLL with good value for 75MHz, and set phase to 90% */ + if (shared) { + __raw_writel(sdata->sdrc_dlla_ctrl, SDRC_DLLA_CTRL); + __raw_writel(sdata->sdrc_dlla_ctrl & ~(BIT2|bug), SDRC_DLLA_CTRL); + __raw_writel(sdata->sdrc_dllb_ctrl, SDRC_DLLB_CTRL); + __raw_writel(sdata->sdrc_dllb_ctrl & ~(BIT2|bug) , SDRC_DLLB_CTRL); + } + sdelay(9000); + if (!first || mem_ok()) /* passed test or 2nd bank init */ + return; + else { + first = 0; + goto men_combo; + } +} + + +/***************************************************** + * 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; + + /* global settings */ + __raw_writel(0x10, GPMC_SYSCONFIG); /* smart idle */ + __raw_writel(0x0, GPMC_IRQENABLE); /* isr's sources masked */ + __raw_writel(0x1, GPMC_TIMEOUT_CONTROL);/* timeout disable */ + __raw_writel(0x111, GPMC_CONFIG); /* set nWP, disable limited addr */ + + /* 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); + __raw_writel(H4_24XX_GPMC_CONFIG1_0|mux|mtype|mwidth, GPMC_CONFIG1_0); + //__raw_writel(H4_24XX_GPMC_CONFIG2_0, GPMC_CONFIG2_0); + __raw_writel(H4_24XX_GPMC_CONFIG3_0, GPMC_CONFIG3_0); + __raw_writel(H4_24XX_GPMC_CONFIG4_0, GPMC_CONFIG4_0); + //__raw_writel(H4_24XX_GPMC_CONFIG5_0, GPMC_CONFIG5_0); + __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 100644 index 0000000..4696a71 --- /dev/null +++ b/board/omap2420h4/omap2420h4.c @@ -0,0 +1,834 @@ +/* + * (C) Copyright 2004 + * Texas Instruments, + * Richard Woodruff + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static 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; +#ifndef CONFIG_PARTIAL_SRAM + s_init(0x0); /* full sram build, never skip clock and sdrc, no point */ +#else + gpmc_init(); +#endif + 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: s_init + * Description: Does early system init of muxing and clocks. + * - Called at time when only stack is available. + **********************************************************/ +void s_init(int skip) +{ + watchdog_init(); + set_muxconf_regs(); + delay(100); + + if (!skip) + prcm_init(); + + peripheral_enable(); + icache_enable(); +#ifndef CONFIG_APTIX + if (!skip) + memif_init(); +#endif +} + +/******************************************************* + * 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) +{ + int mode; +#define GP (BIT8|BIT9) + + /* There are 4 watch dogs. 1 secure, and 3 general purpose. + * I would expect that the ROM takes care of the secure one, + * but we will try also. Of the 3 GP ones, 1 can reset us + * directly, the other 2 only generate MPU interrupts. + */ + mode = (__raw_readl(CONTROL_STATUS) & (BIT8|BIT9)); + if (mode == GP) { + __raw_writel(WD_UNLOCK1 ,WD1_BASE+WSPR); + wait_for_command_complete(WD1_BASE); + __raw_writel(WD_UNLOCK2 ,WD1_BASE+WSPR); + } + __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 + ******************************************************/ +static 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_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; +#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(); + + display_board_info(btype); + if (btype == BOARD_H4_MENELAUS) + update_mux(btype,mtype); + + if ((mtype == DDR_COMBO) || (mtype == DDR_STACKED)) { + do_sdrc_init(SDRC_CS1_OSET, NOT_EARLY); /* init other chip select */ + size0 = size1 = SZ_32M; + } else + size0 = SZ_64M; + + gd->bd->bi_dram[0].start = PHYS_SDRAM_1; + gd->bd->bi_dram[0].size = size0; + gd->bd->bi_dram[1].start = PHYS_SDRAM_2; + 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 = 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 */ + } + } +} + + diff --git a/board/omap2420h4/platform.S b/board/omap2420h4/platform.S new file mode 100644 index 0000000..3728e84 --- /dev/null +++ b/board/omap2420h4/platform.S @@ -0,0 +1,237 @@ +/* + * Board specific setup info + * + * (C) Copyright 2004 + * Texas Instruments, + * Richard Woodruff + * + * 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 +#include +#include +#include +#include + +_TEXT_BASE: + .word TEXT_BASE /* sdram load addr from config.mk */ + +#ifdef CONFIG_PARTIAL_SRAM + +/************************************************************************** + * 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) */ +#endif + +.globl platformsetup +platformsetup: + mov r3, r0 /* save skip information */ +#ifdef CONFIG_APTIX + ldr r0, REG_SDRC_MCFG_0 + ldr r1, VAL_SDRC_MCFG_0 + str r1, [r0] + ldr r0, REG_SDRC_MR_0 + ldr r1, VAL_SDRC_MR_0 + str r1, [r0] + /* a ddr needs emr1 set here */ + ldr r0, REG_SDRC_SHARING + ldr r1, VAL_SDRC_SHARING + str r1, [r0] + ldr r0, REG_SDRC_RFR_CTRL_0 + ldr r1, VAL_SDRC_RFR_CTRL_0 + str r1, [r0] + + /* little delay after init */ + mov r2, #0x1800 +1: + subs r2, r2, #0x1 + bne 1b +#endif +#ifdef CONFIG_PARTIAL_SRAM + ldr sp, SRAM_STACK + str ip, [sp] /* stash old link register */ + mov ip, lr /* save link reg across call */ + mov r0, r3 /* pass skip info to s_init */ + bl s_init /* go setup pll,mux,memory */ + ldr ip, [sp] /* restore save ip */ + mov lr, ip /* restore link reg */ +#endif + /* 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 + +#ifdef CONFIG_APTIX +REG_SDRC_SHARING: + .word SDRC_SHARING +REG_SDRC_MCFG_0: + .word SDRC_MCFG_0 +REG_SDRC_MR_0: + .word SDRC_MR_0 +REG_SDRC_RFR_CTRL_0: + .word SDRC_RFR_CTRL +VAL_SDRC_SHARING: + .word VAL_H4_SDRC_SHARING +VAL_SDRC_MCFG_0: + .word VAL_H4_SDRC_MCFG_0 +VAL_SDRC_MR_0: + .word VAL_H4_SDRC_MR_0 +VAL_SDRC_RFR_CTRL_0: + .word VAL_H4_SDRC_RFR_CTRL_0 +#endif + + + + + + diff --git a/board/omap2420h4/sys_info.c b/board/omap2420h4/sys_info.c new file mode 100644 index 0000000..b5fe9e3 --- /dev/null +++ b/board/omap2420h4/sys_info.c @@ -0,0 +1,202 @@ +/* + * (C) Copyright 2004 + * Texas Instruments, + * Richard Woodruff + * + * 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 +#include +#include +#include +#include /* get mem tables */ +#include +#include +#include + +/************************************************************************** + * 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; + + 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 */ +} + +/*********************************************************** + * 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) +{ + if (get_cpu_type() == CPU_2422) + return(DDR_STACKED); + + if (get_board_type() == BOARD_H4_MENELAUS) + return(DDR_COMBO); + else + return(DDR_DISCRETE); +} + +/*********************************************************************** + * 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) + ******************************************************************/ +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 & 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"; + char cpu_2422[] = "2422"; + char db_men[] = "Menelaus"; + char db_ip[]= "IP"; + char *cpu_s, *db_s; + u32 cpu = get_cpu_type(); + + if(cpu == CPU_2420) + cpu_s = cpu_2420; + else + cpu_s = cpu_2422; + if(btype == BOARD_H4_MENELAUS) + db_s = db_men; + else + db_s = db_ip; + printf("TI H4 SDP Base Board with OMAP%s %s Daughter Board\n",cpu_s, db_s); +} diff --git a/board/omap2420h4/u-boot.lds b/board/omap2420h4/u-boot.lds new file mode 100644 index 0000000..724c1dd --- /dev/null +++ b/board/omap2420h4/u-boot.lds @@ -0,0 +1,58 @@ +/* + * January 2004 - Changed to support H4 device + * Copyright (c) 2004 Texas Instruments + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * 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 = .; +} -- cgit v1.1