U-Boot
Threads by month
- ----- 2025 -----
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2000 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
March 2011
- 238 participants
- 485 discussions
From: Andreas Huber <andreas.huber(a)keymile.com>
This reads the DIP switch on mgcoge. The DIP switch is connected to
the BFTICU (0x40000089) FPGA. If the DIP switch is set the environment
variable 'actual_bank' is set to 0 and starts the SW in bank0.
Signed-off-by: Andreas Huber <andreas.huber(a)keymile.com>
Signed-off-by: Holger Brunck <holger.brunck(a)keymile.com>
---
board/keymile/mgcoge/mgcoge.c | 18 ++++++++++++++++++
include/configs/mgcoge.h | 5 +++++
2 files changed, 23 insertions(+), 0 deletions(-)
diff --git a/board/keymile/mgcoge/mgcoge.c b/board/keymile/mgcoge/mgcoge.c
index 5c9496c..5dcdf37 100644
--- a/board/keymile/mgcoge/mgcoge.c
+++ b/board/keymile/mgcoge/mgcoge.c
@@ -293,6 +293,24 @@ int checkboard(void)
return 0;
}
+#define DIPSWITCH_OFFSET 0x89
+#define DIPSWITCH_MASK 0x0f
+
+int last_stage_init(void)
+{
+ u8 dip_switch;
+ /* Dip switch */
+ dip_switch = readb(CONFIG_SYS_BFTICU_BASE + DIPSWITCH_OFFSET);
+ dip_switch &= DIPSWITCH_MASK;
+ /* dip switch 'full reset' or 'db erase' */
+ if (dip_switch & 0x1 || dip_switch & 0x2) {
+ /* start bootloader */
+ puts("DIP: Enabled\n");
+ setenv("actual_bank", "0");
+ }
+ return 0;
+}
+
/*
* Early board initalization.
*/
diff --git a/include/configs/mgcoge.h b/include/configs/mgcoge.h
index 6dec0ee..f1bd32a 100644
--- a/include/configs/mgcoge.h
+++ b/include/configs/mgcoge.h
@@ -348,4 +348,9 @@
#define OF_TBCLK (bd->bi_busfreq / 4)
#define OF_STDOUT_PATH "/soc/cpm/serial@11a90"
+/* enable last_stage_init */
+#define CONFIG_LAST_STAGE_INIT 1
+/* bfticu address */
+#define CONFIG_SYS_BFTICU_BASE 0x40000000
+
#endif /* __CONFIG_H */
--
1.7.0.5
2
9
This patch brings the VCMA9 port in sync with the latest U-Boot
version by doing the following:
- do the necessary adjustments to support the ARM relocation feature
- use the CFI flash driver (and removing the old one)
- various cleanups and coding style fixes
Signed-off-by: David Mueller <d.mueller(a)elsoft.ch>
diff --git a/board/mpl/vcma9/Makefile b/board/mpl/vcma9/Makefile
index 27cef1d..59c25f9 100644
--- a/board/mpl/vcma9/Makefile
+++ b/board/mpl/vcma9/Makefile
@@ -28,7 +28,7 @@ endif
LIB = $(obj)lib$(BOARD).o
-COBJS := vcma9.o flash.o cmd_vcma9.o
+COBJS := vcma9.o cmd_vcma9.o
COBJS += ../common/common_util.o
SOBJS := lowlevel_init.o
diff --git a/board/mpl/vcma9/cmd_vcma9.c b/board/mpl/vcma9/cmd_vcma9.c
index 0d5f46e..0f02b7e 100644
--- a/board/mpl/vcma9/cmd_vcma9.c
+++ b/board/mpl/vcma9/cmd_vcma9.c
@@ -43,7 +43,7 @@ static uchar cs8900_chksum(ushort data)
DECLARE_GLOBAL_DATA_PTR;
-extern void print_vcma9_info(void);
+extern void vcma9_print_info(void);
extern int vcma9_cantest(int);
extern int vcma9_nandtest(void);
extern int vcma9_nanderase(void);
@@ -60,7 +60,7 @@ int do_vcma9(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
char cs8900_name[10];
if (strcmp(argv[1], "info") == 0)
{
- print_vcma9_info();
+ vcma9_print_info();
return 0;
}
#if defined(CONFIG_CS8900)
diff --git a/board/mpl/vcma9/config.mk b/board/mpl/vcma9/config.mk
index e345913..fef5308 100644
--- a/board/mpl/vcma9/config.mk
+++ b/board/mpl/vcma9/config.mk
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2002, 2003
+# (C) Copyright 2002, 2003, 2010
# David Mueller, ELSOFT AG, <d.mueller(a)elsoft.ch>
#
# MPL VCMA9 board with S3C2410X (ARM920T) cpu
@@ -7,18 +7,10 @@
# see http://www.mpl.ch/ for more information about the MPL VCMA9
#
-#
-# MPL VCMA9 has 1 bank of minimal 16 MB DRAM
-# from 0x30000000
-#
# Linux-Kernel is expected to be at 3000'8000, entry 3000'8000
# optionally with a ramdisk at 3040'0000
#
-# we load ourself to 33F8'0000
+# NOR flash is mapped at address 0
#
-# download area is 3080'0000
-#
-
-#CONFIG_SYS_TEXT_BASE = 0x30F80000
-CONFIG_SYS_TEXT_BASE = 0x33F80000
+CONFIG_SYS_TEXT_BASE = 0x0
diff --git a/board/mpl/vcma9/flash.c b/board/mpl/vcma9/flash.c
deleted file mode 100644
index 7abf9cf..0000000
--- a/board/mpl/vcma9/flash.c
+++ /dev/null
@@ -1,432 +0,0 @@
-/*
- * (C) Copyright 2002
- * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
- * Alex Zuepke <azu(a)sysgo.de>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <common.h>
-
-ulong myflush (void);
-
-
-#define FLASH_BANK_SIZE PHYS_FLASH_SIZE
-#define MAIN_SECT_SIZE 0x10000 /* 64 KB */
-
-flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
-
-
-#define CMD_READ_ARRAY 0x000000F0
-#define CMD_UNLOCK1 0x000000AA
-#define CMD_UNLOCK2 0x00000055
-#define CMD_ERASE_SETUP 0x00000080
-#define CMD_ERASE_CONFIRM 0x00000030
-#define CMD_PROGRAM 0x000000A0
-#define CMD_UNLOCK_BYPASS 0x00000020
-
-#define MEM_FLASH_ADDR1 (*(volatile u16 *)(CONFIG_SYS_FLASH_BASE + (0x00000555 << 1)))
-#define MEM_FLASH_ADDR2 (*(volatile u16 *)(CONFIG_SYS_FLASH_BASE + (0x000002AA << 1)))
-
-#define BIT_ERASE_DONE 0x00000080
-#define BIT_RDY_MASK 0x00000080
-#define BIT_PROGRAM_ERROR 0x00000020
-#define BIT_TIMEOUT 0x80000000 /* our flag */
-
-#define READY 1
-#define ERR 2
-#define TMO 4
-
-/*-----------------------------------------------------------------------
- */
-
-ulong flash_init (void)
-{
- int i, j;
- ulong size = 0;
-
- for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) {
- ulong flashbase = 0;
-
- flash_info[i].flash_id =
-#if defined(CONFIG_AMD_LV400)
- (AMD_MANUFACT & FLASH_VENDMASK) |
- (AMD_ID_LV400B & FLASH_TYPEMASK);
-#elif defined(CONFIG_AMD_LV800)
- (AMD_MANUFACT & FLASH_VENDMASK) |
- (AMD_ID_LV800B & FLASH_TYPEMASK);
-#else
-#error "Unknown flash configured"
-#endif
- flash_info[i].size = FLASH_BANK_SIZE;
- flash_info[i].sector_count = CONFIG_SYS_MAX_FLASH_SECT;
- memset (flash_info[i].protect, 0, CONFIG_SYS_MAX_FLASH_SECT);
- if (i == 0)
- flashbase = PHYS_FLASH_1;
- else
- panic ("configured too many flash banks!\n");
- for (j = 0; j < flash_info[i].sector_count; j++) {
- if (j <= 3) {
- /* 1st one is 16 KB */
- if (j == 0) {
- flash_info[i].start[j] =
- flashbase + 0;
- }
-
- /* 2nd and 3rd are both 8 KB */
- if ((j == 1) || (j == 2)) {
- flash_info[i].start[j] =
- flashbase + 0x4000 + (j -
- 1) *
- 0x2000;
- }
-
- /* 4th 32 KB */
- if (j == 3) {
- flash_info[i].start[j] =
- flashbase + 0x8000;
- }
- } else {
- flash_info[i].start[j] =
- flashbase + (j - 3) * MAIN_SECT_SIZE;
- }
- }
- size += flash_info[i].size;
- }
-
- flash_protect (FLAG_PROTECT_SET,
- CONFIG_SYS_FLASH_BASE,
- CONFIG_SYS_FLASH_BASE + monitor_flash_len - 1,
- &flash_info[0]);
-
- flash_protect (FLAG_PROTECT_SET,
- CONFIG_ENV_ADDR,
- CONFIG_ENV_ADDR + CONFIG_ENV_SIZE - 1, &flash_info[0]);
-
- return size;
-}
-
-/*-----------------------------------------------------------------------
- */
-void flash_print_info (flash_info_t * info)
-{
- int i;
-
- switch (info->flash_id & FLASH_VENDMASK) {
- case (AMD_MANUFACT & FLASH_VENDMASK):
- puts ("AMD: ");
- break;
- default:
- puts ("Unknown Vendor ");
- break;
- }
-
- switch (info->flash_id & FLASH_TYPEMASK) {
- case (AMD_ID_LV400B & FLASH_TYPEMASK):
- puts ("1x Amd29LV400BB (4Mbit)\n");
- break;
- case (AMD_ID_LV800B & FLASH_TYPEMASK):
- puts ("1x Amd29LV800BB (8Mbit)\n");
- break;
- default:
- puts ("Unknown Chip Type\n");
- goto Done;
- break;
- }
-
- printf (" Size: %ld MB in %d Sectors\n",
- info->size >> 20, info->sector_count);
-
- puts (" Sector Start Addresses:");
- for (i = 0; i < info->sector_count; i++) {
- if ((i % 5) == 0) {
- puts ("\n ");
- }
- printf (" %08lX%s", info->start[i],
- info->protect[i] ? " (RO)" : " ");
- }
- puts ("\n");
-
-Done: ;
-}
-
-/*-----------------------------------------------------------------------
- */
-
-int flash_erase (flash_info_t * info, int s_first, int s_last)
-{
- ushort result;
- int iflag, cflag, prot, sect;
- int rc = ERR_OK;
- int chip;
-
- /* first look for protection bits */
-
- if (info->flash_id == FLASH_UNKNOWN)
- return ERR_UNKNOWN_FLASH_TYPE;
-
- if ((s_first < 0) || (s_first > s_last)) {
- return ERR_INVAL;
- }
-
- if ((info->flash_id & FLASH_VENDMASK) !=
- (AMD_MANUFACT & FLASH_VENDMASK)) {
- return ERR_UNKNOWN_FLASH_VENDOR;
- }
-
- prot = 0;
- for (sect = s_first; sect <= s_last; ++sect) {
- if (info->protect[sect]) {
- prot++;
- }
- }
- if (prot)
- return ERR_PROTECTED;
-
- /*
- * Disable interrupts which might cause a timeout
- * here. Remember that our exception vectors are
- * at address 0 in the flash, and we don't want a
- * (ticker) exception to happen while the flash
- * chip is in programming mode.
- */
- cflag = icache_status ();
- icache_disable ();
- iflag = disable_interrupts ();
-
- /* Start erase on unprotected sectors */
- for (sect = s_first; sect <= s_last && !ctrlc (); sect++) {
- printf ("Erasing sector %2d ... ", sect);
-
- /* arm simple, non interrupt dependent timer */
- reset_timer_masked ();
-
- if (info->protect[sect] == 0) { /* not protected */
- vu_short *addr = (vu_short *) (info->start[sect]);
-
- MEM_FLASH_ADDR1 = CMD_UNLOCK1;
- MEM_FLASH_ADDR2 = CMD_UNLOCK2;
- MEM_FLASH_ADDR1 = CMD_ERASE_SETUP;
-
- MEM_FLASH_ADDR1 = CMD_UNLOCK1;
- MEM_FLASH_ADDR2 = CMD_UNLOCK2;
- *addr = CMD_ERASE_CONFIRM;
-
- /* wait until flash is ready */
- chip = 0;
-
- do {
- result = *addr;
-
- /* check timeout */
- if (get_timer_masked () >
- CONFIG_SYS_FLASH_ERASE_TOUT) {
- MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
- chip = TMO;
- break;
- }
-
- if (!chip
- && (result & 0xFFFF) & BIT_ERASE_DONE)
- chip = READY;
-
- if (!chip
- && (result & 0xFFFF) & BIT_PROGRAM_ERROR)
- chip = ERR;
-
- } while (!chip);
-
- MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
-
- if (chip == ERR) {
- rc = ERR_PROG_ERROR;
- goto outahere;
- }
- if (chip == TMO) {
- rc = ERR_TIMOUT;
- goto outahere;
- }
-
- puts ("ok.\n");
- } else { /* it was protected */
-
- puts ("protected!\n");
- }
- }
-
- if (ctrlc ())
- puts ("User Interrupt!\n");
-
- outahere:
- /* allow flash to settle - wait 10 ms */
- udelay_masked (10000);
-
- if (iflag)
- enable_interrupts ();
-
- if (cflag)
- icache_enable ();
-
- return rc;
-}
-
-/*-----------------------------------------------------------------------
- * Copy memory to flash
- */
-
-static int write_hword (flash_info_t * info, ulong dest, ushort data)
-{
- vu_short *addr = (vu_short *) dest;
- ushort result;
- int rc = ERR_OK;
- int cflag, iflag;
- int chip;
-
- /*
- * Check if Flash is (sufficiently) erased
- */
- result = *addr;
- if ((result & data) != data)
- return ERR_NOT_ERASED;
-
-
- /*
- * Disable interrupts which might cause a timeout
- * here. Remember that our exception vectors are
- * at address 0 in the flash, and we don't want a
- * (ticker) exception to happen while the flash
- * chip is in programming mode.
- */
- cflag = icache_status ();
- icache_disable ();
- iflag = disable_interrupts ();
-
- MEM_FLASH_ADDR1 = CMD_UNLOCK1;
- MEM_FLASH_ADDR2 = CMD_UNLOCK2;
- MEM_FLASH_ADDR1 = CMD_PROGRAM;
- *addr = data;
-
- /* arm simple, non interrupt dependent timer */
- reset_timer_masked ();
-
- /* wait until flash is ready */
- chip = 0;
- do {
- result = *addr;
-
- /* check timeout */
- if (get_timer_masked () > CONFIG_SYS_FLASH_ERASE_TOUT) {
- chip = ERR | TMO;
- break;
- }
- if (!chip && ((result & 0x80) == (data & 0x80)))
- chip = READY;
-
- if (!chip && ((result & 0xFFFF) & BIT_PROGRAM_ERROR)) {
- result = *addr;
-
- if ((result & 0x80) == (data & 0x80))
- chip = READY;
- else
- chip = ERR;
- }
-
- } while (!chip);
-
- *addr = CMD_READ_ARRAY;
-
- if (chip == ERR || *addr != data)
- rc = ERR_PROG_ERROR;
-
- if (iflag)
- enable_interrupts ();
-
- if (cflag)
- icache_enable ();
-
- return rc;
-}
-
-/*-----------------------------------------------------------------------
- * Copy memory to flash.
- */
-
-int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
-{
- ulong cp, wp;
- int l;
- int i, rc;
- ushort data;
-
- wp = (addr & ~1); /* get lower word aligned address */
-
- /*
- * handle unaligned start bytes
- */
- if ((l = addr - wp) != 0) {
- data = 0;
- for (i = 0, cp = wp; i < l; ++i, ++cp) {
- data = (data >> 8) | (*(uchar *) cp << 8);
- }
- for (; i < 2 && cnt > 0; ++i) {
- data = (data >> 8) | (*src++ << 8);
- --cnt;
- ++cp;
- }
- for (; cnt == 0 && i < 2; ++i, ++cp) {
- data = (data >> 8) | (*(uchar *) cp << 8);
- }
-
- if ((rc = write_hword (info, wp, data)) != 0) {
- return (rc);
- }
- wp += 2;
- }
-
- /*
- * handle word aligned part
- */
- while (cnt >= 2) {
- data = *((vu_short *) src);
- if ((rc = write_hword (info, wp, data)) != 0) {
- return (rc);
- }
- src += 2;
- wp += 2;
- cnt -= 2;
- }
-
- if (cnt == 0) {
- return ERR_OK;
- }
-
- /*
- * handle unaligned tail bytes
- */
- data = 0;
- for (i = 0, cp = wp; i < 2 && cnt > 0; ++i, ++cp) {
- data = (data >> 8) | (*src++ << 8);
- --cnt;
- }
- for (; i < 2; ++i, ++cp) {
- data = (data >> 8) | (*(uchar *) cp << 8);
- }
-
- return write_hword (info, wp, data);
-}
diff --git a/board/mpl/vcma9/lowlevel_init.S b/board/mpl/vcma9/lowlevel_init.S
index 062e868..cb1518b 100644
--- a/board/mpl/vcma9/lowlevel_init.S
+++ b/board/mpl/vcma9/lowlevel_init.S
@@ -4,9 +4,9 @@
* Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw(a)its.tudelft.nl) and
* Jan-Derk Bakker (J.D.Bakker(a)its.tudelft.nl)
*
- * Modified for the Samsung SMDK2410 by
- * (C) Copyright 2002
+ * Modified for MPL VCMA9 by
* David Mueller, ELSOFT AG, <d.mueller(a)elsoft.ch>
+ * (C) Copyright 2002, 2003, 2004, 2005
*
* See file CREDITS for list of people who contributed to this
* project.
@@ -32,12 +32,21 @@
#include <version.h>
-/* some parameters for the board */
+/* register definitions */
+#define PLD_BASE 0x28000000
+#define MISC_REG 0x103
+#define SDRAM_REG 0x106
#define BWSCON 0x48000000
-#define PLD_BASE 0x2C000000
-#define SDRAM_REG 0x2C000106
+#define CLKBASE 0x4C000000
+#define LOCKTIME 0x0
+#define MPLLCON 0x4
+#define UPLLCON 0x8
+#define GPIOBASE 0x56000000
+#define GSTATUS1 0xB0
+#define FASTCPU 0x02
+/* some parameters for the board */
/* BWSCON */
#define DW8 (0x0)
#define DW16 (0x1)
@@ -48,83 +57,160 @@
/* BANKSIZE */
#define BURST_EN (0x1<<7)
-#define B1_BWSCON (DW16)
-#define B2_BWSCON (DW32)
-#define B3_BWSCON (DW32)
-#define B4_BWSCON (DW16 + WAIT + UBLB)
-#define B5_BWSCON (DW8 + UBLB)
-#define B6_BWSCON (DW32)
-#define B7_BWSCON (DW32)
-
-/* BANK0CON */
-#define B0_Tacs 0x0 /* 0clk */
-#define B0_Tcos 0x1 /* 1clk */
-/*#define B0_Tcos 0x0 0clk */
-#define B0_Tacc 0x7 /* 14clk */
-/*#define B0_Tacc 0x5 8clk */
-#define B0_Tcoh 0x0 /* 0clk */
-#define B0_Tah 0x0 /* 0clk */
-#define B0_Tacp 0x0 /* page mode is not used */
-#define B0_PMC 0x0 /* page mode disabled */
-
-/* BANK1CON */
-#define B1_Tacs 0x0 /* 0clk */
-#define B1_Tcos 0x1 /* 1clk */
-/*#define B1_Tcos 0x0 0clk */
-#define B1_Tacc 0x7 /* 14clk */
-/*#define B1_Tacc 0x5 8clk */
-#define B1_Tcoh 0x0 /* 0clk */
-#define B1_Tah 0x0 /* 0clk */
-#define B1_Tacp 0x0 /* page mode is not used */
-#define B1_PMC 0x0 /* page mode disabled */
+/* BANK0CON 200 */
+#define B0_Tacs_200 0x0 /* 0clk (or 0x1 1clk) */
+#define B0_Tcos_200 0x1 /* 1clk (or 0x2 2clk) */
+#define B0_Tacc_200 0x5 /* 8clk (or 0x6 10clk) */
+#define B0_Tcoh_200 0x0 /* 0clk */
+#define B0_Tcah_200 0x3 /* 4clk (or0x01 1clk) */
+#define B0_Tacp_200 0x0 /* page mode is not used */
+#define B0_PMC_200 0x0 /* page mode disabled */
+
+/* BANK0CON 250 */
+#define B0_Tacs_250 0x0 /* 0clk (or 0x1 1clk) */
+#define B0_Tcos_250 0x1 /* 1clk (or 0x2 2clk) */
+#define B0_Tacc_250 0x5 /* 8clk (or 0x7 14clk) */
+#define B0_Tcoh_250 0x0 /* 0clk */
+#define B0_Tcah_250 0x3 /* 4clk (or 0x1 1clk) */
+#define B0_Tacp_250 0x0 /* page mode is not used */
+#define B0_PMC_250 0x0 /* page mode disabled */
+
+/* BANK0CON 266 */
+#define B0_Tacs_266 0x0 /* 0clk (or 0x1 1clk) */
+#define B0_Tcos_266 0x1 /* 1clk (or 0x2 2clk) */
+#define B0_Tacc_266 0x6 /* 10clk (or 0x7 14clk) */
+#define B0_Tcoh_266 0x0 /* 0clk */
+#define B0_Tcah_266 0x3 /* 4clk (or 0x1 1clk) */
+#define B0_Tacp_266 0x0 /* page mode is not used */
+#define B0_PMC_266 0x0 /* page mode disabled */
+
+/* BANK1CON 200 */
+#define B1_Tacs_200 0x0 /* 0clk (or 0x1 1clk) */
+#define B1_Tcos_200 0x1 /* 1clk (or 0x2 2clk) */
+#define B1_Tacc_200 0x5 /* 8clk (or 0x6 10clk) */
+#define B1_Tcoh_200 0x0 /* 0clk */
+#define B1_Tcah_200 0x3 /* 4clk (or 0x1 1clk) */
+#define B1_Tacp_200 0x0 /* page mode is not used */
+#define B1_PMC_200 0x0 /* page mode disabled */
+
+/* BANK1CON 250 */
+#define B1_Tacs_250 0x0 /* 0clk (or 0x1 1clk) */
+#define B1_Tcos_250 0x1 /* 1clk (or 0x2 2clk) */
+#define B1_Tacc_250 0x5 /* 8clk (or 0x7 14clk) */
+#define B1_Tcoh_250 0x0 /* 0clk */
+#define B1_Tcah_250 0x3 /* 4clk (or 0x1 1clk) */
+#define B1_Tacp_250 0x0 /* page mode is not used */
+#define B1_PMC_250 0x0 /* page mode disabled */
+
+/* BANK1CON 266 */
+#define B1_Tacs_266 0x0 /* 0clk (or 0x1 1clk) */
+#define B1_Tcos_266 0x1 /* 1clk (or 0x2 2clk) */
+#define B1_Tacc_266 0x6 /* 10clk (or 0x7 14clk) */
+#define B1_Tcoh_266 0x0 /* 0clk */
+#define B1_Tcah_266 0x3 /* 4clk (or 0x1 1clk) */
+#define B1_Tacp_266 0x0 /* page mode is not used */
+#define B1_PMC_266 0x0 /* page mode disabled */
+/* BANK2CON 200 + 250 + 266 */
#define B2_Tacs 0x3 /* 4clk */
#define B2_Tcos 0x3 /* 4clk */
#define B2_Tacc 0x7 /* 14clk */
#define B2_Tcoh 0x3 /* 4clk */
-#define B2_Tah 0x3 /* 4clk */
+#define B2_Tcah 0x3 /* 4clk */
#define B2_Tacp 0x0 /* page mode is not used */
#define B2_PMC 0x0 /* page mode disabled */
+/* BANK3CON 200 + 250 + 266 */
#define B3_Tacs 0x3 /* 4clk */
#define B3_Tcos 0x3 /* 4clk */
#define B3_Tacc 0x7 /* 14clk */
#define B3_Tcoh 0x3 /* 4clk */
-#define B3_Tah 0x3 /* 4clk */
+#define B3_Tcah 0x3 /* 4clk */
#define B3_Tacp 0x0 /* page mode is not used */
#define B3_PMC 0x0 /* page mode disabled */
-#define B4_Tacs 0x3 /* 4clk */
-#define B4_Tcos 0x1 /* 1clk */
-#define B4_Tacc 0x7 /* 14clk */
-#define B4_Tcoh 0x1 /* 1clk */
-#define B4_Tah 0x0 /* 0clk */
-#define B4_Tacp 0x0 /* page mode is not used */
-#define B4_PMC 0x0 /* page mode disabled */
-
-#define B5_Tacs 0x0 /* 0clk */
-#define B5_Tcos 0x3 /* 4clk */
-#define B5_Tacc 0x5 /* 8clk */
-#define B5_Tcoh 0x2 /* 2clk */
-#define B5_Tah 0x1 /* 1clk */
-#define B5_Tacp 0x0 /* page mode is not used */
-#define B5_PMC 0x0 /* page mode disabled */
+/* BANK4CON 200 */
+#define B4_Tacs_200 0x1 /* 1clk */
+#define B4_Tcos_200 0x3 /* 4clk */
+#define B4_Tacc_200 0x7 /* 14clk */
+#define B4_Tcoh_200 0x3 /* 4clk */
+#define B4_Tcah_200 0x2 /* 2clk */
+#define B4_Tacp_200 0x0 /* page mode is not used */
+#define B4_PMC_200 0x0 /* page mode disabled */
+
+/* BANK4CON 250 */
+#define B4_Tacs_250 0x1 /* 1clk */
+#define B4_Tcos_250 0x3 /* 4clk */
+#define B4_Tacc_250 0x7 /* 14clk */
+#define B4_Tcoh_250 0x3 /* 4clk */
+#define B4_Tcah_250 0x2 /* 2clk */
+#define B4_Tacp_250 0x0 /* page mode is not used */
+#define B4_PMC_250 0x0 /* page mode disabled */
+
+/* BANK4CON 266 */
+#define B4_Tacs_266 0x1 /* 1clk */
+#define B4_Tcos_266 0x3 /* 4clk */
+#define B4_Tacc_266 0x7 /* 14clk */
+#define B4_Tcoh_266 0x3 /* 4clk */
+#define B4_Tcah_266 0x2 /* 2clk */
+#define B4_Tacp_266 0x0 /* page mode is not used */
+#define B4_PMC_266 0x0 /* page mode disabled */
+
+/* BANK5CON 200 */
+#define B5_Tacs_200 0x0 /* 0clk */
+#define B5_Tcos_200 0x3 /* 4clk */
+#define B5_Tacc_200 0x4 /* 6clk */
+#define B5_Tcoh_200 0x3 /* 4clk */
+#define B5_Tcah_200 0x1 /* 1clk */
+#define B5_Tacp_200 0x0 /* page mode is not used */
+#define B5_PMC_200 0x0 /* page mode disabled */
+
+/* BANK5CON 250 */
+#define B5_Tacs_250 0x0 /* 0clk */
+#define B5_Tcos_250 0x3 /* 4clk */
+#define B5_Tacc_250 0x5 /* 8clk */
+#define B5_Tcoh_250 0x3 /* 4clk */
+#define B5_Tcah_250 0x1 /* 1clk */
+#define B5_Tacp_250 0x0 /* page mode is not used */
+#define B5_PMC_250 0x0 /* page mode disabled */
+
+/* BANK5CON 266 */
+#define B5_Tacs_266 0x0 /* 0clk */
+#define B5_Tcos_266 0x3 /* 4clk */
+#define B5_Tacc_266 0x5 /* 8clk */
+#define B5_Tcoh_266 0x3 /* 4clk */
+#define B5_Tcah_266 0x1 /* 1clk */
+#define B5_Tacp_266 0x0 /* page mode is not used */
+#define B5_PMC_266 0x0 /* page mode disabled */
#define B6_MT 0x3 /* SDRAM */
-#define B6_Trcd 0x1 /* 3clk */
+#define B6_Trcd_200 0x0 /* 2clk */
+#define B6_Trcd_250 0x1 /* 3clk */
+#define B6_Trcd_266 0x1 /* 3clk */
#define B6_SCAN 0x2 /* 10bit */
#define B7_MT 0x3 /* SDRAM */
-#define B7_Trcd 0x1 /* 3clk */
+#define B7_Trcd_200 0x0 /* 2clk */
+#define B7_Trcd_250 0x1 /* 3clk */
+#define B7_Trcd_266 0x1 /* 3clk */
#define B7_SCAN 0x2 /* 10bit */
/* REFRESH parameter */
#define REFEN 0x1 /* Refresh enable */
#define TREFMD 0x0 /* CBR(CAS before RAS)/Auto refresh */
-#define Trp 0x0 /* 2clk */
-#define Trc 0x3 /* 7clk */
-#define Tchr 0x2 /* 3clk */
-#define REFCNT 1113 /* period=15.6us, HCLK=60Mhz, (2048+1-15.6*60) */
+#define Trp_200 0x0 /* 2clk */
+#define Trp_250 0x1 /* 3clk */
+#define Trp_266 0x1 /* 3clk */
+#define Tsrc_200 0x1 /* 5clk */
+#define Tsrc_250 0x2 /* 6clk */
+#define Tsrc_266 0x3 /* 7clk */
+
+/* period=15.6us, HCLK=100Mhz, (2048+1-15.6*100) */
+#define REFCNT_200 489
+/* period=15.6us, HCLK=125Mhz, (2048+1-15.6*125) */
+#define REFCNT_250 99
+/* period=15.6us, HCLK=133Mhz, (2048+1-15.6*133) */
+#define REFCNT_266 0
/**************************************/
_TEXT_BASE:
@@ -132,81 +218,304 @@ _TEXT_BASE:
.globl lowlevel_init
lowlevel_init:
+ /* use r0 to relocate DATA read/write to flash rather than memory ! */
+ ldr r0, _TEXT_BASE
+ ldr r13, =BWSCON
+
+ /* enable minimal access to PLD */
+ ldr r1, [r13] /* load default BWSCON */
+ orr r1, r1, #(DW8 + UBLB) << 20 /* set necessary CS attrs */
+ str r1, [r13] /* set BWSCON */
+ ldr r1, =0x7FF0 /* select slowest timing */
+ str r1, [r13, #0x18] /* set BANKCON5 */
+
+ ldr r1, =PLD_BASE
+ ldr r2, =SETUPDATA
+ ldrb r1, [r1, #MISC_REG]
+ sub r2, r2, r0
+ tst r1, #FASTCPU /* FASTCPU available ? */
+ addeq r2, r2, #SETUPENTRY_SIZE
+
/* memory control configuration */
- /* make r0 relative the current location so that it */
- /* reads SMRDATA out of FLASH rather than memory ! */
- ldr r0, =CSDATA
- ldr r1, _TEXT_BASE
- sub r0, r0, r1
- ldr r1, =BWSCON /* Bus Width Status Controller */
- add r2, r0, #CSDATA_END-CSDATA
+ /* r2 = pointer into timing table */
+ /* r13 = pointer to MEM controller regs (starting with BWSCON) */
+ add r3, r2, #CSDATA_OFFSET
+ add r4, r3, #CSDATAENTRY_SIZE
0:
- ldr r3, [r0], #4
- str r3, [r1], #4
- cmp r2, r0
+ ldr r1, [r3], #4
+ str r1, [r13], #4
+ cmp r3, r4
bne 0b
/* PLD access is now possible */
- /* r0 == SDRAMDATA */
- /* r1 == SDRAM controller regs */
- ldr r2, =PLD_BASE
- ldrb r3, [r2, #SDRAM_REG-PLD_BASE]
- mov r4, #SDRAMDATA1_END-SDRAMDATA
+ /* r3 = SDRAMDATA
+ /* r13 = pointer to MEM controller regs */
+ ldr r1, =PLD_BASE
+ mov r4, #SDRAMENTRY_SIZE
+ ldrb r1, [r1, #SDRAM_REG]
/* calculate start and end point */
- mla r0, r3, r4, r0
- add r2, r0, r4
+ mla r3, r4, r1, r3
+ add r4, r3, r4
0:
- ldr r3, [r0], #4
- str r3, [r1], #4
- cmp r2, r0
+ ldr r1, [r3], #4
+ str r1, [r13], #4
+ cmp r3, r4
bne 0b
+ /* setup MPLL registers */
+ ldr r1, =CLKBASE
+ ldr r4, =0xFFFFFF
+ add r3, r2, #4 /* r3 points to PLL values */
+ str r4, [r1, #LOCKTIME]
+ ldmia r3, {r4,r5}
+ str r5, [r1, #UPLLCON] /* writing PLL register */
+ /* !! order seems to be important !! */
+ /* a little delay */
+ ldr r3, =0x4000
+0:
+ subs r3, r3, #1
+ bne 0b
+
+ str r4, [r1, #MPLLCON] /* writing PLL register */
+ /* !! order seems to be important !! */
+ /* a little delay */
+ ldr r3, =0x4000
+0:
+ subs r3, r3, #1
+ bne 0b
+
/* everything is fine now */
mov pc, lr
.ltorg
/* the literal pools origin */
-CSDATA:
- .word (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))
- .word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC))
- .word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC))
- .word ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC))
- .word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC))
- .word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC))
- .word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC))
-CSDATA_END:
-
-SDRAMDATA:
-/* 4Mx8x4 */
- .word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))
- .word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))
- .word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
- .word 0x32 + BURST_EN
- .word 0x30
- .word 0x30
-SDRAMDATA1_END:
-
-/* 8Mx8x4 (not implemented yet) */
- .word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))
- .word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))
- .word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
- .word 0x32 + BURST_EN
- .word 0x30
- .word 0x30
-
-/* 2Mx8x4 (not implemented yet) */
- .word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))
- .word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))
- .word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
- .word 0x32 + BURST_EN
- .word 0x30
- .word 0x30
-
-/* 4Mx8x2 (not implemented yet) */
- .word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))
- .word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))
- .word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
- .word 0x32 + BURST_EN
- .word 0x30
- .word 0x30
+#define MK_BWSCON(bws1, bws2, bws3, bws4, bws5, bws6, bws7) \
+ ((bws1) << 4) + \
+ ((bws2) << 8) + \
+ ((bws3) << 12) + \
+ ((bws4) << 16) + \
+ ((bws5) << 20) + \
+ ((bws6) << 24) + \
+ ((bws7) << 28)
+
+#define MK_BANKCON(tacs, tcos, tacc, tcoh, tcah, tacp, pmc) \
+ ((tacs) << 13) + \
+ ((tcos) << 11) + \
+ ((tacc) << 8) + \
+ ((tcoh) << 6) + \
+ ((tcah) << 4) + \
+ ((tacp) << 2) + \
+ (pmc)
+
+#define MK_BANKCON_SDRAM(trcd, scan) \
+ ((0x03) << 15) + \
+ ((trcd) << 2) + \
+ (scan)
+
+#define MK_SDRAM_REFRESH(enable, trefmd, trp, tsrc, cnt) \
+ ((enable) << 23) + \
+ ((trefmd) << 22) + \
+ ((trp) << 20) + \
+ ((tsrc) << 18) + \
+ (cnt)
+
+SETUPDATA:
+ .word 0x32410002
+ /* PLL values (MDIV, PDIV, SDIV) for 250 MHz */
+ .word (0x75 << 12) + (0x01 << 4) + (0x01 << 0)
+ /* PLL values for USB clock */
+ .word (0x48 << 12) + (0x03 << 4) + (0x02 << 0)
+
+ /* timing for 250 MHz*/
+0:
+ .equiv CSDATA_OFFSET, (. - SETUPDATA)
+ .word MK_BWSCON(DW16, \
+ DW32, \
+ DW32, \
+ DW16 + WAIT + UBLB, \
+ DW8 + UBLB, \
+ DW32, \
+ DW32)
+
+ .word MK_BANKCON(B0_Tacs_250, \
+ B0_Tcos_250, \
+ B0_Tacc_250, \
+ B0_Tcoh_250, \
+ B0_Tcah_250, \
+ B0_Tacp_250, \
+ B0_PMC_250)
+
+ .word MK_BANKCON(B1_Tacs_250, \
+ B1_Tcos_250, \
+ B1_Tacc_250, \
+ B1_Tcoh_250, \
+ B1_Tcah_250, \
+ B1_Tacp_250, \
+ B1_PMC_250)
+
+ .word MK_BANKCON(B2_Tacs, \
+ B2_Tcos, \
+ B2_Tacc, \
+ B2_Tcoh, \
+ B2_Tcah, \
+ B2_Tacp, \
+ B2_PMC)
+
+ .word MK_BANKCON(B3_Tacs, \
+ B3_Tcos, \
+ B3_Tacc, \
+ B3_Tcoh, \
+ B3_Tcah, \
+ B3_Tacp, \
+ B3_PMC)
+
+ .word MK_BANKCON(B4_Tacs_250, \
+ B4_Tcos_250, \
+ B4_Tacc_250, \
+ B4_Tcoh_250, \
+ B4_Tcah_250, \
+ B4_Tacp_250, \
+ B4_PMC_250)
+
+ .word MK_BANKCON(B5_Tacs_250, \
+ B5_Tcos_250, \
+ B5_Tacc_250, \
+ B5_Tcoh_250, \
+ B5_Tcah_250, \
+ B5_Tacp_250, \
+ B5_PMC_250)
+
+ .equiv CSDATAENTRY_SIZE, (. - 0b)
+ /* 4Mx8x4 */
+0:
+ .word MK_BANKCON_SDRAM(B6_Trcd_250, B6_SCAN)
+ .word MK_BANKCON_SDRAM(B7_Trcd_250, B7_SCAN)
+ .word MK_SDRAM_REFRESH(REFEN, TREFMD, Trp_250, Tsrc_250, REFCNT_250)
+ .word 0x32 + BURST_EN
+ .word 0x30
+ .word 0x30
+ .equiv SDRAMENTRY_SIZE, (. - 0b)
+
+ /* 8Mx8x4 (not implemented yet) */
+ .word MK_BANKCON_SDRAM(B6_Trcd_250, B6_SCAN)
+ .word MK_BANKCON_SDRAM(B7_Trcd_250, B7_SCAN)
+ .word MK_SDRAM_REFRESH(REFEN, TREFMD, Trp_250, Tsrc_250, REFCNT_250)
+ .word 0x32 + BURST_EN
+ .word 0x30
+ .word 0x30
+
+ /* 2Mx8x4 (not implemented yet) */
+ .word MK_BANKCON_SDRAM(B6_Trcd_250, B6_SCAN)
+ .word MK_BANKCON_SDRAM(B7_Trcd_250, B7_SCAN)
+ .word MK_SDRAM_REFRESH(REFEN, TREFMD, Trp_250, Tsrc_250, REFCNT_250)
+ .word 0x32 + BURST_EN
+ .word 0x30
+ .word 0x30
+
+ /* 4Mx8x2 (not implemented yet) */
+ .word MK_BANKCON_SDRAM(B6_Trcd_250, B6_SCAN)
+ .word MK_BANKCON_SDRAM(B7_Trcd_250, B7_SCAN)
+ .word MK_SDRAM_REFRESH(REFEN, TREFMD, Trp_250, Tsrc_250, REFCNT_250)
+ .word 0x32 + BURST_EN
+ .word 0x30
+ .word 0x30
+
+ .equiv SETUPENTRY_SIZE, (. - SETUPDATA)
+
+ .word 0x32410000
+ /* PLL values (MDIV, PDIV, SDIV) for 200 MHz (Fout = 202.8MHz) */
+ .word (0xA1 << 12) + (0x03 << 4) + (0x01 << 0)
+ /* PLL values for USB clock */
+ .word (0x48 << 12) + (0x03 << 4) + (0x02 << 0)
+
+ /* timing for 200 MHz and default*/
+ .word MK_BWSCON(DW16, \
+ DW32, \
+ DW32, \
+ DW16 + WAIT + UBLB, \
+ DW8 + UBLB, \
+ DW32, \
+ DW32)
+
+ .word MK_BANKCON(B0_Tacs_200, \
+ B0_Tcos_200, \
+ B0_Tacc_200, \
+ B0_Tcoh_200, \
+ B0_Tcah_200, \
+ B0_Tacp_200, \
+ B0_PMC_200)
+
+ .word MK_BANKCON(B1_Tacs_200, \
+ B1_Tcos_200, \
+ B1_Tacc_200, \
+ B1_Tcoh_200, \
+ B1_Tcah_200, \
+ B1_Tacp_200, \
+ B1_PMC_200)
+
+ .word MK_BANKCON(B2_Tacs, \
+ B2_Tcos, \
+ B2_Tacc, \
+ B2_Tcoh, \
+ B2_Tcah, \
+ B2_Tacp, \
+ B2_PMC)
+
+ .word MK_BANKCON(B3_Tacs, \
+ B3_Tcos, \
+ B3_Tacc, \
+ B3_Tcoh, \
+ B3_Tcah, \
+ B3_Tacp, \
+ B3_PMC)
+
+ .word MK_BANKCON(B4_Tacs_200, \
+ B4_Tcos_200, \
+ B4_Tacc_200, \
+ B4_Tcoh_200, \
+ B4_Tcah_200, \
+ B4_Tacp_200, \
+ B4_PMC_200)
+
+ .word MK_BANKCON(B5_Tacs_200, \
+ B5_Tcos_200, \
+ B5_Tacc_200, \
+ B5_Tcoh_200, \
+ B5_Tcah_200, \
+ B5_Tacp_200, \
+ B5_PMC_200)
+
+ /* 4Mx8x4 */
+ .word MK_BANKCON_SDRAM(B6_Trcd_200, B6_SCAN)
+ .word MK_BANKCON_SDRAM(B7_Trcd_200, B7_SCAN)
+ .word MK_SDRAM_REFRESH(REFEN, TREFMD, Trp_200, Tsrc_200, REFCNT_200)
+ .word 0x32 + BURST_EN
+ .word 0x30
+ .word 0x30
+
+ /* 8Mx8x4 (not implemented yet) */
+ .word MK_BANKCON_SDRAM(B6_Trcd_200, B6_SCAN)
+ .word MK_BANKCON_SDRAM(B7_Trcd_200, B7_SCAN)
+ .word MK_SDRAM_REFRESH(REFEN, TREFMD, Trp_200, Tsrc_200, REFCNT_200)
+ .word 0x32 + BURST_EN
+ .word 0x30
+ .word 0x30
+
+ /* 2Mx8x4 (not implemented yet) */
+ .word MK_BANKCON_SDRAM(B6_Trcd_200, B6_SCAN)
+ .word MK_BANKCON_SDRAM(B7_Trcd_200, B7_SCAN)
+ .word MK_SDRAM_REFRESH(REFEN, TREFMD, Trp_200, Tsrc_200, REFCNT_200)
+ .word 0x32 + BURST_EN
+ .word 0x30
+ .word 0x30
+
+ /* 4Mx8x2 (not implemented yet) */
+ .word MK_BANKCON_SDRAM(B6_Trcd_200, B6_SCAN)
+ .word MK_BANKCON_SDRAM(B7_Trcd_200, B7_SCAN)
+ .word MK_SDRAM_REFRESH(REFEN, TREFMD, Trp_200, Tsrc_200, REFCNT_200)
+ .word 0x32 + BURST_EN
+ .word 0x30
+ .word 0x30
+
+ .equiv SETUPDATA_SIZE, (. - SETUPDATA)
diff --git a/board/mpl/vcma9/vcma9.c b/board/mpl/vcma9/vcma9.c
index 978e6fd..b6b49f5 100644
--- a/board/mpl/vcma9/vcma9.c
+++ b/board/mpl/vcma9/vcma9.c
@@ -3,7 +3,7 @@
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Marius Groeger <mgroeger(a)sysgo.de>
*
- * (C) Copyright 2002
+ * (C) Copyright 2002, 2010
* David Mueller, ELSOFT AG, <d.mueller(a)elsoft.ch>
*
* See file CREDITS for list of people who contributed to this
@@ -27,100 +27,53 @@
#include <common.h>
#include <netdev.h>
-#include <asm/arch/s3c24x0_cpu.h>
-#include <stdio_dev.h>
#include <i2c.h>
+#include <asm/io.h>
+#include <asm/arch/s3c24x0_cpu.h>
#include "vcma9.h"
#include "../common/common_util.h"
DECLARE_GLOBAL_DATA_PTR;
-#define FCLK_SPEED 1
-
-#if FCLK_SPEED==0 /* Fout = 203MHz, Fin = 12MHz for Audio */
-#define M_MDIV 0xC3
-#define M_PDIV 0x4
-#define M_SDIV 0x1
-#elif FCLK_SPEED==1 /* Fout = 202.8MHz */
-#define M_MDIV 0xA1
-#define M_PDIV 0x3
-#define M_SDIV 0x1
-#endif
-
-#define USB_CLOCK 1
-
-#if USB_CLOCK==0
-#define U_M_MDIV 0xA1
-#define U_M_PDIV 0x3
-#define U_M_SDIV 0x1
-#elif USB_CLOCK==1
-#define U_M_MDIV 0x48
-#define U_M_PDIV 0x3
-#define U_M_SDIV 0x2
-#endif
-
-static inline void delay(unsigned long loops)
-{
- __asm__ volatile ("1:\n"
- "subs %0, %1, #1\n"
- "bne 1b":"=r" (loops):"0" (loops));
-}
-
/*
* Miscellaneous platform dependent initialisations
*/
-int board_init(void)
+int board_early_init_f(void)
{
struct s3c24x0_clock_power * const clk_power =
s3c24x0_get_base_clock_power();
struct s3c24x0_gpio * const gpio = s3c24x0_get_base_gpio();
- /* to reduce PLL lock time, adjust the LOCKTIME register */
- clk_power->locktime = 0xFFFFFF;
-
- /* configure MPLL */
- clk_power->mpllcon = ((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV);
-
- /* some delay between MPLL and UPLL */
- delay (4000);
-
- /* configure UPLL */
- clk_power->upllcon = ((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV);
-
- /* some delay between MPLL and UPLL */
- delay (8000);
-
/* set up the I/O ports */
- gpio->gpacon = 0x007FFFFF;
- gpio->gpbcon = 0x002AAAAA;
- gpio->gpbup = 0x000002BF;
- gpio->gpccon = 0xAAAAAAAA;
- gpio->gpcup = 0x0000FFFF;
- gpio->gpdcon = 0xAAAAAAAA;
- gpio->gpdup = 0x0000FFFF;
- gpio->gpecon = 0xAAAAAAAA;
- gpio->gpeup = 0x000037F7;
- gpio->gpfcon = 0x00000000;
- gpio->gpfup = 0x00000000;
- gpio->gpgcon = 0xFFEAFF5A;
- gpio->gpgup = 0x0000F0DC;
- gpio->gphcon = 0x0028AAAA;
- gpio->gphup = 0x00000656;
-
- /* setup correct IRQ modes for NIC */
- /* rising edge mode */
- gpio->extint2 = (gpio->extint2 & ~(7<<8)) | (4<<8);
-
- /* select USB port 2 to be host or device (fix to host for now) */
- gpio->misccr |= 0x08;
-
- /* init serial */
- gd->baudrate = CONFIG_BAUDRATE;
- gd->have_console = 1;
- serial_init();
+ writel(0x007FFFFF, &gpio->gpacon);
+ writel(0x002AAAAA, &gpio->gpbcon);
+ writel(0x000002BF, &gpio->gpbup);
+ writel(0xAAAAAAAA, &gpio->gpccon);
+ writel(0x0000FFFF, &gpio->gpcup);
+ writel(0xAAAAAAAA, &gpio->gpdcon);
+ writel(0x0000FFFF, &gpio->gpdup);
+ writel(0xAAAAAAAA, &gpio->gpecon);
+ writel(0x000037F7, &gpio->gpeup);
+ writel(0x00000000, &gpio->gpfcon);
+ writel(0x00000000, &gpio->gpfup);
+ writel(0xFFEAFF5A, &gpio->gpgcon);
+ writel(0x0000F0DC, &gpio->gpgup);
+ writel(0x0028AAAA, &gpio->gphcon);
+ writel(0x00000656, &gpio->gphup);
+
+ /* setup correct IRQ modes for NIC (rising edge mode) */
+ writel((readl(&gpio->extint2) & ~(7<<8)) | (4<<8), &gpio->extint2);
+
+ /* select USB port 2 to be host or device (setup as host for now) */
+ writel(readl(&gpio->misccr) | 0x08, &gpio->misccr);
+
+ return 0;
+}
+int board_init(void)
+{
/* arch number of VCMA9-Board */
gd->bd->bi_arch_number = MACH_TYPE_MPL_VCMA9;
@@ -134,113 +87,32 @@ int board_init(void)
}
/*
- * NAND flash initialization.
- */
-#if defined(CONFIG_CMD_NAND)
-extern ulong
-nand_probe(ulong physadr);
-
-
-static inline void NF_Reset(void)
-{
- int i;
-
- NF_SetCE(NFCE_LOW);
- NF_Cmd(0xFF); /* reset command */
- for(i = 0; i < 10; i++); /* tWB = 100ns. */
- NF_WaitRB(); /* wait 200~500us; */
- NF_SetCE(NFCE_HIGH);
-}
-
-
-static inline void NF_Init(void)
-{
-#if 0 /* a little bit too optimistic */
-#define TACLS 0
-#define TWRPH0 3
-#define TWRPH1 0
-#else
-#define TACLS 0
-#define TWRPH0 4
-#define TWRPH1 2
-#endif
-
- NF_Conf((1<<15)|(0<<14)|(0<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0));
- /*nand->NFCONF = (1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0); */
- /* 1 1 1 1, 1 xxx, r xxx, r xxx */
- /* En 512B 4step ECCR nFCE=H tACLS tWRPH0 tWRPH1 */
-
- NF_Reset();
-}
-
-void
-nand_init(void)
-{
- struct s3c2410_nand * const nand = s3c2410_get_base_nand();
-
- NF_Init();
-#ifdef DEBUG
- printf("NAND flash probing at 0x%.8lX\n", (ulong)nand);
-#endif
- printf ("%4lu MB\n", nand_probe((ulong)nand) >> 20);
-}
-#endif
-
-/*
* Get some Board/PLD Info
*/
-static u8 Get_PLD_ID(void)
+static u8 get_pld_reg(enum vcma9_pld_regs reg)
{
- VCMA9_PLD * const pld = VCMA9_get_base_PLD();
-
- return(pld->ID);
+ return readb(VCMA9_PLD_BASE + reg);
}
-static u8 Get_PLD_BOARD(void)
+static u8 get_pld_version(void)
{
- VCMA9_PLD * const pld = VCMA9_get_base_PLD();
-
- return(pld->BOARD);
+ return (get_pld_reg(VCMA9_PLD_ID) >> 4) & 0x0F;
}
-static u8 Get_PLD_SDRAM(void)
+static u8 get_pld_revision(void)
{
- VCMA9_PLD * const pld = VCMA9_get_base_PLD();
-
- return(pld->SDRAM);
+ return get_pld_reg(VCMA9_PLD_ID) & 0x0F;
}
-static u8 Get_PLD_Version(void)
+static uchar get_board_pcb(void)
{
- return((Get_PLD_ID() >> 4) & 0x0F);
+ return ((get_pld_reg(VCMA9_PLD_BOARD) >> 4) & 0x03) + 'A';
}
-static u8 Get_PLD_Revision(void)
+static u8 get_nr_chips(void)
{
- return(Get_PLD_ID() & 0x0F);
-}
-
-#if 0 /* not used */
-static int Get_Board_Config(void)
-{
- u8 config = Get_PLD_BOARD() & 0x03;
-
- if (config == 3)
- return 1;
- else
- return 0;
-}
-#endif
-
-static uchar Get_Board_PCB(void)
-{
- return(((Get_PLD_BOARD() >> 4) & 0x03) + 'A');
-}
-
-static u8 Get_SDRAM_ChipNr(void)
-{
- switch ((Get_PLD_SDRAM() >> 4) & 0x0F) {
+ switch ((get_pld_reg(VCMA9_PLD_SDRAM) >> 4) & 0x0F) {
case 0: return 4;
case 1: return 1;
case 2: return 2;
@@ -248,9 +120,9 @@ static u8 Get_SDRAM_ChipNr(void)
}
}
-static ulong Get_SDRAM_ChipSize(void)
+static ulong get_chip_size(void)
{
- switch (Get_PLD_SDRAM() & 0x0F) {
+ switch (get_pld_reg(VCMA9_PLD_SDRAM) & 0x0F) {
case 0: return 16 * (1024*1024);
case 1: return 32 * (1024*1024);
case 2: return 8 * (1024*1024);
@@ -258,9 +130,10 @@ static ulong Get_SDRAM_ChipSize(void)
default: return 0;
}
}
-static const char * Get_SDRAM_ChipGeom(void)
+
+static const char *get_chip_geom(void)
{
- switch (Get_PLD_SDRAM() & 0x0F) {
+ switch (get_pld_reg(VCMA9_PLD_SDRAM) & 0x0F) {
case 0: return "4Mx8x4";
case 1: return "8Mx8x4";
case 2: return "2Mx8x4";
@@ -269,23 +142,21 @@ static const char * Get_SDRAM_ChipGeom(void)
}
}
-static void Show_VCMA9_Info(char *board_name, char *serial)
+static void vcma9_show_info(char *board_name, char *serial)
{
printf("Board: %s SN: %s PCB Rev: %c PLD(%d,%d)\n",
- board_name, serial, Get_Board_PCB(), Get_PLD_Version(), Get_PLD_Revision());
- printf("SDRAM: %d chips %s\n", Get_SDRAM_ChipNr(), Get_SDRAM_ChipGeom());
+ board_name, serial,
+ get_board_pcb(), get_pld_version(), get_pld_revision());
+ printf("SDRAM: %d chips %s\n", get_nr_chips(), get_chip_geom());
}
int dram_init(void)
{
- gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
- gd->bd->bi_dram[0].size = Get_SDRAM_ChipSize() * Get_SDRAM_ChipNr();
-
+ /* dram_init must store complete ramsize in gd->ram_size */
+ gd->ram_size = get_chip_size() * get_nr_chips();
return 0;
}
-/* ------------------------------------------------------------------------- */
-
/*
* Check Board Identity:
*/
@@ -303,50 +174,35 @@ int checkboard(void)
puts ("### No HW ID - assuming VCMA9");
} else {
b->serial_name[5] = 0;
- Show_VCMA9_Info(b->serial_name, &b->serial_name[6]);
+ vcma9_show_info(b->serial_name, &b->serial_name[6]);
}
} else {
s[5] = 0;
- Show_VCMA9_Info(s, &s[6]);
+ vcma9_show_info(s, &s[6]);
}
- /*printf("\n");*/
- return(0);
-}
-
-int last_stage_init(void)
-{
- checkboard();
- stdio_print_current_devices();
- check_env();
return 0;
}
-/***************************************************************************
- * some helping routines
- */
-#if !CONFIG_USB_KEYBOARD
-int overwrite_console(void)
+int board_late_init(void)
{
- /* return TRUE if console should be overwritten */
+ /*
+ * check if environment is healthy, otherwise restore values
+ * from shadow copy
+ */
+ check_env();
return 0;
}
-#endif
-/************************************************************************
-* Print VCMA9 Info
-************************************************************************/
-void print_vcma9_info(void)
+void vcma9_print_info(void)
{
- char s[50];
- int i;
+ char *s = getenv("serial#");
- if ((i = getenv_f("serial#", s, 32)) < 0) {
+ if (!s) {
puts ("### No HW ID - assuming VCMA9");
- printf("i %d", i*24);
} else {
s[5] = 0;
- Show_VCMA9_Info(s, &s[6]);
+ vcma9_show_info(s, &s[6]);
}
}
@@ -360,3 +216,15 @@ int board_eth_init(bd_t *bis)
return rc;
}
#endif
+
+/*
+ * Hardcoded flash setup:
+ * Flash 0 is a non-CFI AMD AM29F400BB flash.
+ */
+ulong board_flash_get_legacy(ulong base, int banknum, flash_info_t *info)
+{
+ info->portwidth = FLASH_CFI_16BIT;
+ info->chipwidth = FLASH_CFI_BY16;
+ info->interface = FLASH_CFI_X16;
+ return 1;
+}
diff --git a/board/mpl/vcma9/vcma9.h b/board/mpl/vcma9/vcma9.h
index 94fd2fa..baaea85 100644
--- a/board/mpl/vcma9/vcma9.h
+++ b/board/mpl/vcma9/vcma9.h
@@ -29,106 +29,17 @@
extern int mem_test(unsigned long start, unsigned long ramsize,int mode);
-void print_vcma9_info(void);
-
-#if defined(CONFIG_CMD_NAND)
-typedef enum {
- NFCE_LOW,
- NFCE_HIGH
-} NFCE_STATE;
-
-static inline void NF_Conf(u16 conf)
-{
- struct s3c2410_nand * const nand = s3c2410_get_base_nand();
-
- nand->NFCONF = conf;
-}
-
-static inline void NF_Cmd(u8 cmd)
-{
- struct s3c2410_nand * const nand = s3c2410_get_base_nand();
-
- nand->NFCMD = cmd;
-}
-
-static inline void NF_CmdW(u8 cmd)
-{
- NF_Cmd(cmd);
- udelay(1);
-}
-
-static inline void NF_Addr(u8 addr)
-{
- struct s3c2410_nand * const nand = s3c2410_get_base_nand();
-
- nand->NFADDR = addr;
-}
-
-static inline void NF_SetCE(NFCE_STATE s)
-{
- struct s3c2410_nand * const nand = s3c2410_get_base_nand();
-
- switch (s) {
- case NFCE_LOW:
- nand->NFCONF &= ~(1<<11);
- break;
-
- case NFCE_HIGH:
- nand->NFCONF |= (1<<11);
- break;
- }
-}
-
-static inline void NF_WaitRB(void)
-{
- struct s3c2410_nand * const nand = s3c2410_get_base_nand();
-
- while (!(nand->NFSTAT & (1<<0)));
-}
-
-static inline void NF_Write(u8 data)
-{
- struct s3c2410_nand * const nand = s3c2410_get_base_nand();
-
- nand->NFDATA = data;
-}
-
-static inline u8 NF_Read(void)
-{
- struct s3c2410_nand * const nand = s3c2410_get_base_nand();
-
- return(nand->NFDATA);
-}
-
-static inline void NF_Init_ECC(void)
-{
- struct s3c2410_nand * const nand = s3c2410_get_base_nand();
-
- nand->NFCONF |= (1<<12);
-}
-
-static inline u32 NF_Read_ECC(void)
-{
- struct s3c2410_nand * const nand = s3c2410_get_base_nand();
-
- return(nand->NFECC);
-}
-
-#endif
-
-/* VCMA9 PLD regsiters */
-typedef struct {
- u8 ID;
- u8 NIC;
- u8 CAN;
- u8 MISC;
- u8 GPCD;
- u8 BOARD;
- u8 SDRAM;
-} /*__attribute__((__packed__))*/ VCMA9_PLD;
-
-#define VCMA9_PLD_BASE 0x2C000100
-static inline VCMA9_PLD *VCMA9_get_base_PLD(void)
-{
- return (VCMA9_PLD * const)VCMA9_PLD_BASE;
-}
+void vcma9_print_info(void);
+
+/* VCMA9 PLD registers */
+enum vcma9_pld_regs {
+ VCMA9_PLD_ID,
+ VCMA9_PLD_NIC,
+ VCMA9_PLD_CAN,
+ VCMA9_PLD_MISC,
+ VCMA9_PLD_GPCD,
+ VCMA9_PLD_BOARD,
+ VCMA9_PLD_SDRAM
+};
+
+#define VCMA9_PLD_BASE (0x2C000100)
diff --git a/include/configs/VCMA9.h b/include/configs/VCMA9.h
index ebe9e42..a82012f 100644
--- a/include/configs/VCMA9.h
+++ b/include/configs/VCMA9.h
@@ -33,21 +33,21 @@
* High Level Configuration Options
* (easy to change)
*/
-#define CONFIG_ARM920T 1 /* This is an ARM920T Core */
-#define CONFIG_S3C24X0 1 /* in a SAMSUNG S3C24x0-type SoC */
-#define CONFIG_S3C2410 1 /* specifically a SAMSUNG S3C2410 SoC */
-#define CONFIG_VCMA9 1 /* on a MPL VCMA9 Board */
+#define CONFIG_ARM920T /* This is an ARM920T Core */
+#define CONFIG_S3C24X0 /* in a SAMSUNG S3C24x0-type SoC */
+#define CONFIG_S3C2410 /* specifically a SAMSUNG S3C2410 SoC */
+#define CONFIG_VCMA9 /* on a MPL VCMA9 Board */
-/* input clock of PLL */
-#define CONFIG_SYS_CLK_FREQ 12000000/* VCMA9 has 12MHz input clock */
+#define CONFIG_SYS_ARM_CACHE_WRITETHROUGH
-#define USE_920T_MMU 1
-#undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */
+/* input clock of PLL (VCMA9 has 12MHz input clock) */
+#define CONFIG_SYS_CLK_FREQ 12000000
-#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */
-#define CONFIG_SETUP_MEMORY_TAGS 1
-#define CONFIG_INITRD_TAG 1
+#undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */
+#define CONFIG_CMDLINE_TAG /* enable passing of ATAGs */
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_INITRD_TAG
/*
* BOOTP options
@@ -57,7 +57,6 @@
#define CONFIG_BOOTP_GATEWAY
#define CONFIG_BOOTP_HOSTNAME
-
/*
* Command line configuration.
*/
@@ -68,146 +67,154 @@
#define CONFIG_CMD_I2C
#define CONFIG_CMD_USB
#define CONFIG_CMD_REGINFO
-#define CONFIG_CMD_FAT
#define CONFIG_CMD_DATE
#define CONFIG_CMD_ELF
#define CONFIG_CMD_DHCP
#define CONFIG_CMD_PING
#define CONFIG_CMD_BSP
+#define CONFIG_CMD_NAND
+#define BOARD_LATE_INIT
#define CONFIG_SYS_HUSH_PARSER
#define CONFIG_SYS_PROMPT_HUSH_PS2 "> "
+#define CONFIG_CMDLINE_EDITING
+
/***********************************************************
* I2C stuff:
* the MPL VCMA9 is equipped with an ATMEL 24C256 EEPROM at
* address 0x50 with 16bit addressing
***********************************************************/
-#define CONFIG_HARD_I2C /* I2C with hardware support */
+#define CONFIG_HARD_I2C /* I2C with hardware support */
#define CONFIG_SYS_I2C_SPEED 100000 /* I2C speed */
#define CONFIG_SYS_I2C_SLAVE 0x7F /* I2C slave addr */
+/* we use the built-in I2C controller */
+#define CONFIG_DRIVER_S3C24X0_I2C
+
#define CONFIG_SYS_I2C_EEPROM_ADDR 0x50
#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2
-#define CONFIG_ENV_IS_IN_EEPROM 1 /* use EEPROM for environment vars */
-#define CONFIG_ENV_OFFSET 0x000 /* environment starts at offset 0 */
-#define CONFIG_ENV_SIZE 0x800 /* 2KB should be more than enough */
+/* use EEPROM for environment vars */
+#define CONFIG_ENV_IS_IN_EEPROM 1
+/* environment starts at offset 0 */
+#define CONFIG_ENV_OFFSET 0x000
+/* 2KB should be more than enough */
+#define CONFIG_ENV_SIZE 0x800
#undef CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW
-#define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS 6 /* 64 bytes page write mode on 24C256 */
+/* 64 bytes page write mode on 24C256 */
+#define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS 6
#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS 10
/*
- * Size of malloc() pool
- */
-/*#define CONFIG_MALLOC_SIZE (CONFIG_ENV_SIZE + 128*1024)*/
-
-#define CONFIG_SYS_MONITOR_LEN (256 * 1024)
-#define CONFIG_SYS_MALLOC_LEN (1024 * 1024) /* BUNZIP2 needs a lot of RAM */
-
-/*
* Hardware drivers
*/
#define CONFIG_NET_MULTI
-#define CONFIG_CS8900 /* we have a CS8900 on-board */
-#define CONFIG_CS8900_BASE 0x20000300
-#define CONFIG_CS8900_BUS16 /* the Linux driver does accesses as shorts */
-
-#define CONFIG_DRIVER_S3C24X0_I2C 1 /* we use the buildin I2C controller */
+#define CONFIG_CS8900 /* we have a CS8900 on-board */
+#define CONFIG_CS8900_BASE 0x20000300
+#define CONFIG_CS8900_BUS16
/*
* select serial console configuration
*/
#define CONFIG_S3C24X0_SERIAL
-#define CONFIG_SERIAL1 1 /* we use SERIAL 1 on VCMA9 */
+#define CONFIG_SERIAL1 1 /* we use SERIAL 1 on VCMA9 */
/************************************************************
- * USB support
+ * USB support (currently only works with D-cache off)
************************************************************/
-#define CONFIG_USB_OHCI 1
-#define CONFIG_USB_KEYBOARD 1
-#define CONFIG_USB_STORAGE 1
-#define CONFIG_DOS_PARTITION 1
+#define CONFIG_USB_OHCI
+#define CONFIG_USB_KEYBOARD
+#define CONFIG_USB_STORAGE
+#define CONFIG_DOS_PARTITION
/* Enable needed helper functions */
-#define CONFIG_SYS_STDIO_DEREGISTER /* needs stdio_deregister */
+#define CONFIG_SYS_STDIO_DEREGISTER /* needs stdio_deregister */
/************************************************************
* RTC
************************************************************/
-#define CONFIG_RTC_S3C24X0 1
+#define CONFIG_RTC_S3C24X0
/* allow to overwrite serial and ethaddr */
#define CONFIG_ENV_OVERWRITE
-#define CONFIG_BAUDRATE 9600
+#define CONFIG_BAUDRATE 9600
-#define CONFIG_BOOTDELAY 5
-/* autoboot (do NOT change this set environment variable "bootdelay" to -1 instead) */
-/* #define CONFIG_BOOT_RETRY_TIME -10 /XXX* feature is available but not enabled */
-#define CONFIG_ZERO_BOOTDELAY_CHECK /* check console even if bootdelay = 0 */
+#define CONFIG_BOOTDELAY 5
+#define CONFIG_BOOT_RETRY_TIME -1
+#define CONFIG_RESET_TO_RETRY
+#define CONFIG_ZERO_BOOTDELAY_CHECK
-#define CONFIG_NETMASK 255.255.255.0
-#define CONFIG_IPADDR 10.0.0.110
-#define CONFIG_SERVERIP 10.0.0.1
+#define CONFIG_NETMASK 255.255.255.0
+#define CONFIG_IPADDR 10.0.0.110
+#define CONFIG_SERVERIP 10.0.0.1
#if defined(CONFIG_CMD_KGDB)
-#define CONFIG_KGDB_BAUDRATE 115200 /* speed to run kgdb serial port */
+/* speed to run kgdb serial port */
+#define CONFIG_KGDB_BAUDRATE 115200
/* what's this ? it's not used anywhere */
-#define CONFIG_KGDB_SER_INDEX 1 /* which serial port to use */
+#define CONFIG_KGDB_SER_INDEX 2 /* which serial port to use */
#endif
/*
* Miscellaneous configurable options
*/
-#define CONFIG_SYS_LONGHELP /* undef to save memory */
-#define CONFIG_SYS_PROMPT "VCMA9 # " /* Monitor Command Prompt */
-#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */
-#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE+sizeof(CONFIG_SYS_PROMPT)+16) /* Print Buffer Size */
-#define CONFIG_SYS_MAXARGS 16 /* max number of command args */
-#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE /* Boot Argument Buffer Size */
+#define CONFIG_SYS_LONGHELP /* undef to save memory */
+#define CONFIG_SYS_PROMPT "VCMA9 # "
+#define CONFIG_SYS_CBSIZE 256
+/* Print Buffer Size */
+#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE+sizeof(CONFIG_SYS_PROMPT)+16)
+#define CONFIG_SYS_MAXARGS 16
+/* Boot Argument Buffer Size */
+#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE
+
+#define CONFIG_DISPLAY_CPUINFO /* Display cpu info */
+#define CONFIG_DISPLAY_BOARDINFO /* Display board info */
-#define CONFIG_SYS_MEMTEST_START 0x30000000 /* memtest works on */
-#define CONFIG_SYS_MEMTEST_END 0x30F80000 /* 15.5 MB in DRAM */
+#define CONFIG_SYS_MEMTEST_START 0x30000000 /* memtest works on */
+#define CONFIG_SYS_MEMTEST_END 0x31FFFFFF /* 32 MB in DRAM */
#define CONFIG_SYS_ALT_MEMTEST
#define CONFIG_SYS_LOAD_ADDR 0x30800000 /* default load address */
-/* we configure PWM Timer 4 to 1us ~ 1MHz */
-/*#define CONFIG_SYS_HZ 1000000 */
-#define CONFIG_SYS_HZ 1562500
+/* we configure PWM Timer 4 to 1ms 1000Hz */
+#define CONFIG_SYS_HZ 1000
/* valid baudrates */
#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
-/* support BZIP2 compression */
-#define CONFIG_BZIP2 1
+/* support additional compression methods */
+#define CONFIG_BZIP2
+#define CONFIG_LZO
+#define CONFIG_LZMA
/************************************************************
* Ident
************************************************************/
/*#define VERSION_TAG "released"*/
#define VERSION_TAG "unstable"
-#define CONFIG_IDENT_STRING "\n(c) 2003 by MPL AG Switzerland, MEV-10080-001 " VERSION_TAG
+#define CONFIG_IDENT_STRING "\n(c) 2010 by MPL AG Switzerland, " \
+ "MEV-10080-001 " VERSION_TAG
/*-----------------------------------------------------------------------
* Stack sizes
*
* The stack sizes are set up in start.S using the settings below
*/
-#define CONFIG_STACKSIZE (128*1024) /* regular stack */
+#define CONFIG_STACKSIZE (128*1024) /* regular stack */
#ifdef CONFIG_USE_IRQ
-#define CONFIG_STACKSIZE_IRQ (4*1024) /* IRQ stack */
-#define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */
+#define CONFIG_STACKSIZE_IRQ (4*1024) /* IRQ stack */
+#define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */
#endif
/*-----------------------------------------------------------------------
* Physical Memory Map
*/
-#define CONFIG_NR_DRAM_BANKS 1 /* we have 1 bank of DRAM */
-#define PHYS_SDRAM_1 0x30000000 /* SDRAM Bank #1 */
-#define PHYS_FLASH_1 0x00000000 /* Flash Bank #1 */
+#define CONFIG_NR_DRAM_BANKS 1 /* we have 1 bank of DRAM */
+#define PHYS_SDRAM_1 0x30000000 /* SDRAM Bank #1 */
+#define PHYS_FLASH_1 0x00000000 /* Flash Bank #1 */
#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_1
@@ -215,36 +222,60 @@
* FLASH and environment organization
*/
-#define CONFIG_AMD_LV400 1 /* uncomment this if you have a LV400 flash */
-#if 0
-#define CONFIG_AMD_LV800 1 /* uncomment this if you have a LV800 flash */
-#endif
-
+#define CONFIG_SYS_FLASH_CFI
+#define CONFIG_FLASH_CFI_DRIVER
+#define CONFIG_FLASH_CFI_LEGACY
+#define CONFIG_SYS_FLASH_LEGACY_512Kx16
+#define CONFIG_FLASH_SHOW_PROGRESS 45
#define CONFIG_SYS_MAX_FLASH_BANKS 1 /* max number of memory banks */
-#ifdef CONFIG_AMD_LV800
-#define PHYS_FLASH_SIZE 0x00100000 /* 1MB */
-#define CONFIG_SYS_MAX_FLASH_SECT (19) /* max number of sectors on one chip */
-#define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + 0x0F0000) /* addr of environment */
-#endif
-#ifdef CONFIG_AMD_LV400
-#define PHYS_FLASH_SIZE 0x00080000 /* 512KB */
-#define CONFIG_SYS_MAX_FLASH_SECT (11) /* max number of sectors on one chip */
-#define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + 0x070000) /* addr of environment */
-#endif
+#define CONFIG_SYS_FLASH_BANKS_LIST { CONFIG_SYS_FLASH_BASE }
+#define CONFIG_SYS_MAX_FLASH_SECT (19)
-/* timeout values are in ticks */
-#define CONFIG_SYS_FLASH_ERASE_TOUT (5*CONFIG_SYS_HZ) /* Timeout for Flash Erase */
-#define CONFIG_SYS_FLASH_WRITE_TOUT (5*CONFIG_SYS_HZ) /* Timeout for Flash Write */
+/*
+ * Size of malloc() pool
+ * BZIP2 / LZO / LZMA need a lot of RAM
+ */
+#define CONFIG_SYS_MALLOC_LEN (4 * 1024 * 1024)
+#define CONFIG_SYS_MONITOR_LEN (512 * 1024)
+#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_FLASH_BASE
-#if 0
-#define CONFIG_ENV_IS_IN_FLASH 1
-#define CONFIG_ENV_SIZE 0x10000 /* Total Size of Environment Sector */
+/*
+ * NAND configuration
+ */
+#ifdef CONFIG_CMD_NAND
+#define CONFIG_NAND_S3C2410
+#define CONFIG_SYS_S3C2410_NAND_HWECC
+#define CONFIG_SYS_MAX_NAND_DEVICE 1
+#define NAND_MAX_CHIPS 1
+#define CONFIG_SYS_NAND_BASE 0x4E000000
+#define CONFIG_S3C24XX_CUSTOM_NAND_TIMING
+#define CONFIG_S3C24XX_TACLS 1
+#define CONFIG_S3C24XX_TWRPH0 5
+#define CONFIG_S3C24XX_TWRPH1 3
#endif
+#define MULTI_PURPOSE_SOCKET_ADDR 0x08000000
-#define CONFIG_SYS_JFFS2_FIRST_BANK 0
-#define CONFIG_SYS_JFFS2_NUM_BANKS 1
-
-#define MULTI_PURPOSE_SOCKET_ADDR 0x08000000
+/*
+ * File system
+ */
+#define CONFIG_CMD_FAT
+#define CONFIG_CMD_EXT2
+#define CONFIG_CMD_UBI
+#define CONFIG_CMD_UBIFS
+#define CONFIG_YAFFS2
+#define CONFIG_RBTREE
+#define CONFIG_MTD_DEVICE /* needed for mtdparts commands */
+#define CONFIG_MTD_PARTITIONS
+#define CONFIG_CMD_MTDPARTS
+#define CONFIG_LZO
+
+/* additions for new relocation code, must added to all boards */
+#undef CONFIG_SYS_ARM_WITHOUT_RELOC
+#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1
+#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + 0x1000 - \
+ GENERATED_GBL_DATA_SIZE)
+
+#define CONFIG_BOARD_EARLY_INIT_F
#endif /* __CONFIG_H */
4
23
This patch adds support for OpenCores tiny_spi.
http://opencores.org/project,tiny_spi
Signed-off-by: Thomas Chou <thomas(a)wytron.com.tw>
---
drivers/spi/Makefile | 1 +
drivers/spi/oc_tiny_spi.c | 241 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 242 insertions(+), 0 deletions(-)
create mode 100644 drivers/spi/oc_tiny_spi.c
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index e34a124..8ad1d7f 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -35,6 +35,7 @@ COBJS-$(CONFIG_KIRKWOOD_SPI) += kirkwood_spi.o
COBJS-$(CONFIG_MPC52XX_SPI) += mpc52xx_spi.o
COBJS-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o
COBJS-$(CONFIG_MXC_SPI) += mxc_spi.o
+COBJS-$(CONFIG_OC_TINY_SPI) += oc_tiny_spi.o
COBJS-$(CONFIG_OMAP3_SPI) += omap3_spi.o
COBJS-$(CONFIG_SOFT_SPI) += soft_spi.o
diff --git a/drivers/spi/oc_tiny_spi.c b/drivers/spi/oc_tiny_spi.c
new file mode 100644
index 0000000..c234d90
--- /dev/null
+++ b/drivers/spi/oc_tiny_spi.c
@@ -0,0 +1,241 @@
+/*
+ * Opencore tiny_spi driver
+ *
+ * http://opencores.org/project,tiny_spi
+ *
+ * based on bfin_spi.c
+ * Copyright (c) 2005-2008 Analog Devices Inc.
+ * Copyright (C) 2010 Thomas Chou <thomas(a)wytron.com.tw>
+ *
+ * Licensed under the GPL-2 or later.
+ */
+#include <common.h>
+#include <asm/io.h>
+#include <malloc.h>
+#include <spi.h>
+#include <asm/gpio.h>
+#define TINY_SPI_RXDATA 0
+#define TINY_SPI_TXDATA 4
+#define TINY_SPI_STATUS 8
+#define TINY_SPI_CONTROL 12
+#define TINY_SPI_BAUD 16
+
+#define TINY_SPI_STATUS_TXE 0x1
+#define TINY_SPI_STATUS_TXR 0x2
+
+struct tiny_spi_host {
+ ulong base;
+ uint freq;
+ uint baudwidth;
+};
+static struct tiny_spi_host tiny_spi_host_list[] = CONFIG_SYS_TINY_SPI_LIST;
+
+struct tiny_spi_slave {
+ struct spi_slave slave;
+ struct tiny_spi_host *host;
+ uint mode;
+ uint baud;
+ uint flg;
+};
+#define to_tiny_spi_slave(s) container_of(s, struct tiny_spi_slave, slave)
+
+__attribute__((weak))
+int spi_cs_is_valid(unsigned int bus, unsigned int cs)
+{
+ return bus < ARRAY_SIZE(tiny_spi_host_list) && gpio_is_valid(cs);
+}
+
+__attribute__((weak))
+void spi_cs_activate(struct spi_slave *slave)
+{
+ struct tiny_spi_slave *tiny_spi = to_tiny_spi_slave(slave);
+ unsigned int cs = slave->cs;
+ gpio_set_value(cs, tiny_spi->flg);
+ debug("%s: SPI_CS_GPIO:%x\n", __func__, gpio_get_value(cs));
+}
+
+__attribute__((weak))
+void spi_cs_deactivate(struct spi_slave *slave)
+{
+ struct tiny_spi_slave *tiny_spi = to_tiny_spi_slave(slave);
+ unsigned int cs = slave->cs;
+ gpio_set_value(cs, !tiny_spi->flg);
+ debug("%s: SPI_CS_GPIO:%x\n", __func__, gpio_get_value(cs));
+}
+
+void spi_set_speed(struct spi_slave *slave, uint hz)
+{
+ struct tiny_spi_slave *tiny_spi = to_tiny_spi_slave(slave);
+ struct tiny_spi_host *host = tiny_spi->host;
+ tiny_spi->baud = DIV_ROUND_UP(host->freq, hz * 2) - 1;
+ if (tiny_spi->baud > (1 << host->baudwidth) - 1)
+ tiny_spi->baud = (1 << host->baudwidth) - 1;
+ debug("%s: speed %u actual %u\n", __func__, hz,
+ host->freq / ((tiny_spi->baud + 1) * 2));
+}
+
+void spi_init(void)
+{
+}
+
+struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
+ unsigned int hz, unsigned int mode)
+{
+ struct tiny_spi_slave *tiny_spi;
+
+ if (!spi_cs_is_valid(bus, cs) || gpio_request(cs, "tiny_spi"))
+ return NULL;
+
+ tiny_spi = malloc(sizeof(*tiny_spi));
+ if (!tiny_spi)
+ return NULL;
+ memset(tiny_spi, 0, sizeof(*tiny_spi));
+
+ tiny_spi->slave.bus = bus;
+ tiny_spi->slave.cs = cs;
+ tiny_spi->host = &tiny_spi_host_list[bus];
+ tiny_spi->mode = mode & (SPI_CPOL | SPI_CPHA);
+ tiny_spi->flg = mode & SPI_CS_HIGH ? 1 : 0;
+ spi_set_speed(&tiny_spi->slave, hz);
+
+ debug("%s: bus:%i cs:%i base:%lx\n", __func__,
+ bus, cs, tiny_spi->host->base);
+ return &tiny_spi->slave;
+}
+
+void spi_free_slave(struct spi_slave *slave)
+{
+ struct tiny_spi_slave *tiny_spi = to_tiny_spi_slave(slave);
+ gpio_free(slave->cs);
+ free(tiny_spi);
+}
+
+int spi_claim_bus(struct spi_slave *slave)
+{
+ struct tiny_spi_slave *tiny_spi = to_tiny_spi_slave(slave);
+ struct tiny_spi_host *host = tiny_spi->host;
+ debug("%s: bus:%i cs:%i\n", __func__, slave->bus, slave->cs);
+ gpio_direction_output(slave->cs, !tiny_spi->flg);
+ writel(tiny_spi->mode, host->base + TINY_SPI_CONTROL);
+ writel(tiny_spi->baud, host->base + TINY_SPI_BAUD);
+ return 0;
+}
+
+void spi_release_bus(struct spi_slave *slave)
+{
+ debug("%s: bus:%i cs:%i\n", __func__, slave->bus, slave->cs);
+}
+
+#ifndef CONFIG_TINY_SPI_IDLE_VAL
+# define CONFIG_TINY_SPI_IDLE_VAL 0xff
+#endif
+
+int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
+ void *din, unsigned long flags)
+{
+ struct tiny_spi_host *host = to_tiny_spi_slave(slave)->host;
+ const u8 *txp = dout;
+ u8 *rxp = din;
+ uint bytes = bitlen / 8;
+ uint i;
+
+ debug("%s: bus:%i cs:%i bitlen:%i bytes:%i flags:%lx\n", __func__,
+ slave->bus, slave->cs, bitlen, bytes, flags);
+ if (bitlen == 0)
+ goto done;
+
+ /* assume to do 8 bits transfers */
+ if (bitlen % 8) {
+ flags |= SPI_XFER_END;
+ goto done;
+ }
+
+ if (flags & SPI_XFER_BEGIN)
+ spi_cs_activate(slave);
+
+ /* we need to tighten the transfer loop */
+ if (txp && rxp) {
+ writeb(*txp++, host->base + TINY_SPI_TXDATA);
+ if (bytes > 1) {
+ writeb(*txp++, host->base + TINY_SPI_TXDATA);
+ for (i = 2; i < bytes; i++) {
+ u8 rx, tx = *txp++;
+ while (!(readb(host->base + TINY_SPI_STATUS) &
+ TINY_SPI_STATUS_TXR))
+ ;
+ rx = readb(host->base + TINY_SPI_TXDATA);
+ writeb(tx, host->base + TINY_SPI_TXDATA);
+ *rxp++ = rx;
+ }
+ while (!(readb(host->base + TINY_SPI_STATUS) &
+ TINY_SPI_STATUS_TXR))
+ ;
+ *rxp++ = readb(host->base + TINY_SPI_TXDATA);
+ }
+ while (!(readb(host->base + TINY_SPI_STATUS) &
+ TINY_SPI_STATUS_TXE))
+ ;
+ *rxp++ = readb(host->base + TINY_SPI_RXDATA);
+ } else if (rxp) {
+ writeb(CONFIG_TINY_SPI_IDLE_VAL, host->base + TINY_SPI_TXDATA);
+ if (bytes > 1) {
+ writeb(CONFIG_TINY_SPI_IDLE_VAL,
+ host->base + TINY_SPI_TXDATA);
+ for (i = 2; i < bytes; i++) {
+ u8 rx;
+ while (!(readb(host->base + TINY_SPI_STATUS) &
+ TINY_SPI_STATUS_TXR))
+ ;
+ rx = readb(host->base + TINY_SPI_TXDATA);
+ writeb(CONFIG_TINY_SPI_IDLE_VAL,
+ host->base + TINY_SPI_TXDATA);
+ *rxp++ = rx;
+ }
+ while (!(readb(host->base + TINY_SPI_STATUS) &
+ TINY_SPI_STATUS_TXR))
+ ;
+ *rxp++ = readb(host->base + TINY_SPI_TXDATA);
+ }
+ while (!(readb(host->base + TINY_SPI_STATUS) &
+ TINY_SPI_STATUS_TXE))
+ ;
+ *rxp++ = readb(host->base + TINY_SPI_RXDATA);
+ } else if (txp) {
+ writeb(*txp++, host->base + TINY_SPI_TXDATA);
+ if (bytes > 1) {
+ writeb(*txp++, host->base + TINY_SPI_TXDATA);
+ for (i = 2; i < bytes; i++) {
+ u8 tx = *txp++;
+ while (!(readb(host->base + TINY_SPI_STATUS) &
+ TINY_SPI_STATUS_TXR))
+ ;
+ writeb(tx, host->base + TINY_SPI_TXDATA);
+ }
+ }
+ while (!(readb(host->base + TINY_SPI_STATUS) &
+ TINY_SPI_STATUS_TXE))
+ ;
+ } else {
+ writeb(CONFIG_TINY_SPI_IDLE_VAL, host->base + TINY_SPI_TXDATA);
+ if (bytes > 1) {
+ writeb(CONFIG_TINY_SPI_IDLE_VAL,
+ host->base + TINY_SPI_TXDATA);
+ for (i = 2; i < bytes; i++) {
+ while (!(readb(host->base + TINY_SPI_STATUS) &
+ TINY_SPI_STATUS_TXR))
+ ;
+ writeb(CONFIG_TINY_SPI_IDLE_VAL,
+ host->base + TINY_SPI_TXDATA);
+ }
+ }
+ while (!(readb(host->base + TINY_SPI_STATUS) &
+ TINY_SPI_STATUS_TXE))
+ ;
+ }
+
+ done:
+ if (flags & SPI_XFER_END)
+ spi_cs_deactivate(slave);
+
+ return 0;
+}
--
1.7.3.4
3
8
From: Roberto Cerati <roberto.cerati(a)bticino.it>
The device interface is 16 bits wide.
All the available packets are read from the incoming fifo.
Signed-off-by: Roberto Cerati <roberto.cerati(a)bticino.it
Signed-off-by: Raffaele Recalcati <raffaele.recalcati(a)bticino.it>
---
This driver has been adapted to u-boot starting from ks8851_mll linux driver.
The smsc911x u-boot has been used as reference.
TODO: smsc911x reads only one packet from incoming fifo, ks8851_mll reads all packets
in the incoming fifo, but it is not checked if upper driver level (net/eth.c ?) manages more than
one packet.
This driver has been tested against u-boot-2009.11-psp03.00.01.06
u-boot version present in ti-dvsdk_dm3730-evm_4_01_00_09 DVSDK.
The board name is baia and is based on dm3730 soc adapted from
evm-dm3730 Ti board.
drivers/net/Makefile | 1 +
drivers/net/ks8851_mll.c | 708 ++++++++++++++++++++++++++++++++++++++++++++++
drivers/net/ks8851_mll.h | 358 +++++++++++++++++++++++
3 files changed, 1067 insertions(+), 0 deletions(-)
create mode 100644 drivers/net/ks8851_mll.c
create mode 100644 drivers/net/ks8851_mll.h
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index fd9d0b4..ed69090 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -84,6 +84,7 @@ COBJS-$(CONFIG_TSI108_ETH) += tsi108_eth.o
COBJS-$(CONFIG_ULI526X) += uli526x.o
COBJS-$(CONFIG_VSC7385_ENET) += vsc7385.o
COBJS-$(CONFIG_XILINX_EMACLITE) += xilinx_emaclite.o
+COBJS-$(CONFIG_KS8851_MLL) += ks8851_mll.o
COBJS := $(sort $(COBJS-y))
SRCS := $(COBJS:.o=.c)
diff --git a/drivers/net/ks8851_mll.c b/drivers/net/ks8851_mll.c
new file mode 100644
index 0000000..b1560cc
--- /dev/null
+++ b/drivers/net/ks8851_mll.c
@@ -0,0 +1,708 @@
+/*
+ * Micrel KS8851_MLL 16bit Network driver
+ * Copyright (c) 2011 Roberto Cerati <roberto.cerati(a)bticino.it>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <common.h>
+#include <command.h>
+#include <malloc.h>
+#include <net.h>
+#include <miiphy.h>
+
+#include "ks8851_mll.h"
+
+#define MAX_RECV_FRAMES 32
+#define MAX_BUF_SIZE 2048
+#define TX_BUF_SIZE 2000
+#define RX_BUF_SIZE 2000
+
+#define KS_CCR 0x08
+#define CCR_EEPROM (1 << 9)
+#define CCR_SPI (1 << 8)
+#define CCR_8BIT (1 << 7)
+#define CCR_16BIT (1 << 6)
+#define CCR_32BIT (1 << 5)
+#define CCR_SHARED (1 << 4)
+#define CCR_32PIN (1 << 0)
+
+/*
+ * union ks_tx_hdr - tx header data
+ * @txb: The header as bytes
+ * @txw: The header as 16bit, little-endian words
+ *
+ * A dual representation of the tx header data to allow
+ * access to individual bytes, and to allow 16bit accesses
+ * with 16bit alignment.
+ */
+union ks_tx_hdr {
+ u8 txb[4];
+ __le16 txw[2];
+};
+
+/*
+ * struct ks_net - KS8851 driver private data
+ * @net_device : The network device we're bound to
+ * @txh : temporaly buffer to save status/length.
+ * @frame_head_info : frame header information for multi-pkt rx.
+ * @statelock : Lock on this structure for tx list.
+ * @msg_enable : The message flags controlling driver output (see ethtool).
+ * @frame_cnt : number of frames received.
+ * @bus_width : i/o bus width.
+ * @irq : irq number assigned to this device.
+ * @rc_rxqcr : Cached copy of KS_RXQCR.
+ * @rc_txcr : Cached copy of KS_TXCR.
+ * @rc_ier : Cached copy of KS_IER.
+ * @sharedbus : Multipex(addr and data bus) mode indicator.
+ * @cmd_reg_cache : command register cached.
+ * @cmd_reg_cache_int : command register cached. Used in the irq handler.
+ * @promiscuous : promiscuous mode indicator.
+ * @all_mcast : mutlicast indicator.
+ * @mcast_lst_size : size of multicast list.
+ * @mcast_lst : multicast list.
+ * @mcast_bits : multicast enabed.
+ * @mac_addr : MAC address assigned to this device.
+ * @fid : frame id.
+ * @extra_byte : number of extra byte prepended rx pkt.
+ * @enabled : indicator this device works.
+ *
+ */
+
+/* Receive multiplex framer header info */
+struct type_frame_head {
+ u16 sts; /* Frame status */
+ u16 len; /* Byte count */
+} fr_h_i[MAX_RECV_FRAMES];
+
+struct ks_net {
+ struct net_device *netdev;
+ union ks_tx_hdr txh;
+ struct type_frame_head *frame_head_info;
+ u32 msg_enable;
+ u32 frame_cnt;
+ int bus_width;
+ int irq;
+
+ u16 rc_rxqcr;
+ u16 rc_txcr;
+ u16 rc_ier;
+ u16 sharedbus;
+ u16 cmd_reg_cache;
+ u16 cmd_reg_cache_int;
+ u16 promiscuous;
+ u16 all_mcast;
+ u16 mcast_lst_size;
+ u8 mcast_lst[MAX_MCAST_LST][MAC_ADDR_LEN];
+ u8 mcast_bits[HW_MCAST_SIZE];
+ u8 mac_addr[6];
+ u8 fid;
+ u8 extra_byte;
+ u8 enabled;
+} ks_str, *ks;
+
+#define BE3 0x8000 /* Byte Enable 3 */
+#define BE2 0x4000 /* Byte Enable 2 */
+#define BE1 0x2000 /* Byte Enable 1 */
+#define BE0 0x1000 /* Byte Enable 0 */
+
+#define mdelay(n) udelay((n)*1000)
+
+static u8 ks_rdreg8(struct eth_device *dev, u16 offset)
+{
+ volatile u16 *hw_addr = (u16 *)(dev->iobase);
+ volatile u16 *hw_addr_cmd = (u16 *)(dev->iobase + 2);
+
+ u16 data;
+
+ u8 shift_bit = offset & 0x03;
+ u8 shift_data = (offset & 1) << 3;
+
+ *hw_addr_cmd = offset | (u16)(BE0 << shift_bit);
+
+ data = *hw_addr;
+ return (u8)(data >> shift_data);
+}
+
+static u16 ks_rdreg16(struct eth_device *dev, u16 offset)
+{
+ volatile u16 *hw_addr = (u16 *)(dev->iobase);
+ volatile u16 *hw_addr_cmd = (u16 *)(dev->iobase + 2);
+
+ *hw_addr_cmd = offset | ((BE1 | BE0) << (offset & 0x02));
+
+ return *hw_addr;
+}
+
+static void ks_wrreg8(struct eth_device *dev, u16 offset, u8 val)
+{
+ volatile u16 *hw_addr = (u16 *)(dev->iobase);
+ volatile u16 *hw_addr_cmd = (u16 *)(dev->iobase + 2);
+
+ u8 shift_bit = (offset & 0x03);
+ u16 value_write = (u16)(val << ((offset & 1) << 3));
+
+ *hw_addr_cmd = (u16)offset | (BE0 << shift_bit);
+ *hw_addr = value_write;
+}
+
+static void ks_wrreg16(struct eth_device *dev, u16 offset, u16 val)
+{
+ volatile u16 *hw_addr = (u16 *)(dev->iobase);
+ volatile u16 *hw_addr_cmd = (u16 *)(dev->iobase + 2);
+
+ *hw_addr_cmd = offset | ((BE1 | BE0) << (offset & 0x02));
+ *hw_addr = val;
+}
+
+/*
+ * ks_inblk - read a block of data from QMU. This is called after sudo DMA mode
+ * enabled.
+ * @ks: The chip state
+ * @wptr: buffer address to save data
+ * @len: length in byte to read
+ *
+ */
+static inline void ks_inblk(struct eth_device *dev, u16 *wptr, u32 len)
+{
+ volatile u16 *hw_addr = (u16 *)(dev->iobase);
+ u16 tmp;
+ len >>= 1;
+ while (len--)
+ *wptr++ = *hw_addr;
+}
+
+/*
+ * ks_outblk - write data to QMU. This is called after sudo DMA mode enabled.
+ * @ks: The chip information
+ * @wptr: buffer address
+ * @len: length in byte to write
+ *
+ */
+static inline void ks_outblk(struct eth_device *dev, u16 *wptr, u32 len)
+{
+ volatile u16 *hw_addr = (u16 *)(dev->iobase);
+ len >>= 1;
+ while (len--)
+ *hw_addr = *wptr++;
+}
+
+static void ks_disable_int(struct eth_device *dev)
+{
+ ks_wrreg16(dev, KS_IER, 0x0000);
+}
+
+static void ks_enable_int(struct eth_device *dev)
+{
+ ks_wrreg16(dev, KS_IER, ks->rc_ier);
+}
+
+static void ks_set_powermode(struct eth_device *dev, unsigned pwrmode)
+{
+ unsigned pmecr;
+
+ ks_rdreg16(dev, KS_GRR);
+ pmecr = ks_rdreg16(dev, KS_PMECR);
+ pmecr &= ~PMECR_PM_MASK;
+ pmecr |= pwrmode;
+
+ ks_wrreg16(dev, KS_PMECR, pmecr);
+}
+
+/*
+ * ks_read_config - read chip configuration of bus width.
+ * @ks: The chip information
+ *
+ */
+static void ks_read_config(struct eth_device *dev)
+{
+ u16 reg_data = 0;
+
+ /* Regardless of bus width, 8 bit read should always work.*/
+ reg_data = ks_rdreg8(dev, KS_CCR) & 0x00FF;
+ reg_data |= ks_rdreg8(dev, KS_CCR+1) << 8;
+
+ /* addr/data bus are multiplexed */
+ ks->sharedbus = (reg_data & CCR_SHARED) == CCR_SHARED;
+
+ /*
+ * There are garbage data when reading data from QMU,
+ * depending on bus-width.
+ */
+ if (reg_data & CCR_8BIT) {
+ ks->bus_width = ENUM_BUS_8BIT;
+ ks->extra_byte = 1;
+ } else if (reg_data & CCR_16BIT) {
+ ks->bus_width = ENUM_BUS_16BIT;
+ ks->extra_byte = 2;
+ } else {
+ ks->bus_width = ENUM_BUS_32BIT;
+ ks->extra_byte = 4;
+ }
+}
+
+/*
+ * ks_soft_reset - issue one of the soft reset to the device
+ * @ks: The device state.
+ * @op: The bit(s) to set in the GRR
+ *
+ * Issue the relevant soft-reset command to the device's GRR register
+ * specified by @op.
+ *
+ * Note, the delays are in there as a caution to ensure that the reset
+ * has time to take effect and then complete. Since the datasheet does
+ * not currently specify the exact sequence, we have chosen something
+ * that seems to work with our device.
+ */
+static void ks_soft_reset(struct eth_device *dev, unsigned op)
+{
+ /* Disable interrupt first */
+ ks_wrreg16(dev, KS_IER, 0x0000);
+ ks_wrreg16(dev, KS_GRR, op);
+ mdelay(10); /* wait a short time to effect reset */
+ ks_wrreg16(dev, KS_GRR, 0);
+ mdelay(1); /* wait for condition to clear */
+}
+
+void ks_enable_qmu(struct eth_device *dev)
+{
+ u16 w;
+
+ w = ks_rdreg16(dev, KS_TXCR);
+
+ /* Enables QMU Transmit (TXCR). */
+ ks_wrreg16(dev, KS_TXCR, w | TXCR_TXE);
+
+ /*
+ * RX Frame Count Threshold Enable and Auto-Dequeue RXQ Frame
+ * Enable
+ */
+ w = ks_rdreg16(dev, KS_RXQCR);
+ ks_wrreg16(dev, KS_RXQCR, w | RXQCR_RXFCTE);
+
+ /* Enables QMU Receive (RXCR1). */
+ w = ks_rdreg16(dev, KS_RXCR1);
+ ks_wrreg16(dev, KS_RXCR1, w | RXCR1_RXE);
+}
+
+static void ks_disable_qmu(struct eth_device *dev)
+{
+ u16 w;
+
+ w = ks_rdreg16(dev, KS_TXCR);
+
+ /* Disables QMU Transmit (TXCR). */
+ w &= ~TXCR_TXE;
+ ks_wrreg16(dev, KS_TXCR, w);
+
+ /* Disables QMU Receive (RXCR1). */
+ w = ks_rdreg16(dev, KS_RXCR1);
+ w &= ~RXCR1_RXE ;
+ ks_wrreg16(dev, KS_RXCR1, w);
+
+}
+
+static inline void ks_read_qmu(struct eth_device *dev, u16 *buf, u32 len)
+{
+ u32 r = ks->extra_byte & 0x1 ;
+ u32 w = ks->extra_byte - r;
+
+ /* 1. set sudo DMA mode */
+ ks_wrreg16(dev, KS_RXFDPR, RXFDPR_RXFPAI);
+ ks_wrreg8(dev, KS_RXQCR, (ks->rc_rxqcr | RXQCR_SDA) & 0xff);
+
+ /*
+ * 2. read prepend data
+ *
+ * read 4 + extra bytes and discard them.
+ * extra bytes for dummy, 2 for status, 2 for len
+ */
+
+ if ((r))
+ ks_rdreg8(dev, 0);
+
+ ks_inblk(dev, buf, w + 2 + 2);
+
+ /* 3. read pkt data */
+ ks_inblk(dev, buf, ALIGN(len, 4));
+
+ /* 4. reset sudo DMA Mode */
+ ks_wrreg8(dev, KS_RXQCR, ks->rc_rxqcr);
+}
+
+static void ks_rcv(struct eth_device *dev, uchar **pv_data)
+{
+ u32 i;
+ struct type_frame_head *frame_hdr = ks->frame_head_info;
+
+ ks->frame_cnt = ks_rdreg16(dev, KS_RXFCTR) >> 8;
+
+ /* read all header information */
+ for (i = 0; i < ks->frame_cnt; i++) {
+ /* Checking Received packet status */
+ frame_hdr->sts = ks_rdreg16(dev, KS_RXFHSR);
+ /* Get packet len from hardware */
+ frame_hdr->len = ks_rdreg16(dev, KS_RXFHBCR);
+ frame_hdr++;
+ }
+
+ frame_hdr = ks->frame_head_info;
+ while (ks->frame_cnt--) {
+ if ((frame_hdr->sts & RXFSHR_RXFV) &&
+ (frame_hdr->len < RX_BUF_SIZE) && frame_hdr->len) {
+
+ /* read data block including CRC 4 bytes */
+ ks_read_qmu(dev, (u16 *)(*pv_data), frame_hdr->len);
+
+ /* NetRxPackets buffer size is ok (*pv_data pointer) */
+ NetReceive(*pv_data, frame_hdr->len);
+ pv_data++;
+ } else {
+ ks_wrreg16(dev, KS_RXQCR, (ks->rc_rxqcr | RXQCR_RRXEF));
+ printf(DRIVERNAME
+ ": bad packet. \n");
+ }
+ frame_hdr++;
+ }
+}
+
+/*
+ * ks_read_selftest - read the selftest memory info.
+ * @ks: The device state
+ *
+ * Read and check the TX/RX memory selftest information.
+ */
+static int ks_read_selftest(struct eth_device *dev)
+{
+ unsigned both_done = MBIR_TXMBF | MBIR_RXMBF;
+ int ret = 0;
+ unsigned rd;
+
+ rd = ks_rdreg16(dev, KS_MBIR);
+
+ if ((rd & both_done) != both_done) {
+ printf(DRIVERNAME ": Memory selftest not finished\n");
+ return 0;
+ }
+
+ if (rd & MBIR_TXMBFA) {
+ printf(DRIVERNAME ": TX memory selftest fails\n");
+ ret |= 1;
+ }
+
+ if (rd & MBIR_RXMBFA) {
+ printf(DRIVERNAME ": RX memory selftest fails\n");
+ ret |= 2;
+ }
+
+ printf(DRIVERNAME ": the selftest passes\n");
+ return ret;
+}
+
+static void ks_setup(struct eth_device *dev)
+{
+ u16 w;
+
+ /*
+ * Configure QMU Transmit
+ */
+
+ /* Setup Transmit Frame Data Pointer Auto-Increment (TXFDPR) */
+ ks_wrreg16(dev, KS_TXFDPR, TXFDPR_TXFPAI);
+
+ /* Setup Receive Frame Data Pointer Auto-Increment */
+ ks_wrreg16(dev, KS_RXFDPR, RXFDPR_RXFPAI);
+
+ /* Setup Receive Frame Threshold - 1 frame (RXFCTFC) */
+ ks_wrreg16(dev, KS_RXFCTR, 1 & RXFCTR_THRESHOLD_MASK);
+
+ /* Setup RxQ Command Control (RXQCR) */
+ ks->rc_rxqcr = RXQCR_CMD_CNTL;
+ ks_wrreg16(dev, KS_RXQCR, ks->rc_rxqcr);
+
+ /*
+ * set the force mode to half duplex, default is full duplex
+ * because if the auto-negotiation fails, most switch uses
+ * half-duplex.
+ */
+ w = ks_rdreg16(dev, KS_P1MBCR);
+ w &= ~P1MBCR_FORCE_FDX;
+ ks_wrreg16(dev, KS_P1MBCR, w);
+
+ w = TXCR_TXFCE | TXCR_TXPE | TXCR_TXCRC | TXCR_TCGIP;
+ ks_wrreg16(dev, KS_TXCR, w);
+
+ w = RXCR1_RXFCE | RXCR1_RXBE | RXCR1_RXUE | RXCR1_RXME | RXCR1_RXIPFCC;
+
+ /* Normal mode */
+ w |= RXCR1_RXPAFMA;
+
+ ks_wrreg16(dev, KS_RXCR1, w);
+}
+
+static void ks_setup_int(struct eth_device *dev)
+{
+ ks->rc_ier = 0x00;
+
+ /* Clear the interrupts status of the hardware. */
+ ks_wrreg16(dev, KS_ISR, 0xffff);
+
+ /* Enables the interrupts of the hardware. */
+ ks->rc_ier = (IRQ_LCI | IRQ_TXI | IRQ_RXI);
+}
+
+static int ks8851_mll_detect_chip(struct eth_device *dev)
+{
+ unsigned short val, i;
+
+ ks_read_config(dev);
+
+ if (ks->bus_width == ENUM_BUS_16BIT)
+ printf(DRIVERNAME ": ENUM_BUS_16BIT\n");
+ else
+ printf(DRIVERNAME ": no 16 bit bus\n");
+
+
+ val = ks_rdreg16(dev, KS_CIDER);
+
+ if (val == 0xffff) {
+ /* Special case -- no chip present */
+ printf(DRIVERNAME ": is chip mounted ?\n");
+ return -1;
+ } else if ((val & 0xfff0) != CIDER_ID) {
+ printf(DRIVERNAME ": Invalid chip id 0x%04lx\n", val);
+ return -1;
+ }
+
+ printf("Read back KS8851 id 0x%x\n", val);
+
+ /* only one entry in the table */
+ val &= 0xfff0;
+ for (i = 0; chip_ids[i].id != 0; i++) {
+ if (chip_ids[i].id == val)
+ break;
+ }
+ if (!chip_ids[i].id) {
+ printf(DRIVERNAME ": Unknown chip ID %04x\n", val);
+ return -1;
+ }
+
+ dev->priv = (void *)&chip_ids[i];
+
+ return 0;
+}
+
+static void ks8851_mll_reset(struct eth_device *dev)
+{
+ /* wake up powermode to normal mode */
+ ks_set_powermode(dev, PMECR_PM_NORMAL);
+ mdelay(1); /* wait for normal mode to take effect */
+
+ /* Disable interrupt and reset */
+ ks_soft_reset(dev, GRR_GSR);
+
+ /* turn off the IRQs and ack any outstanding */
+ ks_wrreg16(dev, KS_IER, 0x0000);
+ ks_wrreg16(dev, KS_ISR, 0xffff);
+
+ /* shutdown RX/TX QMU */
+ ks_disable_qmu(dev);
+}
+
+static void ks8851_mll_handle_mac_address(struct eth_device *dev)
+{
+ u16 addrh, addrm, addrl;
+ uchar *m = dev->enetaddr;
+
+ addrh = m[1] | (m[0] << 8);
+ addrm = m[3] | (m[2] << 8);
+ addrl = m[5] | (m[4] << 8);
+
+ ks_wrreg16(dev, KS_MARH, addrh);
+ ks_wrreg16(dev, KS_MARM, addrm);
+ ks_wrreg16(dev, KS_MARL, addrl);
+
+ printf(DRIVERNAME ": MAC %pM\n", m);
+}
+
+static void ks8851_mll_phy_configure(struct eth_device *dev)
+{
+ ks_setup(dev);
+ ks_setup_int(dev);
+ u16 data;
+
+ /* Probing the phy */
+ data = ks_rdreg16(dev, KS_OBCR);
+ ks_wrreg16(dev, KS_OBCR, data | OBCR_ODS_16MA);
+
+ printf(DRIVERNAME ": phy initialized\n");
+}
+
+
+static void ks8851_mll_enable(struct eth_device *dev)
+{
+ ks_wrreg16(dev, KS_ISR, 0xffff);
+ ks_enable_int(dev);
+ ks_enable_qmu(dev);
+}
+
+static int ks8851_mll_init(struct eth_device *dev, bd_t * bd)
+{
+ struct chip_id *id = dev->priv;
+
+ printf(DRIVERNAME ": detected %s controller\n", id->name);
+
+ if (ks_read_selftest(dev)) {
+ printf(DRIVERNAME ": Selftest failed\n");
+ return -1;
+ }
+
+ ks8851_mll_reset(dev);
+
+ /* Configure the PHY, initialize the link state */
+ ks8851_mll_phy_configure(dev);
+
+ /* static allocation of private informations */
+ ks->frame_head_info = fr_h_i;
+
+ ks8851_mll_handle_mac_address(dev);
+
+ /* Turn on Tx + Rx */
+ ks8851_mll_enable(dev);
+
+ return 0;
+}
+
+static void ks_write_qmu(struct eth_device *dev, u8 *pdata, u16 len)
+{
+ /* start header at txb[0] to align txw entries */
+ ks->txh.txw[0] = 0;
+ ks->txh.txw[1] = cpu_to_le16(len);
+
+ /* 1. set sudo-DMA mode */
+ ks_wrreg8(dev, KS_RXQCR, (ks->rc_rxqcr | RXQCR_SDA) & 0xff);
+ /* 2. write status/lenth info */
+ ks_outblk(dev, ks->txh.txw, 4);
+ /* 3. write pkt data */
+ ks_outblk(dev, (u16 *)pdata, ALIGN(len, 4));
+ /* 4. reset sudo-DMA mode */
+ ks_wrreg8(dev, KS_RXQCR, ks->rc_rxqcr);
+ /* 5. Enqueue Tx(move the pkt from TX buffer into TXQ) */
+ ks_wrreg16(dev, KS_TXQCR, TXQCR_METFE);
+ /* 6. wait until TXQCR_METFE is auto-cleared */
+ while (ks_rdreg16(dev, KS_TXQCR) & TXQCR_METFE)
+ ;
+}
+
+static int ks8851_mll_send(struct eth_device *dev,
+ volatile void *packet, int length)
+{
+ u8 *data = (u8 *)packet;
+ u16 tmplen = (u16) length;
+ u32 status = 0;
+
+ u16 retv;
+
+ /*
+ * Extra space are required:
+ * 4 byte for alignment, 4 for status/length, 4 for CRC
+ */
+ retv = ks_rdreg16(dev, KS_TXMIR) & 0x1fff;
+ if (retv >= tmplen + 12)
+ ks_write_qmu(dev, data, tmplen);
+ else
+ status = 1;
+
+ if (!status)
+ return 0;
+
+ printf(DRIVERNAME ": failed to send packet: %s%s\n",
+ status & 1 ? "No buffer " : "",
+ status & 2 ? "Other error" : "");
+
+ return -1;
+}
+
+static void ks8851_mll_halt(struct eth_device *dev)
+{
+ ks8851_mll_reset(dev);
+}
+
+/*
+ * Maximum receive ring size; that is, the number of packets
+ * we can buffer before overflow happens. Basically, this just
+ * needs to be enough to prevent a packet being discarded while
+ * we are processing the previous one.
+ */
+static int ks8851_mll_rx(struct eth_device *dev)
+{
+ u16 status;
+
+ status = ks_rdreg16(dev, KS_ISR);
+
+ ks_wrreg16(dev, KS_ISR, status);
+
+ if ((status & IRQ_RXI))
+ ks_rcv(dev, (uchar **)NetRxPackets);
+
+ if ((status & IRQ_LDI)) {
+ u16 pmecr = ks_rdreg16(dev, KS_PMECR);
+ pmecr &= ~PMECR_WKEVT_MASK;
+ ks_wrreg16(dev, KS_PMECR, pmecr | PMECR_WKEVT_LINK);
+ }
+
+ return 0;
+}
+
+int ks8851_mll_register(u8 dev_num, int base_addr)
+{
+ unsigned short addrl, addrm, addrh;
+ struct eth_device *dev;
+
+ dev = malloc(sizeof(*dev));
+ if (!dev) {
+ free(dev);
+ return -1;
+ }
+ memset(dev, 0, sizeof(*dev));
+
+ dev->iobase = base_addr;
+
+ ks = &ks_str;
+
+ /* Try to detect chip. Will fail if not present. */
+ if (ks8851_mll_detect_chip(dev)) {
+ free(dev);
+ return 0;
+ }
+
+ addrh = ks_rdreg16(dev, KS_MARH);
+ addrm = ks_rdreg16(dev, KS_MARM);
+ addrl = ks_rdreg16(dev, KS_MARL);
+ dev->enetaddr[0] = addrh >> 8;
+ dev->enetaddr[1] = addrh;
+ dev->enetaddr[2] = addrm >> 8;
+ dev->enetaddr[3] = addrm;
+ dev->enetaddr[4] = addrl >> 8;
+ dev->enetaddr[5] = addrl;
+
+ dev->init = ks8851_mll_init;
+ dev->halt = ks8851_mll_halt;
+ dev->send = ks8851_mll_send;
+ dev->recv = ks8851_mll_rx;
+ sprintf(dev->name, "%s-%hu", DRIVERNAME, dev_num);
+
+ eth_register(dev);
+ return 1;
+}
diff --git a/drivers/net/ks8851_mll.h b/drivers/net/ks8851_mll.h
new file mode 100644
index 0000000..0a1d2d3
--- /dev/null
+++ b/drivers/net/ks8851_mll.h
@@ -0,0 +1,358 @@
+/**
+ * drivers/net/ks8851_mll.c
+ * Copyright (c) 2009 Micrel Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/*
+ * modified by
+ * (c) 2011 Bticino s.p.a, Roberto Cerati <roberto.cerati(a)bticino.it>
+ */
+/**
+ * Supports:
+ * KS8851 16bit MLL chip from Micrel Inc.
+ */
+#ifndef _KS8851_MLL_H_
+#define _KS8851_MLL_H_
+
+#include <linux/types.h>
+
+#define DRIVERNAME "ks8851_mll"
+
+/* MAC address registers */
+#define KS_MARL 0x10
+#define KS_MARM 0x12
+#define KS_MARH 0x14
+
+#define KS_OBCR 0x20
+#define OBCR_ODS_16MA (1 << 6)
+
+#define KS_EEPCR 0x22
+#define EEPCR_EESA (1 << 4)
+#define EEPCR_EESB (1 << 3)
+#define EEPCR_EEDO (1 << 2)
+#define EEPCR_EESCK (1 << 1)
+#define EEPCR_EECS (1 << 0)
+
+#define KS_MBIR 0x24
+#define MBIR_TXMBF (1 << 12)
+#define MBIR_TXMBFA (1 << 11)
+#define MBIR_RXMBF (1 << 4)
+#define MBIR_RXMBFA (1 << 3)
+
+#define KS_GRR 0x26
+#define GRR_QMU (1 << 1)
+#define GRR_GSR (1 << 0)
+
+#define KS_WFCR 0x2A
+#define WFCR_MPRXE (1 << 7)
+#define WFCR_WF3E (1 << 3)
+#define WFCR_WF2E (1 << 2)
+#define WFCR_WF1E (1 << 1)
+#define WFCR_WF0E (1 << 0)
+
+#define KS_WF0CRC0 0x30
+#define KS_WF0CRC1 0x32
+#define KS_WF0BM0 0x34
+#define KS_WF0BM1 0x36
+#define KS_WF0BM2 0x38
+#define KS_WF0BM3 0x3A
+
+#define KS_WF1CRC0 0x40
+#define KS_WF1CRC1 0x42
+#define KS_WF1BM0 0x44
+#define KS_WF1BM1 0x46
+#define KS_WF1BM2 0x48
+#define KS_WF1BM3 0x4A
+
+#define KS_WF2CRC0 0x50
+#define KS_WF2CRC1 0x52
+#define KS_WF2BM0 0x54
+#define KS_WF2BM1 0x56
+#define KS_WF2BM2 0x58
+#define KS_WF2BM3 0x5A
+
+#define KS_WF3CRC0 0x60
+#define KS_WF3CRC1 0x62
+#define KS_WF3BM0 0x64
+#define KS_WF3BM1 0x66
+#define KS_WF3BM2 0x68
+#define KS_WF3BM3 0x6A
+
+#define KS_TXCR 0x70
+#define TXCR_TCGICMP (1 << 8)
+#define TXCR_TCGUDP (1 << 7)
+#define TXCR_TCGTCP (1 << 6)
+#define TXCR_TCGIP (1 << 5)
+#define TXCR_FTXQ (1 << 4)
+#define TXCR_TXFCE (1 << 3)
+#define TXCR_TXPE (1 << 2)
+#define TXCR_TXCRC (1 << 1)
+#define TXCR_TXE (1 << 0)
+
+#define KS_TXSR 0x72
+#define TXSR_TXLC (1 << 13)
+#define TXSR_TXMC (1 << 12)
+#define TXSR_TXFID_MASK (0x3f << 0)
+#define TXSR_TXFID_SHIFT (0)
+#define TXSR_TXFID_GET(_v) (((_v) >> 0) & 0x3f)
+
+
+#define KS_RXCR1 0x74
+#define RXCR1_FRXQ (1 << 15)
+#define RXCR1_RXUDPFCC (1 << 14)
+#define RXCR1_RXTCPFCC (1 << 13)
+#define RXCR1_RXIPFCC (1 << 12)
+#define RXCR1_RXPAFMA (1 << 11)
+#define RXCR1_RXFCE (1 << 10)
+#define RXCR1_RXEFE (1 << 9)
+#define RXCR1_RXMAFMA (1 << 8)
+#define RXCR1_RXBE (1 << 7)
+#define RXCR1_RXME (1 << 6)
+#define RXCR1_RXUE (1 << 5)
+#define RXCR1_RXAE (1 << 4)
+#define RXCR1_RXINVF (1 << 1)
+#define RXCR1_RXE (1 << 0)
+#define RXCR1_FILTER_MASK (RXCR1_RXINVF | RXCR1_RXAE | \
+ RXCR1_RXMAFMA | RXCR1_RXPAFMA)
+
+#define KS_RXCR2 0x76
+#define RXCR2_SRDBL_MASK (0x7 << 5)
+#define RXCR2_SRDBL_SHIFT (5)
+#define RXCR2_SRDBL_4B (0x0 << 5)
+#define RXCR2_SRDBL_8B (0x1 << 5)
+#define RXCR2_SRDBL_16B (0x2 << 5)
+#define RXCR2_SRDBL_32B (0x3 << 5)
+/* #define RXCR2_SRDBL_FRAME (0x4 << 5) */
+#define RXCR2_IUFFP (1 << 4)
+#define RXCR2_RXIUFCEZ (1 << 3)
+#define RXCR2_UDPLFE (1 << 2)
+#define RXCR2_RXICMPFCC (1 << 1)
+#define RXCR2_RXSAF (1 << 0)
+
+#define KS_TXMIR 0x78
+
+#define KS_RXFHSR 0x7C
+#define RXFSHR_RXFV (1 << 15)
+#define RXFSHR_RXICMPFCS (1 << 13)
+#define RXFSHR_RXIPFCS (1 << 12)
+#define RXFSHR_RXTCPFCS (1 << 11)
+#define RXFSHR_RXUDPFCS (1 << 10)
+#define RXFSHR_RXBF (1 << 7)
+#define RXFSHR_RXMF (1 << 6)
+#define RXFSHR_RXUF (1 << 5)
+#define RXFSHR_RXMR (1 << 4)
+#define RXFSHR_RXFT (1 << 3)
+#define RXFSHR_RXFTL (1 << 2)
+#define RXFSHR_RXRF (1 << 1)
+#define RXFSHR_RXCE (1 << 0)
+#define RXFSHR_ERR (RXFSHR_RXCE | RXFSHR_RXRF |\
+ RXFSHR_RXFTL | RXFSHR_RXMR |\
+ RXFSHR_RXICMPFCS | RXFSHR_RXIPFCS |\
+ RXFSHR_RXTCPFCS)
+#define KS_RXFHBCR 0x7E
+#define RXFHBCR_CNT_MASK 0x0FFF
+
+#define KS_TXQCR 0x80
+#define TXQCR_AETFE (1 << 2)
+#define TXQCR_TXQMAM (1 << 1)
+#define TXQCR_METFE (1 << 0)
+
+#define KS_RXQCR 0x82
+#define RXQCR_RXDTTS (1 << 12)
+#define RXQCR_RXDBCTS (1 << 11)
+#define RXQCR_RXFCTS (1 << 10)
+#define RXQCR_RXIPHTOE (1 << 9)
+#define RXQCR_RXDTTE (1 << 7)
+#define RXQCR_RXDBCTE (1 << 6)
+#define RXQCR_RXFCTE (1 << 5)
+#define RXQCR_ADRFE (1 << 4)
+#define RXQCR_SDA (1 << 3)
+#define RXQCR_RRXEF (1 << 0)
+#define RXQCR_CMD_CNTL (RXQCR_RXFCTE|RXQCR_ADRFE)
+
+#define KS_TXFDPR 0x84
+#define TXFDPR_TXFPAI (1 << 14)
+#define TXFDPR_TXFP_MASK (0x7ff << 0)
+#define TXFDPR_TXFP_SHIFT (0)
+
+#define KS_RXFDPR 0x86
+#define RXFDPR_RXFPAI (1 << 14)
+
+#define KS_RXDTTR 0x8C
+#define KS_RXDBCTR 0x8E
+
+#define KS_IER 0x90
+#define KS_ISR 0x92
+#define IRQ_LCI (1 << 15)
+#define IRQ_TXI (1 << 14)
+#define IRQ_RXI (1 << 13)
+#define IRQ_RXOI (1 << 11)
+#define IRQ_TXPSI (1 << 9)
+#define IRQ_RXPSI (1 << 8)
+#define IRQ_TXSAI (1 << 6)
+#define IRQ_RXWFDI (1 << 5)
+#define IRQ_RXMPDI (1 << 4)
+#define IRQ_LDI (1 << 3)
+#define IRQ_EDI (1 << 2)
+#define IRQ_SPIBEI (1 << 1)
+#define IRQ_DEDI (1 << 0)
+
+#define KS_RXFCTR 0x9C
+#define RXFCTR_THRESHOLD_MASK 0x00FF
+
+#define KS_RXFC 0x9D
+#define RXFCTR_RXFC_MASK (0xff << 8)
+#define RXFCTR_RXFC_SHIFT (8)
+#define RXFCTR_RXFC_GET(_v) (((_v) >> 8) & 0xff)
+#define RXFCTR_RXFCT_MASK (0xff << 0)
+#define RXFCTR_RXFCT_SHIFT (0)
+
+#define KS_TXNTFSR 0x9E
+
+#define KS_MAHTR0 0xA0
+#define KS_MAHTR1 0xA2
+#define KS_MAHTR2 0xA4
+#define KS_MAHTR3 0xA6
+
+#define KS_FCLWR 0xB0
+#define KS_FCHWR 0xB2
+#define KS_FCOWR 0xB4
+
+#define KS_CIDER 0xC0
+#define CIDER_ID 0x8870
+#define CIDER_REV_MASK (0x7 << 1)
+#define CIDER_REV_SHIFT (1)
+#define CIDER_REV_GET(_v) (((_v) >> 1) & 0x7)
+
+#define KS_CGCR 0xC6
+#define KS_IACR 0xC8
+#define IACR_RDEN (1 << 12)
+#define IACR_TSEL_MASK (0x3 << 10)
+#define IACR_TSEL_SHIFT (10)
+#define IACR_TSEL_MIB (0x3 << 10)
+#define IACR_ADDR_MASK (0x1f << 0)
+#define IACR_ADDR_SHIFT (0)
+
+#define KS_IADLR 0xD0
+#define KS_IAHDR 0xD2
+
+#define KS_PMECR 0xD4
+#define PMECR_PME_DELAY (1 << 14)
+#define PMECR_PME_POL (1 << 12)
+#define PMECR_WOL_WAKEUP (1 << 11)
+#define PMECR_WOL_MAGICPKT (1 << 10)
+#define PMECR_WOL_LINKUP (1 << 9)
+#define PMECR_WOL_ENERGY (1 << 8)
+#define PMECR_AUTO_WAKE_EN (1 << 7)
+#define PMECR_WAKEUP_NORMAL (1 << 6)
+#define PMECR_WKEVT_MASK (0xf << 2)
+#define PMECR_WKEVT_SHIFT (2)
+#define PMECR_WKEVT_GET(_v) (((_v) >> 2) & 0xf)
+#define PMECR_WKEVT_ENERGY (0x1 << 2)
+#define PMECR_WKEVT_LINK (0x2 << 2)
+#define PMECR_WKEVT_MAGICPKT (0x4 << 2)
+#define PMECR_WKEVT_FRAME (0x8 << 2)
+#define PMECR_PM_MASK (0x3 << 0)
+#define PMECR_PM_SHIFT (0)
+#define PMECR_PM_NORMAL (0x0 << 0)
+#define PMECR_PM_ENERGY (0x1 << 0)
+#define PMECR_PM_SOFTDOWN (0x2 << 0)
+#define PMECR_PM_POWERSAVE (0x3 << 0)
+
+/* Standard MII PHY data */
+#define KS_P1MBCR 0xE4
+#define P1MBCR_FORCE_FDX (1 << 8)
+
+#define KS_P1MBSR 0xE6
+#define P1MBSR_AN_COMPLETE (1 << 5)
+#define P1MBSR_AN_CAPABLE (1 << 3)
+#define P1MBSR_LINK_UP (1 << 2)
+
+#define KS_PHY1ILR 0xE8
+#define KS_PHY1IHR 0xEA
+#define KS_P1ANAR 0xEC
+#define KS_P1ANLPR 0xEE
+
+#define KS_P1SCLMD 0xF4
+#define P1SCLMD_LEDOFF (1 << 15)
+#define P1SCLMD_TXIDS (1 << 14)
+#define P1SCLMD_RESTARTAN (1 << 13)
+#define P1SCLMD_DISAUTOMDIX (1 << 10)
+#define P1SCLMD_FORCEMDIX (1 << 9)
+#define P1SCLMD_AUTONEGEN (1 << 7)
+#define P1SCLMD_FORCE100 (1 << 6)
+#define P1SCLMD_FORCEFDX (1 << 5)
+#define P1SCLMD_ADV_FLOW (1 << 4)
+#define P1SCLMD_ADV_100BT_FDX (1 << 3)
+#define P1SCLMD_ADV_100BT_HDX (1 << 2)
+#define P1SCLMD_ADV_10BT_FDX (1 << 1)
+#define P1SCLMD_ADV_10BT_HDX (1 << 0)
+
+#define KS_P1CR 0xF6
+#define P1CR_HP_MDIX (1 << 15)
+#define P1CR_REV_POL (1 << 13)
+#define P1CR_OP_100M (1 << 10)
+#define P1CR_OP_FDX (1 << 9)
+#define P1CR_OP_MDI (1 << 7)
+#define P1CR_AN_DONE (1 << 6)
+#define P1CR_LINK_GOOD (1 << 5)
+#define P1CR_PNTR_FLOW (1 << 4)
+#define P1CR_PNTR_100BT_FDX (1 << 3)
+#define P1CR_PNTR_100BT_HDX (1 << 2)
+#define P1CR_PNTR_10BT_FDX (1 << 1)
+#define P1CR_PNTR_10BT_HDX (1 << 0)
+
+/* TX Frame control */
+
+#define TXFR_TXIC (1 << 15)
+#define TXFR_TXFID_MASK (0x3f << 0)
+#define TXFR_TXFID_SHIFT (0)
+
+#define KS_P1SR 0xF8
+#define P1SR_HP_MDIX (1 << 15)
+#define P1SR_REV_POL (1 << 13)
+#define P1SR_OP_100M (1 << 10)
+#define P1SR_OP_FDX (1 << 9)
+#define P1SR_OP_MDI (1 << 7)
+#define P1SR_AN_DONE (1 << 6)
+#define P1SR_LINK_GOOD (1 << 5)
+#define P1SR_PNTR_FLOW (1 << 4)
+#define P1SR_PNTR_100BT_FDX (1 << 3)
+#define P1SR_PNTR_100BT_HDX (1 << 2)
+#define P1SR_PNTR_10BT_FDX (1 << 1)
+#define P1SR_PNTR_10BT_HDX (1 << 0)
+
+#define ENUM_BUS_NONE 0
+#define ENUM_BUS_8BIT 1
+#define ENUM_BUS_16BIT 2
+#define ENUM_BUS_32BIT 3
+
+#define MAX_MCAST_LST 32
+#define HW_MCAST_SIZE 8
+#define MAC_ADDR_LEN 6
+
+/* Chip ID values */
+
+struct chip_id {
+ u16 id;
+ char *name;
+};
+
+static const struct chip_id chip_ids[] = {
+ { CIDER_ID, "KSZ8851" },
+ { 0, NULL },
+};
+
+#endif
--
1.7.0.4
3
2
The following patchset updates the support for the keymile
boards.
- heavy rework of the headerfiles, common board code
- add support for 4 new mpc83xx based boards
- add support for 1 82xx based board
- add support for 2 new kirkwood based boards
- fix i2c deblocking for this boards
Patch overview:
Heiko Schocher (15):
keymile: rework headerfiles for keymile boards
mpc832x: add support for the mpc8321 based suvd3 board
mpc832x: add support for mpc8321 based tuxa1 board
mpc832x: add support for mpc8321 based tuda1 board
arm: add support for kirkwood based mgcoge2un board
arm: add support of Kirkwood based board SUEN8
ppc: add support for ppc based board mgcoge2ne
powerpc, 83xx: add kmsupx5 board support
km-arm: i2c support for suenx based boards
km_arm: change some register values for SDRAM initialization
ppc, 8321: cleanup tuxa1, tuda1 and suvd3 support
keymile, common; fix i2c deblocking support
arm, keymile: updates for the arm based boards from keymile
keymile boards: add CONFIG_PIGGY_MAC_ADRESS_OFFSET
keymile, common: add setting of some environment variables
Holger Brunck (2):
ppc, arm: rework and enhance keymile-common.h
keymile-common.h: remove IO mux stuff
Huber, Andreas (1):
ppc, mgcoge, mgcoge2ne: add DIP switch detection
Thomas Herzmann (1):
keymile boards: support of boardId / hwkey lists
Thomas Reufer (1):
keymile, 8321 boards: move common definitions to km8321-common.h
MAINTAINERS | 7 +
arch/powerpc/cpu/mpc83xx/fdt.c | 3 +-
arch/powerpc/lib/bootcount.c | 2 +-
board/keymile/common/common.c | 179 ++++++--
board/keymile/common/common.h | 5 +
board/keymile/{kmeter1 => km83xx}/Makefile | 0
.../keymile/{kmeter1/kmeter1.c => km83xx/km83xx.c} | 101 ++++-
board/keymile/km_arm/km_arm.c | 70 +++-
board/keymile/km_arm/kwbimage.cfg | 32 +-
board/keymile/mgcoge/mgcoge.c | 34 ++-
boards.cfg | 9 +-
include/configs/keymile-common.h | 465 ++++++++++++++------
include/configs/km-powerpc.h | 92 ++++
include/configs/km82xx-common.h | 321 ++++++++++++++
include/configs/km8321-common.h | 140 ++++++
include/configs/km83xx-common.h | 325 ++++++++++++++
include/configs/km_arm.h | 97 ++++-
include/configs/kmeter1.h | 344 ++-------------
include/configs/kmsupx5.h | 89 ++++
include/configs/mgcoge.h | 296 +------------
include/configs/mgcoge2ne.h | 63 +++
include/configs/mgcoge2un.h | 62 +++
include/configs/suen3.h | 45 +--
include/configs/suen8.h | 61 +++
include/configs/suvd3.h | 104 +++++
include/configs/tuda1.h | 141 ++++++
include/configs/tuxa1.h | 124 ++++++
post/lib_powerpc/fpu/Makefile | 33 --
28 files changed, 2313 insertions(+), 931 deletions(-)
rename board/keymile/{kmeter1 => km83xx}/Makefile (100%)
rename board/keymile/{kmeter1/kmeter1.c => km83xx/km83xx.c} (64%)
create mode 100644 include/configs/km-powerpc.h
create mode 100644 include/configs/km82xx-common.h
create mode 100644 include/configs/km8321-common.h
create mode 100644 include/configs/km83xx-common.h
create mode 100644 include/configs/kmsupx5.h
create mode 100644 include/configs/mgcoge2ne.h
create mode 100644 include/configs/mgcoge2un.h
create mode 100644 include/configs/suen8.h
create mode 100644 include/configs/suvd3.h
create mode 100644 include/configs/tuda1.h
create mode 100644 include/configs/tuxa1.h
delete mode 100644 post/lib_powerpc/fpu/Makefile
cc: Holger Brunck <holger.brunck(a)keymile.com>
cc: Heiko Schocher <hs(a)denx.de>
cc: Kim Phillips <kim.phillips(a)freescale.com>
cc: Wolfgang Denk <wd(a)denx.de>
cc: Detlev Zundel <dzu(a)denx.de>
cc: Prafulla Wadaskar <prafulla(a)marvell.com>
cc: Valentin Longchamp <valentin.longchamp(a)keymile.com>
6
122

29 Apr '11
I am working on a custom OMAPL138 (DA8XX) based board. On 2010.12 release
USB host mode is successfully working. But it is broken on 2011.03-rc1.
I am taking "USB device not accepting new address (errror=2)" error
when i issue "usb start" cmd.
I analysed the problem but can not come up with a solution.
Regards.
--
View this message in context: http://old.nabble.com/musb%3A-usb-storage%3A-USB-device-not-accepting-new-a…
Sent from the Uboot - Users mailing list archive at Nabble.com.
3
4
Add the 'pixis_reset dump' command, which displays the contents of the PIXIS
registers. This command is only available if DEBUG is defined.
Signed-off-by: Timur Tabi <timur(a)freescale.com>
---
board/freescale/common/ngpixis.c | 58 ++++++++++++++++++++++++++++++++++++++
1 files changed, 58 insertions(+), 0 deletions(-)
diff --git a/board/freescale/common/ngpixis.c b/board/freescale/common/ngpixis.c
index 4e01e5a..765f035 100644
--- a/board/freescale/common/ngpixis.c
+++ b/board/freescale/common/ngpixis.c
@@ -119,11 +119,50 @@ void __set_altbank(void)
}
void set_altbank(void) __attribute__((weak, alias("__set_altbank")));
+#ifdef DEBUG
+static void pixis_dump_regs(void)
+{
+ unsigned int i;
+
+ printf("id=%02x\n", PIXIS_READ(id));
+ printf("arch=%02x\n", PIXIS_READ(arch));
+ printf("scver=%02x\n", PIXIS_READ(scver));
+ printf("csr=%02x\n", PIXIS_READ(csr));
+ printf("rst=%02x\n", PIXIS_READ(rst));
+ printf("aux=%02x\n", PIXIS_READ(aux));
+ printf("spd=%02x\n", PIXIS_READ(spd));
+ printf("brdcfg0=%02x\n", PIXIS_READ(brdcfg0));
+ printf("brdcfg1=%02x\n", PIXIS_READ(brdcfg1));
+ printf("addr=%02x\n", PIXIS_READ(addr));
+ printf("data=%02x\n", PIXIS_READ(data));
+ printf("led=%02x\n", PIXIS_READ(led));
+ printf("vctl=%02x\n", PIXIS_READ(vctl));
+ printf("vstat=%02x\n", PIXIS_READ(vstat));
+ printf("vcfgen0=%02x\n", PIXIS_READ(vcfgen0));
+ printf("ocmcsr=%02x\n", PIXIS_READ(ocmcsr));
+ printf("ocmmsg=%02x\n", PIXIS_READ(ocmmsg));
+ printf("gmdbg=%02x\n", PIXIS_READ(gmdbg));
+ printf("sclk=%02x%02x%02x\n",
+ PIXIS_READ(sclk[0]), PIXIS_READ(sclk[1]), PIXIS_READ(sclk[2]));
+ printf("dclk=%02x%02x%02x\n",
+ PIXIS_READ(dclk[0]), PIXIS_READ(dclk[1]), PIXIS_READ(dclk[2]));
+ printf("watch=%02x\n", PIXIS_READ(watch));
+
+ for (i = 0; i < 8; i++) {
+ printf("SW%u=%02x/%02x ", i + 1,
+ PIXIS_READ(s[i].sw), PIXIS_READ(s[i].en));
+ }
+ putc('\n');
+}
+#endif
int pixis_reset_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
unsigned int i;
char *p_altbank = NULL;
+#ifdef DEBUG
+ char *p_dump = NULL;
+#endif
char *unknown_param = NULL;
/* No args is a simple reset request.
@@ -137,6 +176,13 @@ int pixis_reset_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
continue;
}
+#ifdef DEBUG
+ if (strcmp(argv[i], "dump") == 0) {
+ p_dump = argv[i];
+ continue;
+ }
+#endif
+
unknown_param = argv[i];
}
@@ -145,6 +191,15 @@ int pixis_reset_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
return 1;
}
+#ifdef DEBUG
+ if (p_dump) {
+ pixis_dump_regs();
+
+ /* 'dump' ignores other commands */
+ return 0;
+ }
+#endif
+
if (p_altbank)
set_altbank();
else
@@ -161,4 +216,7 @@ U_BOOT_CMD(
"Reset the board using the FPGA sequencer",
"- hard reset to default bank\n"
"pixis_reset altbank - reset to alternate bank\n"
+#ifdef DEBUG
+ "pixis_reset dump - display the PIXIS registers\n"
+#endif
);
--
1.7.3.4
2
1

28 Apr '11
Add function video_get_video_mode(), which parses the "video-mode" environment
variable and returns each of its components. The format matches the video=
command-line option used for Linux:
video-mode=<driver>:<xres>x<yres>-<depth>@<freq><,option=string>
<driver> The video driver, ignored by U-Boot
<xres> The X resolution (in pixels) to use.
<yres> The Y resolution (in pixels) to use.
<depth> The color depth (in bits) to use.
<freq> The frequency (in Hz) to use.
<options> A comma-separated list of device-specific options
Signed-off-by: Timur Tabi <timur(a)freescale.com>
---
doc/README.video | 19 +++++++++++++
drivers/video/videomodes.c | 64 ++++++++++++++++++++++++++++++++++++++++++++
drivers/video/videomodes.h | 3 ++
3 files changed, 86 insertions(+), 0 deletions(-)
diff --git a/doc/README.video b/doc/README.video
index 34e199c..0c04bea 100644
--- a/doc/README.video
+++ b/doc/README.video
@@ -28,3 +28,22 @@ The driver has been tested with the following configurations:
- MPC823FADS with AD7176 on a PAL TV (YCbYCr) - arsenio(a)tin.it
- GENIETV with AD7177 on a PAL TV (YCbYCr) - arsenio(a)tin.it
+
+
+"video-mode" environment variable
+===============================
+
+The 'video-mode' environment variable can be used to enable and configure
+some video drivers. The format matches the video= command-line option used
+for Linux:
+
+ video-mode=<driver>:<xres>x<yres>-<depth>@<freq><,option=string>
+
+ <driver> The video driver name, ignored by U-Boot
+ <xres> The X resolution (in pixels) to use.
+ <yres> The Y resolution (in pixels) to use.
+ <depth> The color depth (in bits) to use.
+ <freq> The frequency (in Hz) to use.
+ <options> A comma-separated list of device-specific options
+
+Example: video-mode=fslfb:1280x1024-32@60,monitor=dvi
diff --git a/drivers/video/videomodes.c b/drivers/video/videomodes.c
index d27ce1d..6fe5811 100644
--- a/drivers/video/videomodes.c
+++ b/drivers/video/videomodes.c
@@ -1,6 +1,7 @@
/*
* (C) Copyright 2004
* Pierre Aubert, Staubli Faverges , <p.aubert(a)staubli.com>
+ * Copyright 2011 Freescale Semiconductor, Inc.
*
* See file CREDITS for list of people who contributed to this
* project.
@@ -73,6 +74,8 @@
****************************************************************************/
#include <common.h>
+#include <linux/ctype.h>
+
#include "videomodes.h"
const struct ctfb_vesa_modes vesa_modes[VESA_MODES_COUNT] = {
@@ -206,3 +209,64 @@ int video_get_params (struct ctfb_res_modes *pPar, char *penv)
}
return bpp;
}
+
+/*
+ * Parse the 'video-mode' environment variable
+ *
+ * Example: "video-mode=fslfb:1280x1024-32@60,monitor=dvi". See
+ * doc/README.video for more information on how to set the variable.
+ *
+ * @xres: returned value of X-resolution
+ * @yres: returned value of Y-resolution
+ * @depth: returned value of color depth
+ * @freq: returned value of monitor frequency
+ * @options: pointer to any remaining options, or NULL
+ *
+ * Returns 1 if valid values were found, 0 otherwise
+ */
+int video_get_video_mode(unsigned int *xres, unsigned int *yres,
+ unsigned int *depth, unsigned int *freq, const char **options)
+{
+ char *p = getenv("video-mode");
+ if (!p)
+ return 0;
+
+ /* Skip over the driver name, which we don't care about. */
+ p = strchr(p, ':');
+ if (!p)
+ return 0;
+
+ /* Get the X-resolution*/
+ while (*p && !isdigit(*p))
+ p++;
+ *xres = simple_strtoul(p, &p, 10);
+ if (!*xres)
+ return 0;
+
+ /* Get the Y-resolution */
+ while (*p && !isdigit(*p))
+ p++;
+ *yres = simple_strtoul(p, &p, 10);
+ if (!*yres)
+ return 0;
+
+ /* Get the depth */
+ while (*p && !isdigit(*p))
+ p++;
+ *depth = simple_strtoul(p, &p, 10);
+ if (!*depth)
+ return 0;
+
+ /* Get the frequency */
+ while (*p && !isdigit(*p))
+ p++;
+ *freq = simple_strtoul(p, &p, 10);
+ if (!*freq)
+ return 0;
+
+ /* Find the extra options, if any */
+ p = strchr(p, ',');
+ *options = p ? p + 1 : NULL;
+
+ return 1;
+}
diff --git a/drivers/video/videomodes.h b/drivers/video/videomodes.h
index 0d7c335..e546ab4 100644
--- a/drivers/video/videomodes.h
+++ b/drivers/video/videomodes.h
@@ -86,3 +86,6 @@ extern const struct ctfb_vesa_modes vesa_modes[];
extern const struct ctfb_res_modes res_mode_init[];
int video_get_params (struct ctfb_res_modes *pPar, char *penv);
+
+int video_get_video_mode(unsigned int *xres, unsigned int *yres,
+ unsigned int *depth, unsigned int *freq, const char **options);
--
1.7.3.4
2
2

28 Apr '11
There seems to be tools producing incorrect 'end of bitmap data'
markers '0100' in a RLE bitmap. Drawing such bitmaps can result
in overwriting memory above the frame buffer. E.g. on MPC5121e
based boards this memory can contain U-Boot environment.
We may not rely on the correct end of bitmap data marker 0001
only, but also have to check whether we are going to draw a
valid frame buffer scan line.
The patch provides a simple fix by checking the row index:
we finish the drawing if the row index becomes negative.
Reported-by: Michael Weiss <michael.weiss(a)ifm.com>
Signed-off-by: Anatolij Gustschin <agust(a)denx.de>
Tested-by: Anatolij Gustschin <agust(a)denx.de>
---
drivers/video/cfb_console.c | 9 ++++++++-
1 files changed, 8 insertions(+), 1 deletions(-)
diff --git a/drivers/video/cfb_console.c b/drivers/video/cfb_console.c
index 3d047f2..599ebdb 100644
--- a/drivers/video/cfb_console.c
+++ b/drivers/video/cfb_console.c
@@ -938,7 +938,10 @@ static int display_rle8_bitmap (bmp_image_t *img, int xoff, int yoff,
/* scan line end marker */
bm += 2;
x = 0;
- y--;
+ if (--y < 0) {
+ decode = 0;
+ continue;
+ }
fbp = (unsigned char *)
((unsigned int)video_fb_address +
(((y + yoff) * VIDEO_COLS) +
@@ -952,6 +955,10 @@ static int display_rle8_bitmap (bmp_image_t *img, int xoff, int yoff,
/* run offset marker */
x += bm[2];
y -= bm[3];
+ if (y < 0) {
+ decode = 0;
+ continue;
+ }
fbp = (unsigned char *)
((unsigned int)video_fb_address +
(((y + yoff) * VIDEO_COLS) +
--
1.7.1
1
2

[U-Boot] [PATCH 0/3] Add support for the MMC device to the vexpress
by matt.waddel@linaro.org 28 Apr '11
by matt.waddel@linaro.org 28 Apr '11
28 Apr '11
From: Matt Waddel <matt.waddel(a)linaro.org>
These patches add support for the ARM PrimeCell PL180 MultiMedia Interface.
The Versatile Express was the test platform for these changes.
Matt Waddel (3):
MMC: Max blocks value adjustable
MMC: Add support for PL180 ARM mmc device
ARMV7: Vexpress: Add MMC support
board/armltd/vexpress/ca9x4_ct_vxp.c | 9 +
drivers/mmc/Makefile | 1 +
drivers/mmc/mmc.c | 19 +-
drivers/mmc/mmci.c | 452 ++++++++++++++++++++++++++++++++++
drivers/mmc/mmci.h | 181 ++++++++++++++
include/configs/ca9x4_ct_vxp.h | 4 +
6 files changed, 656 insertions(+), 10 deletions(-)
create mode 100644 drivers/mmc/mmci.c
create mode 100644 drivers/mmc/mmci.h
6
24