diff options
57 files changed, 4638 insertions, 753 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index b5f3458..3f16dab 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -531,6 +531,7 @@ Prakash Kumar <prakash@embedx.com> Guennadi Liakhovetski <g.liakhovetski@gmx.de> mx31ads i.MX31 + SMDK6400 S3C6400 David Müller <d.mueller@elsoft.ch> @@ -519,6 +519,7 @@ LIST_ARM11=" \ imx31_litekit \ imx31_phycore \ mx31ads \ + smdk6400 \ " ######################################################################### @@ -2495,7 +2495,7 @@ cp1026_config: unconfig @board/integratorcp/split_by_variant.sh $@ davinci_dvevm_config : unconfig - @$(MKCONFIG) $(@:_config=) arm arm926ejs dv-evm davinci davinci + @$(MKCONFIG) $(@:_config=) arm arm926ejs dvevm davinci davinci davinci_schmoogie_config : unconfig @$(MKCONFIG) $(@:_config=) arm arm926ejs schmoogie davinci davinci @@ -2758,6 +2758,23 @@ mx31ads_config : unconfig omap2420h4_config : unconfig @$(MKCONFIG) $(@:_config=) arm arm1136 omap2420h4 NULL omap24xx +######################################################################### +## ARM1176 Systems +######################################################################### +smdk6400_noUSB_config \ +smdk6400_config : unconfig + @mkdir -p $(obj)include $(obj)board/samsung/smdk6400 + @mkdir -p $(obj)nand_spl/board/samsung/smdk6400 + @echo "#define CONFIG_NAND_U_BOOT" > $(obj)include/config.h + @if [ -z "$(findstring smdk6400_noUSB_config,$@)" ]; then \ + echo "RAM_TEXT = 0x57e00000" >> $(obj)board/samsung/smdk6400/config.tmp;\ + $(MKCONFIG) $(@:_config=) arm arm1176 smdk6400 samsung s3c64xx; \ + else \ + echo "RAM_TEXT = 0xc7e00000" >> $(obj)board/samsung/smdk6400/config.tmp;\ + $(MKCONFIG) $(@:_noUSB_config=) arm arm1176 smdk6400 samsung s3c64xx; \ + fi + @echo "CONFIG_NAND_U_BOOT = y" >> $(obj)include/config.mk + #======================================================================== # i386 #======================================================================== diff --git a/board/davinci/common/Makefile b/board/davinci/common/Makefile new file mode 100644 index 0000000..127bb6e --- /dev/null +++ b/board/davinci/common/Makefile @@ -0,0 +1,53 @@ +# +# (C) Copyright 2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +ifneq ($(OBJTREE),$(SRCTREE)) +$(shell mkdir -p $(obj)board/$(VENDOR)/common) +endif + +LIB = $(obj)lib$(VENDOR).a + +COBJS := psc.o misc.o + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) +SOBJS := $(addprefix $(obj),$(SOBJS)) + +$(LIB): $(obj).depend $(OBJS) $(SOBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS) + +clean: + rm -f $(SOBJS) $(OBJS) + +distclean: clean + rm -f $(LIB) core *.bak $(obj).depend + +######################################################################### +# This is for $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/board/davinci/common/misc.c b/board/davinci/common/misc.c new file mode 100644 index 0000000..71a3b87 --- /dev/null +++ b/board/davinci/common/misc.c @@ -0,0 +1,126 @@ +/* + * Miscelaneous DaVinci functions. + * + * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net> + * Copyright (C) 2008 Lyrtech <www.lyrtech.com> + * Copyright (C) 2004 Texas Instruments. + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <common.h> +#include <i2c.h> +#include <asm/arch/hardware.h> + +DECLARE_GLOBAL_DATA_PTR; + +int dram_init(void) +{ + gd->bd->bi_dram[0].start = PHYS_SDRAM_1; + gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; + + return(0); +} + +static int dv_get_pllm_output(uint32_t pllm) +{ + return (pllm + 1) * (CFG_HZ_CLOCK / 1000000); +} + +void dv_display_clk_infos(void) +{ + printf("ARM Clock: %dMHz\n", dv_get_pllm_output(REG(PLL1_PLLM)) / 2); + printf("DDR Clock: %dMHz\n", dv_get_pllm_output(REG(PLL2_PLLM)) / + ((REG(PLL2_DIV2) & 0x1f) + 1) / 2); +} + +/* Read ethernet MAC address from EEPROM for DVEVM compatible boards. + * Returns 1 if found, 0 otherwise. + */ +int dvevm_read_mac_address(uint8_t *buf) +{ +#ifdef CFG_I2C_EEPROM_ADDR + /* Read MAC address. */ + if (i2c_read(CFG_I2C_EEPROM_ADDR, 0x7F00, CFG_I2C_EEPROM_ADDR_LEN, + (uint8_t *) &buf[0], 6)) + goto i2cerr; + + /* Check that MAC address is not null. */ + if (memcmp(buf, "\0\0\0\0\0\0", 6) == 0) + goto err; + + return 1; /* Found */ + +i2cerr: + printf("Read from EEPROM @ 0x%02x failed\n", CFG_I2C_EEPROM_ADDR); +err: +#endif /* CFG_I2C_EEPROM_ADDR */ + + return 0; +} + +/* If there is a MAC address in the environment, and if it is not identical to + * the MAC address in the ROM, then a warning is printed and the MAC address + * from the environment is used. + * + * If there is no MAC address in the environment, then it will be initialized + * (silently) from the value in the ROM. + */ +void dv_configure_mac_address(uint8_t *rom_enetaddr) +{ + int i; + u_int8_t env_enetaddr[6]; + char *tmp = getenv("ethaddr"); + char *end; + + /* Read Ethernet MAC address from the U-Boot environment. + * If it is not defined, env_enetaddr[] will be cleared. */ + for (i = 0; i < 6; i++) { + env_enetaddr[i] = tmp ? simple_strtoul(tmp, &end, 16) : 0; + if (tmp) + tmp = (*end) ? end+1 : end; + } + + /* Check if ROM and U-Boot environment MAC addresses match. */ + if (memcmp(env_enetaddr, "\0\0\0\0\0\0", 6) != 0 && + memcmp(env_enetaddr, rom_enetaddr, 6) != 0) { + printf("Warning: MAC addresses don't match:\n"); + printf(" ROM MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n", + rom_enetaddr[0], rom_enetaddr[1], + rom_enetaddr[2], rom_enetaddr[3], + rom_enetaddr[4], rom_enetaddr[5]); + printf(" \"ethaddr\" value: %02X:%02X:%02X:%02X:%02X:%02X\n", + env_enetaddr[0], env_enetaddr[1], + env_enetaddr[2], env_enetaddr[3], + env_enetaddr[4], env_enetaddr[5]) ; + debug("### Using MAC address from environment\n"); + } + if (!tmp) { + char ethaddr[20]; + + /* There is no MAC address in the environment, so we initialize + * it from the value in the ROM. */ + sprintf(ethaddr, "%02X:%02X:%02X:%02X:%02X:%02X", + rom_enetaddr[0], rom_enetaddr[1], + rom_enetaddr[2], rom_enetaddr[3], + rom_enetaddr[4], rom_enetaddr[5]) ; + debug("### Setting environment from ROM MAC address = \"%s\"\n", + ethaddr); + setenv("ethaddr", ethaddr); + } +} diff --git a/board/davinci/common/misc.h b/board/davinci/common/misc.h new file mode 100644 index 0000000..4a57dbb --- /dev/null +++ b/board/davinci/common/misc.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2008 Lyrtech <www.lyrtech.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __MISC_H +#define __MISC_H + +extern void timer_init(void); +extern int eth_hw_init(void); + +void dv_display_clk_infos(void); +int dvevm_read_mac_address(uint8_t *buf); +void dv_configure_mac_address(uint8_t *rom_enetaddr); + +#endif /* __MISC_H */ diff --git a/board/davinci/common/psc.c b/board/davinci/common/psc.c new file mode 100644 index 0000000..00dc07c --- /dev/null +++ b/board/davinci/common/psc.c @@ -0,0 +1,117 @@ +/* + * Power and Sleep Controller (PSC) functions. + * + * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net> + * Copyright (C) 2008 Lyrtech <www.lyrtech.com> + * Copyright (C) 2004 Texas Instruments. + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <common.h> +#include <asm/arch/hardware.h> + +/* + * The DM6446 includes two separate power domains: "Always On" and "DSP". The + * "Always On" power domain is always on when the chip is on. The "Always On" + * domain is powered by the VDD pins of the DM6446. The majority of the + * DM6446's modules lie within the "Always On" power domain. A separate + * domain called the "DSP" domain houses the C64x+ and VICP. The "DSP" domain + * is not always on. The "DSP" power domain is powered by the CVDDDSP pins of + * the DM6446. + */ + +/* Works on Always On power domain only (no PD argument) */ +void lpsc_on(unsigned int id) +{ + dv_reg_p mdstat, mdctl; + + if (id >= DAVINCI_LPSC_GEM) + return; /* Don't work on DSP Power Domain */ + + mdstat = REG_P(PSC_MDSTAT_BASE + (id * 4)); + mdctl = REG_P(PSC_MDCTL_BASE + (id * 4)); + + while (REG(PSC_PTSTAT) & 0x01); + + if ((*mdstat & 0x1f) == 0x03) + return; /* Already on and enabled */ + + *mdctl |= 0x03; + + /* Special treatment for some modules as for sprue14 p.7.4.2 */ + switch (id) { + case DAVINCI_LPSC_VPSSSLV: + case DAVINCI_LPSC_EMAC: + case DAVINCI_LPSC_EMAC_WRAPPER: + case DAVINCI_LPSC_MDIO: + case DAVINCI_LPSC_USB: + case DAVINCI_LPSC_ATA: + case DAVINCI_LPSC_VLYNQ: + case DAVINCI_LPSC_UHPI: + case DAVINCI_LPSC_DDR_EMIF: + case DAVINCI_LPSC_AEMIF: + case DAVINCI_LPSC_MMC_SD: + case DAVINCI_LPSC_MEMSTICK: + case DAVINCI_LPSC_McBSP: + case DAVINCI_LPSC_GPIO: + *mdctl |= 0x200; + break; + } + + REG(PSC_PTCMD) = 0x01; + + while (REG(PSC_PTSTAT) & 0x03); + while ((*mdstat & 0x1f) != 0x03); /* Probably an overkill... */ +} + +/* If DSPLINK is used, we don't want U-Boot to power on the DSP. */ +#if !defined(CFG_USE_DSPLINK) +void dsp_on(void) +{ + int i; + + if (REG(PSC_PDSTAT1) & 0x1f) + return; /* Already on */ + + REG(PSC_GBLCTL) |= 0x01; + REG(PSC_PDCTL1) |= 0x01; + REG(PSC_PDCTL1) &= ~0x100; + REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_GEM * 4)) |= 0x03; + REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_GEM * 4)) &= 0xfffffeff; + REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_IMCOP * 4)) |= 0x03; + REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_IMCOP * 4)) &= 0xfffffeff; + REG(PSC_PTCMD) = 0x02; + + for (i = 0; i < 100; i++) { + if (REG(PSC_EPCPR) & 0x02) + break; + } + + REG(PSC_CHP_SHRTSW) = 0x01; + REG(PSC_PDCTL1) |= 0x100; + REG(PSC_EPCCR) = 0x02; + + for (i = 0; i < 100; i++) { + if (!(REG(PSC_PTSTAT) & 0x02)) + break; + } + + REG(PSC_GBLCTL) &= ~0x1f; +} +#endif /* CFG_USE_DSPLINK */ diff --git a/board/integratorap/memsetup.S b/board/davinci/common/psc.h index da43cb6..6ab2575 100644 --- a/board/integratorap/memsetup.S +++ b/board/davinci/common/psc.h @@ -1,13 +1,13 @@ /* - * Memory setup for integratorAP + * Copyright (C) 2008 Lyrtech <www.lyrtech.com> * * See file CREDITS for list of people who contributed to this * project. * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. + * This program is 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 @@ -16,14 +16,13 @@ * * 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 - */ -/* - * Memory setup - * - the reset defaults are assumed sufficient + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -.globl memsetup -memsetup: - mov pc,lr +#ifndef __PSC_H +#define __PSC_H + +void lpsc_on(unsigned int id); +void dsp_on(void); + +#endif /* __PSC_H */ diff --git a/board/davinci/dv-evm/dv_board.c b/board/davinci/dv-evm/dv_board.c deleted file mode 100644 index 834eb68..0000000 --- a/board/davinci/dv-evm/dv_board.c +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net> - * - * Parts are shamelessly stolen from various TI sources, original copyright - * follows: - * ----------------------------------------------------------------- - * - * Copyright (C) 2004 Texas Instruments. - * - * ---------------------------------------------------------------------------- - * 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., 675 Mass Ave, Cambridge, MA 02139, USA. - * ---------------------------------------------------------------------------- - */ - -#include <common.h> -#include <i2c.h> -#include <asm/arch/hardware.h> -#include <asm/arch/emac_defs.h> - -DECLARE_GLOBAL_DATA_PTR; - -extern void timer_init(void); -extern int eth_hw_init(void); - - -/* Works on Always On power domain only (no PD argument) */ -void lpsc_on(unsigned int id) -{ - dv_reg_p mdstat, mdctl; - - if (id >= DAVINCI_LPSC_GEM) - return; /* Don't work on DSP Power Domain */ - - mdstat = REG_P(PSC_MDSTAT_BASE + (id * 4)); - mdctl = REG_P(PSC_MDCTL_BASE + (id * 4)); - - while (REG(PSC_PTSTAT) & 0x01) {;} - - if ((*mdstat & 0x1f) == 0x03) - return; /* Already on and enabled */ - - *mdctl |= 0x03; - - /* Special treatment for some modules as for sprue14 p.7.4.2 */ - if ( (id == DAVINCI_LPSC_VPSSSLV) || - (id == DAVINCI_LPSC_EMAC) || - (id == DAVINCI_LPSC_EMAC_WRAPPER) || - (id == DAVINCI_LPSC_MDIO) || - (id == DAVINCI_LPSC_USB) || - (id == DAVINCI_LPSC_ATA) || - (id == DAVINCI_LPSC_VLYNQ) || - (id == DAVINCI_LPSC_UHPI) || - (id == DAVINCI_LPSC_DDR_EMIF) || - (id == DAVINCI_LPSC_AEMIF) || - (id == DAVINCI_LPSC_MMC_SD) || - (id == DAVINCI_LPSC_MEMSTICK) || - (id == DAVINCI_LPSC_McBSP) || - (id == DAVINCI_LPSC_GPIO) - ) - *mdctl |= 0x200; - - REG(PSC_PTCMD) = 0x01; - - while (REG(PSC_PTSTAT) & 0x03) {;} - while ((*mdstat & 0x1f) != 0x03) {;} /* Probably an overkill... */ -} - -void dsp_on(void) -{ - int i; - - if (REG(PSC_PDSTAT1) & 0x1f) - return; /* Already on */ - - REG(PSC_GBLCTL) |= 0x01; - REG(PSC_PDCTL1) |= 0x01; - REG(PSC_PDCTL1) &= ~0x100; - REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_GEM * 4)) |= 0x03; - REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_GEM * 4)) &= 0xfffffeff; - REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_IMCOP * 4)) |= 0x03; - REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_IMCOP * 4)) &= 0xfffffeff; - REG(PSC_PTCMD) = 0x02; - - for (i = 0; i < 100; i++) { - if (REG(PSC_EPCPR) & 0x02) - break; - } - - REG(PSC_CHP_SHRTSW) = 0x01; - REG(PSC_PDCTL1) |= 0x100; - REG(PSC_EPCCR) = 0x02; - - for (i = 0; i < 100; i++) { - if (!(REG(PSC_PTSTAT) & 0x02)) - break; - } - - REG(PSC_GBLCTL) &= ~0x1f; -} - - -int board_init(void) -{ - /* arch number of the board */ - gd->bd->bi_arch_number = MACH_TYPE_DAVINCI_EVM; - - /* address of boot parameters */ - gd->bd->bi_boot_params = LINUX_BOOT_PARAM_ADDR; - - /* Workaround for TMS320DM6446 errata 1.3.22 */ - REG(PSC_SILVER_BULLET) = 0; - - /* Power on required peripherals */ - lpsc_on(DAVINCI_LPSC_EMAC); - lpsc_on(DAVINCI_LPSC_EMAC_WRAPPER); - lpsc_on(DAVINCI_LPSC_MDIO); - lpsc_on(DAVINCI_LPSC_I2C); - lpsc_on(DAVINCI_LPSC_UART0); - lpsc_on(DAVINCI_LPSC_TIMER1); - lpsc_on(DAVINCI_LPSC_GPIO); - - /* Powerup the DSP */ - dsp_on(); - - /* Bringup UART0 out of reset */ - REG(UART0_PWREMU_MGMT) = 0x0000e003; - - /* Enable GIO3.3V cells used for EMAC */ - REG(VDD3P3V_PWDN) = 0; - - /* Enable UART0 MUX lines */ - REG(PINMUX1) |= 1; - - /* Enable EMAC and AEMIF pins */ - REG(PINMUX0) = 0x80000c1f; - - /* Enable I2C pin Mux */ - REG(PINMUX1) |= (1 << 7); - - /* Set the Bus Priority Register to appropriate value */ - REG(VBPR) = 0x20; - - timer_init(); - - return(0); -} - -int misc_init_r (void) -{ - u_int8_t tmp[20], buf[10]; - int i = 0; - int clk = 0; - - clk = ((REG(PLL2_PLLM) + 1) * 27) / ((REG(PLL2_DIV2) & 0x1f) + 1); - - printf ("ARM Clock : %dMHz\n", ((REG(PLL1_PLLM) + 1) * 27 ) / 2); - printf ("DDR Clock : %dMHz\n", (clk / 2)); - - /* Set Ethernet MAC address from EEPROM */ - if (i2c_read(CFG_I2C_EEPROM_ADDR, 0x7f00, CFG_I2C_EEPROM_ADDR_LEN, buf, 6)) { - printf("\nEEPROM @ 0x%02x read FAILED!!!\n", CFG_I2C_EEPROM_ADDR); - } else { - tmp[0] = 0xff; - for (i = 0; i < 6; i++) - tmp[0] &= buf[i]; - - if ((tmp[0] != 0xff) && (getenv("ethaddr") == NULL)) { - sprintf((char *)&tmp[0], "%02x:%02x:%02x:%02x:%02x:%02x", - buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]); - setenv("ethaddr", (char *)&tmp[0]); - } - } - - if (!eth_hw_init()) - printf("ethernet init failed!\n"); - - i2c_read (0x39, 0x00, 1, (u_int8_t *)&i, 1); - - setenv ("videostd", ((i & 0x80) ? "pal" : "ntsc")); - - return(0); -} - -int dram_init(void) -{ - gd->bd->bi_dram[0].start = PHYS_SDRAM_1; - gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; - - return(0); -} diff --git a/board/davinci/dv-evm/Makefile b/board/davinci/dvevm/Makefile index 579efe2..fb31ee4 100644 --- a/board/davinci/dv-evm/Makefile +++ b/board/davinci/dvevm/Makefile @@ -27,7 +27,7 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(BOARD).a -COBJS := dv_board.o +COBJS := $(BOARD).o SOBJS := board_init.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) diff --git a/board/davinci/dv-evm/board_init.S b/board/davinci/dvevm/board_init.S index 22d8adc..22d8adc 100644 --- a/board/davinci/dv-evm/board_init.S +++ b/board/davinci/dvevm/board_init.S diff --git a/board/davinci/dv-evm/config.mk b/board/davinci/dvevm/config.mk index aa89d0e..aa89d0e 100644 --- a/board/davinci/dv-evm/config.mk +++ b/board/davinci/dvevm/config.mk diff --git a/board/davinci/dvevm/dvevm.c b/board/davinci/dvevm/dvevm.c new file mode 100644 index 0000000..151f8a9 --- /dev/null +++ b/board/davinci/dvevm/dvevm.c @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net> + * + * Parts are shamelessly stolen from various TI sources, original copyright + * follows: + * ----------------------------------------------------------------- + * + * Copyright (C) 2004 Texas Instruments. + * + * ---------------------------------------------------------------------------- + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * ---------------------------------------------------------------------------- + */ + +#include <common.h> +#include <i2c.h> +#include <asm/arch/hardware.h> +#include <asm/arch/emac_defs.h> +#include "../common/psc.h" +#include "../common/misc.h" + +DECLARE_GLOBAL_DATA_PTR; + +int board_init(void) +{ + /* arch number of the board */ + gd->bd->bi_arch_number = MACH_TYPE_DAVINCI_EVM; + + /* address of boot parameters */ + gd->bd->bi_boot_params = LINUX_BOOT_PARAM_ADDR; + + /* Workaround for TMS320DM6446 errata 1.3.22 */ + REG(PSC_SILVER_BULLET) = 0; + + /* Power on required peripherals */ + lpsc_on(DAVINCI_LPSC_EMAC); + lpsc_on(DAVINCI_LPSC_EMAC_WRAPPER); + lpsc_on(DAVINCI_LPSC_MDIO); + lpsc_on(DAVINCI_LPSC_I2C); + lpsc_on(DAVINCI_LPSC_UART0); + lpsc_on(DAVINCI_LPSC_TIMER1); + lpsc_on(DAVINCI_LPSC_GPIO); + +#if !defined(CFG_USE_DSPLINK) + /* Powerup the DSP */ + dsp_on(); +#endif /* CFG_USE_DSPLINK */ + + /* Bringup UART0 out of reset */ + REG(UART0_PWREMU_MGMT) = 0x0000e003; + + /* Enable GIO3.3V cells used for EMAC */ + REG(VDD3P3V_PWDN) = 0; + + /* Enable UART0 MUX lines */ + REG(PINMUX1) |= 1; + + /* Enable EMAC and AEMIF pins */ + REG(PINMUX0) = 0x80000c1f; + + /* Enable I2C pin Mux */ + REG(PINMUX1) |= (1 << 7); + + /* Set the Bus Priority Register to appropriate value */ + REG(VBPR) = 0x20; + + timer_init(); + + return(0); +} + +int misc_init_r(void) +{ + uint8_t video_mode; + uint8_t eeprom_enetaddr[6]; + + dv_display_clk_infos(); + + /* Read Ethernet MAC address from EEPROM if available. */ + if (dvevm_read_mac_address(eeprom_enetaddr)) + dv_configure_mac_address(eeprom_enetaddr); + + if (!eth_hw_init()) + printf("ethernet init failed!\n"); + + i2c_read(0x39, 0x00, 1, &video_mode, 1); + + setenv("videostd", ((video_mode & 0x80) ? "pal" : "ntsc")); + + return(0); +} diff --git a/board/davinci/dv-evm/u-boot.lds b/board/davinci/dvevm/u-boot.lds index a4fcd1a..a4fcd1a 100644 --- a/board/davinci/dv-evm/u-boot.lds +++ b/board/davinci/dvevm/u-boot.lds diff --git a/board/davinci/schmoogie/Makefile b/board/davinci/schmoogie/Makefile index 579efe2..fb31ee4 100644 --- a/board/davinci/schmoogie/Makefile +++ b/board/davinci/schmoogie/Makefile @@ -27,7 +27,7 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(BOARD).a -COBJS := dv_board.o +COBJS := $(BOARD).o SOBJS := board_init.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) diff --git a/board/davinci/schmoogie/dv_board.c b/board/davinci/schmoogie/schmoogie.c index 3017546..99fd326 100644 --- a/board/davinci/schmoogie/dv_board.c +++ b/board/davinci/schmoogie/schmoogie.c @@ -28,89 +28,11 @@ #include <i2c.h> #include <asm/arch/hardware.h> #include <asm/arch/emac_defs.h> +#include "../common/psc.h" +#include "../common/misc.h" DECLARE_GLOBAL_DATA_PTR; -extern void timer_init(void); -extern int eth_hw_init(void); - - -/* Works on Always On power domain only (no PD argument) */ -void lpsc_on(unsigned int id) -{ - dv_reg_p mdstat, mdctl; - - if (id >= DAVINCI_LPSC_GEM) - return; /* Don't work on DSP Power Domain */ - - mdstat = REG_P(PSC_MDSTAT_BASE + (id * 4)); - mdctl = REG_P(PSC_MDCTL_BASE + (id * 4)); - - while (REG(PSC_PTSTAT) & 0x01) {;} - - if ((*mdstat & 0x1f) == 0x03) - return; /* Already on and enabled */ - - *mdctl |= 0x03; - - /* Special treatment for some modules as for sprue14 p.7.4.2 */ - if ( (id == DAVINCI_LPSC_VPSSSLV) || - (id == DAVINCI_LPSC_EMAC) || - (id == DAVINCI_LPSC_EMAC_WRAPPER) || - (id == DAVINCI_LPSC_MDIO) || - (id == DAVINCI_LPSC_USB) || - (id == DAVINCI_LPSC_ATA) || - (id == DAVINCI_LPSC_VLYNQ) || - (id == DAVINCI_LPSC_UHPI) || - (id == DAVINCI_LPSC_DDR_EMIF) || - (id == DAVINCI_LPSC_AEMIF) || - (id == DAVINCI_LPSC_MMC_SD) || - (id == DAVINCI_LPSC_MEMSTICK) || - (id == DAVINCI_LPSC_McBSP) || - (id == DAVINCI_LPSC_GPIO) - ) - *mdctl |= 0x200; - - REG(PSC_PTCMD) = 0x01; - - while (REG(PSC_PTSTAT) & 0x03) {;} - while ((*mdstat & 0x1f) != 0x03) {;} /* Probably an overkill... */ -} - -void dsp_on(void) -{ - int i; - - if (REG(PSC_PDSTAT1) & 0x1f) - return; /* Already on */ - - REG(PSC_GBLCTL) |= 0x01; - REG(PSC_PDCTL1) |= 0x01; - REG(PSC_PDCTL1) &= ~0x100; - REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_GEM * 4)) |= 0x03; - REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_GEM * 4)) &= 0xfffffeff; - REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_IMCOP * 4)) |= 0x03; - REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_IMCOP * 4)) &= 0xfffffeff; - REG(PSC_PTCMD) = 0x02; - - for (i = 0; i < 100; i++) { - if (REG(PSC_EPCPR) & 0x02) - break; - } - - REG(PSC_CHP_SHRTSW) = 0x01; - REG(PSC_PDCTL1) |= 0x100; - REG(PSC_EPCCR) = 0x02; - - for (i = 0; i < 100; i++) { - if (!(REG(PSC_PTSTAT) & 0x02)) - break; - } - - REG(PSC_GBLCTL) &= ~0x1f; -} - - int board_init(void) { /* arch number of the board */ @@ -131,8 +53,10 @@ int board_init(void) lpsc_on(DAVINCI_LPSC_TIMER1); lpsc_on(DAVINCI_LPSC_GPIO); +#if !defined(CFG_USE_DSPLINK) /* Powerup the DSP */ dsp_on(); +#endif /* CFG_USE_DSPLINK */ /* Bringup UART0 out of reset */ REG(UART0_PWREMU_MGMT) = 0x0000e003; @@ -157,11 +81,10 @@ int board_init(void) return(0); } -int misc_init_r (void) +int misc_init_r(void) { u_int8_t tmp[20], buf[10]; int i = 0; - int clk = 0; /* Set serial number from UID chip */ u_int8_t crc_tbl[256] = { @@ -199,17 +122,15 @@ int misc_init_r (void) 0xb6, 0xe8, 0x0a, 0x54, 0xd7, 0x89, 0x6b, 0x35 }; - clk = ((REG(PLL2_PLLM) + 1) * 27) / ((REG(PLL2_DIV2) & 0x1f) + 1); - - printf ("ARM Clock : %dMHz\n", ((REG(PLL1_PLLM) + 1) * 27 ) / 2); - printf ("DDR Clock : %dMHz\n", (clk / 2)); + dv_display_clk_infos(); /* Set serial number from UID chip */ if (i2c_read(CFG_UID_ADDR, 0, 1, buf, 8)) { printf("\nUID @ 0x%02x read FAILED!!!\n", CFG_UID_ADDR); forceenv("serial#", "FAILED"); } else { - if (buf[0] != 0x70) { /* Device Family Code */ + if (buf[0] != 0x70) { + /* Device Family Code */ printf("\nUID @ 0x%02x read FAILED!!!\n", CFG_UID_ADDR); forceenv("serial#", "FAILED"); } @@ -234,11 +155,3 @@ int misc_init_r (void) return(0); } - -int dram_init(void) -{ - gd->bd->bi_dram[0].start = PHYS_SDRAM_1; - gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; - - return(0); -} diff --git a/board/davinci/sffsdr/sffsdr.c b/board/davinci/sffsdr/sffsdr.c index f41081f..f47ba0f 100644 --- a/board/davinci/sffsdr/sffsdr.c +++ b/board/davinci/sffsdr/sffsdr.c @@ -31,6 +31,8 @@ #include <i2c.h> #include <asm/arch/hardware.h> #include <asm/arch/emac_defs.h> +#include "../common/psc.h" +#include "../common/misc.h" #define DAVINCI_A3CR (0x01E00014) /* EMIF-A CS3 config register. */ #define DAVINCI_A3CR_VAL (0x3FFFFFFD) /* EMIF-A CS3 value for FPGA. */ @@ -41,89 +43,6 @@ DECLARE_GLOBAL_DATA_PTR; -extern void timer_init(void); -extern int eth_hw_init(void); - - -/* Works on Always On power domain only (no PD argument) */ -void lpsc_on(unsigned int id) -{ - dv_reg_p mdstat, mdctl; - - if (id >= DAVINCI_LPSC_GEM) - return; /* Don't work on DSP Power Domain */ - - mdstat = REG_P(PSC_MDSTAT_BASE + (id * 4)); - mdctl = REG_P(PSC_MDCTL_BASE + (id * 4)); - - while (REG(PSC_PTSTAT) & 0x01); - - if ((*mdstat & 0x1f) == 0x03) - return; /* Already on and enabled */ - - *mdctl |= 0x03; - - /* Special treatment for some modules as for sprue14 p.7.4.2 */ - switch (id) { - case DAVINCI_LPSC_VPSSSLV: - case DAVINCI_LPSC_EMAC: - case DAVINCI_LPSC_EMAC_WRAPPER: - case DAVINCI_LPSC_MDIO: - case DAVINCI_LPSC_USB: - case DAVINCI_LPSC_ATA: - case DAVINCI_LPSC_VLYNQ: - case DAVINCI_LPSC_UHPI: - case DAVINCI_LPSC_DDR_EMIF: - case DAVINCI_LPSC_AEMIF: - case DAVINCI_LPSC_MMC_SD: - case DAVINCI_LPSC_MEMSTICK: - case DAVINCI_LPSC_McBSP: - case DAVINCI_LPSC_GPIO: - *mdctl |= 0x200; - break; - } - - REG(PSC_PTCMD) = 0x01; - - while (REG(PSC_PTSTAT) & 0x03); - while ((*mdstat & 0x1f) != 0x03); /* Probably an overkill... */ -} - -#if !defined(CFG_USE_DSPLINK) -void dsp_on(void) -{ - int i; - - if (REG(PSC_PDSTAT1) & 0x1f) - return; /* Already on */ - - REG(PSC_GBLCTL) |= 0x01; - REG(PSC_PDCTL1) |= 0x01; - REG(PSC_PDCTL1) &= ~0x100; - REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_GEM * 4)) |= 0x03; - REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_GEM * 4)) &= 0xfffffeff; - REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_IMCOP * 4)) |= 0x03; - REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_IMCOP * 4)) &= 0xfffffeff; - REG(PSC_PTCMD) = 0x02; - - for (i = 0; i < 100; i++) { - if (REG(PSC_EPCPR) & 0x02) - break; - } - - REG(PSC_CHP_SHRTSW) = 0x01; - REG(PSC_PDCTL1) |= 0x100; - REG(PSC_EPCCR) = 0x02; - - for (i = 0; i < 100; i++) { - if (!(REG(PSC_PTSTAT) & 0x02)) - break; - } - - REG(PSC_GBLCTL) &= ~0x1f; -} -#endif /* CFG_USE_DSPLINK */ - int board_init(void) { /* arch number of the board */ @@ -172,8 +91,10 @@ int board_init(void) return(0); } -/* Read ethernet MAC address from Integrity data structure inside EEPROM. */ -int read_mac_address(uint8_t *buf) +/* Read ethernet MAC address from Integrity data structure inside EEPROM. + * Returns 1 if found, 0 otherwise. + */ +static int sffsdr_read_mac_address(uint8_t *buf) { u_int32_t value, mac[2], address; @@ -182,7 +103,7 @@ int read_mac_address(uint8_t *buf) CFG_I2C_EEPROM_ADDR_LEN, (uint8_t *) &value, 4)) goto err; if (value != INTEGRITY_CHECKWORD_VALUE) - return 1; + return 0; /* Read SYSCFG structure offset. */ if (i2c_read(CFG_I2C_EEPROM_ADDR, INTEGRITY_SYSCFG_OFFSET, @@ -216,30 +137,23 @@ int read_mac_address(uint8_t *buf) buf[4] = mac[1] >> 24; buf[5] = mac[1] >> 16; - return 0; + return 1; /* Found */ err: printf("Read from EEPROM @ 0x%02x failed\n", CFG_I2C_EEPROM_ADDR); - return 1; + return 0; } /* Platform dependent initialisation. */ int misc_init_r(void) { - int i; - u_int8_t i2cbuf; - u_int8_t env_enetaddr[6], eeprom_enetaddr[6]; - char *tmp = getenv("ethaddr"); - char *end; - int clk; + uint8_t i2cbuf; + uint8_t eeprom_enetaddr[6]; /* EMIF-A CS3 configuration for FPGA. */ REG(DAVINCI_A3CR) = DAVINCI_A3CR_VAL; - clk = ((REG(PLL2_PLLM) + 1) * 27) / ((REG(PLL2_DIV2) & 0x1f) + 1); - - printf("ARM Clock: %dMHz\n", ((REG(PLL1_PLLM) + 1) * 27) / 2); - printf("DDR Clock: %dMHz\n", (clk / 2)); + dv_display_clk_infos(); /* Configure I2C switch (PCA9543) to enable channel 0. */ i2cbuf = CFG_I2C_PCA9543_ENABLE_CH0; @@ -249,43 +163,9 @@ int misc_init_r(void) return 1; } - /* Read Ethernet MAC address from the U-Boot environment. */ - for (i = 0; i < 6; i++) { - env_enetaddr[i] = tmp ? simple_strtoul(tmp, &end, 16) : 0; - if (tmp) - tmp = (*end) ? end+1 : end; - } - - /* Read Ethernet MAC address from EEPROM. */ - if (read_mac_address(eeprom_enetaddr) == 0) { - if (memcmp(env_enetaddr, "\0\0\0\0\0\0", 6) != 0 && - memcmp(env_enetaddr, eeprom_enetaddr, 6) != 0) { - printf("\nWarning: MAC addresses don't match:\n"); - printf("\tHW MAC address: " - "%02X:%02X:%02X:%02X:%02X:%02X\n", - eeprom_enetaddr[0], eeprom_enetaddr[1], - eeprom_enetaddr[2], eeprom_enetaddr[3], - eeprom_enetaddr[4], eeprom_enetaddr[5]); - printf("\t\"ethaddr\" value: " - "%02X:%02X:%02X:%02X:%02X:%02X\n", - env_enetaddr[0], env_enetaddr[1], - env_enetaddr[2], env_enetaddr[3], - env_enetaddr[4], env_enetaddr[5]) ; - debug("### Set MAC addr from environment\n"); - memcpy(eeprom_enetaddr, env_enetaddr, 6); - } - if (!tmp) { - char ethaddr[20]; - - sprintf(ethaddr, "%02X:%02X:%02X:%02X:%02X:%02X", - eeprom_enetaddr[0], eeprom_enetaddr[1], - eeprom_enetaddr[2], eeprom_enetaddr[3], - eeprom_enetaddr[4], eeprom_enetaddr[5]) ; - debug("### Set environment from HW MAC addr = \"%s\"\n", - ethaddr); - setenv("ethaddr", ethaddr); - } - } + /* Read Ethernet MAC address from EEPROM if available. */ + if (sffsdr_read_mac_address(eeprom_enetaddr)) + dv_configure_mac_address(eeprom_enetaddr); if (!eth_hw_init()) printf("Ethernet init failed\n"); @@ -296,11 +176,3 @@ int misc_init_r(void) return(0); } - -int dram_init(void) -{ - gd->bd->bi_dram[0].start = PHYS_SDRAM_1; - gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; - - return(0); -} diff --git a/board/davinci/sonata/Makefile b/board/davinci/sonata/Makefile index 579efe2..fb31ee4 100644 --- a/board/davinci/sonata/Makefile +++ b/board/davinci/sonata/Makefile @@ -27,7 +27,7 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(BOARD).a -COBJS := dv_board.o +COBJS := $(BOARD).o SOBJS := board_init.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) diff --git a/board/davinci/sonata/dv_board.c b/board/davinci/sonata/dv_board.c deleted file mode 100644 index a6f9bc7..0000000 --- a/board/davinci/sonata/dv_board.c +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net> - * - * Parts are shamelessly stolen from various TI sources, original copyright - * follows: - * ----------------------------------------------------------------- - * - * Copyright (C) 2004 Texas Instruments. - * - * ---------------------------------------------------------------------------- - * 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., 675 Mass Ave, Cambridge, MA 02139, USA. - * ---------------------------------------------------------------------------- - */ - -#include <common.h> -#include <i2c.h> -#include <asm/arch/hardware.h> -#include <asm/arch/emac_defs.h> - -DECLARE_GLOBAL_DATA_PTR; - -extern void timer_init(void); -extern int eth_hw_init(void); - - -/* Works on Always On power domain only (no PD argument) */ -void lpsc_on(unsigned int id) -{ - dv_reg_p mdstat, mdctl; - - if (id >= DAVINCI_LPSC_GEM) - return; /* Don't work on DSP Power Domain */ - - mdstat = REG_P(PSC_MDSTAT_BASE + (id * 4)); - mdctl = REG_P(PSC_MDCTL_BASE + (id * 4)); - - while (REG(PSC_PTSTAT) & 0x01) {;} - - if ((*mdstat & 0x1f) == 0x03) - return; /* Already on and enabled */ - - *mdctl |= 0x03; - - /* Special treatment for some modules as for sprue14 p.7.4.2 */ - if ( (id == DAVINCI_LPSC_VPSSSLV) || - (id == DAVINCI_LPSC_EMAC) || - (id == DAVINCI_LPSC_EMAC_WRAPPER) || - (id == DAVINCI_LPSC_MDIO) || - (id == DAVINCI_LPSC_USB) || - (id == DAVINCI_LPSC_ATA) || - (id == DAVINCI_LPSC_VLYNQ) || - (id == DAVINCI_LPSC_UHPI) || - (id == DAVINCI_LPSC_DDR_EMIF) || - (id == DAVINCI_LPSC_AEMIF) || - (id == DAVINCI_LPSC_MMC_SD) || - (id == DAVINCI_LPSC_MEMSTICK) || - (id == DAVINCI_LPSC_McBSP) || - (id == DAVINCI_LPSC_GPIO) - ) - *mdctl |= 0x200; - - REG(PSC_PTCMD) = 0x01; - - while (REG(PSC_PTSTAT) & 0x03) {;} - while ((*mdstat & 0x1f) != 0x03) {;} /* Probably an overkill... */ -} - -void dsp_on(void) -{ - int i; - - if (REG(PSC_PDSTAT1) & 0x1f) - return; /* Already on */ - - REG(PSC_GBLCTL) |= 0x01; - REG(PSC_PDCTL1) |= 0x01; - REG(PSC_PDCTL1) &= ~0x100; - REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_GEM * 4)) |= 0x03; - REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_GEM * 4)) &= 0xfffffeff; - REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_IMCOP * 4)) |= 0x03; - REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_IMCOP * 4)) &= 0xfffffeff; - REG(PSC_PTCMD) = 0x02; - - for (i = 0; i < 100; i++) { - if (REG(PSC_EPCPR) & 0x02) - break; - } - - REG(PSC_CHP_SHRTSW) = 0x01; - REG(PSC_PDCTL1) |= 0x100; - REG(PSC_EPCCR) = 0x02; - - for (i = 0; i < 100; i++) { - if (!(REG(PSC_PTSTAT) & 0x02)) - break; - } - - REG(PSC_GBLCTL) &= ~0x1f; -} - - -int board_init(void) -{ - /* arch number of the board */ - gd->bd->bi_arch_number = MACH_TYPE_SONATA; - - /* address of boot parameters */ - gd->bd->bi_boot_params = LINUX_BOOT_PARAM_ADDR; - - /* Workaround for TMS320DM6446 errata 1.3.22 */ - REG(PSC_SILVER_BULLET) = 0; - - /* Power on required peripherals */ - lpsc_on(DAVINCI_LPSC_EMAC); - lpsc_on(DAVINCI_LPSC_EMAC_WRAPPER); - lpsc_on(DAVINCI_LPSC_MDIO); - lpsc_on(DAVINCI_LPSC_I2C); - lpsc_on(DAVINCI_LPSC_UART0); - lpsc_on(DAVINCI_LPSC_TIMER1); - lpsc_on(DAVINCI_LPSC_GPIO); - - /* Powerup the DSP */ - dsp_on(); - - /* Bringup UART0 out of reset */ - REG(UART0_PWREMU_MGMT) = 0x0000e003; - - /* Enable GIO3.3V cells used for EMAC */ - REG(VDD3P3V_PWDN) = 0; - - /* Enable UART0 MUX lines */ - REG(PINMUX1) |= 1; - - /* Enable EMAC and AEMIF pins */ - REG(PINMUX0) = 0x80000c1f; - - /* Enable I2C pin Mux */ - REG(PINMUX1) |= (1 << 7); - - /* Set the Bus Priority Register to appropriate value */ - REG(VBPR) = 0x20; - - timer_init(); - - return(0); -} - -int misc_init_r (void) -{ - u_int8_t tmp[20], buf[10]; - int i = 0; - int clk = 0; - - - clk = ((REG(PLL2_PLLM) + 1) * 27) / ((REG(PLL2_DIV2) & 0x1f) + 1); - - printf ("ARM Clock : %dMHz\n", ((REG(PLL1_PLLM) + 1) * 27 ) / 2); - printf ("DDR Clock : %dMHz\n", (clk / 2)); - - /* Set Ethernet MAC address from EEPROM */ - if (i2c_read(CFG_I2C_EEPROM_ADDR, 0x7f00, CFG_I2C_EEPROM_ADDR_LEN, buf, 6)) { - printf("\nEEPROM @ 0x%02x read FAILED!!!\n", CFG_I2C_EEPROM_ADDR); - } else { - tmp[0] = 0xff; - for (i = 0; i < 6; i++) - tmp[0] &= buf[i]; - - if ((tmp[0] != 0xff) && (getenv("ethaddr") == NULL)) { - sprintf((char *)&tmp[0], "%02x:%02x:%02x:%02x:%02x:%02x", - buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]); - setenv("ethaddr", (char *)&tmp[0]); - } - } - - if (!eth_hw_init()) - printf("ethernet init failed!\n"); - - return(0); -} - -int dram_init(void) -{ - gd->bd->bi_dram[0].start = PHYS_SDRAM_1; - gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; - - return(0); -} diff --git a/board/davinci/sonata/sonata.c b/board/davinci/sonata/sonata.c new file mode 100644 index 0000000..a6fe825 --- /dev/null +++ b/board/davinci/sonata/sonata.c @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net> + * + * Parts are shamelessly stolen from various TI sources, original copyright + * follows: + * ----------------------------------------------------------------- + * + * Copyright (C) 2004 Texas Instruments. + * + * ---------------------------------------------------------------------------- + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * ---------------------------------------------------------------------------- + */ + +#include <common.h> +#include <asm/arch/hardware.h> +#include <asm/arch/emac_defs.h> +#include "../common/psc.h" +#include "../common/misc.h" + +DECLARE_GLOBAL_DATA_PTR; + +int board_init(void) +{ + /* arch number of the board */ + gd->bd->bi_arch_number = MACH_TYPE_SONATA; + + /* address of boot parameters */ + gd->bd->bi_boot_params = LINUX_BOOT_PARAM_ADDR; + + /* Workaround for TMS320DM6446 errata 1.3.22 */ + REG(PSC_SILVER_BULLET) = 0; + + /* Power on required peripherals */ + lpsc_on(DAVINCI_LPSC_EMAC); + lpsc_on(DAVINCI_LPSC_EMAC_WRAPPER); + lpsc_on(DAVINCI_LPSC_MDIO); + lpsc_on(DAVINCI_LPSC_I2C); + lpsc_on(DAVINCI_LPSC_UART0); + lpsc_on(DAVINCI_LPSC_TIMER1); + lpsc_on(DAVINCI_LPSC_GPIO); + +#if !defined(CFG_USE_DSPLINK) + /* Powerup the DSP */ + dsp_on(); +#endif /* CFG_USE_DSPLINK */ + + /* Bringup UART0 out of reset */ + REG(UART0_PWREMU_MGMT) = 0x0000e003; + + /* Enable GIO3.3V cells used for EMAC */ + REG(VDD3P3V_PWDN) = 0; + + /* Enable UART0 MUX lines */ + REG(PINMUX1) |= 1; + + /* Enable EMAC and AEMIF pins */ + REG(PINMUX0) = 0x80000c1f; + + /* Enable I2C pin Mux */ + REG(PINMUX1) |= (1 << 7); + + /* Set the Bus Priority Register to appropriate value */ + REG(VBPR) = 0x20; + + timer_init(); + + return(0); +} + +int misc_init_r(void) +{ + uint8_t eeprom_enetaddr[6]; + + dv_display_clk_infos(); + + /* Read Ethernet MAC address from EEPROM if available. */ + if (dvevm_read_mac_address(eeprom_enetaddr)) + dv_configure_mac_address(eeprom_enetaddr); + + if (!eth_hw_init()) + printf("ethernet init failed!\n"); + + return(0); +} diff --git a/board/integratorap/Makefile b/board/integratorap/Makefile index f78de3a..79f501a 100644 --- a/board/integratorap/Makefile +++ b/board/integratorap/Makefile @@ -30,7 +30,7 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(BOARD).a COBJS := integratorap.o flash.o -SOBJS := lowlevel_init.o memsetup.o +SOBJS := lowlevel_init.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) diff --git a/board/integratorcp/Makefile b/board/integratorcp/Makefile index 9201acc..92a1a07 100644 --- a/board/integratorcp/Makefile +++ b/board/integratorcp/Makefile @@ -26,7 +26,7 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(BOARD).a COBJS := integratorcp.o flash.o -SOBJS := lowlevel_init.o memsetup.o +SOBJS := lowlevel_init.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) diff --git a/board/samsung/smdk6400/.gitignore b/board/samsung/smdk6400/.gitignore new file mode 100644 index 0000000..25ab492 --- /dev/null +++ b/board/samsung/smdk6400/.gitignore @@ -0,0 +1,5 @@ +# +# Generated files +# + +/config.tmp diff --git a/board/samsung/smdk6400/Makefile b/board/samsung/smdk6400/Makefile new file mode 100644 index 0000000..7130220 --- /dev/null +++ b/board/samsung/smdk6400/Makefile @@ -0,0 +1,54 @@ +# +# (C) Copyright 2000, 2001, 2002 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# (C) Copyright 2008 +# Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de> +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(BOARD).a + +COBJS-y := smdk6400.o +SOBJS := lowlevel_init.o + +SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS-y)) +SOBJS := $(addprefix $(obj),$(SOBJS)) + +$(LIB): $(obj).depend $(SOBJS) $(OBJS) + $(AR) $(ARFLAGS) $@ $(SOBJS) $(OBJS) + +clean: + rm -f $(SOBJS) $(OBJS) + +distclean: clean + rm -f $(LIB) core *.bak $(obj).depend + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/board/samsung/smdk6400/config.mk b/board/samsung/smdk6400/config.mk new file mode 100644 index 0000000..298d387 --- /dev/null +++ b/board/samsung/smdk6400/config.mk @@ -0,0 +1,30 @@ +# +# (C) Copyright 2002 +# Gary Jennejohn, DENX Software Engineering, <gj@denx.de> +# David Mueller, ELSOFT AG, <d.mueller@elsoft.ch> +# +# (C) Copyright 2008 +# Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de> +# +# SAMSUNG SMDK6400 board with mDirac3 (ARM1176) cpu +# +# see http://www.samsung.com/ for more information on SAMSUNG + +# On SMDK6400 we use the 64 MB SDRAM bank at +# +# 0x50000000 to 0x58000000 +# +# Linux-Kernel is expected to be at 0x50008000, entry 0x50008000 +# +# we load ourselves to 0x57e00000 without MMU +# with MMU, load address is changed to 0xc7e00000 +# +# download area is 0x5000c000 + +sinclude $(OBJTREE)/board/$(BOARDDIR)/config.tmp + +ifndef CONFIG_NAND_SPL +TEXT_BASE = $(RAM_TEXT) +else +TEXT_BASE = 0 +endif diff --git a/board/samsung/smdk6400/lowlevel_init.S b/board/samsung/smdk6400/lowlevel_init.S new file mode 100644 index 0000000..034c810 --- /dev/null +++ b/board/samsung/smdk6400/lowlevel_init.S @@ -0,0 +1,316 @@ +/* + * Memory Setup stuff - taken from blob memsetup.S + * + * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) and + * Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl) + * + * Modified for the Samsung SMDK2410 by + * (C) Copyright 2002 + * David Mueller, ELSOFT AG, <d.mueller@elsoft.ch> + * + * (C) Copyright 2008 + * Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + + +#include <config.h> +#include <version.h> + +#include <s3c6400.h> + +#ifdef CONFIG_SERIAL1 +#define ELFIN_UART_CONSOLE_BASE (ELFIN_UART_BASE + ELFIN_UART0_OFFSET) +#elif defined(CONFIG_SERIAL2) +#define ELFIN_UART_CONSOLE_BASE (ELFIN_UART_BASE + ELFIN_UART1_OFFSET) +#else +#define ELFIN_UART_CONSOLE_BASE (ELFIN_UART_BASE + ELFIN_UART2_OFFSET) +#endif + +_TEXT_BASE: + .word TEXT_BASE + + .globl lowlevel_init +lowlevel_init: + mov r12, lr + + /* LED on only #8 */ + ldr r0, =ELFIN_GPIO_BASE + ldr r1, =0x55540000 + str r1, [r0, #GPNCON_OFFSET] + + ldr r1, =0x55555555 + str r1, [r0, #GPNPUD_OFFSET] + + ldr r1, =0xf000 + str r1, [r0, #GPNDAT_OFFSET] + + /* Disable Watchdog */ + ldr r0, =0x7e000000 @0x7e004000 + orr r0, r0, #0x4000 + mov r1, #0 + str r1, [r0] + + /* External interrupt pending clear */ + ldr r0, =(ELFIN_GPIO_BASE+EINTPEND_OFFSET) /*EINTPEND*/ + ldr r1, [r0] + str r1, [r0] + + ldr r0, =ELFIN_VIC0_BASE_ADDR @0x71200000 + ldr r1, =ELFIN_VIC1_BASE_ADDR @0x71300000 + + /* Disable all interrupts (VIC0 and VIC1) */ + mvn r3, #0x0 + str r3, [r0, #oINTMSK] + str r3, [r1, #oINTMSK] + + /* Set all interrupts as IRQ */ + mov r3, #0x0 + str r3, [r0, #oINTMOD] + str r3, [r1, #oINTMOD] + + /* Pending Interrupt Clear */ + mov r3, #0x0 + str r3, [r0, #oVECTADDR] + str r3, [r1, #oVECTADDR] + + /* init system clock */ + bl system_clock_init + +#ifndef CONFIG_NAND_SPL + /* for UART */ + bl uart_asm_init +#endif + +#ifdef CONFIG_BOOT_NAND + /* simple init for NAND */ + bl nand_asm_init +#endif + + bl mem_ctrl_asm_init + +/* Wakeup support. Don't know if it's going to be used, untested. */ + ldr r0, =(ELFIN_CLOCK_POWER_BASE + RST_STAT_OFFSET) + ldr r1, [r0] + bic r1, r1, #0xfffffff7 + cmp r1, #0x8 + beq wakeup_reset + +1: + mov lr, r12 + mov pc, lr + +wakeup_reset: + + /* Clear wakeup status register */ + ldr r0, =(ELFIN_CLOCK_POWER_BASE + WAKEUP_STAT_OFFSET) + ldr r1, [r0] + str r1, [r0] + + /* LED test */ + ldr r0, =ELFIN_GPIO_BASE + ldr r1, =0x3000 + str r1, [r0, #GPNDAT_OFFSET] + + /* Load return address and jump to kernel */ + ldr r0, =(ELFIN_CLOCK_POWER_BASE + INF_REG0_OFFSET) + /* r1 = physical address of s3c6400_cpu_resume function */ + ldr r1, [r0] + /* Jump to kernel (sleep-s3c6400.S) */ + mov pc, r1 + nop + nop +/* + * system_clock_init: Initialize core clock and bus clock. + * void system_clock_init(void) + */ +system_clock_init: + ldr r0, =ELFIN_CLOCK_POWER_BASE /* 0x7e00f000 */ + +#ifdef CONFIG_SYNC_MODE + ldr r1, [r0, #OTHERS_OFFSET] + mov r2, #0x40 + orr r1, r1, r2 + str r1, [r0, #OTHERS_OFFSET] + + nop + nop + nop + nop + nop + + ldr r2, =0x80 + orr r1, r1, r2 + str r1, [r0, #OTHERS_OFFSET] + +check_syncack: + ldr r1, [r0, #OTHERS_OFFSET] + ldr r2, =0xf00 + and r1, r1, r2 + cmp r1, #0xf00 + bne check_syncack +#else /* ASYNC Mode */ + nop + nop + nop + nop + nop + + /* + * This was unconditional in original Samsung sources, but it doesn't + * seem to make much sense on S3C6400. + */ +#ifndef CONFIG_S3C6400 + ldr r1, [r0, #OTHERS_OFFSET] + bic r1, r1, #0xC0 + orr r1, r1, #0x40 + str r1, [r0, #OTHERS_OFFSET] + +wait_for_async: + ldr r1, [r0, #OTHERS_OFFSET] + and r1, r1, #0xf00 + cmp r1, #0x0 + bne wait_for_async +#endif + + ldr r1, [r0, #OTHERS_OFFSET] + bic r1, r1, #0x40 + str r1, [r0, #OTHERS_OFFSET] +#endif + + mov r1, #0xff00 + orr r1, r1, #0xff + str r1, [r0, #APLL_LOCK_OFFSET] + str r1, [r0, #MPLL_LOCK_OFFSET] + + /* Set Clock Divider */ + ldr r1, [r0, #CLK_DIV0_OFFSET] + bic r1, r1, #0x30000 + bic r1, r1, #0xff00 + bic r1, r1, #0xff + ldr r2, =CLK_DIV_VAL + orr r1, r1, r2 + str r1, [r0, #CLK_DIV0_OFFSET] + + ldr r1, =APLL_VAL + str r1, [r0, #APLL_CON_OFFSET] + ldr r1, =MPLL_VAL + str r1, [r0, #MPLL_CON_OFFSET] + + /* FOUT of EPLL is 96MHz */ + ldr r1, =0x200203 + str r1, [r0, #EPLL_CON0_OFFSET] + ldr r1, =0x0 + str r1, [r0, #EPLL_CON1_OFFSET] + + /* APLL, MPLL, EPLL select to Fout */ + ldr r1, [r0, #CLK_SRC_OFFSET] + orr r1, r1, #0x7 + str r1, [r0, #CLK_SRC_OFFSET] + + /* wait at least 200us to stablize all clock */ + mov r1, #0x10000 +1: subs r1, r1, #1 + bne 1b + + /* Synchronization for VIC port */ +#if defined(CONFIG_SYNC_MODE) + ldr r1, [r0, #OTHERS_OFFSET] + orr r1, r1, #0x20 + str r1, [r0, #OTHERS_OFFSET] +#elif !defined(CONFIG_S3C6400) + /* According to 661558um_S3C6400X_rev10.pdf 0x20 is reserved */ + ldr r1, [r0, #OTHERS_OFFSET] + bic r1, r1, #0x20 + str r1, [r0, #OTHERS_OFFSET] +#endif + mov pc, lr + + +#ifndef CONFIG_NAND_SPL +/* + * uart_asm_init: Initialize UART's pins + */ +uart_asm_init: + /* set GPIO to enable UART */ + ldr r0, =ELFIN_GPIO_BASE + ldr r1, =0x220022 + str r1, [r0, #GPACON_OFFSET] + mov pc, lr +#endif + +#ifdef CONFIG_BOOT_NAND +/* + * NAND Interface init for SMDK6400 + */ +nand_asm_init: + ldr r0, =ELFIN_NAND_BASE + ldr r1, [r0, #NFCONF_OFFSET] + orr r1, r1, #0x70 + orr r1, r1, #0x7700 + str r1, [r0, #NFCONF_OFFSET] + + ldr r1, [r0, #NFCONT_OFFSET] + orr r1, r1, #0x07 + str r1, [r0, #NFCONT_OFFSET] + + mov pc, lr +#endif + +#ifdef CONFIG_ENABLE_MMU +/* + * MMU Table for SMDK6400 + */ + + /* form a first-level section entry */ +.macro FL_SECTION_ENTRY base,ap,d,c,b + .word (\base << 20) | (\ap << 10) | \ + (\d << 5) | (1<<4) | (\c << 3) | (\b << 2) | (1<<1) +.endm + +.section .mmudata, "a" + .align 14 + /* the following alignment creates the mmu table at address 0x4000. */ + .globl mmu_table +mmu_table: + .set __base, 0 + /* 1:1 mapping for debugging */ + .rept 0xA00 + FL_SECTION_ENTRY __base, 3, 0, 0, 0 + .set __base, __base + 1 + .endr + + /* access is not allowed. */ + .rept 0xC00 - 0xA00 + .word 0x00000000 + .endr + + /* 128MB for SDRAM 0xC0000000 -> 0x50000000 */ + .set __base, 0x500 + .rept 0xC80 - 0xC00 + FL_SECTION_ENTRY __base, 3, 0, 1, 1 + .set __base, __base + 1 + .endr + + /* access is not allowed. */ + .rept 0x1000 - 0xc80 + .word 0x00000000 + .endr +#endif diff --git a/board/samsung/smdk6400/smdk6400.c b/board/samsung/smdk6400/smdk6400.c new file mode 100644 index 0000000..77fd2c8 --- /dev/null +++ b/board/samsung/smdk6400/smdk6400.c @@ -0,0 +1,130 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * (C) Copyright 2002 + * David Mueller, ELSOFT AG, <d.mueller@elsoft.ch> + * + * (C) Copyright 2008 + * Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <s3c6400.h> + +/* ------------------------------------------------------------------------- */ +#define CS8900_Tacs 0x0 /* 0clk address set-up */ +#define CS8900_Tcos 0x4 /* 4clk chip selection set-up */ +#define CS8900_Tacc 0xE /* 14clk access cycle */ +#define CS8900_Tcoh 0x1 /* 1clk chip selection hold */ +#define CS8900_Tah 0x4 /* 4clk address holding time */ +#define CS8900_Tacp 0x6 /* 6clk page mode access cycle */ +#define CS8900_PMC 0x0 /* normal(1data)page mode configuration */ + +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 + */ + +static void cs8900_pre_init(void) +{ + SROM_BW_REG &= ~(0xf << 4); + SROM_BW_REG |= (1 << 7) | (1 << 6) | (1 << 4); + SROM_BC1_REG = ((CS8900_Tacs << 28) + (CS8900_Tcos << 24) + + (CS8900_Tacc << 16) + (CS8900_Tcoh << 12) + + (CS8900_Tah << 8) + (CS8900_Tacp << 4) + CS8900_PMC); +} + +int board_init(void) +{ + DECLARE_GLOBAL_DATA_PTR; + + cs8900_pre_init(); + + /* NOR-flash in SROM0 */ + + /* Enable WAIT */ + SROM_BW_REG |= 4 | 8 | 1; + + gd->bd->bi_arch_number = MACH_TYPE; + gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100; + + return 0; +} + +int dram_init(void) +{ + DECLARE_GLOBAL_DATA_PTR; + + gd->bd->bi_dram[0].start = PHYS_SDRAM_1; + gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; + + return 0; +} + +#ifdef CONFIG_DISPLAY_BOARDINFO +int checkboard(void) +{ + printf("Board: SMDK6400\n"); + return 0; +} +#endif + +#ifdef CONFIG_ENABLE_MMU +ulong virt_to_phy_smdk6400(ulong addr) +{ + if ((0xc0000000 <= addr) && (addr < 0xc8000000)) + return addr - 0xc0000000 + 0x50000000; + else + printf("do not support this address : %08lx\n", addr); + + return addr; +} +#endif + +#if defined(CONFIG_CMD_NAND) && defined(CFG_NAND_LEGACY) +#include <linux/mtd/nand.h> +extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE]; +void nand_init(void) +{ + nand_probe(CFG_NAND_BASE); + if (nand_dev_desc[0].ChipID != NAND_ChipID_UNKNOWN) + print_size(nand_dev_desc[0].totlen, "\n"); +} +#endif + +ulong board_flash_get_legacy (ulong base, int banknum, flash_info_t *info) +{ + if (banknum == 0) { /* non-CFI boot flash */ + info->portwidth = FLASH_CFI_16BIT; + info->chipwidth = FLASH_CFI_BY16; + info->interface = FLASH_CFI_X16; + return 1; + } else + return 0; +} diff --git a/board/samsung/smdk6400/u-boot-nand.lds b/board/samsung/smdk6400/u-boot-nand.lds new file mode 100644 index 0000000..132ab21 --- /dev/null +++ b/board/samsung/smdk6400/u-boot-nand.lds @@ -0,0 +1,62 @@ +/* + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, <gj@denx.de> + * + * (C) Copyright 2008 + * Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + . = 0x00000000; + + . = ALIGN(4); + .text : + { + cpu/arm1176/start.o (.text) + cpu/arm1176/s3c64xx/cpu_init.o (.text) + *(.text) + } + + . = ALIGN(4); + .rodata : { *(.rodata) } + + . = ALIGN(4); + .data : { *(.data) } + + . = ALIGN(4); + .got : { *(.got) } + + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + . = ALIGN(4); + .mmudata : { *(.mmudata) } + + . = ALIGN(4); + __bss_start = .; + .bss : { *(.bss) } + _end = .; +} diff --git a/cpu/arm1176/Makefile b/cpu/arm1176/Makefile new file mode 100644 index 0000000..1ca9199 --- /dev/null +++ b/cpu/arm1176/Makefile @@ -0,0 +1,50 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# (C) Copyright 2008 +# Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de> +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(CPU).a + +START = start.o +COBJS = cpu.o + +SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) +START := $(addprefix $(obj),$(START)) + +all: $(obj).depend $(START) $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/cpu/arm1176/config.mk b/cpu/arm1176/config.mk new file mode 100644 index 0000000..5083594 --- /dev/null +++ b/cpu/arm1176/config.mk @@ -0,0 +1,35 @@ +# +# (C) Copyright 2002 +# Gary Jennejohn, DENX Software Engineering, <gj@denx.de> +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +PLATFORM_RELFLAGS += -fno-strict-aliasing -fno-common -ffixed-r8 \ + -msoft-float + +# Make ARMv5 to allow more compilers to work, even though its v6. +PLATFORM_CPPFLAGS += -march=armv5t +# ========================================================================= +# +# Supply options according to compiler version +# +# ========================================================================= +PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) +PLATFORM_CPPFLAGS +=$(call cc-option,-mno-thumb-interwork,) +PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/cpu/arm1176/cpu.c b/cpu/arm1176/cpu.c new file mode 100644 index 0000000..1e94f7d --- /dev/null +++ b/cpu/arm1176/cpu.c @@ -0,0 +1,188 @@ +/* + * (C) Copyright 2004 Texas Insturments + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, <gj@denx.de> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * CPU specific code + */ + +#include <common.h> +#include <command.h> +#include <s3c6400.h> + +static void cache_flush (void); + +/* read co-processor 15, register #1 (control register) */ +static unsigned long read_p15_c1 (void) +{ + unsigned long value; + + __asm__ __volatile__( + "mrc p15, 0, %0, c1, c0, 0 @ read control reg\n" + : "=r" (value) + : + : "memory"); + return value; +} + +/* write to co-processor 15, register #1 (control register) */ +static void write_p15_c1 (unsigned long value) +{ + __asm__ __volatile__( + "mcr p15, 0, %0, c1, c0, 0 @ write it back\n" + : + : "r" (value) + : "memory"); + + read_p15_c1(); +} + +static void cp_delay (void) +{ + volatile int i; + + /* Many OMAP regs need at least 2 nops */ + for (i = 0; i < 100; i++) + __asm__ __volatile__("nop\n"); +} + +/* See also ARM Ref. Man. */ +#define C1_MMU (1 << 0) /* mmu off/on */ +#define C1_ALIGN (1 << 1) /* alignment faults off/on */ +#define C1_DC (1 << 2) /* dcache off/on */ +#define C1_WB (1 << 3) /* merging write buffer on/off */ +#define C1_BIG_ENDIAN (1 << 7) /* big endian off/on */ +#define C1_SYS_PROT (1 << 8) /* system protection */ +#define C1_ROM_PROT (1 << 9) /* ROM protection */ +#define C1_IC (1 << 12) /* icache off/on */ +#define C1_HIGH_VECTORS (1 << 13) /* location of vectors: low/high */ +#define RESERVED_1 (0xf << 3) /* must be 111b for R/W */ + +int cpu_init (void) +{ + return 0; +} + +int cleanup_before_linux (void) +{ + /* + * this function is called just before we call linux + * it prepares the processor for linux + * + * we turn off caches etc ... + */ + + disable_interrupts (); + + /* turn off I/D-cache */ + icache_disable(); + dcache_disable(); + cache_flush(); + + return 0; +} + + +/* * reset the cpu by setting up the watchdog timer and let him time out */ +void reset_cpu (ulong ignored) +{ + printf("reset... \n\n\n"); + SW_RST_REG = 0x6400; + /* loop forever and wait for reset to happen */ + while (1) { + if (serial_tstc()) { + serial_getc(); + break; + } + } + /*NOTREACHED*/ +} + +int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + disable_interrupts (); + reset_cpu (0); + /*NOTREACHED*/ + return 0; +} + +void icache_enable (void) +{ + ulong reg; + + reg = read_p15_c1 (); /* get control reg. */ + cp_delay (); + write_p15_c1 (reg | C1_IC); +} + +void icache_disable (void) +{ + ulong reg; + + reg = read_p15_c1 (); + cp_delay (); + write_p15_c1 (reg & ~C1_IC); +} + +int icache_status (void) +{ + return (read_p15_c1 () & C1_IC) != 0; +} + +/* It makes no sense to use the dcache if the MMU is not enabled */ +void dcache_enable (void) +{ + ulong reg; + + reg = read_p15_c1 (); + cp_delay (); + write_p15_c1 (reg | C1_DC); +} + +void dcache_disable (void) +{ + ulong reg; + + reg = read_p15_c1 (); + cp_delay (); + write_p15_c1 (reg & ~C1_DC); +} + +int dcache_status (void) +{ + return (read_p15_c1 () & C1_DC) != 0; +} + +/* flush I/D-cache */ +static void cache_flush (void) +{ + /* invalidate both caches and flush btb */ + asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (0)); + /* mem barrier to sync things */ + asm ("mcr p15, 0, %0, c7, c10, 4": :"r" (0)); +} diff --git a/cpu/arm1176/s3c64xx/Makefile b/cpu/arm1176/s3c64xx/Makefile new file mode 100644 index 0000000..4ab1811 --- /dev/null +++ b/cpu/arm1176/s3c64xx/Makefile @@ -0,0 +1,49 @@ +# +# (C) Copyright 2000-2003 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# (C) Copyright 2008 +# Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de> +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(SOC).a + +COBJS-y = interrupts.o +COBJS-$(CONFIG_S3C6400) += cpu_init.o speed.o +COBJS-$(CONFIG_USB_OHCI_NEW) += usb.o + +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS-y)) + +all: $(obj).depend $(START) $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/cpu/arm1176/s3c64xx/config.mk b/cpu/arm1176/s3c64xx/config.mk new file mode 100644 index 0000000..204e880 --- /dev/null +++ b/cpu/arm1176/s3c64xx/config.mk @@ -0,0 +1,34 @@ +# +# (C) Copyright 2002 +# Gary Jennejohn, DENX Software Engineering, <gj@denx.de> +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +PLATFORM_RELFLAGS += -fno-strict-aliasing -fno-common -ffixed-r8 \ + -msoft-float + +# Make ARMv5 to allow more compilers to work, even though its v6. +PLATFORM_CPPFLAGS += -march=armv5t +# ========================================================================= +# +# Supply options according to compiler version +# +# ========================================================================= +#PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) +PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/cpu/arm1176/s3c64xx/cpu_init.S b/cpu/arm1176/s3c64xx/cpu_init.S new file mode 100644 index 0000000..08bda99 --- /dev/null +++ b/cpu/arm1176/s3c64xx/cpu_init.S @@ -0,0 +1,142 @@ +/* + * Originates from Samsung's u-boot 1.1.6 port to S3C6400 / SMDK6400 + * + * Copyright (C) 2008 + * Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <config.h> +#include <s3c6400.h> + + .globl mem_ctrl_asm_init +mem_ctrl_asm_init: + /* Memory subsystem address 0x7e00f120 */ + ldr r0, =ELFIN_MEM_SYS_CFG + + /* Xm0CSn2 = NFCON CS0, Xm0CSn3 = NFCON CS1 */ + mov r1, #0xd + str r1, [r0] + + /* DMC1 base address 0x7e001000 */ + ldr r0, =ELFIN_DMC1_BASE + + ldr r1, =0x4 + str r1, [r0, #INDEX_DMC_MEMC_CMD] + + ldr r1, =DMC_DDR_REFRESH_PRD + str r1, [r0, #INDEX_DMC_REFRESH_PRD] + + ldr r1, =DMC_DDR_CAS_LATENCY + str r1, [r0, #INDEX_DMC_CAS_LATENCY] + + ldr r1, =DMC_DDR_t_DQSS + str r1, [r0, #INDEX_DMC_T_DQSS] + + ldr r1, =DMC_DDR_t_MRD + str r1, [r0, #INDEX_DMC_T_MRD] + + ldr r1, =DMC_DDR_t_RAS + str r1, [r0, #INDEX_DMC_T_RAS] + + ldr r1, =DMC_DDR_t_RC + str r1, [r0, #INDEX_DMC_T_RC] + + ldr r1, =DMC_DDR_t_RCD + ldr r2, =DMC_DDR_schedule_RCD + orr r1, r1, r2 + str r1, [r0, #INDEX_DMC_T_RCD] + + ldr r1, =DMC_DDR_t_RFC + ldr r2, =DMC_DDR_schedule_RFC + orr r1, r1, r2 + str r1, [r0, #INDEX_DMC_T_RFC] + + ldr r1, =DMC_DDR_t_RP + ldr r2, =DMC_DDR_schedule_RP + orr r1, r1, r2 + str r1, [r0, #INDEX_DMC_T_RP] + + ldr r1, =DMC_DDR_t_RRD + str r1, [r0, #INDEX_DMC_T_RRD] + + ldr r1, =DMC_DDR_t_WR + str r1, [r0, #INDEX_DMC_T_WR] + + ldr r1, =DMC_DDR_t_WTR + str r1, [r0, #INDEX_DMC_T_WTR] + + ldr r1, =DMC_DDR_t_XP + str r1, [r0, #INDEX_DMC_T_XP] + + ldr r1, =DMC_DDR_t_XSR + str r1, [r0, #INDEX_DMC_T_XSR] + + ldr r1, =DMC_DDR_t_ESR + str r1, [r0, #INDEX_DMC_T_ESR] + + ldr r1, =DMC1_MEM_CFG + str r1, [r0, #INDEX_DMC_MEMORY_CFG] + + ldr r1, =DMC1_MEM_CFG2 + str r1, [r0, #INDEX_DMC_MEMORY_CFG2] + + ldr r1, =DMC1_CHIP0_CFG + str r1, [r0, #INDEX_DMC_CHIP_0_CFG] + + ldr r1, =DMC_DDR_32_CFG + str r1, [r0, #INDEX_DMC_USER_CONFIG] + + /* DMC0 DDR Chip 0 configuration direct command reg */ + ldr r1, =DMC_NOP0 + str r1, [r0, #INDEX_DMC_DIRECT_CMD] + + /* Precharge All */ + ldr r1, =DMC_PA0 + str r1, [r0, #INDEX_DMC_DIRECT_CMD] + + /* Auto Refresh 2 time */ + ldr r1, =DMC_AR0 + str r1, [r0, #INDEX_DMC_DIRECT_CMD] + str r1, [r0, #INDEX_DMC_DIRECT_CMD] + + /* MRS */ + ldr r1, =DMC_mDDR_EMR0 + str r1, [r0, #INDEX_DMC_DIRECT_CMD] + + /* Mode Reg */ + ldr r1, =DMC_mDDR_MR0 + str r1, [r0, #INDEX_DMC_DIRECT_CMD] + + /* Enable DMC1 */ + mov r1, #0x0 + str r1, [r0, #INDEX_DMC_MEMC_CMD] + +check_dmc1_ready: + ldr r1, [r0, #INDEX_DMC_MEMC_STATUS] + mov r2, #0x3 + and r1, r1, r2 + cmp r1, #0x1 + bne check_dmc1_ready + nop + + mov pc, lr + + .ltorg diff --git a/cpu/arm1176/s3c64xx/interrupts.c b/cpu/arm1176/s3c64xx/interrupts.c new file mode 100644 index 0000000..8356ae4 --- /dev/null +++ b/cpu/arm1176/s3c64xx/interrupts.c @@ -0,0 +1,174 @@ +/* + * (C) Copyright 2003 + * Texas Instruments <www.ti.com> + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Alex Zuepke <azu@sysgo.de> + * + * (C) Copyright 2002-2004 + * Gary Jennejohn, DENX Software Engineering, <gj@denx.de> + * + * (C) Copyright 2004 + * Philippe Robin, ARM Ltd. <philippe.robin@arm.com> + * + * (C) Copyright 2008 + * Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/proc-armv/ptrace.h> +#include <s3c6400.h> + +static ulong timer_load_val; + +#define PRESCALER 167 + +static s3c64xx_timers *s3c64xx_get_base_timers(void) +{ + return (s3c64xx_timers *)ELFIN_TIMER_BASE; +} + +/* macro to read the 16 bit timer */ +static inline ulong read_timer(void) +{ + s3c64xx_timers *const timers = s3c64xx_get_base_timers(); + + return timers->TCNTO4; +} + +/* Internal tick units */ +/* Last decremneter snapshot */ +static unsigned long lastdec; +/* Monotonic incrementing timer */ +static unsigned long long timestamp; + +int interrupt_init(void) +{ + s3c64xx_timers *const timers = s3c64xx_get_base_timers(); + + /* use PWM Timer 4 because it has no output */ + /* + * We use the following scheme for the timer: + * Prescaler is hard fixed at 167, divider at 1/4. + * This gives at PCLK frequency 66MHz approx. 10us ticks + * The timer is set to wrap after 100s, at 66MHz this obviously + * happens after 10,000,000 ticks. A long variable can thus + * keep values up to 40,000s, i.e., 11 hours. This should be + * enough for most uses:-) Possible optimizations: select a + * binary-friendly frequency, e.g., 1ms / 128. Also calculate + * the prescaler automatically for other PCLK frequencies. + */ + timers->TCFG0 = PRESCALER << 8; + if (timer_load_val == 0) { + timer_load_val = get_PCLK() / PRESCALER * (100 / 4); /* 100s */ + timers->TCFG1 = (timers->TCFG1 & ~0xf0000) | 0x20000; + } + + /* load value for 10 ms timeout */ + lastdec = timers->TCNTB4 = timer_load_val; + /* auto load, manual update of Timer 4 */ + timers->TCON = (timers->TCON & ~0x00700000) | TCON_4_AUTO | + TCON_4_UPDATE; + + /* auto load, start Timer 4 */ + timers->TCON = (timers->TCON & ~0x00700000) | TCON_4_AUTO | COUNT_4_ON; + timestamp = 0; + + return 0; +} + +/* + * timer without interrupts + */ + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + ulong now = read_timer(); + + if (lastdec >= now) { + /* normal mode */ + timestamp += lastdec - now; + } else { + /* we have an overflow ... */ + timestamp += lastdec + timer_load_val - now; + } + lastdec = now; + + return timestamp; +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk(void) +{ + /* We overrun in 100s */ + return (ulong)(timer_load_val / 100); +} + +void reset_timer_masked(void) +{ + /* reset time */ + lastdec = read_timer(); + timestamp = 0; +} + +void reset_timer(void) +{ + reset_timer_masked(); +} + +ulong get_timer_masked(void) +{ + return get_ticks() / (timer_load_val / (100 * CFG_HZ)); +} + +ulong get_timer(ulong base) +{ + return get_timer_masked() - base; +} + +void set_timer(ulong t) +{ + timestamp = t * (timer_load_val / (100 * CFG_HZ)); +} + +void udelay(unsigned long usec) +{ + unsigned long long tmp; + ulong tmo; + + tmo = (usec + 9) / 10; + tmp = get_ticks() + tmo; /* get current timestamp */ + + while (get_ticks() < tmp)/* loop till event */ + /*NOP*/; +} diff --git a/cpu/arm1176/s3c64xx/speed.c b/cpu/arm1176/s3c64xx/speed.c new file mode 100644 index 0000000..5c335a5 --- /dev/null +++ b/cpu/arm1176/s3c64xx/speed.c @@ -0,0 +1,145 @@ +/* + * (C) Copyright 2001-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2002 + * David Mueller, ELSOFT AG, d.mueller@elsoft.ch + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * This code should work for both the S3C2400 and the S3C2410 + * as they seem to have the same PLL and clock machinery inside. + * The different address mapping is handled by the s3c24xx.h files below. + */ + +#include <common.h> +#include <s3c6400.h> + +#define APLL 0 +#define MPLL 1 +#define EPLL 2 + +/* ------------------------------------------------------------------------- */ +/* + * NOTE: This describes the proper use of this file. + * + * CONFIG_SYS_CLK_FREQ should be defined as the input frequency of the PLL. + * + * get_FCLK(), get_HCLK(), get_PCLK() and get_UCLK() return the clock of + * the specified bus in HZ. + */ +/* ------------------------------------------------------------------------- */ + +static ulong get_PLLCLK(int pllreg) +{ + ulong r, m, p, s; + + switch (pllreg) { + case APLL: + r = APLL_CON_REG; + break; + case MPLL: + r = MPLL_CON_REG; + break; + case EPLL: + r = EPLL_CON0_REG; + break; + default: + hang(); + } + + m = (r >> 16) & 0x3ff; + p = (r >> 8) & 0x3f; + s = r & 0x7; + + return m * (CONFIG_SYS_CLK_FREQ / (p * (1 << s))); +} + +/* return ARMCORE frequency */ +ulong get_ARMCLK(void) +{ + ulong div; + + div = CLK_DIV0_REG; + + return get_PLLCLK(APLL) / ((div & 0x7) + 1); +} + +/* return FCLK frequency */ +ulong get_FCLK(void) +{ + return get_PLLCLK(APLL); +} + +/* return HCLK frequency */ +ulong get_HCLK(void) +{ + ulong fclk; + + uint hclkx2_div = ((CLK_DIV0_REG >> 9) & 0x7) + 1; + uint hclk_div = ((CLK_DIV0_REG >> 8) & 0x1) + 1; + + /* + * Bit 7 exists on s3c6410, and not on s3c6400, it is reserved on + * s3c6400 and is always 0, and it is indeed running in ASYNC mode + */ + if (OTHERS_REG & 0x80) + fclk = get_FCLK(); /* SYNC Mode */ + else + fclk = get_PLLCLK(MPLL); /* ASYNC Mode */ + + return fclk / (hclk_div * hclkx2_div); +} + +/* return PCLK frequency */ +ulong get_PCLK(void) +{ + ulong fclk; + uint hclkx2_div = ((CLK_DIV0_REG >> 9) & 0x7) + 1; + uint pre_div = ((CLK_DIV0_REG >> 12) & 0xf) + 1; + + if (OTHERS_REG & 0x80) + fclk = get_FCLK(); /* SYNC Mode */ + else + fclk = get_PLLCLK(MPLL); /* ASYNC Mode */ + + return fclk / (hclkx2_div * pre_div); +} + +/* return UCLK frequency */ +ulong get_UCLK(void) +{ + return get_PLLCLK(EPLL); +} + +int print_cpuinfo(void) +{ + printf("\nCPU: S3C6400@%luMHz\n", get_ARMCLK() / 1000000); + printf(" Fclk = %luMHz, Hclk = %luMHz, Pclk = %luMHz ", + get_FCLK() / 1000000, get_HCLK() / 1000000, + get_PCLK() / 1000000); + + if (OTHERS_REG & 0x80) + printf("(SYNC Mode) \n"); + else + printf("(ASYNC Mode) \n"); + return 0; +} diff --git a/board/integratorcp/memsetup.S b/cpu/arm1176/s3c64xx/usb.c index da43cb6..274a4ed 100644 --- a/board/integratorcp/memsetup.S +++ b/cpu/arm1176/s3c64xx/usb.c @@ -1,5 +1,8 @@ /* - * Memory setup for integratorAP + * URB OHCI HCD (Host Controller Driver) initialization for USB on the S3C64XX. + * + * Copyright (C) 2008, + * Guennadi Liakhovetski, DENX Software Engineering <lg@denx.de> * * See file CREDITS for list of people who contributed to this * project. @@ -18,12 +21,25 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA + * */ -/* - * Memory setup - * - the reset defaults are assumed sufficient - */ -.globl memsetup -memsetup: - mov pc,lr +#include <common.h> +#include <s3c6400.h> + +int usb_cpu_init(void) +{ + OTHERS_REG |= 0x10000; + return 0; +} + +int usb_cpu_stop(void) +{ + OTHERS_REG &= ~0x10000; + return 0; +} + +void usb_cpu_init_fail(void) +{ + OTHERS_REG &= ~0x10000; +} diff --git a/cpu/arm1176/start.S b/cpu/arm1176/start.S new file mode 100644 index 0000000..991277f --- /dev/null +++ b/cpu/arm1176/start.S @@ -0,0 +1,469 @@ +/* + * armboot - Startup Code for S3C6400/ARM1176 CPU-core + * + * Copyright (c) 2007 Samsung Electronics + * + * Copyright (C) 2008 + * Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * 2007-09-21 - Restructured codes by jsgood (jsgood.yang@samsung.com) + * 2007-09-21 - Added MoviNAND and OneNAND boot codes by + * jsgood (jsgood.yang@samsung.com) + * Base codes by scsuh (sc.suh) + */ + +#include <config.h> +#include <version.h> +#ifdef CONFIG_ENABLE_MMU +#include <asm/proc/domain.h> +#endif +#include <s3c6400.h> + +#if !defined(CONFIG_ENABLE_MMU) && !defined(CFG_PHY_UBOOT_BASE) +#define CFG_PHY_UBOOT_BASE CFG_UBOOT_BASE +#endif + +/* + ************************************************************************* + * + * Jump vector table as in table 3.1 in [1] + * + ************************************************************************* + */ + +.globl _start +_start: b reset +#ifndef CONFIG_NAND_SPL + ldr pc, _undefined_instruction + ldr pc, _software_interrupt + ldr pc, _prefetch_abort + ldr pc, _data_abort + ldr pc, _not_used + ldr pc, _irq + ldr pc, _fiq + +_undefined_instruction: + .word undefined_instruction +_software_interrupt: + .word software_interrupt +_prefetch_abort: + .word prefetch_abort +_data_abort: + .word data_abort +_not_used: + .word not_used +_irq: + .word irq +_fiq: + .word fiq +_pad: + .word 0x12345678 /* now 16*4=64 */ +#else + . = _start + 64 +#endif + +.global _end_vect +_end_vect: + .balignl 16,0xdeadbeef +/* + ************************************************************************* + * + * Startup Code (reset vector) + * + * do important init only if we don't start from memory! + * setup Memory and board specific bits prior to relocation. + * relocate armboot to ram + * setup stack + * + ************************************************************************* + */ + +_TEXT_BASE: + .word TEXT_BASE + +/* + * Below variable is very important because we use MMU in U-Boot. + * Without it, we cannot run code correctly before MMU is ON. + * by scsuh. + */ +_TEXT_PHY_BASE: + .word CFG_PHY_UBOOT_BASE + +.globl _armboot_start +_armboot_start: + .word _start + +/* + * These are defined in the board-specific linker script. + */ +.globl _bss_start +_bss_start: + .word __bss_start + +.globl _bss_end +_bss_end: + .word _end + +/* + * the actual reset code + */ + +reset: + /* + * set the cpu to SVC32 mode + */ + mrs r0, cpsr + bic r0, r0, #0x3f + orr r0, r0, #0xd3 + msr cpsr, r0 + +/* + ************************************************************************* + * + * CPU_init_critical registers + * + * setup important registers + * setup memory timing + * + ************************************************************************* + */ + /* + * we do sys-critical inits only at reboot, + * not when booting from ram! + */ +cpu_init_crit: + /* + * When booting from NAND - it has definitely been a reset, so, no need + * to flush caches and disable the MMU + */ +#ifndef CONFIG_NAND_SPL + /* + * flush v4 I/D caches + */ + mov r0, #0 + mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */ + mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */ + + /* + * disable MMU stuff and caches + */ + mrc p15, 0, r0, c1, c0, 0 + bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS) + bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM) + orr r0, r0, #0x00000002 @ set bit 2 (A) Align + orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache + /* Prepare to disable the MMU */ + adr r1, mmu_disable_phys + /* We presume we're within the first 1024 bytes */ + and r1, r1, #0x3fc + ldr r2, _TEXT_PHY_BASE + ldr r3, =0xfff00000 + and r2, r2, r3 + orr r2, r2, r1 + b mmu_disable + + .align 5 + /* Run in a single cache-line */ +mmu_disable: + mcr p15, 0, r0, c1, c0, 0 + nop + nop + mov pc, r2 +#endif + +mmu_disable_phys: + /* Peri port setup */ + ldr r0, =0x70000000 + orr r0, r0, #0x13 + mcr p15,0,r0,c15,c2,4 @ 256M (0x70000000 - 0x7fffffff) + + /* + * Go setup Memory and board specific bits prior to relocation. + */ + bl lowlevel_init /* go setup pll,mux,memory */ + +after_copy: +#ifdef CONFIG_ENABLE_MMU +enable_mmu: + /* enable domain access */ + ldr r5, =0x0000ffff + mcr p15, 0, r5, c3, c0, 0 /* load domain access register */ + + /* Set the TTB register */ + ldr r0, _mmu_table_base + ldr r1, =CFG_PHY_UBOOT_BASE + ldr r2, =0xfff00000 + bic r0, r0, r2 + orr r1, r0, r1 + mcr p15, 0, r1, c2, c0, 0 + + /* Enable the MMU */ + mrc p15, 0, r0, c1, c0, 0 + orr r0, r0, #1 /* Set CR_M to enable MMU */ + + /* Prepare to enable the MMU */ + adr r1, skip_hw_init + and r1, r1, #0x3fc + ldr r2, _TEXT_BASE + ldr r3, =0xfff00000 + and r2, r2, r3 + orr r2, r2, r1 + b mmu_enable + + .align 5 + /* Run in a single cache-line */ +mmu_enable: + + mcr p15, 0, r0, c1, c0, 0 + nop + nop + mov pc, r2 +#endif + +skip_hw_init: + /* Set up the stack */ +stack_setup: +#ifdef CONFIG_MEMORY_UPPER_CODE + ldr sp, =(CFG_UBOOT_BASE + CFG_UBOOT_SIZE - 0xc) +#else + ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ + sub r0, r0, #CFG_MALLOC_LEN /* malloc area */ + sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */ + sub sp, r0, #12 /* leave 3 words for abort-stack */ + +#endif + +clear_bss: + ldr r0, _bss_start /* find start of bss segment */ + ldr r1, _bss_end /* stop here */ + mov r2, #0 /* clear */ + +clbss_l: + str r2, [r0] /* clear loop... */ + add r0, r0, #4 + cmp r0, r1 + ble clbss_l + +#ifndef CONFIG_NAND_SPL + ldr pc, _start_armboot + +_start_armboot: + .word start_armboot +#else + b nand_boot +/* .word nand_boot*/ +#endif + +#ifdef CONFIG_ENABLE_MMU +_mmu_table_base: + .word mmu_table +#endif + +#ifndef CONFIG_NAND_SPL +/* + * we assume that cache operation is done before. (eg. cleanup_before_linux()) + * actually, we don't need to do anything about cache if not use d-cache in + * U-Boot. So, in this function we clean only MMU. by scsuh + * + * void theLastJump(void *kernel, int arch_num, uint boot_params); + */ +#ifdef CONFIG_ENABLE_MMU + .globl theLastJump +theLastJump: + mov r9, r0 + ldr r3, =0xfff00000 + ldr r4, _TEXT_PHY_BASE + adr r5, phy_last_jump + bic r5, r5, r3 + orr r5, r5, r4 + mov pc, r5 +phy_last_jump: + /* + * disable MMU stuff + */ + mrc p15, 0, r0, c1, c0, 0 + bic r0, r0, #0x00002300 /* clear bits 13, 9:8 (--V- --RS) */ + bic r0, r0, #0x00000087 /* clear bits 7, 2:0 (B--- -CAM) */ + orr r0, r0, #0x00000002 /* set bit 2 (A) Align */ + orr r0, r0, #0x00001000 /* set bit 12 (I) I-Cache */ + mcr p15, 0, r0, c1, c0, 0 + + mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */ + + mov r0, #0 + mov pc, r9 +#endif +/* + ************************************************************************* + * + * Interrupt handling + * + ************************************************************************* + */ +@ +@ IRQ stack frame. +@ +#define S_FRAME_SIZE 72 + +#define S_OLD_R0 68 +#define S_PSR 64 +#define S_PC 60 +#define S_LR 56 +#define S_SP 52 + +#define S_IP 48 +#define S_FP 44 +#define S_R10 40 +#define S_R9 36 +#define S_R8 32 +#define S_R7 28 +#define S_R6 24 +#define S_R5 20 +#define S_R4 16 +#define S_R3 12 +#define S_R2 8 +#define S_R1 4 +#define S_R0 0 + +#define MODE_SVC 0x13 +#define I_BIT 0x80 + +/* + * use bad_save_user_regs for abort/prefetch/undef/swi ... + */ + + .macro bad_save_user_regs + /* carve out a frame on current user stack */ + sub sp, sp, #S_FRAME_SIZE + /* Save user registers (now in svc mode) r0-r12 */ + stmia sp, {r0 - r12} + + ldr r2, _armboot_start + sub r2, r2, #(CFG_MALLOC_LEN) + /* set base 2 words into abort stack */ + sub r2, r2, #(CFG_GBL_DATA_SIZE+8) + /* get values for "aborted" pc and cpsr (into parm regs) */ + ldmia r2, {r2 - r3} + /* grab pointer to old stack */ + add r0, sp, #S_FRAME_SIZE + + add r5, sp, #S_SP + mov r1, lr + /* save sp_SVC, lr_SVC, pc, cpsr */ + stmia r5, {r0 - r3} + /* save current stack into r0 (param register) */ + mov r0, sp + .endm + + .macro get_bad_stack + /* setup our mode stack (enter in banked mode) */ + ldr r13, _armboot_start + /* move past malloc pool */ + sub r13, r13, #(CFG_MALLOC_LEN) + /* move to reserved a couple spots for abort stack */ + sub r13, r13, #(CFG_GBL_DATA_SIZE + 8) + + /* save caller lr in position 0 of saved stack */ + str lr, [r13] + /* get the spsr */ + mrs lr, spsr + /* save spsr in position 1 of saved stack */ + str lr, [r13, #4] + + /* prepare SVC-Mode */ + mov r13, #MODE_SVC + @ msr spsr_c, r13 + /* switch modes, make sure moves will execute */ + msr spsr, r13 + /* capture return pc */ + mov lr, pc + /* jump to next instruction & switch modes. */ + movs pc, lr + .endm + + .macro get_bad_stack_swi + /* space on current stack for scratch reg. */ + sub r13, r13, #4 + /* save R0's value. */ + str r0, [r13] + /* get data regions start */ + ldr r0, _armboot_start + /* move past malloc pool */ + sub r0, r0, #(CFG_MALLOC_LEN) + /* move past gbl and a couple spots for abort stack */ + sub r0, r0, #(CFG_GBL_DATA_SIZE + 8) + /* save caller lr in position 0 of saved stack */ + str lr, [r0] + /* get the spsr */ + mrs r0, spsr + /* save spsr in position 1 of saved stack */ + str lr, [r0, #4] + /* restore r0 */ + ldr r0, [r13] + /* pop stack entry */ + add r13, r13, #4 + .endm + +/* + * exception handlers + */ + .align 5 +undefined_instruction: + get_bad_stack + bad_save_user_regs + bl do_undefined_instruction + + .align 5 +software_interrupt: + get_bad_stack_swi + bad_save_user_regs + bl do_software_interrupt + + .align 5 +prefetch_abort: + get_bad_stack + bad_save_user_regs + bl do_prefetch_abort + + .align 5 +data_abort: + get_bad_stack + bad_save_user_regs + bl do_data_abort + + .align 5 +not_used: + get_bad_stack + bad_save_user_regs + bl do_not_used + + .align 5 +irq: + get_bad_stack + bad_save_user_regs + bl do_irq + + .align 5 +fiq: + get_bad_stack + bad_save_user_regs + bl do_fiq +#endif /* CONFIG_NAND_SPL */ diff --git a/cpu/arm926ejs/davinci/dp83848.c b/cpu/arm926ejs/davinci/dp83848.c index 2aa9ef1..59f039b 100644 --- a/cpu/arm926ejs/davinci/dp83848.c +++ b/cpu/arm926ejs/davinci/dp83848.c @@ -38,9 +38,9 @@ int dp83848_is_phy_connected(int phy_addr) { u_int16_t id1, id2; - if (!dm644x_eth_phy_read(phy_addr, DP83848_PHYID1_REG, &id1)) + if (!davinci_eth_phy_read(phy_addr, DP83848_PHYID1_REG, &id1)) return(0); - if (!dm644x_eth_phy_read(phy_addr, DP83848_PHYID2_REG, &id2)) + if (!davinci_eth_phy_read(phy_addr, DP83848_PHYID2_REG, &id2)) return(0); if ((id1 == DP83848_PHYID1_OUI) && (id2 == DP83848_PHYID2_OUI)) @@ -54,13 +54,13 @@ int dp83848_get_link_speed(int phy_addr) u_int16_t tmp; volatile emac_regs* emac = (emac_regs *)EMAC_BASE_ADDR; - if (!dm644x_eth_phy_read(phy_addr, DP83848_STAT_REG, &tmp)) + if (!davinci_eth_phy_read(phy_addr, DP83848_STAT_REG, &tmp)) return(0); if (!(tmp & DP83848_LINK_STATUS)) /* link up? */ return(0); - if (!dm644x_eth_phy_read(phy_addr, DP83848_PHY_STAT_REG, &tmp)) + if (!davinci_eth_phy_read(phy_addr, DP83848_PHY_STAT_REG, &tmp)) return(0); /* Speed doesn't matter, there is no setting for it in EMAC... */ @@ -101,7 +101,7 @@ int dp83848_init_phy(int phy_addr) } /* Disable PHY Interrupts */ - dm644x_eth_phy_write(phy_addr, DP83848_PHY_INTR_CTRL_REG, 0); + davinci_eth_phy_write(phy_addr, DP83848_PHY_INTR_CTRL_REG, 0); return(ret); } @@ -112,13 +112,13 @@ int dp83848_auto_negotiate(int phy_addr) u_int16_t tmp; - if (!dm644x_eth_phy_read(phy_addr, DP83848_CTL_REG, &tmp)) + if (!davinci_eth_phy_read(phy_addr, DP83848_CTL_REG, &tmp)) return(0); /* Restart Auto_negotiation */ tmp &= ~DP83848_AUTONEG; /* remove autonegotiation enable */ tmp |= DP83848_ISOLATE; /* Electrically isolate PHY */ - dm644x_eth_phy_write(phy_addr, DP83848_CTL_REG, tmp); + davinci_eth_phy_write(phy_addr, DP83848_CTL_REG, tmp); /* Set the Auto_negotiation Advertisement Register * MII advertising for Next page, 100BaseTxFD and HD, @@ -126,23 +126,23 @@ int dp83848_auto_negotiate(int phy_addr) */ tmp = DP83848_NP | DP83848_TX_FDX | DP83848_TX_HDX | DP83848_10_FDX | DP83848_10_HDX | DP83848_AN_IEEE_802_3; - dm644x_eth_phy_write(phy_addr, DP83848_ANA_REG, tmp); + davinci_eth_phy_write(phy_addr, DP83848_ANA_REG, tmp); /* Read Control Register */ - if (!dm644x_eth_phy_read(phy_addr, DP83848_CTL_REG, &tmp)) + if (!davinci_eth_phy_read(phy_addr, DP83848_CTL_REG, &tmp)) return(0); tmp |= DP83848_SPEED_SELECT | DP83848_AUTONEG | DP83848_DUPLEX_MODE; - dm644x_eth_phy_write(phy_addr, DP83848_CTL_REG, tmp); + davinci_eth_phy_write(phy_addr, DP83848_CTL_REG, tmp); /* Restart Auto_negotiation */ tmp |= DP83848_RESTART_AUTONEG; - dm644x_eth_phy_write(phy_addr, DP83848_CTL_REG, tmp); + davinci_eth_phy_write(phy_addr, DP83848_CTL_REG, tmp); /*check AutoNegotiate complete */ udelay(10000); - if (!dm644x_eth_phy_read(phy_addr, DP83848_STAT_REG, &tmp)) + if (!davinci_eth_phy_read(phy_addr, DP83848_STAT_REG, &tmp)) return(0); if (!(tmp & DP83848_AUTONEG_COMP)) diff --git a/cpu/arm926ejs/davinci/ether.c b/cpu/arm926ejs/davinci/ether.c index 5ae035b..f6f81df 100644 --- a/cpu/arm926ejs/davinci/ether.c +++ b/cpu/arm926ejs/davinci/ether.c @@ -50,12 +50,12 @@ unsigned int emac_dbg = 0; #define debug_emac(fmt,args...) if (emac_dbg) printf(fmt,##args) /* Internal static functions */ -static int dm644x_eth_hw_init (void); -static int dm644x_eth_open (void); -static int dm644x_eth_close (void); -static int dm644x_eth_send_packet (volatile void *packet, int length); -static int dm644x_eth_rcv_packet (void); -static void dm644x_eth_mdio_enable(void); +static int davinci_eth_hw_init (void); +static int davinci_eth_open (void); +static int davinci_eth_close (void); +static int davinci_eth_send_packet (volatile void *packet, int length); +static int davinci_eth_rcv_packet (void); +static void davinci_eth_mdio_enable(void); static int gen_init_phy(int phy_addr); static int gen_is_phy_connected(int phy_addr); @@ -65,48 +65,48 @@ static int gen_auto_negotiate(int phy_addr); /* Wrappers exported to the U-Boot proper */ int eth_hw_init(void) { - return(dm644x_eth_hw_init()); + return(davinci_eth_hw_init()); } int eth_init(bd_t * bd) { - return(dm644x_eth_open()); + return(davinci_eth_open()); } void eth_halt(void) { - dm644x_eth_close(); + davinci_eth_close(); } int eth_send(volatile void *packet, int length) { - return(dm644x_eth_send_packet(packet, length)); + return(davinci_eth_send_packet(packet, length)); } int eth_rx(void) { - return(dm644x_eth_rcv_packet()); + return(davinci_eth_rcv_packet()); } void eth_mdio_enable(void) { - dm644x_eth_mdio_enable(); + davinci_eth_mdio_enable(); } /* End of wrappers */ -static u_int8_t dm644x_eth_mac_addr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; +static u_int8_t davinci_eth_mac_addr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; /* * This function must be called before emac_open() if you want to override * the default mac address. */ -void dm644x_eth_set_mac_addr(const u_int8_t *addr) +void davinci_eth_set_mac_addr(const u_int8_t *addr) { int i; - for (i = 0; i < sizeof (dm644x_eth_mac_addr); i++) { - dm644x_eth_mac_addr[i] = addr[i]; + for (i = 0; i < sizeof (davinci_eth_mac_addr); i++) { + davinci_eth_mac_addr[i] = addr[i]; } } @@ -130,7 +130,7 @@ static volatile u_int8_t active_phy_addr = 0xff; phy_t phy; -static void dm644x_eth_mdio_enable(void) +static void davinci_eth_mdio_enable(void) { u_int32_t clkdiv; @@ -149,7 +149,7 @@ static void dm644x_eth_mdio_enable(void) * If no active PHY (or more than one PHY) found returns 0. * Sets active_phy_addr variable. */ -static int dm644x_eth_phy_detect(void) +static int davinci_eth_phy_detect(void) { u_int32_t phy_act_state; int i; @@ -159,7 +159,7 @@ static int dm644x_eth_phy_detect(void) if ((phy_act_state = adap_mdio->ALIVE) == 0) return(0); /* No active PHYs */ - debug_emac("dm644x_eth_phy_detect(), ALIVE = 0x%08x\n", phy_act_state); + debug_emac("davinci_eth_phy_detect(), ALIVE = 0x%08x\n", phy_act_state); for (i = 0; i < 32; i++) { if (phy_act_state & (1 << i)) { @@ -177,7 +177,7 @@ static int dm644x_eth_phy_detect(void) /* Read a PHY register via MDIO inteface. Returns 1 on success, 0 otherwise */ -int dm644x_eth_phy_read(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t *data) +int davinci_eth_phy_read(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t *data) { int tmp; @@ -201,7 +201,7 @@ int dm644x_eth_phy_read(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t *data) } /* Write to a PHY register via MDIO inteface. Blocks until operation is complete. */ -int dm644x_eth_phy_write(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t data) +int davinci_eth_phy_write(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t data) { while (adap_mdio->USERACCESS0 & MDIO_USERACCESS0_GO) {;} @@ -235,14 +235,14 @@ static int gen_is_phy_connected(int phy_addr) { u_int16_t dummy; - return(dm644x_eth_phy_read(phy_addr, PHY_PHYIDR1, &dummy)); + return(davinci_eth_phy_read(phy_addr, PHY_PHYIDR1, &dummy)); } static int gen_get_link_speed(int phy_addr) { u_int16_t tmp; - if (dm644x_eth_phy_read(phy_addr, MII_STATUS_REG, &tmp) && (tmp & 0x04)) + if (davinci_eth_phy_read(phy_addr, MII_STATUS_REG, &tmp) && (tmp & 0x04)) return(1); return(0); @@ -252,16 +252,16 @@ static int gen_auto_negotiate(int phy_addr) { u_int16_t tmp; - if (!dm644x_eth_phy_read(phy_addr, PHY_BMCR, &tmp)) + if (!davinci_eth_phy_read(phy_addr, PHY_BMCR, &tmp)) return(0); /* Restart Auto_negotiation */ tmp |= PHY_BMCR_AUTON; - dm644x_eth_phy_write(phy_addr, PHY_BMCR, tmp); + davinci_eth_phy_write(phy_addr, PHY_BMCR, tmp); /*check AutoNegotiate complete */ udelay (10000); - if (!dm644x_eth_phy_read(phy_addr, PHY_BMSR, &tmp)) + if (!davinci_eth_phy_read(phy_addr, PHY_BMSR, &tmp)) return(0); if (!(tmp & PHY_BMSR_AUTN_COMP)) @@ -273,19 +273,19 @@ static int gen_auto_negotiate(int phy_addr) #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) -static int dm644x_mii_phy_read(char *devname, unsigned char addr, unsigned char reg, unsigned short *value) +static int davinci_mii_phy_read(char *devname, unsigned char addr, unsigned char reg, unsigned short *value) { - return(dm644x_eth_phy_read(addr, reg, value) ? 0 : 1); + return(davinci_eth_phy_read(addr, reg, value) ? 0 : 1); } -static int dm644x_mii_phy_write(char *devname, unsigned char addr, unsigned char reg, unsigned short value) +static int davinci_mii_phy_write(char *devname, unsigned char addr, unsigned char reg, unsigned short value) { - return(dm644x_eth_phy_write(addr, reg, value) ? 0 : 1); + return(davinci_eth_phy_write(addr, reg, value) ? 0 : 1); } -int dm644x_eth_miiphy_initialize(bd_t *bis) +int davinci_eth_miiphy_initialize(bd_t *bis) { - miiphy_register(phy.name, dm644x_mii_phy_read, dm644x_mii_phy_write); + miiphy_register(phy.name, davinci_mii_phy_read, davinci_mii_phy_write); return(1); } @@ -296,13 +296,13 @@ int dm644x_eth_miiphy_initialize(bd_t *bis) * EMAC modules power or pin multiplexors, that is done by board_init() * much earlier in bootup process. Returns 1 on success, 0 otherwise. */ -static int dm644x_eth_hw_init(void) +static int davinci_eth_hw_init(void) { u_int32_t phy_id; u_int16_t tmp; int i; - dm644x_eth_mdio_enable(); + davinci_eth_mdio_enable(); for (i = 0; i < 256; i++) { if (adap_mdio->ALIVE) @@ -316,18 +316,18 @@ static int dm644x_eth_hw_init(void) } /* Find if a PHY is connected and get it's address */ - if (!dm644x_eth_phy_detect()) + if (!davinci_eth_phy_detect()) return(0); /* Get PHY ID and initialize phy_ops for a detected PHY */ - if (!dm644x_eth_phy_read(active_phy_addr, PHY_PHYIDR1, &tmp)) { + if (!davinci_eth_phy_read(active_phy_addr, PHY_PHYIDR1, &tmp)) { active_phy_addr = 0xff; return(0); } phy_id = (tmp << 16) & 0xffff0000; - if (!dm644x_eth_phy_read(active_phy_addr, PHY_PHYIDR2, &tmp)) { + if (!davinci_eth_phy_read(active_phy_addr, PHY_PHYIDR2, &tmp)) { active_phy_addr = 0xff; return(0); } @@ -364,7 +364,7 @@ static int dm644x_eth_hw_init(void) /* Eth device open */ -static int dm644x_eth_open(void) +static int davinci_eth_open(void) { dv_reg_p addr; u_int32_t clkdiv, cnt; @@ -389,26 +389,26 @@ static int dm644x_eth_open(void) /* Using channel 0 only - other channels are disabled */ adap_emac->MACINDEX = 0; adap_emac->MACADDRHI = - (dm644x_eth_mac_addr[3] << 24) | - (dm644x_eth_mac_addr[2] << 16) | - (dm644x_eth_mac_addr[1] << 8) | - (dm644x_eth_mac_addr[0]); + (davinci_eth_mac_addr[3] << 24) | + (davinci_eth_mac_addr[2] << 16) | + (davinci_eth_mac_addr[1] << 8) | + (davinci_eth_mac_addr[0]); adap_emac->MACADDRLO = - (dm644x_eth_mac_addr[5] << 8) | - (dm644x_eth_mac_addr[4]); + (davinci_eth_mac_addr[5] << 8) | + (davinci_eth_mac_addr[4]); adap_emac->MACHASH1 = 0; adap_emac->MACHASH2 = 0; /* Set source MAC address - REQUIRED */ adap_emac->MACSRCADDRHI = - (dm644x_eth_mac_addr[3] << 24) | - (dm644x_eth_mac_addr[2] << 16) | - (dm644x_eth_mac_addr[1] << 8) | - (dm644x_eth_mac_addr[0]); + (davinci_eth_mac_addr[3] << 24) | + (davinci_eth_mac_addr[2] << 16) | + (davinci_eth_mac_addr[1] << 8) | + (davinci_eth_mac_addr[0]); adap_emac->MACSRCADDRLO = - (dm644x_eth_mac_addr[4] << 8) | - (dm644x_eth_mac_addr[5]); + (davinci_eth_mac_addr[4] << 8) | + (davinci_eth_mac_addr[5]); /* Set DMA 8 TX / 8 RX Head pointers to 0 */ addr = &adap_emac->TX0HDP; @@ -473,7 +473,7 @@ static int dm644x_eth_open(void) } /* EMAC Channel Teardown */ -static void dm644x_eth_ch_teardown(int ch) +static void davinci_eth_ch_teardown(int ch) { dv_reg dly = 0xff; dv_reg cnt; @@ -516,12 +516,12 @@ static void dm644x_eth_ch_teardown(int ch) } /* Eth device close */ -static int dm644x_eth_close(void) +static int davinci_eth_close(void) { debug_emac("+ emac_close\n"); - dm644x_eth_ch_teardown(EMAC_CH_TX); /* TX Channel teardown */ - dm644x_eth_ch_teardown(EMAC_CH_RX); /* RX Channel teardown */ + davinci_eth_ch_teardown(EMAC_CH_TX); /* TX Channel teardown */ + davinci_eth_ch_teardown(EMAC_CH_RX); /* RX Channel teardown */ /* Reset EMAC module and disable interrupts in wrapper */ adap_emac->SOFTRESET = 1; @@ -537,7 +537,7 @@ static int tx_send_loop = 0; * This function sends a single packet on the network and returns * positive number (number of bytes transmitted) or negative for error */ -static int dm644x_eth_send_packet (volatile void *packet, int length) +static int davinci_eth_send_packet (volatile void *packet, int length) { int ret_status = -1; @@ -568,7 +568,7 @@ static int dm644x_eth_send_packet (volatile void *packet, int length) /* Wait for packet to complete or link down */ while (1) { if (!phy.get_link_speed (active_phy_addr)) { - dm644x_eth_ch_teardown (EMAC_CH_TX); + davinci_eth_ch_teardown (EMAC_CH_TX); return (ret_status); } if (adap_emac->TXINTSTATRAW & 0x01) { @@ -584,7 +584,7 @@ static int dm644x_eth_send_packet (volatile void *packet, int length) /* * This function handles receipt of a packet from the network */ -static int dm644x_eth_rcv_packet (void) +static int davinci_eth_rcv_packet (void) { volatile emac_desc *rx_curr_desc; volatile emac_desc *curr_desc; diff --git a/cpu/arm926ejs/davinci/lxt972.c b/cpu/arm926ejs/davinci/lxt972.c index 8130b48..ce3e41c 100644 --- a/cpu/arm926ejs/davinci/lxt972.c +++ b/cpu/arm926ejs/davinci/lxt972.c @@ -39,9 +39,9 @@ int lxt972_is_phy_connected(int phy_addr) { u_int16_t id1, id2; - if (!dm644x_eth_phy_read(phy_addr, PHY_PHYIDR1, &id1)) + if (!davinci_eth_phy_read(phy_addr, PHY_PHYIDR1, &id1)) return(0); - if (!dm644x_eth_phy_read(phy_addr, PHY_PHYIDR2, &id2)) + if (!davinci_eth_phy_read(phy_addr, PHY_PHYIDR2, &id2)) return(0); if ((id1 == (0x0013)) && ((id2 & 0xfff0) == 0x78e0)) @@ -55,20 +55,20 @@ int lxt972_get_link_speed(int phy_addr) u_int16_t stat1, tmp; volatile emac_regs *emac = (emac_regs *)EMAC_BASE_ADDR; - if (!dm644x_eth_phy_read(phy_addr, PHY_LXT971_STAT2, &stat1)) + if (!davinci_eth_phy_read(phy_addr, PHY_LXT971_STAT2, &stat1)) return(0); if (!(stat1 & PHY_LXT971_STAT2_LINK)) /* link up? */ return(0); - if (!dm644x_eth_phy_read(phy_addr, PHY_LXT971_DIG_CFG, &tmp)) + if (!davinci_eth_phy_read(phy_addr, PHY_LXT971_DIG_CFG, &tmp)) return(0); tmp |= PHY_LXT971_DIG_CFG_MII_DRIVE; - dm644x_eth_phy_write(phy_addr, PHY_LXT971_DIG_CFG, tmp); + davinci_eth_phy_write(phy_addr, PHY_LXT971_DIG_CFG, tmp); /* Read back */ - if (!dm644x_eth_phy_read(phy_addr, PHY_LXT971_DIG_CFG, &tmp)) + if (!davinci_eth_phy_read(phy_addr, PHY_LXT971_DIG_CFG, &tmp)) return(0); /* Speed doesn't matter, there is no setting for it in EMAC... */ @@ -95,7 +95,7 @@ int lxt972_init_phy(int phy_addr) } /* Disable PHY Interrupts */ - dm644x_eth_phy_write(phy_addr, PHY_LXT971_INT_ENABLE, 0); + davinci_eth_phy_write(phy_addr, PHY_LXT971_INT_ENABLE, 0); return(ret); } @@ -105,16 +105,16 @@ int lxt972_auto_negotiate(int phy_addr) { u_int16_t tmp; - if (!dm644x_eth_phy_read(phy_addr, PHY_BMCR, &tmp)) + if (!davinci_eth_phy_read(phy_addr, PHY_BMCR, &tmp)) return(0); /* Restart Auto_negotiation */ tmp |= PHY_BMCR_RST_NEG; - dm644x_eth_phy_write(phy_addr, PHY_BMCR, tmp); + davinci_eth_phy_write(phy_addr, PHY_BMCR, tmp); /*check AutoNegotiate complete */ udelay (10000); - if (!dm644x_eth_phy_read(phy_addr, PHY_BMSR, &tmp)) + if (!davinci_eth_phy_read(phy_addr, PHY_BMSR, &tmp)) return(0); if (!(tmp & PHY_BMSR_AUTN_COMP)) diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile index 1923310..b0abe6e 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile @@ -37,6 +37,7 @@ endif COBJS-$(CONFIG_NAND_FSL_ELBC) += fsl_elbc_nand.o COBJS-$(CONFIG_NAND_FSL_UPM) += fsl_upm.o +COBJS-$(CONFIG_NAND_S3C64XX) += s3c64xx.o endif COBJS := $(COBJS-y) diff --git a/drivers/mtd/nand/s3c64xx.c b/drivers/mtd/nand/s3c64xx.c new file mode 100644 index 0000000..159fe76 --- /dev/null +++ b/drivers/mtd/nand/s3c64xx.c @@ -0,0 +1,319 @@ +/* + * (C) Copyright 2006 DENX Software Engineering + * + * Implementation for U-Boot 1.1.6 by Samsung + * + * (C) Copyright 2008 + * Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> + +#include <nand.h> +#include <s3c6400.h> + +#include <asm/io.h> +#include <asm/errno.h> + +#define MAX_CHIPS 2 +static int nand_cs[MAX_CHIPS] = {0, 1}; + +#ifdef CONFIG_NAND_SPL +#define printf(arg...) do {} while (0) +#endif + +/* Nand flash definition values by jsgood */ +#ifdef S3C_NAND_DEBUG +/* + * Function to print out oob buffer for debugging + * Written by jsgood + */ +static void print_oob(const char *header, struct mtd_info *mtd) +{ + int i; + struct nand_chip *chip = mtd->priv; + + printf("%s:\t", header); + + for (i = 0; i < 64; i++) + printf("%02x ", chip->oob_poi[i]); + + printf("\n"); +} +#endif /* S3C_NAND_DEBUG */ + +#ifdef CONFIG_NAND_SPL +static u_char nand_read_byte(struct mtd_info *mtd) +{ + struct nand_chip *this = mtd->priv; + return readb(this->IO_ADDR_R); +} + +static void nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) +{ + int i; + struct nand_chip *this = mtd->priv; + + for (i = 0; i < len; i++) + writeb(buf[i], this->IO_ADDR_W); +} + +static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) +{ + int i; + struct nand_chip *this = mtd->priv; + + for (i = 0; i < len; i++) + buf[i] = readb(this->IO_ADDR_R); +} +#endif + +static void s3c_nand_select_chip(struct mtd_info *mtd, int chip) +{ + int ctrl = readl(NFCONT); + + switch (chip) { + case -1: + ctrl |= 6; + break; + case 0: + ctrl &= ~2; + break; + case 1: + ctrl &= ~4; + break; + default: + return; + } + + writel(ctrl, NFCONT); +} + +/* + * Hardware specific access to control-lines function + * Written by jsgood + */ +static void s3c_nand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) +{ + struct nand_chip *this = mtd->priv; + + if (ctrl & NAND_CTRL_CHANGE) { + if (ctrl & NAND_CLE) + this->IO_ADDR_W = (void __iomem *)NFCMMD; + else if (ctrl & NAND_ALE) + this->IO_ADDR_W = (void __iomem *)NFADDR; + else + this->IO_ADDR_W = (void __iomem *)NFDATA; + if (ctrl & NAND_NCE) + s3c_nand_select_chip(mtd, *(int *)this->priv); + else + s3c_nand_select_chip(mtd, -1); + } + + if (cmd != NAND_CMD_NONE) + writeb(cmd, this->IO_ADDR_W); +} + +/* + * Function for checking device ready pin + * Written by jsgood + */ +static int s3c_nand_device_ready(struct mtd_info *mtdinfo) +{ + return !!(readl(NFSTAT) & NFSTAT_RnB); +} + +#ifdef CFG_S3C_NAND_HWECC +/* + * This function is called before encoding ecc codes to ready ecc engine. + * Written by jsgood + */ +static void s3c_nand_enable_hwecc(struct mtd_info *mtd, int mode) +{ + u_long nfcont, nfconf; + + /* + * The original driver used 4-bit ECC for "new" MLC chips, i.e., for + * those with non-zero ID[3][3:2], which anyway only holds for ST + * (Numonyx) chips + */ + nfconf = readl(NFCONF) & ~NFCONF_ECC_4BIT; + + writel(nfconf, NFCONF); + + /* Initialize & unlock */ + nfcont = readl(NFCONT); + nfcont |= NFCONT_INITECC; + nfcont &= ~NFCONT_MECCLOCK; + + if (mode == NAND_ECC_WRITE) + nfcont |= NFCONT_ECC_ENC; + else if (mode == NAND_ECC_READ) + nfcont &= ~NFCONT_ECC_ENC; + + writel(nfcont, NFCONT); +} + +/* + * This function is called immediately after encoding ecc codes. + * This function returns encoded ecc codes. + * Written by jsgood + */ +static int s3c_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, + u_char *ecc_code) +{ + u_long nfcont, nfmecc0; + + /* Lock */ + nfcont = readl(NFCONT); + nfcont |= NFCONT_MECCLOCK; + writel(nfcont, NFCONT); + + nfmecc0 = readl(NFMECC0); + + ecc_code[0] = nfmecc0 & 0xff; + ecc_code[1] = (nfmecc0 >> 8) & 0xff; + ecc_code[2] = (nfmecc0 >> 16) & 0xff; + ecc_code[3] = (nfmecc0 >> 24) & 0xff; + + return 0; +} + +/* + * This function determines whether read data is good or not. + * If SLC, must write ecc codes to controller before reading status bit. + * If MLC, status bit is already set, so only reading is needed. + * If status bit is good, return 0. + * If correctable errors occured, do that. + * If uncorrectable errors occured, return -1. + * Written by jsgood + */ +static int s3c_nand_correct_data(struct mtd_info *mtd, u_char *dat, + u_char *read_ecc, u_char *calc_ecc) +{ + int ret = -1; + u_long nfestat0, nfmeccdata0, nfmeccdata1, err_byte_addr; + u_char err_type, repaired; + + /* SLC: Write ecc to compare */ + nfmeccdata0 = (calc_ecc[1] << 16) | calc_ecc[0]; + nfmeccdata1 = (calc_ecc[3] << 16) | calc_ecc[2]; + writel(nfmeccdata0, NFMECCDATA0); + writel(nfmeccdata1, NFMECCDATA1); + + /* Read ecc status */ + nfestat0 = readl(NFESTAT0); + err_type = nfestat0 & 0x3; + + switch (err_type) { + case 0: /* No error */ + ret = 0; + break; + + case 1: + /* + * 1 bit error (Correctable) + * (nfestat0 >> 7) & 0x7ff :error byte number + * (nfestat0 >> 4) & 0x7 :error bit number + */ + err_byte_addr = (nfestat0 >> 7) & 0x7ff; + repaired = dat[err_byte_addr] ^ (1 << ((nfestat0 >> 4) & 0x7)); + + printf("S3C NAND: 1 bit error detected at byte %ld. " + "Correcting from 0x%02x to 0x%02x...OK\n", + err_byte_addr, dat[err_byte_addr], repaired); + + dat[err_byte_addr] = repaired; + + ret = 1; + break; + + case 2: /* Multiple error */ + case 3: /* ECC area error */ + printf("S3C NAND: ECC uncorrectable error detected. " + "Not correctable.\n"); + ret = -1; + break; + } + + return ret; +} +#endif /* CFG_S3C_NAND_HWECC */ + +/* + * Board-specific NAND initialization. The following members of the + * argument are board-specific (per include/linux/mtd/nand.h): + * - IO_ADDR_R?: address to read the 8 I/O lines of the flash device + * - IO_ADDR_W?: address to write the 8 I/O lines of the flash device + * - hwcontrol: hardwarespecific function for accesing control-lines + * - dev_ready: hardwarespecific function for accesing device ready/busy line + * - enable_hwecc?: function to enable (reset) hardware ecc generator. Must + * only be provided if a hardware ECC is available + * - eccmode: mode of ecc, see defines + * - chip_delay: chip dependent delay for transfering data from array to + * read regs (tR) + * - options: various chip options. They can partly be set to inform + * nand_scan about special functionality. See the defines for further + * explanation + * Members with a "?" were not set in the merged testing-NAND branch, + * so they are not set here either. + */ +int board_nand_init(struct nand_chip *nand) +{ + static int chip_n; + + if (chip_n >= MAX_CHIPS) + return -ENODEV; + + NFCONT_REG = (NFCONT_REG & ~NFCONT_WP) | NFCONT_ENABLE | 0x6; + + nand->IO_ADDR_R = (void __iomem *)NFDATA; + nand->IO_ADDR_W = (void __iomem *)NFDATA; + nand->cmd_ctrl = s3c_nand_hwcontrol; + nand->dev_ready = s3c_nand_device_ready; + nand->select_chip = s3c_nand_select_chip; + nand->options = 0; +#ifdef CONFIG_NAND_SPL + nand->read_byte = nand_read_byte; + nand->write_buf = nand_write_buf; + nand->read_buf = nand_read_buf; +#endif + +#ifdef CFG_S3C_NAND_HWECC + nand->ecc.hwctl = s3c_nand_enable_hwecc; + nand->ecc.calculate = s3c_nand_calculate_ecc; + nand->ecc.correct = s3c_nand_correct_data; + + /* + * If you get more than 1 NAND-chip with different page-sizes on the + * board one day, it will get more complicated... + */ + nand->ecc.mode = NAND_ECC_HW; + nand->ecc.size = CFG_NAND_ECCSIZE; + nand->ecc.bytes = CFG_NAND_ECCBYTES; +#else + nand->ecc.mode = NAND_ECC_SOFT; +#endif /* ! CFG_S3C_NAND_HWECC */ + + nand->priv = nand_cs + chip_n++; + + return 0; +} diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index 2384735..f30014d 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -30,6 +30,7 @@ COBJS-$(CONFIG_MCFUART) += mcfuart.o COBJS-$(CONFIG_NS9750_UART) += ns9750_serial.o COBJS-y += ns16550.o COBJS-$(CONFIG_DRIVER_S3C4510_UART) += s3c4510b_uart.o +COBJS-$(CONFIG_S3C64XX) += s3c64xx.o COBJS-y += serial.o COBJS-$(CONFIG_MAX3100_SERIAL) += serial_max3100.o COBJS-y += serial_pl010.o diff --git a/drivers/serial/s3c64xx.c b/drivers/serial/s3c64xx.c new file mode 100644 index 0000000..9d8fcb9 --- /dev/null +++ b/drivers/serial/s3c64xx.c @@ -0,0 +1,172 @@ +/* + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, <gj@denx.de> + * + * (C) Copyright 2008 + * Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <common.h> + +#include <s3c6400.h> + +#ifdef CONFIG_SERIAL1 +#define UART_NR S3C64XX_UART0 + +#elif defined(CONFIG_SERIAL2) +#define UART_NR S3C64XX_UART1 + +#elif defined(CONFIG_SERIAL3) +#define UART_NR S3C64XX_UART2 + +#else +#error "Bad: you didn't configure serial ..." +#endif + +#define barrier() asm volatile("" ::: "memory") + +/* + * The coefficient, used to calculate the baudrate on S3C6400 UARTs is + * calculated as + * C = UBRDIV * 16 + number_of_set_bits_in_UDIVSLOT + * however, section 31.6.11 of the datasheet doesn't recomment using 1 for 1, + * 3 for 2, ... (2^n - 1) for n, instead, they suggest using these constants: + */ +static const int udivslot[] = { + 0, + 0x0080, + 0x0808, + 0x0888, + 0x2222, + 0x4924, + 0x4a52, + 0x54aa, + 0x5555, + 0xd555, + 0xd5d5, + 0xddd5, + 0xdddd, + 0xdfdd, + 0xdfdf, + 0xffdf, +}; + +void serial_setbrg(void) +{ + DECLARE_GLOBAL_DATA_PTR; + s3c64xx_uart *const uart = s3c64xx_get_base_uart(UART_NR); + u32 pclk = get_PCLK(); + u32 baudrate = gd->baudrate; + int i; + + i = (pclk / baudrate) % 16; + + uart->UBRDIV = pclk / baudrate / 16 - 1; + uart->UDIVSLOT = udivslot[i]; + + for (i = 0; i < 100; i++) + barrier(); +} + +/* + * Initialise the serial port with the given baudrate. The settings + * are always 8 data bits, no parity, 1 stop bit, no start bits. + */ +int serial_init(void) +{ + s3c64xx_uart *const uart = s3c64xx_get_base_uart(UART_NR); + + /* reset and enable FIFOs, set triggers to the maximum */ + uart->UFCON = 0xff; + uart->UMCON = 0; + /* 8N1 */ + uart->ULCON = 3; + /* No interrupts, no DMA, pure polling */ + uart->UCON = 5; + + serial_setbrg(); + + return 0; +} + +/* + * Read a single byte from the serial port. Returns 1 on success, 0 + * otherwise. When the function is succesfull, the character read is + * written into its argument c. + */ +int serial_getc(void) +{ + s3c64xx_uart *const uart = s3c64xx_get_base_uart(UART_NR); + + /* wait for character to arrive */ + while (!(uart->UTRSTAT & 0x1)); + + return uart->URXH & 0xff; +} + +#ifdef CONFIG_MODEM_SUPPORT +static int be_quiet; +void disable_putc(void) +{ + be_quiet = 1; +} + +void enable_putc(void) +{ + be_quiet = 0; +} +#endif + + +/* + * Output a single byte to the serial port. + */ +void serial_putc(const char c) +{ + s3c64xx_uart *const uart = s3c64xx_get_base_uart(UART_NR); + +#ifdef CONFIG_MODEM_SUPPORT + if (be_quiet) + return; +#endif + + /* wait for room in the tx FIFO */ + while (!(uart->UTRSTAT & 0x2)); + + uart->UTXH = c; + + /* If \n, also do \r */ + if (c == '\n') + serial_putc('\r'); +} + +/* + * Test whether a character is in the RX buffer + */ +int serial_tstc(void) +{ + s3c64xx_uart *const uart = s3c64xx_get_base_uart(UART_NR); + + return uart->UTRSTAT & 0x1; +} + +void serial_puts(const char *s) +{ + while (*s) + serial_putc(*s++); +} diff --git a/drivers/usb/usb_ohci.c b/drivers/usb/usb_ohci.c index fd60edb..0bfa4d7 100644 --- a/drivers/usb/usb_ohci.c +++ b/drivers/usb/usb_ohci.c @@ -69,6 +69,7 @@ #if defined(CONFIG_ARM920T) || \ defined(CONFIG_S3C2400) || \ defined(CONFIG_S3C2410) || \ + defined(CONFIG_S3C6400) || \ defined(CONFIG_440EP) || \ defined(CONFIG_PCI_OHCI) || \ defined(CONFIG_MPC5200) || \ diff --git a/include/asm-arm/arch-davinci/emac_defs.h b/include/asm-arm/arch-davinci/emac_defs.h index 0e10116..c11161f 100644 --- a/include/asm-arm/arch-davinci/emac_defs.h +++ b/include/asm-arm/arch-davinci/emac_defs.h @@ -284,8 +284,8 @@ typedef struct { dv_reg USERPHYSEL1; } mdio_regs; -int dm644x_eth_phy_read(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t *data); -int dm644x_eth_phy_write(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t data); +int davinci_eth_phy_read(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t *data); +int davinci_eth_phy_write(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t data); typedef struct { diff --git a/include/asm-arm/arch-s3c64xx/hardware.h b/include/asm-arm/arch-s3c64xx/hardware.h new file mode 100644 index 0000000..84d24c9 --- /dev/null +++ b/include/asm-arm/arch-s3c64xx/hardware.h @@ -0,0 +1,63 @@ +/* + * Originates from Samsung's u-boot 1.1.6 port to S3C6400 / SMDK6400 + * + * (C) Copyright 2008 + * Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _ARCH_HARDWARE_H_ +#define _ARCH_HARDWARE_H_ + +#include <asm/sizes.h> + +#ifndef __ASSEMBLY__ +#define UData(Data) ((unsigned long) (Data)) + +#define __REG(x) (*(vu_long *)(x)) +#define __REGl(x) (*(vu_long *)(x)) +#define __REGw(x) (*(vu_short *)(x)) +#define __REGb(x) (*(vu_char *)(x)) +#define __REG2(x, y) (*(vu_long *)((x) + (y))) +#else +#define UData(Data) (Data) + +#define __REG(x) (x) +#define __REGl(x) (x) +#define __REGw(x) (x) +#define __REGb(x) (x) +#define __REG2(x, y) ((x) + (y)) +#endif + +#define Fld(Size, Shft) (((Size) << 16) + (Shft)) + +#define FSize(Field) ((Field) >> 16) +#define FShft(Field) ((Field) & 0x0000FFFF) +#define FMsk(Field) (((UData (1) << FSize (Field)) - 1) << FShft (Field)) +#define FAlnMsk(Field) ((UData (1) << FSize (Field)) - 1) +#define F1stBit(Field) (UData (1) << FShft (Field)) + +#define FClrBit(Data, Bit) (Data = (Data & ~(Bit))) +#define FClrFld(Data, Field) (Data = (Data & ~FMsk(Field))) + +#define FInsrt(Value, Field) \ + (UData (Value) << FShft (Field)) + +#define FExtr(Data, Field) \ + ((UData (Data) >> FShft (Field)) & FAlnMsk (Field)) + +#endif /* _ARCH_HARDWARE_H_ */ diff --git a/include/common.h b/include/common.h index de3d595..a394988 100644 --- a/include/common.h +++ b/include/common.h @@ -490,7 +490,8 @@ int prt_mpc8220_clks (void); ulong get_OPB_freq (void); ulong get_PCI_freq (void); #endif -#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) || defined(CONFIG_LH7A40X) +#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) || \ + defined(CONFIG_LH7A40X) || defined(CONFIG_S3C6400) void s3c2410_irq(void); #define ARM920_IRQ_CALLBACK s3c2410_irq ulong get_FCLK (void); diff --git a/include/configs/smdk6400.h b/include/configs/smdk6400.h new file mode 100644 index 0000000..f0c146e --- /dev/null +++ b/include/configs/smdk6400.h @@ -0,0 +1,307 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * Gary Jennejohn <gj@denx.de> + * David Mueller <d.mueller@elsoft.ch> + * + * (C) Copyright 2008 + * Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de> + * + * Configuation settings for the SAMSUNG SMDK6400(mDirac-III) board. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +/* + * High Level Configuration Options + * (easy to change) + */ +#define CONFIG_S3C6400 1 /* in a SAMSUNG S3C6400 SoC */ +#define CONFIG_S3C64XX 1 /* in a SAMSUNG S3C64XX Family */ +#define CONFIG_SMDK6400 1 /* on a SAMSUNG SMDK6400 Board */ + +#define CFG_SDRAM_BASE 0x50000000 + +/* input clock of PLL: SMDK6400 has 12MHz input clock */ +#define CONFIG_SYS_CLK_FREQ 12000000 + +#if !defined(CONFIG_NAND_SPL) && (TEXT_BASE >= 0xc0000000) +#define CONFIG_ENABLE_MMU +#endif + +#define CONFIG_MEMORY_UPPER_CODE + +#define CONFIG_SETUP_MEMORY_TAGS +#define CONFIG_CMDLINE_TAG +#define CONFIG_INITRD_TAG + +/* + * Architecture magic and machine type + */ +#define MACH_TYPE 1270 + +#define CONFIG_DISPLAY_CPUINFO +#define CONFIG_DISPLAY_BOARDINFO + +#undef CONFIG_SKIP_RELOCATE_UBOOT + +/* + * Size of malloc() pool + */ +#define CFG_MALLOC_LEN (CFG_ENV_SIZE + 1024 * 1024) +#define CFG_GBL_DATA_SIZE 128 /* size in bytes for initial data */ + +/* + * Hardware drivers + */ +#define CONFIG_DRIVER_CS8900 1 /* we have a CS8900 on-board */ +#define CS8900_BASE 0x18800300 +#define CS8900_BUS16 1 /* follow the Linux driver */ + +/* + * select serial console configuration + */ +#define CONFIG_SERIAL1 1 /* we use SERIAL 1 on SMDK6400 */ + +#define CFG_HUSH_PARSER /* use "hush" command parser */ +#ifdef CFG_HUSH_PARSER +#define CFG_PROMPT_HUSH_PS2 "> " +#endif + +#define CONFIG_CMDLINE_EDITING + +/* allow to overwrite serial and ethaddr */ +#define CONFIG_ENV_OVERWRITE + +#define CONFIG_BAUDRATE 115200 + +/*********************************************************** + * Command definition + ***********************************************************/ +#include <config_cmd_default.h> + +#define CONFIG_CMD_CACHE +#define CONFIG_CMD_REGINFO +#define CONFIG_CMD_LOADS +#define CONFIG_CMD_LOADB +#define CONFIG_CMD_ENV +#define CONFIG_CMD_NAND +#if defined(CONFIG_BOOT_ONENAND) +#define CONFIG_CMD_ONENAND +#endif +#define CONFIG_CMD_PING +#define CONFIG_CMD_ELF +#define CONFIG_CMD_FAT +#define CONFIG_CMD_EXT2 + +#define CONFIG_BOOTDELAY 3 + +#define CONFIG_ZERO_BOOTDELAY_CHECK + +#if (CONFIG_COMMANDS & CONFIG_CMD_KGDB) +#define CONFIG_KGDB_BAUDRATE 115200 /* speed to run kgdb serial port */ +#define CONFIG_KGDB_SER_INDEX 1 /* which serial port to use */ +#endif + +/* + * Miscellaneous configurable options + */ +#define CFG_LONGHELP /* undef to save memory */ +#define CFG_PROMPT "SMDK6400 # " /* Monitor Command Prompt */ +#define CFG_CBSIZE 256 /* Console I/O Buffer Size */ +#define CFG_PBSIZE 384 /* Print Buffer Size */ +#define CFG_MAXARGS 16 /* max number of command args */ +#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ + +#define CFG_MEMTEST_START CFG_SDRAM_BASE /* memtest works on */ +#define CFG_MEMTEST_END (CFG_SDRAM_BASE + 0x7e00000) /* 126MB in DRAM */ + +#define CFG_LOAD_ADDR CFG_SDRAM_BASE /* default load address */ + +#define CFG_HZ 1000 + +/* valid baudrates */ +#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 } + +/*----------------------------------------------------------------------- + * Stack sizes + * + * The stack sizes are set up in start.S using the settings below + */ +#define CONFIG_STACKSIZE 0x40000 /* regular stack 256KB */ + +/********************************** + Support Clock Settings + ********************************** + Setting SYNC ASYNC + ---------------------------------- + 667_133_66 X O + 533_133_66 O O + 400_133_66 X O + 400_100_50 O O + **********************************/ + +/*#define CONFIG_CLK_667_133_66*/ +#define CONFIG_CLK_533_133_66 +/* +#define CONFIG_CLK_400_100_50 +#define CONFIG_CLK_400_133_66 +#define CONFIG_SYNC_MODE +*/ + +/* SMDK6400 has 2 banks of DRAM, but we use only one in U-Boot */ +#define CONFIG_NR_DRAM_BANKS 1 +#define PHYS_SDRAM_1 CFG_SDRAM_BASE /* SDRAM Bank #1 */ +#define PHYS_SDRAM_1_SIZE 0x08000000 /* 128 MB in Bank #1 */ + +#define CFG_FLASH_BASE 0x10000000 +#define CFG_MONITOR_BASE 0x00000000 + +/*----------------------------------------------------------------------- + * FLASH and environment organization + */ +#define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */ +/* AM29LV160B has 35 sectors, AM29LV800B - 19 */ +#define CFG_MAX_FLASH_SECT 40 + +#define CONFIG_AMD_LV800 +#define CFG_FLASH_CFI 1 /* Use CFI parameters (needed?) */ +/* Use drivers/cfi_flash.c, even though the flash is not CFI-compliant */ +#define CONFIG_FLASH_CFI_DRIVER 1 +#define CFG_FLASH_CFI_WIDTH FLASH_CFI_16BIT +#define CONFIG_FLASH_CFI_LEGACY +#define CFG_FLASH_LEGACY_512Kx16 + +/* timeout values are in ticks */ +#define CFG_FLASH_ERASE_TOUT (5 * CFG_HZ) /* Timeout for Flash Erase */ +#define CFG_FLASH_WRITE_TOUT (5 * CFG_HZ) /* Timeout for Flash Write */ + +#define CFG_ENV_SIZE 0x4000 /* Total Size of Environment Sector */ + +/* + * SMDK6400 board specific data + */ + +#define CONFIG_IDENT_STRING " for SMDK6400" + +/* base address for uboot */ +#define CFG_PHY_UBOOT_BASE (CFG_SDRAM_BASE + 0x07e00000) +/* total memory available to uboot */ +#define CFG_UBOOT_SIZE (1024 * 1024) + +#ifdef CONFIG_ENABLE_MMU +#define CFG_MAPPED_RAM_BASE 0xc0000000 +#define CONFIG_BOOTCOMMAND "nand read 0xc0018000 0x60000 0x1c0000;" \ + "bootm 0xc0018000" +#else +#define CFG_MAPPED_RAM_BASE CFG_SDRAM_BASE +#define CONFIG_BOOTCOMMAND "nand read 0x50018000 0x60000 0x1c0000;" \ + "bootm 0x50018000" +#endif + +/* NAND U-Boot load and start address */ +#define CFG_UBOOT_BASE (CFG_MAPPED_RAM_BASE + 0x07e00000) + +#define CFG_ENV_OFFSET 0x0040000 + +/* NAND configuration */ +#define CFG_MAX_NAND_DEVICE 1 +#define CFG_NAND_BASE 0x70200010 +#define NAND_MAX_CHIPS 1 +#define CFG_S3C_NAND_HWECC + +#define CFG_NAND_SKIP_BAD_DOT_I 1 /* ".i" read skips bad blocks */ +#define CFG_NAND_WP 1 +#define CFG_NAND_YAFFS_WRITE 1 /* support yaffs write */ +#define CFG_NAND_BBT_2NDPAGE 1 /* bad-block markers in 1st and 2nd pages */ + +#define CFG_NAND_U_BOOT_DST CFG_PHY_UBOOT_BASE /* NUB load-addr */ +#define CFG_NAND_U_BOOT_START CFG_NAND_U_BOOT_DST /* NUB start-addr */ + +#define CFG_NAND_U_BOOT_OFFS (4 * 1024) /* Offset to RAM U-Boot image */ +#define CFG_NAND_U_BOOT_SIZE (252 * 1024) /* Size of RAM U-Boot image */ + +/* NAND chip page size */ +#define CFG_NAND_PAGE_SIZE 2048 +/* NAND chip block size */ +#define CFG_NAND_BLOCK_SIZE (128 * 1024) +/* NAND chip page per block count */ +#define CFG_NAND_PAGE_COUNT 64 +/* Location of the bad-block label */ +#define CFG_NAND_BAD_BLOCK_POS 0 +/* Extra address cycle for > 128MiB */ +#define CFG_NAND_5_ADDR_CYCLE + +/* Size of the block protected by one OOB (Spare Area in Samsung terminology) */ +#define CFG_NAND_ECCSIZE CFG_NAND_PAGE_SIZE +/* Number of ECC bytes per OOB - S3C6400 calculates 4 bytes ECC in 1-bit mode */ +#define CFG_NAND_ECCBYTES 4 +/* Number of ECC-blocks per NAND page */ +#define CFG_NAND_ECCSTEPS (CFG_NAND_PAGE_SIZE / CFG_NAND_ECCSIZE) +/* Size of a single OOB region */ +#define CFG_NAND_OOBSIZE 64 +/* Number of ECC bytes per page */ +#define CFG_NAND_ECCTOTAL (CFG_NAND_ECCBYTES * CFG_NAND_ECCSTEPS) +/* ECC byte positions */ +#define CFG_NAND_ECCPOS {40, 41, 42, 43, 44, 45, 46, 47, \ + 48, 49, 50, 51, 52, 53, 54, 55, \ + 56, 57, 58, 59, 60, 61, 62, 63} + +/* Boot configuration (define only one of next 3) */ +#define CONFIG_BOOT_NAND +/* None of these are currently implemented. Left from the original Samsung + * version for reference +#define CONFIG_BOOT_NOR +#define CONFIG_BOOT_MOVINAND +#define CONFIG_BOOT_ONENAND +*/ + +#define CONFIG_NAND +#define CONFIG_NAND_S3C64XX +/* Unimplemented or unsupported. See comment above. +#define CONFIG_ONENAND +#define CONFIG_MOVINAND +*/ + +/* Settings as above boot configuration */ +#define CFG_ENV_IS_IN_NAND +#define CONFIG_BOOTARGS "console=ttySAC,115200" + +#if !defined(CONFIG_ENABLE_MMU) +#define CONFIG_CMD_USB 1 +#define CONFIG_USB_OHCI_NEW 1 +#define CFG_USB_OHCI_REGS_BASE 0x74300000 +#define CFG_USB_OHCI_SLOT_NAME "s3c6400" +#define CFG_USB_OHCI_MAX_ROOT_PORTS 3 +#define CFG_USB_OHCI_CPU_INIT 1 +#define LITTLEENDIAN 1 /* used by usb_ohci.c */ + +#define CONFIG_USB_STORAGE 1 +#endif +#define CONFIG_DOS_PARTITION 1 + +#if defined(CONFIG_USB_OHCI_NEW) && defined(CONFIG_ENABLE_MMU) +# error "usb_ohci.c is currently broken with MMU enabled." +#endif + +#endif /* __CONFIG_H */ diff --git a/include/s3c6400.h b/include/s3c6400.h new file mode 100644 index 0000000..fd3e99b --- /dev/null +++ b/include/s3c6400.h @@ -0,0 +1,894 @@ +/* + * (C) Copyright 2007 + * Byungjae Lee, Samsung Erectronics, bjlee@samsung.com. + * - only support for S3C6400 + * + * (C) Copyright 2008 + * Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/************************************************ + * NAME : s3c6400.h + * + * Based on S3C6400 User's manual Rev 0.0 + ************************************************/ + +#ifndef __S3C6400_H__ +#define __S3C6400_H__ + +#ifndef CONFIG_S3C6400 +#define CONFIG_S3C6400 1 +#endif + +#define S3C64XX_UART_CHANNELS 3 +#define S3C64XX_SPI_CHANNELS 2 + +#include <asm/hardware.h> + +#define ELFIN_CLOCK_POWER_BASE 0x7e00f000 + +/* Clock & Power Controller for mDirac3*/ +#define APLL_LOCK_OFFSET 0x00 +#define MPLL_LOCK_OFFSET 0x04 +#define EPLL_LOCK_OFFSET 0x08 +#define APLL_CON_OFFSET 0x0C +#define MPLL_CON_OFFSET 0x10 +#define EPLL_CON0_OFFSET 0x14 +#define EPLL_CON1_OFFSET 0x18 +#define CLK_SRC_OFFSET 0x1C +#define CLK_DIV0_OFFSET 0x20 +#define CLK_DIV1_OFFSET 0x24 +#define CLK_DIV2_OFFSET 0x28 +#define CLK_OUT_OFFSET 0x2C +#define HCLK_GATE_OFFSET 0x30 +#define PCLK_GATE_OFFSET 0x34 +#define SCLK_GATE_OFFSET 0x38 +#define AHB_CON0_OFFSET 0x100 +#define AHB_CON1_OFFSET 0x104 +#define AHB_CON2_OFFSET 0x108 +#define SELECT_DMA_OFFSET 0x110 +#define SW_RST_OFFSET 0x114 +#define SYS_ID_OFFSET 0x118 +#define MEM_SYS_CFG_OFFSET 0x120 +#define QOS_OVERRIDE0_OFFSET 0x124 +#define QOS_OVERRIDE1_OFFSET 0x128 +#define MEM_CFG_STAT_OFFSET 0x12C +#define PWR_CFG_OFFSET 0x804 +#define EINT_MASK_OFFSET 0x808 +#define NOR_CFG_OFFSET 0x810 +#define STOP_CFG_OFFSET 0x814 +#define SLEEP_CFG_OFFSET 0x818 +#define OSC_FREQ_OFFSET 0x820 +#define OSC_STABLE_OFFSET 0x824 +#define PWR_STABLE_OFFSET 0x828 +#define FPC_STABLE_OFFSET 0x82C +#define MTC_STABLE_OFFSET 0x830 +#define OTHERS_OFFSET 0x900 +#define RST_STAT_OFFSET 0x904 +#define WAKEUP_STAT_OFFSET 0x908 +#define BLK_PWR_STAT_OFFSET 0x90C +#define INF_REG0_OFFSET 0xA00 +#define INF_REG1_OFFSET 0xA04 +#define INF_REG2_OFFSET 0xA08 +#define INF_REG3_OFFSET 0xA0C +#define INF_REG4_OFFSET 0xA10 +#define INF_REG5_OFFSET 0xA14 +#define INF_REG6_OFFSET 0xA18 +#define INF_REG7_OFFSET 0xA1C + +#define OSC_CNT_VAL_OFFSET 0x824 +#define PWR_CNT_VAL_OFFSET 0x828 +#define FPC_CNT_VAL_OFFSET 0x82C +#define MTC_CNT_VAL_OFFSET 0x830 + +#define APLL_LOCK_REG __REG(ELFIN_CLOCK_POWER_BASE + APLL_LOCK_OFFSET) +#define MPLL_LOCK_REG __REG(ELFIN_CLOCK_POWER_BASE + MPLL_LOCK_OFFSET) +#define EPLL_LOCK_REG __REG(ELFIN_CLOCK_POWER_BASE + EPLL_LOCK_OFFSET) +#define APLL_CON_REG __REG(ELFIN_CLOCK_POWER_BASE + APLL_CON_OFFSET) +#define MPLL_CON_REG __REG(ELFIN_CLOCK_POWER_BASE + MPLL_CON_OFFSET) +#define EPLL_CON0_REG __REG(ELFIN_CLOCK_POWER_BASE + EPLL_CON0_OFFSET) +#define EPLL_CON1_REG __REG(ELFIN_CLOCK_POWER_BASE + EPLL_CON1_OFFSET) +#define CLK_SRC_REG __REG(ELFIN_CLOCK_POWER_BASE + CLK_SRC_OFFSET) +#define CLK_DIV0_REG __REG(ELFIN_CLOCK_POWER_BASE + CLK_DIV0_OFFSET) +#define CLK_DIV1_REG __REG(ELFIN_CLOCK_POWER_BASE + CLK_DIV1_OFFSET) +#define CLK_DIV2_REG __REG(ELFIN_CLOCK_POWER_BASE + CLK_DIV2_OFFSET) +#define CLK_OUT_REG __REG(ELFIN_CLOCK_POWER_BASE + CLK_OUT_OFFSET) +#define HCLK_GATE_REG __REG(ELFIN_CLOCK_POWER_BASE + HCLK_GATE_OFFSET) +#define PCLK_GATE_REG __REG(ELFIN_CLOCK_POWER_BASE + PCLK_GATE_OFFSET) +#define SCLK_GATE_REG __REG(ELFIN_CLOCK_POWER_BASE + SCLK_GATE_OFFSET) +#define AHB_CON0_REG __REG(ELFIN_CLOCK_POWER_BASE + AHB_CON0_OFFSET) +#define AHB_CON1_REG __REG(ELFIN_CLOCK_POWER_BASE + AHB_CON1_OFFSET) +#define AHB_CON2_REG __REG(ELFIN_CLOCK_POWER_BASE + AHB_CON2_OFFSET) +#define SELECT_DMA_REG __REG(ELFIN_CLOCK_POWER_BASE + \ + SELECT_DMA_OFFSET) +#define SW_RST_REG __REG(ELFIN_CLOCK_POWER_BASE + SW_RST_OFFSET) +#define SYS_ID_REG __REG(ELFIN_CLOCK_POWER_BASE + SYS_ID_OFFSET) +#define MEM_SYS_CFG_REG __REG(ELFIN_CLOCK_POWER_BASE + \ + MEM_SYS_CFG_OFFSET) +#define QOS_OVERRIDE0_REG __REG(ELFIN_CLOCK_POWER_BASE + \ + QOS_OVERRIDE0_OFFSET) +#define QOS_OVERRIDE1_REG __REG(ELFIN_CLOCK_POWER_BASE + \ + QOS_OVERRIDE1_OFFSET) +#define MEM_CFG_STAT_REG __REG(ELFIN_CLOCK_POWER_BASE + \ + MEM_CFG_STAT_OFFSET) +#define PWR_CFG_REG __REG(ELFIN_CLOCK_POWER_BASE + PWR_CFG_OFFSET) +#define EINT_MASK_REG __REG(ELFIN_CLOCK_POWER_BASE + EINT_MASK_OFFSET) +#define NOR_CFG_REG __REG(ELFIN_CLOCK_POWER_BASE + NOR_CFG_OFFSET) +#define STOP_CFG_REG __REG(ELFIN_CLOCK_POWER_BASE + STOP_CFG_OFFSET) +#define SLEEP_CFG_REG __REG(ELFIN_CLOCK_POWER_BASE + SLEEP_CFG_OFFSET) +#define OSC_FREQ_REG __REG(ELFIN_CLOCK_POWER_BASE + OSC_FREQ_OFFSET) +#define OSC_CNT_VAL_REG __REG(ELFIN_CLOCK_POWER_BASE + \ + OSC_CNT_VAL_OFFSET) +#define PWR_CNT_VAL_REG __REG(ELFIN_CLOCK_POWER_BASE + \ + PWR_CNT_VAL_OFFSET) +#define FPC_CNT_VAL_REG __REG(ELFIN_CLOCK_POWER_BASE + \ + FPC_CNT_VAL_OFFSET) +#define MTC_CNT_VAL_REG __REG(ELFIN_CLOCK_POWER_BASE + \ + MTC_CNT_VAL_OFFSET) +#define OTHERS_REG __REG(ELFIN_CLOCK_POWER_BASE + OTHERS_OFFSET) +#define RST_STAT_REG __REG(ELFIN_CLOCK_POWER_BASE + RST_STAT_OFFSET) +#define WAKEUP_STAT_REG __REG(ELFIN_CLOCK_POWER_BASE + \ + WAKEUP_STAT_OFFSET) +#define BLK_PWR_STAT_REG __REG(ELFIN_CLOCK_POWER_BASE + \ + BLK_PWR_STAT_OFFSET) +#define INF_REG0_REG __REG(ELFIN_CLOCK_POWER_BASE + INF_REG0_OFFSET) +#define INF_REG1_REG __REG(ELFIN_CLOCK_POWER_BASE + INF_REG1_OFFSET) +#define INF_REG2_REG __REG(ELFIN_CLOCK_POWER_BASE + INF_REG2_OFFSET) +#define INF_REG3_REG __REG(ELFIN_CLOCK_POWER_BASE + INF_REG3_OFFSET) +#define INF_REG4_REG __REG(ELFIN_CLOCK_POWER_BASE + INF_REG4_OFFSET) +#define INF_REG5_REG __REG(ELFIN_CLOCK_POWER_BASE + INF_REG5_OFFSET) +#define INF_REG6_REG __REG(ELFIN_CLOCK_POWER_BASE + INF_REG6_OFFSET) +#define INF_REG7_REG __REG(ELFIN_CLOCK_POWER_BASE + INF_REG7_OFFSET) + +#define APLL_LOCK (ELFIN_CLOCK_POWER_BASE + APLL_LOCK_OFFSET) +#define MPLL_LOCK (ELFIN_CLOCK_POWER_BASE + MPLL_LOCK_OFFSET) +#define EPLL_LOCK (ELFIN_CLOCK_POWER_BASE + EPLL_LOCK_OFFSET) +#define APLL_CON (ELFIN_CLOCK_POWER_BASE + APLL_CON_OFFSET) +#define MPLL_CON (ELFIN_CLOCK_POWER_BASE + MPLL_CON_OFFSET) +#define EPLL_CON0 (ELFIN_CLOCK_POWER_BASE + EPLL_CON0_OFFSET) +#define EPLL_CON1 (ELFIN_CLOCK_POWER_BASE + EPLL_CON1_OFFSET) +#define CLK_SRC (ELFIN_CLOCK_POWER_BASE + CLK_SRC_OFFSET) +#define CLK_DIV0 (ELFIN_CLOCK_POWER_BASE + CLK_DIV0_OFFSET) +#define CLK_DIV1 (ELFIN_CLOCK_POWER_BASE + CLK_DIV1_OFFSET) +#define CLK_DIV2 (ELFIN_CLOCK_POWER_BASE + CLK_DIV2_OFFSET) +#define CLK_OUT (ELFIN_CLOCK_POWER_BASE + CLK_OUT_OFFSET) +#define HCLK_GATE (ELFIN_CLOCK_POWER_BASE + HCLK_GATE_OFFSET) +#define PCLK_GATE (ELFIN_CLOCK_POWER_BASE + PCLK_GATE_OFFSET) +#define SCLK_GATE (ELFIN_CLOCK_POWER_BASE + SCLK_GATE_OFFSET) +#define AHB_CON0 (ELFIN_CLOCK_POWER_BASE + AHB_CON0_OFFSET) +#define AHB_CON1 (ELFIN_CLOCK_POWER_BASE + AHB_CON1_OFFSET) +#define AHB_CON2 (ELFIN_CLOCK_POWER_BASE + AHB_CON2_OFFSET) +#define SELECT_DMA (ELFIN_CLOCK_POWER_BASE + SELECT_DMA_OFFSET) +#define SW_RST (ELFIN_CLOCK_POWER_BASE + SW_RST_OFFSET) +#define SYS_ID (ELFIN_CLOCK_POWER_BASE + SYS_ID_OFFSET) +#define MEM_SYS_CFG (ELFIN_CLOCK_POWER_BASE + MEM_SYS_CFG_OFFSET) +#define QOS_OVERRIDE0 (ELFIN_CLOCK_POWER_BASE + QOS_OVERRIDE0_OFFSET) +#define QOS_OVERRIDE1 (ELFIN_CLOCK_POWER_BASE + QOS_OVERRIDE1_OFFSET) +#define MEM_CFG_STAT (ELFIN_CLOCK_POWER_BASE + MEM_CFG_STAT_OFFSET) +#define PWR_CFG (ELFIN_CLOCK_POWER_BASE + PWR_CFG_OFFSET) +#define EINT_MASK (ELFIN_CLOCK_POWER_BASE + EINT_MASK_OFFSET) +#define NOR_CFG (ELFIN_CLOCK_POWER_BASE + NOR_CFG_OFFSET) +#define STOP_CFG (ELFIN_CLOCK_POWER_BASE + STOP_CFG_OFFSET) +#define SLEEP_CFG (ELFIN_CLOCK_POWER_BASE + SLEEP_CFG_OFFSET) +#define OSC_FREQ (ELFIN_CLOCK_POWER_BASE + OSC_FREQ_OFFSET) +#define OSC_CNT_VAL (ELFIN_CLOCK_POWER_BASE + OSC_CNT_VAL_OFFSET) +#define PWR_CNT_VAL (ELFIN_CLOCK_POWER_BASE + PWR_CNT_VAL_OFFSET) +#define FPC_CNT_VAL (ELFIN_CLOCK_POWER_BASE + FPC_CNT_VAL_OFFSET) +#define MTC_CNT_VAL (ELFIN_CLOCK_POWER_BASE + MTC_CNT_VAL_OFFSET) +#define OTHERS (ELFIN_CLOCK_POWER_BASE + OTHERS_OFFSET) +#define RST_STAT (ELFIN_CLOCK_POWER_BASE + RST_STAT_OFFSET) +#define WAKEUP_STAT (ELFIN_CLOCK_POWER_BASE + WAKEUP_STAT_OFFSET) +#define BLK_PWR_STAT (ELFIN_CLOCK_POWER_BASE + BLK_PWR_STAT_OFFSET) +#define INF_REG0 (ELFIN_CLOCK_POWER_BASE + INF_REG0_OFFSET) +#define INF_REG1 (ELFIN_CLOCK_POWER_BASE + INF_REG1_OFFSET) +#define INF_REG2 (ELFIN_CLOCK_POWER_BASE + INF_REG2_OFFSET) +#define INF_REG3 (ELFIN_CLOCK_POWER_BASE + INF_REG3_OFFSET) +#define INF_REG4 (ELFIN_CLOCK_POWER_BASE + INF_REG4_OFFSET) +#define INF_REG5 (ELFIN_CLOCK_POWER_BASE + INF_REG5_OFFSET) +#define INF_REG6 (ELFIN_CLOCK_POWER_BASE + INF_REG6_OFFSET) +#define INF_REG7 (ELFIN_CLOCK_POWER_BASE + INF_REG7_OFFSET) + + +/* + * GPIO + */ +#define ELFIN_GPIO_BASE 0x7f008000 + +#define GPACON_OFFSET 0x00 +#define GPADAT_OFFSET 0x04 +#define GPAPUD_OFFSET 0x08 +#define GPACONSLP_OFFSET 0x0C +#define GPAPUDSLP_OFFSET 0x10 +#define GPBCON_OFFSET 0x20 +#define GPBDAT_OFFSET 0x04 +#define GPBPUD_OFFSET 0x08 +#define GPBCONSLP_OFFSET 0x0C +#define GPBPUDSLP_OFFSET 0x30 +#define GPCCON_OFFSET 0x40 +#define GPCDAT_OFFSET 0x44 +#define GPCPUD_OFFSET 0x48 +#define GPCCONSLP_OFFSET 0x4C +#define GPCPUDSLP_OFFSET 0x50 +#define GPDCON_OFFSET 0x60 +#define GPDDAT_OFFSET 0x64 +#define GPDPUD_OFFSET 0x68 +#define GPDCONSLP_OFFSET 0x6C +#define GPDPUDSLP_OFFSET 0x70 +#define GPECON_OFFSET 0x80 +#define GPEDAT_OFFSET 0x84 +#define GPEPUD_OFFSET 0x88 +#define GPECONSLP_OFFSET 0x8C +#define GPEPUDSLP_OFFSET 0x90 +#define GPFCON_OFFSET 0xA0 +#define GPFDAT_OFFSET 0xA4 +#define GPFPUD_OFFSET 0xA8 +#define GPFCONSLP_OFFSET 0xAC +#define GPFPUDSLP_OFFSET 0xB0 +#define GPGCON_OFFSET 0xC0 +#define GPGDAT_OFFSET 0xC4 +#define GPGPUD_OFFSET 0xC8 +#define GPGCONSLP_OFFSET 0xCC +#define GPGPUDSLP_OFFSET 0xD0 +#define GPHCON0_OFFSET 0xE0 +#define GPHCON1_OFFSET 0xE4 +#define GPHDAT_OFFSET 0xE8 +#define GPHPUD_OFFSET 0xEC +#define GPHCONSLP_OFFSET 0xF0 +#define GPHPUDSLP_OFFSET 0xF4 +#define GPICON_OFFSET 0x100 +#define GPIDAT_OFFSET 0x104 +#define GPIPUD_OFFSET 0x108 +#define GPICONSLP_OFFSET 0x10C +#define GPIPUDSLP_OFFSET 0x110 +#define GPJCON_OFFSET 0x120 +#define GPJDAT_OFFSET 0x124 +#define GPJPUD_OFFSET 0x128 +#define GPJCONSLP_OFFSET 0x12C +#define GPJPUDSLP_OFFSET 0x130 +#define MEM0DRVCON_OFFSET 0x1D0 +#define MEM1DRVCON_OFFSET 0x1D4 +#define GPKCON0_OFFSET 0x800 +#define GPKCON1_OFFSET 0x804 +#define GPKDAT_OFFSET 0x808 +#define GPKPUD_OFFSET 0x80C +#define GPLCON0_OFFSET 0x810 +#define GPLCON1_OFFSET 0x814 +#define GPLDAT_OFFSET 0x818 +#define GPLPUD_OFFSET 0x81C +#define GPMCON_OFFSET 0x820 +#define GPMDAT_OFFSET 0x824 +#define GPMPUD_OFFSET 0x828 +#define GPNCON_OFFSET 0x830 +#define GPNDAT_OFFSET 0x834 +#define GPNPUD_OFFSET 0x838 +#define GPOCON_OFFSET 0x140 +#define GPODAT_OFFSET 0x144 +#define GPOPUD_OFFSET 0x148 +#define GPOCONSLP_OFFSET 0x14C +#define GPOPUDSLP_OFFSET 0x150 +#define GPPCON_OFFSET 0x160 +#define GPPDAT_OFFSET 0x164 +#define GPPPUD_OFFSET 0x168 +#define GPPCONSLP_OFFSET 0x16C +#define GPPPUDSLP_OFFSET 0x170 +#define GPQCON_OFFSET 0x180 +#define GPQDAT_OFFSET 0x184 +#define GPQPUD_OFFSET 0x188 +#define GPQCONSLP_OFFSET 0x18C +#define GPQPUDSLP_OFFSET 0x190 + +#define EINTPEND_OFFSET 0x924 + +#define GPACON_REG __REG(ELFIN_GPIO_BASE + GPACON_OFFSET) +#define GPADAT_REG __REG(ELFIN_GPIO_BASE + GPADAT_OFFSET) +#define GPAPUD_REG __REG(ELFIN_GPIO_BASE + GPAPUD_OFFSET) +#define GPACONSLP_REG __REG(ELFIN_GPIO_BASE + GPACONSLP_OFFSET) +#define GPAPUDSLP_REG __REG(ELFIN_GPIO_BASE + GPAPUDSLP_OFFSET) +#define GPBCON_REG __REG(ELFIN_GPIO_BASE + GPBCON_OFFSET) +#define GPBDAT_REG __REG(ELFIN_GPIO_BASE + GPBDAT_OFFSET) +#define GPBPUD_REG __REG(ELFIN_GPIO_BASE + GPBPUD_OFFSET) +#define GPBCONSLP_REG __REG(ELFIN_GPIO_BASE + GPBCONSLP_OFFSET) +#define GPBPUDSLP_REG __REG(ELFIN_GPIO_BASE + GPBPUDSLP_OFFSET) +#define GPCCON_REG __REG(ELFIN_GPIO_BASE + GPCCON_OFFSET) +#define GPCDAT_REG __REG(ELFIN_GPIO_BASE + GPCDAT_OFFSET) +#define GPCPUD_REG __REG(ELFIN_GPIO_BASE + GPCPUD_OFFSET) +#define GPCCONSLP_REG __REG(ELFIN_GPIO_BASE + GPCCONSLP_OFFSET) +#define GPCPUDSLP_REG __REG(ELFIN_GPIO_BASE + GPCPUDSLP_OFFSET) +#define GPDCON_REG __REG(ELFIN_GPIO_BASE + GPDCON_OFFSET) +#define GPDDAT_REG __REG(ELFIN_GPIO_BASE + GPDDAT_OFFSET) +#define GPDPUD_REG __REG(ELFIN_GPIO_BASE + GPDPUD_OFFSET) +#define GPDCONSLP_REG __REG(ELFIN_GPIO_BASE + GPDCONSLP_OFFSET) +#define GPDPUDSLP_REG __REG(ELFIN_GPIO_BASE + GPDPUDSLP_OFFSET) +#define GPECON_REG __REG(ELFIN_GPIO_BASE + GPECON_OFFSET) +#define GPEDAT_REG __REG(ELFIN_GPIO_BASE + GPEDAT_OFFSET) +#define GPEPUD_REG __REG(ELFIN_GPIO_BASE + GPEPUD_OFFSET) +#define GPECONSLP_REG __REG(ELFIN_GPIO_BASE + GPECONSLP_OFFSET) +#define GPEPUDSLP_REG __REG(ELFIN_GPIO_BASE + GPEPUDSLP_OFFSET) +#define GPFCON_REG __REG(ELFIN_GPIO_BASE + GPFCON_OFFSET) +#define GPFDAT_REG __REG(ELFIN_GPIO_BASE + GPFDAT_OFFSET) +#define GPFPUD_REG __REG(ELFIN_GPIO_BASE + GPFPUD_OFFSET) +#define GPFCONSLP_REG __REG(ELFIN_GPIO_BASE + GPFCONSLP_OFFSET) +#define GPFPUDSLP_REG __REG(ELFIN_GPIO_BASE + GPFPUDSLP_OFFSET) +#define GPGCON_REG __REG(ELFIN_GPIO_BASE + GPGCON_OFFSET) +#define GPGDAT_REG __REG(ELFIN_GPIO_BASE + GPGDAT_OFFSET) +#define GPGPUD_REG __REG(ELFIN_GPIO_BASE + GPGPUD_OFFSET) +#define GPGCONSLP_REG __REG(ELFIN_GPIO_BASE + GPGCONSLP_OFFSET) +#define GPGPUDSLP_REG __REG(ELFIN_GPIO_BASE + GPGPUDSLP_OFFSET) +#define GPHCON0_REG __REG(ELFIN_GPIO_BASE + GPHCON0_OFFSET) +#define GPHCON1_REG __REG(ELFIN_GPIO_BASE + GPHCON1_OFFSET) +#define GPHDAT_REG __REG(ELFIN_GPIO_BASE + GPHDAT_OFFSET) +#define GPHPUD_REG __REG(ELFIN_GPIO_BASE + GPHPUD_OFFSET) +#define GPHCONSLP_REG __REG(ELFIN_GPIO_BASE + GPHCONSLP_OFFSET) +#define GPHPUDSLP_REG __REG(ELFIN_GPIO_BASE + GPHPUDSLP_OFFSET) +#define GPICON_REG __REG(ELFIN_GPIO_BASE + GPICON_OFFSET) +#define GPIDAT_REG __REG(ELFIN_GPIO_BASE + GPIDAT_OFFSET) +#define GPIPUD_REG __REG(ELFIN_GPIO_BASE + GPIPUD_OFFSET) +#define GPICONSLP_REG __REG(ELFIN_GPIO_BASE + GPICONSLP_OFFSET) +#define GPIPUDSLP_REG __REG(ELFIN_GPIO_BASE + GPIPUDSLP_OFFSET) +#define GPJCON_REG __REG(ELFIN_GPIO_BASE + GPJCON_OFFSET) +#define GPJDAT_REG __REG(ELFIN_GPIO_BASE + GPJDAT_OFFSET) +#define GPJPUD_REG __REG(ELFIN_GPIO_BASE + GPJPUD_OFFSET) +#define GPJCONSLP_REG __REG(ELFIN_GPIO_BASE + GPJCONSLP_OFFSET) +#define GPJPUDSLP_REG __REG(ELFIN_GPIO_BASE + GPJPUDSLP_OFFSET) +#define GPKCON0_REG __REG(ELFIN_GPIO_BASE + GPKCON0_OFFSET) +#define GPKCON1_REG __REG(ELFIN_GPIO_BASE + GPKCON1_OFFSET) +#define GPKDAT_REG __REG(ELFIN_GPIO_BASE + GPKDAT_OFFSET) +#define GPKPUD_REG __REG(ELFIN_GPIO_BASE + GPKPUD_OFFSET) +#define GPLCON0_REG __REG(ELFIN_GPIO_BASE + GPLCON0_OFFSET) +#define GPLCON1_REG __REG(ELFIN_GPIO_BASE + GPLCON1_OFFSET) +#define GPLDAT_REG __REG(ELFIN_GPIO_BASE + GPLDAT_OFFSET) +#define GPLPUD_REG __REG(ELFIN_GPIO_BASE + GPLPUD_OFFSET) +#define GPMCON_REG __REG(ELFIN_GPIO_BASE + GPMCON_OFFSET) +#define GPMDAT_REG __REG(ELFIN_GPIO_BASE + GPMDAT_OFFSET) +#define GPMPUD_REG __REG(ELFIN_GPIO_BASE + GPMPUD_OFFSET) +#define GPNCON_REG __REG(ELFIN_GPIO_BASE + GPNCON_OFFSET) +#define GPNDAT_REG __REG(ELFIN_GPIO_BASE + GPNDAT_OFFSET) +#define GPNPUD_REG __REG(ELFIN_GPIO_BASE + GPNPUD_OFFSET) +#define GPOCON_REG __REG(ELFIN_GPIO_BASE + GPOCON_OFFSET) +#define GPODAT_REG __REG(ELFIN_GPIO_BASE + GPODAT_OFFSET) +#define GPOPUD_REG __REG(ELFIN_GPIO_BASE + GPOPUD_OFFSET) +#define GPOCONSLP_REG __REG(ELFIN_GPIO_BASE + GPOCONSLP_OFFSET) +#define GPOPUDSLP_REG __REG(ELFIN_GPIO_BASE + GPOPUDSLP_OFFSET) +#define GPPCON_REG __REG(ELFIN_GPIO_BASE + GPPCON_OFFSET) +#define GPPDAT_REG __REG(ELFIN_GPIO_BASE + GPPDAT_OFFSET) +#define GPPPUD_REG __REG(ELFIN_GPIO_BASE + GPPPUD_OFFSET) +#define GPPCONSLP_REG __REG(ELFIN_GPIO_BASE + GPPCONSLP_OFFSET) +#define GPPPUDSLP_REG __REG(ELFIN_GPIO_BASE + GPPPUDSLP_OFFSET) +#define GPQCON_REG __REG(ELFIN_GPIO_BASE + GPQCON_OFFSET) +#define GPQDAT_REG __REG(ELFIN_GPIO_BASE + GPQDAT_OFFSET) +#define GPQPUD_REG __REG(ELFIN_GPIO_BASE + GPQPUD_OFFSET) +#define GPQCONSLP_REG __REG(ELFIN_GPIO_BASE + GPQCONSLP_OFFSET) +#define GPQPUDSLP_REG __REG(ELFIN_GPIO_BASE + GPQPUDSLP_OFFSET) + +/* + * Bus Matrix + */ +#define ELFIN_MEM_SYS_CFG 0x7e00f120 + +#define GPACON (ELFIN_GPIO_BASE + GPACON_OFFSET) +#define GPADAT (ELFIN_GPIO_BASE + GPADAT_OFFSET) +#define GPAPUD (ELFIN_GPIO_BASE + GPAPUD_OFFSET) +#define GPACONSLP (ELFIN_GPIO_BASE + GPACONSLP_OFFSET) +#define GPAPUDSLP (ELFIN_GPIO_BASE + GPAPUDSLP_OFFSET) +#define GPBCON (ELFIN_GPIO_BASE + GPBCON_OFFSET) +#define GPBDAT (ELFIN_GPIO_BASE + GPBDAT_OFFSET) +#define GPBPUD (ELFIN_GPIO_BASE + GPBPUD_OFFSET) +#define GPBCONSLP (ELFIN_GPIO_BASE + GPBCONSLP_OFFSET) +#define GPBPUDSLP (ELFIN_GPIO_BASE + GPBPUDSLP_OFFSET) +#define GPCCON (ELFIN_GPIO_BASE + GPCCON_OFFSET) +#define GPCDAT (ELFIN_GPIO_BASE + GPCDAT_OFFSET) +#define GPCPUD (ELFIN_GPIO_BASE + GPCPUD_OFFSET) +#define GPCCONSLP (ELFIN_GPIO_BASE + GPCCONSLP_OFFSET) +#define GPCPUDSLP (ELFIN_GPIO_BASE + GPCPUDSLP_OFFSET) +#define GPDCON (ELFIN_GPIO_BASE + GPDCON_OFFSET) +#define GPDDAT (ELFIN_GPIO_BASE + GPDDAT_OFFSET) +#define GPDPUD (ELFIN_GPIO_BASE + GPDPUD_OFFSET) +#define GPDCONSLP (ELFIN_GPIO_BASE + GPDCONSLP_OFFSET) +#define GPDPUDSLP (ELFIN_GPIO_BASE + GPDPUDSLP_OFFSET) +#define GPECON (ELFIN_GPIO_BASE + GPECON_OFFSET) +#define GPEDAT (ELFIN_GPIO_BASE + GPEDAT_OFFSET) +#define GPEPUD (ELFIN_GPIO_BASE + GPEPUD_OFFSET) +#define GPECONSLP (ELFIN_GPIO_BASE + GPECONSLP_OFFSET) +#define GPEPUDSLP (ELFIN_GPIO_BASE + GPEPUDSLP_OFFSET) +#define GPFCON (ELFIN_GPIO_BASE + GPFCON_OFFSET) +#define GPFDAT (ELFIN_GPIO_BASE + GPFDAT_OFFSET) +#define GPFPUD (ELFIN_GPIO_BASE + GPFPUD_OFFSET) +#define GPFCONSLP (ELFIN_GPIO_BASE + GPFCONSLP_OFFSET) +#define GPFPUDSLP (ELFIN_GPIO_BASE + GPFPUDSLP_OFFSET) +#define GPGCON (ELFIN_GPIO_BASE + GPGCON_OFFSET) +#define GPGDAT (ELFIN_GPIO_BASE + GPGDAT_OFFSET) +#define GPGPUD (ELFIN_GPIO_BASE + GPGPUD_OFFSET) +#define GPGCONSLP (ELFIN_GPIO_BASE + GPGCONSLP_OFFSET) +#define GPGPUDSLP (ELFIN_GPIO_BASE + GPGPUDSLP_OFFSET) +#define GPHCON0 (ELFIN_GPIO_BASE + GPHCON0_OFFSET) +#define GPHCON1 (ELFIN_GPIO_BASE + GPHCON1_OFFSET) +#define GPHDAT (ELFIN_GPIO_BASE + GPHDAT_OFFSET) +#define GPHPUD (ELFIN_GPIO_BASE + GPHPUD_OFFSET) +#define GPHCONSLP (ELFIN_GPIO_BASE + GPHCONSLP_OFFSET) +#define GPHPUDSLP (ELFIN_GPIO_BASE + GPHPUDSLP_OFFSET) +#define GPICON (ELFIN_GPIO_BASE + GPICON_OFFSET) +#define GPIDAT (ELFIN_GPIO_BASE + GPIDAT_OFFSET) +#define GPIPUD (ELFIN_GPIO_BASE + GPIPUD_OFFSET) +#define GPICONSLP (ELFIN_GPIO_BASE + GPICONSLP_OFFSET) +#define GPIPUDSLP (ELFIN_GPIO_BASE + GPIPUDSLP_OFFSET) +#define GPJCON (ELFIN_GPIO_BASE + GPJCON_OFFSET) +#define GPJDAT (ELFIN_GPIO_BASE + GPJDAT_OFFSET) +#define GPJPUD (ELFIN_GPIO_BASE + GPJPUD_OFFSET) +#define GPJCONSLP (ELFIN_GPIO_BASE + GPJCONSLP_OFFSET) +#define GPJPUDSLP (ELFIN_GPIO_BASE + GPJPUDSLP_OFFSET) +#define GPKCON0 (ELFIN_GPIO_BASE + GPKCON0_OFFSET) +#define GPKCON1 (ELFIN_GPIO_BASE + GPKCON1_OFFSET) +#define GPKDAT (ELFIN_GPIO_BASE + GPKDAT_OFFSET) +#define GPKPUD (ELFIN_GPIO_BASE + GPKPUD_OFFSET) +#define GPLCON0 (ELFIN_GPIO_BASE + GPLCON0_OFFSET) +#define GPLCON1 (ELFIN_GPIO_BASE + GPLCON1_OFFSET) +#define GPLDAT (ELFIN_GPIO_BASE + GPLDAT_OFFSET) +#define GPLPUD (ELFIN_GPIO_BASE + GPLPUD_OFFSET) +#define GPMCON (ELFIN_GPIO_BASE + GPMCON_OFFSET) +#define GPMDAT (ELFIN_GPIO_BASE + GPMDAT_OFFSET) +#define GPMPUD (ELFIN_GPIO_BASE + GPMPUD_OFFSET) +#define GPNCON (ELFIN_GPIO_BASE + GPNCON_OFFSET) +#define GPNDAT (ELFIN_GPIO_BASE + GPNDAT_OFFSET) +#define GPNPUD (ELFIN_GPIO_BASE + GPNPUD_OFFSET) +#define GPOCON (ELFIN_GPIO_BASE + GPOCON_OFFSET) +#define GPODAT (ELFIN_GPIO_BASE + GPODAT_OFFSET) +#define GPOPUD (ELFIN_GPIO_BASE + GPOPUD_OFFSET) +#define GPOCONSLP (ELFIN_GPIO_BASE + GPOCONSLP_OFFSET) +#define GPOPUDSLP (ELFIN_GPIO_BASE + GPOPUDSLP_OFFSET) +#define GPPCON (ELFIN_GPIO_BASE + GPPCON_OFFSET) +#define GPPDAT (ELFIN_GPIO_BASE + GPPDAT_OFFSET) +#define GPPPUD (ELFIN_GPIO_BASE + GPPPUD_OFFSET) +#define GPPCONSLP (ELFIN_GPIO_BASE + GPPCONSLP_OFFSET) +#define GPPPUDSLP (ELFIN_GPIO_BASE + GPPPUDSLP_OFFSET) +#define GPQCON (ELFIN_GPIO_BASE + GPQCON_OFFSET) +#define GPQDAT (ELFIN_GPIO_BASE + GPQDAT_OFFSET) +#define GPQPUD (ELFIN_GPIO_BASE + GPQPUD_OFFSET) +#define GPQCONSLP (ELFIN_GPIO_BASE + GPQCONSLP_OFFSET) +#define GPQPUDSLP (ELFIN_GPIO_BASE + GPQPUDSLP_OFFSET) + +/* + * Memory controller + */ +#define ELFIN_SROM_BASE 0x70000000 + +#define SROM_BW_REG __REG(ELFIN_SROM_BASE + 0x0) +#define SROM_BC0_REG __REG(ELFIN_SROM_BASE + 0x4) +#define SROM_BC1_REG __REG(ELFIN_SROM_BASE + 0x8) +#define SROM_BC2_REG __REG(ELFIN_SROM_BASE + 0xC) +#define SROM_BC3_REG __REG(ELFIN_SROM_BASE + 0x10) +#define SROM_BC4_REG __REG(ELFIN_SROM_BASE + 0x14) +#define SROM_BC5_REG __REG(ELFIN_SROM_BASE + 0x18) + +/* + * SDRAM Controller + */ +#define ELFIN_DMC0_BASE 0x7e000000 +#define ELFIN_DMC1_BASE 0x7e001000 + +#define INDEX_DMC_MEMC_STATUS 0x00 +#define INDEX_DMC_MEMC_CMD 0x04 +#define INDEX_DMC_DIRECT_CMD 0x08 +#define INDEX_DMC_MEMORY_CFG 0x0C +#define INDEX_DMC_REFRESH_PRD 0x10 +#define INDEX_DMC_CAS_LATENCY 0x14 +#define INDEX_DMC_T_DQSS 0x18 +#define INDEX_DMC_T_MRD 0x1C +#define INDEX_DMC_T_RAS 0x20 +#define INDEX_DMC_T_RC 0x24 +#define INDEX_DMC_T_RCD 0x28 +#define INDEX_DMC_T_RFC 0x2C +#define INDEX_DMC_T_RP 0x30 +#define INDEX_DMC_T_RRD 0x34 +#define INDEX_DMC_T_WR 0x38 +#define INDEX_DMC_T_WTR 0x3C +#define INDEX_DMC_T_XP 0x40 +#define INDEX_DMC_T_XSR 0x44 +#define INDEX_DMC_T_ESR 0x48 +#define INDEX_DMC_MEMORY_CFG2 0x4C +#define INDEX_DMC_CHIP_0_CFG 0x200 +#define INDEX_DMC_CHIP_1_CFG 0x204 +#define INDEX_DMC_CHIP_2_CFG 0x208 +#define INDEX_DMC_CHIP_3_CFG 0x20C +#define INDEX_DMC_USER_STATUS 0x300 +#define INDEX_DMC_USER_CONFIG 0x304 + +/* + * Memory Chip direct command + */ +#define DMC_NOP0 0x0c0000 +#define DMC_NOP1 0x1c0000 +#define DMC_PA0 0x000000 /* Precharge all */ +#define DMC_PA1 0x100000 +#define DMC_AR0 0x040000 /* Autorefresh */ +#define DMC_AR1 0x140000 +#define DMC_SDR_MR0 0x080032 /* MRS, CAS 3, Burst Length 4 */ +#define DMC_SDR_MR1 0x180032 +#define DMC_DDR_MR0 0x080162 +#define DMC_DDR_MR1 0x180162 +#define DMC_mDDR_MR0 0x080032 /* CAS 3, Burst Length 4 */ +#define DMC_mDDR_MR1 0x180032 +#define DMC_mSDR_EMR0 0x0a0000 /* EMRS, DS:Full, PASR:Full Array */ +#define DMC_mSDR_EMR1 0x1a0000 +#define DMC_DDR_EMR0 0x090000 +#define DMC_DDR_EMR1 0x190000 +#define DMC_mDDR_EMR0 0x0a0000 /* DS:Full, PASR:Full Array */ +#define DMC_mDDR_EMR1 0x1a0000 + +/* + * Definitions for memory configuration + * Set memory configuration + * active_chips = 1'b0 (1 chip) + * qos_master_chip = 3'b000(ARID[3:0]) + * memory burst = 3'b010(burst 4) + * stop_mem_clock = 1'b0(disable dynamical stop) + * auto_power_down = 1'b0(disable auto power-down mode) + * power_down_prd = 6'b00_0000(0 cycle for auto power-down) + * ap_bit = 1'b0 (bit position of auto-precharge is 10) + * row_bits = 3'b010(# row address 13) + * column_bits = 3'b010(# column address 10 ) + * + * Set user configuration + * 2'b10=SDRAM/mSDRAM, 2'b11=DDR, 2'b01=mDDR + * + * Set chip select for chip [n] + * row bank control, bank address 0x3000_0000 ~ 0x37ff_ffff + * CHIP_[n]_CFG=0x30F8, 30: ADDR[31:24], F8: Mask[31:24] + */ + +/* + * Nand flash controller + */ +#define ELFIN_NAND_BASE 0x70200000 + +#define NFCONF_OFFSET 0x00 +#define NFCONT_OFFSET 0x04 +#define NFCMMD_OFFSET 0x08 +#define NFADDR_OFFSET 0x0c +#define NFDATA_OFFSET 0x10 +#define NFMECCDATA0_OFFSET 0x14 +#define NFMECCDATA1_OFFSET 0x18 +#define NFSECCDATA0_OFFSET 0x1c +#define NFSBLK_OFFSET 0x20 +#define NFEBLK_OFFSET 0x24 +#define NFSTAT_OFFSET 0x28 +#define NFESTAT0_OFFSET 0x2c +#define NFESTAT1_OFFSET 0x30 +#define NFMECC0_OFFSET 0x34 +#define NFMECC1_OFFSET 0x38 +#define NFSECC_OFFSET 0x3c +#define NFMLCBITPT_OFFSET 0x40 + +#define NFCONF (ELFIN_NAND_BASE + NFCONF_OFFSET) +#define NFCONT (ELFIN_NAND_BASE + NFCONT_OFFSET) +#define NFCMMD (ELFIN_NAND_BASE + NFCMMD_OFFSET) +#define NFADDR (ELFIN_NAND_BASE + NFADDR_OFFSET) +#define NFDATA (ELFIN_NAND_BASE + NFDATA_OFFSET) +#define NFMECCDATA0 (ELFIN_NAND_BASE + NFMECCDATA0_OFFSET) +#define NFMECCDATA1 (ELFIN_NAND_BASE + NFMECCDATA1_OFFSET) +#define NFSECCDATA0 (ELFIN_NAND_BASE + NFSECCDATA0_OFFSET) +#define NFSBLK (ELFIN_NAND_BASE + NFSBLK_OFFSET) +#define NFEBLK (ELFIN_NAND_BASE + NFEBLK_OFFSET) +#define NFSTAT (ELFIN_NAND_BASE + NFSTAT_OFFSET) +#define NFESTAT0 (ELFIN_NAND_BASE + NFESTAT0_OFFSET) +#define NFESTAT1 (ELFIN_NAND_BASE + NFESTAT1_OFFSET) +#define NFMECC0 (ELFIN_NAND_BASE + NFMECC0_OFFSET) +#define NFMECC1 (ELFIN_NAND_BASE + NFMECC1_OFFSET) +#define NFSECC (ELFIN_NAND_BASE + NFSECC_OFFSET) +#define NFMLCBITPT (ELFIN_NAND_BASE + NFMLCBITPT_OFFSET) + +#define NFCONF_REG __REG(ELFIN_NAND_BASE + NFCONF_OFFSET) +#define NFCONT_REG __REG(ELFIN_NAND_BASE + NFCONT_OFFSET) +#define NFCMD_REG __REG(ELFIN_NAND_BASE + NFCMMD_OFFSET) +#define NFADDR_REG __REG(ELFIN_NAND_BASE + NFADDR_OFFSET) +#define NFDATA_REG __REG(ELFIN_NAND_BASE + NFDATA_OFFSET) +#define NFDATA8_REG __REGb(ELFIN_NAND_BASE + NFDATA_OFFSET) +#define NFMECCDATA0_REG __REG(ELFIN_NAND_BASE + NFMECCDATA0_OFFSET) +#define NFMECCDATA1_REG __REG(ELFIN_NAND_BASE + NFMECCDATA1_OFFSET) +#define NFSECCDATA0_REG __REG(ELFIN_NAND_BASE + NFSECCDATA0_OFFSET) +#define NFSBLK_REG __REG(ELFIN_NAND_BASE + NFSBLK_OFFSET) +#define NFEBLK_REG __REG(ELFIN_NAND_BASE + NFEBLK_OFFSET) +#define NFSTAT_REG __REG(ELFIN_NAND_BASE + NFSTAT_OFFSET) +#define NFESTAT0_REG __REG(ELFIN_NAND_BASE + NFESTAT0_OFFSET) +#define NFESTAT1_REG __REG(ELFIN_NAND_BASE + NFESTAT1_OFFSET) +#define NFMECC0_REG __REG(ELFIN_NAND_BASE + NFMECC0_OFFSET) +#define NFMECC1_REG __REG(ELFIN_NAND_BASE + NFMECC1_OFFSET) +#define NFSECC_REG __REG(ELFIN_NAND_BASE + NFSECC_OFFSET) +#define NFMLCBITPT_REG __REG(ELFIN_NAND_BASE + NFMLCBITPT_OFFSET) + +#define NFCONF_ECC_4BIT (1<<24) + +#define NFCONT_ECC_ENC (1<<18) +#define NFCONT_WP (1<<16) +#define NFCONT_MECCLOCK (1<<7) +#define NFCONT_SECCLOCK (1<<6) +#define NFCONT_INITMECC (1<<5) +#define NFCONT_INITSECC (1<<4) +#define NFCONT_INITECC (NFCONT_INITMECC | NFCONT_INITSECC) +#define NFCONT_CS_ALT (1<<2) +#define NFCONT_CS (1<<1) +#define NFCONT_ENABLE (1<<0) + +#define NFSTAT_ECCENCDONE (1<<7) +#define NFSTAT_ECCDECDONE (1<<6) +#define NFSTAT_RnB (1<<0) + +#define NFESTAT0_ECCBUSY (1<<31) + +/* + * Interrupt + */ +#define ELFIN_VIC0_BASE_ADDR 0x71200000 +#define ELFIN_VIC1_BASE_ADDR 0x71300000 +#define oINTMOD 0x0C /* VIC INT SELECT (IRQ or FIQ) */ +#define oINTUNMSK 0x10 /* VIC INT EN (write 1 to unmask) */ +#define oINTMSK 0x14 /* VIC INT EN CLEAR (write 1 to mask) */ +#define oINTSUBMSK 0x1C /* VIC SOFT INT CLEAR */ +#define oVECTADDR 0xF00 /* VIC ADDRESS */ + +/* + * Watchdog timer + */ +#define ELFIN_WATCHDOG_BASE 0x7E004000 + +#define WTCON_REG __REG(0x7E004004) +#define WTDAT_REG __REG(0x7E004008) +#define WTCNT_REG __REG(0x7E00400C) + + +/* + * UART + */ +#define ELFIN_UART_BASE 0x7F005000 + +#define ELFIN_UART0_OFFSET 0x0000 +#define ELFIN_UART1_OFFSET 0x0400 +#define ELFIN_UART2_OFFSET 0x0800 + +#define ULCON_OFFSET 0x00 +#define UCON_OFFSET 0x04 +#define UFCON_OFFSET 0x08 +#define UMCON_OFFSET 0x0C +#define UTRSTAT_OFFSET 0x10 +#define UERSTAT_OFFSET 0x14 +#define UFSTAT_OFFSET 0x18 +#define UMSTAT_OFFSET 0x1C +#define UTXH_OFFSET 0x20 +#define URXH_OFFSET 0x24 +#define UBRDIV_OFFSET 0x28 +#define UDIVSLOT_OFFSET 0x2C +#define UINTP_OFFSET 0x30 +#define UINTSP_OFFSET 0x34 +#define UINTM_OFFSET 0x38 + +#define ULCON0_REG __REG(0x7F005000) +#define UCON0_REG __REG(0x7F005004) +#define UFCON0_REG __REG(0x7F005008) +#define UMCON0_REG __REG(0x7F00500C) +#define UTRSTAT0_REG __REG(0x7F005010) +#define UERSTAT0_REG __REG(0x7F005014) +#define UFSTAT0_REG __REG(0x7F005018) +#define UMSTAT0_REG __REG(0x7F00501c) +#define UTXH0_REG __REG(0x7F005020) +#define URXH0_REG __REG(0x7F005024) +#define UBRDIV0_REG __REG(0x7F005028) +#define UDIVSLOT0_REG __REG(0x7F00502c) +#define UINTP0_REG __REG(0x7F005030) +#define UINTSP0_REG __REG(0x7F005034) +#define UINTM0_REG __REG(0x7F005038) + +#define ULCON1_REG __REG(0x7F005400) +#define UCON1_REG __REG(0x7F005404) +#define UFCON1_REG __REG(0x7F005408) +#define UMCON1_REG __REG(0x7F00540C) +#define UTRSTAT1_REG __REG(0x7F005410) +#define UERSTAT1_REG __REG(0x7F005414) +#define UFSTAT1_REG __REG(0x7F005418) +#define UMSTAT1_REG __REG(0x7F00541c) +#define UTXH1_REG __REG(0x7F005420) +#define URXH1_REG __REG(0x7F005424) +#define UBRDIV1_REG __REG(0x7F005428) +#define UDIVSLOT1_REG __REG(0x7F00542c) +#define UINTP1_REG __REG(0x7F005430) +#define UINTSP1_REG __REG(0x7F005434) +#define UINTM1_REG __REG(0x7F005438) + +#define UTRSTAT_TX_EMPTY (1 << 2) +#define UTRSTAT_RX_READY (1 << 0) +#define UART_ERR_MASK 0xF + +/* + * PWM timer + */ +#define ELFIN_TIMER_BASE 0x7F006000 + +#define TCFG0_REG __REG(0x7F006000) +#define TCFG1_REG __REG(0x7F006004) +#define TCON_REG __REG(0x7F006008) +#define TCNTB0_REG __REG(0x7F00600c) +#define TCMPB0_REG __REG(0x7F006010) +#define TCNTO0_REG __REG(0x7F006014) +#define TCNTB1_REG __REG(0x7F006018) +#define TCMPB1_REG __REG(0x7F00601c) +#define TCNTO1_REG __REG(0x7F006020) +#define TCNTB2_REG __REG(0x7F006024) +#define TCMPB2_REG __REG(0x7F006028) +#define TCNTO2_REG __REG(0x7F00602c) +#define TCNTB3_REG __REG(0x7F006030) +#define TCMPB3_REG __REG(0x7F006034) +#define TCNTO3_REG __REG(0x7F006038) +#define TCNTB4_REG __REG(0x7F00603c) +#define TCNTO4_REG __REG(0x7F006040) + +/* Fields */ +#define fTCFG0_DZONE Fld(8, 16) /* the dead zone length (=timer 0) */ +#define fTCFG0_PRE1 Fld(8, 8) /* prescaler value for time 2,3,4 */ +#define fTCFG0_PRE0 Fld(8, 0) /* prescaler value for time 0,1 */ +#define fTCFG1_MUX4 Fld(4, 16) +/* bits */ +#define TCFG0_DZONE(x) FInsrt((x), fTCFG0_DZONE) +#define TCFG0_PRE1(x) FInsrt((x), fTCFG0_PRE1) +#define TCFG0_PRE0(x) FInsrt((x), fTCFG0_PRE0) +#define TCON_4_AUTO (1 << 22) /* auto reload on/off for Timer 4 */ +#define TCON_4_UPDATE (1 << 21) /* manual Update TCNTB4 */ +#define TCON_4_ONOFF (1 << 20) /* 0: Stop, 1: start Timer 4 */ +#define COUNT_4_ON (TCON_4_ONOFF * 1) +#define COUNT_4_OFF (TCON_4_ONOFF * 0) +#define TCON_3_AUTO (1 << 19) /* auto reload on/off for Timer 3 */ +#define TIMER3_ATLOAD_ON (TCON_3_AUTO * 1) +#define TIMER3_ATLAOD_OFF FClrBit(TCON, TCON_3_AUTO) +#define TCON_3_INVERT (1 << 18) /* 1: Inverter on for TOUT3 */ +#define TIMER3_IVT_ON (TCON_3_INVERT * 1) +#define TIMER3_IVT_OFF (FClrBit(TCON, TCON_3_INVERT)) +#define TCON_3_MAN (1 << 17) /* manual Update TCNTB3,TCMPB3 */ +#define TIMER3_MANUP (TCON_3_MAN*1) +#define TIMER3_NOP (FClrBit(TCON, TCON_3_MAN)) +#define TCON_3_ONOFF (1 << 16) /* 0: Stop, 1: start Timer 3 */ +#define TIMER3_ON (TCON_3_ONOFF * 1) +#define TIMER3_OFF (FClrBit(TCON, TCON_3_ONOFF)) + +#if defined(CONFIG_CLK_400_100_50) +#define STARTUP_AMDIV 400 +#define STARTUP_MDIV 400 +#define STARTUP_PDIV 6 +#define STARTUP_SDIV 1 +#elif defined(CONFIG_CLK_400_133_66) +#define STARTUP_AMDIV 400 +#define STARTUP_MDIV 533 +#define STARTUP_PDIV 6 +#define STARTUP_SDIV 1 +#elif defined(CONFIG_CLK_533_133_66) +#define STARTUP_AMDIV 533 +#define STARTUP_MDIV 533 +#define STARTUP_PDIV 6 +#define STARTUP_SDIV 1 +#elif defined(CONFIG_CLK_667_133_66) +#define STARTUP_AMDIV 667 +#define STARTUP_MDIV 533 +#define STARTUP_PDIV 6 +#define STARTUP_SDIV 1 +#endif + +#define STARTUP_PCLKDIV 3 +#define STARTUP_HCLKX2DIV 1 +#define STARTUP_HCLKDIV 1 +#define STARTUP_MPLLDIV 1 +#define STARTUP_APLLDIV 0 + +#define CLK_DIV_VAL ((STARTUP_PCLKDIV << 12) | (STARTUP_HCLKX2DIV << 9) | \ + (STARTUP_HCLKDIV << 8) | (STARTUP_MPLLDIV<<4) | STARTUP_APLLDIV) +#define MPLL_VAL ((1 << 31) | (STARTUP_MDIV << 16) | \ + (STARTUP_PDIV << 8) | STARTUP_SDIV) +#define STARTUP_MPLL (((CONFIG_SYS_CLK_FREQ >> STARTUP_SDIV) / \ + STARTUP_PDIV) * STARTUP_MDIV) + +#if defined(CONFIG_SYNC_MODE) +#define APLL_VAL ((1 << 31) | (STARTUP_MDIV << 16) | \ + (STARTUP_PDIV << 8) | STARTUP_SDIV) +#define STARTUP_APLL (((CONFIG_SYS_CLK_FREQ >> STARTUP_SDIV) / \ + STARTUP_PDIV) * STARTUP_MDIV) +#define STARTUP_HCLK (STARTUP_MPLL / (STARTUP_HCLKX2DIV + 1) / \ + (STARTUP_HCLKDIV + 1)) +#else +#define APLL_VAL ((1 << 31) | (STARTUP_AMDIV << 16) | \ + (STARTUP_PDIV << 8) | STARTUP_SDIV) +#define STARTUP_APLL (((CONFIG_SYS_CLK_FREQ >> STARTUP_SDIV) / \ + STARTUP_PDIV) * STARTUP_AMDIV) +#define STARTUP_HCLK (STARTUP_MPLL / (STARTUP_HCLKX2DIV + 1) / \ + (STARTUP_HCLKDIV + 1)) +#endif + + +/*----------------------------------------------------------------------- + * Physical Memory Map + */ +#define DMC1_MEM_CFG 0x80010012 /* Chip1, Burst4, Row/Column bit */ +#define DMC1_MEM_CFG2 0xB45 +#define DMC1_CHIP0_CFG 0x150F8 /* 0x4000_0000 ~ 0x43ff_ffff (64MB) */ +#define DMC_DDR_32_CFG 0x0 /* 32bit, DDR */ + +/* Memory Parameters */ +/* DDR Parameters */ +#define DDR_tREFRESH 7800 /* ns */ +#define DDR_tRAS 45 /* ns (min: 45ns)*/ +#define DDR_tRC 68 /* ns (min: 67.5ns)*/ +#define DDR_tRCD 23 /* ns (min: 22.5ns)*/ +#define DDR_tRFC 80 /* ns (min: 80ns)*/ +#define DDR_tRP 23 /* ns (min: 22.5ns)*/ +#define DDR_tRRD 15 /* ns (min: 15ns)*/ +#define DDR_tWR 15 /* ns (min: 15ns)*/ +#define DDR_tXSR 120 /* ns (min: 120ns)*/ +#define DDR_CASL 3 /* CAS Latency 3 */ + +/* + * mDDR memory configuration + */ + +#define NS_TO_CLK(t) ((STARTUP_HCLK / 1000 * (t) - 1) / 1000000) + +#define DMC_DDR_BA_EMRS 2 +#define DMC_DDR_MEM_CASLAT 3 +/* 6 Set Cas Latency to 3 */ +#define DMC_DDR_CAS_LATENCY (DDR_CASL << 1) +/* Min 0.75 ~ 1.25 */ +#define DMC_DDR_t_DQSS 1 +/* Min 2 tck */ +#define DMC_DDR_t_MRD 2 +/* 7, Min 45ns */ +#define DMC_DDR_t_RAS (NS_TO_CLK(DDR_tRAS) + 1) +/* 10, Min 67.5ns */ +#define DMC_DDR_t_RC (NS_TO_CLK(DDR_tRC) + 1) +/* 4,5(TRM), Min 22.5ns */ +#define DMC_DDR_t_RCD (NS_TO_CLK(DDR_tRCD) + 1) +#define DMC_DDR_schedule_RCD ((DMC_DDR_t_RCD - 3) << 3) +/* 11,18(TRM) Min 80ns */ +#define DMC_DDR_t_RFC (NS_TO_CLK(DDR_tRFC) + 1) +#define DMC_DDR_schedule_RFC ((DMC_DDR_t_RFC - 3) << 5) +/* 4, 5(TRM) Min 22.5ns */ +#define DMC_DDR_t_RP (NS_TO_CLK(DDR_tRP) + 1) +#define DMC_DDR_schedule_RP ((DMC_DDR_t_RP - 3) << 3) +/* 3, Min 15ns */ +#define DMC_DDR_t_RRD (NS_TO_CLK(DDR_tRRD) + 1) +/* Min 15ns */ +#define DMC_DDR_t_WR (NS_TO_CLK(DDR_tWR) + 1) +#define DMC_DDR_t_WTR 2 +/* 1tck + tIS(1.5ns) */ +#define DMC_DDR_t_XP 2 +/* 17, Min 120ns */ +#define DMC_DDR_t_XSR (NS_TO_CLK(DDR_tXSR) + 1) +#define DMC_DDR_t_ESR DMC_DDR_t_XSR +/* TRM 2656 */ +#define DMC_DDR_REFRESH_PRD (NS_TO_CLK(DDR_tREFRESH)) +/* 2b01 : mDDR */ +#define DMC_DDR_USER_CONFIG 1 + +#ifndef __ASSEMBLY__ +enum s3c64xx_uarts_nr { + S3C64XX_UART0, + S3C64XX_UART1, + S3C64XX_UART2, +}; + +#include "s3c64x0.h" + +static inline s3c64xx_uart *s3c64xx_get_base_uart(enum s3c64xx_uarts_nr nr) +{ + return (s3c64xx_uart *)(ELFIN_UART_BASE + (nr * 0x400)); +} +#endif + +#endif /*__S3C6400_H__*/ diff --git a/include/s3c64x0.h b/include/s3c64x0.h new file mode 100644 index 0000000..0bbf1d0 --- /dev/null +++ b/include/s3c64x0.h @@ -0,0 +1,90 @@ +/* + * (C) Copyright 2003 + * David MÃŒller ELSOFT AG Switzerland. d.mueller@elsoft.ch + * + * (C) Copyright 2008 + * Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/************************************************ + * NAME : S3C64XX.h + * Version : 31.3.2003 + * + * common stuff for SAMSUNG S3C64XX SoC + ************************************************/ + +#ifndef __S3C64XX_H__ +#define __S3C64XX_H__ + +#if defined(CONFIG_SYNC_MODE) && defined(CONFIG_S3C6400) +#error CONFIG_SYNC_MODE unavailable on S3C6400, please, fix your configuration! +#endif + +#include <asm/types.h> + +/* UART (see manual chapter 11) */ +typedef struct { + volatile u32 ULCON; + volatile u32 UCON; + volatile u32 UFCON; + volatile u32 UMCON; + volatile u32 UTRSTAT; + volatile u32 UERSTAT; + volatile u32 UFSTAT; + volatile u32 UMSTAT; +#ifdef __BIG_ENDIAN + volatile u8 res1[3]; + volatile u8 UTXH; + volatile u8 res2[3]; + volatile u8 URXH; +#else /* Little Endian */ + volatile u8 UTXH; + volatile u8 res1[3]; + volatile u8 URXH; + volatile u8 res2[3]; +#endif + volatile u32 UBRDIV; +#ifdef __BIG_ENDIAN + volatile u8 res3[2]; + volatile u16 UDIVSLOT; +#else + volatile u16 UDIVSLOT; + volatile u8 res3[2]; +#endif +} s3c64xx_uart; + +/* PWM TIMER (see manual chapter 10) */ +typedef struct { + volatile u32 TCNTB; + volatile u32 TCMPB; + volatile u32 TCNTO; +} s3c64xx_timer; + +typedef struct { + volatile u32 TCFG0; + volatile u32 TCFG1; + volatile u32 TCON; + s3c64xx_timer ch[4]; + volatile u32 TCNTB4; + volatile u32 TCNTO4; +} s3c64xx_timers; + +#endif /*__S3C64XX_H__*/ diff --git a/lib_arm/board.c b/lib_arm/board.c index 6e3ef08..5ade882 100644 --- a/lib_arm/board.c +++ b/lib_arm/board.c @@ -430,9 +430,9 @@ void start_armboot (void) /* Perform network card initialisation if necessary */ #ifdef CONFIG_DRIVER_TI_EMAC -extern void dm644x_eth_set_mac_addr (const u_int8_t *addr); +extern void davinci_eth_set_mac_addr (const u_int8_t *addr); if (getenv ("ethaddr")) { - dm644x_eth_set_mac_addr(gd->bd->bi_enetaddr); + davinci_eth_set_mac_addr(gd->bd->bi_enetaddr); } #endif diff --git a/nand_spl/board/samsung/smdk6400/Makefile b/nand_spl/board/samsung/smdk6400/Makefile new file mode 100644 index 0000000..ae9eb2a --- /dev/null +++ b/nand_spl/board/samsung/smdk6400/Makefile @@ -0,0 +1,106 @@ +# +# (C) Copyright 2006-2007 +# Stefan Roese, DENX Software Engineering, sr@denx.de. +# +# (C) Copyright 2008 +# Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de> +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +CONFIG_NAND_SPL = y + +include $(TOPDIR)/config.mk +include $(TOPDIR)/nand_spl/board/$(BOARDDIR)/config.mk + +LDSCRIPT= $(TOPDIR)/nand_spl/board/$(BOARDDIR)/u-boot.lds +LDFLAGS = -Bstatic -T $(LDSCRIPT) -Ttext $(TEXT_BASE) $(PLATFORM_LDFLAGS) +AFLAGS += -DCONFIG_NAND_SPL +CFLAGS += -DCONFIG_NAND_SPL + +SOBJS = start.o cpu_init.o lowlevel_init.o +COBJS = nand_boot.o nand_ecc.o s3c64xx.o + +SRCS := $(addprefix $(obj),$(SOBJS:.o=.S) $(COBJS:.o=.c)) +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) +__OBJS := $(SOBJS) $(COBJS) +LNDIR := $(OBJTREE)/nand_spl/board/$(BOARDDIR) + +nandobj := $(OBJTREE)/nand_spl/ + +ALL = $(nandobj)u-boot-spl $(nandobj)u-boot-spl.bin $(nandobj)u-boot-spl-16k.bin + +all: $(obj).depend $(ALL) + +$(nandobj)u-boot-spl-16k.bin: $(nandobj)u-boot-spl + $(OBJCOPY) ${OBJCFLAGS} --pad-to=$(PAD_TO) -O binary $< $@ + +$(nandobj)u-boot-spl.bin: $(nandobj)u-boot-spl + $(OBJCOPY) ${OBJCFLAGS} -O binary $< $@ + +$(nandobj)u-boot-spl: $(OBJS) + cd $(LNDIR) && $(LD) $(LDFLAGS) $(__OBJS) \ + -Map $(nandobj)u-boot-spl.map \ + -o $(nandobj)u-boot-spl + +# create symbolic links for common files + +# from cpu directory +$(obj)start.S: + @rm -f $@ + @ln -s $(TOPDIR)/cpu/arm1176/start.S $@ + +# from SoC directory +$(obj)cpu_init.S: + @rm -f $@ + @ln -s $(TOPDIR)/cpu/arm1176/s3c64xx/cpu_init.S $@ + +# from board directory +$(obj)lowlevel_init.S: + @rm -f $@ + @ln -s $(TOPDIR)/board/samsung/smdk6400/lowlevel_init.S $@ + +# from nand_spl directory +$(obj)nand_boot.c: + @rm -f $@ + @ln -s $(TOPDIR)/nand_spl/nand_boot.c $@ + +# from drivers/mtd/nand directory +$(obj)nand_ecc.c: + @rm -f $@ + @ln -s $(TOPDIR)/drivers/mtd/nand/nand_ecc.c $@ + +$(obj)s3c64xx.c: + @rm -f $@ + @ln -s $(TOPDIR)/drivers/mtd/nand/s3c64xx.c $@ + +######################################################################### + +$(obj)%.o: $(obj)%.S + $(CC) $(AFLAGS) -c -o $@ $< + +$(obj)%.o: $(obj)%.c + $(CC) $(CFLAGS) -c -o $@ $< + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/nand_spl/board/samsung/smdk6400/config.mk b/nand_spl/board/samsung/smdk6400/config.mk new file mode 100644 index 0000000..4b16230 --- /dev/null +++ b/nand_spl/board/samsung/smdk6400/config.mk @@ -0,0 +1,40 @@ +# +# (C) Copyright 2006 +# Stefan Roese, DENX Software Engineering, sr@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +# +# Samsung S3C64xx Reference Platform (smdk6400) board + +# TEXT_BASE for SPL: +# +# On S3C64xx platforms the SPL is located in SRAM at 0. +# +# TEXT_BASE = 0 + +include $(TOPDIR)/board/$(BOARDDIR)/config.mk + +# PAD_TO used to generate a 4kByte binary needed for the combined image +# -> PAD_TO = TEXT_BASE + 4096 +PAD_TO := $(shell expr $$[$(TEXT_BASE) + 4096]) + +ifeq ($(debug),1) +PLATFORM_CPPFLAGS += -DDEBUG +endif diff --git a/nand_spl/board/samsung/smdk6400/u-boot.lds b/nand_spl/board/samsung/smdk6400/u-boot.lds new file mode 100644 index 0000000..1bf022c --- /dev/null +++ b/nand_spl/board/samsung/smdk6400/u-boot.lds @@ -0,0 +1,61 @@ +/* + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, <gj@denx.de> + * + * (C) Copyright 2008 + * Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + . = 0x00000000; + + . = ALIGN(4); + .text : + { + start.o (.text) + cpu_init.o (.text) + nand_boot.o (.text) + + *(.text) + } + + . = ALIGN(4); + .rodata : { *(.rodata) } + + . = ALIGN(4); + .data : { *(.data) } + + . = ALIGN(4); + .got : { *(.got) } + + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + . = ALIGN(4); + __bss_start = .; + .bss : { *(.bss) } + _end = .; +} @@ -576,7 +576,7 @@ extern int at91rm9200_miiphy_initialize(bd_t *bis); extern int emac4xx_miiphy_initialize(bd_t *bis); extern int mcf52x2_miiphy_initialize(bd_t *bis); extern int ns7520_miiphy_initialize(bd_t *bis); -extern int dm644x_eth_miiphy_initialize(bd_t *bis); +extern int davinci_eth_miiphy_initialize(bd_t *bis); int eth_initialize(bd_t *bis) @@ -599,7 +599,7 @@ int eth_initialize(bd_t *bis) ns7520_miiphy_initialize(bis); #endif #if defined(CONFIG_DRIVER_TI_EMAC) - dm644x_eth_miiphy_initialize(bis); + davinci_eth_miiphy_initialize(bis); #endif return 0; } |