diff -Nur blob-xscale/AUTHORS blob-2.0.5-pre3-glencoe05/AUTHORS --- blob-xscale/AUTHORS 2005-04-29 21:00:00.000000000 -0400 +++ blob-2.0.5-pre3-glencoe05/AUTHORS 2005-04-20 14:55:19.000000000 -0400 @@ -100,3 +100,6 @@ ====================================== - Abraham vd Merwe +* Intel Glencoe port +======================== +- Matthias Ihmig diff -Nur blob-xscale/configure.in blob-2.0.5-pre3-glencoe05/configure.in --- blob-xscale/configure.in 2005-04-29 21:00:00.000000000 -0400 +++ blob-2.0.5-pre3-glencoe05/configure.in 2005-02-19 00:01:28.000000000 -0500 @@ -84,6 +84,7 @@ csir_ims CSIR Incident Management System dafit Prueftechnik VibXpert frodo 2d3D, Inc. SA-1110 Development Board + glencoe Intel Beyond 3G Client (Glencoe platform) h3600 Compaq Ipaq H36x0 hackkit The Hack Kit base board idr Vercel UD-1 @@ -216,6 +217,17 @@ use_cpu="sa1110" use_lcd="no" ;; + glencoe) + board_name="Intel B3G Client (Glencoe)" + AC_DEFINE(GLENCOE,1,[Intel B3G Client (Glencoe)]) + BLOB_PLATFORM_OBJS="glencoe.o" + BLOB_LED_DRIVER_OBJS="led-mmap.o" + BLOB_LED_STARTCODE="ledasm-mmap.o" + BLOB_FLASH_OBJS="strata.o" + DIAG_PLATFORM_OBJS="glencoe.o" + use_cpu="pxa250" + use_lcd="no" + ;; h3600) board_name="Compaq Ipaq H3600 series" AC_DEFINE(H3600,1,[Compaq Ipaq H3600 series]) @@ -492,6 +504,9 @@ lubbock) BLOB_NETWORK_DRIVER_OBJS="ether-pxausb.o pxa_usb_ctl.o pxa_usb_ep0.o pxa_usb_ep1.o pxa_usb_ep2.o" ;; + glencoe) + BLOB_NETWORK_DRIVER_OBJS="ether-bvdusb.o bvd_usb_ctl.o bvd_usb_ep0.o bvd_usb_ep1.o bvd_usb_ep2.o" + ;; mainstone) BLOB_NETWORK_DRIVER_OBJS="ether-bvdusb.o bvd_usb_ctl.o bvd_usb_ep0.o bvd_usb_ep1.o bvd_usb_ep2.o" ;; @@ -907,6 +922,7 @@ src/Makefile src/blob/Makefile src/blob/xlli/Makefile +src/blob/xlli/glencoe/Makefile src/blob/xlli/mainstone/Makefile src/commands/Makefile src/diag/Makefile diff -Nur blob-xscale/include/blob/arch/glencoe.h blob-2.0.5-pre3-glencoe05/include/blob/arch/glencoe.h --- blob-xscale/include/blob/arch/glencoe.h 1969-12-31 19:00:00.000000000 -0500 +++ blob-2.0.5-pre3-glencoe05/include/blob/arch/glencoe.h 2005-04-15 20:20:36.000000000 -0400 @@ -0,0 +1,132 @@ +/* + * glencoe.h: Glencoe specific defines, based on mainstone.h + * Adapted by Matthias Ihmig + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef BLOB_ARCH_GLENCOE_H +#define BLOB_ARCH_GLENCOE_H + +/* Use STUART */ +#define USE_SERIAL3 1 +#define TERMINAL_SPEED baud_115200 + +/* Complete size of Flash memory in bytes - can't be detected right now due to Intel's own flash driver implementation */ +#define FULL_FLASHMEM_LEN (32 * 1024 * 1024) + +/* the base address were BLOB is loaded by the first stage loader */ +#define BLOB_ABS_BASE_ADDR (0xa0300400) + +/* where do various parts live in RAM */ +#define BLOB_RAM_BASE (0xa0200000) +#define KERNEL_RAM_BASE (0xa0008000) +#define PARAM_RAM_BASE (0xa0260000) +#define RAMDISK_RAM_BASE (0xa0500000) + +/* and where do they live in flash */ +#define BLOB_FLASH_BASE (0x00000000) +#define BLOB_FLASH_LEN (256 * 1024) +#define KERNEL_FLASH_BASE (BLOB_FLASH_BASE + BLOB_FLASH_LEN) +#define KERNEL_FLASH_LEN (2 * 1024 * 1024) + +/* LOAD_RAMDISK into ram? =0 - we don't use an initrd, but a complete rootfs instead. blob's RAMDISK is our ROOTFS*/ +#define LOAD_RAMDISK 0 +#define PARAM_FLASH_LEN (256 * 1024) +#define RAMDISK_FLASH_BASE (KERNEL_FLASH_BASE + KERNEL_FLASH_LEN) +#define RAMDISK_FLASH_LEN (FULL_FLASHMEM_LEN - KERNEL_FLASH_LEN - PARAM_FLASH_LEN - BLOB_FLASH_LEN) +// #define RAMDISK_FLASH_LEN (28 * 1024*1024) +#define PARAM_FLASH_BASE (RAMDISK_FLASH_BASE + RAMDISK_FLASH_LEN) + +/* the position of the kernel boot parameters */ +#define BOOT_PARAMS (0xa0000100) + +/* the size (in kbytes) to which the compressed ramdisk expands - 0=no initrd*/ +#define RAMDISK_SIZE (0 * 1024) + + +/* GPIO settings */ +#undef GPSR0_VALUE +#undef GPSR1_VALUE +#undef GPSR2_VALUE +#undef GPSR3_VALUE +#undef GPDR0_VALUE +#undef GPDR1_VALUE +#undef GPDR2_VALUE +#undef GPDR3_VALUE +#undef GPCR0_VALUE +#undef GPCR1_VALUE +#undef GPCR2_VALUE +#undef GPCR3_VALUE +#undef GAFR0_L_VALUE +#undef GAFR0_U_VALUE +#undef GAFR1_L_VALUE +#undef GAFR1_U_VALUE +#undef GAFR2_L_VALUE +#undef GAFR2_U_VALUE +#undef GAFR3_L_VALUE +#undef GAFR3_U_VALUE + +#define GPSR0_VALUE 0x00009A04 +#define GPSR1_VALUE 0x03C70000 +#define GPSR2_VALUE 0x0420C000 +#define GPSR3_VALUE 0x001A0240 + +#define GPCR0_VALUE 0x003B0000 +#define GPCR1_VALUE 0x00000002 +#define GPCR2_VALUE 0x03C10000 +#define GPCR3_VALUE 0x01841020 + +#define GPDR0_VALUE 0xD3BB9A04 +#define GPDR1_VALUE 0xFCFFAB83 +#define GPDR2_VALUE 0x1FFFFFFF +#define GPDR3_VALUE 0x01FFF260 + +#define GAFR0_L_VALUE 0x98000000 +#define GAFR0_U_VALUE 0xA51A8092 +#define GAFR1_L_VALUE 0x699A9552 +#define GAFR1_U_VALUE 0xAAA5A5AA +#define GAFR2_L_VALUE 0x6AAAAAAA +#define GAFR2_U_VALUE 0x55A00400 +#define GAFR3_L_VALUE 0x54000055 +#define GAFR3_U_VALUE 0x000016A9 + +/* Memory configuration */ +#define MDREFR_VALUE 0x20199019 +#define MDCNFG_VALUE 0x09C00BCB +#define MDMRS_VALUE 0x00000000 + +/* + * #define MSC0_VALUE 0x39F2A7A3 + * #define MSC1_VALUE 0x0000A691 + * #define MSC2_VALUE 0x0000B884 + */ + +/* TFTP download RAM base */ +#define TFTP_RAM_START 0xa1000000 + +/* GREEN_LED: GPxR1, BLUE_LED,BL,LCD: GPxR2 */ +#define GLN_nGREEN_LED 0x00000002 +#define GLN_nBLUE_LED 0x00010000 +#define GLN_BL_PWR_ON 0x00400000 +#define GLN_LCD_PWR_ON 0x00800000 + +/* LED: we have no memory mapped I/O, but Set/Clear reg instead -> for switching OFF, use GPSR1 instead of LED_ADDR=GPCR1 */ +#define LED_ADDR GPCR1 +#define LED_ON GLN_nBLUE_LED +#define LED_OFF GLN_nBLUE_LED + +#endif diff -Nur blob-xscale/include/blob/arch.h blob-2.0.5-pre3-glencoe05/include/blob/arch.h --- blob-xscale/include/blob/arch.h 2005-04-29 21:00:01.000000000 -0400 +++ blob-2.0.5-pre3-glencoe05/include/blob/arch.h 2005-02-19 00:02:48.000000000 -0500 @@ -52,6 +52,8 @@ # include #elif defined FRODO # include +#elif defined GLENCOE +# include #elif defined HKIT # include #elif defined H3600 diff -Nur blob-xscale/include/blob/linux.h blob-2.0.5-pre3-glencoe05/include/blob/linux.h --- blob-xscale/include/blob/linux.h 2005-04-29 21:00:01.000000000 -0400 +++ blob-2.0.5-pre3-glencoe05/include/blob/linux.h 2005-02-20 15:26:15.000000000 -0500 @@ -80,6 +80,8 @@ # define ARCH_NUMBER (358) #elif defined MAINSTONE # define ARCH_NUMBER (406) +#elif defined GLENCOE +# define ARCH_NUMBER (4061) #else #warning "FIXME: Calling the kernel with a generic SA1100 architecture code. YMMV!" #define ARCH_NUMBER (18) diff -Nur blob-xscale/myblobmake blob-2.0.5-pre3-glencoe05/myblobmake --- blob-xscale/myblobmake 1969-12-31 19:00:00.000000000 -0500 +++ blob-2.0.5-pre3-glencoe05/myblobmake 2005-04-24 02:27:42.000000000 -0400 @@ -0,0 +1,43 @@ +### Small script to automate configuring and compiling blob for Glencoe +### run without parameters +### +### Please remember that clock settings can be changed at the end of +### src/blob/xlli/glencoe/src/blob/xlli/glencoe +### +### Author: Matthias Ihmig +### Last Change: 04/24/2005 + +### Setup path to cross-compiler +#export myarmdir=arm-linux +#export myarmdir=arm-linux04 +export myarmdir=arm-linux-3.4.2-oe +export myarmdirpath=$HOME/arm/$myarmdir + +### Setup path to configured kernel sources +#export myarmlinux=linux-2.6.9 +export myarmlinux=linux-2.6.9-intc1-mih1 +export myarmlinuxpath=$HOME/arm/$myarmlinux + +### Configure blob +export WANT_AUTOMAKE=1.8 +export WANT_AUTOCONF=2.5 +export CC=$myarmdirpath/bin/arm-linux-gcc +export OBJCOPY=$myarmdirpath/bin/arm-linux-objcopy +export LD=$myarmdirpath/bin/arm-linux-ld +export RANLIB=$myarmdirpath/bin/arm-linux-ranlib +export AR=$myarmdirpath/bin/arm-linux-ar +export STRIP=$myarmdirpath/bin/arm-linux-strip + +export PATH=$myarmdirpath/arm-linux/bin:$PATH + +make -f Makefile.cvs +make -f Makefile.cvs + +# configure blob with usbdnet +./configure --host=arm-linux --with-board=glencoe --enable-xlli --enable-usbdnet --enable-network --with-linux-prefix=$myarmlinuxpath --enable-maintainer-mode --enable-memtest --enable-zimage --with-commands=all + +# enable blob debug +#./configure --host=arm-linux --with-board=glencoe --enable-xlli --enable-usbdnet --enable-network --with-linux-prefix=$myarmlinuxpath --enable-maintainer-mode --enable-memtest --enable-zimage --with-commands=all --enable-blob-debug + +echo --- now run make +echo --- or to copy the flash binary to /tftp/ afterwards: "make && cp src/blob/blob /tftp/blob" diff -Nur blob-xscale/src/blob/flash-commands.c blob-2.0.5-pre3-glencoe05/src/blob/flash-commands.c --- blob-xscale/src/blob/flash-commands.c 2005-04-29 21:00:02.000000000 -0400 +++ blob-2.0.5-pre3-glencoe05/src/blob/flash-commands.c 2005-04-20 01:26:14.000000000 -0400 @@ -44,6 +44,15 @@ #include +/* The following hack for Mainstone&Glencoe is a little bit ugly - the reason is I didn't want to + * rewrite the existing flash driver from the Mainstone port and integrate it into the + * blob framework, but still be able to use the "flash" command. + * The flash driver from Mainstone uses flash_write, blob uses flash_write_region + * resp. flash_erase instead of flash_erase_region. Thus the following #define wrappers for Mainstone/Glencoe + */ + +#include + int parse_partition(char *s, u32 **addr, u32 *length) { const blob_partition_t *p = pt_find_by_name(s); @@ -123,8 +132,16 @@ nwords = (numBytes + sizeof(u32) - 1) / sizeof(u32); printf("Saving %s to flash\n", argv[1]); - +#if defined(GLENCOE) || defined(MAINSTONE) + struct flash_chip chip; + chip.base = 0 * 0x04000000; + if (BOOT_DEF & 0x1) chip.buswidth = 2; + else chip.buswidth = 4; + flash_probe(&chip); + return flash_write( &chip, dst, (u8*) src, numBytes); +#else flash_write_region(dst, src, nwords); +#endif return 0; } @@ -226,8 +243,16 @@ printerror(rv, argv[1]); return 0; } - +#if defined(GLENCOE) || defined(MAINSTONE) + struct flash_chip chip; + chip.base = 0 * 0x04000000; + if (BOOT_DEF & 0x1) chip.buswidth = 2; + else chip.buswidth = 4; + flash_probe(&chip); + rv = flash_erase(&chip, addr, length); +#else rv = flash_erase_region(addr, length >> 2); +#endif if (rv < 0) { printerror(rv, argv[1]); return 0; diff -Nur blob-xscale/src/blob/glencoe.c blob-2.0.5-pre3-glencoe05/src/blob/glencoe.c --- blob-xscale/src/blob/glencoe.c 1969-12-31 19:00:00.000000000 -0500 +++ blob-2.0.5-pre3-glencoe05/src/blob/glencoe.c 2005-04-20 14:57:14.000000000 -0400 @@ -0,0 +1,386 @@ +/* + * glencoe.c: Glencoe specific stuff, based on mainstone.c + * + * Copyright (C) 2003 Intel Corporation (yu.tang@intel.com) + * Copyright (C) 2005 Matthias Ihmig (m.ihmig@mytum.de) + * + * 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 + * + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct flash_chip flash_chips[2]; + +#undef FLASH_SYNC_MODE_SUPPORT + +static const blob_partition_t glencoe_default_partition_table[] = { + { + /* start of table */ + magic: BLOB_DEFAULT_PART_TABLE_MAGIC, + next: sizeof(blob_partition_t), + offset: 0x00000000, /* absolute base address */ + size: FULL_FLASHMEM_LEN /* total size of flash memory */ + }, + { + /* blob itself */ + magic: BLOB_PART_VALID_MAGIC, + next: sizeof(blob_partition_t), + offset: BLOB_FLASH_BASE, + size: BLOB_FLASH_LEN, + name: "blob", + mem_base: BLOB_RAM_BASE + }, + { + /* kernel */ + magic: BLOB_PART_VALID_MAGIC, + next: sizeof(blob_partition_t), + offset: KERNEL_FLASH_BASE, + size: KERNEL_FLASH_LEN, + name: "zImage", + flags: BLOB_PART_FLAG_LOAD | BLOB_PART_FLAG_EXEC, + mem_base: KERNEL_RAM_BASE, + entry_point: KERNEL_RAM_BASE + }, + { + /* the ramdisk is our jffs2 root filesystem */ + magic: BLOB_PART_VALID_MAGIC, + next: sizeof(blob_partition_t), + offset: RAMDISK_FLASH_BASE, + size: RAMDISK_FLASH_LEN, + name: "rootfs", + flags: BLOB_PART_FLAG_JFFS2, + mem_base: RAMDISK_RAM_BASE + }, + { + // Glencoe's Flash has 4 Top Parameter Blocks a 32 kByte, + // so exclude that from rootfs + // Parameter Block currently unused! + magic: BLOB_PART_VALID_MAGIC, + next: sizeof(blob_partition_t), + offset: PARAM_FLASH_BASE, + size: PARAM_FLASH_LEN, + name: "param", + flags: BLOB_PART_FLAG_PTABLE, + mem_base: PARAM_RAM_BASE + }, + { + /* last entry */ + magic: BLOB_PART_LAST_MAGIC + } +}; + + +static const flash_descriptor_t glencoe_flash_descriptors[] = +{ + { + size: 2* 128 * 1024, + num: 128, + lockable: 0 + }, + { + /* NULL block */ + }, +}; + +static void init_glencoe_flash_driver(void) +{ + int i = 0; + flash_descriptors = glencoe_flash_descriptors; + flash_driver = NULL; + + /* the default partition table */ + default_partition_table = glencoe_default_partition_table; + + /* IF there's a flash partition table, we don't know where it will live, so + * put the pointer at 0x0000000 and let the partition table + * parser figure out. If none is found, the default table is used. + */ + flash_partition_table = (blob_partition_t*)0x00000000; + + for (i=0; i<1; i++) { + struct flash_chip *chip = flash_chips + i; + + chip->base = i * 0x04000000; + + if (BOOT_DEF & 0x1) chip->buswidth = 2; + else chip->buswidth = 4; + + flash_probe(chip); + } +} + +__initlist(init_glencoe_flash_driver, INIT_LEVEL_DRIVER_SELECTION); + + +static void glencoe_init_hardware(void) +{ + +#ifdef CONFIG_NETWORK_SUPPORT + unsigned char serverip[4]={192,168,1,100}; + unsigned char clientip[4]={192,168,1,101}; + + /* set default ip */ + memcpy(serveripaddress, serverip, sizeof(serverip)); + memcpy(clientipaddress, clientip, sizeof(clientip)); +#endif + +// Should not really be necessary if set correctly in the default GPIO-reg values +#ifdef USE_SERIAL2 + /* setup BTUART GPIOs (BTRXD, BTTXD, BTCTS, BTRTS) */ + GPDR1 &= ~0x00003A00; + GPDR1 |= 0x00002800; + GAFR1_L &= ~0x0FF00000; + GAFR1_L |= 0x09900000; +#endif + + /* select drivers */ + reboot_driver = &pxa_reboot_driver; + serial_driver = &pxa_serial_driver; + +#ifdef CONFIG_USBSERIAL_SUPPORT + usb_serial_driver= &bvd_usb_serial_driver; +#endif + + led_driver = &mmap_led_driver; + timer_driver = &intelarm_timer_driver; +#ifdef CONFIG_USBDNET_SUPPORT + ether_driver = &bvdusb_ether_driver; +#endif + GPSR2 = GLN_nBLUE_LED; + GPSR1 = GLN_nGREEN_LED; +} + + +__initlist(glencoe_init_hardware, INIT_LEVEL_DRIVER_SELECTION); + +/********************************************************************* + * cmd_flash_write + * + * AUTOR: SELETZ + * REVISED: + * + * Command wrapper for low-level flash write access + * + */ +static int cmd_flash_write( int argc, char *argv[] ) +{ + int ret = 0; + u32 src = 0L; + u32 dest = 0L; + u32 len = 0L; + struct flash_chip *chip=NULL; + + if ( argc < 4 ) { + ret = -1; + goto DONE; + } + + ret = strtou32( argv[1], &src ); + if ( ret < 0 ) { + ret = -1; + goto DONE; + } + + ret = strtou32( argv[2], &dest ); + if ( ret < 0 ) { + ret = -1; + goto DONE; + } + + ret = strtou32( argv[3], &len ); + if ( ret < 0 ) { + ret = -1; + goto DONE; + } + + // for glencoe, the dest is currently always in chip[0], but keep it for later extensions + if (dest<0x04000000) chip = &flash_chips[0]; + else chip = &flash_chips[1]; + + printf("chip-id: %x, chip-type: %x\n", chip->id, chip->type); + ret = flash_write( chip, dest, (u8*) src, len); + +DONE: + return ret; +} + + +static char flashwritehelp[] = "fwrite srcadr destadr size(bytes)\n" +"flash a memory region\n"; +__commandlist( cmd_flash_write, "fwrite", flashwritehelp ); + +/********************************************************************* + * cmd_flash_erase + * + * AUTOR: SELETZ + * REVISED: + * + * Command wrapper for low-level flash erasing + * + */ +static int cmd_flash_erase( int argc, char *argv[] ) +{ + int ret = 0; + u32 dest = 0L; + u32 len = 0L; + struct flash_chip *chip=NULL; + + if ( argc < 3 ) { + ret = -1; + goto DONE; + } + + ret = strtou32( argv[1], &dest ); + if ( ret < 0 ) { + ret = -1; + goto DONE; + } + + ret = strtou32( argv[2], &len ); + if ( ret < 0 ){ + ret = -1; + goto DONE; + } + + if(dest < 0x04000000) chip = &flash_chips[0]; + else chip = &flash_chips[1]; + + ret = flash_erase(chip, dest, len); + +DONE: + return ret; +} + +static char flasherasehelp[] = "ferase adr size(bytes)\n" +"erase a flash region\n"; +__commandlist( cmd_flash_erase, "ferase", flasherasehelp ); + +/********************************************************************* + * cmd_clock_info + * + * AUTOR: yu tang, rusty geldmacher + * REVISED: + * + * prints out clock information. taken from Yu's kernel patch + * + */ +#define BASE_CLK 13000000 +static int cmd_clock_info(int argc, char *argv[]) +{ + unsigned long cccr_val, ccsr_val, clkcfg_val; + unsigned int L, M, N2; + unsigned int r_clk, t_clk, s_clk, m_clk; + int k0db, k1db; + + cccr_val = CCCR; + ccsr_val = CCSR; + asm( "mrc p14, 0, %0, c6, c0, 0" : "=r" (clkcfg_val) ); + + L = ccsr_val & 0x1f; + N2 = (ccsr_val>>7) & 0x7; + + if (L <= 10) M = 1; + else if (L <=20 ) M =2; + else M=4; + + r_clk = (L * BASE_CLK); + t_clk = (L * BASE_CLK * N2) / 2; + + /* Fast-bus Mode ? */ + if (clkcfg_val & 0x8) + s_clk = r_clk; + else + s_clk = r_clk/2; + + /* Alternate setting? */ + if (cccr_val & 0x2000000) + m_clk = s_clk; + else + m_clk = r_clk / M; + + if (MDREFR & MDREFR_K0DB4) + k0db = 4; + else if (MDREFR & MDREFR_K0DB2) + k0db = 2; + else + k0db = 1; + + if (MDREFR & MDREFR_K1DB2) + k1db = 2; + else + k1db = 1; + + printf("Run Mode clock: %d.%02dMHz (*%d)\n", + r_clk / 1000000, (r_clk % 1000000) / 10000, L ); + printf("Turbo Mode clock: %d.%02dMHz (*%d.%d, %sactive)\n", + t_clk / 1000000, (t_clk % 1000000) / 10000, N2 / 2, (N2 % 2) * 5, + (clkcfg_val & 0x1) ? "" : "in" ); + printf("Memory clock: %d.%02dMHz (Alt=%d, SDCLK[0]=/%d, SDCLK[1]=/%d)\n", + m_clk / 1000000, (m_clk % 1000000) / 10000,(int)(cccr_val>>25)&1, + k0db, k1db ); + printf("System bus clock: %d.%02dMHz \n", + s_clk / 1000000, (s_clk % 1000000) / 10000 ); +} + +static char clockinfohelp[] = "clockinfo\n" +"print out processor clock information\n"; +__commandlist(cmd_clock_info, "clockinfo", clockinfohelp); + + +/********************************************************************* + * cmd_go + * + * AUTOR: Yu Tang + * REVISED: + * + * Start execution at indicated address + * + */ +static int cmd_go(int argc, char *argv[]) +{ + void (*myfunc)() = NULL; + int ret; + + if (argc != 2) return -1; + + ret = strtou32( argv[1], &myfunc); + if (ret < 0) return -1; + + printf("\nStarting at 0x%08x...\n\n", (u32)myfunc); + myfunc(); + printf("\nDone.\n"); + + return 0; +} + +static char gohelp[] = "go address\n" +"Start execution at $address\n"; +__commandlist(cmd_go, "go", gohelp); diff -Nur blob-xscale/src/blob/main.c blob-2.0.5-pre3-glencoe05/src/blob/main.c --- blob-xscale/src/blob/main.c 2005-04-29 21:00:02.000000000 -0400 +++ blob-2.0.5-pre3-glencoe05/src/blob/main.c 2005-04-23 17:55:06.000000000 -0400 @@ -79,7 +79,7 @@ blob_status.terminalSpeed = TERMINAL_SPEED; blob_status.load_ramdisk = LOAD_RAMDISK; blob_status.cmdline[0] = '\0'; - blob_status.boot_delay = 10; + blob_status.boot_delay = 3; /* call subsystems (blob_status.* may change) */ init_subsystems(); @@ -99,6 +99,7 @@ printf("\nConsider yourself BLOBed!\n\n"); printf("%sCopyright (C) 1999 2000 2001 2002 2003 " "Jan-Derk Bakker and Erik Mouw\n", version_str); + printf("Adapted for Glencoe by Matthias Ihmig in 2004/05 for Intel\n"); printf(PACKAGE " comes with ABSOLUTELY NO WARRANTY; " "read the GNU GPL for details.\n"); printf("This is free software, and you are welcome " diff -Nur blob-xscale/src/blob/partition.c blob-2.0.5-pre3-glencoe05/src/blob/partition.c --- blob-xscale/src/blob/partition.c 2005-04-29 21:00:02.000000000 -0400 +++ blob-2.0.5-pre3-glencoe05/src/blob/partition.c 2005-02-19 00:37:33.000000000 -0500 @@ -92,7 +92,7 @@ dprintf("Searching flash partition table... \n"); rv = flash_get_first_block_address(&a); if(rv < 0) { - dprintf("first block not found\n"); + dprintf("first block not found -> no partition table stored in flash (use hardcoded one).\n"); return; } @@ -215,8 +215,8 @@ return; case BLOB_PART_VALID_MAGIC: - printf(" 0x%08x @ 0x%08x (%d kB): '%s'\n", - t->size, t->offset, t->size, t->name); + printf(" 0x%08x @ 0x%08x (%d B = %d kB): '%s'\n", + t->size, t->offset, t->size, t->size/1024, t->name); if(t->flags & BLOB_PART_FLAG_PTABLE) printf(" contains parameter blocks\n"); diff -Nur blob-xscale/src/blob/xlli/glencoe/Makefile.am blob-2.0.5-pre3-glencoe05/src/blob/xlli/glencoe/Makefile.am --- blob-xscale/src/blob/xlli/glencoe/Makefile.am 1969-12-31 19:00:00.000000000 -0500 +++ blob-2.0.5-pre3-glencoe05/src/blob/xlli/glencoe/Makefile.am 2005-02-19 18:46:29.000000000 -0500 @@ -0,0 +1,36 @@ +# +# Makefile.am +# +# Copyright (C) 2004 Yu Tang(yu.tang@intel.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 +# + +noinst_LIBRARIES = libxlli.a + + +libxlli_a_SOURCES = start.s xlli_LowLev_Init.s + +libxlli_a_DEPENDENCIES = \ + xlli_LowLev_mac.mac \ + xlli_Bulverde_defs.inc \ + xlli_Glencoe_defs.inc \ + xlli_LowLev_Init.s \ + start.s + +CLEANFILES = ${srcdir}/*~ + + +DISTCLEANFILES = ${builddir}/.deps/*.P diff -Nur blob-xscale/src/blob/xlli/glencoe/start.s blob-2.0.5-pre3-glencoe05/src/blob/xlli/glencoe/start.s --- blob-xscale/src/blob/xlli/glencoe/start.s 1969-12-31 19:00:00.000000000 -0500 +++ blob-2.0.5-pre3-glencoe05/src/blob/xlli/glencoe/start.s 2005-04-01 19:03:14.000000000 -0500 @@ -0,0 +1,210 @@ +/* + * start.s: Glencoe/Bulverde start code using XLLI + * + * Copyright (C) 2004 Intel Corporation (yu.tang@intel.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 "xlli_Bulverde_defs.inc" @ Bulverde specific include file + .include "xlli_Glencoe_defs.inc" @ Glencoe specific include file + +.text + +/* + * We start by implementing *all* exception vectors + * + * Reset vector: this initialises the machine + * note here that this not yet taken sleep wakeup into account -- lets just + * get something to work first. + */ + +.macro blink, count + mov r3, \count + b endless_blink +.endm + +.globl reset +reset: + /* Check reset cause */ + ldr r0, =xlli_PMRCREGS_PHYSICAL_BASE + ldr r10, [r0, #xlli_RCSR_offset] + + mov r2, #xlli_RCSR_ALL + and r10, r10, r2 + + mov r12, #0 + + /* Clear RCSR bits as they are sticky */ + str r2, [r0, #xlli_RCSR_offset] + + /* Pack PSSR/RCSR together */ + ldr r1, [r0, #xlli_PSSR_offset] + mov r2, #0x3F + and r1, r1, r2 + mov r1, r1, lsl #16 + orr r10, r10, r1 + + /* GPIO Reset */ + tst r10, #xlli_RCSR_GPR + bne 1f + + /* Hardware/Power On reset */ + tst r10, #xlli_RCSR_HWR + bne 1f + + /* Watchdog reset */ + tst r10, #xlli_RCSR_WDR + bne 1f + + /* Sleep or Deep sleep Mode Reset */ + tst r10, #xlli_RCSR_SMR + add r12, r12, #0x1 + bne 2f + +1: + /* Read system configuration and LCD configuration, + * stored in PSPR + */ + bl xlli_read_SCR + + /* Initialize clocks */ + bl xlli_clks_init + + /* Intialize power manager and internal memory */ + bl xlli_pwrmgr_init + bl xlli_IMpwr_init + +2: + /* Initialize GPIO */ + bl xlli_GPIO_init + + ldr r5, =xlli_GPIOREGS_PHYSICAL_BASE @ Load the GPIO register block base address + @ switch on LCD backlight + ldr r4, =xlli_PLATFORM_BL_PWR_ON + str r4, [r5, #xlli_GPSR2_offset] + + /* Initialize Memory Controller */ + bl xlli_mem_init + + /* Initialize Interrupt Controller */ + bl xlli_intr_init + + /* Intialize clocks when sleep reset */ + tst r12, #0x1 + blne xlli_clks_init_sleepReset + + /* Perform frequence change */ + bl xlli_mem_Tmax + bl xlli_mem_restart + bl xlli_setClocks + bl xlli_freq_change + bl xlli_mem_Topt + bl xlli_mem_restart + + /* Initialize OS timer */ + bl xlli_ost_init + + /* Check whether last sleep due to vdd/batt error: pspr should + * has special value 0x3 : + * - if so, do normal boot + * - otherwise, do suspend/resume + */ + ldr r0, =xlli_PMRCREGS_PHYSICAL_BASE + ldr r1, [r0, #xlli_PSPR_offset] + tst r12, #0x1 + cmpne r1, #0x3 + movne pc, r1 + + bl normal_boot + + /* should never be here */ + blink #1 + +.globl undefined_instruction +undefined_instruction: + blink #2 + +.globl software_interrupt +software_interrupt: + blink #3 + +.globl prefetch_abort +prefetch_abort: + blink #4 + +.globl data_abort +data_abort: + blink #5 + +.globl not_used +not_used: + blink #6 + +.globl irq +irq: + blink #7 + +.globl fiq +fiq: + blink #8 + +ledset: + mov pc, lr + +ledclear: + mov pc, lr + +ledsetup: + mov r2, lr + bl ledclear + mov pc, r2 + +.macro wait, count + mov r0, \count +0: + subs r0, r0, #1 + bne 0b +.endm + +ledflash: + mov r2, lr + bl ledset + wait #0x400000 + bl ledclear + wait #0x400000 + mov pc, r2 + +endless_blink: + mov r4, r3 + +0: + ldr r5, =xlli_GPIOREGS_PHYSICAL_BASE @ Load the GPIO register block base address + ldr r6, =(xlli_PLATFORM_nGREEN_LED + xlli_PLATFORM_nBLUE_LED) + + str r6, [r5, #xlli_GPCR1_offset] @ Write the R0 values + str r6, [r5, #xlli_GPCR2_offset] @ Write the R0 values + bl ledflash + + str r6, [r5, #xlli_GPSR1_offset] @ Write the R0 values + str r6, [r5, #xlli_GPSR2_offset] @ Write the R0 values + bl ledflash + + subs r4, r4, #1 + bne 0b + wait #0x2000000 + b endless_blink + diff -Nur blob-xscale/src/blob/xlli/glencoe/xlli_Bulverde_defs.inc blob-2.0.5-pre3-glencoe05/src/blob/xlli/glencoe/xlli_Bulverde_defs.inc --- blob-xscale/src/blob/xlli/glencoe/xlli_Bulverde_defs.inc 1969-12-31 19:00:00.000000000 -0500 +++ blob-2.0.5-pre3-glencoe05/src/blob/xlli/glencoe/xlli_Bulverde_defs.inc 2005-02-19 18:46:29.000000000 -0500 @@ -0,0 +1,365 @@ +@********************************************************************************* +@ +@ Copyright (C) 2004, Intel Corporation +@ +@ This software program is licensed subject to the GNU General Public License +@ (GPL).Version 2,June 1991, available at http://www.fsf.org/copyleft/gpl.html +@ +@********************************************************************************* +@ +@ FILENAME: xlli_Bulverde_defs.inc (Core processor address definitions for PXA27x) +@ +@ LAST MODIFIED: 5-Apr-2004 +@ +@****************************************************************************** +@ +@ Include file for PXA27x Processor based +@ Cross Platform Low Level Initialization (XLLI) +@ + +@ +@ GENERAL PURPOSE I/O (GPIO) base address and register offsets from the base address +@ + + .equ xlli_GPIOREGS_PHYSICAL_BASE,0x40E00000 + +@ GPIO register offsets from the base address + + .equ xlli_GPLR0_offset,(0x000) @ GPIO Level registers + .equ xlli_GPLR1_offset,(0x004) + .equ xlli_GPLR2_offset,(0x008) + .equ xlli_GPLR3_offset,(0x100) + + .equ xlli_GPDR0_offset,(0x00C) @ GPIO Direction registers + .equ xlli_GPDR1_offset,(0x010) + .equ xlli_GPDR2_offset,(0x014) + .equ xlli_GPDR3_offset,(0x10C) + + .equ xlli_GPSR0_offset,(0x018) @ GPIO Set registers + .equ xlli_GPSR1_offset,(0x01C) + .equ xlli_GPSR2_offset,(0x020) + .equ xlli_GPSR3_offset,(0x118) + + .equ xlli_GPCR0_offset,(0x024) @ GPIO Clear registers + .equ xlli_GPCR1_offset,(0x028) + .equ xlli_GPCR2_offset,(0x02C) + .equ xlli_GPCR3_offset,(0x124) + + .equ xlli_GAFR0_L_offset,(0x054) @ GPIO Alternate function registers (Bits 15:0) + .equ xlli_GAFR0_U_offset,(0x058) @ Bits 31:16 + .equ xlli_GAFR1_L_offset,(0x05c) @ Bits 47:32 + .equ xlli_GAFR1_U_offset,(0x060) @ Bits 63:48 + .equ xlli_GAFR2_L_offset,(0x064) @ Bits 79:64 + .equ xlli_GAFR2_U_offset,(0x068) @ Bits 95:80 + .equ xlli_GAFR3_L_offset,(0x06C) @ Bits 111:96 + .equ xlli_GAFR3_U_offset,(0x070) @ Bits 127:112 + +@ +@ POWER MANAGER base address and register offsets from the base address +@ + + .equ xlli_PMRCREGS_PHYSICAL_BASE,0x40F00000 + + .equ xlli_PMCR_offset,(0x00) @ Power Manager Control Register + .equ xlli_PSSR_offset,(0x04) @ Power Manager Sleep Status Register + .equ xlli_PSPR_offset,(0x08) @ Power Manager Scratch Pad Register + .equ xlli_PWER_offset,(0x0C) @ Power Manager Wake-up Enable Register + .equ xlli_PRER_offset,(0x10) @ Power Manager GPIO Rising-edge Detect Enable Register + .equ xlli_PFER_offset,(0x14) @ Power Manager GPIO Falling-edge Detect Enable Register + .equ xlli_PEDR_offset,(0x18) @ Power Manager GPIO Edge Detect Status Register + .equ xlli_PCFR_offset,(0x1C) @ Power Manager General Configuration Register + .equ xlli_PGSR0_offset,(0x20) @ Power Manager GPIO Sleep State Register for GP [31-0] + .equ xlli_PGSR1_offset,(0x24) @ Power Manager GPIO Sleep State Register for GP [63-32] + .equ xlli_PGSR2_offset,(0x28) @ Power Manager GPIO Sleep State Register for GP [95-64] + .equ xlli_PGSR3_offset,(0x2C) @ Power Manager GPIO Sleep State Register for GP [120-96] + .equ xlli_RCSR_offset,(0x30) @ Reset Controller Status Register + .equ xlli_PSLR_offset,(0x34) @ Power Manager Sleep Mode Config Register + .equ xlli_PSTR_offset,(0x38) @ Power Manager Standby Mode Config Register + .equ xlli_PSNR_offset,(0x3C) @ Power Manager Sense Moce Config Register + .equ xlli_PVCR_offset,(0x40) @ Power Manager Voltage Change Control Register + .equ xlli_PKWR_offset,(0x50) @ Power Manager Keyboard Wake-up Enable Register + .equ xlli_PKSR_offset,(0x54) @ Power Manager Keyboard Edge-Detect Status Register + .equ xlli_PI2DBR_offset,(0x188) @ Power I2C Data Buffer Register + .equ xlli_PI2CR_offset,(0x190) @ Power I2C Control Register + .equ xlli_PI2SR_offset,(0x198) @ Power I2C Status Register + .equ xlli_PI2SAR_offset,(0x1A0) @ Power I2C Slave Address Register + +@ +@ POWER MANAGER register bit masks +@ + .equ xlli_PSSR_SSS,(0x01) @ Software Sleep Status + .equ xlli_PSSR_BFS,(0x02) @ Battery Fault Status + .equ xlli_PSSR_VFS,(0x04) @ VCC Fault Status + .equ xlli_PSSR_PH,(0x10) @ Peripheral Control Hold + .equ xlli_PSSR_RDH,(0x20) @ Read Disable Hold + + .equ xlli_PCFR_OPDE,(0x01) @ Processor (13MHz) osc power-down enable + .equ xlli_PCFR_FP,(0x02) @ Float PCMCIA during sleep modes + .equ xlli_PCFR_FS,(0x04) @ Float Static Chip Selects + .equ xlli_PCFR_GPR_EN,(0x10) @ GPIO 1 performs GPIO reset + .equ xlli_PCFR_SYSEN_EN,(0x20) @ SYS_EN pin + .equ xlli_PCFR_PI2C_EN,(0x40) @ + .equ xlli_PCFR_DC_EN,(0x80) @ Deep-Sleep Mode + .equ xlli_PCFR_FVC,(0x400) @ + .equ xlli_PCFR_L1_EN,(0x800) @ + .equ xlli_PCFR_GPROD,(0x1000) @ + .equ xlli_PCFR_PO,(0x4000) @ + .equ xlli_PCFR_RO,(0x8000) @ + .equ xlli_PCFR_USEDBITS,(xlli_PCFR_OPDE | xlli_PCFR_FP | xlli_PCFR_FS | xlli_PCFR_GPR_EN | xlli_PCFR_SYSEN_EN| xlli_PCFR_PI2C_EN | xlli_PCFR_DC_EN | xlli_PCFR_FVC | xlli_PCFR_L1_EN| xlli_PCFR_GPROD | xlli_PCFR_PO | xlli_PCFR_RO) + .equ xlli_PWER_WE0,(0x01) @ Wake-up Enable GPIO pin 0 + .equ xlli_PWER_WE1,(0x02) @ Wake-up Enable GPIO pin 1 + .equ xlli_PWER_WERTC,(0x80000000) @ RTC Standby, Wake-up Enable- + +@ +@ MEMORY CONTROLLER base address and register offsets from the base address +@ + + .equ xlli_MEMORY_CONFIG_BASE,0x48000000 + + .equ xlli_MDCNFG_offset,(0x00) + .equ xlli_MDREFR_offset,(0x04) + .equ xlli_MSC0_offset,(0x08) + .equ xlli_MSC1_offset,(0x0C) + .equ xlli_MSC2_offset,(0x10) + .equ xlli_MECR_offset,(0x14) + .equ xlli_SXLCR_offset,(0x18) + .equ xlli_SXCNFG_offset,(0x1C) + .equ xlli_FLYCNFG_offset,(0x20) + .equ xlli_SXMRS_offset,(0x24) + .equ xlli_MCMEM0_offset,(0x28) + .equ xlli_MCMEM1_offset,(0x2C) + .equ xlli_MCATT0_offset,(0x30) + .equ xlli_MCATT1_offset,(0x34) + .equ xlli_MCIO0_offset,(0x38) + .equ xlli_MCIO1_offset,(0x3C) + .equ xlli_MDMRS_offset,(0x40) + .equ xlli_BOOT_DEF_offset,(0x44) + .equ xlli_ARB_CNTL_offset,(0x48) + .equ xlli_BSCNTR0_offset,(0x4C) + .equ xlli_BSCNTR1_offset,(0x50) + .equ xlli_LCDBSCNTR_offset,(0x54) + .equ xlli_MDMRSLP_offset,(0x58) + .equ xlli_BSCNTR2_offset,(0x5C) + .equ xlli_BSCNTR3_offset,(0x60) + +@ Memory Controller bit defs + + .equ xlli_MDREFR_K0DB4,(0x20000000) @ Sync Static Clock 0 divide by 4 control/status + .equ xlli_MDREFR_K2FREE,(0x02000000) @ Set to force SDCLK[2] to be free running + .equ xlli_MDREFR_K1FREE,(0x01000000) @ Set to force SDCLK[1] to be free running + .equ xlli_MDREFR_K0FREE,(0x00800000) @ Set to force SDCLK[0] to be free running + .equ xlli_MDREFR_SLFRSH,(0x00400000) @ Self Refresh Control Status bit + .equ xlli_MDREFR_APD,(0x00100000) @ Auto Power Down bit + .equ xlli_MDREFR_K2DB2,(0x00080000) @ SDRAM clock pin 2 divide by 2 control/status + .equ xlli_MDREFR_K1DB2,(0x00020000) @ SDRAM clock pin 1 divide by 2 control/status + .equ xlli_MDREFR_K1RUN,(0x00010000) @ SDRAM clock pin 1 run/control status + .equ xlli_MDREFR_E1PIN,(0x00008000) @ SDRAM clock Enable pin 1 level control/status + .equ xlli_MDREFR_K0DB2,(0x00004000) @ Sync Static Memory Clock divide by 2 control/status + .equ xlli_MDREFR_K0RUN,(0x00002000) @ Sync Static Memory Clock Pin 0 + .equ xlli_MDREFR_E0PIN,(0x00000100) @ SDRAM clock enable pin 0 (Cotulla ONLY!!) + + .equ xlli_MDCNFG_DE0,(0x00000001) @ SDRAM enable bit for partition 0 + .equ xlli_MDCNFG_DE1,(0x00000002) @ SDRAM enable bit for partition 1 + .equ xlli_MDCNFG_DE2,(0x00010000) @ SDRAM enable bit for partition 2 + .equ xlli_MDCNFG_DE3,(0x00020000) @ SDRAM enable bit for partition 3 + .equ xlli_MDCNFG_DWID0,(0x00000004) @ SDRAM bus width (clear = 32 bits, set = 16 bits) + +@ +@ INTERNAL MEMORY CONTROLLER base address and register offsets from the base address +@ + + .equ xlli_IMEMORY_CONFIG_BASE,(0x58000000) + + .equ xlli_IMPMCR_offset,(0x00) @ Internal Memory Power Manager Control Register + .equ xlli_IMPMSR_offset,(0x08) @ Internal Memory Power Management Status Register + + +@ +@ INTERRUPT CONTROLLER base address and register offsets from the base address +@ + + .equ xlli_INTERREGS_PHYSICAL_BASE,(0x40D00000) + + .equ xlli_ICIP_offset,(0x00) @ Interrupt Controller IRQ Pending Register + .equ xlli_ICMR_offset,(0x04) @ Interrupt Controller Mask Register + .equ xlli_ICLR_offset,(0x08) @ Interrupt Controller Level Register + .equ xlli_ICFP_offset,(0x0C) @ Interrupt Controller FIQ pending Register + .equ xlli_ICPR_offset,(0x10) @ Interrupt Controller Pending Register + .equ xlli_ICCR_offset,(0x14) @ Interrupt Controller Control Register + .equ xlli_ICHP_offset,(0x18) @ Interrupt Controller Highest Priority Reg + .equ xlli_ICMR2_offset,(0xA0) @ Interrupt Controller Mask Register 2 + .equ xlli_ICLR2_offset,(0xA4) @ Interrupt Controller Level Register 2 + .equ xlli_ICCR2_offset,(0xAC) @ Interrupt Controller Control Register 2 + +@ +@ CLOCK REGISTERS base address and register offsets from the base address +@ + + .equ xlli_CLKREGS_PHYSICAL_BASE,(0x41300000) + + .equ xlli_CCCR_offset,(0x00) @ Core Clock Configuration Register + .equ xlli_CKEN_offset,(0x04) @ Clock-Enable Register + .equ xlli_OSCC_offset,(0x08) @ Oscillator Configuration Register + .equ xlli_CCSR_offset,(0x0C) @ Core Clock Status Register + + .equ xlli_CCCR_A_Bit_Mask,(0x1 << 25) @ "A" bit is bit 25 in CCCR +@ +@ OS TIMER REGISTERS base address and register offsets from the base address +@ + + .equ xlli_OSTREGS_PHYSICAL_BASE,(0x40A00000) + + .equ xlli_OSMR0_offset,(0x00) @ OS Timer Match Register 0 + .equ xlli_OSMR1_offset,(0x04) @ OS Timer Match Register 1 + .equ xlli_OSMR2_offset,(0x08) @ OS Timer Match Register 2 + .equ xlli_OSMR3_offset,(0x0C) @ OS Timer Match Register 3 + + .equ xlli_OSCR0_offset,(0x10) @ OS Timer Count Register 0 + .equ xlli_OSSR_offset,(0x14) @ OS Timer Status Register + .equ xlli_OWER_offset,(0x18) @ OS Timer Watchdog Enable Register + .equ xlli_OIER_offset,(0x1C) @ OS Timer Interrupt Enable Register + + .equ xlli_OSCR4_offset,(0x40) @ OS Timer Count Register 4 + .equ xlli_OSCR5_offset,(0x44) @ OS Timer Count Register 5 + .equ xlli_OSCR6_offset,(0x48) @ OS Timer Count Register 6 + .equ xlli_OSCR7_offset,(0x4C) @ OS Timer Count Register 7 + .equ xlli_OSCR8_offset,(0x50) @ OS Timer Count Register 8 + .equ xlli_OSCR9_offset,(0x54) @ OS Timer Count Register 9 + .equ xlli_OSCR10_offset,(0x58) @ OS Timer Count Register 10 + .equ xlli_OSCR11_offset,(0x5C) @ OS Timer Count Register 11 + + .equ xlli_OSMR4_offset,(0x80) @ OS Timer Match Register 4 + .equ xlli_OSMR5_offset,(0x84) @ OS Timer Match Register 5 + .equ xlli_OSMR6_offset,(0x88) @ OS Timer Match Register 6 + .equ xlli_OSMR7_offset,(0x8C) @ OS Timer Match Register 7 + .equ xlli_OSMR8_offset,(0x90) @ OS Timer Match Register 8 + .equ xlli_OSMR9_offset,(0x94) @ OS Timer Match Register 9 + .equ xlli_OSMR10_offset,(0x98) @ OS Timer Match Register 10 + .equ xlli_OSMR11_offset,(0x9C) @ OS Timer Match Register 11 + + .equ xlli_OMCR4_offset,(0xC0) @ OS Timer Match Control Register 4 + .equ xlli_OMCR5_offset,(0xC4) @ OS Timer Match Control Register 5 + .equ xlli_OMCR6_offset,(0xC8) @ OS Timer Match Control Register 6 + .equ xlli_OMCR7_offset,(0xCC) @ OS Timer Match Control Register 7 + .equ xlli_OMCR8_offset,(0xD0) @ OS Timer Match Control Register 8 + .equ xlli_OMCR9_offset,(0xD4) @ OS Timer Match Control Register 9 + .equ xlli_OMCR10_offset,(0xD8) @ OS Timer Match Control Register 10 + .equ xlli_OMCR11_offset,(0xDC) @ OS Timer Match Control Register 11 + + .equ xlli_OSSR_ALL,(0xFFF) @ Match register status "sticky bits" + .equ xlli_OIER_E1,(0x002) @ Interrupt enable bit for match register #1 + +@ +@ REAL TIME CLOCK (RTC) REGISTERS base address and register offsets from the base address +@ + + .equ xlli_RTCREGS_PHYSICAL_BASE,(0x04090000) + + .equ xlli_RCNR_offset,(0x00) @ RTC Counter Register + .equ xlli_RTAR_offset,(0x04) @ RTC Alarm Register + .equ xlli_RTSR_offset,(0x08) @ RTC Status Register + .equ xlli_RTTR_offset,(0x0C) @ RTC Timer Trim Register + .equ xlli_RDCR_offset,(0x10) @ RTC Day Counter Register + .equ xlli_RYCR_offset,(0x14) @ RTC Year Counter Register + .equ xlli_RDAR1_offset,(0x18) @ RTC Day Alarm Register 1 + .equ xlli_RYAR1_offset,(0x1C) @ RTC Year Alarm Register 2 + .equ xlli_RDAR2_offset,(0x20) @ RTC Day Alarm Register 2 + .equ xlli_RYAR2_offset,(0x24) @ RTC Year Alarm Register 2 + .equ xlli_SWCR_offset,(0x28) @ Stopwatch Counter Register + .equ xlli_SWAR1_offset,(0x2C) @ Stopwatch Alarm Register 1 + .equ xlli_SWAR2_offset,(0x30) @ Stopwatch Alarm Register 2 + .equ xlli_PICR_offset,(0x34) @ Periodic Interrupt Counter Register + .equ xlli_PIAR_offset,(0x38) @ Periodic Interrupt Alarm Register + + +@ Interrupt Controller bit defs + + .equ xlli_OSCC_OOK,(0x01) @ Oscillator OK bit + .equ xlli_OSCC_OON,(0x02) @ Timekeeping (32.768KHz) Osc bit + .equ xlli_OSCC_TOUT_EN,(0x04) @ Timekeeping Output enable + .equ xlli_OSCC_PIO_EN,(0x08) @ Processor Oscillator Output Enable + +@ +@ Coprocessor 15 data bits +@ + + .equ xlli_control_icache,(0x1000) @ bit 12 - i-cache bit + .equ xlli_control_btb,(0x0800) @ bit 11 - btb bit + .equ xlli_control_r,(0x0200) @ Bit 9 + .equ xlli_control_s,(0x0100) @ Bit 8 + .equ xlli_control_dcache,(0x0004) @ Bit 2 - d-cache bit + .equ xlli_control_mmu,(0x0001) @ Bit 0 - MMU bit + + +@ +@ CP 15 related settings +@ + + .equ xlli_PID,(0x00) + .equ xlli_DACR,(0x01) + .equ xlli_CONTROL_DCACHE,(0x04) + .equ xlli_CONTROL_MINIDATA_01,(0x10) + .equ xlli_CONTROL_BTB,(0x800) @ Brach Target Buffer bit + +@ +@ register bit masks - RCSR +@ + .equ xlli_RCSR_HWR,(0x01) + .equ xlli_RCSR_WDR,(0x02) + .equ xlli_RCSR_SMR,(0x04) + .equ xlli_RCSR_GPR,(0x08) + .equ xlli_RCSR_ALL,(0xF) + + +@ +@ CPSR Processor constants + + .equ xlli_CPSR_Mode_MASK,(0x0000001F) + .equ xlli_CPSR_Mode_USR,(0x10) + .equ xlli_CPSR_Mode_FIQ,(0x11) + .equ xlli_CPSR_Mode_IRQ,(0x12) + .equ xlli_CPSR_Mode_SVC,(0x13) + .equ xlli_CPSR_Mode_ABT,(0x17) + .equ xlli_CPSR_Mode_UND,(0x1B) + .equ xlli_CPSR_Mode_SYS,(0x1F) + + .equ xlli_CPSR_I_Bit,(0x80) + .equ xlli_CPSR_F_Bit,(0x40) + + + .equ xlli_PWRMODE_SLEEP,(0x00000003) @ Value for cp14: Reg7 to induce sleep. +@ Bit settings +@ + .equ xlli_BIT_0,0x00000001 + .equ xlli_BIT_1,0x00000002 + .equ xlli_BIT_2,0x00000004 + .equ xlli_BIT_3,0x00000008 + .equ xlli_BIT_4,0x00000010 + .equ xlli_BIT_5,0x00000020 + .equ xlli_BIT_6,0x00000040 + .equ xlli_BIT_7,0x00000080 + .equ xlli_BIT_8,0x00000100 + .equ xlli_BIT_9,0x00000200 + .equ xlli_BIT_10,0x00000400 + .equ xlli_BIT_11,0x00000800 + .equ xlli_BIT_12,0x00001000 + .equ xlli_BIT_13,0x00002000 + .equ xlli_BIT_14,0x00004000 + .equ xlli_BIT_15,0x00008000 + .equ xlli_BIT_16,0x00010000 + .equ xlli_BIT_17,0x00020000 + .equ xlli_BIT_18,0x00040000 + .equ xlli_BIT_19,0x00080000 + .equ xlli_BIT_20,0x00100000 + .equ xlli_BIT_21,0x00200000 + .equ xlli_BIT_22,0x00400000 + .equ xlli_BIT_23,0x00800000 + .equ xlli_BIT_24,0x01000000 + .equ xlli_BIT_25,0x02000000 + .equ xlli_BIT_26,0x04000000 + .equ xlli_BIT_27,0x08000000 + .equ xlli_BIT_28,0x10000000 + .equ xlli_BIT_29,0x20000000 + .equ xlli_BIT_30,0x40000000 + .equ xlli_BIT_31,0x80000000 + diff -Nur blob-xscale/src/blob/xlli/glencoe/xlli_Glencoe_defs.inc blob-2.0.5-pre3-glencoe05/src/blob/xlli/glencoe/xlli_Glencoe_defs.inc --- blob-xscale/src/blob/xlli/glencoe/xlli_Glencoe_defs.inc 1969-12-31 19:00:00.000000000 -0500 +++ blob-2.0.5-pre3-glencoe05/src/blob/xlli/glencoe/xlli_Glencoe_defs.inc 2005-02-19 21:44:02.000000000 -0500 @@ -0,0 +1,570 @@ +@********************************************************************************* +@ +@ Copyright (C) 2004, Intel Corporation +@ +@ This software program is licensed subject to the GNU General Public License +@ (GPL).Version 2,June 1991, available at http://www.fsf.org/copyleft/gpl.html +@ +@********************************************************************************* +@ +@ FILENAME: xlli_Glencoe_defs.inc (Platform specific addresses and +@ defalut values for Glencoe platform bring up, based on Mainstone 4-Aug-04)) +@ NOTE: - This file has a def to configure xlli for MCP and non-MCP processors +@ +@ LAST MODIFIED: 19-Feb-2005 +@ +@****************************************************************************** +@ +@ +@ Include file for Glencoe specific Cross Platform Low Level Initialization (XLLI), based in Mainstone II's +@ +@.equ xlli_SDRAM_SIZE_32_MB, 0 @ Uncomment for 32 Mb of SDRAM +@.equ xlli_SDRAM_SIZE_128_MB, 0 @ Uncomment for 128 Mb of SDRAM +@.equ xlli_SDRAM_WIDTH_16_BIT, 0 @ Uncomment for 16-bit SDRAM bus +@.equ xlli_FLASH_WIDTH_16_BIT, 0 @ Uncomment for 16-bit FLASH bus +.equ xlli_C0_BULVERDE, 0 @ Uncomment for PXA27x step C0 +@ +@ PLATFORM REGISTERS base address and register offsets from the base address +@ + .equ xlli_PLATFORM_REGISTERS,0x08000000 + .equ xlli_PLATFORM_nGREEN_LED,(0x00000002) @ Green general purpose LED, 0=on, 1=off, use GPxR1 + .equ xlli_PLATFORM_nBLUE_LED, (0x00010000) @ Blue general purpose LED, 0=on, 1=off, use GPxR2 + .equ xlli_PLATFORM_BL_PWR_ON, (0x00400000) @ Backlight power control, 0=off, 1=on, use GPxR2 + .equ xlli_PLATFORM_LCD_PWR_ON,(0x00800000) @ LCD power control, 0=off, 1=on, use GPxR2 + +@ +@ Platform specific bits +@ + .equ xlli_SYS_RESET,0x01 @ System reset bit + +@ +@ platform GPIO pin settings (Bulverde/Glencoe) +@ + .equ xlli_GPSR0_value,(0x00009A04) @ Set registers + .equ xlli_GPSR1_value,(0x03C70000) + .equ xlli_GPSR2_value,(0x0420C000) + .equ xlli_GPSR3_value,(0x001A0240) + + .equ xlli_GPCR0_value,(0x003B0000) @ Clear registers + .equ xlli_GPCR1_value,(0x00000002) + .equ xlli_GPCR2_value,(0x03C10000) + .equ xlli_GPCR3_value,(0x01841020) + + .equ xlli_GRER0_value,(0x0) @ Rising Edge Detect + .equ xlli_GRER1_value,(0x0) + .equ xlli_GRER2_value,(0x0) + .equ xlli_GRER3_value,(0x00000800) + + .equ xlli_GFER0_value,(0x08000003) @ Falling Edge Detect + .equ xlli_GFER1_value,(0x0) + .equ xlli_GFER2_value,(0x0) + .equ xlli_GFER3_value,(0x00000590) + + .equ xlli_GPLR0_value,(0x0) @ Pin Level Registers + .equ xlli_GPLR1_value,(0x0) + .equ xlli_GPLR2_value,(0x0) + .equ xlli_GPLR3_value,(0x0) + + .equ xlli_GEDR0_value,(0x0) @ Edge Detect Status + .equ xlli_GEDR1_value,(0x0) + .equ xlli_GEDR2_value,(0x0) + .equ xlli_GEDR3_value,(0x0) + + .ifdef POST_BUILD + + .equ xlli_GPDR0_value,(0xD3BB9A04) @ Direction Registers for Glencoe + .equ xlli_GPDR1_value,(0xFCFFAB83) + .equ xlli_GPDR2_value,(0x1FFFFFFF) + .equ xlli_GPDR3_value,(0x01FFF260) + + .else + + .equ xlli_GPDR0_value,(0xD3BB9A04) @ Direction Registers for Glencoe + .equ xlli_GPDR1_value,(0xFCFFAB83) @ orig. intel glencoe:0xFCFFAB83 + .equ xlli_GPDR2_value,(0x1FFFFFFF) + .equ xlli_GPDR3_value,(0x01FFF260) + .endif + + .equ xlli_GAFR0_L_value,(0x98000000) @ Alternate function registers for glencoe + .equ xlli_GAFR0_U_value,(0xA51A8092) + .equ xlli_GAFR1_L_value,(0x699A9552) + .equ xlli_GAFR1_U_value,(0xAAA5A5AA) + .equ xlli_GAFR2_L_value,(0x6AAAAAAA) + .equ xlli_GAFR2_U_value,(0x55A00400) + .equ xlli_GAFR3_L_value,(0x54000055) + .equ xlli_GAFR3_U_value,(0x000016A9) + +@ +@ MEMORY CONTROLLER SETTINGS FOR MAINSTONE +@ +@@MDREFR_VAL EQU 0x229D9019 ; SDRAM Refresh Reg (SDCLK[0]=MemClk/4, APD, SDCLK[1]=MemClk, DRI=x019) +@@ mainstone_blob:0x0000001E, mainstone_wince=0x229D9019, intel glencoe:0x20199019 + .equ xlli_MDREFR_value,(0x20199019) @ SDRAM Refresh Reg + .equ xlli_MSC0_value, (0xB2D0A2B2) + +@ .equ xlli_MSC0_DC_value,(0x7FF0B8F2) @ PXA27x Card Flash value (Non-MCP version) +@ .equ xlli_MSC0_MS_value,(0x23F2B8F2) @ Mainstone Board Flash value + + .equ xlli_MECR_value,(0x00000001) @@ Expansion memory (PCMCIA/CF) Bus Config (NOS=2, card is NOT there) + .equ xlli_MCMEM0_value,(0x0001C391) @@ Card I-face Common Mem Space socket 0 timing config + .equ xlli_MCMEM1_value,(0x0001C391) @@ Card I-face Common Mem Space socket 1 timing config + .equ xlli_MCATT0_value,(0x0001C391) @@ Card I-face Attribute Space socket 0 timing config + .equ xlli_MCATT1_value,(0x0001C391) @@ Card I-face Attribute Space socket 1 timing config + .equ xlli_MCIO0_value,(0x0001C391) @@ Card I-face I/O Space socket 0 timing config + .equ xlli_MCIO1_value,(0x0001C391) @@ Card I-face I/O Space socket 1 timing config + + .equ xlli_FLYCNFG_value,(0x00010001) @@ Fly-by-DMA config. reg (==POR: both DVALs active low) + + @@.equ xlli_MDMRSLP_value,(0x0000C008) @@ SDRAM Mode Reg Set Config Reg - Low Power + .equ xlli_MDMRSLP_value,(0x0000C048) @@ SDRAM Mode Reg Set Config Reg - changed driver strength (Glencoe_Intel) + + .equ xlli_SXCNFG_value,(0x40044004) @ Default value at boot up, Glencoe: 0x4000600D + + +@ +@ Optimal values for MSCO for various MemClk frequencies are listed below +@ These values are for L18 async flash +@ + .ifdef xlli_C0_BULVERDE + + .equ xlli_MSC0_13,(0x11101110) + .equ xlli_MSC0_19,(0x11101110) + .equ xlli_MSC0_26,(0x11201120) @ 26 MHz setting + .equ xlli_MSC0_32,(0x11201120) + .equ xlli_MSC0_39,(0x11301130) @ 39 MHz setting + .equ xlli_MSC0_45,(0x11301130) + .equ xlli_MSC0_52,(0x11401140) @ 52 MHz setting + .equ xlli_MSC0_58,(0x11401140) + .equ xlli_MSC0_65,(0x11501150) @ 65 MHz setting + .equ xlli_MSC0_68,(0x11501150) + .equ xlli_MSC0_71,(0x11501150) @ 71.5 MHz setting + .equ xlli_MSC0_74,(0x11601160) + .equ xlli_MSC0_78,(0x12601260) @ 78 MHz setting + .equ xlli_MSC0_81,(0x12601260) + .equ xlli_MSC0_84,(0x12601260) @ 84.5 MHz setting + .equ xlli_MSC0_87,(0x12701270) + .equ xlli_MSC0_91,(0x12701270) @ 91 MHz setting + .equ xlli_MSC0_94,(0x12701270) @ 94.2 MHz setting + .equ xlli_MSC0_97,(0x12701270) @ 97.5 MHz setting + .equ xlli_MSC0_100,(0x12801280) @ 100.7 MHz setting + .equ xlli_MSC0_104,(0x12801280) @ 104 MHz setting + .equ xlli_MSC0_110,(0x12901290) + .equ xlli_MSC0_117,(0x13901390) @ 117 MHz setting + .equ xlli_MSC0_124,(0x13A013A0) + .equ xlli_MSC0_130,(0x13A013A0) @ 130 MHz setting + .equ xlli_MSC0_136,(0x13B013B0) + .equ xlli_MSC0_143,(0x13B013B0) + .equ xlli_MSC0_149,(0x13C013C0) + .equ xlli_MSC0_156,(0x14C014C0) + .equ xlli_MSC0_162,(0x14C014C0) + .equ xlli_MSC0_169,(0x14C014C0) + .equ xlli_MSC0_175,(0x14C014C0) + .equ xlli_MSC0_182,(0x14C014C0) + .equ xlli_MSC0_188,(0x14C014C0) + .equ xlli_MSC0_195,(0x15C015C0) + .equ xlli_MSC0_201,(0x15D015D0) + .equ xlli_MSC0_208,(0x15D015D0) + + .else + +@ This is a hack to get around some stupid B0 timing issue where it doesn't like the optimal +@ values according to it's own SPEC!?! These timing values are relaxed from the above optimal +@ but they work for B-step PXA27x... ugh.... + + .equ xlli_MSC0_13,(0x12101210) + .equ xlli_MSC0_19,(0x12101210) + .equ xlli_MSC0_26,(0x12201220) @ 26 MHz setting + .equ xlli_MSC0_32,(0x12201220) + .equ xlli_MSC0_39,(0x13301330) @ 39 MHz setting + .equ xlli_MSC0_45,(0x13301330) + .equ xlli_MSC0_52,(0x13401340) @ 52 MHz setting + .equ xlli_MSC0_58,(0x13601360) + .equ xlli_MSC0_65,(0x13501350) @ 65 MHz setting + .equ xlli_MSC0_68,(0x13501350) + .equ xlli_MSC0_71,(0x14601460) @ 71.5 MHz setting + .equ xlli_MSC0_74,(0x14601460) + .equ xlli_MSC0_78,(0x14601460) @ 78 MHz setting + .equ xlli_MSC0_81,(0x14701470) + .equ xlli_MSC0_84,(0x14701470) @ 84.5 MHz setting + .equ xlli_MSC0_87,(0x14701470) + .equ xlli_MSC0_91,(0x14701470) @ 91 MHz setting + .equ xlli_MSC0_94,(0x14801480) @ 94.2 MHz setting + .equ xlli_MSC0_97,(0x14801480) @ 97.5 MHz setting + .equ xlli_MSC0_100,(0x15801580) @ 100.7 MHz setting + .equ xlli_MSC0_104,(0x15801580) @ 104 MHz setting + .equ xlli_MSC0_110,(0x15901590) + .equ xlli_MSC0_117,(0x15A015A0) @ 117 MHz setting + .equ xlli_MSC0_124,(0x15A015A0) + .equ xlli_MSC0_130,(0x15B015B0) @ 130 MHz setting + .equ xlli_MSC0_136,(0x16B016B0) + .equ xlli_MSC0_143,(0x16C016C0) + .equ xlli_MSC0_149,(0x16C016C0) + .equ xlli_MSC0_156,(0x16C016C0) + .equ xlli_MSC0_162,(0x16C016C0) + .equ xlli_MSC0_169,(0x17D017D0) @ Given that the optimal value would be 13 (RDF), but according to B0 manual, it's different + .equ xlli_MSC0_175,(0x17C017C0) + .equ xlli_MSC0_182,(0x17C017C0) + .equ xlli_MSC0_188,(0x17D017D0) + .equ xlli_MSC0_195,(0x17E017E0) + .equ xlli_MSC0_201,(0x18E018E0) + .equ xlli_MSC0_208,(0x18E018E0) + + .endif @ xlli_C0_BULVERDE + +@ +@ Optimal values for DTC settings for various MemClk settings (MDCNFG) +@ + .ifdef xlli_SDRAM_WIDTH_16_BIT + +@ Really, we should have yet another flag that is dependant on the SDRAM part, but since only +@ the MCP's SDRAM parameters are different than the MSII platform, I'm choosing to pick the 16-bit +@ width to trigger for the different timing values + + .equ xlli_DTC_13,(0x00000000) @ 13 MHz setting + .equ xlli_DTC_19,(0x00000000) @ 19 MHz setting + .equ xlli_DTC_26,(0x00000000) @ 26 MHz setting + .equ xlli_DTC_32,(0x00000000) @ 32 MHz setting + .equ xlli_DTC_39,(0x01000100) @ 39 MHz setting + .equ xlli_DTC_45,(0x01000100) @ 45 MHz setting + .equ xlli_DTC_52,(0x01000100) @ 52 MHz setting + .equ xlli_DTC_58,(0x01000100) @ 58 MHz setting + .equ xlli_DTC_65,(0x01000100) @ 65 MHz setting + .equ xlli_DTC_68,(0x02000200) @ 68 MHz setting + .equ xlli_DTC_71,(0x02000200) @ 71 MHz setting + .equ xlli_DTC_74,(0x02000200) @ 74 MHz setting + .equ xlli_DTC_78,(0x02000200) @ 78 MHz setting + .equ xlli_DTC_81,(0x02000200) @ 81 MHz setting + .equ xlli_DTC_84,(0x02000200) @ 84 MHz setting + .equ xlli_DTC_87,(0x02000200) @ 87 MHz setting + .equ xlli_DTC_91,(0x02000200) @ 91 MHz setting + .equ xlli_DTC_94,(0x02000200) @ 94 MHz setting + .equ xlli_DTC_97,(0x02000200) @ 97 MHz setting + .equ xlli_DTC_100,(0x03000300) @ 100 MHz setting + .equ xlli_DTC_104,(0x03000300) @ 104 MHz setting + .equ xlli_DTC_110,(0x01000100) @ 110 MHz setting - SDCLK Halved + .equ xlli_DTC_117,(0x01000100) @ 117 MHz setting - SDCLK Halved + .equ xlli_DTC_124,(0x01000100) @ 124 MHz setting - SDCLK Halved + .equ xlli_DTC_130,(0x02000200) @ 130 MHz setting - SDCLK Halved + .equ xlli_DTC_136,(0x02000200) @ 136 MHz setting - SDCLK Halved + .equ xlli_DTC_143,(0x02000200) @ 143 MHz setting - SDCLK Halved + .equ xlli_DTC_149,(0x02000200) @ 149 MHz setting - SDCLK Halved + .equ xlli_DTC_156,(0x02000200) @ 156 MHz setting - SDCLK Halved + .equ xlli_DTC_162,(0x02000200) @ 162 MHz setting - SDCLK Halved + .equ xlli_DTC_169,(0x02000200) @ 169 MHz setting - SDCLK Halved + .equ xlli_DTC_175,(0x02000200) @ 175 MHz setting - SDCLK Halved + .equ xlli_DTC_182,(0x02000200) @ 182 MHz setting - SDCLK Halved + .equ xlli_DTC_188,(0x02000200) @ 188 MHz setting - SDCLK Halved + .equ xlli_DTC_195,(0x02000200) @ 195 MHz setting - SDCLK Halved + .equ xlli_DTC_201,(0x03000300) @ 201 MHz setting - SDCLK Halved + .equ xlli_DTC_208,(0x03000300) @ 208 MHz setting - SDCLK Halved +@ +@ Optimal values for DRI settings for various MemClk settings (MDREFR) +@ + .equ xlli_DRI_13,(0x002) @ 13 MHz setting + .equ xlli_DRI_19,(0x003) + .equ xlli_DRI_26,(0x004) @ 26 MHz setting + .equ xlli_DRI_32,(0x006) + .equ xlli_DRI_39,(0x007) @ 39 MHz setting + .equ xlli_DRI_45,(0x009) + .equ xlli_DRI_52,(0x00A) @ 52 MHz setting + .equ xlli_DRI_58,(0x00C) + .equ xlli_DRI_65,(0x00D) @ 65 MHz setting + .equ xlli_DRI_68,(0x00E) + .equ xlli_DRI_71,(0x00F) @ 71 MHz setting + .equ xlli_DRI_74,(0x010) + .equ xlli_DRI_78,(0x010) @ 78 MHz setting + .equ xlli_DRI_81,(0x011) + .equ xlli_DRI_84,(0x012) @ 84 MHz setting + .equ xlli_DRI_87,(0x013) + .equ xlli_DRI_91,(0x013) @ 91 MHz setting + .equ xlli_DRI_94,(0x014) @ 94 MHz setting + .equ xlli_DRI_97,(0x015) @ 97 MHz setting + .equ xlli_DRI_100,(0x016) @ 100 MHz setting + .equ xlli_DRI_104,(0x016) @ 104 MHz setting + .equ xlli_DRI_110,(0x018) + .equ xlli_DRI_117,(0x019) @ 117 MHz setting + .equ xlli_DRI_124,(0x01B) + .equ xlli_DRI_130,(0x01C) @ 130 MHz setting + .equ xlli_DRI_136,(0x01E) + .equ xlli_DRI_143,(0x01F) + .equ xlli_DRI_149,(0x021) + .equ xlli_DRI_156,(0x022) + .equ xlli_DRI_162,(0x024) + .equ xlli_DRI_169,(0x025) @ 169 MHz setting + .equ xlli_DRI_175,(0x027) + .equ xlli_DRI_182,(0x028) + .equ xlli_DRI_188,(0x02A) + .equ xlli_DRI_195,(0x02B) + .equ xlli_DRI_201,(0x02D) + .equ xlli_DRI_208,(0x02E) @ 208 MHz setting + + .else @ ELSE not 16 bit SDRAM width + + .equ xlli_DTC_13,(0x00000000) @ 13 MHz setting + .equ xlli_DTC_19,(0x00000000) @ 19 MHz setting + .equ xlli_DTC_26,(0x00000000) @ 26 MHz setting + .equ xlli_DTC_32,(0x00000000) @ 32 MHz setting + .equ xlli_DTC_39,(0x00000000) @ 39 MHz setting + .equ xlli_DTC_45,(0x00000000) @ 45 MHz setting + .equ xlli_DTC_52,(0x00000000) @ 52 MHz setting + .equ xlli_DTC_58,(0x01000100) @ 58 MHz setting + .equ xlli_DTC_65,(0x01000100) @ 65 MHz setting + .equ xlli_DTC_68,(0x01000100) @ 68 MHz setting + .equ xlli_DTC_71,(0x01000100) @ 71 MHz setting + .equ xlli_DTC_74,(0x01000100) @ 74 MHz setting + .equ xlli_DTC_78,(0x01000100) @ 78 MHz setting + .equ xlli_DTC_81,(0x01000100) @ 81 MHz setting + .equ xlli_DTC_84,(0x01000100) @ 84 MHz setting + .equ xlli_DTC_87,(0x01000100) @ 87 MHz setting + .equ xlli_DTC_91,(0x02000200) @ 91 MHz setting + .equ xlli_DTC_94,(0x02000200) @ 94 MHz setting + .equ xlli_DTC_97,(0x02000200) @ 97 MHz setting + .equ xlli_DTC_100,(0x02000200) @ 100 MHz setting + .equ xlli_DTC_104,(0x02000200) @ 104 MHz setting + .equ xlli_DTC_110,(0x01000100) @ 110 MHz setting - SDCLK Halved + .equ xlli_DTC_117,(0x01000100) @ 117 MHz setting - SDCLK Halved + .equ xlli_DTC_124,(0x01000100) @ 124 MHz setting - SDCLK Halved + .equ xlli_DTC_130,(0x01000100) @ 130 MHz setting - SDCLK Halved + .equ xlli_DTC_136,(0x01000100) @ 136 MHz setting - SDCLK Halved + .equ xlli_DTC_143,(0x01000100) @ 143 MHz setting - SDCLK Halved + .equ xlli_DTC_149,(0x01000100) @ 149 MHz setting - SDCLK Halved + .equ xlli_DTC_156,(0x01000100) @ 156 MHz setting - SDCLK Halved + .equ xlli_DTC_162,(0x01000100) @ 162 MHz setting - SDCLK Halved + .equ xlli_DTC_169,(0x01000100) @ 169 MHz setting - SDCLK Halved + .equ xlli_DTC_175,(0x01000100) @ 175 MHz setting - SDCLK Halved + .equ xlli_DTC_182,(0x02000200) @ 182 MHz setting - SDCLK Halved - Close to edge, so bump up + .equ xlli_DTC_188,(0x02000200) @ 188 MHz setting - SDCLK Halved - Close to edge, so bump up + .equ xlli_DTC_195,(0x02000200) @ 195 MHz setting - SDCLK Halved - Close to edge, so bump up + .equ xlli_DTC_201,(0x02000200) @ 201 MHz setting - SDCLK Halved - Close to edge, so bump up + .equ xlli_DTC_208,(0x02000200) @ 208 MHz setting - SDCLK Halved - Close to edge, so bump up +@ +@ Optimal values for DRI settings for various MemClk settings (MDREFR) +@ + .equ xlli_DRI_13,(0x002) @ 13 MHz setting + .equ xlli_DRI_19,(0x003) + .equ xlli_DRI_26,(0x005) @ 26 MHz setting + .equ xlli_DRI_32,(0x006) + .equ xlli_DRI_39,(0x008) @ 39 MHz setting + .equ xlli_DRI_45,(0x00A) + .equ xlli_DRI_52,(0x00B) @ 52 MHz setting + .equ xlli_DRI_58,(0x00D) + .equ xlli_DRI_65,(0x00E) @ 65 MHz setting + .equ xlli_DRI_68,(0x00F) + .equ xlli_DRI_71,(0x010) @ 71 MHz setting + .equ xlli_DRI_74,(0x011) + .equ xlli_DRI_78,(0x012) @ 78 MHz setting + .equ xlli_DRI_81,(0x012) + .equ xlli_DRI_84,(0x013) @ 84 MHz setting + .equ xlli_DRI_87,(0x014) + .equ xlli_DRI_91,(0x015) @ 91 MHz setting + .equ xlli_DRI_94,(0x016) @ 94 MHz setting + .equ xlli_DRI_97,(0x016) @ 97 MHz setting + .equ xlli_DRI_100,(0x017) @ 100 MHz setting + .equ xlli_DRI_104,(0x018) @ 104 MHz setting + .equ xlli_DRI_110,(0x01A) + .equ xlli_DRI_117,(0x01B) @ 117 MHz setting + .equ xlli_DRI_124,(0x01D) + .equ xlli_DRI_130,(0x01E) @ 130 MHz setting + .equ xlli_DRI_136,(0x020) + .equ xlli_DRI_143,(0x021) + .equ xlli_DRI_149,(0x023) + .equ xlli_DRI_156,(0x025) + .equ xlli_DRI_162,(0x026) + .equ xlli_DRI_169,(0x028) @ 169 MHz setting + .equ xlli_DRI_175,(0x029) + .equ xlli_DRI_182,(0x02B) + .equ xlli_DRI_188,(0x02D) + .equ xlli_DRI_195,(0x02E) + .equ xlli_DRI_201,(0x030) + .equ xlli_DRI_208,(0x031) @ 208 MHz setting + + .endif @ xlli_SDRAM_WIDTH_16_BIT + +@ +@ SDRAM Settings +@ + .ifdef xlli_SDRAM_WIDTH_16_BIT + .equ xlli_MDCNFG_value,(0x00002BCC) @ SDRAM Config Reg (MCP Version) + .else + .equ xlli_MDCNFG_value,(0x09C00BCB) @ SDRAM Config Reg (Non-MCP Version) + .endif + + .equ xlli_MDMRS_value,(0x00000000) @ SDRAM Mode Reg Set Config Reg (MDMRS1: burst reads & writes) + +@ +@ MEMORY PHYSICAL BASE ADDRESS(S) +@ + + .equ xlli_SRAM_PHYSICAL_BASE,(0X5C000000) @ Physical base address for SRAM + .equ xlli_SDRAM_PHYSICAL_BASE,(0xA0000000) @ Physical base address for SDRAM + +@ +@ CORE, SYSTEM BUS, MEMORY BUS Default frequency setting for Mainstone +@ + .equ xlli_CCCR_value,(0x00000107) @ PXA27x (HW reset value to start) +@ +@ Clock Enable Register (CKEN) setting +@ + .equ xlli_CKEN_value,(0x00400200) @ Data to be set into the clock enable register + @ Bit 6 enables FFUART + @ bit 9 enables OS timers + @ Bit 22 enables memory clock +@ +@ Address where system configuration data is stored +@ + .equ xlli_SCR_data,0x5C03FFFC @ Address of system config data + +@ +@ Misc constants +@ + .equ xlli_MemSize_1Mb,0x00100000 + .ifdef xlli_SDRAM_SIZE_32_MB + .equ xlli_p_PageTable,0xA1FFC000 @ Base address for memory Page Table (MCP version) + .else + .equ xlli_p_PageTable,0xA3FFC000 @ Base address for memory Page Table (Non-MCP version) + .endif + .equ xlli_s_PageTable,0x00004000 @ Page Table size (4K words - 16 Kb) + + + .equ xlli_FLASH_WRITE_CMD,0x0060 @ Code for writing to flash + .equ xlli_FLASH_WCONF_CMD,0x0003 @ Code to confirm write to flash + .equ xlli_FLASH_READ_CMD,0x00FF @ Code to place flash in read mode + .equ xlli_FLASH_READQUERY_CMD,0x0098 @ Code to place flash in a 'query CFI' mode + +@ +@ Note 1: For the current L3/L18 flash, it has a maximium frequency of 52MHz. In addition, the SXCNFG.LC value is based on the +@ SDClk presented to the flash, not the MEMClk as with most other Memory Controller settings, a bit odd, but so be it. +@ +@ Note 2: We have just optimized these values for 52MHz SDClk to the Flash part. The OEM could optimize this for other SDClk values, +@ but as there are so many, and the predominant Intel supported frequencies put the flash part into 52MHz operation, it +@ made more sense to focus on the code, as each OEM will decide how best to run/optimize their platform. +@ +@ Explaination of RCR value: +@ +@ Read Mode = 0x0 = Sync. Mode +@ Latency Count = 0x5 +@ Wait Polarity = 0x0 = Wait active low +@ Data Hold = 0x0 = Hold for 1 clock +@ Wait Delay = 0x1 = Wait de-asserted 1 dcycle before valid data +@ Burst Sequence = 0x1 = Linear +@ Clock Edge = 0x1 = Rising +@ Burst Wrap = 0x0 = wrap +@ Burst length = 0x3 = 16 word burst +@ +@ Note on Burst Length: Spacial locality suggests that having a burst of 16 will give better results than that of 8, however, +@ be aware that 8 words is a cache line, so it may be more beneficial to revert to a burst length of 8 words per +@ burst as opposed to 16 words per burst +@ + .equ xlli_FLASH_RCR16_value,0x25C3<<1 @ Value to set flash into sync mode - optimal RC.LC value for 52MHz flash is 5 + .equ xlli_FLASH_RCR32_value,0x25C3<<2 @ Value to set flash into sync mode - optimal RC.LC value for 52MHz flash is 5 + +@ +@ Value below is simply to align with the settings put in for the flash RCR value +@ + .equ xlli_SXCNFG_sync_value,0x7011 @ SXCNFG value for sync flash operation - optimal SXCNFG.LC value for 52MHz flash is 4 + +@ +@ Values to put the flash back into Asynchronous mode +@ + .equ xlli_FLASH_ASYNC_RCR16_value,0xA5C2<<1 @ Value to set flash into sync mode - optimal RC.LC value for 52MHz flash is 5 + .equ xlli_FLASH_ASYNC_RCR32_value,0xA5C2<<2 @ Value to set flash into sync mode - optimal RC.LC value for 52MHz flash is 5 + .equ xlli_SXCNFG_async_value,0x7010 @ SXCNFG value for sync flash operation - optimal SXCNFG.LC value for 52MHz flash is 4 + + +@ +@ Types of flash that XLLI can discover include: +@ +@ TYPE CODE RANGE +@ ---- ---------------- +@ J3 = 0x16 -> 0x18 +@ K3 = 0x8801 -> 0x8803 +@ K18 = 0x8805 -> 0x8807 +@ L18 = 0x880E -> 0x8810 +@ L3 = 0x8812 -> 0x8815 +@ + .equ xlli_J3_FlashID_Code,0x0018 @ return value of J3 in parallel mode + .equ xlli_K3_FlashID_Code,0x8803 @ use the upper (so can compare as <= + .equ xlli_K18_FlashID_Code,0x8807 @ use the upper (so can compare as <= + .equ xlli_L18_FlashID_Code,0x8810 @ use the upper (so can compare as <= + .equ xlli_L3_FlashID_Code,0x8815 @ use the upper (so can compare as <= + + +@ +@ Special conditional required for Power On SelfTest (POST) build +@ + .ifdef POST_BUILD + .equ xlli_v_xbBOOTROM,0x04000000 @ Required for POST + .else + .equ xlli_v_xbBOOTROM,0x00000000 @ Everything else + .endif + + +@ xlli_CLOCK_SWITCH_* contain the clock settings like used in former switch-based Mainstone board +@ The bit assignments remain the same +@ +@ *** Change the values below for adapting clock settings +@ +@ Bit 0-6: encodes L and N (see table below ) + .equ xlli_CLOCK_SWITCH_L_N, (0x63) @ see table below + .equ xlli_CLOCK_SWITCH_CCCR_A, (0x0 << 7) @ Bit 7: Memory controller CLK. 1 -> CLK=13*L/2, 0 -> CLK=13*L/M + @ where M = 1(L=2-10), M = 2(L=11-20), or M = 4(L=21-31) + .equ xlli_CLOCK_SWITCH_FASTBUS,(0x0 << 8) @ Bit 8: Fast/Normal bus speed (! not supported at all for C0 stepping!) + @ If hex switch setting is 0x5A - 0x7F or 0xDA and greater, the Fast Bus mode bit must be cleared + .equ xlli_CLOCK_SWITCH_SDCLK, (0x1 << 9) @ Bit 9: for SDCLK setting (MemClk/2 or MemClock) + .equ xlli_CLOCK_SWITCH_TURBO, (0x1 << 10) @ Bit 10: for Turbo or non-Turbo mode + +@ Turbo-mode frequency T = 13MHz * L * N +@ Run-mode frequency R = 13MHz * L +@ System-bus frequency = 13MHz * L / 2 (normal bus speed) +@ = 13MHz * L (fast bus speed, not supported for C0 stepping!) +@ Memory controller freq = 13MHz * L / M (M=1, 2 or 4) +@ LCD frequency = 13MHz * L / K (where K = 1 (L = 2-7), K = 2 (L = 8-16), or K = 4 (L = 17-31) ) +@ +@ Example: (SDCLK=1, FastBus=0) + +@ L=19,N=2 ->0x63, CCCR_A=0, TURBO=1 : T=494MHz, SysBud=124MHz, Mem=124MHz, LCD=62MHz + +@ L=20,N=2 ->0x66, CCCR_A=0, TURBO=1 : T=520MHz, SysBus=130MHz, Mem=130MHz, LCD=65MHz + +@ L=22,N=1.5->0x6A, CCCR_A=1, TURBO=1 : T=429MHz, SysBus=143MHz, Mem=143MHz, LCD=71MHz May be unstable +@ L=24,N=1.5->0x6E, CCCR_A=1, TURBO=1 : T=468MHz, SysBus=156MHz, Mem=156MHz, LCD=78MHz ! Crash! + +@ L=31,N=1 ->0x77, CCCR_A=0, TURBO=0 : T=R=403MHz,SysBus=201MHz, Mem=101MHz, LCD=101MHz +@ L=31,N=1 ->0x77, CCCR_A=1, TURBO=0 : T=R=403MHz,SysBus=201MHz, Mem=201MHz, LCD=101MHz ! Crash! + +@ Lookup table for xlli_CLOCK_SWITCH_L_N +@ "00" L=2, N=1 @ "01" L=2, N=1.5 @ "02" L=2, N=2 @ "03" L=2, N=2.5 +@ "04" L=2, N=3 @ "05" L=2, N=3.5 @ "06" L=2, N=4 @ "07" L=3, N=1 +@ "08" L=3, N=1.5 @ "09" L=3, N=2 @ "0A" L=3, N=2.5 @ "0B" L=3, N=3 +@ "0C" L=3, N=3.5 @ "0D" L=3, N=4 @ "0E" L=4, N=1 @ "0F" L=4, N=1.5 +@ "10" L=4, N=2 @ "11" L=4, N=2.5 @ "12" L=4, N=3 @ "13" L=4, N=3.5 +@ "14" L=4, N=4 @ "15" L=5, N=1 @ "16" L=5, N=1.5 @ "17" L=5, N=2 +@ "18" L=5, N=2.5 @ "19" L=5, N=3 @ "1A" L=5, N=3.5 @ "1B" L=5, N=4 +@ "1C" L=6, N=1 @ "1D" L=6, N=1.5 @ "1E" L=6, N=2 @ "1F" L=6, N=2.5 +@ "20" L=6, N=3 @ "21" L=6, N=3.5 @ "22" L=6, N=4 @ "23" L=7, N=1 +@ "24" L=7, N=1.5 @ "25" L=7, N=2 @ "26" L=7, N=2.5 @ "27" L=7, N=3 +@ "28" L=7, N=3.5 @ "29" L=7, N=4 @ "2A" L=8, N=1 @ "2B" L=8, N=1.5 +@ "2C" L=8, N=2 @ "2D" L=8, N=2.5 @ "2E" L=8, N=3 @ "2F" L=8, N=3.5 +@ "30" L=8, N=4 @ "31" L=9, N=1 @ "32" L=9, N=1.5 @ "33" L=9, N=2 +@ "34" L=9, N=2.5 @ "35" L=9, N=3 @ "36" L=9, N=3.5 @ "37" L=9, N=4 +@ "38" L=10, N=1 @ "39" L=10, N=1.5 @ "3A" L=10, N=2 @ "3B" L=10, N=2.5 +@ "3C" L=10, N=3 @ "3D" L=10, N=3.5 @ "3E" L=10, N=4 @ "3F" L=11, N=1 +@ "40" L=11, N=1.5 @ "41" L=11, N=2 @ "42" L=11, N=2.5 @ "43" L=11, N=3 +@ "44" L=11, N=3.5 @ "45" L=12, N=1 @ "46" L=12, N=1.5 @ "47" L=12, N=2 +@ "48" L=12, N=2.5 @ "49" L=12, N=3 @ "4A" L=13, N=1 @ "4B" L=13, N=1.5 +@ "4C" L=13, N=2 @ "4D" L=13, N=2.5 @ "4E" L=13, N=3 @ "4F" L=14, N=1 +@ "50" L=14, N=1.5 @ "51" L=14, N=2 @ "52" L=14, N=2.5 @ "53" L=15, N=1 +@ "54" L=15, N=1.5 @ "55" L=15, N=2 @ "56" L=15, N=2.5 @ "57" L=16, N=1 +@ "58" L=16, N=1.5 @ "59" L=16, N=2 @ "5A" L=16, N=2.5 @ "5B" L=17, N=1 +@ "5C" L=17, N=1.5 @ "5D" L=17, N=2 @ "5E" L=18, N=1 @ "5F" L=18, N=1.5 +@ "60" L=18, N=2 @ "61" L=19, N=1 @ "62" L=19, N=1.5 @ "63" L=19, N=2 +@ "64" L=20, N=1 @ "65" L=20, N=1.5 @ "66" L=20, N=2 @ "67" L=21, N=1 +@ "68" L=21, N=1.5 @ "69" L=22, N=1 @ "6A" L=22, N=1.5 @ "6B" L=23, N=1 +@ "6C" L=23, N=1.5 @ "6D" L=24, N=1 @ "6E" L=24, N=1.5 @ "6F" L=25, N=1 +@ "70" L=25, N=1.5 @ "71" L=26, N=1 @ "72" L=26, N=1.5 @ "73" L=27, N=1 +@ "74" L=28, N=1 @ "75" L=29, N=1 @ "76" L=30, N=1 @ "77" L=31, N=1 +@ "78" L=14, N=3 for 546 MHz Turbo Mode @ "79" L=15, N=3 for 585 MHz Turbo Mode +@ "7A" L=16, N=3 for 624 MHz Turbo Mode @ "7B" L=31, N=1 (same values as "77") +@ "7C" L=31, N=1 (same values as "77") @ "7D" L=31, N=1 (same values as "77") +@ "7E" L=31, N=1 (same values as "77") @ "7F" L=31, N=1 (same values as "77") + diff -Nur blob-xscale/src/blob/xlli/glencoe/xlli_LowLev_Init.s blob-2.0.5-pre3-glencoe05/src/blob/xlli/glencoe/xlli_LowLev_Init.s --- blob-xscale/src/blob/xlli/glencoe/xlli_LowLev_Init.s 1969-12-31 19:00:00.000000000 -0500 +++ blob-2.0.5-pre3-glencoe05/src/blob/xlli/glencoe/xlli_LowLev_Init.s 2005-04-23 18:13:19.000000000 -0400 @@ -0,0 +1,3042 @@ +@---------------------------------------------------------------------------------------- +@ +@ Copyright (C) 2004, Intel Corporation +@ +@ This software program is licensed subject to the GNU General Public License +@ (GPL).Version 2,June 1991, available at http://www.fsf.org/copyleft/gpl.html +@ +@********************************************************************************* +@ +@ FILENAME: xlli_LowLev_Init.s +@ +@ PURPOSE: Provides low Level init procedures written specifically for +@ the PXA27x/Glencoe platform. (based on Mainstone II code 4-Aug-04) +@ Changes by Matthias Ihmig +@ +@ LAST MODIFIED: 19-Feb-2005 +@ +@****************************************************************************** +@ +@ The functions in this source code are using the branch with link instruction. +@ Unless otherwise specified, no system stack is assumed and no registers are preserved. +@ +@ NOTES: +@ +@ The use of these subroutines and/or the order in which they are called is, for the most part, +@ arbitrary and is left up to the user. Only a few subroutines must be called in a specific order. +@ For example, it makes no sense to go to virtual mode before the MMU is initialized and +@ the page table is set up.... and, in order to set up the page table, memory needs to be initialized +@ first. +@ + .include "xlli_Bulverde_defs.inc" @ PXA27x specific include file + .include "xlli_Glencoe_defs.inc" @ Glencoe specific include file + .include "xlli_LowLev_mac.mac" @ Glencoe Macro definitions + + + @NOT SUPPORTED: AREA "|text|, CODE, READONLY, ALIGN=5" @ Align =5 required for "ALIGN 32" feature to work. +@ +@ List of Low Level Init functions in this source code include: +@ + .global xlli_read_SCR @ Reads the SCR and LCDR virtural registers and places in SRAM + .global xlli_GPIO_init @ Get SCR and LCDCR data and Initialize the GPIO ports + .global xlli_mem_init @ Memory controller initialization + .global xlli_mem_restart @ Restart memory controller + .global xlli_mem_Tmax @ Sets maximum memory configuration values + .global xlli_mem_Topt @ Sets optimal memory configuration values based on MemClk frequency + .global xlli_intr_init @ Interrupt initialization (masks all interrupts) + .global xlli_freq_change @ Frequency change sequence + .global xlli_clks_init @ Initialize system clocks + .global xlli_clks_init_sleepReset @ Initialize system clock after a sleep reset + .global xlli_ost_init @ Initalize Operating System Timers + .global xlli_icache_enable @ Enable I-Cache, D-Cache, and Branch Target Buffer + .global xlli_pwrmgr_init @ Initialize the Power Manager + .global xlli_setPTB @ Set the Page Table Base address (used for sleep resets) + .global xlli_initPageTable @ Initialize Page Table for MMU unit + .global xlli_MMU_init @ Initialize the Memory Management Unit + .global xlli_goVirtual @ Make the transition from physical address to virtual address + .global xlli_IMpwr_init @ Initialize Internal Memory for use + .global GetSCR @ Returns System Configuration Register data to 'C' program caller + .global xlli_setClocks @ Reads platform switchs and sets PXA27x frequencies + .global xlli_getFreq @ Returns current system clock settings to 'C' program caller + .global xlli_setBufImpedance @ Sets SCRAM buffer impedance (C callable) + .global xlli_setBufImp @ Sets SCRAM buffer impedance (ROM callable) + .global xlli_enableSyncFlash @ Sets flash memory into synchronous mode + .global xlli_disableSyncFlash @ Sets flash memory into asynchronous mode + .global xlli_isMemBusWidth16Bit @ Checks the BOOT_SEL bit to determine bus width + .global xlli_queryFlash @ Queries the Flash CFI ID register + + + +@******************************************************************************************** +@ +@ ********************************************************* +@ ********** ********** +@ ********** READ SYSTEM CONFIGURATION REGISTERS ********** +@ ********** ********** +@ ********************************************************* +@ +@ This subroutine will reconfigure the GPIO pins in order to read the SCR (system +@ Configuration Register) and the LCDCR (LCD Configuration Register) and place this +@ information into SRAM for use by other programs. +@ +@ Once these virtural register have been read, the GPIOs are reconfigured to their +@ previous state. +@ +@ NOTES: Written for the PXA27x Processor on the Glencoe/Mainstone Development Platform. +@ +@ This subroutine uses and DOES NOT PRESERVE registers r1, r2, r3, r4, r5, r6, r7, r8 and r9 +@ + +xlli_read_SCR: +@ +@ Insure the RDH and PH bits on PXA27x must be clear to enable GPIO pins. +@ They are sticky bits so they must be set to clear them. +@ + ldr r4, =xlli_PMRCREGS_PHYSICAL_BASE + mov r2, #(xlli_PSSR_PH | xlli_PSSR_RDH) @ Set the PH and RDH bits to enable all GPIOs + str r2, [r4, #xlli_PSSR_offset] @ Enable all GPIO lines + + +@ +@ Get, and save the present GPIO settings for direction registers 0, 1 and 2 +@ + ldr r4, =xlli_GPIOREGS_PHYSICAL_BASE @ Get the GPIO registers base address + ldr r5, [r4, #xlli_GPDR1_offset] @ Save direction values for GPIOs [63:32] + ldr r6, [r4, #xlli_GPDR2_offset] @ Save direction values for GPIOs [95:64] + ldr r7, [r4, #xlli_GAFR1_U_offset] @ Save alt function values for GPIOs [63:48] + ldr r8, [r4, #xlli_GAFR2_L_offset] @ Save alt function values for GPIOs [79:64] + ldr r9, [r4, #xlli_GAFR2_U_offset] @ Save alt function values for GPIOs [95:80] + +@ +@ Clear the bits of those GPIOs we need to read as inputs and write back to the GPIO +@ direction registers. The alternate function bits also need to be cleared. For this +@ particular code sequence "Magic Numbers" are used for the bit clear masks. +@ +@ To cut down on the number of registers used we'll do GPDR1 and GPDR2 now and take care of +@ GPDR0 (and it's alternate function bits) later. Because this code is usually run very early +@ in the boot sequence (before SDRAM is brought up) the code assumes there is no stack to +@ preserve the contents of the registers used. +@ + ldr r2, =0xFC000000 @ Register clear mask for GPDR1 + bic r1, r5, r2 @ Clear the bits we need to read in GPDR1 + str r1, [r4, #xlli_GPDR1_offset] @ Write direction values for GPIOs [63:32] + + ldr r2, =0x00C02FFF @ Register clear mask for GPDR2 + bic r1, r6, r2 @ Clear the bits we need to read in GPDR2 + str r1, [r4, #xlli_GPDR2_offset] @ Write direction values for GPIOs [95:64] +@ +@ Clear the alternate function bits for the direction bits we need to look at. +@ + ldr r2, =0xFFF00000 @ Register clear mask for GAFR1_U + bic r1, r7, r2 @ Clear the alt func for bits we need to read in GAFR1_U + str r1, [r4, #xlli_GAFR1_U_offset] @ Write alt function values for GPIOs [63:48] + + ldr r2, =0x0CFFFFFF @ Register clear mask for GAFR2_L + bic r1, r8, r2 @ Clear the alt func for bits we need to read in GAFR2_L + str r1, [r4, #xlli_GAFR2_L_offset] @ Write alt function values for GPIOs [79:64] + + ldr r2, =0x0000F000 @ Register clear mask for GAFR2_U + bic r1, r9, r2 @ Clear the alt func for bits we need to read in GAFR2_U + str r1, [r4, #xlli_GAFR2_U_offset] @ Write alt function values for GPIOs [95:80] + + mov r1, #0x200 +xlli_1: subs r1, r1, #1 @ Short delay required to allow the new GPIO... + bne xlli_1 @ ...settings to take effect +@ +@ With the GPIO direction registers set, the Platform System Configuration Register is read +@ from GPIO bits 73:58 and are stored in SRAM. +@ This data is placed in the UPPER 16 BITS (31:16) of this register. +@ + ldr r1, [r4, #xlli_GPLR1_offset] @ Get levels for GPIOs [63:32] + mov r1, r1, LSR #10 @ Move the data 10 bits to the right + ldr r2, [r4, #xlli_GPLR2_offset] @ Get levels for GPIOs [95:64] + mov r3, r2 @ Save a copy for future reference + mov r2, r2, LSL #22 @ Move the data 22 bits to the left + orr r1, r1, r2 @ This places GPIO data bits [73:58] into bits [31:16] + ldr r2, =0xFFFF0000 @ Mask word + and r1, r1, r2 @ Make sure the bottom 16 bits are clear +@ +@ Restore GPDR1, GPDR2, GAFR1_U, GAFR2_L and GAFR2_U to their original values +@ + str r5, [r4, #xlli_GPDR1_offset] @ Restore direction values for GPIOs [63:32] + str r6, [r4, #xlli_GPDR2_offset] @ Restore direction values for GPIOs [95:64] + str r7, [r4, #xlli_GAFR1_U_offset] @ Restore alt function values for GPIOs [63:48] + str r8, [r4, #xlli_GAFR2_L_offset] @ Restore alt function values for GPIOs [79:64] + str r9, [r4, #xlli_GAFR2_U_offset] @ Restore alt function values for GPIOs [95:80] +@ +@ Configure GPDR0, GAFR0_L and GAFR0_U to pick up four status bits we need from this word +@ NOTE: The values in r1 and r4 must be preserved through this section of code. +@ + ldr r5, [r4, #xlli_GPDR0_offset] @ Save direction values for GPIOs [31:0] + ldr r6, [r4, #xlli_GAFR0_L_offset] @ Save alt function values for GPIOs [15:0] + ldr r7, [r4, #xlli_GAFR0_U_offset] @ Save alt function values for GPIOs [31:16] + + ldr r2, =0xC0084000 @ Register clear mask for GPDR0 + bic r8, r5, r2 @ Clear the bits we need to read in GPDR0 + str r8, [r4, #xlli_GPDR0_offset] @ Write direction values for GPIOs [31:0] +@ +@ Clear the alternate function bits for the direction bits we need to look at. +@ + ldr r2, =0x30000000 @ Register clear mask for GAFR0_L + bic r8, r6, r2 @ Clear the alt func for bits we need to read in GAFR0_L + str r8, [r4, #xlli_GAFR0_L_offset] @ Write alt function values for GPIOs [15:0] + + ldr r2, =0xF00000C0 @ Register clear mask for GAFR0_U + bic r8, r7, r2 @ Clear the alt func for bits we need to read in GAFR0_U + str r8, [r4, #xlli_GAFR0_U_offset] @ Write alt function values for GPIOs [31:16] + + mov r2, #0x200 +xlli_2: subs r2, r2, #1 @ Short delay required to allow the new GPIO... + bne xlli_2 @ ...settings to take effect +@ +@ The data that makes up the LCDCR registar (GPIO bits 87, 86, 77, 75, 74, 19, and 14) are +@ stored in bits 6:0 of the PSPR. The xlli code does not use this data - it is only placed +@ into the PSPR to make the data accessable to other users who can then take the data and +@ store it elsewhere or simply ignore it and write over it. +@ +@ The SCR data is in the upper 16 bits of r1. Now the data for the LCDCR register needs +@ to be assembled from data saved in r3 in addition to two bits to be read from GPIOs 31:0 +@ and this data needs to be ORed into r1 as well. +@ + and r2, r3, #0x2000 @ isolate bit 77 + mov r2, r2, LSR #9 @ Move to bit position #4 + + and r8, r3, #0xC00 @ Extract bits 75:74 + mov r8, r8, LSR #8 @ Move GPIO bits 75:74 to bit position 3:2 + orr r2, r2, r8 @ Save these two bits into r2 + + and r8, r3, #0xC00000 @ Extract bits 87:86 + mov r8, r8, LSR #17 @ Move GPIO bits 87:86 to bit position 6:5 + orr r2, r2, r8 @ Save these two bits into r2 + + ldr r3, [r4, #xlli_GPLR0_offset] @ Get levels for GPIOs [31:0] + mov r3, r3, LSR #14 @ Allign GPIO bit 14 with bit position 0 + and r8, r3, #0x1 @ Extract this bit + orr r2, r2, r8 @ OR this bit into r2 + + mov r3, r3, LSR #4 @ move GPIO bit 19 into bit location 1 + and r8, r3, #0x2 @ extract this bit + orr r2, r2, r8 @ OR this bit value into r2 + + mov r3, r3, LSR #5 @ move GPIO bits 31:30 into bit locations 8:7 + and r3, r3, #0x180 @ isolate these bits + orr r2, r2, r3 @ OR this bit value into r2 +@ +@ Restore GPDR0, GAFR0_L and GAFR0_U to their original values +@ + str r5, [r4, #xlli_GPDR0_offset] @ Restore direction values for GPIOs [31:0] + str r6, [r4, #xlli_GAFR0_L_offset] @ Restore alt function values for GPIOs [15:0] + str r7, [r4, #xlli_GAFR0_U_offset] @ Restore alt function values for GPIOs [31:16] +@ +@ Now we need to read status from GPIOs 103, 104 and 113 +@ +@ Configure GPDR3, GAFR3_L and GAFR3_U to pick up three status bits we need from this word +@ NOTE: The values in r1 and r4 must be preserved through this section of code. +@ + ldr r5, [r4, #xlli_GPDR3_offset] @ Save direction values for GPIOs [127:96] + ldr r6, [r4, #xlli_GAFR3_L_offset] @ Save alt function values for GPIOs [111:96] + ldr r7, [r4, #xlli_GAFR3_U_offset] @ Save alt function values for GPIOs [127:112] + + ldr r9, =0x00020180 @ Register clear mask for GPDR3 + bic r8, r5, r9 @ Clear the bits we need to read in GPDR3 + str r8, [r4, #xlli_GPDR3_offset] @ Write direction values for GPIOs [127:96] +@ +@ Clear the alternate function bits for the direction bits we need to look at. +@ + ldr r9, =0x0003C000 @ Register clear mask for GAFR3_L + bic r8, r6, r9 @ Clear the alt func for bits we need to read in GAFR3_L + str r8, [r4, #xlli_GAFR3_L_offset] @ Write alt function values for GPIOs [111:96] + + ldr r9, =0x0000000C @ Register clear mask for GAFR3_U + bic r8, r7, r9 @ Clear the alt func for bits we need to read in GAFR3_U + str r8, [r4, #xlli_GAFR3_U_offset] @ Write alt function values for GPIOs [127:112] + + mov r9, #0x200 +xlli_15: subs r9, r9, #1 @ Short delay required to allow the new GPIO... + bne xlli_15 @ ...settings to take effect + + ldr r3, [r4, #xlli_GPLR3_offset] @ Get levels for GPIOs [127:96] +@ +@ Restore GPDR3, GAFR3_L and GAFR3_U to their original values +@ + str r5, [r4, #xlli_GPDR3_offset] @ Restore direction values for GPIOs [127:96] + str r6, [r4, #xlli_GAFR3_L_offset] @ Restore alt function values for GPIOs [111:96] + str r7, [r4, #xlli_GAFR3_U_offset] @ Restore alt function values for GPIOs [127:112] + + mov r3, r3, LSL #2 @ Move GPIO bits 103:104 to bit locations 11:10 + and r8, r3, #0xC00 @ extract settings for bits 11:10 + orr r2, r2, r8 @ Add in to value for system config word + + mov r3, r3, LSR #10 @ Move GPIO bits 113 to bit location 9 + and r8, r3, #0x400 @ extract setting for bit 9 + orr r2, r2, r8 @ Add in to value for system config word +@ +@ Read back from APB to ensure our writes have completed before continuing +@ + ldr r8, [r4, #xlli_GAFR3_U_offset] +@ +@ r2 now contains the SCR2 register data in bits 11:0 +@ This value gets ORed with the SCR data in bits 31:16 of r1 +@ + orr r1, r1, r2 @ Generate the data word to be stored +@ +@ Update SRAM with the above data +@ + ldr r4, =xlli_SCR_data @ Get SRAM address where data is to be stored + str r1, [r4] @ Write the contents to SRAM + + mov pc, lr @ Return to calling program + + + + .ltorg + +@********************************************************************************************* +@ +@ ************************************* +@ ********** ********** +@ ********** CONFIGURE GPIOs ********** +@ ********** ********** +@ ************************************* +@ +@ This subroutine sets up the GPIO pins in accordance with the values contained in the platform include file. +@ +@ NOTES: Written for the PXA27x Processor on the Glencoe/Mainstone Development Platform. +@ +xlli_GPIO_init: +@ +@ Get GPIO registers base address and configure all GPIO lines. +@ + ldr r0, =xlli_GPIOREGS_PHYSICAL_BASE @ Load the GPIO register block base address + + ldr r1, =xlli_GPSR0_value @ Get the pin set values for GPSR0 + str r1, [r0, #xlli_GPSR0_offset] @ Write the R0 values + + ldr r2, =xlli_GPSR1_value @ Get the pin set values for GPSR1 + str r2, [r0, #xlli_GPSR1_offset] @ Write the R1 values + + ldr r1, =xlli_GPSR2_value @ Get the pin set values for GPSR2 + str r1, [r0, #xlli_GPSR2_offset] @ Write the R2 values + + ldr r2, =xlli_GPSR3_value @ Get the pin set values for GPSR3 + str r2, [r0, #xlli_GPSR3_offset] @ Write the R3 values + + ldr r1, =xlli_GPCR0_value @ Get the pin clear values for GPCR0 + str r1, [r0, #xlli_GPCR0_offset] @ Write the R0 values + + ldr r2, =xlli_GPCR1_value @ Get the pin clear values for GPCR1 + str r2, [r0, #xlli_GPCR1_offset] @ Write the R1 values + + ldr r1, =xlli_GPCR2_value @ Get the pin clear values for GPCR2 + str r1, [r0, #xlli_GPCR2_offset] @ Write the R2 values + + ldr r2, =xlli_GPCR3_value @ Get the pin clear values for GPCR3 + str r2, [r0, #xlli_GPCR3_offset] @ Write the R3 values + + ldr r1, =xlli_GPDR0_value @ Get the pin direction values for GPDR0 + str r1, [r0, #xlli_GPDR0_offset] @ Write the R0 values + + ldr r2, =xlli_GPDR1_value @ Get the pin direction values for GPDR1 + str r2, [r0, #xlli_GPDR1_offset] @ Write the R1 values + + ldr r1, =xlli_GPDR2_value @ Get the pin direction values for GPDR2 + str r1, [r0, #xlli_GPDR2_offset] @ Write the R2 values + + ldr r2, =xlli_GPDR3_value @ Get the pin direction values for GPDR3 + str r2, [r0, #xlli_GPDR3_offset] @ Write the R3 values + + ldr r1, =xlli_GAFR0_L_value @ Get the pin alt function values for GAFR0_L + str r1, [r0, #xlli_GAFR0_L_offset] @ Write the R0_L values + + ldr r2, =xlli_GAFR0_U_value @ Get the pin alt function values for GAFR0_U + str r2, [r0, #xlli_GAFR0_U_offset] @ Write the R0_U values + + ldr r1, =xlli_GAFR1_L_value @ Get the pin alt function values for GAFR1_L + str r1, [r0, #xlli_GAFR1_L_offset] @ Write the R1_L values + + ldr r2, =xlli_GAFR1_U_value @ Get the pin alt function values for GAFR1_U + str r2, [r0, #xlli_GAFR1_U_offset] @ Write the R1_U values + + ldr r1, =xlli_GAFR2_L_value @ Get the pin alt function values for GAFR2_L + str r1, [r0, #xlli_GAFR2_L_offset] @ Write the R2_L values + + ldr r2, =xlli_GAFR2_U_value @ Get the pin alt function values for GAFR2_U + str r2, [r0, #xlli_GAFR2_U_offset] @ Write the R2_U values + + ldr r1, =xlli_GAFR3_L_value @ Get the pin alt function values for GAFR3_L + str r1, [r0, #xlli_GAFR3_L_offset] @ Write the R3_L values + + ldr r2, =xlli_GAFR3_U_value @ Get the pin alt function values for GAFR3_U + str r2, [r0, #xlli_GAFR3_U_offset] @ Write the R3_U values + +@ +@ The RDH and PH bits on PXA27x must be set to enable updated GPIO pins. +@ These are sticky bits. +@ + ldr r0, =xlli_PMRCREGS_PHYSICAL_BASE + mov r2, #(xlli_PSSR_PH | xlli_PSSR_RDH) @ Set the PH and RDH bits to enable all GPIOs + str r2, [r0, #xlli_PSSR_offset] @ Enable all GPIO lines +@ +@ Read back from APB to ensure our writes have completed before continuing +@ + ldr r2, [r0, #xlli_PSSR_offset] + + mov pc, lr @ Return to calling program + + + + .ltorg + +@******************************************************************************************* +@ +@ ************************************************** +@ ********** ********** +@ ********** INITIALIZE MEMORY CONTROLLER ********** +@ ********** ********** +@ ************************************************** +@ +@ The sequence below is based on the recommended memory initializing steps detailed +@ in the PXA27x EAS, Volume I (Section 13.17, page 13-72) +@ + +xlli_mem_init: + +@ +@ ***** STEP 1: ***** +@ +@ Delay 200 uS +@ + ldr r2, =xlli_OSTREGS_PHYSICAL_BASE @ Load OS timer base address + ldr r3, [r2, #xlli_OSCR0_offset] @ Fetch starting value of OSCR0 + add r3, r3, #0x300 @ Really 0x2E1 is about 200usec, so 0x300 should be plenty +xlli_3: ldr r1, [r2, #xlli_OSCR0_offset] @ Fetch current OSCR0 value + cmp r1, r3 @ Is the timer past the time out value? + bmi xlli_3 @ No - Loop until it is + +@ +@ STEP 1 - 1st bullet: Write MSC0, MSC1 and MSC2 (the order is not important) +@ ******************* +@ +@ There is only one FLASH memory on the Glencoe board, so don't have to probe any switches + + ldr r1, =xlli_MSC0_value +@ +@ Finally - Write the memory control registers +@ +@ For Glencoe, we have only one Flash chip, which is connected to CS0 + + ldr r4, =xlli_MEMORY_CONFIG_BASE @ Get memory controller base address + + str r1, [r4, #xlli_MSC0_offset] @ Write the value out + ldr r1, [r4, #xlli_MSC0_offset] @ Read back to latch the data + +@ +@ STEP 1 - 2nd bullet: Write MECR, MCMEM0, MCMEM1, MCATT0, MCATT1, MCIO0, MCIO1 (order not important) +@ ******************* +@ + ldr r2, =xlli_MECR_value @ write MECR + str r2, [r4, #xlli_MECR_offset] + + ldr r1, =xlli_MCMEM0_value @ write MCMEM0 + str r1, [r4, #xlli_MCMEM0_offset] + + ldr r2, =xlli_MCMEM1_value @ write MCMEM1 + str r2, [r4, #xlli_MCMEM1_offset] + + ldr r1, =xlli_MCATT0_value @ write MCATT0 + str r1, [r4, #xlli_MCATT0_offset] + + ldr r2, =xlli_MCATT1_value @ write MCATT1 + str r2, [r4, #xlli_MCATT1_offset] + + ldr r1, =xlli_MCIO0_value @ write MCIO0 + str r1, [r4, #xlli_MCIO0_offset] + + ldr r2, =xlli_MCIO1_value @ write MCIO1 + str r2, [r4, #xlli_MCIO1_offset] +@ +@ STEP 1 - 3rd bullet: Write FLYCNFG +@ ******************* +@ + ldr r1, =xlli_FLYCNFG_value @ write FLYCNFG + str r1, [r4, #xlli_FLYCNFG_offset] +@ + +@ +@ STEP 1 - 4th bullet: SKIPPED (used only when coming out of sleep) +@ ******************* +@ +@ (If required, this would be a write to MDCNFG with enable bits deasserted.) + + +@ +@ STEP 1 - 5th bullet: update MDREFR settings +@ ******************* +@ + ldr r2, [r4, #xlli_MDREFR_offset] @ Get reset state of MDREFR + mov r2, r2, lsr #0xC @ Shift data 12 bits (0xC) to the right + mov r2, r2, lsl #0xC @ and shift left 12 bits (Clears DRI field) + @ because left shifts fill bits with zeros. + + ldr r1, =xlli_MDREFR_value @ Fetch MDREFR value for this platform + mov r1, r1, lsl #0x14 @ use shifts to extract the DRI field using + mov r1, r1, lsr #0x14 @ same method as before but shifting 20 (0x14) + @ bits left, then right again. + + orr r2, r2, r1 @ insert the DRI field extracted above + str r2, [r4, #xlli_MDREFR_offset] @ write value with valid DRI to MDREFR + + orr r2, r2, #xlli_MDREFR_K0RUN @ Enable K0RUN + bic r2, r2, #xlli_MDREFR_K0DB2 @ Configure K0DB2 + orr r2, r2, #xlli_MDREFR_K0DB4 @ Set K0DB4 = MemClk/4 + bic r2, r2, #(xlli_MDREFR_K1FREE | xlli_MDREFR_K2FREE) @ Clear free run clock bits + + orr r2, r2, #xlli_MDREFR_K0FREE @ Set K0FREE (as per Mainstone spec...) + + str r2, [r4, #xlli_MDREFR_offset] @ Write back MDREFR + + @ + @ Preserve MDREFR in r2 + @ + +@ ***** STEP 2 ***** +@ +@ For systems with Synchronous Flash +@ +@ Note: Synchronous Flash is handled in a separate xlli Function +@ + +@ +@ ***** STEP 3 ***** +@ +@ Clear the free run clock bits to enable the use of SDCLK for memory timing +@ + bic r2, r2, #(xlli_MDREFR_K2FREE | xlli_MDREFR_K1FREE | xlli_MDREFR_K0FREE) + +@ +@ set K1RUN if bank 0 installed +@ + orr r2, r2, #xlli_MDREFR_K1RUN @ Enable SDCLK[1] + bic r2, r2, #xlli_MDREFR_K2DB2 @ Clear K2DB2 + str r2, [r4, #xlli_MDREFR_offset] @ write updated MDREFR + ldr r2, [r4, #xlli_MDREFR_offset] @ read back + + bic r2, r2, #xlli_MDREFR_SLFRSH @ Disable self refresh + str r2, [r4, #xlli_MDREFR_offset] @ write updated MDREFR + ldr r2, [r4, #xlli_MDREFR_offset] @ read back + + orr r2, r2, #xlli_MDREFR_E1PIN @ Assert E1PIN to enable SDCKE[1] + str r2, [r4, #xlli_MDREFR_offset] @ write updated MDREFR (finished with value in r2) + ldr r2, [r4, #xlli_MDREFR_offset] @ read back + + nop @ Do not remove! + nop @ Do not remove! +@ +@ ***** STEP 4 ***** +@ +@ Appropriately configure, but don't enable, each SDRAM partition pair +@ + ldr r1, =xlli_MDCNFG_value @ Fetch platform value for MDCNFG + + bic r1, r1, #(xlli_MDCNFG_DE0 | xlli_MDCNFG_DE1) @ Disable all + bic r1, r1, #(xlli_MDCNFG_DE2 | xlli_MDCNFG_DE3) @ SDRAM banks +@ +@ Glencoe's bus width is 32 bit +@ + bic r1, r1, #xlli_MDCNFG_DWID0 @ Set banks 0/1 for 32 bit width + + orr r1, r1, #xlli_BIT_11 @ This reserved bit should always be set + orr r1, r1, #xlli_BIT_27 @ This reserved bit should always be set + str r1, [r4, #xlli_MDCNFG_offset] @ Write w/o enabling SDRAM banks + +@ +@ ***** STEP 5 ***** (Delay at least 200 uS) +@ + ldr r2, =xlli_OSTREGS_PHYSICAL_BASE @ Load OS timer base address + ldr r3, [r2, #xlli_OSCR0_offset] @ Fetch starting value of OSCR0 + add r3, r3, #0x300 @ Really 0x2E1 is about 200usec, so 0x300 should be plenty +xlli_5: ldr r1, [r2, #xlli_OSCR0_offset] @ Fetch current OSCR0 value + cmp r1, r3 @ Is the timer past the time out value? + bmi xlli_5 @ No - Loop until it is +@ +@ ***** STEP 6 ***** (Make sure DCACHE is disabled) +@ + mrc p15, 0, r2, c1, c0, 0 @ load r2 contents of register 1 in CP 15 + bic r2, r2, #xlli_CONTROL_DCACHE @ Disable D-Cache + mcr p15, 0, r2, c1, c0, 0 @ Write back to CP15 +@ +@ ***** STEP 7 ***** +@ +@ Access memory *not yet enabled* for CBR refresh cycles (8) +@ - CBR is generated for all banks +@ + ldr r1, =xlli_SDRAM_PHYSICAL_BASE + str r1, [r1] + str r1, [r1] + str r1, [r1] + str r1, [r1] + str r1, [r1] + str r1, [r1] + str r1, [r1] + str r1, [r1] + + str r1, [r1] @ Fix for erratum #116. Makes up for ineffective 1st mem access. + @ This is being left in for PXA27x for the moment + + +@ +@ ***** STEP 8 ***** +@ +@ Re-enable D-cache if desired (we don't) + +@ +@ ***** STEP 9 ***** +@ +@ Re-enable SDRAM partitions +@ + ldr r2, [r4, #xlli_MDCNFG_offset] @ Fetch the current MDCNFG value + orr r2, r2, #xlli_MDCNFG_DE0 @ Enable SDRAM bank 0 + .ifdef xlli_SDRAM_SIZE_128_MB @ Eanble SDRAM bank 1? + orr r2, r2, #xlli_MDCNFG_DE1 @ Enable SDRAM bank 1 + .endif + str r2, [r4, #xlli_MDCNFG_offset] @ Write back MDCNFG, enabling the SDRAM bank(s) +@ +@ ***** STEP 10 ***** +@ +@ Write the MDMRS register to trigger an MRS command to all enabled banks of SDRAM. +@ +@ + ldr r1, =xlli_MDMRS_value @ Fetch platform MDMRS value + str r1, [r4, #xlli_MDMRS_offset] @ Write the MDMRS value back +@ +@ ***** STEP 11 ***** +@ +@ In systems with SDRAM or Synchronous Flash, optionally enable auto-power-down by setting MDREFR:APD +@ + ldr r3, [r4, #xlli_MDREFR_offset] @ Get MDREFR value + orr r3, r3, #xlli_MDREFR_APD @ enable auto power down + str r3, [r4, #xlli_MDREFR_offset] @ Write value back + + + mov pc, lr @ return to calling routine + + + .ltorg + +@******************************************************************************************** +@ +@ *********************************************** +@ ********** ********** +@ ********** RESTART MEMORY CONTROLLER ********** +@ ********** ********** +@ *********************************************** +@ +@ This command restarts the memory controller and should be called after a frequency change sequence +@ or when memory controller settings have been changed (such as xlli_mem_Tmax and xlli_memTopt). +@ + +xlli_mem_restart: + + ldr r4, =xlli_MEMORY_CONFIG_BASE @ Get memory controller base address + ldr r2, [r4, #xlli_MDREFR_offset] @ Get MDREFR value + bic r3, r2, #xlli_MDREFR_E0PIN @ Clear E0PIN to disable SDCKE[0] + bic r3, r3, #xlli_MDREFR_E1PIN @ Clear E1PIN to disable SDCKE[1] + b xlli_5A +@ +@ The next line should start on a cache line boundary so we don't accidently hang the system +@ + .balign 32 +xlli_5A: str r3, [r4, #xlli_MDREFR_offset] @ Write value back with E0PIN and E1PIN cleared + str r2, [r4, #xlli_MDREFR_offset] @ Write value back with E0PIN and E1PIN set +@ +@ Disable all SDRAM banks +@ + ldr r1, [r4, #xlli_MDCNFG_offset] @ Fetch platform value for MDCNFG + bic r1, r1, #(xlli_MDCNFG_DE0 | xlli_MDCNFG_DE1) @ Disable all + bic r1, r1, #(xlli_MDCNFG_DE2 | xlli_MDCNFG_DE3) @ SDRAM banks + str r1, [r4, #xlli_MDCNFG_offset] @ Write w/o enabling SDRAM banks +@ +@ Access memory *not yet enabled* for CBR refresh cycles (8) +@ - CBR is generated for all banks +@ + ldr r1, =xlli_SDRAM_PHYSICAL_BASE + str r1, [r1] + str r1, [r1] + str r1, [r1] + str r1, [r1] + str r1, [r1] + str r1, [r1] + str r1, [r1] + str r1, [r1] + + str r1, [r1] @ Fix for erratum #116. Makes up for ineffective 1st mem access. + @ This is being left in for PXA27x for the moment +@ +@ Re-enable SDRAM partition(s) +@ + ldr r2, [r4, #xlli_MDCNFG_offset] @ Fetch the current MDCNFG value + orr r2, r2, #xlli_MDCNFG_DE0 @ Enable SDRAM bank 0 + .ifdef xlli_SDRAM_SIZE_128_MB @ Eanble SDRAM bank 1? + orr r2, r2, #xlli_MDCNFG_DE1 @ Enable SDRAM bank 1 + .endif + str r2, [r4, #xlli_MDCNFG_offset] @ Write back MDCNFG, enabling the SDRAM bank(s) +@ +@ Write the MDMRS register to trigger an MRS command to all enabled banks of SDRAM. +@ +@ + ldr r1, [r4, #xlli_MDMRS_offset] @ Fetch platform MDMRS value + str r1, [r4, #xlli_MDMRS_offset] @ Write the MDMRS value back +@ + ldr r3, [r4, #xlli_MDREFR_offset] @ Get MDREFR value + str r3, [r4, #xlli_MDREFR_offset] @ Write value back + + mov pc, lr @ return to calling routine + + + +@******************************************************************************************** +@ +@ ******************************************************** +@ ********** ********** +@ ********** MAXIMIZE MEMORY CONTROLLER VALUES ********** +@ ********** ********** +@ ******************************************************** +@ +@ NOTE: This function maximizes the timing values in the memory controller so the frequency change +@ sequence can be done safely without the risk of a system hang. Once the frequency change +@ sequence is complete, xlli__mem_Topt may be called to set the optimal timing values. +@ +@ This function does not need to be called if the new MemClk frequency is going to be higher +@ than the present MemClk frequency. However, the overhead of this function is minimal so +@ it is suggested this function be called before any change frequency sequence. +@ +@ r1, r2, and r3 are used and not preserved. +@ +xlli_mem_Tmax: + + ldr r1, =xlli_MEMORY_CONFIG_BASE @ Get memory controller base address + ldr r3, =0x7FF07FF0 @ Maximize bits for RDF, RDN and RRR +@ + ldr r2, [r1, #xlli_MSC0_offset] @ Get MSC0 value + orr r2, r2, r3 @ Set all the RDF, RDN and RRR bits + str r2, [r1, #xlli_MSC0_offset] @ Set the new MSC0 value + ldr r2, [r1, #xlli_MSC0_offset] @ Read MSC0 value back to lock the values +@ + ldr r3, =0x03000300 @ Set up mask bits for DTC0 and DTC2 + ldr r2, [r1, #xlli_MDCNFG_offset] @ Get present MDCNFG value + orr r2, r2, r3 @ Clear the DTC0 and DTC2 bits + str r2, [r1, #xlli_MDCNFG_offset] @ Write back the MDCNFG value +@ + ldr r3, =0xFFF @ Set up mask bits for DRI value + ldr r2, [r1, #xlli_MDREFR_offset] @ Get present MDREFR value + bic r2, r2, r3 @ Clear all the DRI bits + orr r2, r2, #0x13 @ Set to lowest safe value + str r2, [r1, #xlli_MDREFR_offset] @ Write back the MDREFR value + + mov pc, lr @ return to calling routine + + + +@******************************************************************************************** +@ +@ *********************************************************** +@ ********** ********** +@ ********** SET OPTIMAL MEMORY CONTROLLER VALUES ********** +@ ********** ********** +@ *********************************************************** +@ +@ NOTE: This function sets the TIMING values in the memory controller to the optimum values based on +@ the frequency of the MemClk. This function should be called AFTER the frequency change +@ sequence is complete to get optimal performance out of the memory system. +@ +@ If changing the core frequency to a value that increases the MemClk speed, it is strongly +@ suggested that xlli_MSCx_max be called before the frequency change sequence. Once the +@ frequency chage sequence is complete, this routine may be called to reset the optimal +@ values for the memory system and the memory controller restarted. +@ +@ r1 through r8 are used and not preserved. +@ +xlli_mem_Topt: + + ldr r1, =xlli_CLKREGS_PHYSICAL_BASE @ Get base address of clock registers + ldr r2, [r1, #xlli_CCSR_offset] @ Get current clock status + and r2, r2, #0x1F @ r2 now contains the CCSR L value + + ldr r3, [r1, #xlli_CCCR_offset] @ Get the current CCCR for the "A" bit + and r3, r3, #xlli_CCCR_A_Bit_Mask + mov r3, r3, LSR #0x19 @ Move down to bit position 0 to make comparison easy (LSL by 25) +@ +@ Check for the "B" bit from CCCR (CP14,R6) +@ + mrc p14, 0, r1, c6, c0, 0 @ Get data in CP14, Register 6 + and r1, r1, #0x8 @ Grab just the "B" bit + mov r1, r1, LSR #0x2 @ move it to bit position 1 + orr r9, r3, r1 @ At this point r9 contains the A-bit at pos. 0 & B-bit at pos. 1 + + ldr r1, =xlli_MEMORY_CONFIG_BASE @ Load r1 with memory controller base address +@ +@ The MemClk speed is determined by the L, A and B values. +@ Unfortunaly, the only practical way to do this is to rip through all the legal +@ values and load a register when there is a match. Illegal values result in no change +@ + ldr r3, =0x7FF07FF0 @ Bit mask for RDF, RDN and RRR (MSC0) + ldr r4, [r1, #xlli_MSC0_offset] @ Get present MSC0 value + bic r4, r4, r3 @ Clear the RDF, RDN and RRR bits + + ldr r5, =0x03000300 @ DTC0, DTC2 bit mask (MDCNFG) + ldr r6, [r1, #xlli_MDCNFG_offset] @ Get present MDCNFG value + bic r6, r6, r5 @ Clear DTC0, DTC2 + + ldr r7, =0xC0200FFF @ DRI and RESERVED bit mask (MDREFR) + ldr r8, [r1, #xlli_MDREFR_offset] @ Get present MDREFR value + bic r8, r8, r7 @ Clear DRI and RESERVED bits + ldr r7, = 0xFFF @ Reload r7 with worst-case DRI value for safety +@ +@ r9 = 0x0: A=0, B=0 +@ 0x1: A=1, B=0 +@ 0x2: A=0, B=1 +@ 0x3: A=1, B=1 +@ + cmp r9, #0x1 @ A == 1, B == 0 ? + beq xlli_A1B0_Table + + cmp r9, #0x3 @ A == 1, B == 1 ? + beq xlli_A1B1_Table + +@ +@ Else drop through to A=0, B=x table +@ +xlli_A0Bx_Table: + cmp r2, #2 @ Is L=2? + ldreq r3, =xlli_MSC0_26 @ Yes - load values + ldreq r5, =xlli_DTC_26 + ldreq r7, =xlli_DRI_26 + cmp r2, #3 @ Is L=3? + ldreq r3, =xlli_MSC0_39 @ Yes - load values + ldreq r5, =xlli_DTC_39 + ldreq r7, =xlli_DRI_39 + cmp r2, #4 @ Is L=4? + ldreq r3, =xlli_MSC0_52 @ Yes - load values + ldreq r5, =xlli_DTC_52 + ldreq r7, =xlli_DRI_52 + cmp r2, #5 @ Is L=5? + ldreq r3, =xlli_MSC0_65 @ Yes - load values + ldreq r5, =xlli_DTC_65 + ldreq r7, =xlli_DRI_65 + cmp r2, #6 @ Is L=6? + ldreq r3, =xlli_MSC0_78 @ Yes - load values + ldreq r5, =xlli_DTC_78 + ldreq r7, =xlli_DRI_78 + cmp r2, #7 @ Is L=7? + ldreq r3, =xlli_MSC0_91 @ Yes - load values + ldreq r5, =xlli_DTC_91 + ldreq r7, =xlli_DRI_91 + cmp r2, #8 @ Is L=8? + ldreq r3, =xlli_MSC0_104 @ Yes - load values + ldreq r5, =xlli_DTC_104 + ldreq r7, =xlli_DRI_104 + cmp r2, #9 @ Is L=9? + ldreq r3, =xlli_MSC0_117 @ Yes - load values + ldreq r5, =xlli_DTC_117 + ldreq r7, =xlli_DRI_117 + + cmp r2, #10 @ Is L=10? + ldreq r3, =xlli_MSC0_130 @ Yes - load values + ldreq r5, =xlli_DTC_130 + ldreq r7, =xlli_DRI_130 + cmp r2, #11 @ Is L=11? + ldreq r3, =xlli_MSC0_71 @ Yes - load values + ldreq r5, =xlli_DTC_71 + ldreq r7, =xlli_DRI_71 + cmp r2, #12 @ Is L=12? + ldreq r3, =xlli_MSC0_78 @ Yes - load values + ldreq r5, =xlli_DTC_78 + ldreq r7, =xlli_DRI_78 + cmp r2, #13 @ Is L=13? + ldreq r3, =xlli_MSC0_84 @ Yes - load value + ldreq r5, =xlli_DTC_84 + ldreq r7, =xlli_DRI_84 + cmp r2, #14 @ Is L=14? + ldreq r3, =xlli_MSC0_91 @ Yes - load values + ldreq r5, =xlli_DTC_91 + ldreq r7, =xlli_DRI_91 + cmp r2, #15 @ Is L=15? + ldreq r3, =xlli_MSC0_97 @ Yes - load values + ldreq r5, =xlli_DTC_97 + ldreq r7, =xlli_DRI_97 + + cmp r2, #16 @ Is L=16? + ldreq r3, =xlli_MSC0_104 @ Yes - load values + ldreq r5, =xlli_DTC_104 + ldreq r7, =xlli_DRI_104 + cmp r2, #17 @ Is L=17? + ldreq r3, =xlli_MSC0_110 @ Yes - load values + ldreq r5, =xlli_DTC_110 + ldreq r7, =xlli_DRI_110 + cmp r2, #18 @ Is L=18? + ldreq r3, =xlli_MSC0_117 @ Yes - load values + ldreq r5, =xlli_DTC_117 + ldreq r7, =xlli_DRI_117 + cmp r2, #19 @ Is L=19? + ldreq r3, =xlli_MSC0_124 @ Yes - load values + ldreq r5, =xlli_DTC_124 + ldreq r7, =xlli_DRI_124 + cmp r2, #20 @ Is L=20? + ldreq r3, =xlli_MSC0_130 @ Yes - load values + ldreq r5, =xlli_DTC_130 + ldreq r7, =xlli_DRI_130 + + cmp r2, #21 @ Is L=21? + ldreq r3, =xlli_MSC0_68 @ Yes - load values + ldreq r5, =xlli_DTC_68 + ldreq r7, =xlli_DRI_68 + cmp r2, #22 @ Is L=22? + ldreq r3, =xlli_MSC0_71 @ Yes - load values + ldreq r5, =xlli_DTC_71 + ldreq r7, =xlli_DRI_71 + cmp r2, #23 @ Is L=23? + ldreq r3, =xlli_MSC0_74 @ Yes - load values + ldreq r5, =xlli_DTC_74 + ldreq r7, =xlli_DRI_74 + cmp r2, #24 @ Is L=24? + ldreq r3, =xlli_MSC0_78 @ Yes - load values + ldreq r5, =xlli_DTC_78 + ldreq r7, =xlli_DRI_78 + cmp r2, #25 @ Is L=25? + ldreq r3, =xlli_MSC0_81 @ Yes - load values + ldreq r5, =xlli_DTC_81 + ldreq r7, =xlli_DRI_81 + + cmp r2, #26 @ Is L=26? + ldreq r3, =xlli_MSC0_84 @ Yes - load values + ldreq r5, =xlli_DTC_84 + ldreq r7, =xlli_DRI_84 + cmp r2, #27 @ Is L=27? + ldreq r3, =xlli_MSC0_87 @ Yes - load values + ldreq r5, =xlli_DTC_87 + ldreq r7, =xlli_DRI_87 + cmp r2, #28 @ Is L=28? + ldreq r3, =xlli_MSC0_91 @ Yes - load values + ldreq r5, =xlli_DTC_91 + ldreq r7, =xlli_DRI_91 + cmp r2, #29 @ Is L=29? + ldreq r3, =xlli_MSC0_94 @ Yes - load values + ldreq r5, =xlli_DTC_94 + ldreq r7, =xlli_DRI_94 + cmp r2, #30 @ Is L=30? + ldreq r3, =xlli_MSC0_97 @ Yes - load values + ldreq r5, =xlli_DTC_97 + ldreq r7, =xlli_DRI_97 + cmp r2, #31 @ Is L=31? + ldreq r3, =xlli_MSC0_100 @ Yes - load values + ldreq r5, =xlli_DTC_100 + ldreq r7, =xlli_DRI_100 + + b XLLI_Done_MSC0_Opt_Update + +xlli_A1B0_Table: + + cmp r2, #2 @ Is L=2? + ldreq r3, =xlli_MSC0_13 @ Yes - load values + ldreq r5, =xlli_DTC_13 + ldreq r7, =xlli_DRI_13 + cmp r2, #3 @ Is L=3? + ldreq r3, =xlli_MSC0_19 @ Yes - load values + ldreq r5, =xlli_DTC_19 + ldreq r7, =xlli_DRI_19 + cmp r2, #4 @ Is L=4? + ldreq r3, =xlli_MSC0_26 @ Yes - load values + ldreq r5, =xlli_DTC_26 + ldreq r7, =xlli_DRI_26 + cmp r2, #5 @ Is L=5? + ldreq r3, =xlli_MSC0_32 @ Yes - load values + ldreq r5, =xlli_DTC_32 + ldreq r7, =xlli_DRI_32 + cmp r2, #6 @ Is L=6? + ldreq r3, =xlli_MSC0_39 @ Yes - load values + ldreq r5, =xlli_DTC_39 + ldreq r7, =xlli_DRI_39 + cmp r2, #7 @ Is L=7? + ldreq r3, =xlli_MSC0_45 @ Yes - load values + ldreq r5, =xlli_DTC_45 + ldreq r7, =xlli_DRI_45 + + cmp r2, #8 @ Is L=8? + ldreq r3, =xlli_MSC0_52 @ Yes - load values + ldreq r5, =xlli_DTC_52 + ldreq r7, =xlli_DRI_52 + cmp r2, #9 @ Is L=9? + ldreq r3, =xlli_MSC0_58 @ Yes - load values + ldreq r5, =xlli_DTC_58 + ldreq r7, =xlli_DRI_58 + + cmp r2, #10 @ Is L=10? + ldreq r3, =xlli_MSC0_65 @ Yes - load values + ldreq r5, =xlli_DTC_65 + ldreq r7, =xlli_DRI_65 +@ +@ L11 - L20 ARE THE SAME for A0Bx +@ + cmp r2, #11 @ Is L=11? + ldreq r3, =xlli_MSC0_71 @ Yes - load values + ldreq r5, =xlli_DTC_71 + ldreq r7, =xlli_DRI_71 + cmp r2, #12 @ Is L=12? + ldreq r3, =xlli_MSC0_78 @ Yes - load values + ldreq r5, =xlli_DTC_78 + ldreq r7, =xlli_DRI_78 + cmp r2, #13 @ Is L=13? + ldreq r3, =xlli_MSC0_84 @ Yes - load values + ldreq r5, =xlli_DTC_84 + ldreq r7, =xlli_DRI_84 + cmp r2, #14 @ Is L=14? + ldreq r3, =xlli_MSC0_91 @ Yes - load values + ldreq r5, =xlli_DTC_91 + ldreq r7, =xlli_DRI_91 + cmp r2, #15 @ Is L=15? + ldreq r3, =xlli_MSC0_97 @ Yes - load values + ldreq r5, =xlli_DTC_97 + ldreq r7, =xlli_DRI_97 + cmp r2, #16 @ Is L=16? + ldreq r3, =xlli_MSC0_104 @ Yes - load values + ldreq r5, =xlli_DTC_104 + ldreq r7, =xlli_DRI_104 + cmp r2, #17 @ Is L=17? + ldreq r3, =xlli_MSC0_110 @ Yes - load values + ldreq r5, =xlli_DTC_110 + ldreq r7, =xlli_DRI_110 + cmp r2, #18 @ Is L=18? + ldreq r3, =xlli_MSC0_117 @ Yes - load values + ldreq r5, =xlli_DTC_117 + ldreq r7, =xlli_DRI_117 + cmp r2, #19 @ Is L=19? + ldreq r3, =xlli_MSC0_124 @ Yes - load values + ldreq r5, =xlli_DTC_124 + ldreq r7, =xlli_DRI_124 + cmp r2, #20 @ Is L=20? + ldreq r3, =xlli_MSC0_130 @ Yes - load values + ldreq r5, =xlli_DTC_130 + ldreq r7, =xlli_DRI_130 + + cmp r2, #21 @ Is L=21? + ldreq r3, =xlli_MSC0_136 @ Yes - load values + ldreq r5, =xlli_DTC_136 + ldreq r7, =xlli_DRI_136 + cmp r2, #22 @ Is L=22? + ldreq r3, =xlli_MSC0_143 @ Yes - load values + ldreq r5, =xlli_DTC_143 + ldreq r7, =xlli_DRI_143 + cmp r2, #23 @ Is L=23? + ldreq r3, =xlli_MSC0_149 @ Yes - load values + ldreq r5, =xlli_DTC_149 + ldreq r7, =xlli_DRI_149 + cmp r2, #24 @ Is L=24? + ldreq r3, =xlli_MSC0_156 @ Yes - load values + ldreq r5, =xlli_DTC_156 + ldreq r7, =xlli_DRI_156 + cmp r2, #25 @ Is L=25? + ldreq r3, =xlli_MSC0_162 @ Yes - load values + ldreq r5, =xlli_DTC_162 + ldreq r7, =xlli_DRI_162 + + cmp r2, #26 @ Is L=26? + ldreq r3, =xlli_MSC0_169 @ Yes - load values + ldreq r5, =xlli_DTC_169 + ldreq r7, =xlli_DRI_169 + cmp r2, #27 @ Is L=27? + ldreq r3, =xlli_MSC0_175 @ Yes - load values + ldreq r5, =xlli_DTC_175 + ldreq r7, =xlli_DRI_175 + cmp r2, #28 @ Is L=28? + ldreq r3, =xlli_MSC0_182 @ Yes - load values + ldreq r5, =xlli_DTC_182 + ldreq r7, =xlli_DRI_182 + cmp r2, #29 @ Is L=29? + ldreq r3, =xlli_MSC0_188 @ Yes - load values + ldreq r5, =xlli_DTC_188 + ldreq r7, =xlli_DRI_188 + cmp r2, #30 @ Is L=30? + ldreq r3, =xlli_MSC0_195 @ Yes - load values + ldreq r5, =xlli_DTC_195 + ldreq r7, =xlli_DRI_195 + cmp r2, #31 @ Is L=31? + ldreq r3, =xlli_MSC0_201 @ Yes - load values + ldreq r5, =xlli_DTC_201 + ldreq r7, =xlli_DRI_201 + + b XLLI_Done_MSC0_Opt_Update + + +xlli_A1B1_Table: + cmp r2, #2 @ Is L=2? + ldreq r3, =xlli_MSC0_26 @ Yes - load values + ldreq r5, =xlli_DTC_26 + ldreq r7, =xlli_DRI_26 + cmp r2, #3 @ Is L=3? + ldreq r3, =xlli_MSC0_39 @ Yes - load values + ldreq r5, =xlli_DTC_39 + ldreq r7, =xlli_DRI_39 + cmp r2, #4 @ Is L=4? + ldreq r3, =xlli_MSC0_52 @ Yes - load values + ldreq r5, =xlli_DTC_52 + ldreq r7, =xlli_DRI_52 + cmp r2, #5 @ Is L=5? + ldreq r3, =xlli_MSC0_65 @ Yes - load values + ldreq r5, =xlli_DTC_65 + ldreq r7, =xlli_DRI_65 + cmp r2, #6 @ Is L=6? + ldreq r3, =xlli_MSC0_78 @ Yes - load values + ldreq r5, =xlli_DTC_78 + ldreq r7, =xlli_DRI_78 + cmp r2, #7 @ Is L=7? + ldreq r3, =xlli_MSC0_91 @ Yes - load values + ldreq r5, =xlli_DTC_91 + ldreq r7, =xlli_DRI_91 + cmp r2, #8 @ Is L=8? + ldreq r3, =xlli_MSC0_104 @ Yes - load values + ldreq r5, =xlli_DTC_104 + ldreq r7, =xlli_DRI_104 + cmp r2, #9 @ Is L=9? + ldreq r3, =xlli_MSC0_117 @ Yes - load values + ldreq r5, =xlli_DTC_117 + ldreq r7, =xlli_DRI_117 + + cmp r2, #10 @ Is L=10? + ldreq r3, =xlli_MSC0_130 @ Yes - load values + ldreq r5, =xlli_DTC_130 + ldreq r7, =xlli_DRI_130 + cmp r2, #11 @ Is L=11? + ldreq r3, =xlli_MSC0_143 @ Yes - load values + ldreq r5, =xlli_DTC_143 + ldreq r7, =xlli_DRI_143 + cmp r2, #12 @ Is L=12? + ldreq r3, =xlli_MSC0_156 @ Yes - load values + ldreq r5, =xlli_DTC_156 + ldreq r7, =xlli_DRI_156 + cmp r2, #13 @ Is L=13? + ldreq r3, =xlli_MSC0_169 @ Yes - load values + ldreq r5, =xlli_DTC_169 + ldreq r7, =xlli_DRI_169 + cmp r2, #14 @ Is L=14? + ldreq r3, =xlli_MSC0_182 @ Yes - load values + ldreq r5, =xlli_DTC_182 + ldreq r7, =xlli_DRI_182 + cmp r2, #15 @ Is L=15? + ldreq r3, =xlli_MSC0_195 @ Yes - load values + ldreq r5, =xlli_DTC_195 + ldreq r7, =xlli_DRI_195 + + cmp r2, #16 @ Is L=16? + ldreq r3, =xlli_MSC0_208 @ Yes - load values + ldreq r5, =xlli_DTC_208 + ldreq r7, =xlli_DRI_208 + +XLLI_Done_MSC0_Opt_Update: + +@ +@ Update MSC0 +@ + orr r4, r4, r3 @ Update the RDF, RDN and RRR bits + str r4, [r1, #xlli_MSC0_offset] @ Set the new MSC0 value + ldr r4, [r1, #xlli_MSC0_offset] @ Read MSC0 value back to lock the values + +@ +@ Update DRI bits +@ + orr r8, r8, r7 @ Update the DRI bits + str r8, [r1, #xlli_MDREFR_offset] @ Set the new MDREFR value + +@ +@ Update DTC bits +@ + orr r6, r6, r5 @ Update DTC0 and DTC2 bits + str r6, [r1, #xlli_MDCNFG_offset] @ Write back the MDCNFG value + + mov pc, lr @ return to calling routine + + + + .ltorg + +@******************************************************************************************** +@ +@ ****************************************************** +@ ********** ********** +@ ********** INITIALIZE (MASK) ALL INTERRUPTS ********** +@ ********** ********** +@ ****************************************************** +@ +@ NOTE: On system reset, all interrupts should be cleared by hardware. +@ This enforces disabling of all interrupts to HW boot default conditions. +@ +xlli_intr_init: + + ldr r4, =xlli_INTERREGS_PHYSICAL_BASE @ Load controller physical base address + ldr r2, =0x0 @ zero out a work register + str r2, [r4, #xlli_ICMR_offset] @ Mask all interrupts (clear mask register) + str r2, [r4, #xlli_ICMR2_offset] @ Mask all interrupts (clear mask register) 2 + str r2, [r4, #xlli_ICLR_offset] @ Clear the interrupt level register + str r2, [r4, #xlli_ICLR2_offset] @ Clear the interrupt level register 2 + str r2, [r4, #xlli_ICCR_offset] @ Clear Interrupt Control Register + str r2, [r4, #xlli_ICCR2_offset] @ Clear Interrupt Control Register 2 +@ +@ Read back from APB to ensure our writes have completed before continuing +@ + ldr r2, [r4, #xlli_ICMR_offset] + + mov pc, lr @ return to calling routine + + + +@******************************************************************************************** +@ +@ ********************************************** +@ ********** ********** +@ ********** INITIALIZE CLOCK MANAGER ********** +@ ********** ********** +@ ********************************************** +@ +@ Disable the peripheral clocks, and set the core clock frequency +@ +@ NOTE: The Change Frequency Sequence should be called after this function in order +@ for the clock frequencies set in the CCCR register to take effect. +@ +@ The code then spins on the oscillator OK bit until the oscilator is stable +@ which can take as long as two seconds. +@ + +xlli_clks_init: + +@ Turn Off ALL on-chip peripheral clocks for re-configuration +@ + ldr r4, =xlli_CLKREGS_PHYSICAL_BASE@ Load clock registers base address + ldr r1, =0x400000 @ Forces memory clock to stay ON!! + ldr r2, =xlli_CKEN_value @ Get any other bits required from the include file + orr r1, r1, r2 @ OR everything together + str r1, [r4, #xlli_CKEN_offset] @ ... and write out to the clock enable register +@ +@ Set Crystal: Memory Freq, Memory:RunMode Freq, RunMode, TurboMode Freq Multipliers, +@ set RunMode & TurboMode to default frequency. +@ + ldr r2, =xlli_CCCR_value @ Get CORE_CLK_DEFAULT value + str r2, [r4, #xlli_CCCR_offset] @ Write to the clock config register +@ +@ Enable the 32 KHz oscillator. For Glencoe, do not enable output! GEM module uses that pin!! +@ (32KHz output enable GPIO10) +@ + mov r1, #(xlli_OSCC_OON) + str r1, [r4, #xlli_OSCC_offset] @ for RTC and Power Manager +@ +@ Init Real Time Clock (RTC) registers +@ + ldr r4, =xlli_RTCREGS_PHYSICAL_BASE @ Load RTC registers base address + mov r2, #0 @ Clear a work register + str r2, [r4, #xlli_RTSR_offset] @ Clear RTC Status register + str r2, [r4, #xlli_RCNR_offset] @ Clear RTC Counter Register + str r2, [r4, #xlli_RTAR_offset] @ Clear RTC Alarm Register + str r2, [r4, #xlli_SWCR_offset] @ Clear Stopwatch Counter Register + str r2, [r4, #xlli_SWAR1_offset] @ Clear Stopwatch Alarm Register 1 + str r2, [r4, #xlli_SWAR2_offset] @ Clear Stopwatch Alarm Register 2 + str r2, [r4, #xlli_PICR_offset] @ Clear Periodic Counter Register + str r2, [r4, #xlli_PIAR_offset] @ Clear Interrupt Alarm Register + +@ +@ Check the Oscillator OK (OOK) bit in clock register OSCC to insure the timekeeping oscillator +@ is enabled and stable before returning to the calling program. +@ + ldr r4, =xlli_CLKREGS_PHYSICAL_BASE @ Reload clock registers base address +xlli_6: + ldr r1, [r4, #xlli_OSCC_offset] @ Get the status of the OSCC register + ands r1, r1, #xlli_OSCC_OOK @ is the oscillator OK bit set? + beq xlli_6 @ Spin in this loop until the bit is set + + mov pc, lr @ return to calling routine + + + +@******************************************************************************************** +@ +@ **************************************************************** +@ ********** ********** +@ ********** INITIALIZE CLOCK MANAGER (FROM SLEEP MODE) ********** +@ ********** ********** +@ **************************************************************** +@ +@ Disable the peripheral clocks, and set the core clock frequency +@ +@ The code then spins on the oscillator OK bit until the oscilator is stable +@ which can take as long as two seconds. +@ + +xlli_clks_init_sleepReset: + +@ Turn Off ALL on-chip peripheral clocks for re-configuration +@ + ldr r4, =xlli_CLKREGS_PHYSICAL_BASE@ Load clock registers base address + ldr r1, =0x400000 @ Forces memory clock to stay ON!! + ldr r2, =xlli_CKEN_value @ Get any other bits required from the include file + orr r1, r1, r2 @ OR everything together + str r1, [r4, #xlli_CKEN_offset] @ ... and write out to the clock enable register +@ +@ Set Crystal: Memory Freq, Memory:RunMode Freq, RunMode, TurboMode Freq Multipliers, +@ set RunMode & TurboMode to default frequency. +@ + ldr r2, =xlli_CCCR_value @ Get CORE_CLK_DEFAULT value + str r2, [r4, #xlli_CCCR_offset] @ Write to the clock config register +@ +@ Read back from APB to ensure our writes have completed before continuing +@ + ldr r2, [r4, #xlli_CCCR_offset] + + mov pc, lr @ return to calling routine + + + +@******************************************************************************************** +@ +@ *********************************************** +@ ********** ********** +@ ********** FREQUENCY CHANGE SEQUENCE ********** +@ ********** ********** +@ *********************************************** +@ +@ This subroutine initiates the frequency change sequence and restarts the memory controller +@ + +xlli_freq_change: + + mrc p14, 0, r2, c6, c0, 0 @ Get present status (preserve Turbo and Fast Bus bits) + orr r2, r2, #2 @ Set the F bit + mcr p14, 0, r2, c6, c0, 0 @ initiate the frequency change sequence - Wheeeeeeeee! +@ +@ If the clock frequency is chaged, the MDREFR Register must be rewritten, even +@ if it's the same value. This will result in a refresh being performed and the +@ refresh counter being reset to the reset interval. (Section 13.10.3, pg 13-17 of EAS) +@ + ldr r4, =xlli_MEMORY_CONFIG_BASE @ Get memory controller base address + ldr r1, [r4, #xlli_MDREFR_offset] @ Get the current state of MDREFR + str r1, [r4, #xlli_MDREFR_offset] @ Re-write this value + + mov pc, lr @ return to calling routine + + + +@******************************************************************************************** +@ +@ ******************************************************** +@ ********** ********** +@ ********** INITIALIZE OPERATING SYSTEM TIMERS ********** +@ ********** ********** +@ ******************************************************** +@ +@ This code segment initializes the OST count registers to zero, clears the +@ status bits in OSSR, and zeroes out the match registers. +@ +@ After this function is called, the OS timers should be initalized to the +@ same state as on HW reset. +@ +@ The interrupt bit for match register 1 is set for use by timing macros. +@ + +xlli_ost_init: + + ldr r2, =xlli_OSTREGS_PHYSICAL_BASE @ get base address for os timer registers + mov r3, #0 @ clear work register + + str r3, [r2, #xlli_OSCR0_offset] @ zero out OS Timer Count register + str r3, [r2, #xlli_OWER_offset] @ zero out OS Timer Watchdog Match Enable Register + str r3, [r2, #xlli_OIER_offset] @ zero out OS Timer Interrupt Enable register + str r3, [r2, #xlli_OSSR_offset] @ zero out OS Timer Status register + + str r3, [r2, #xlli_OMCR4_offset] @ Zero out Match Control Registers + str r3, [r2, #xlli_OMCR5_offset] + str r3, [r2, #xlli_OMCR6_offset] + str r3, [r2, #xlli_OMCR7_offset] + str r3, [r2, #xlli_OMCR8_offset] + str r3, [r2, #xlli_OMCR9_offset] + str r3, [r2, #xlli_OMCR10_offset] + str r3, [r2, #xlli_OMCR11_offset] + + str r3, [r2, #xlli_OSCR0_offset] @ Zero out count register 0 + str r3, [r2, #xlli_OSCR4_offset] @ Zero out count register 4 - 11 + str r3, [r2, #xlli_OSCR5_offset] + str r3, [r2, #xlli_OSCR6_offset] + str r3, [r2, #xlli_OSCR7_offset] + str r3, [r2, #xlli_OSCR8_offset] + str r3, [r2, #xlli_OSCR9_offset] + str r3, [r2, #xlli_OSCR10_offset] + str r3, [r2, #xlli_OSCR11_offset] + + str r3, [r2, #xlli_OSMR0_offset] @ zero-out all 12 match registers + str r3, [r2, #xlli_OSMR1_offset] + str r3, [r2, #xlli_OSMR2_offset] + str r3, [r2, #xlli_OSMR3_offset] + str r3, [r2, #xlli_OSMR4_offset] + str r3, [r2, #xlli_OSMR5_offset] + str r3, [r2, #xlli_OSMR6_offset] + str r3, [r2, #xlli_OSMR7_offset] + str r3, [r2, #xlli_OSMR8_offset] + str r3, [r2, #xlli_OSMR9_offset] + str r3, [r2, #xlli_OSMR10_offset] + str r3, [r2, #xlli_OSMR11_offset] + + ldr r1, =xlli_OSSR_ALL @ Clear the status bits - these are 'sticky' bits, + str r1, [r2, #xlli_OSSR_offset] @ These bits are cleared by writing 1's to them +@ +@ Read back from APB to ensure our writes have completed before continuing +@ + ldr r1, [r2, #xlli_OSSR_offset] + + mov pc, lr @ return to calling routine + + + +@******************************************************************************************** +@ +@ ********************************************************************** +@ ********** ********** +@ ********** ENABLE I-CACHE, D-CACHE AND BRANCH TARGET BUFFER ********** +@ ********** ********** +@ ********************************************************************** +@ +@ This code segment enables the Instruction Cache, Data Cache, and the Branch Target Buffer. +@ +xlli_icache_enable: + + mrc p15, 0, r2, c1, c0, 0 @ Get the contents of the ARM control register + mov r2, r2, LSL #18 @ Upper 18-bits must be written as zero... + mov r2, r2, LSR #18 @ ....clear them now + + orr r2, r2, #xlli_control_icache @ set the i-cache bit + orr r2, r2, #xlli_control_btb @ set the btb bit + orr r2, r2, #xlli_control_dcache @ set the d-cache bit + + @ This code segment writes the contents of r2 into the ARM control register. + @ Note: you must either format the contents of w1 so that reserved bits + @ are written with the proper value, or get the getARMControl values and + @ modify the control bits you need. + @ + @ make sure this is first instruction in a cache line + + b xlli_7 + .balign 32 +xlli_7: + mcr p15, 0, r2, c1, c0, 0 + + @ This code segment guarantees that previous writes to coprocessor 15 have + @ completed. Depending on what is being modified in cp15 (turning on + @ the mmu, for example), these instructions may need to be executed + @ from the icache. + + mrc p15, 0, r2, c1, c0, 0 + mov r2, r2 + sub pc, pc, #4 + + mov pc, lr @ return to calling routine + + + +@******************************************************************************************** +@ +@ ************************************************** +@ ********** ********** +@ ********** INITIALIZE the POWER MANAGER ********** +@ ********** ********** +@ ************************************************** +@ +@ This code initializes the Power Manager +@ +xlli_pwrmgr_init: + + ldr r2, =xlli_PMRCREGS_PHYSICAL_BASE @ get base address of power mgr / reset control regs + + mov r1, #0 @ clear a work register + str r1, [r2, #xlli_PWER_offset] @ Reset Power Manager Wake-up register + str r1, [r2, #xlli_PRER_offset] @ Clear Power Manager Rising-Edge Detector Enables + str r1, [r2, #xlli_PFER_offset] @ Clear Power Manager Falling-Edge Detector Enables + str r1, [r2, #xlli_PEDR_offset] @ Clear Power Manager GPIO edge-Detect Status register + str r1, [r2, #xlli_PGSR0_offset] @ Clear GPIO sleep state registers (GPIOs 31:0) + str r1, [r2, #xlli_PGSR1_offset] @ Clear GPIO sleep state registers (GPIOs 63:32) + str r1, [r2, #xlli_PGSR2_offset] @ Clear GPIO sleep state registers (GPIOs 95:64) + str r1, [r2, #xlli_PGSR3_offset] @ Clear GPIO sleep state registers (GPIOs 118:96) + str r1, [r2, #xlli_PSTR_offset] @ Reset Standby Configuration Register + str r1, [r2, #xlli_PVCR_offset] @ Reset Power Manager Voltage Change Control Register + str r1, [r2, #xlli_PKWR_offset] @ Clear Keyboard Wake-up Enable Register + str r1, [r2, #xlli_PKSR_offset] @ Clear Keyboard Edge Detect Status Register +@ +@ Initialize the PCFR (Power Manager General Congiguration Manager) +@ Assume PCFR is 'sane' - zeroed on power up +@ + ldr r3, =xlli_PMRCREGS_PHYSICAL_BASE + ldr r1, [r3, #xlli_PCFR_offset] + ldr r2, =xlli_PCFR_USEDBITS + and r1, r1, r2 @ clear unused bits + orr r1, r1, #xlli_PCFR_OPDE @ enable 3.68Mhz power-down + orr r1, r1, #xlli_PCFR_SYSEN_EN @ System power supply enable pin + str r1, [r3, #xlli_PCFR_offset] +@ +@ Read back from APB to ensure our writes have completed before continuing +@ + ldr r1, [r3, #xlli_PCFR_offset] + + mov pc, lr @ return to calling routine + + + +@******************************************************************************************** +@ +@ ***************************************** +@ ********** ********** +@ ********** SET PAGE TABLE BASE ********** +@ ********** ********** +@ ***************************************** +@ +@ Set page table base (used after a sleep reset) +@ +xlli_setPTB: + + ldr r1, =xlli_p_PageTable @ Get address of Page Table base + mcr p15, 0, r1, c2, c0, 0 @ Load Page Table base into CP 15 + + mov pc, lr @ return to calling routine + + + +@******************************************************************************************** +@ +@ *************************************************************** +@ ********** ********** +@ ********** INITIALIZE PAGE TABLES FOR MEMORY MAPPING ********** +@ ********** ********** +@ *************************************************************** +@ +@ Init the Page Table area of memory by writting zeros out to the table +@ + +xlli_initPageTable: + + ldr r1, =xlli_p_PageTable @ Get address of Page Table base + mcr p15, 0, r1, c2, c0, 0 @ Load Page Table base into CP 15 +@ +@ zero-out the page table memory region +@ + mov r2, #xlli_s_PageTable @ get table size + mov r3, #0 +xlli_8: + subs r2, r2, #4 @ Increment offset into table + str r3, [r1, r2] @ Clear table entry + bne xlli_8 @ Keep looping until done + + mov pc, lr @ return to calling routine + + + +@******************************************************************************************** +@ +@ *********************************************************** +@ ********** ********** +@ ********** INITIALIZE THE MEMORY MANAGEMENT UNIT ********** +@ ********** ********** +@ *********************************************************** +@ +@ Initialize the memory management unit +@ + +xlli_MMU_init: + + @ set DACR + ldr r1, =xlli_DACR + mcr p15, 0, r1, c3, c0, 0 @ Set DACR + + ldr r2, =xlli_PID + mov r2, r2, LSR #25 @ Clear the lo-order 25 bits + mov r2, r2, LSL #25 @ (may be unnecessary) + mcr p15, 0, r2, c13, c0, 0 @ Set PID + + mrc p15, 0, r1, c1, c0, 1 @ Get the current aux control settings + +@ extract the control bits such that reserved bits are 0, this will +@ prep the bits for a subsequent write. + + and r1, r1, #0x33 + orr r1, r1, #xlli_CONTROL_MINIDATA_01 @ orr in the mini-data cache attributes + + mcr p15, 0, r1, c1, c0, 1 @ Write back the new settings + +@ invalidate and enable the BTB + + mcr p15, 0, r1, c7, c5, 6 @ invalidate the Branch Target Buffer +@ +@ enable the BTB +@ + mrc p15, 0, r1, c1, c0, 0 + mov r1, r1, LSL #18 @ Upper 18 bits must be + mov r1, r1, LSR #18 @ written as zeros + orr r1, r1, #xlli_CONTROL_BTB @ set the BTB bit + + b xlli_9 @ 1st instruction on cache line + .balign 32 +xlli_9: + mcr p15, 0, r1, c1, c0, 0 @ write the data back + mrc p15, 0, r1, c2, c0, 0 @ Insure that the write completes + mov r1, r1 @ before continuing + sub pc, pc, #4 + + mov pc, lr @ return to calling routine + + + +@******************************************************************************************** +@ +@ ************************************************************** +@ ********** ********** +@ ********** FIRE UP THE MMU - SWITCH TO VIRTUAL MODE ********** +@ ********** ********** +@ ************************************************************** +@ +@ Make the transistion from physical mode to virtual mode. +@ +@ This subroutine assumes thaqt execution is from boot ROM and that +@ the MMU is disabled when this subroutine is called. +@ +@ NOTES: +@ +@ 1. The memory system must already be up and running. +@ 2. The page table must be initalized (zeroed out) +@ 3. The memory to be accessed must have their page table entries filled in. +@ 4. The MMU needs to be initialized first. +@ 5. When this subroutine returns to the caller, all addresses are virtual. +@ +@ Typically this would be the last low level init subroutine to be run before +@ control is turned over to an operating system. +@ + +xlli_goVirtual: +@ +@ (1) Temporarily overwrite page table entry that maps where we are now. +@ +@ This code section effectivly makes the table entry where the program counter +@ (pc) would point now and, the table entry where the new pc value will point, +@ (after going to virtual addressing) result in the code pointing to the same +@ physical address regardless of which pc value is used. This is to +@ cover those cases where the pc is altered after the jump to virtual +@ addresing. If the sections are idenity (flat) mapped, then the following +@ code basicly rewrites a single table entery with a copy of itself. Once the +@ pc has been altered to the virtual address, the original table entry for the +@ address space we are now is is restored to its original value. +@ +@ CAUTION: If the page table is mapped to virtual address different from the physical +@ address, this code is likely to result in an exception to 0x10 (Data Abort) unless +@ you modify the code in the section to take this into account. +@ + ldr r1, =xlli_p_PageTable @ Get address of Page Table base + + mov r4, pc, LSR #(20) @ Current execution location (divide by 1 Mb) + mov r4, r4, LSL #(2) @ Insure lower two bits are zero + add r4, r4, r1 @ Point to RAM page table entry for this address space + ldr r3, [r4] @ Save the existing table entry in r3 +@ +@ Do not alter r3 or r4 as we will need them later... +@ + ldr r2, =(xlli_v_xbBOOTROM >> (18)) + add r2, r2, r1 @ Point to new (virtual) ROM page table entry + ldr r1, [r2] @ Get this (virtural address) table entry.... +@ +@ Overwrite RAM entry for current (physical address) table entry +@ + str r1, [r4] @ ....and place it in the current table entry. + +@ end-of-part (1) +@ ------------------------------------------------- +@ (2) setup to enable the MMU +@ +@ Generate (in r1) the virtual address the code will jump to once the +@ transition has been made to virtual address mode. +@ + add r1, pc, #xlli_12 - (.+8) @ Load address of xlli_12 into r1 + add r1, r1, #xlli_v_xbBOOTROM @ add offset to virtual ROM address +@ +@ Invalidate both TLBs +@ + mcr p15, 0, r2, c8, c7, 0 @ Invalidates both instruction and data TLBs +@ +@ enable mmu +@ + mrc p15, 0, r2, c1, c0, 0 @ Read current settings in control reg + mov r2, r2, LSL #18 @ Upper 18-bits must be written as zero, + mov r2, r2, LSR #18 @ ... clear them now. +@ +@ Set ROM protection, Clear System protection, Set MMU bit +@ + orr r2, r2, #xlli_control_r @ set the ROM Protection bit + bic r2, r2, #xlli_control_s @ clear the System Protection bit + orr r2, r2, #xlli_control_mmu @ set the MMU bit +@ +@ Write back the new value +@ + b xlli_11 @ make sure this is first instruction in a cache line + .balign 32 +xlli_11: + mcr p15, 0, r2, c1, c0, 0 @ Go Virtual! + mrc p15, 0, r2, c2, c0, 0 @ Insure that the write completes + mov r2, r2 @ before continuing + sub pc, pc, #4 +@ +@ invalidate both caches, btb +@ + mcr p15, 0, r2, c7, c7, 0 + + mov pc, r1 @ Load virtual address into the pc + nop @ nop instructions to "empty the pipeline" + nop + nop + nop + nop + nop +xlli_12: + add lr, lr, #xlli_v_xbBOOTROM @ Update the link register return address + +@ end-of-part (2) +@ ------------------------------------------------- +@ (3) restore the overwritten page table entry, flush all caches +@ The following instruction assumes the page table is idenity mapped! +@ + str r3, [r4] @ This restores original page table entry +@ +@ Invalidate both TLBs and caches +@ + mcr p15, 0, r2, c8, c7, 0 @ Invalidates both instruction and data TLBs + mcr p15, 0, r2, c7, c7, 0 @ invalidate both caches, BTB + + nop @ Make sure the pipe is empty + nop + nop + nop + nop + nop +@ +@ end-of-part (3) +@ ------------------------------------------------- +@ set up cache memory for use +@ + mcr p15, 0, r1, c7, c6, 0 @ Invalidates the D cache + mcr p15, 0, r1, c8, c6, 0 @ Invalidates the data TLB + + mrc p15, 0, r2, c2, c0, 0 @ Insure that the write completes + mov r2, r2 @ before continuing + sub pc, pc, #4 +@ +@ invalidate the BTB +@ + mcr p15, 0, r1, c7, c5, 6 @ invalidate the Branch Target Buffer +@ +@ Enable ICache, DCache, BTB +@ + mrc p15, 0, r2, c1, c0, 0 @ Read current settings in control reg + mov r2, r2, LSL #18 @ Upper 18-bits must be written as zero, + mov r2, r2, LSR #18 @ ... clear them now. + + orr r2, r2, #xlli_control_dcache @ set the DCache bit + orr r2, r2, #xlli_control_icache @ set the ICache bit + orr r2, r2, #xlli_control_btb +@ +@ Write back the new value +@ + b xlli_13 @ make sure this is first instruction in a cache line + .balign 32 +xlli_13: + mcr p15, 0, r2, c1, c0, 0 + mrc p15, 0, r2, c2, c0, 0 @ Insure that the write completes + mov r2, r2 @ before continuing + sub pc, pc, #4 + + mov pc, lr @ return to calling routine + + + +@******************************************************************************************** +@ +@ *************************************************************** +@ ********** ********** +@ ********** INITIALIZE INTERNAL MEMORY POWER REGISTER ********** +@ ********** ********** +@ *************************************************************** +@ +@ Power up the internal memory for use (Default on system reset) +@ +@ Note: This subroutine sets the internal memory to the hardware reset default state +@ which is all memory in run mode with auto wake-up disabled and never going +@ into standby mode. +@ + +xlli_IMpwr_init: + + ldr r2, =xlli_IMEMORY_CONFIG_BASE @ get base address of IM Power Management control regs + mov r1, #0 @ Set all memory to RUN mode and disable auto wakeup + str r1, [r2, #xlli_IMPMCR_offset] @ Write the data to the control register + + mov pc, lr @ return to calling routine + + + +@******************************************************************************************** +@ +@ ******************************************************* +@ ********** ********** +@ ********** GET SYSTEM CONFIGURATION REGISTER ********** +@ ********** ********** +@ ******************************************************* +@ +@ This is a "C" program callable subroutine that returns the value stored in the +@ last SRAM memory location - which presumably still contains the Glencoe/Mainstone +@ system configuration data that was put there by the xlli_read_SCR subroutine. +@ +@ Note: The system stack register must be set up before this subroutine is called. +@ + +GetSCR: + + stmfd sp!, {r1, lr} @ Save r1 and link register on the stack + ldr r1, =xlli_SCR_data @ Address where system config data is stored + ldr r0, [r1] @ Read the contents of SCR into r0 + ldmfd sp!, {r1, pc} @ Restore r1 and return to caller + + + +@******************************************************************************************** +@ +@ ************************************************************ +@ ********** ********** +@ ********** SET SYSTEM CLOCKS FROM INCLUDED DEFINE ********** +@ ********** ********** +@ ************************************************************ +@ +@ This subroutine sets the PXA27x/Glencoe clocks based on the settings in xlli_Glencoe.defs +@ In order not to break the familiarity with the Mainstone platform, the clock settings are +@ composed into a Mainstone-switch like value, which is used here. +@ NOTE: This subroutine just sets the bits according to switch settings. The user needs to call the +@ change frequency sequence subroutine (xlli_freq_change) for the values to take effect. +@ +xlli_setClocks: +@ +@ This code segment gets the platform hex switch settings and loads the appropriate N and L values into +@ the CCCR register. Switch register Bits 15:11 and 7 are ignored by this code. +@ + ldr r2, =(xlli_CLOCK_SWITCH_L_N | xlli_CLOCK_SWITCH_CCCR_A | xlli_CLOCK_SWITCH_FASTBUS | xlli_CLOCK_SWITCH_SDCLK | xlli_CLOCK_SWITCH_TURBO) @ calculate value (eq. to Mainstone switch setting) + + and r3, r2, #0x7F @ Get both HEX rotary values + mov r3, r3, LSL #2 @ Multiply by 4 to get word offset + add r1, pc, #xlli_CLK_DATA - (.+8) @ Load address of CLK_DATA into r1 + add r1, r1, r3 @ Point to address that contains the CCCR data to be loaded + ldr r5, [r1] @ load CCCR value into r5 + ands r3, r2, #0x80 @ Is bit 7 set (to set the CCCR A bit)? - This is why we only + @ need a table that goes through 7F (they're the same above it) + orrne r5, r5, #0x2000000 @ YES - set the A bit + ldr r1, =xlli_CLKREGS_PHYSICAL_BASE @ Get clocks register base address + str r5, [r1, #xlli_CCCR_offset] @ Load the new CCCR value +@ +@ Read back from APB to ensure our writes have completed before continuing +@ +@ ldr r5, [r1, #xlli_CCCR_offset] + +@ +@ Check switch bit 9 for SDCLK setting (MemClk/2 or MemClock) +@ + ldr r1, =xlli_MEMORY_CONFIG_BASE @ Clock registers base address + ldr r6, [r1, #xlli_MDREFR_offset] @ get present value + ands r3, r2, #0x200 @ Test switch bit 9 for "dot" or "no dot" position + bicne r6, r6, #xlli_MDREFR_K1DB2 @ clear bit + orreq r6, r6, #xlli_MDREFR_K1DB2 @ set bit so SDCLK = 1/2 MCEMCLK + str r6, [r1, #xlli_MDREFR_offset] @ Write data back to register +@ +@ Check switch bit 8 for Fast/Normal bus speed. +@ If hex switch setting is 0x5A - 0x7F or 0xDA and greater, the Fast Bus mode bit must +@ be cleared. +@ NOTE: Do not alter the contents of r5 which has the new CCCR value stored in it! +@ + mrc p14, 0, r4, c6, c0, 0 @ Get data in CP14, Register 6 + ands r3, r2, #0x100 @ Test bit 8 for "dot" or "no dot" + biceq r4, r4, #0X8 @ Clear Fast Bus speed bit + beq xlli_14 @ B=0, so jump over the part that check if it's save to set B=1 + orrne r4, r4, #0x8 @ Set Fast Bus speed bit + +@ At this point, B=1 so we need to compare against 0x5A through 0x7F and then against +@ 0xDA through 0xF7. F8-FA are NECESSARY for A=1, N=3, B=1 is A LEGAL value, so must +@ preserve. Otherswise, we need to see if we've hit a point where the Fast Bus mode bit must be cleared +@ + and r3, r2, #0x7F @ Grab just the HEX rotary switch value + +@ If we blindly assume A=1 in this compare, we've taken care of most of the problem. This reduces +@ the amount of compares to 2, as we compare against 0x5A which will take care of the 0xDA case also + cmp r3, #0x5A @ Compare to a hex switch setting of 0x5A (A=x, B=1) + ble xlli_14 @ Less than or Equal, jump over the next few instructions + + and r3, r2, #0xFF @ Grab just the HEX rotary switch value AGAIN + cmp r3, #0xF7 @ We've hit the F8-FA, so jump to end + bgt xlli_14 + +@ Now clear the Fast Bus (B-bit) if we've hit this point + bic r4, r4, #0x8 @ Clear Fast Bus speed bit if greater or equal to 0x5A + +xlli_14: +@ +@ Check switch bit 10 for Turbo or non-Turbo mode. +@ + ands r3, r2, #0x400 @ Test switch bit 10 for "dot" or "no dot" position + biceq r4, r4, #1 @ Clear Turbo bit + orrne r4, r4, #1 @ Set Turbo bit + + bic r4, r4, #0x2 @ Clear the F bit (so frequency change doesn't happen here) + +@ Now write the value back + mcr p14, 0, r4, c6, c0, 0 @ Write data to CP14, Register 6 + +@ At this point, although we've already set the MDREFR register based off of switch bit 9 +@ We need to chack the MDREFR register vs. the desired frequency. If it's too high, we should +@ halve or even quarter (for flash) if it's too hight to run properly. This is being done here +@ as it is the intent to call the frequency change sequency after this function. +@ Values that need to halve or quarter MemClk (the rest can be left alone): +@ +@ For A=0, B=0: +@ K0DB2=1 (K1DB2 cleared) when L= 5-8 (0x15-0x30), 11-16 (0x3F-0x5A), 21-31 (0x67-0x7F) +@ K0DB4=1 and K1DB2=1 when L= 9 (0x31-0x37), 10 (0x38-0x3E), 17-20 (0x5B-0x7F) +@ +@ For A=0, B=1: *NOTE* (L17 and higher are illegal for B=1) +@ K0DB2=1 (K1DB2 cleared) when L= 5-8 (0x15-0x30), 11-16 (0x3F-0x5A) +@ K0DB4=1 and K1DB2=1 when L= 9 (0x31-0x37), 10 (0x38-0x3E) +@ +@ For A=1, B=0: +@ K0DB2=1 (K1DB2 cleared) when L= 9-16 (0xB1-0xDA) +@ K0DB4=1 and K1DB2=1 when L= 17-31 (0xDB-0xFF) +@ +@ For A=1, B=1: *NOTE* (L17 and higher are illegal for B=1) +@ K0DB2=1 (K1DB2 cleared) when L= 5-8 (0x95-0xB0) +@ K0DB4=1 and K1DB2=1 when L= 9-16 (0xB1-0xDA) +@ + + mov r3, r6 @ R6 from way above still contains the value we wrote to teh MDREFR register. + +@ Clear the KxDBx bits, so that way we can set it to what we want + + ldr r7, =0x20084000 @ KxDBx clear mask (leave K1DB2 from above) + bic r3, r3, r7 @ Clear the KxDBx bits + +@ At this point r5 = CCCR, R4 = B bit (CP14,R6). Pull out the relevant bits + + and r7, r5, #xlli_CCCR_A_Bit_Mask @ R5 now has just the A bit + mov r7, r7, LSR #25 @ move it down to the lowest bit (for easy comparison's sake) + and r2, r5, #0x1F @ Get the L value + and r1, r4, #0x8 @ Get the B bit + mov r1, r1, LSR #3 @ Move it down (that comparison thing...) + + @ Now r0 = A-bit, r1 = B-bit, r2 = L-value + + cmp r7, #0x0 @ A == 0? + bne xlli_a_equ_1 @ Nope, A=1, jump to that area of code +@ +@ A=0 at this point +@ + cmp r1, #0x0 @ B == 0? + bne xlli_a0_b_equ_1 @ Nope, A=0, B=1 + + @ A=0, B=0 at this point + cmp r2, #0x5 @ r2 < 5 ? + bcc xlli_done_mdrefr_check @ L2-L4 need no MemClk division + cmp r2, #0x8 @ r2 <= 8 ? + bls xlli_set_k0db2 @ L5-L8 need MemClk/2 + cmp r2, #0xA @ r2 <= 10? + bls xlli_set_k0db4 @ L9-L10 need MemClk/4 + cmp r2, #0x10 @ r2 <= 16? + bls xlli_set_k0db2 @ L11-L16 need MemClk/2 + cmp r2, #0x14 @ r2 <= 20? + bls xlli_set_k0db4 @ L17-L20 need MemClk/4 + bhi xlli_set_k0db2 @ L21-L31 need MemClk/2 + +xlli_a0_b_equ_1: +@ +@ A=0, B=1 +@ + cmp r2, #0x5 @ r2 < 5 ? + bcc xlli_done_mdrefr_check @ L2-L4 need no MemClk division + cmp r2, #0x8 @ r2 <= 8 ? + bls xlli_set_k0db2 @ L5-L8 need MemClk/2 + cmp r2, #0xA @ r2 <= 10? + bls xlli_set_k0db4 @ L9-L10 need MemClk/4 + bhi xlli_set_k0db2 @ L11-L16 need MemClk/2 - We've already prevented L above 16 when B=1 + +xlli_a_equ_1: +@ +@ A=1, B=? +@ + cmp r1, #0x0 @ B == 0? + bne xlli_a1_b_equ_1 @ Nope, A=0, B=1 +@ +@ A=1, B=0 at this point +@ + cmp r2, #0x9 @ r2 < 9 ? + bcc xlli_done_mdrefr_check @ L2-L8 need no MemClk division + cmp r2, #0x10 @ r2 <= 16 ? + bls xlli_set_k0db2 @ L9-L16 need MemClk/2 + bhi xlli_set_k0db4 @ L17-L31 need MemClk/4 + +xlli_a1_b_equ_1: +@ +@ A=1, B=1 +@ + cmp r2, #0x5 @ r2 < 5 ? + bcc xlli_done_mdrefr_check @ L2-L4 need no MemClk division + cmp r2, #0x8 @ r2 <= 8 ? + bhi xlli_set_k0db4 @ L9-L16 need MemClk/4 +@ +@ Just fall through to k0db2 for L5-8 +@ +@ NOTE: Since the expected order is to call xlli_mem_Tmax before calling this function, +@ simply set the KxDBx bits and move on (mem timings already maxed) +@ +xlli_set_k0db2: +@ +@ Set the K0DB2 bit, K1DB2 does not need to be set +@ + mov r2, #0x1 + mov r2, r2, LSL #14 @ Set MDREFR bit 14 (K0DB2) + orr r3, r3, r2 + b xlli_done_mdrefr_check @skip over the MemClk/4 stuff + +xlli_set_k0db4: +@ +@ Set the K0DB4 bit, K1DB2 must also be set (frequencies higher than 104MHz) +@ + ldr r2, =0x20020000 @ Set Bits 29 (K0DB4) & 17 (K1DB2) + orr r3, r3, r2 +@ +@ Now just fall through to setting the MDREFR back +@ +xlli_done_mdrefr_check: +@ +@ Write the MDREFR value back and move on. +@ + ldr r7, =xlli_MEMORY_CONFIG_BASE @ Reload r0 with memory controller base address + str r3, [r7, #xlli_MDREFR_offset] @ Set the new MDREFR value + + mov pc, lr @ Return to calling routine +@ +@ The following table is a lookup table for the values of L and N to be used depending on the hex switch +@ setting on the Mainstone development platform. The values listed below are simply the values to be +@ loaded directly into the CCCR register. "xx" = Hex Switch setting, L = Core frequency, N = Turbo multiplier +@ +@ For the Glencoe platform, the same assignments have been used, but the actual values are set in xlli_Glencoe_defs.inc +@ +xlli_CLK_DATA: + .balign 4 + .word 0x102 @ "00" L=2, N=1 + .balign 4 + .word 0X182 @ "01" L=2, N=1.5 + .balign 4 + .word 0X202 @ "02" L=2, N=2 + .balign 4 + .word 0X282 @ "03" L=2, N=2.5 + .balign 4 + .word 0X302 @ "04" L=2, N=3 + .balign 4 + .word 0X382 @ "05" L=2, N=3.5 + .balign 4 + .word 0X402 @ "06" L=2, N=4 + + .balign 4 + .word 0x103 @ "07" L=3, N=1 + .balign 4 + .word 0X183 @ "08" L=3, N=1.5 + .balign 4 + .word 0X203 @ "09" L=3, N=2 + .balign 4 + .word 0X283 @ "0A" L=3, N=2.5 + .balign 4 + .word 0X303 @ "0B" L=3, N=3 + .balign 4 + .word 0X383 @ "0C" L=3, N=3.5 + .balign 4 + .word 0X403 @ "0D" L=3, N=4 + + .balign 4 + .word 0x104 @ "0E" L=4, N=1 + .balign 4 + .word 0X184 @ "0F" L=4, N=1.5 + .balign 4 + .word 0X204 @ "10" L=4, N=2 + .balign 4 + .word 0X284 @ "11" L=4, N=2.5 + .balign 4 + .word 0X304 @ "12" L=4, N=3 + .balign 4 + .word 0X384 @ "13" L=4, N=3.5 + .balign 4 + .word 0X404 @ "14" L=4, N=4 + + .balign 4 + .word 0x105 @ "15" L=5, N=1 + .balign 4 + .word 0X185 @ "16" L=5, N=1.5 + .balign 4 + .word 0X205 @ "17" L=5, N=2 + .balign 4 + .word 0X285 @ "18" L=5, N=2.5 + .balign 4 + .word 0X305 @ "19" L=5, N=3 + .balign 4 + .word 0X385 @ "1A" L=5, N=3.5 + .balign 4 + .word 0X405 @ "1B" L=5, N=4 + + .balign 4 + .word 0x106 @ "1C" L=6, N=1 + .balign 4 + .word 0X186 @ "1D" L=6, N=1.5 + .balign 4 + .word 0X206 @ "1E" L=6, N=2 + .balign 4 + .word 0X286 @ "1F" L=6, N=2.5 + .balign 4 + .word 0X306 @ "20" L=6, N=3 + .balign 4 + .word 0X386 @ "21" L=6, N=3.5 + .balign 4 + .word 0X406 @ "22" L=6, N=4 + + .balign 4 + .word 0x107 @ "23" L=7, N=1 + .balign 4 + .word 0X187 @ "24" L=7, N=1.5 + .balign 4 + .word 0X207 @ "25" L=7, N=2 + .balign 4 + .word 0X287 @ "26" L=7, N=2.5 + .balign 4 + .word 0X307 @ "27" L=7, N=3 + .balign 4 + .word 0X387 @ "28" L=7, N=3.5 + .balign 4 + .word 0X407 @ "29" L=7, N=4 + + .balign 4 + .word 0x108 @ "2A" L=8, N=1 + .balign 4 + .word 0X188 @ "2B" L=8, N=1.5 + .balign 4 + .word 0X208 @ "2C" L=8, N=2 + .balign 4 + .word 0X288 @ "2D" L=8, N=2.5 + .balign 4 + .word 0X308 @ "2E" L=8, N=3 + .balign 4 + .word 0X388 @ "2F" L=8, N=3.5 + .balign 4 + .word 0X408 @ "30" L=8, N=4 + + .balign 4 + .word 0x109 @ "31" L=9, N=1 + .balign 4 + .word 0X189 @ "32" L=9, N=1.5 + .balign 4 + .word 0X209 @ "33" L=9, N=2 + .balign 4 + .word 0X289 @ "34" L=9, N=2.5 + .balign 4 + .word 0X309 @ "35" L=9, N=3 + .balign 4 + .word 0X389 @ "36" L=9, N=3.5 + .balign 4 + .word 0X409 @ "37" L=9, N=4 + + .balign 4 + .word 0x10A @ "38" L=10, N=1 + .balign 4 + .word 0X18A @ "39" L=10, N=1.5 + .balign 4 + .word 0X20A @ "3A" L=10, N=2 + .balign 4 + .word 0X28A @ "3B" L=10, N=2.5 + .balign 4 + .word 0X30A @ "3C" L=10, N=3 + .balign 4 + .word 0X38A @ "3D" L=10, N=3.5 + .balign 4 + .word 0X40A @ "3E" L=10, N=4 + + .balign 4 + .word 0x10B @ "3F" L=11, N=1 + .balign 4 + .word 0X18B @ "40" L=11, N=1.5 + .balign 4 + .word 0X20B @ "41" L=11, N=2 + .balign 4 + .word 0X28B @ "42" L=11, N=2.5 + .balign 4 + .word 0X30B @ "43" L=11, N=3 + .balign 4 + .word 0X38B @ "44" L=11, N=3.5 + + .balign 4 + .word 0x10C @ "45" L=12, N=1 + .balign 4 + .word 0X18C @ "46" L=12, N=1.5 + .balign 4 + .word 0X20C @ "47" L=12, N=2 + .balign 4 + .word 0X28C @ "48" L=12, N=2.5 + .balign 4 + .word 0X30C @ "49" L=12, N=3 + + .balign 4 + .word 0x10D @ "4A" L=13, N=1 + .balign 4 + .word 0X18D @ "4B" L=13, N=1.5 + .balign 4 + .word 0X20D @ "4C" L=13, N=2 + .balign 4 + .word 0X28D @ "4D" L=13, N=2.5 + .balign 4 + .word 0X30D @ "4E" L=13, N=3 + + .balign 4 + .word 0x10E @ "4F" L=14, N=1 + .balign 4 + .word 0X18E @ "50" L=14, N=1.5 + .balign 4 + .word 0X20E @ "51" L=14, N=2 + .balign 4 + .word 0X28E @ "52" L=14, N=2.5 + + .balign 4 + .word 0x10F @ "53" L=15, N=1 + .balign 4 + .word 0X18F @ "54" L=15, N=1.5 + .balign 4 + .word 0X20F @ "55" L=15, N=2 + .balign 4 + .word 0X28F @ "56" L=15, N=2.5 + + .balign 4 + .word 0x110 @ "57" L=16, N=1 + .balign 4 + .word 0X190 @ "58" L=16, N=1.5 + .balign 4 + .word 0X210 @ "59" L=16, N=2 + .balign 4 + .word 0X290 @ "5A" L=16, N=2.5 + + .balign 4 + .word 0x111 @ "5B" L=17, N=1 + .balign 4 + .word 0x191 @ "5C" L=17, N=1.5 + .balign 4 + .word 0x211 @ "5D" L=17, N=2 + + .balign 4 + .word 0x112 @ "5E" L=18, N=1 + .balign 4 + .word 0x192 @ "5F" L=18, N=1.5 + .balign 4 + .word 0x212 @ "60" L=18, N=2 + + .balign 4 + .word 0x113 @ "61" L=19, N=1 + .balign 4 + .word 0x193 @ "62" L=19, N=1.5 + .balign 4 + .word 0x213 @ "63" L=19, N=2 + + .balign 4 + .word 0x114 @ "64" L=20, N=1 + .balign 4 + .word 0x194 @ "65" L=20, N=1.5 + .balign 4 + .word 0x214 @ "66" L=20, N=2 + + .balign 4 + .word 0x115 @ "67" L=21, N=1 + .balign 4 + .word 0x195 @ "68" L=21, N=1.5 + + .balign 4 + .word 0x116 @ "69" L=22, N=1 + .balign 4 + .word 0x196 @ "6A" L=22, N=1.5 + + .balign 4 + .word 0x117 @ "6B" L=23, N=1 + .balign 4 + .word 0x197 @ "6C" L=23, N=1.5 + + .balign 4 + .word 0x118 @ "6D" L=24, N=1 + .balign 4 + .word 0x198 @ "6E" L=24, N=1.5 + + .balign 4 + .word 0x119 @ "6F" L=25, N=1 + .balign 4 + .word 0x199 @ "70" L=25, N=1.5 + + .balign 4 + .word 0x11A @ "71" L=26, N=1 + .balign 4 + .word 0x19A @ "72" L=26, N=1.5 + + .balign 4 + .word 0x11B @ "73" L=27, N=1 + + .balign 4 + .word 0x11C @ "74" L=28, N=1 + + .balign 4 + .word 0x11D @ "75" L=29, N=1 + + .balign 4 + .word 0x11E @ "76" L=30, N=1 + + .balign 4 + .word 0x11F @ "77" L=31, N=1 + + .balign 4 + .word 0X30E @ "78" L=14, N=3 for 546 MHz Turbo Mode + + .balign 4 + .word 0X30F @ "79" L=15, N=3 for 585 MHz Turbo Mode + + .balign 4 + .word 0X310 @ "7A" L=16, N=3 for 624 MHz Turbo Mode + + .balign 4 + .word 0x11F @ "7B" L=31, N=1 (same values as "77") + .balign 4 + .word 0x11F @ "7C" L=31, N=1 (same values as "77") + .balign 4 + .word 0x11F @ "7D" L=31, N=1 (same values as "77") + .balign 4 + .word 0x11F @ "7E" L=31, N=1 (same values as "77") + .balign 4 + .word 0x11F @ "7F" L=31, N=1 (same values as "77") +@ +@ For the A bit = 1 +@ This table would be exactly the same as the above, only with the 'A' bit set, +@ so don't bother reproducting it. +@ + + +@******************************************************************************************** +@ +@ ********************************************************** +@ ********** ********** +@ ********** GET SYSTEM CLOCKS FREQUENCY SETTINGS ********** +@ ********** ( C Program callable version) ********** +@ ********************************************************** +@ +@ This subroutine returns all the data required to decode +@ the frequencies of the system busses. +@ +@ R4 returns the following: +@ +@ bits 4:0 = CCSR value of the L bits +@ bits 8:5 = CCSR value of the N bits +@ bit 9 = CLKCFG value for the TURBO bit +@ bit 10 = CLKCFG value for the B (Fast Bus) bit +@ bit 11 = CCSR value for the A bit +@ bit 12 = MDREFR value of K1DB2 bit +@ bit 13 = MDREFR value of K0DB4 bit +@ bit 14 = MDREFR value of K0DB2 bit +@ bit 15 = CLKCFG value of HT bit +@ bit 16 = PPDIS_S bit in the CCSR register +@ bit 17 = CPDIS_S bit in the CCSR register +@ + +xlli_getFreq: + + stmfd sp!, {r1, r2, lr} @ Save r1, r2 and link register on the stack + + ldr r1, =xlli_CLKREGS_PHYSICAL_BASE @ Address base for clock config registers + ldr r0, [r1, #xlli_CCSR_offset] @ Read the contents of CCSR into r0 + mov r1, r0 @ and copy into r1 + and r0, r0, #0x1F @ Leave just the L bits in r0 + and r2, r1, #0x780 @ Leave just the N bits in r2 + mov r2, r2, LSR #2 @ Shift N bits right by 2 bits + orr r0, r0, r2 @ and load into r0 + ands r2, r1, #xlli_BIT_30 @ Is the PPDIS_S bit set? + orrne r0, r0, #xlli_BIT_16 @ Yes - set bit 16 in R0 + ands r2, r1, #xlli_BIT_31 @ Is the CPDIS_S bit set? + orrne r0, r0, #xlli_BIT_17 @ Yes - set bit 17 in R0 + + mrc p14, 0, r2, c6, c0, 0 @ Get data in CP14, Register 6 + ands r1, r2, #xlli_BIT_0 @ Is the turbo bit set? + orrne r0, r0, #xlli_BIT_9 @ Yes - set bit 9 in r0 + ands r1, r2, #xlli_BIT_3 @ Is the B bit set? + orrne r0, r0, #xlli_BIT_10 @ Yes - set bit 10 in r0 + ands r1, r2, #xlli_BIT_2 @ is the HT bit set? + orrne r0, r0, #xlli_BIT_15 @ Yes - set bit 15 in r0 + + ldr r1, =xlli_CLKREGS_PHYSICAL_BASE @ Address base for clock config registers + ldr r2, [r1, #xlli_CCCR_offset] @ Read the contents of CCCR into r2 + ands r1, r2, #0x2000000 @ Is the A bit set? + orrne r0, r0, #xlli_BIT_11 @ Yes - set bit 11 in r0 + + ldr r1, =xlli_MEMORY_CONFIG_BASE @ Get base address of memory registers + ldr r2, [r1, #xlli_MDREFR_offset] @ Get contents of MDREFR register + ands r1, r2, #xlli_MDREFR_K1DB2 @ Is the K1DB2 bit set? + orrne r0, r0, #xlli_BIT_12 @ Yes - set bit 12 in r0 + ands r1, r2, #xlli_MDREFR_K0DB4 @ Is the K0DB4 bit set? + orrne r0, r0, #xlli_BIT_13 @ Yes - set bit 13 in r0 + ands r1, r2, #xlli_MDREFR_K0DB2 @ Is the K0DB2 bit set? + orrne r0, r0, #xlli_BIT_14 @ Yes - set bit 14 in r0 + + ldmfd sp!, {r1, r2, pc} @ Restore r1, r2 and return to caller + + + +@******************************************************************************************** +@ +@ ****************************************************** +@ ********** ********** +@ ********** SET SDRAM MEMORY BUFFER STRENGTH ********** +@ ********** ( C Program callable version) ********** +@ ****************************************************** +@ +@ This subroutine is a "C" callable function that adjusts the buffer drive impedance for SDRAM +@ +@ REQUIRED PARAMETER: +@ +@ r0 = buffer strength (Range of 0x0 to 0xF) +@ +@ Default value is 0x5 on system boot. A higher value results in a lower +@ buffer impedance. This subroutine only changes buffer impedance that +@ affect SDRAM. See Developer's Manual (Memory Controller) for more details. +@ + +xlli_setBufImpedance: + + stmfd sp!, {r1, r2, lr} @ Save r1, r2 and link register on the stack + ldr r1, =xlli_MEMORY_CONFIG_BASE @ Get memory controller base address +@ +@ Duplicate the value in lowest nibble so it is duplicated in all 8 nibbels +@ + and r0, r0, #0xF @ Isolate bits 3:0 of parameter + mov r2, r0, LSL #4 @ Shift 4 bits to the left + orr r0, r0, r2 @ Copy in next significant nibble + mov r2, r2, LSL #4 @ Shift 4 bits to the left + orr r0, r0, r2 @ Copy in next significant nibble + mov r2, r2, LSL #4 @ Shift 4 bits to the left + orr r0, r0, r2 @ Copy in next significant nibble + mov r2, r2, LSL #4 @ Shift 4 bits to the left + orr r0, r0, r2 @ Copy in next significant nibble + mov r2, r2, LSL #4 @ Shift 4 bits to the left + orr r0, r0, r2 @ Copy in next significant nibble + mov r2, r2, LSL #4 @ Shift 4 bits to the left + orr r0, r0, r2 @ Copy in next significant nibble + mov r2, r2, LSL #4 @ Shift 4 bits to the left + orr r0, r0, r2 @ Copy in next significant nibble +@ +@ The 8 nibbles in r0 are now all the same value +@ + str r0, [r1, #xlli_BSCNTR3_offset] @ Set buffer strength for address lines + str r0, [r1, #xlli_BSCNTR0_offset] @ Set buffer strength for SDCLK + ldr r2, [r1, #xlli_BSCNTR1_offset] @ Get buffer strength for BSCNTR1 + and r2, r2, #0xF0 @ Preserve bits 7:4 in r2 + bic r0, r0, #0xF0 @ Clear bits 7:4 in r0 + orr r2, r0, r2 @ OR with the value from BSCNTR1 + str r2, [r1, #xlli_BSCNTR1_offset] @ Write buffer strength to BSCNTR1 + str r0, [r1, #xlli_BSCNTR2_offset] @ Write buffer strength to BSCNTR2 +@ +@ Read back from APB to ensure our writes have completed before continuing +@ + ldr r0, [r1, #xlli_BSCNTR2_offset] + + + ldmfd sp!, {r1, r2, pc} @ Restore r1, r2 and return to caller + + +@******************************************************************************************** +@ +@ ****************************************************** +@ ********** ********** +@ ********** SET SDRAM MEMORY BUFFER STRENGTH ********** +@ ********** (ROM based version) ********** +@ ****************************************************** +@ +@ This subroutine adjusts the buffer drive impedance for SDRAM +@ +@ REQUIRED PARAMETER: +@ +@ r3 = buffer strength (Range of 0x0 to 0xF) +@ +@ Default value is 0x5 on system boot. A higher value results in a lower +@ buffer impedance. This subroutine only changes buffer impedance that +@ affect SDRAM. See Developer's Manual (Memory Controller) for more details. +@ + +xlli_setBufImp: + + ldr r1, =xlli_MEMORY_CONFIG_BASE @ Get memory controller base address +@ +@ Duplicate the value in lowest nibble so it is duplicated in all 8 nibbels +@ + and r3, r3, #0xF @ Isolate bits 3:0 of parameter + mov r2, r3 @ Copy into r2 + mov r2, r2, LSL #4 @ Shift 4 bits to the left + orr r2, r3, r2 @ Copy in next significant nibble + mov r2, r2, LSL #4 @ Shift 4 bits to the left + orr r2, r3, r2 @ Copy in next significant nibble + mov r2, r2, LSL #4 @ Shift 4 bits to the left + orr r2, r3, r2 @ Copy in next significant nibble + mov r2, r2, LSL #4 @ Shift 4 bits to the left + orr r2, r3, r2 @ Copy in next significant nibble + mov r2, r2, LSL #4 @ Shift 4 bits to the left + orr r2, r3, r2 @ Copy in next significant nibble + mov r2, r2, LSL #4 @ Shift 4 bits to the left + orr r2, r3, r2 @ Copy in next significant nibble + mov r2, r2, LSL #4 @ Shift 4 bits to the left + orr r2, r3, r2 @ Copy in next significant nibble +@ +@ The 8 nibbles in r2 are now all the same value +@ + str r2, [r1, #xlli_BSCNTR3_offset] @ Set buffer strength for address lines + str r2, [r1, #xlli_BSCNTR0_offset] @ Set buffer strength for SDCLK + ldr r3, [r1, #xlli_BSCNTR1_offset] @ Get buffer strength for BSCNTR1 + and r3, r3, #0xF0 @ Preserve bits 7:4 in r3 + bic r2, r2, #0xF0 @ Clear bits 7:4 in r2 + orr r3, r3, r2 @ OR with the value from BSCNTR1 + str r3, [r1, #xlli_BSCNTR1_offset] @ Write buffer strength to BSCNTR1 + str r2, [r1, #xlli_BSCNTR2_offset] @ Write buffer strength to BSCNTR2 +@ +@ Read back from APB to ensure our writes have completed before continuing +@ + ldr r0, [r1, #xlli_BSCNTR2_offset] + + mov pc, lr @ Return to calling routine + + + +@******************************************************************************* +@ +@ ************************************************* +@ ********** ********** +@ ********** RETURN THE MEMORY BUS WIDTH ********** +@ ********** ********** +@ ************************************************* +@ +@ This subroutine reads the Bootsel pin and returns if the Bus Width is 16 or 32 bits in width +@ +@ REQUIRED PARAMETERS: +@ +@ NONE +@ +@ REGISTERS USED +@ +@ R1 & R2 - none are preserved +@ +@ RETURN REGISTER +@ +@ R1 - returned the following (in keeping with the dev. manual, section 6.5.4): +@ 0 - Bus is in a 32-bit configuration +@ 1 - Bus is in a 16-bit configuration +@ +xlli_isMemBusWidth16Bit: + + ldr r1, =xlli_MEMORY_CONFIG_BASE @ Clock registers base address + ldr r2, [r1, #xlli_BOOT_DEF_offset] @ Get present value of the Boot_Sel register + and r1, r2, #0x1 @ We only care about the lowest bit, so hack off all others + + mov pc, lr @ Return to calling routine + + + + +@******************************************************************************************** +@ +@ *************************************************** +@ ********** ********** +@ ********** READ FLASH MEMORY ID FROM CFI ********** +@ ********** ********** +@ *************************************************** +@ +@ This subroutine reads the Intel StrataFlash(R) FLASH memory's CFI to retrieve the Flash ID +@ +@ REQUIRED PARAMETERS: +@ +@ NONE +@ +@ REGISTERS USED +@ +@ R1, R2, R3, R4, R5, R6, R7 - none are preserved +@ +@ RETURN REGISTER +@ R1 - returned containing the 'Flash ID' +@ +@ Notes: +@ Types of flash that XLLI can discover include: +@ +@ TYPE CODE RANGE +@ ---- ---------------- +@ J3 = 0x16 -> 0x18 +@ K3 = 0x8801 -> 0x8803 +@ K18 = 0x8805 -> 0x8807 +@ L18 = 0x880E -> 0x8810 +@ L3 = 0x8812 -> 0x8815 +@ + +xlli_queryFlash: + + mov r7, lr @ Save off the Link Register so we can return to the right caller + bl xlli_isMemBusWidth16Bit @ Find the bus width + mov r6, r1 @ Move the result up out of the way so we can re-use it further down +@ +@ Load up the registers with the flash commands +@ + ldr r4, =xlli_FLASH_READQUERY_CMD @ Set the flash into query mode command + ldr r5, =xlli_FLASH_READ_CMD @ Set the flash back into 'Read Array' mode command + + cmp r6, #0x1 @ Compare return value - 1 indicates that it's a 16-bit bus + beq xlli_Query_Invalidate @ If 16-bit, don't double up the registers, so jump to locked routines +@ +@ Bus is 32-bits wide, so need to 'double' up the commands +@ (Flash query command first) +@ + mov r4, r4, LSL #16 + orr r4, r4, #xlli_FLASH_READQUERY_CMD +@ +@ Flash Read array command next +@ + mov r5, r5, LSL #16 + orr r5, r5, #xlli_FLASH_READ_CMD @ Results in R3 = 0x00FF00FF + +xlli_Query_Invalidate: +@ +@ Time to setup the locking code +@ + cmp r6, #0x1 @ Compare return value - 1 indicates that it's a 16-bit bus + addeq r3, pc, #xlli_Query_16_Start-(.+8) @ Start of code to lock into the ICache (16-bit version) + addne r3, pc, #xlli_Query_32_Start-(.+8) @ Start of code to lock into the ICache (32-bit version) + mvn r1, #31 @ Time to ensure that we're 32-byte.baligned + and r3, r3, r1 + + addeq r2, pc, #xlli_Query_16_End-(.+8) @ End of code to lock into the ICache (16-bit version) + addne r2, pc, #xlli_Query_32_End-(.+8) @ End of code to lock into the ICache (32-bit version) + and r2, r2, r1 + + mrc p15, 0, r1, c1, c0, 0 @ read (0x78) cp15.1 + orr r1, r1, #0x1000 @ enable ICache + mcr p15, 0, r1, c1, c0, 0 @ write it + xlli_cpWait r1 @ Now stall to ensure the write occured + + mcr p15, 0, r1, c9, c1, 1 @ unlock entire i$ + mcr p15, 0, r1 ,c7, c5, 0 @ flush i$ and BTB + xlli_cpWait r1 + +xlli_Query_LockLoop: + mcr p15, 0, r3, c7, c5, 1 @ Invalidate i$ line (same as we are about to lock - CAN affect a locked line!) + mcr p15, 0, r3, c9, c1, 0 @ lock line into icache, based on r3 + cmp r3, r2 @ are we done? + add r3, r3, #32 @ increment to next cache-line + bne xlli_Query_LockLoop + cmp r6, #0x1 @ Compare return value - 1 indicates that it's a 16-bit bus + beq xlli_Query_16_Start @ Now jump to the Query code locked in the i-cache (16-bit version) + bne xlli_Query_32_Start @ Now jump to the Query code locked in the i-cache (32-bit version) + + .balign 32 @ ensure is cache-line.baligned (i.e. 32 Bytes = 2^5) +xlli_Query_16_Start: + + @ Read Device Identifier to obtain RCR value (a 2 cycle operation) + mov r3, #0x0 @ Boot Flash Base address + strh r4, [r3] @ Put the flash into Query Mode + + mov r3, #0x2 @ Read 2nd word: "Device Code" entry in Query Structure + ldrh r6, [r3] @ 2nd cycle; r8 now contains the device code on upper and lower halves of data bus. +@ +@ NOTE: DO NOT TOUCH R6 AFTER THIS POINT AS IT HAS THE RETURN VALUE! +@ + mov r3, #0x0 + strh r5, [r3] @ Put back into read array mode + ldrh r5, [r3] @ Create a data dependency stall to ensure the command was written + nop @ Flush the pipeline + nop + nop + nop + b xlli_Query_Cleanup @ Jump to the clean-up code + + .balign 32 @ padding +xlli_Query_16_End: nop + + .balign 32 @ ensure is cache-line.baligned (i.e. 32 Bytes = 2^5) +xlli_Query_32_Start: + + @ Read Device Identifier to obtain RCR value (a 2 cycle operation) + mov r3, #0x0 @ Boot Flash Base address + str r4, [r3] @ Put the flash into Query Mode + + mov r3, #0x4 @ Read 2nd word: "Device Code" entry in Query Structure + ldr r6, [r3] @ 2nd cycle; r8 now contains the device code on upper and lower halves of data bus. +@ +@ NOTE: DO NOT TOUCH R6 AFTER THIS POINT AS IT HAS THE RETURN VALUE! +@ + mov r3, #0x0 + str r5, [r3] @ Put back into read array mode + ldr r5, [r3] @ Create a data dependency stall to ensure the command was written + nop @ Flush the pipeline + nop + nop + nop + b xlli_Query_Cleanup @ Jump to the clean-up code + + .balign 32 @ padding +xlli_Query_32_End: nop +@ +@ Now clean-up from all the cache locking +@ + .balign 32 +xlli_Query_Cleanup: + + mcr p15, 0, r2, c9, c1, 1 @ Unlock entire i$ + mov r2, #0x78 + mcr p15, 0, r2, c1, c0, 0 @ Disable i$ now that we are done with it + xlli_cpWait r2 + + mcr p15, 0, r2, c7, c5, 0 @ Flush i$ and BTB + xlli_cpWait r2 + + mov r1, r6 @ Move the return value into R1 for the return + + mov pc, r7 @ Return to calling routine - remember the 1st instruction in this f'n was to move the LR -> R7 + + + + +@******************************************************************************************** +@ +@ ************************************************************ +@ ********** ********** +@ ********** SET FLASH MEMORY INTO SYNCHRONOUS MODE ********** +@ ********** ********** +@ ************************************************************ +@ +@ This subroutine sets Intel StrataFlash(R) FLASH memory into the synchronous mode of operation. +@ +@ REQUIRED PARAMETERS: +@ +@ NONE +@ +@ REGISTERS USED +@ +@ R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12 - none are preserved +@ +xlli_enableSyncFlash: +@ +@ Prepare to write instructions to Intel StrataFlash for synchronous mode +@ +@ The read Configurarion Register (RCR) in the flash memory defaults to 0xFFFF +@ on power up (async read). The following code reconfigures the flash for +@ synchronous burst reads as follows: +@ +@ RCR[15] = 0b0 (Synchronous Burst Mode) +@ RCR[14] = 0b0 (reserved) +@ RCR[13:11] = 0b1000 (Latency Count = Code 4) +@ RCR[10] = 0b1 (Wait Polarity - not used) +@ RCR[9] = 0b0 (hold data for one clock) +@ RCR[8] = 0b1 (Wait delay = 1 - not used) +@ RCR[7] = 0b1 (linear burst sequence) +@ RCR[6] = 0b1 (Rising clock edge) +@ RCR[5:4] = 0b00 (reserved) +@ RCR[3] = 0b0 (Wrap - access wrap within selected burst length) +@ RCR[2:0] = 0b010 (Burst Length = 8 words) +@ +@ Note: K0RUN is enabled in the xlli_mem_init function + + mov r12, lr @ Save off the Link Register so we can return to the right caller + bl xlli_isMemBusWidth16Bit @ Find the bus width + mov r11, r1 @ move the result up out of the way so we can re-use it further down + @ R8 and higher are not touched in the following functin (this would be a good thing) + bl xlli_queryFlash @ R1 has the Flash ID - returned from xlli_queryFlash + + ldr r2, =0xffff + and r1, r1, r2 @ We only care about the lowest device, as they must be the same + ldr r2, =xlli_J3_FlashID_Code + cmp r1, r2 @ Is this J3 flash + ble xlli_enableSync_Done @ No can do sync. flash on J3 so skip this routine + + @ Now load up all the regsiters with their appropriate values + + cmp r11, #0x1 @ Compare return value - 1 indicates that it's a 16-bit bus + ldreq r2, =xlli_FLASH_RCR16_value @ Value to set into flash RCR register for 16-bit + ldrne r2, =xlli_FLASH_RCR32_value @ Value to set into flash RCR register for 32-bit + ldr r7, =xlli_SXCNFG_sync_value @ SXCNFG value + + ldr r1, =xlli_MEMORY_CONFIG_BASE @ Memory config register base + mov r3, #xlli_FLASH_WRITE_CMD @ Write to flash instruction + mov r4, #xlli_FLASH_WCONF_CMD @ Write to flash confirm instruction + mov r5, #xlli_FLASH_READ_CMD @ Load "read array" mode command + mov r6, #0x0 @ Boot Flash Base address + + @ Now one last check if we're 16 or 32-bit & jump to the appropriate code + cmp r11, #0x1 @ Compare return value - 1 indicates that it's a 16-bit bus + beq xlli_enableSync_Invalidate @ if we're 16-bit, gotta skip over the block of 32-bit code + + @ We're 32-bit, so need to 'double' up the commands + + @ Flash Write command first + mov r3, r3, LSL #16 + orr r3, r3, #xlli_FLASH_WRITE_CMD @ Results in R3 = 0x00600060 + + @ Flash WConf command next + mov r4, r4, LSL #16 + orr r4, r4, #xlli_FLASH_WCONF_CMD @ Results in R3 = 0x00030003 + + @ Flash Read Array command + mov r5, r5, LSL #16 + orr r5, r5, #xlli_FLASH_READ_CMD @ Results in R3 = 0x00FF00FF + + @ At this point, R1-7 are USED, so DO NOT TOUCH. R8 can be reused, R9 & 10 are free also, R12 contains the proper Link return value + +xlli_enableSync_Invalidate: + @ Time to setup the locking code + cmp r11, #0x1 @ Compare return value - 1 indicates that it's a 16-bit bus + addeq r10, pc, #xlli_enableSync_16_Start-(.+8) + addne r10, pc, #xlli_enableSync_32_Start-(.+8) + mvn r8, #31 @ Time to ensure that we're 32-byte.baligned + and r10, r10, r8 + + addeq r9, pc, #xlli_enableSync_16_End-(.+8) + addne r9, pc, #xlli_enableSync_32_End-(.+8) + and r9, r9, r8 + + mrc p15, 0, r8, c1, c0, 0 @ read (0x78) cp15.1 + orr r8, r8, #0x1000 @ enable ICache + mcr p15, 0, r8, c1, c0, 0 @ write it + xlli_cpWait r8 @ Now stall to ensure the write occured + + mcr p15, 0, r8, c9, c1, 1 @ unlock entire i$ + mcr p15, 0, r8, c7, c5, 0 @ flush i$ and BTB + xlli_cpWait r8 + +xlli_enableSync_LockLoop: + mcr p15, 0, r10, c7, c5, 1 @ Invalidate i$ line (same as we are about to lock - CAN affect a locked line!) + mcr p15, 0, r10, c9, c1, 0 @ lock line into icache, based on r3 + cmp r10, r9 @ are we done? + add r10, r10, #32 @ increment to next cache-line + bne xlli_enableSync_LockLoop + + cmp r11, #0x1 @ Compare return value - 1 indicates that it's a 16-bit bus + beq xlli_enableSync_16_Start + bne xlli_enableSync_32_Start @ Now jump to the code locked in the i-cache + + + .balign 32 @ ensure is cache-line.baligned (i.e. 32 Bytes = 2^5) +xlli_enableSync_16_Start: + + @ Now program everything into the Flash and SXCNFG registers + str r7, [r1, #xlli_SXCNFG_offset] @ Update PXA27x SXCNFG register + strh r3, [r2] @ Yes, the data is on the address bus! + strh r4, [r2] @ Confirm the write to the RCR + strh r5, [r6] @ Place flash back in read mode + ldrh r5, [r6] @ Create a data dependency stall to ensure the command was written + nop @ Flush the pipeline + nop + nop + nop + b xlli_enableSync_Cleanup @ Now jump to the clean-up code + + .balign 32 @ padding +xlli_enableSync_16_End: nop + + .balign 32 @ ensure is cache-line.baligned (i.e. 32 Bytes = 2^5) +xlli_enableSync_32_Start: + + @ Now program everything into the Flash and SXCNFG registers + str r7, [r1, #xlli_SXCNFG_offset] @ Update PXA27x SXCNFG register + str r3, [r2] @ Yes, the data is on the address bus! + str r4, [r2] @ Confirm the write to the RCR + str r5, [r6] @ Place flash back in read mode + ldr r5, [r6] @ Create a data dependency stall to ensure the command was written + nop @ Flush the pipeline + nop + nop + nop + b xlli_enableSync_Cleanup @ Now jump to the clean-up code + + .balign 32 @ padding +xlli_enableSync_32_End: nop + + @ Now clean-up from all the cache locking + + .balign 32 +xlli_enableSync_Cleanup: + + mcr p15, 0, r1, c9, c1, 1 @ unlock entire i$ + mov r1, #0x78 + mcr p15, 0, r1, c1, c0, 0 @ disable i$ now that we are done with it + xlli_cpWait r1 @ Stall the pipeline + + mcr p15, 0, r1 ,c7, c5, 0 @ flush i$ and BTB + xlli_cpWait r1 + +xlli_enableSync_Done: + @ Return to caller + mov pc, r12 @ Return to calling routine - recall we moved LR->R9 as first instruction + + + +@******************************************************************************************** +@ +@ ************************************************************** +@ ********** ********** +@ ********** DISABLES FLASH MEMORY'S SYNCHRONOUS MODE ********** +@ ********** ********** +@ ************************************************************** +@ +@ This subroutine sets Intel StrataFlash(R) FLASH memory into the asynchronous mode of operation. +@ +@ ********** THIS IS AN INITAL RELEASE OF THE CODE - SUBJECT TO CHANGE!! ********** +@ +@ REQUIRED PARAMETERS: +@ +@ NONE +@ +@ REGISTERS USED +@ +@ R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12 - none are preserved +@ +xlli_disableSyncFlash: + + mov r12, lr @ Save off the Link Register so we can return to the right caller + bl xlli_isMemBusWidth16Bit @ Find the bus width + mov r11, r1 @ move the result up out of the way so we can re-use it further down + @ R8 and higher are not touched in the following functin (this would be a good thing) + bl xlli_queryFlash @ R1 has the Flash ID - returned from xlli_queryFlash + + ldr r2, =0xffff + and r1, r1, r2 @ We only care about the lowest device, as they must be the same + ldr r2, =xlli_J3_FlashID_Code + cmp r1, r2 @ Is this J3 flash + ble xlli_disableSync_Done @ No can do sync. flash on J3 so skip this routine + + @ Now load up all the regsiters with their appropriate values + cmp r11, #0x1 @ Compare return value - 1 indicates that it's a 16-bit bus + ldreq r2, =xlli_FLASH_ASYNC_RCR16_value @ Value to set into flash RCR register for 16-bit + ldrne r2, =xlli_FLASH_ASYNC_RCR32_value @ Value to set into flash RCR register for 32-bit + ldr r7, =xlli_SXCNFG_async_value @ SXCNFG value + + ldr r1, =xlli_MEMORY_CONFIG_BASE @ Memory config register base + mov r3, #xlli_FLASH_WRITE_CMD @ Write to flash instruction + mov r4, #xlli_FLASH_WCONF_CMD @ Write to flash confirm instruction + mov r5, #xlli_FLASH_READ_CMD @ Load "read array" mode command + mov r6, #0x0 @ Boot Flash Base address + + @ Now one last check if we're 16 or 32-bit & jump to the appropriate code + cmp r11, #0x1 @ Compare return value - 1 indicates that it's a 16-bit bus + beq xlli_disableSync_Invalidate @ if we're 16-bit, gotta skip over the block of 32-bit code + + @ We're 32-bit, so need to 'double' up the commands + + @ Flash Write command first + mov r3, r3, LSL #16 + orr r3, r3, #xlli_FLASH_WRITE_CMD @ Results in R3 = 0x00600060 + + @ Flash WConf command next + mov r4, r4, LSL #16 + orr r4, r4, #xlli_FLASH_WCONF_CMD @ Results in R3 = 0x00030003 + + @ Flash Read Array command + mov r5, r5, LSL #16 + orr r5, r5, #xlli_FLASH_READ_CMD @ Results in R3 = 0x00FF00FF + + @ At this point, R1-7 are USED, so DO NOT TOUCH. R8 can be reused, R9 & 10 are free also, R12 contains the proper Link return value + +xlli_disableSync_Invalidate: + @ Time to setup the locking code + cmp r11, #0x1 @ Compare return value - 1 indicates that it's a 16-bit bus + addeq r10, pc, #xlli_disableSync_16_Start-(.+8) + addne r10, pc, #xlli_disableSync_32_Start-(.+8) + mvn r8, #31 @ Time to ensure that we're 32-byte.baligned + and r10, r10, r8 + + addeq r9, pc, #xlli_disableSync_16_End-(.+8) + addne r9, pc, #xlli_disableSync_32_End-(.+8) + and r9, r9, r8 + + mrc p15, 0, r8, c1, c0, 0 @ read (0x78) cp15.1 + orr r8, r8, #0x1000 @ enable ICache + mcr p15, 0, r8, c1, c0, 0 @ write it + xlli_cpWait r8 @ Now stall to ensure the write occured + + mcr p15, 0, r8, c9, c1, 1 @ unlock entire i$ + mcr p15, 0, r8, c7, c5, 0 @ flush i$ and BTB + xlli_cpWait r8 + +xlli_disableSync_LockLoop: + mcr p15, 0, r10, c7, c5, 1 @ Invalidate i$ line (same as we are about to lock - CAN affect a locked line!) + mcr p15, 0, r10, c9, c1, 0 @ lock line into icache, based on r3 + cmp r10, r9 @ are we done? + add r10, r10, #32 @ increment to next cache-line + bne xlli_disableSync_LockLoop + cmp r11, #0x1 @ Compare return value - 1 indicates that it's a 16-bit bus + beq xlli_disableSync_16_Start @ Now jump to the code locked in the i-cache + bne xlli_disableSync_32_Start @ Now jump to the code locked in the i-cache + + + .balign 32 @ ensure is cache-line.baligned (i.e. 32 Bytes = 2^5) +xlli_disableSync_16_Start: + + @ Now program everything into the Flash and SXCNFG registers + str r7, [r1, #xlli_SXCNFG_offset] @ Update PXA27x SXCNFG register + strh r3, [r2] @ Yes, the data is on the address bus! + strh r4, [r2] @ Confirm the write to the RCR + strh r5, [r6] @ Place flash back in read mode + ldrh r5, [r6] @ Create a data dependency stall to ensure the command was written + nop @ Flush the pipeline + nop + nop + nop + b xlli_disableSync_Cleanup @ Now jump to the clean-up code + + .balign 32 @ padding +xlli_disableSync_16_End: nop + + + .balign 32 @ ensure is cache-line.baligned (i.e. 32 Bytes = 2^5) +xlli_disableSync_32_Start: + + @ Now program everything into the Flash and SXCNFG registers + str r7, [r1, #xlli_SXCNFG_offset] @ Update PXA27x SXCNFG register + str r3, [r2] @ Yes, the data is on the address bus! + str r4, [r2] @ Confirm the write to the RCR + str r5, [r6] @ Place flash back in read mode + ldr r5, [r6] @ Create a data dependency stall to ensure the command was written + nop @ Flush the pipeline + nop + nop + nop + b xlli_disableSync_Cleanup @ Now jump to the clean-up code + + .balign 32 @ padding +xlli_disableSync_32_End: nop + + @ Now clean-up from all the cache locking + + .balign 32 +xlli_disableSync_Cleanup: + + mcr p15, 0, r1, c9, c1, 1 @ unlock entire i$ + mov r1, #0x78 + mcr p15, 0, r1, c1, c0, 0 @ disable i$ now that we are done with it + xlli_cpWait r1 @ Stall the pipeline + + mcr p15, 0, r1 ,c7, c5, 0 @ flush i$ and BTB + xlli_cpWait r1 + +xlli_disableSync_Done: + @ Return to caller + mov pc, r12 @ Return to calling routine - recall we moved LR->R9 as first instruction + + + +@******************************************************************************************** +@******************************************************************************************** + + + + diff -Nur blob-xscale/src/blob/xlli/glencoe/xlli_LowLev_mac.mac blob-2.0.5-pre3-glencoe05/src/blob/xlli/glencoe/xlli_LowLev_mac.mac --- blob-xscale/src/blob/xlli/glencoe/xlli_LowLev_mac.mac 1969-12-31 19:00:00.000000000 -0500 +++ blob-2.0.5-pre3-glencoe05/src/blob/xlli/glencoe/xlli_LowLev_mac.mac 2005-02-19 21:44:50.000000000 -0500 @@ -0,0 +1,179 @@ +@********************************************************************************* +@ +@ Copyright (C) 2004, Intel Corporation +@ +@ This software program is licensed subject to the GNU General Public License +@ (GPL).Version 2,June 1991, available at http://www.fsf.org/copyleft/gpl.html +@ +@********************************************************************************* +@ +@ xlli_LowLev_mac.mac +@ MainStone/Glencoe Platform Low Level Macros +@ +@ Copyright (c) 2002 by Intel Corp. Hudson MA +@ +@ List of macros in this file: +@ +@ +@ xlli_mapSECTIONS (Macro) Generates page table entries for MMU +@ +@********************************************************************************* + + + + +@********************************************************************************* +@ This macro will map a region using 1MB sections +@ Notes: +@ 1)You must call xlli_initPageTable before this macro is valid. +@ 2) This version of the macro is used when NAMED values are passed to the macro + + .macro xlli_mapSECTIONS w1,w2,w3,w4,size,virtual,physical,access,Level1tab + +@ $size = size of region to be mapped +@ $virtual = starting virtual address of region +@ $physical = starting physical address of region +@ $access = access bits for this region +@ $tabl = physical (base) address of page tables +@ $Level1tab = offset from page table base to level 1 entries + + @ get the page table base address from cp15 + + mrc p15, 0, \w4, c2, c0, 0 + mov \w4, \w4, LSR #14 @ Clear the low order 14 bits because cp15... + mov \w4, \w4, LSL #14 @ ...read of these bits are unpredictable + + ldr \w3, =\size @ get size of bank + cmp \w3, #0 + beq 2 @ if size=0, skip + + ldr \w2, =\Level1tab + (\virtual:SHR:(20-2)) @ generate table index + + add \w2, \w2, \w4 @ offset into page table + mov \w3, \w3, LSR #20 @ no. of 1MB segments + + ldr \w1, =(\physical + \access) @ create table entry +1: + str \w1, [\w2], #4 @ store table entry and increment + add \w1, \w1, #xlli_MemSize_1Mb @ add section number field + subs \w3, \w3, #1 @ decrement loop count + bne 1 +2: + + .endm +@********************************************************************************* +@ +@ ************************************************** +@ ********** ********** +@ ********** xlli_mapSECTIONS_Var ********** +@ ********** ********** +@ ************************************************** +@ +@ This macro will map a region using 1MB sections +@ Notes: +@ 1)You must call xlli_initPageTable before this macro is valid. +@ 2) This version of the macro is used when REGISTER values are passed to the macro + + .macro xlli_mapSECTIONS_Var w1,w2,w3,w4,size,virtual,physical,access,Level1tab + +@ $size = size of region to be mapped +@ $virtual = starting virtual address of region +@ $physical = starting physical address of region +@ $access = access bits for this region +@ $tabl = physical (base) address of page tables +@ $Level1tab = offset from page table base to level 1 entries + + @ get the page table base address from cp15 + + mrc p15, 0, \w4, c2, c0, 0 + mov \w4, \w4, LSR #14 @ Clear the low order 14 bits because cp15... + mov \w4, \w4, LSL #14 @ ...read of these bits are unpredictable + + mov \w3, \size @ get size of bank + cmp \w3, #0 + beq 2 @ if size=0, skip + + mov \w2, \virtual, LSR #(20-2) + add \w2, \w2, #\Level1tab @ generate table index + + add \w2, \w2, \w4 @ offset into page table + mov \w3, \w3, LSR #20 @ no. of 1MB segments + + add \w1, \physical, \access @ create table entry +1: + str \w1, [\w2], #4 @ store table entry and increment + add \w1, \w1, #xlli_MemSize_1Mb @ add section number field + subs \w3, \w3, #1 @ decrement loop count + bne 1 +2: + + .endm +@********************************************************************************* +@ +@ ************************************************** +@ ********** ********** +@ ********** xlli_cpWait ********** +@ ********** ********** +@ ************************************************** +@ +@ This macro will arbitrarily read CP15 to create a stall in the pipeline. +@ +@ Notes: +@ $Rd = temporary register to use +@ + .macro xlli_cpWait Rd + + MRC P15, 0, \Rd, C2, C0, 0 @ arbitrary read of CP15 + MOV \Rd, \Rd @ wait for it (foward dependency) + SUB PC, PC, #4 @ branch to next instruction + + .endm + +@********************************************************************************* +@ +@ ************************************************** +@ ********** ********** +@ ********** xlli_retCCSR_L_Val ********** +@ ********** ********** +@ ************************************************** +@ +@ This macro will read the CCSR's L value and return it in the designated register +@ +@ Notes: +@ $Base should contain the base address of the CCSR (virtual or phy) +@ + .macro xlli_retCCSR_L_Val retval,Base,gp1 + + @ read CCCR's value + ldr \retval, [\Base, #xlli_CCSR_offset] + + @ mask out irrelevant bits + ldr \gp1, =0x1F + and \retval, \retval, \gp1 + + .endm + +@********************************************************************************* +@ +@ ************************************************** +@ ********** ********** +@ ********** xlli_retCCSR_2N_Val ********** +@ ********** ********** +@ ************************************************** +@ +@ This macro will read the CCSR and return the 2N value in $retval +@ +@ Notes: +@ $Base should contain the base address of the CCSR (virtual or phy) +@ + .macro xlli_retCCSR_2N_Val retval,Base,gp1 + + @ read CCCR's value + ldr \retval, [\Base, #xlli_CCSR_offset] + + @ mask out irrelevant bits + ldr \gp1, =0x780 + and \retval, \retval, \gp1 + mov \retval, \retval LSR #7 + + .endm diff -Nur blob-xscale/src/blob/xlli/mainstone/start.s blob-2.0.5-pre3-glencoe05/src/blob/xlli/mainstone/start.s --- blob-xscale/src/blob/xlli/mainstone/start.s 2005-04-29 21:00:03.000000000 -0400 +++ blob-2.0.5-pre3-glencoe05/src/blob/xlli/mainstone/start.s 2005-04-29 21:16:20.000000000 -0400 @@ -65,6 +65,10 @@ /* Hardware/Power On reset */ tst r10, #xlli_RCSR_HWR bne 1f + + /* Watchdog/software reset */ + tst r10, #xlli_RCSR_WDR + bne 1f /* Sleep or Deep sleep Mode Reset */ tst r10, #xlli_RCSR_SMR diff -Nur blob-xscale/src/commands/download.c blob-2.0.5-pre3-glencoe05/src/commands/download.c --- blob-xscale/src/commands/download.c 2005-04-29 21:00:01.000000000 -0400 +++ blob-2.0.5-pre3-glencoe05/src/commands/download.c 2005-02-19 00:18:03.000000000 -0500 @@ -91,6 +91,7 @@ /* something went wrong */ retval = *numRead; + printf ("download.c: Something went wrong. *numRead = %d\n", *numRead); /* reload the correct memory */ do_reload(argv[1]); @@ -117,7 +118,7 @@ return 0; } -static char download_help[] = "download {blob|param|kernel|ramdisk}\n" +char download_help[] = "download {blob|param|kernel|ramdisk}\n" "Download image to RAM using uuencode\n"; diff -Nur blob-xscale/src/diag/glencoe.c blob-2.0.5-pre3-glencoe05/src/diag/glencoe.c --- blob-xscale/src/diag/glencoe.c 1969-12-31 19:00:00.000000000 -0500 +++ blob-2.0.5-pre3-glencoe05/src/diag/glencoe.c 2005-02-19 00:19:22.000000000 -0500 @@ -0,0 +1,40 @@ +/* + * glencoe.c: Glencoe specific stuff + * + * Copyright (C) 2002 Intel Corporation (yu.tang@intel.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 + * + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + + + + +static void glencoe_init_hardware(void) +{ + /* select serial driver */ + serial_driver = &pxa_serial_driver; + timer_driver = &intelarm_timer_driver; +} + +__initlist(glencoe_init_hardware, INIT_LEVEL_DRIVER_SELECTION); diff -Nur blob-xscale/src/lib/download.c blob-2.0.5-pre3-glencoe05/src/lib/download.c --- blob-xscale/src/lib/download.c 2005-04-29 21:00:02.000000000 -0400 +++ blob-2.0.5-pre3-glencoe05/src/lib/download.c 2005-02-19 02:28:50.000000000 -0500 @@ -50,7 +50,7 @@ void PrintSerialSpeed(serial_baud_t speed) { if (speed >= baud_COUNT) printf("(unknown)"); - else printf("%d%i", speed, baud_rates[speed]); + else printf("%d (%i)", speed, baud_rates[speed]); } diff -Nur blob-xscale/src/lib/reboot-pxa.c blob-2.0.5-pre3-glencoe05/src/lib/reboot-pxa.c --- blob-xscale/src/lib/reboot-pxa.c 2005-04-29 21:00:02.000000000 -0400 +++ blob-2.0.5-pre3-glencoe05/src/lib/reboot-pxa.c 2005-04-01 18:30:29.000000000 -0500 @@ -31,14 +31,15 @@ #include #include - +#include +#include void pxa_reboot(void) { -#warning "FIXME: add real PXA reboot code here! -- Erik" - printf("FIXME: add PXA-250 reboot code here!\n"); - printf("Going into endless loop, just use your reset button...\n"); + OWER = 0x1; + OSMR3 = (OSCR + 368640); /* ... in 100 ms */ + serial_flush_output(); for(;;); diff -Nur blob-xscale/src/lib/serial-pxa.c blob-2.0.5-pre3-glencoe05/src/lib/serial-pxa.c --- blob-xscale/src/lib/serial-pxa.c 2005-04-29 21:00:02.000000000 -0400 +++ blob-2.0.5-pre3-glencoe05/src/lib/serial-pxa.c 2005-02-19 12:22:57.000000000 -0500 @@ -127,6 +127,11 @@ CKEN |= CKEN7_BTUART; #endif +#ifdef USE_SERIAL3 + /* enable STUART clock */ + CKEN |= CKEN5_STUART; +#endif + /* get correct divisor */ switch(baud) { case baud_1200: diff -Nur blob-xscale/src/lib/serial_usb.c blob-2.0.5-pre3-glencoe05/src/lib/serial_usb.c --- blob-xscale/src/lib/serial_usb.c 2005-04-29 21:00:02.000000000 -0400 +++ blob-2.0.5-pre3-glencoe05/src/lib/serial_usb.c 2005-04-01 14:29:11.000000000 -0500 @@ -40,7 +40,7 @@ { #ifdef BLOB_DEBUG if(usb_serial_driver == NULL) { - printf("Serial over USB driver handle is NULL!\n") + printf("Serial over USB driver handle is NULL!\n"); return -ERANGE; } #endif diff -Nur blob-xscale/src/lib/tftp.c blob-2.0.5-pre3-glencoe05/src/lib/tftp.c --- blob-xscale/src/lib/tftp.c 2005-04-29 21:00:02.000000000 -0400 +++ blob-2.0.5-pre3-glencoe05/src/lib/tftp.c 2005-04-06 21:52:15.000000000 -0400 @@ -17,6 +17,8 @@ #include #include +#include + #undef TFTP_DEBUG #ifdef TFTP_DEBUG static int dbg = 1; @@ -141,6 +143,8 @@ printascii("TFTPing "); printascii(file); + + msleep(20000); finished = 0; do {