浏览代码

armv7: Add support for ST-Ericsson U8500 href platform

Minimal platform support to boot linux from SD.

Supported devices/hw limited to external MMC/SD slot,
GPIO, I2C and minimal PRCMU.

Signed-off-by: John Rigby <john.rigby@linaro.org>
CC: Albert Aribaud <albert.aribaud@free.fr>
John Rigby 14 年之前
父节点
当前提交
afbf88993c

+ 50 - 0
board/st-ericsson/u8500/Makefile

@@ -0,0 +1,50 @@
+#
+# Copyright (C) ST-Ericsson SA 2009
+#
+# 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
+
+CFLAGS += -D__RELEASE -D__STN_8500
+LIB	= $(obj)lib$(BOARD).o
+
+COBJS	:= u8500_href.o gpio.o prcmu.o
+
+SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS))
+SOBJS	:= $(addprefix $(obj),$(SOBJS))
+
+$(LIB): $(obj).depend $(OBJS) $(SOBJS)
+	$(call cmd_link_o_target, $(OBJS) $(SOBJS))
+
+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
+
+#########################################################################

+ 347 - 0
board/st-ericsson/u8500/gpio.c

@@ -0,0 +1,347 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2009
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/arch/gpio.h>
+
+static struct gpio_register *addr_gpio_register[] = {
+	(void *)U8500_GPIO_0_BASE,
+	(void *)U8500_GPIO_1_BASE,
+	(void *)U8500_GPIO_2_BASE,
+	(void *)U8500_GPIO_3_BASE,
+	(void *)U8500_GPIO_4_BASE,
+	(void *)U8500_GPIO_5_BASE,
+	(void *)U8500_GPIO_6_BASE,
+	(void *)U8500_GPIO_7_BASE,
+	(void *)U8500_GPIO_8_BASE,
+};
+
+struct gpio_altfun_data altfun_table[] = {
+	{
+		.altfun = GPIO_ALT_I2C_0,
+		.start = 147,
+		.end = 148,
+		.cont = 0,
+		.type = GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_I2C_1,
+		.start = 16,
+		.end = 17,
+		.cont = 0,
+		.type = GPIO_ALTF_B,
+	},
+	{
+		.altfun = GPIO_ALT_I2C_2,
+		.start = 10,
+		.end = 11,
+		.cont = 0,
+		.type = GPIO_ALTF_B,
+	},
+	{
+		.altfun = GPIO_ALT_I2C_3,
+		.start = 229,
+		.end = 230,
+		.cont = 0,
+		.type = GPIO_ALTF_C,
+	},
+	{
+		.altfun = GPIO_ALT_UART_0_MODEM,
+		.start = 0,
+		.end = 3,
+		.cont = 1,
+		.type = GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_UART_0_MODEM,
+		.start = 33,
+		.end = 36,
+		.cont = 0,
+		.type = GPIO_ALTF_C,
+	},
+	{
+		.altfun = GPIO_ALT_UART_1,
+		.start = 4,
+		.end = 7,
+		.cont = 0,
+		.type =
+			GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_UART_2,
+		.start = 18,
+		.end = 19,
+		.cont = 1,
+		.type = GPIO_ALTF_B,
+	},
+	{
+		.altfun = GPIO_ALT_UART_2,
+		.start = 29,
+		.end = 32,
+		.cont = 0,
+		.type = GPIO_ALTF_C,
+	},
+	{
+		.altfun = GPIO_ALT_MSP_0,
+		.start = 12,
+		.end = 17,
+		.cont = 1,
+		.type = GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_MSP_0,
+		.start = 21,
+		.end = 21,
+		.cont = 0,
+		.type = GPIO_ALTF_B,
+	},
+	{
+		.altfun = GPIO_ALT_MSP_1,
+		.start = 33,
+		.end = 36,
+		.cont = 0,
+		.type = GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_MSP_2,
+		.start = 192,
+		.end = 196,
+		.cont = 0,
+		.type = GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_LCD_PANEL,
+		.start = 64,
+		.end = 93,
+		.cont = 1,
+		.type = GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_LCD_PANEL,
+		.start = 150,
+		.end = 171,
+		.cont = 0,
+		.type = GPIO_ALTF_B,
+	},
+	{
+		.altfun = GPIO_ALT_SD_CARD0,
+		.start = 18,
+		.end = 28,
+		.cont = 0,
+		.type = GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_MM_CARD0,
+		.start = 18,
+		.end = 32,
+		.cont = 0,
+		.type = GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_USB_OTG,
+		.start = 256,
+		.end = 267,
+		.cont = 0,
+		.type = GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_EMMC,
+		.start = 197,
+		.end = 207,
+		.cont = 0,
+		.type = GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_POP_EMMC,
+		.start = 128,
+		.end = 138,
+		.cont = 0,
+		.type = GPIO_ALTF_A,
+	},
+};
+
+/*
+ * Static Function declarations
+ */
+enum gpio_error gpio_setpinconfig(int pin_id, struct gpio_config *config)
+{
+	struct gpio_register *p_gpio_register =
+	    addr_gpio_register[GPIO_BLOCK(pin_id)];
+	u32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
+	enum gpio_error error = GPIO_OK;
+	u32 temp_reg;
+
+	switch (config->mode) {
+	case GPIO_ALTF_A:
+		temp_reg = readl(&p_gpio_register->gpio_afsa);
+		temp_reg |= mask;
+		writel(temp_reg, &p_gpio_register->gpio_afsa);
+		temp_reg = readl(&p_gpio_register->gpio_afsb);
+		temp_reg &= ~mask;
+		writel(temp_reg, &p_gpio_register->gpio_afsb);
+		break;
+	case GPIO_ALTF_B:
+		temp_reg = readl(&p_gpio_register->gpio_afsa);
+		temp_reg &= ~mask;
+		writel(temp_reg, &p_gpio_register->gpio_afsa);
+		temp_reg = readl(&p_gpio_register->gpio_afsb);
+		temp_reg |= mask;
+		writel(temp_reg, &p_gpio_register->gpio_afsb);
+		break;
+	case GPIO_ALTF_C:
+		temp_reg = readl(&p_gpio_register->gpio_afsa);
+		temp_reg |= mask;
+		writel(temp_reg, &p_gpio_register->gpio_afsa);
+		temp_reg = readl(&p_gpio_register->gpio_afsb);
+		temp_reg |= mask;
+		writel(temp_reg, &p_gpio_register->gpio_afsb);
+		break;
+	case GPIO_MODE_SOFTWARE:
+		temp_reg = readl(&p_gpio_register->gpio_afsa);
+		temp_reg &= ~mask;
+		writel(temp_reg, &p_gpio_register->gpio_afsa);
+		temp_reg = readl(&p_gpio_register->gpio_afsb);
+		temp_reg &= ~mask;
+		writel(temp_reg, &p_gpio_register->gpio_afsb);
+
+		switch (config->direction) {
+		case GPIO_DIR_INPUT:
+			writel(mask, &p_gpio_register->gpio_dirc);
+			break;
+		case GPIO_DIR_OUTPUT:
+			writel(mask, &p_gpio_register->gpio_dirs);
+			break;
+		case GPIO_DIR_LEAVE_UNCHANGED:
+			break;
+		default:
+			return GPIO_INVALID_PARAMETER;
+		}
+
+		break;
+	case GPIO_MODE_LEAVE_UNCHANGED:
+		break;
+	default:
+		return GPIO_INVALID_PARAMETER;
+	}
+	return error;
+}
+
+enum gpio_error gpio_resetgpiopin(int pin_id, char *dev_name)
+{
+	struct gpio_register *p_gpio_register =
+	    addr_gpio_register[GPIO_BLOCK(pin_id)];
+	u32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
+	enum gpio_error error = GPIO_OK;
+	u32 temp_reg;
+
+	temp_reg = readl(&p_gpio_register->gpio_afsa);
+	temp_reg &= ~mask;
+	writel(temp_reg, &p_gpio_register->gpio_afsa);
+	temp_reg = readl(&p_gpio_register->gpio_afsb);
+	temp_reg &= ~mask;
+	writel(temp_reg, &p_gpio_register->gpio_afsb);
+	writel(mask, &p_gpio_register->gpio_dirc);
+
+	return error;
+}
+
+struct gpio_config altfun_pinconfig;
+enum gpio_error gpio_altfunction(enum gpio_alt_function alt_func,
+			    int which_altfunc, char *dev_name)
+{
+	int i, j, start, end;
+	enum gpio_error error = -1;
+
+	for (i = 0; i < ARRAY_SIZE(altfun_table); i++) {
+		if (altfun_table[i].altfun != alt_func)
+			continue;
+
+		start = altfun_table[i].start;
+		end = altfun_table[i].end;
+		for (j = start; j <= end; j++) {
+			if (which_altfunc == GPIO_ALTF_FIND)
+				altfun_pinconfig.mode = altfun_table[i].type;
+			else
+				altfun_pinconfig.mode = which_altfunc;
+			altfun_pinconfig.direction = GPIO_DIR_OUTPUT;
+			altfun_pinconfig.dev_name = dev_name;
+
+			if (which_altfunc != GPIO_ALTF_DISABLE)
+				error = gpio_setpinconfig(j, &altfun_pinconfig);
+			else
+				error = gpio_resetgpiopin(j, dev_name);
+			if (!error)
+				continue;
+			printf("GPIO %d configuration failure (nmdk_error:%d)",
+				j, error);
+			error = GPIO_INVALID_PARAMETER;
+			return error;
+		}
+
+		if (!altfun_table[i].cont)
+			break;
+	}
+	return error;
+}
+
+int gpio_writepin(int pin_id, enum gpio_data value, char *dev_name)
+{
+	struct gpio_register *p_gpio_register =
+	    addr_gpio_register[GPIO_BLOCK(pin_id)];
+	u32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
+
+	switch (value) {
+	case GPIO_DATA_HIGH:
+		writel(mask, &p_gpio_register->gpio_dats);
+		break;
+	case GPIO_DATA_LOW:
+		writel(mask, &p_gpio_register->gpio_datc);
+		break;
+	default:
+		printf("Invalid value passed in %s", __FUNCTION__);
+		return GPIO_INVALID_PARAMETER;
+	}
+	return GPIO_OK;
+}
+
+int gpio_readpin(int pin_id, enum gpio_data *rv)
+{
+	struct gpio_register *p_gpio_register =
+	    addr_gpio_register[GPIO_BLOCK(pin_id)];
+	u32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
+
+	if ((readl(&p_gpio_register->gpio_dat) & mask) != 0)
+		*rv = GPIO_DATA_HIGH;
+	else
+		*rv = GPIO_DATA_LOW;
+	return GPIO_OK;
+}
+
+int gpio_altfuncenable(enum gpio_alt_function altfunc, char *dev_name)
+{
+	return (int)gpio_altfunction(altfunc, GPIO_ALTF_FIND, dev_name);
+}
+
+int gpio_altfuncdisable(enum gpio_alt_function altfunc, char *dev_name)
+{
+	return (int)gpio_altfunction(altfunc, GPIO_ALTF_DISABLE, dev_name);
+}

+ 55 - 0
board/st-ericsson/u8500/prcmu-fw.h

@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2009 ST-Ericsson SA
+ *
+ * Copied from the Linux version:
+ * Author: Kumar Sanghvi <kumar.sanghvi@stericsson.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __MACH_PRCMU_FW_V1_H
+#define __MACH_PRCMU_FW_V1_H
+
+#define AP_EXECUTE	2
+#define I2CREAD		1
+#define I2C_WR_OK	1
+#define I2C_RD_OK	2
+#define I2CWRITE	0
+
+#define _PRCMU_TCDM_BASE    U8500_PRCMU_TCDM_BASE
+#define PRCM_XP70_CUR_PWR_STATE (_PRCMU_TCDM_BASE + 0xFFC)      /* 4 BYTES */
+
+#define PRCM_REQ_MB5        (_PRCMU_TCDM_BASE + 0xE44)    /* 4 bytes  */
+#define PRCM_ACK_MB5        (_PRCMU_TCDM_BASE + 0xDF4)    /* 4 bytes */
+
+/* Mailbox 5 Requests */
+#define PRCM_REQ_MB5_I2COPTYPE_REG	(PRCM_REQ_MB5 + 0x0)
+#define PRCM_REQ_MB5_BIT_FIELDS		(PRCM_REQ_MB5 + 0x1)
+#define PRCM_REQ_MB5_I2CSLAVE		(PRCM_REQ_MB5 + 0x2)
+#define PRCM_REQ_MB5_I2CVAL		(PRCM_REQ_MB5 + 0x3)
+
+/* Mailbox 5 ACKs */
+#define PRCM_ACK_MB5_STATUS	(PRCM_ACK_MB5 + 0x1)
+#define PRCM_ACK_MB5_SLAVE	(PRCM_ACK_MB5 + 0x2)
+#define PRCM_ACK_MB5_VAL	(PRCM_ACK_MB5 + 0x3)
+
+#define LOW_POWER_WAKEUP	1
+#define EXE_WAKEUP		0
+
+#define REQ_MB5			5
+
+extern int prcmu_i2c_read(u8 reg, u16 slave);
+extern int prcmu_i2c_write(u8 reg, u16 slave, u8 reg_data);
+
+#endif /* __MACH_PRCMU_FW_V1_H */

+ 165 - 0
board/st-ericsson/u8500/prcmu.c

@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2009 ST-Ericsson SA
+ *
+ * Adapted from the Linux version:
+ * Author: Kumar Sanghvi <kumar.sanghvi@stericsson.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ */
+
+/*
+ * NOTE: This currently does not support the I2C workaround access method.
+ */
+
+#include <common.h>
+#include <config.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include <asm/types.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+
+#include "prcmu-fw.h"
+
+/* CPU mailbox registers */
+#define PRCM_MBOX_CPU_VAL (U8500_PRCMU_BASE + 0x0fc)
+#define PRCM_MBOX_CPU_SET (U8500_PRCMU_BASE + 0x100)
+#define PRCM_MBOX_CPU_CLR (U8500_PRCMU_BASE + 0x104)
+
+static int prcmu_is_ready(void)
+{
+	int ready = readb(PRCM_XP70_CUR_PWR_STATE) == AP_EXECUTE;
+	if (!ready)
+		printf("PRCMU firmware not ready\n");
+	return ready;
+}
+
+static int _wait_for_req_complete(int num)
+{
+	int timeout = 1000;
+
+	/* checking any already on-going transaction */
+	while ((readl(PRCM_MBOX_CPU_VAL) & (1 << num)) && timeout--)
+		;
+
+	timeout = 1000;
+
+	/* Set an interrupt to XP70 */
+	writel(1 << num, PRCM_MBOX_CPU_SET);
+
+	while ((readl(PRCM_MBOX_CPU_VAL) & (1 << num)) && timeout--)
+		;
+
+	if (!timeout) {
+		printf("PRCMU operation timed out\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+/**
+ * prcmu_i2c_read - PRCMU - 4500 communication using PRCMU I2C
+ * @reg: - db8500 register bank to be accessed
+ * @slave:  - db8500 register to be accessed
+ * Returns: ACK_MB5  value containing the status
+ */
+int prcmu_i2c_read(u8 reg, u16 slave)
+{
+	uint8_t i2c_status;
+	uint8_t i2c_val;
+
+	if (!prcmu_is_ready())
+		return -1;
+
+	debug("\nprcmu_4500_i2c_read:bank=%x;reg=%x;\n",
+			reg, slave);
+
+	/* prepare the data for mailbox 5 */
+	writeb((reg << 1) | I2CREAD, PRCM_REQ_MB5_I2COPTYPE_REG);
+	writeb((1 << 3) | 0x0, PRCM_REQ_MB5_BIT_FIELDS);
+	writeb(slave, PRCM_REQ_MB5_I2CSLAVE);
+	writeb(0, PRCM_REQ_MB5_I2CVAL);
+
+	_wait_for_req_complete(REQ_MB5);
+
+	/* retrieve values */
+	debug("ack-mb5:transfer status = %x\n",
+			readb(PRCM_ACK_MB5_STATUS));
+	debug("ack-mb5:reg bank = %x\n", readb(PRCM_ACK_MB5) >> 1);
+	debug("ack-mb5:slave_add = %x\n",
+			readb(PRCM_ACK_MB5_SLAVE));
+	debug("ack-mb5:reg_val = %d\n", readb(PRCM_ACK_MB5_VAL));
+
+	i2c_status = readb(PRCM_ACK_MB5_STATUS);
+	i2c_val = readb(PRCM_ACK_MB5_VAL);
+
+	if (i2c_status == I2C_RD_OK)
+		return i2c_val;
+	else {
+
+		printf("prcmu_i2c_read:read return status= %d\n",
+				i2c_status);
+		return -1;
+	}
+
+}
+
+/**
+ * prcmu_i2c_write - PRCMU-db8500 communication using PRCMU I2C
+ * @reg: - db8500 register bank to be accessed
+ * @slave:  - db800 register to be written to
+ * @reg_data: - the data to write
+ * Returns: ACK_MB5 value containing the status
+ */
+int prcmu_i2c_write(u8 reg, u16 slave, u8 reg_data)
+{
+	uint8_t i2c_status;
+
+	if (!prcmu_is_ready())
+		return -1;
+
+	debug("\nprcmu_4500_i2c_write:bank=%x;reg=%x;\n",
+			reg, slave);
+
+	/* prepare the data for mailbox 5 */
+	writeb((reg << 1) | I2CWRITE, PRCM_REQ_MB5_I2COPTYPE_REG);
+	writeb((1 << 3) | 0x0, PRCM_REQ_MB5_BIT_FIELDS);
+	writeb(slave, PRCM_REQ_MB5_I2CSLAVE);
+	writeb(reg_data, PRCM_REQ_MB5_I2CVAL);
+
+	debug("\ncpu_is_u8500v11\n");
+	_wait_for_req_complete(REQ_MB5);
+
+	/* retrieve values */
+	debug("ack-mb5:transfer status = %x\n",
+			readb(PRCM_ACK_MB5_STATUS));
+	debug("ack-mb5:reg bank = %x\n", readb(PRCM_ACK_MB5) >> 1);
+	debug("ack-mb5:slave_add = %x\n",
+			readb(PRCM_ACK_MB5_SLAVE));
+	debug("ack-mb5:reg_val = %d\n", readb(PRCM_ACK_MB5_VAL));
+
+	i2c_status = readb(PRCM_ACK_MB5_STATUS);
+	debug("\ni2c_status = %x\n", i2c_status);
+	if (i2c_status == I2C_WR_OK)
+		return 0;
+	else {
+		printf("ape-i2c: i2c_status : 0x%x\n", i2c_status);
+		return -1;
+	}
+}

+ 546 - 0
board/st-ericsson/u8500/u8500_href.c

@@ -0,0 +1,546 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2009
+ *
+ * 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 <config.h>
+#include <common.h>
+#include <i2c.h>
+#include <asm/types.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/sys_proto.h>
+#ifdef CONFIG_MMC
+#include "../../../drivers/mmc/arm_pl180_mmci.h"
+#endif
+
+#define NOMADIK_PER4_BASE	(0x80150000)
+#define NOMADIK_BACKUPRAM0_BASE (NOMADIK_PER4_BASE + 0x00000)
+#define NOMADIK_BACKUPRAM1_BASE (NOMADIK_PER4_BASE + 0x01000)
+
+/* Power, Reset, Clock Management Unit */
+/*
+ * SVA: Smart Video Accelerator
+ * SIA: Smart Imaging Accelerator
+ * SGA: Smart Graphic accelerator
+ * B2R2: Graphic blitter
+ */
+#define PRCMU_BASE	CFG_PRCMU_BASE	/* 0x80157000 for U8500 */
+#define PRCM_ARMCLKFIX_MGT_REG		(PRCMU_BASE + 0x000)
+#define PRCM_ACLK_MGT_REG		(PRCMU_BASE + 0x004)
+#define PRCM_SVAMMDSPCLK_MGT_REG	(PRCMU_BASE + 0x008)
+#define PRCM_SIAMMDSPCLK_MGT_REG	(PRCMU_BASE + 0x00C)
+#define PRCM_SAAMMDSPCLK_MGT_REG	(PRCMU_BASE + 0x010)
+#define PRCM_SGACLK_MGT_REG		(PRCMU_BASE + 0x014)
+#define PRCM_UARTCLK_MGT_REG		(PRCMU_BASE + 0x018)
+#define PRCM_MSPCLK_MGT_REG		(PRCMU_BASE + 0x01C)
+#define PRCM_I2CCLK_MGT_REG		(PRCMU_BASE + 0x020)
+#define PRCM_SDMMCCLK_MGT_REG		(PRCMU_BASE + 0x024)
+#define PRCM_SLIMCLK_MGT_REG		(PRCMU_BASE + 0x028)
+#define PRCM_PER1CLK_MGT_REG		(PRCMU_BASE + 0x02C)
+#define PRCM_PER2CLK_MGT_REG		(PRCMU_BASE + 0x030)
+#define PRCM_PER3CLK_MGT_REG		(PRCMU_BASE + 0x034)
+#define PRCM_PER5CLK_MGT_REG		(PRCMU_BASE + 0x038)
+#define PRCM_PER6CLK_MGT_REG		(PRCMU_BASE + 0x03C)
+#define PRCM_PER7CLK_MGT_REG		(PRCMU_BASE + 0x040)
+#define PRCM_DMACLK_MGT_REG		(PRCMU_BASE + 0x074)
+#define PRCM_B2R2CLK_MGT_REG		(PRCMU_BASE + 0x078)
+
+#define PRCM_PLLSOC0_FREQ_REG		(PRCMU_BASE + 0x080)
+#define PRCM_PLLSOC1_FREQ_REG		(PRCMU_BASE + 0x084)
+#define PRCM_PLLARM_FREQ_REG		(PRCMU_BASE + 0x088)
+#define PRCM_PLLDDR_FREQ_REG		(PRCMU_BASE + 0x08C)
+#define PRCM_ARM_CHGCLKREQ_REG		(PRCMU_BASE + 0x114)
+
+#define PRCM_TCR			(PRCMU_BASE + 0x1C8)
+
+/*
+ * Memory controller register
+ */
+#define DMC_BASE_ADDR			0x80156000
+#define DMC_CTL_97			(DMC_BASE_ADDR + 0x184)
+
+int board_id;	/* set in board_late_init() */
+
+/* PLLs for clock management registers */
+enum {
+	GATED = 0,
+	PLLSOC0,	/* pllsw = 001, ffs() = 1 */
+	PLLSOC1,	/* pllsw = 010, ffs() = 2 */
+	PLLDDR,		/* pllsw = 100, ffs() = 3 */
+	PLLARM,
+};
+
+static struct pll_freq_regs {
+	int idx;	/* index fror pll_name and pll_khz arrays */
+	uint32_t addr;
+} pll_freq_regs[] = {
+	{PLLSOC0, PRCM_PLLSOC0_FREQ_REG},
+	{PLLSOC1, PRCM_PLLSOC1_FREQ_REG},
+	{PLLDDR, PRCM_PLLDDR_FREQ_REG},
+	{PLLARM, PRCM_PLLARM_FREQ_REG},
+	{0, 0},
+};
+
+static const char *pll_name[5] = {"GATED", "SOC0", "SOC1", "DDR", "ARM"};
+static uint32_t pll_khz[5];	/* use ffs(pllsw(reg)) as index for 0..3 */
+
+static struct clk_mgt_regs {
+	uint32_t addr;
+	uint32_t val;
+	const char *descr;
+} clk_mgt_regs[] = {
+	/* register content taken from bootrom settings */
+	{PRCM_ARMCLKFIX_MGT_REG, 0x0120, "ARMCLKFIX"}, /* ena, SOC0/0, ??? */
+	{PRCM_ACLK_MGT_REG, 0x0125, "ACLK"},	/* ena, SOC0/5, 160 MHz */
+	{PRCM_SVAMMDSPCLK_MGT_REG, 0x1122, "SVA"}, /* ena, SOC0/2, 400 MHz */
+	{PRCM_SIAMMDSPCLK_MGT_REG, 0x0022, "SIA"}, /* dis, SOC0/2, 400 MHz */
+	{PRCM_SAAMMDSPCLK_MGT_REG, 0x0822, "SAA"}, /* dis, SOC0/4, 200 MHz */
+	{PRCM_SGACLK_MGT_REG, 0x0024, "SGA"},	/* dis, SOC0/4, 200 MHz */
+	{PRCM_UARTCLK_MGT_REG, 0x0300, "UART"},	/* ena, GATED, CLK38 */
+	{PRCM_MSPCLK_MGT_REG, 0x0200, "MSP"},	/* dis, GATED, CLK38 */
+	{PRCM_I2CCLK_MGT_REG, 0x0130, "I2C"},	/* ena, SOC0/16, 50 MHz */
+	{PRCM_SDMMCCLK_MGT_REG, 0x0130, "SDMMC"}, /* ena, SOC0/16, 50 MHz */
+	{PRCM_PER1CLK_MGT_REG, 0x126, "PER1"},	/* ena, SOC0/6, 133 MHz */
+	{PRCM_PER2CLK_MGT_REG, 0x126, "PER2"},	/* ena, SOC0/6, 133 MHz */
+	{PRCM_PER3CLK_MGT_REG, 0x126, "PER3"},	/* ena, SOC0/6, 133 MHz */
+	{PRCM_PER5CLK_MGT_REG, 0x126, "PER5"},	/* ena, SOC0/6, 133 MHz */
+	{PRCM_PER6CLK_MGT_REG, 0x126, "PER6"},	/* ena, SOC0/6, 133 MHz */
+	{PRCM_PER7CLK_MGT_REG, 0x128, "PER7"},	/* ena, SOC0/8, 100 MHz */
+	{PRCM_DMACLK_MGT_REG, 0x125, "DMA"},	/* ena, SOC0/5, 160 MHz */
+	{PRCM_B2R2CLK_MGT_REG, 0x025, "B2R2"},	/* dis, SOC0/5, 160 MHz */
+	{0, 0, NULL},
+};
+
+static void init_regs(void);
+
+DECLARE_GLOBAL_DATA_PTR;
+#if defined(CONFIG_SHOW_BOOT_PROGRESS)
+void show_boot_progress(int progress)
+{
+	printf("Boot reached stage %d\n", progress);
+}
+#endif
+
+static unsigned int read_asicid(void)
+{
+	unsigned int *address = (void *)U8500_BOOTROM_BASE
+				+ U8500_BOOTROM_ASIC_ID_OFFSET;
+	return readl(address);
+}
+
+int cpu_is_u8500v11(void)
+{
+	return read_asicid() == 0x008500A1;
+}
+
+/*
+ * Miscellaneous platform dependent initialisations
+ */
+
+int board_early_init_f(void)
+{
+	init_regs();
+	return 0;
+}
+
+int board_init(void)
+{
+	uint32_t unused_cols_rows;
+	unsigned int nrows;
+	unsigned int ncols;
+
+	gd->bd->bi_arch_number = 0x1A4;
+	gd->bd->bi_boot_params = 0x00000100;
+	gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
+
+	/*
+	 * Assumption: 2 CS active, both CS have same layout.
+	 *             15 rows max, 11 cols max (controller spec).
+	 *             memory chip has 8 banks, I/O width 32 bit.
+	 * The correct way would be to read MR#8: I/O width and density,
+	 * but this requires locking against the PRCMU firmware.
+	 * Simplified approach:
+	 * Read number of unused rows and columns from mem controller.
+	 * size = nCS x 2^(rows+cols) x nbanks x buswidth_bytes
+	 */
+	unused_cols_rows = readl(DMC_CTL_97);
+	nrows = 15 - (unused_cols_rows & 0x07);
+	ncols = 11 - ((unused_cols_rows & 0x0700) >> 8);
+	gd->bd->bi_dram[0].size = 2 * (1 << (nrows + ncols)) * 8 * 4;
+
+	icache_enable();
+
+	return 0;
+}
+
+int dram_init(void)
+{
+	gd->ram_size = PHYS_SDRAM_SIZE_1;
+
+	return 0;
+}
+
+unsigned int addr_vall_arr[] = {
+	0x8011F000, 0x0000FFFF, /* Clocks for HSI TODO: Enable reqd only */
+	0x8011F008, 0x00001CFF, /* Clocks for HSI TODO: Enable reqd only */
+	0x8000F000, 0x00007FFF, /* Clocks for I2C TODO: Enable reqd only */
+	0x8000F008, 0x00007FFF, /* Clocks for I2C TODO: Enable reqd only */
+	0x80157020, 0x00000150, /* I2C 48MHz clock */
+	0x8012F000, 0x00007FFF, /* Clocks for SD TODO: Enable reqd only */
+	0x8012F008, 0x00007FFF, /* Clocks for SD TODO: Enable reqd only */
+	0xA03DF000, 0x0000000D, /* Clock for MTU Timers */
+	0x8011E00C, 0x00000000, /* GPIO ALT FUNC for EMMC */
+	0x8011E004, 0x0000FFE0, /* GPIO ALT FUNC for EMMC */
+	0x8011E020, 0x0000FFE0, /* GPIO ALT FUNC for EMMC */
+	0x8011E024, 0x00000000, /* GPIO ALT FUNC for EMMC */
+	0x8012E000, 0x20000000, /* GPIO ALT FUNC for UART */
+	0x8012E00C, 0x00000000, /* GPIO ALT FUNC for SD */
+	0x8012E004, 0x0FFC0000, /* GPIO ALT FUNC for SD */
+	0x8012E020, 0x60000000, /* GPIO ALT FUNC for SD */
+	0x8012E024, 0x60000000, /* GPIO ALT FUNC for SD */
+	0x801571E4, 0x0000000C, /* PRCMU settings for B2R2,
+				   PRCM_APE_RESETN_SET_REG */
+	0x80157024, 0x00000130, /* PRCMU settings for EMMC/SD */
+	0xA03FF000, 0x00000003, /* USB */
+	0xA03FF008, 0x00000001, /* USB */
+	0xA03FE00C, 0x00000000, /* USB */
+	0xA03FE020, 0x00000FFF, /* USB */
+	0xA03FE024, 0x00000000	/* USB */
+};
+
+#ifdef BOARD_LATE_INIT
+#ifdef CONFIG_MMC
+
+#define LDO_VAUX3_MASK		0x3
+#define LDO_VAUX3_ENABLE	0x1
+#define VAUX3_VOLTAGE_2_9V	0xd
+
+#define AB8500_REGU_CTRL2	0x4
+#define AB8500_REGU_VRF1VAUX3_REGU_REG	0x040A
+#define AB8500_REGU_VRF1VAUX3_SEL_REG	0x0421
+
+static int hrefplus_mmc_power_init(void)
+{
+	int ret;
+	int val;
+
+	if (!cpu_is_u8500v11())
+		return 0;
+
+	/*
+	 * On v1.1 HREF boards (HREF+), Vaux3 needs to be enabled for the SD
+	 * card to work.  This is done by enabling the regulators in the AB8500
+	 * via PRCMU I2C transactions.
+	 *
+	 * This code is derived from the handling of AB8500_LDO_VAUX3 in
+	 * ab8500_ldo_enable() and ab8500_ldo_disable() in Linux.
+	 *
+	 * Turn off and delay is required to have it work across soft reboots.
+	 */
+
+	ret = prcmu_i2c_read(AB8500_REGU_CTRL2, AB8500_REGU_VRF1VAUX3_REGU_REG);
+	if (ret < 0)
+		goto out;
+
+	val = ret;
+
+	/* Turn off */
+	ret = prcmu_i2c_write(AB8500_REGU_CTRL2, AB8500_REGU_VRF1VAUX3_REGU_REG,
+				val & ~LDO_VAUX3_MASK);
+	if (ret < 0)
+		goto out;
+
+	udelay(10 * 1000);
+
+	/* Set the voltage to 2.9V */
+	ret = prcmu_i2c_write(AB8500_REGU_CTRL2,
+				AB8500_REGU_VRF1VAUX3_SEL_REG,
+				VAUX3_VOLTAGE_2_9V);
+	if (ret < 0)
+		goto out;
+
+	val = val & ~LDO_VAUX3_MASK;
+	val = val | LDO_VAUX3_ENABLE;
+
+	/* Turn on the supply */
+	ret = prcmu_i2c_write(AB8500_REGU_CTRL2,
+				AB8500_REGU_VRF1VAUX3_REGU_REG, val);
+
+out:
+	return ret;
+}
+#endif
+/*
+ * called after all initialisation were done, but before the generic
+ * mmc_initialize().
+ */
+int board_late_init(void)
+{
+	uchar byte;
+
+	/*
+	 * Determine and set board_id environment variable
+	 * 0: mop500, 1: href500
+	 * Above boards have different GPIO expander chips which we can
+	 * distinguish by the chip id.
+	 *
+	 * The board_id environment variable is needed for the Linux bootargs.
+	 */
+	(void) i2c_set_bus_num(0);
+	(void) i2c_read(CONFIG_SYS_I2C_GPIOE_ADDR, 0x80, 1, &byte, 1);
+	if (byte == 0x01) {
+		board_id = 0;
+		setenv("board_id", "0");
+	} else {
+		board_id = 1;
+		setenv("board_id", "1");
+	}
+#ifdef CONFIG_MMC
+	hrefplus_mmc_power_init();
+
+	/*
+	 * config extended GPIO pins for level shifter and
+	 * SDMMC_ENABLE
+	 */
+	if (board_id == 0) {
+		/* MOP500 */
+		byte = 0x0c;
+		(void) i2c_write(CONFIG_SYS_I2C_GPIOE_ADDR, 0x89, 1, &byte, 1);
+		(void) i2c_write(CONFIG_SYS_I2C_GPIOE_ADDR, 0x83, 1, &byte, 1);
+	} else {
+		/* HREF */
+		/* set the direction of GPIO KPY9 and KPY10 */
+		byte = 0x06;
+		(void) i2c_write(CONFIG_SYS_I2C_GPIOE_ADDR, 0xC8, 1, &byte, 1);
+		/* must be a multibyte access */
+		(void) i2c_write(CONFIG_SYS_I2C_GPIOE_ADDR, 0xC4, 1,
+						(uchar []) {0x06, 0x06}, 2);
+	}
+#endif /* CONFIG_MMC */
+	/*
+	 * Create a memargs variable which points uses either the memargs256 or
+	 * memargs512 environment variable, depending on the memory size.
+	 * memargs is used to build the bootargs, memargs256 and memargs512 are
+	 * stored in the environment.
+	 */
+	if (gd->bd->bi_dram[0].size == 0x10000000) {
+		setenv("memargs", "setenv bootargs ${bootargs} ${memargs256}");
+		setenv("mem", "256M");
+	} else {
+		setenv("memargs", "setenv bootargs ${bootargs} ${memargs512}");
+		setenv("mem", "512M");
+	}
+
+	return 0;
+}
+#endif /* BOARD_LATE_INIT */
+
+static void early_gpio_setup(struct gpio_register *gpio_reg, u32 bits)
+{
+	writel(readl(&gpio_reg->gpio_dats) | bits, &gpio_reg->gpio_dats);
+	writel(readl(&gpio_reg->gpio_pdis) & ~bits, &gpio_reg->gpio_pdis);
+}
+
+static void init_regs(void)
+{
+	/* FIXME Remove magic register array settings for ED also */
+	struct prcmu *prcmu = (struct prcmu *) U8500_PRCMU_BASE;
+
+	/* Enable timers */
+	writel(1 << 17, &prcmu->tcr);
+
+	u8500_prcmu_enable(&prcmu->per1clk_mgt);
+	u8500_prcmu_enable(&prcmu->per2clk_mgt);
+	u8500_prcmu_enable(&prcmu->per3clk_mgt);
+	u8500_prcmu_enable(&prcmu->per5clk_mgt);
+	u8500_prcmu_enable(&prcmu->per6clk_mgt);
+	u8500_prcmu_enable(&prcmu->per7clk_mgt);
+
+	u8500_prcmu_enable(&prcmu->uartclk_mgt);
+	u8500_prcmu_enable(&prcmu->i2cclk_mgt);
+
+	u8500_prcmu_enable(&prcmu->sdmmcclk_mgt);
+
+	u8500_clock_enable(1, 9, -1);	/* GPIO0 */
+
+	u8500_clock_enable(2, 11, -1);	/* GPIO1 */
+
+	u8500_clock_enable(3, 8, -1);	/* GPIO2 */
+	u8500_clock_enable(5, 1, -1);	/* GPIO3 */
+
+	u8500_clock_enable(3, 6, 6);	/* UART2 */
+
+	gpio_altfuncenable(GPIO_ALT_I2C_0, "I2C0");
+	u8500_clock_enable(3, 3, 3);	/* I2C0 */
+
+	early_gpio_setup((struct gpio_register *)U8500_GPIO_0_BASE, 0x60000000);
+	gpio_altfuncenable(GPIO_ALT_UART_2, "UART2");
+
+	early_gpio_setup((struct gpio_register *)U8500_GPIO_6_BASE, 0x0000ffe0);
+	gpio_altfuncenable(GPIO_ALT_EMMC, "EMMC");
+
+	early_gpio_setup((struct gpio_register *)U8500_GPIO_0_BASE, 0x0000ffe0);
+	gpio_altfuncenable(GPIO_ALT_SD_CARD0, "SDCARD");
+
+	u8500_clock_enable(1, 5, 5);	/* SDI0 */
+	u8500_clock_enable(2, 4, 2);	/* SDI4 */
+
+	u8500_clock_enable(6, 7, -1);	/* MTU0 */
+	u8500_clock_enable(3, 4, 4);	/* SDI2 */
+
+	early_gpio_setup((struct gpio_register *)U8500_GPIO_4_BASE, 0x000007ff);
+	gpio_altfuncenable(GPIO_ALT_POP_EMMC, "EMMC");
+
+	/*
+	 * Enabling clocks for all devices which are AMBA devices in the
+	 * kernel.  Otherwise they will not get probe()'d because the
+	 * peripheral ID register will not be powered.
+	 */
+
+	/* XXX: some of these differ between ED/V1 */
+
+	u8500_clock_enable(1, 1, 1);	/* UART1 */
+	u8500_clock_enable(1, 0, 0);	/* UART0 */
+
+	u8500_clock_enable(3, 2, 2);	/* SSP1 */
+	u8500_clock_enable(3, 1, 1);	/* SSP0 */
+
+	u8500_clock_enable(2, 8, -1);	/* SPI0 */
+	u8500_clock_enable(2, 5, 3);	/* MSP2 */
+}
+
+#ifdef CONFIG_MMC
+static int u8500_mmci_board_init(void)
+{
+	enum gpio_error error;
+	struct gpio_register *gpio_base_address;
+
+	gpio_base_address = (void *)(U8500_GPIO_0_BASE);
+	gpio_base_address->gpio_dats |= 0xFFC0000;
+	gpio_base_address->gpio_pdis &= ~0xFFC0000;
+
+	/* save the GPIO0 AFSELA register */
+	error = gpio_altfuncenable(GPIO_ALT_SD_CARD0, "MMC");
+	if (error != GPIO_OK) {
+		printf("u8500_mmci_board_init() gpio_altfuncenable failed\n");
+		return -ENODEV;
+	}
+	return 0;
+}
+
+int board_mmc_init(bd_t *bd)
+{
+	if (u8500_mmci_board_init())
+		return -ENODEV;
+
+	if (arm_pl180_mmci_init())
+		return -ENODEV;
+	return 0;
+}
+#endif
+
+
+/*
+ * get_pll_freq_khz - return PLL frequency in kHz
+ */
+static uint32_t get_pll_freq_khz(uint32_t inclk_khz, uint32_t freq_reg)
+{
+	uint32_t idf, ldf, odf, seldiv, phi;
+
+	/*
+	 * PLLOUTCLK = PHI = (INCLK*LDF)/(2*ODF*IDF) if SELDIV2=0
+	 * PLLOUTCLK = PHI = (INCLK*LDF)/(4*ODF*IDF) if SELDIV2=1
+	 * where:
+	 * IDF=R(2:0) (when R=000, IDF=1d)
+	 * LDF = 2*D(7:0) (D must be greater than or equal to 6)
+	 * ODF = N(5:0) (when N=000000, 0DF=1d)
+	 */
+
+	idf = (freq_reg & 0x70000) >> 16;
+	ldf = (freq_reg & 0xff) * 2;
+	odf = (freq_reg & 0x3f00) >> 8;
+	seldiv = (freq_reg & 0x01000000) >> 24;
+	phi = (inclk_khz * ldf) / (2 * odf * idf);
+	if (seldiv)
+		phi = phi/2;
+
+	return phi;
+}
+
+int do_clkinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	uint32_t inclk_khz;
+	uint32_t reg, phi;
+	uint32_t clk_khz;
+	unsigned int clk_sel;
+	struct clk_mgt_regs *clks = clk_mgt_regs;
+	struct pll_freq_regs *plls = pll_freq_regs;
+
+	/*
+	 * Go through list of PLLs.
+	 * Initialise pll out frequency array (pll_khz) and print frequency.
+	 */
+	inclk_khz = 38400;	/* 38.4 MHz */
+	while (plls->addr) {
+		reg = readl(plls->addr);
+		phi = get_pll_freq_khz(inclk_khz, reg);
+		pll_khz[plls->idx] = phi;
+		printf("%s PLL out frequency: %d.%d Mhz\n",
+				pll_name[plls->idx], phi/1000, phi % 1000);
+		plls++;
+	}
+
+	/* check ARM clock source */
+	reg = readl(PRCM_ARM_CHGCLKREQ_REG);
+	printf("A9 running on %s\n",
+		(reg & 1) ?  "external clock" : "ARM PLL");
+
+	/* go through list of clk_mgt_reg */
+	printf("\n%19s %9s %7s %9s enabled\n",
+			"name(addr)", "value", "PLL", "CLK[MHz]");
+	while (clks->addr) {
+		reg = readl(clks->addr);
+
+		/* convert bit position into array index */
+		clk_sel = ffs((reg >> 5) & 0x7);	/* PLLSW[2:0] */
+
+		if (reg & 0x200)
+			clk_khz = 38400;	/* CLK38 is set */
+		else if ((reg & 0x1f) == 0)
+			/* ARMCLKFIX_MGT is 0x120, e.g. div = 0 ! */
+			clk_khz = 0;
+		else
+			clk_khz = pll_khz[clk_sel] / (reg & 0x1f);
+
+		printf("%9s(%08x): %08x, %6s, %4d.%03d, %s\n",
+			clks->descr, clks->addr, reg, pll_name[clk_sel],
+			clk_khz / 1000, clk_khz % 1000,
+			(reg & 0x100) ? "ena" : "dis");
+		clks++;
+	}
+
+	return 0;
+}
+
+U_BOOT_CMD(
+	clkinfo,	1,	1,	do_clkinfo,
+	"print clock info",
+	""
+);

+ 1 - 0
boards.cfg

@@ -154,6 +154,7 @@ s5pc210_universal            arm         armv7       universal_c210      samsung
 smdkv310		     arm	 armv7	     smdkv310		 samsung	s5pc2xx
 smdkv310		     arm	 armv7	     smdkv310		 samsung	s5pc2xx
 harmony                      arm         armv7       harmony             nvidia         tegra2
 harmony                      arm         armv7       harmony             nvidia         tegra2
 seaboard                     arm         armv7       seaboard            nvidia         tegra2
 seaboard                     arm         armv7       seaboard            nvidia         tegra2
+u8500_href                   arm         armv7       u8500               st-ericsson    u8500
 actux1                       arm         ixp
 actux1                       arm         ixp
 actux2                       arm         ixp
 actux2                       arm         ixp
 actux3                       arm         ixp
 actux3                       arm         ixp

+ 245 - 0
include/configs/u8500_href.h

@@ -0,0 +1,245 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2009
+ *
+ * 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_U8500
+#define CONFIG_L2_OFF
+
+#define CONFIG_SYS_MEMTEST_START	0x00000000
+#define CONFIG_SYS_MEMTEST_END	0x1FFFFFFF
+#define CONFIG_SYS_HZ		1000		/* must be 1000 */
+
+#define CONFIG_BOARD_EARLY_INIT_F
+#define BOARD_LATE_INIT
+
+/*
+ * Size of malloc() pool
+ */
+#ifdef CONFIG_BOOT_SRAM
+#define CONFIG_ENV_SIZE		(32*1024)
+#define CONFIG_SYS_MALLOC_LEN	(CONFIG_ENV_SIZE + 64*1024)
+#else
+#define CONFIG_ENV_SIZE		(128*1024)
+#define CONFIG_SYS_MALLOC_LEN	(CONFIG_ENV_SIZE + 256*1024)
+#endif
+#define CONFIG_SYS_GBL_DATA_SIZE	128	/* for initial data */
+
+/*
+ * PL011 Configuration
+ */
+#define CONFIG_PL011_SERIAL
+#define CONFIG_PL011_SERIAL_RLCR
+#define CONFIG_PL011_SERIAL_FLUSH_ON_INIT
+
+/*
+ * U8500 UART registers base for 3 serial devices
+ */
+#define CFG_UART0_BASE		0x80120000
+#define CFG_UART1_BASE		0x80121000
+#define CFG_UART2_BASE		0x80007000
+#define CFG_SERIAL0		CFG_UART0_BASE
+#define CFG_SERIAL1		CFG_UART1_BASE
+#define CFG_SERIAL2		CFG_UART2_BASE
+#define CONFIG_PL011_CLOCK	38400000
+#define CONFIG_PL01x_PORTS	{ (void *)CFG_SERIAL0, (void *)CFG_SERIAL1, \
+				  (void *)CFG_SERIAL2 }
+#define CONFIG_CONS_INDEX	2
+#define CONFIG_BAUDRATE		115200
+#define CONFIG_SYS_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200 }
+
+/*
+ * Devices and file systems
+ */
+#define CONFIG_MMC
+#define CONFIG_GENERIC_MMC
+#define CONFIG_DOS_PARTITION
+
+/*
+ * Commands
+ */
+#define CONFIG_CMD_MEMORY
+#define CONFIG_CMD_BOOTD
+#define CONFIG_CMD_BDI
+#define CONFIG_CMD_IMI
+#define CONFIG_CMD_MISC
+#define CONFIG_CMD_RUN
+#define CONFIG_CMD_ECHO
+#define CONFIG_CMD_CONSOLE
+#define CONFIG_CMD_LOADS
+#define CONFIG_CMD_LOADB
+#define CONFIG_CMD_MMC
+#define CONFIG_CMD_FAT
+#define CONFIG_CMD_EXT2
+#define CONFIG_CMD_EMMC
+#define CONFIG_CMD_SOURCE
+#define CONFIG_CMD_I2C
+
+#ifndef CONFIG_BOOTDELAY
+#define CONFIG_BOOTDELAY	1
+#endif
+#define CONFIG_ZERO_BOOTDELAY_CHECK	/* check for keypress on bootdelay==0 */
+
+#undef CONFIG_BOOTARGS
+#define CONFIG_BOOTCOMMAND	"run emmcboot"
+
+#define CONFIG_EXTRA_ENV_SETTINGS \
+	"verify=n\0"							\
+	"loadaddr=0x00100000\0"						\
+	"console=ttyAMA2,115200n8\0"					\
+	"memargs256=mem=96M@0 mem_modem=32M@96M mem=30M@128M "		\
+		"pmem=22M@158M pmem_hwb=44M@180M mem_mali=32@224M\0"	\
+	"memargs512=mem=96M@0 mem_modem=32M@96M mem=44M@128M "		\
+		"pmem=22M@172M mem=30M@194M mem_mali=32M@224M "		\
+		"pmem_hwb=54M@256M mem=202M@310M\0"			\
+	"commonargs=setenv bootargs cachepolicy=writealloc noinitrd "	\
+		"init=init "						\
+		"board_id=${board_id} "					\
+		"logo.${logo} "						\
+		"startup_graphics=${startup_graphics}\0"		\
+	"emmcargs=setenv bootargs ${bootargs} "				\
+		"root=/dev/mmcblk0p2 "					\
+		"rootdelay=1\0"						\
+	"addcons=setenv bootargs ${bootargs} "				\
+		"console=${console}\0"					\
+	"emmcboot=echo Booting from eMMC ...; "				\
+		"run commonargs emmcargs addcons memargs;"		\
+		"mmc read 0 ${loadaddr} 0xA0000 0x4000;"		\
+		"bootm ${loadaddr}\0"					\
+	"flash=mmc init 1;fatload mmc 1 ${loadaddr} flash.scr;"		\
+		"source ${loadaddr}\0"					\
+	"loaduimage=mmc init 1;fatload mmc 1 ${loadaddr} uImage\0"	\
+	"usbtty=cdc_acm\0"						\
+	"stdout=serial,usbtty\0"					\
+	"stdin=serial,usbtty\0"						\
+	"stderr=serial,usbtty\0"
+
+/*
+ * Miscellaneous configurable options
+ */
+
+#define CONFIG_SYS_LONGHELP			/* undef to save memory     */
+#define CONFIG_SYS_PROMPT	"U8500 $ "	/* Monitor Command Prompt   */
+#define CONFIG_SYS_CBSIZE	1024		/* Console I/O Buffer Size  */
+
+/* Print Buffer Size */
+#define CONFIG_SYS_PBSIZE		(CONFIG_SYS_CBSIZE \
+					+ sizeof(CONFIG_SYS_PROMPT) + 16)
+#define CONFIG_SYS_MAXARGS	32	/* max number of command args */
+#define CONFIG_SYS_BARGSIZE	CONFIG_SYS_CBSIZE /* Boot Arg Buffer Size */
+
+#undef	CONFIG_SYS_CLKS_IN_HZ		/* everything, incl board info, in Hz */
+#define CONFIG_SYS_LOAD_ADDR		0x00100000 /* default load address */
+#define CONFIG_SYS_LOADS_BAUD_CHANGE
+
+#define CONFIG_SYS_HUSH_PARSER
+#define CONFIG_SYS_PROMPT_HUSH_PS2	"> "
+#define CONFIG_CMDLINE_EDITING
+
+#define CONFIG_SETUP_MEMORY_TAGS	2
+#define CONFIG_INITRD_TAG
+#define CONFIG_CMDLINE_TAG			/* enable passing of ATAGs  */
+
+/*
+ * I2C
+ */
+#define CONFIG_U8500_I2C
+#undef	CONFIG_HARD_I2C			/* I2C with hardware support */
+#undef	CONFIG_SOFT_I2C			/* I2C bit-banged */
+#define CONFIG_I2C_MULTI_BUS
+#define CONFIG_SYS_I2C_SPEED		100000
+#define CONFIG_SYS_I2C_SLAVE		0	/* slave addr of controller */
+#define CONFIG_SYS_U8500_I2C0_BASE		0x80004000
+#define CONFIG_SYS_U8500_I2C1_BASE		0x80122000
+#define CONFIG_SYS_U8500_I2C2_BASE		0x80128000
+#define CONFIG_SYS_U8500_I2C3_BASE		0x80110000
+#define CONFIG_SYS_U8500_I2C_BUS_MAX		4
+
+#define CONFIG_SYS_I2C_GPIOE_ADDR	0x42	/* GPIO expander chip addr */
+#define CONFIG_TC35892_GPIO
+/*
+ * Stack sizes
+ *
+ * The stack sizes are set up in start.S using the settings below
+ */
+
+#ifdef CONFIG_USE_IRQ
+#define CONFIG_STACKSIZE_IRQ		(4*1024)	/* IRQ stack */
+#define CONFIG_STACKSIZE_FIQ		(4*1024)	/* FIQ stack */
+#endif
+
+/*
+ * Physical Memory Map
+ */
+#define CONFIG_NR_DRAM_BANKS		1
+#define PHYS_SDRAM_1			0x00000000	/* DDR-SDRAM Bank #1 */
+#define PHYS_SDRAM_SIZE_1		0x20000000	/* 512 MB */
+
+/*
+ * additions for new relocation code
+ */
+#define CONFIG_SYS_SDRAM_BASE		PHYS_SDRAM_1
+#define CONFIG_SYS_INIT_RAM_SIZE	0x100000
+#define CONFIG_SYS_GBL_DATA_OFFSET	(CONFIG_SYS_SDRAM_BASE + \
+					 CONFIG_SYS_INIT_RAM_SIZE - \
+					 GENERATED_GBL_DATA_SIZE)
+#define CONFIG_SYS_INIT_SP_ADDR		CONFIG_SYS_GBL_DATA_OFFSET
+
+/* landing address before relocation */
+#ifndef CONFIG_SYS_TEXT_BASE
+#define CONFIG_SYS_TEXT_BASE            0x0
+#endif
+
+/*
+ * MMC related configs
+ * NB Only externa SD slot is currently supported
+ */
+#define MMC_BLOCK_SIZE			512
+#define CONFIG_ARM_PL180_MMCI
+#define CONFIG_ARM_PL180_MMCI_BASE	0x80126000	/* MMC base for 8500  */
+#define CONFIG_ARM_PL180_MMCI_CLOCK_FREQ 6250000
+#define CONFIG_MMC_DEV_NUM		1
+
+#define CONFIG_CMD_ENV
+#define CONFIG_CMD_SAVEENV	/* CMD_ENV is obsolete but used in env_emmc.c */
+#define CONFIG_ENV_IS_IN_MMC
+#define CONFIG_ENV_OFFSET		0x13F80000
+#define CONFIG_SYS_MMC_ENV_DEV          0               /* SLOT2: eMMC */
+
+/*
+ * FLASH and environment organization
+ */
+#define CONFIG_SYS_NO_FLASH
+
+/*
+ * base register values for U8500
+ */
+#define CFG_PRCMU_BASE		0x80157000	/* Power, reset and clock
+						   management unit */
+#define CFG_FSMC_BASE		0x80000000	/* FSMC Controller */
+
+#endif	/* __CONFIG_H */